| /*=============================================================================# |
| # Copyright (c) 2015, 2019 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.internal.docmlet.base.ui.viewer; |
| |
| import static org.eclipse.statet.docmlet.base.ui.viewer.DocViewerConfig.DDE_APPLICATION_ATTR_KEY; |
| import static org.eclipse.statet.docmlet.base.ui.viewer.DocViewerConfig.DDE_COMMAND_ATTR_KEY; |
| import static org.eclipse.statet.docmlet.base.ui.viewer.DocViewerConfig.DDE_TOPIC_ATTR_KEY; |
| import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; |
| import static org.eclipse.statet.jcommons.lang.ObjectUtils.nullable; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.core.filesystem.URIUtil; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubMonitor; |
| import org.eclipse.core.variables.IStringVariable; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.ui.IWorkbenchPage; |
| |
| import org.eclipse.statet.jcommons.collections.ImCollections; |
| import org.eclipse.statet.jcommons.collections.ImList; |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.lang.Nullable; |
| |
| import org.eclipse.statet.ecommons.debug.core.util.LaunchUtils; |
| import org.eclipse.statet.ecommons.io.FileValidator; |
| import org.eclipse.statet.ecommons.io.win.DDE; |
| import org.eclipse.statet.ecommons.io.win.DDEClient; |
| import org.eclipse.statet.ecommons.resources.core.variables.ResourceVariableResolver; |
| import org.eclipse.statet.ecommons.resources.core.variables.ResourceVariables; |
| import org.eclipse.statet.ecommons.ui.util.UIAccess; |
| import org.eclipse.statet.ecommons.ui.workbench.workspace.ResourceVariableUtil; |
| import org.eclipse.statet.ecommons.variables.core.StaticVariable; |
| import org.eclipse.statet.ecommons.variables.core.VariableText2; |
| import org.eclipse.statet.ecommons.variables.core.VariableUtils; |
| |
| import org.eclipse.statet.docmlet.base.ui.DocmlBaseUI; |
| import org.eclipse.statet.docmlet.base.ui.processing.DocProcessingConfig; |
| import org.eclipse.statet.docmlet.base.ui.viewer.DocViewerConfig; |
| import org.eclipse.statet.docmlet.base.ui.viewer.DocViewerUI; |
| |
| |
| @NonNullByDefault |
| public class DocViewerLaunchConfig { |
| |
| |
| protected static CoreException createMissingConfigAttr(final String attrName) { |
| return new CoreException(new Status(IStatus.ERROR, DocmlBaseUI.BUNDLE_ID, |
| NLS.bind("Invalid configuration: configuration attribute ''{0}'' is missing.", attrName) )); |
| } |
| |
| protected static CoreException createValidationFailed(final FileValidator validator) { |
| final IStatus status= validator.getStatus(); |
| return new CoreException(new Status(IStatus.ERROR, DocmlBaseUI.BUNDLE_ID, |
| status.getMessage() )); |
| } |
| |
| protected static CoreException createValidationFailed(final String message) { |
| return new CoreException(new Status(IStatus.ERROR, DocmlBaseUI.BUNDLE_ID, |
| message )); |
| } |
| |
| |
| public static class DDETask { |
| |
| private final String command; |
| private final String application; |
| private final String topic; |
| |
| |
| public DDETask(final String command, final String application, final String topic) { |
| this.command= command; |
| this.application= application; |
| this.topic= topic; |
| } |
| |
| |
| public void exec() throws CoreException { |
| DDEClient.execute(this.application, this.topic, this.command); |
| } |
| |
| |
| } |
| |
| |
| private IFile docFile; |
| private ResourceVariableUtil docFileUtil; |
| |
| private @Nullable VariableText2 variableText; |
| |
| |
| /** |
| * {@link #initDocFile(ILaunchConfiguration, SubMonitor)} |
| */ |
| public DocViewerLaunchConfig() { |
| } |
| |
| public DocViewerLaunchConfig(final ResourceVariableUtil sourceFileUtil, |
| final @Nullable Map<String, ? extends IStringVariable> extraVariables) { |
| this.docFileUtil= nonNullAssert(sourceFileUtil); |
| setDocFile(nonNullAssert((IFile)sourceFileUtil.getResource())); |
| |
| if (extraVariables != null) { |
| getVariableResolver().getExtraVariables().putAll(extraVariables); |
| } |
| } |
| |
| |
| public VariableText2 getVariableResolver() { |
| VariableText2 variableText= this.variableText; |
| if (variableText == null) { |
| final Map<String, IStringVariable> variables= new HashMap<>(); |
| variableText= new VariableText2(variables); |
| this.variableText= variableText; |
| } |
| |
| return variableText; |
| } |
| |
| |
| public void initDocFile(final ILaunchConfiguration configuration, |
| final SubMonitor m) throws CoreException { |
| final FileValidator validator= new FileValidator(true); |
| validator.setResourceLabel("document"); |
| validator.setRequireWorkspace(true, true); |
| validator.setOnDirectory(IStatus.ERROR); |
| |
| final String path= configuration.getAttribute(DocViewerUI.DOC_PATH_ATTR_NAME, (String) null); |
| if (path != null) { |
| validator.setExplicit(path); |
| } |
| else { |
| UIAccess.getDisplay().syncExec(new Runnable() { |
| @Override |
| public void run() { |
| final ResourceVariableUtil util= new ResourceVariableUtil(); |
| util.getResource(); |
| DocViewerLaunchConfig.this.docFileUtil= util; |
| } |
| }); |
| if (this.docFileUtil.getResource() == null) { |
| throw new CoreException(new Status(IStatus.ERROR, DocmlBaseUI.BUNDLE_ID, |
| "No resource for 'document' to view selected in the active Workbench window." )); |
| } |
| validator.setExplicit(this.docFileUtil.getResource()); |
| } |
| |
| if (validator.getStatus().getSeverity() == IStatus.ERROR) { |
| throw createValidationFailed(validator); |
| } |
| |
| setDocFile(nonNullAssert((IFile)validator.getWorkspaceResource())); |
| } |
| |
| protected void setDocFile(final IFile file) { |
| this.docFile= file; |
| |
| ResourceVariableUtil docFileUtil= nullable(this.docFileUtil); |
| if (docFileUtil == null) { |
| docFileUtil= UIAccess.syncExecGet(() -> new ResourceVariableUtil(file)); |
| this.docFileUtil= nonNullAssert(docFileUtil); |
| } |
| |
| { final Map<String, IStringVariable> variables= getVariableResolver().getExtraVariables(); |
| VariableUtils.add(variables, |
| ResourceVariables.getSingleResourceVariables(), |
| new ResourceVariableResolver(this.docFileUtil) ); |
| VariableUtils.add(variables, new StaticVariable( |
| DocProcessingConfig.SOURCE_FILE_PATH_VAR, |
| file.getFullPath().toString() )); |
| } |
| } |
| |
| public IWorkbenchPage getWorkbenchPage() { |
| return this.docFileUtil.getWorkbenchPage(); |
| } |
| |
| public IFile getSourceFile() { |
| return this.docFile; |
| } |
| |
| public ResourceVariableUtil getSourceFileVariableUtil() { |
| return this.docFileUtil; |
| } |
| |
| |
| public ProcessBuilder initProgram(final ILaunchConfiguration configuration) throws CoreException { |
| final IPath programPath; |
| { final FileValidator validator= new FileValidator(true); |
| validator.setResourceLabel("program location"); |
| validator.setOnDirectory(IStatus.ERROR); |
| validator.setVariableResolver(getVariableResolver()); |
| |
| final String path= configuration.getAttribute(DocViewerConfig.PROGRAM_FILE_ATTR_NAME, |
| (String) null ); |
| if (path == null) { |
| throw createMissingConfigAttr(DocViewerConfig.PROGRAM_FILE_ATTR_NAME); |
| } |
| validator.setExplicit(path); |
| |
| if (validator.getStatus().getSeverity() == IStatus.ERROR) { |
| throw createValidationFailed(validator); |
| } |
| |
| programPath= URIUtil.toPath(validator.getFileStore().toURI()); |
| } |
| |
| final ProcessBuilder processBuilder= new ProcessBuilder(programPath.toOSString()); |
| |
| { final ImList<String> arguments= getProgramArguments(configuration, getVariableResolver()); |
| if (!arguments.isEmpty()) { |
| processBuilder.command().addAll(arguments); |
| } |
| } |
| { final Map<String, String> environment= processBuilder.environment(); |
| environment.clear(); |
| environment.putAll(LaunchUtils.createEnvironment(configuration, null)); |
| } |
| |
| return processBuilder; |
| } |
| |
| private ImList<String> getProgramArguments(final ILaunchConfiguration configuration, |
| final VariableText2 variableResolver) throws CoreException { |
| String arguments= configuration.getAttribute(DocViewerConfig.PROGRAM_ARGUMENTS_ATTR_NAME, |
| "" ); //$NON-NLS-1$ |
| if (arguments.isEmpty()) { |
| return ImCollections.emptyList(); |
| } |
| try { |
| arguments= variableResolver.performStringSubstitution(arguments, null); |
| return ImCollections.newList(DebugPlugin.parseArguments(arguments)); |
| } |
| catch (final CoreException e) { |
| throw createValidationFailed(NLS.bind(Messages.ProgramArgs_error_Other_message, |
| e.getMessage() )); |
| } |
| } |
| |
| |
| public @Nullable DDETask loadDDETask(final ILaunchConfiguration configuration, final String attrQualifier, |
| @Nullable String taskLabel, final SubMonitor m) throws CoreException { |
| if (DDE.isSupported()) { |
| if (taskLabel == null) { |
| taskLabel= "DDE"; //$NON-NLS-1$ |
| } |
| String command= configuration.getAttribute(attrQualifier + '/' + DDE_COMMAND_ATTR_KEY, |
| (String) null ); |
| if (command != null && !command.isEmpty()) { |
| String application= configuration.getAttribute(attrQualifier + '/' + DDE_APPLICATION_ATTR_KEY, |
| "" ); //$NON-NLS-1$ |
| String topic= configuration.getAttribute(attrQualifier + '/' + DDE_TOPIC_ATTR_KEY, |
| "" ); //$NON-NLS-1$ |
| |
| final VariableText2 variableResolver= getVariableResolver(); |
| try { |
| command= variableResolver.performStringSubstitution(command, null); |
| } |
| catch (final CoreException e) { |
| createValidationFailed(NLS.bind(Messages.DDECommand_error_Other_message, |
| taskLabel, e.getMessage() )); |
| } |
| try { |
| application= variableResolver.performStringSubstitution(application, null); |
| } |
| catch (final CoreException e) { |
| throw createValidationFailed(NLS.bind(Messages.DDEApplication_error_Other_message, |
| taskLabel, e.getMessage() )); |
| } |
| try { |
| topic= variableResolver.performStringSubstitution(topic, null); |
| } |
| catch (final CoreException e) { |
| throw createValidationFailed(NLS.bind(Messages.DDETopic_error_Other_message, |
| taskLabel, e.getMessage() )); |
| } |
| |
| return new DDETask(command, application, topic); |
| } |
| } |
| return null; |
| } |
| |
| } |