diff options
9 files changed, 191 insertions, 84 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/extensions/StepExecutor.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/extensions/StepExecutor.java index 79bb5f838..293c3e0db 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/extensions/StepExecutor.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/extensions/StepExecutor.java @@ -22,6 +22,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.osgi.util.NLS; import org.eclipse.tcf.te.runtime.callback.Callback; import org.eclipse.tcf.te.runtime.concurrent.util.ExecutorsUtil; +import org.eclipse.tcf.te.runtime.interfaces.IConditionTester; import org.eclipse.tcf.te.runtime.interfaces.ISharedConstants; import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer; import org.eclipse.tcf.te.runtime.stepper.activator.CoreBundleActivator; @@ -73,7 +74,7 @@ public class StepExecutor implements IStepExecutor { * @see org.eclipse.tcf.te.runtime.stepper.interfaces.IStepExecutor#execute(org.eclipse.tcf.te.runtime.stepper.interfaces.IStep, org.eclipse.tcf.te.runtime.stepper.interfaces.IFullQualifiedId, org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext, org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer, org.eclipse.core.runtime.IProgressMonitor) */ @Override - public final void execute(final IStep step, IFullQualifiedId id, final IStepContext context, final IPropertiesContainer data, IProgressMonitor progress) throws CoreException { + public final void execute(final IStep step, final IFullQualifiedId id, final IStepContext context, final IPropertiesContainer data, IProgressMonitor progress) throws CoreException { Assert.isNotNull(step); Assert.isNotNull(id); Assert.isNotNull(context); @@ -104,9 +105,23 @@ public class StepExecutor implements IStepExecutor { step.validateExecute(context, data, id, progress); step.execute(context, data, id, progress, callback); + IConditionTester conditionTester = new Callback.CallbackDoneConditionTester(callback, progress, step.getCancelTimeout()) { + boolean cancelCalled = false; + /* (non-Javadoc) + * @see org.eclipse.tcf.te.runtime.callback.Callback.CallbackDoneConditionTester#isConditionFulfilled() + */ + @Override + public boolean isConditionFulfilled() { + if (!cancelCalled && monitor != null && monitor.isCanceled()) { + cancelCalled = true; + step.cancel(context, data, id, monitor); + } + return super.isConditionFulfilled(); + } + }; // Wait till the step finished, an execution occurred or the // user hit cancel on the progress monitor. - ExecutorsUtil.waitAndExecute(0, callback.getDoneConditionTester(progress, step.getCancelTimeout())); + ExecutorsUtil.waitAndExecute(0, conditionTester); if (callback.getStatus() == null || callback.getStatus().isOK()) { return; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/interfaces/IStep.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/interfaces/IStep.java index 1d7f7abc8..dd744e403 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/interfaces/IStep.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/interfaces/IStep.java @@ -102,6 +102,18 @@ public interface IStep extends IExecutableExtension { public void cleanup(IStepContext context, IPropertiesContainer data, IFullQualifiedId fullQualifiedId, IProgressMonitor monitor); /** + * Cancel the current execute. + * <p> + * This method will be called when the stepper gets canceled. + * + * @param context The context. Must not be <code>null</code>. + * @param data The data. Must not be <code>null</code>. + * @param fullQualifiedId The full qualified id for this step. Must not be <code>null</code>. + * @param monitor The progress monitor. Must not be <code>null</code>. + */ + public void cancel(IStepContext context, IPropertiesContainer data, IFullQualifiedId fullQualifiedId, IProgressMonitor monitor); + + /** * Called from the stepper engine once an error occurred during the stepping. Gives each step, * completed previously to the error, the possibility to rollback whatever the step did. * <p> diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/steps/AbstractStep.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/steps/AbstractStep.java index a828d05df..13d29cce2 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/steps/AbstractStep.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/steps/AbstractStep.java @@ -186,4 +186,11 @@ public abstract class AbstractStep extends ExecutableExtension implements IStep // default timeout is 1 minute return 60000; } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.runtime.stepper.interfaces.IStep#cancel(org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext, org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer, org.eclipse.tcf.te.runtime.stepper.interfaces.IFullQualifiedId, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void cancel(IStepContext context, IPropertiesContainer data, IFullQualifiedId fullQualifiedId, IProgressMonitor monitor) { + } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/callback/Callback.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/callback/Callback.java index 747ccfa0b..f861cbf11 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/callback/Callback.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/callback/Callback.java @@ -53,11 +53,11 @@ public class Callback extends PropertiesContainer implements ICallback { * Condition tester for ExecutorsUtil to check whether the callback is done * or the {@link IProgressMonitor} is canceled. */ - private class CallbackDoneConditionTester implements IConditionTester { - final ICallback callback; - final IProgressMonitor monitor; - int cancelTimeout = -1; - long cancelTime = -1; + public static class CallbackDoneConditionTester implements IConditionTester { + protected final ICallback callback; + protected final IProgressMonitor monitor; + protected int cancelTimeout = -1; + protected long cancelTime = -1; /** * Constructor. diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/steps/ITcfStepAttributes.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/steps/ITcfStepAttributes.java index 6c86f7e18..487a097cd 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/steps/ITcfStepAttributes.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/steps/ITcfStepAttributes.java @@ -1,27 +1,32 @@ -/*******************************************************************************
- * Copyright (c) 2013 Wind River Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the terms
- * of the Eclipse Public License v1.0 which accompanies this distribution, and is
- * available at http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.tcf.te.tcf.core.interfaces.steps;
-
-
-/**
- * Defines locator related step data attribute id's.
- */
-public interface ITcfStepAttributes {
-
- /**
- * Define the prefix used by all other attribute id's as prefix.
- */
- public static final String ATTR_PREFIX = "org.eclipse.tcf.te.tcf.locator"; //$NON-NLS-1$
-
- /**
- * Launch configuration attribute: The TCF channel.
- */
- public static final String ATTR_CHANNEL = ITcfStepAttributes.ATTR_PREFIX + ".channel"; //$NON-NLS-1$
-}
+/******************************************************************************* + * Copyright (c) 2013 Wind River Systems, Inc. and others. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.tcf.core.interfaces.steps; + + +/** + * Defines locator related step data attribute id's. + */ +public interface ITcfStepAttributes { + + /** + * Define the prefix used by all other attribute id's as prefix. + */ + public static final String ATTR_PREFIX = "org.eclipse.tcf.te.tcf.locator"; //$NON-NLS-1$ + + /** + * Launch configuration attribute: The TCF channel. + */ + public static final String ATTR_CHANNEL = ITcfStepAttributes.ATTR_PREFIX + ".channel"; //$NON-NLS-1$ + + /** + * Launch configuration attribute: The token for a running TCF command. + */ + public static final String ATTR_RUNNING_TOKEN = ITcfStepAttributes.ATTR_PREFIX + ".running_token"; //$NON-NLS-1$ +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/steps/AbstractPeerStep.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/steps/AbstractPeerStep.java index 5a077ecfa..cd679dc5b 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/steps/AbstractPeerStep.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/steps/AbstractPeerStep.java @@ -1,45 +1,68 @@ -/*******************************************************************************
- * Copyright (c) 2013 Wind River Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the terms
- * of the Eclipse Public License v1.0 which accompanies this distribution, and is
- * available at http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Wind River Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.tcf.te.tcf.core.steps;
-
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.tcf.protocol.IPeer;
-import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer;
-import org.eclipse.tcf.te.runtime.stepper.interfaces.IFullQualifiedId;
-import org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext;
-import org.eclipse.tcf.te.runtime.stepper.steps.AbstractStep;
-
-/**
- * Abstract peer context step
- */
-public abstract class AbstractPeerStep extends AbstractStep {
-
- /**
- * Returns the active peer context that is currently used.
- *
- * @param context The step context. Must not be <code>null</code>.
- * @param data The data giving object. Must not be <code>null</code>.
- * @param fullQualifiedId The full qualfied id for this step. Must not be <code>null</code>.
- * @return The active peer context.
- */
- protected IPeer getActivePeerContext(IStepContext context, IPropertiesContainer data, IFullQualifiedId fullQualifiedId) {
- Object activeContext = getActiveContext(context, data, fullQualifiedId);
- IPeer peer = null;
- if (activeContext instanceof IPeer)
- return (IPeer)activeContext;
- if (activeContext instanceof IAdaptable)
- peer = (IPeer)((IAdaptable)activeContext).getAdapter(IPeer.class);
- if (peer == null)
- peer = (IPeer)Platform.getAdapterManager().getAdapter(activeContext, IPeer.class);
-
- return peer;
- }
-}
+/******************************************************************************* + * Copyright (c) 2013 Wind River Systems, Inc. and others. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.tcf.core.steps; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.tcf.protocol.IPeer; +import org.eclipse.tcf.protocol.IToken; +import org.eclipse.tcf.protocol.Protocol; +import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer; +import org.eclipse.tcf.te.runtime.stepper.StepperAttributeUtil; +import org.eclipse.tcf.te.runtime.stepper.interfaces.IFullQualifiedId; +import org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext; +import org.eclipse.tcf.te.runtime.stepper.steps.AbstractStep; +import org.eclipse.tcf.te.tcf.core.interfaces.steps.ITcfStepAttributes; + +/** + * Abstract peer context step + */ +public abstract class AbstractPeerStep extends AbstractStep { + + /** + * Returns the active peer context that is currently used. + * + * @param context The step context. Must not be <code>null</code>. + * @param data The data giving object. Must not be <code>null</code>. + * @param fullQualifiedId The full qualfied id for this step. Must not be <code>null</code>. + * @return The active peer context. + */ + protected IPeer getActivePeerContext(IStepContext context, IPropertiesContainer data, IFullQualifiedId fullQualifiedId) { + Object activeContext = getActiveContext(context, data, fullQualifiedId); + IPeer peer = null; + if (activeContext instanceof IPeer) + return (IPeer)activeContext; + if (activeContext instanceof IAdaptable) + peer = (IPeer)((IAdaptable)activeContext).getAdapter(IPeer.class); + if (peer == null) + peer = (IPeer)Platform.getAdapterManager().getAdapter(activeContext, IPeer.class); + + return peer; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.runtime.stepper.steps.AbstractStep#cancel(org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext, org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer, org.eclipse.tcf.te.runtime.stepper.interfaces.IFullQualifiedId, org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void cancel(IStepContext context, IPropertiesContainer data, IFullQualifiedId fullQualifiedId, IProgressMonitor monitor) { + super.cancel(context, data, fullQualifiedId, monitor); + final IToken token = (IToken)StepperAttributeUtil.getProperty(ITcfStepAttributes.ATTR_RUNNING_TOKEN, fullQualifiedId, data); + StepperAttributeUtil.setProperty(ITcfStepAttributes.ATTR_RUNNING_TOKEN, fullQualifiedId, data, null); + if (token != null) { + Protocol.invokeLater(new Runnable() { + @Override + public void run() { + token.cancel(); + } + }); + } + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/interfaces/launcher/IProcessLauncher.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/interfaces/launcher/IProcessLauncher.java index 93c334b25..34d06993b 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/interfaces/launcher/IProcessLauncher.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/interfaces/launcher/IProcessLauncher.java @@ -52,6 +52,13 @@ public interface IProcessLauncher extends IAdaptable { public static String PROP_PROCESS_ARGS = "process.args"; //$NON-NLS-1$ /** + * Property specify the process arguments should be used as is. + * if <code>False</code>, the process image name would be added as the first argument if not already set. + * The property type is {@link Boolean}. + */ + public static String PROP_USE_PROCESS_ARGS_AS_IS = "use.process.args.as.is"; //$NON-NLS-1$ + + /** * Property denoting the process working directory. * <p> * The property type is {@link String}. @@ -59,6 +66,13 @@ public interface IProcessLauncher extends IAdaptable { public static String PROP_PROCESS_CWD = "process.cwd"; //$NON-NLS-1$ /** + * Property specify the process working directory should be used as is. + * if <code>False</code>, an empty cwd would be replaced by the path of the process image. + * The property type is {@link Boolean}. + */ + public static String PROP_USE_PROCESS_CWD_AS_IS = "use.process.cwd.as.is"; //$NON-NLS-1$ + + /** * Property denoting the process environment. * <p> * The property type is {@link Map}< {@link String}, {@link String} >. @@ -131,4 +145,9 @@ public interface IProcessLauncher extends IAdaptable { * Terminates the launched remote process (if still running). */ public void terminate(); + + /** + * Cancels a remote process launch (if callback was not already sent) + */ + public void cancel(); } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java index 524693020..18ccf3346 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java @@ -99,6 +99,9 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher // The streams proxy instance private IProcessStreamsProxy streamsProxy = null; + // The active token. + IToken activeToken = null; + /** * Constructor. */ @@ -200,6 +203,23 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher else Protocol.invokeAndWait(runnable); } + /* (non-Javadoc) + * @see org.eclipse.tcf.te.tcf.processes.core.interfaces.launcher.IProcessLauncher#cancel() + */ + @Override + public void cancel() { + if (activeToken != null && (callback == null || !callback.isDone())) { + final IToken token = activeToken; + activeToken = null; + Protocol.invokeLater(new Runnable() { + @Override + public void run() { + token.cancel(); + } + }); + } + } + /** * Check if the process context really died after sending SIGTERM. * <p> @@ -811,19 +831,23 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher // Get the process attributes String processPath = properties.getStringProperty(IProcessLauncher.PROP_PROCESS_PATH); + Boolean processArgsAsIs = (Boolean)properties.getProperty(IProcessLauncher.PROP_USE_PROCESS_ARGS_AS_IS); String[] processArgs = (String[])properties.getProperty(IProcessLauncher.PROP_PROCESS_ARGS); // Assure that the first argument is the process path itself if (!(processArgs != null && processArgs.length > 0 && processPath.equals(processArgs[0]))) { // Prepend the process path to the list of arguments List<String> args = processArgs != null ? new ArrayList<String>(Arrays.asList(processArgs)) : new ArrayList<String>(); - args.add(0, processPath); + if (processArgsAsIs == null || !processArgsAsIs.booleanValue()) { + args.add(0, processPath); + } processArgs = args.toArray(new String[args.size()]); } + Boolean processCWDAsIs = (Boolean)properties.getProperty(IProcessLauncher.PROP_USE_PROCESS_CWD_AS_IS); String processCWD = properties.getStringProperty(IProcessLauncher.PROP_PROCESS_CWD); // If the process working directory is not explicitly set, default to the process path directory if (processCWD == null || "".equals(processCWD.trim())) { //$NON-NLS-1$ - processCWD = new Path(processPath).removeLastSegments(1).toString(); + processCWD = (processCWDAsIs == null || !processCWDAsIs.booleanValue()) ? new Path(processPath).removeLastSegments(1).toString() : ""; //$NON-NLS-1$ } // Merge the initial process environment and the desired process environment @@ -869,9 +893,10 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher params.put(IProcessesV1.START_USE_TERMINAL, Boolean.valueOf(processConsole)); } - ((IProcessesV1)getSvcProcesses()).start(processCWD, processPath, processArgs, processEnv, params, new IProcesses.DoneStart() { + activeToken = ((IProcessesV1)getSvcProcesses()).start(processCWD, processPath, processArgs, processEnv, params, new IProcesses.DoneStart() { @Override public void doneStart(IToken token, Exception error, ProcessContext process) { + activeToken = null; if (error != null) { // Construct the error message to show to the user String message = NLS.bind(Messages.ProcessLauncher_error_processLaunchFailed, @@ -890,9 +915,10 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher } }); } else { - getSvcProcesses().start(processCWD, processPath, processArgs, processEnv, attach, new IProcesses.DoneStart() { + activeToken = getSvcProcesses().start(processCWD, processPath, processArgs, processEnv, attach, new IProcesses.DoneStart() { @Override public void doneStart(IToken token, Exception error, ProcessContext process) { + activeToken = null; if (error != null) { // Construct the error message to show to the user String message = NLS.bind(Messages.ProcessLauncher_error_processLaunchFailed, diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/navigator/runtime/ContentProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/navigator/runtime/ContentProvider.java index 841478d96..abe6bd711 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/navigator/runtime/ContentProvider.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/navigator/runtime/ContentProvider.java @@ -247,7 +247,7 @@ public class ContentProvider implements ITreeContentProvider { @Override public void run() { IProcessContextNode child = (IProcessContextNode)children[0]; - if (context.getSysMonitorContext().getPID() == child.getSysMonitorContext().getPID()) { + if (child != null && context.getSysMonitorContext().getPID() == child.getSysMonitorContext().getPID()) { if (context.getName() != null) { selected.set(!context.getName().equals(child.getName())); } |