Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Stieber2013-09-25 05:11:06 -0400
committerUwe Stieber2013-09-25 05:20:35 -0400
commitc475011b8458748eb9bea179426603c6d13aac90 (patch)
tree51f648e8a60b8f87b2c07bfe607b19759a0440ff /target_explorer
parentda300dd2f5c3e92a0fbd255a1faed7ca57bd231f (diff)
downloadorg.eclipse.tcf-c475011b8458748eb9bea179426603c6d13aac90.tar.gz
org.eclipse.tcf-c475011b8458748eb9bea179426603c6d13aac90.tar.xz
org.eclipse.tcf-c475011b8458748eb9bea179426603c6d13aac90.zip
Target Explorer: Fix attach to context handling
If selecting two or more contexts in either the process monitor or the system management view tree, attaching to those contexts led to more than one launch.
Diffstat (limited to 'target_explorer')
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.ui/plugin.properties5
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.ui/plugin.xml9
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/steps/AttachStep.java206
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/nls/Messages.java9
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/nls/Messages.properties9
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/handler/AttachHandler.java125
6 files changed, 195 insertions, 168 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/plugin.properties b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/plugin.properties
index f717c26b7..ecddd56d3 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/plugin.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/plugin.properties
@@ -1,5 +1,5 @@
##################################################################################
-# Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. All rights reserved.
+# Copyright (c) 2011, 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
@@ -17,9 +17,6 @@ ExtensionPoint.tabs.name=Launch Configuration Tabs Extension Point
# ***** Command Contributions *****
-command.showInDebugView.name=Show in Debug View Command
-command.showInDebugView.description=Show the selected context in the Debug View
-
command.attach.name=Attach Context Command
command.attach.description=Attach to the selected Context
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/plugin.xml
index 6602c80e6..4124822cc 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/plugin.xml
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/plugin.xml
@@ -545,12 +545,6 @@
<extension point="org.eclipse.ui.commands">
<command
categoryId="org.eclipse.tcf.te.ui.commands.category"
- description="%command.showInDebugView.description"
- id="org.eclipse.tcf.te.launch.command.showInDebugView"
- helpContextId="org.eclipse.tcf.te.launch.command_ShowInDebugView"
- name="%command.showInDebugView.name"/>
- <command
- categoryId="org.eclipse.tcf.te.ui.commands.category"
description="%command.attach.description"
id="org.eclipse.tcf.te.launch.command.attach"
helpContextId="org.eclipse.tcf.te.launch.command_Attach"
@@ -586,9 +580,6 @@
icon="platform:/plugin/org.eclipse.debug.ui/icons/full/etool16/debug_exc.gif"
disabledIcon="platform:/plugin/org.eclipse.debug.ui/icons/full/dtool16/debug_exc.gif"/>
<image
- commandId="org.eclipse.tcf.te.launch.command.showInDebugView"
- icon="platform:/plugin/org.eclipse.debug.ui/icons/full/eview16/debug_view.gif"/>
- <image
commandId="org.eclipse.tcf.te.launch.command.attach"
disabledIcon="icons/dlcl16/attach.gif"
icon="icons/elcl16/attach.gif"/>
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/steps/AttachStep.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/steps/AttachStep.java
index 57b334213..a803f87a9 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/steps/AttachStep.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/steps/AttachStep.java
@@ -9,6 +9,10 @@
*******************************************************************************/
package org.eclipse.tcf.te.tcf.processes.core.model.steps;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
@@ -18,6 +22,7 @@ import org.eclipse.tcf.protocol.IToken;
import org.eclipse.tcf.protocol.Protocol;
import org.eclipse.tcf.services.IProcesses;
import org.eclipse.tcf.services.IProcesses.ProcessContext;
+import org.eclipse.tcf.te.core.async.AsyncCallbackCollector;
import org.eclipse.tcf.te.runtime.callback.Callback;
import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback;
import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer;
@@ -29,6 +34,7 @@ import org.eclipse.tcf.te.runtime.statushandler.StatusHandlerManager;
import org.eclipse.tcf.te.runtime.statushandler.interfaces.IStatusHandler;
import org.eclipse.tcf.te.runtime.statushandler.interfaces.IStatusHandlerConstants;
import org.eclipse.tcf.te.tcf.core.Tcf;
+import org.eclipse.tcf.te.tcf.core.async.CallbackInvocationDelegate;
import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager;
import org.eclipse.tcf.te.tcf.core.model.interfaces.IModel;
import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelRefreshService;
@@ -44,111 +50,143 @@ import org.eclipse.tcf.te.tcf.processes.core.nls.Messages;
public class AttachStep {
/**
- * Attach to the given process context.
+ * Attach to the given list of process context nodes of the given peer model node.
* <p>
* <b>Note:</b> This method must be called from within the TCF dispatch thread.
*
- * @param node The context. Must not be <code>null</code>.
+ * @param peerModel The peer model. Must not be <code>null</code>.
+ * @param nodes The list of process context nodes. Must not be <code>null</code>.
* @param callback The callback to invoke once the operation completed, or<code>null</code>.
*/
- public void executeAttach(final IProcessContextNode node, final ICallback callback) {
+ public void executeAttach(final IPeerModel peerModel, final IProcessContextNode[] nodes, final ICallback callback) {
Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
- Assert.isNotNull(node);
-
- // If the context is already attached, there is nothing to do
- if (node.getProcessContext() != null && !node.getProcessContext().isAttached()) {
- IPeerModel peerNode = (IPeerModel)node.getAdapter(IPeerModel.class);
- if (peerNode != null) {
- // Determine the debug service to attach to the peer node
- IDebugService dbgService = ServiceManager.getInstance().getService(peerNode, IDebugService.class, false);
- if (dbgService != null) {
- // Attach to the peer node first
- dbgService.attach(peerNode, new PropertiesContainer(), null, new Callback() {
- @Override
- protected void internalDone(Object caller, IStatus status) {
- callback.setProperty("launch", getProperty("launch")); //$NON-NLS-1$ //$NON-NLS-2$
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- doAttach(node, callback);
- }
- };
- if (Protocol.isDispatchThread()) runnable.run();
- else Protocol.invokeLater(runnable);
- }
- });
- } else {
- doAttach(node, callback);
- }
- } else {
- onError(node, Messages.AttachStep_error_connect, null, callback);
+ Assert.isNotNull(peerModel);
+ Assert.isNotNull(nodes);
+
+ // Determine if we have to execute the attach at all
+ final List<IProcessContextNode> nodesToAttach = new ArrayList<IProcessContextNode>();
+ for (IProcessContextNode node : nodes) {
+ IPeerModel parentPeerModel = (IPeerModel)node.getAdapter(IPeerModel.class);
+ if (!peerModel.equals(parentPeerModel)) continue;
+
+ // If not yet attached, we have to attach to it
+ if (node.getProcessContext() != null && !node.getProcessContext().isAttached()) {
+ if (!nodesToAttach.contains(node)) nodesToAttach.add(node);
}
- } else {
- if (node.getProcessContext() == null) {
- onError(node, Messages.AttachStep_error_connect, null, callback);
+ }
+
+ // Anything to attach?
+ if (!nodesToAttach.isEmpty()) {
+ // Determine the debug service to attach to the peer node
+ IDebugService dbgService = ServiceManager.getInstance().getService(peerModel, IDebugService.class, false);
+ if (dbgService != null) {
+ // Attach to the peer node first
+ dbgService.attach(peerModel, new PropertiesContainer(), null, new Callback() {
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ callback.setProperty("launch", getProperty("launch")); //$NON-NLS-1$ //$NON-NLS-2$
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ doAttach(peerModel, Collections.unmodifiableList(nodesToAttach), callback);
+ }
+ };
+ if (Protocol.isDispatchThread()) runnable.run();
+ else Protocol.invokeLater(runnable);
+ }
+ });
} else {
- onDone(callback);
+ doAttach(peerModel, Collections.unmodifiableList(nodesToAttach), callback);
}
+ } else {
+ onDone(callback);
}
+
}
/**
- * Opens a channel and perform the attach to the given context node.
+ * Opens a channel and perform the attach to the given process context nodes.
* <p>
* <b>Note:</b> This method must be called from within the TCF dispatch thread.
*
- * @param node The context node. Must not be <code>null</code>.
+ * @param peerModel The peer model. Must not be <code>null</code>.
+ * @param nodes The process context node. Must not be <code>null</code>.
* @param callback The callback to invoke once the operation completed, or<code>null</code>.
*/
- protected void doAttach(final IProcessContextNode node, final ICallback callback) {
+ protected void doAttach(final IPeerModel peerModel, final List<IProcessContextNode> nodes, final ICallback callback) {
Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
- Assert.isNotNull(node);
-
- // Determine the peer model node
- final IPeerModel peerNode = (IPeerModel)node.getAdapter(IPeerModel.class);
-
- // Open a channel
- Tcf.getChannelManager().openChannel(peerNode.getPeer(), null, new IChannelManager.DoneOpenChannel() {
- @Override
- public void doneOpenChannel(final Throwable error, final IChannel channel) {
- if (error == null) {
- final IProcesses service = channel.getRemoteService(IProcesses.class);
- if (service != null) {
- service.getContext(node.getStringProperty(IModelNode.PROPERTY_ID), new IProcesses.DoneGetContext() {
- @Override
- public void doneGetContext(IToken token, Exception error, ProcessContext context) {
- if (error == null && context != null) {
- context.attach(new IProcesses.DoneCommand() {
- @Override
- public void doneCommand(IToken token, Exception error) {
- if (error == null) {
- // We are attached now, trigger a refresh of the node
- IModel model = node.getParent(IModel.class);
- Assert.isNotNull(model);
- model.getService(IModelRefreshService.class).refresh(node, new Callback() {
- @Override
- protected void internalDone(Object caller, IStatus status) {
- onDone(callback);
+ Assert.isNotNull(peerModel);
+ Assert.isNotNull(nodes);
+
+ // Loop the nodes and attach to them
+ if (!nodes.isEmpty()) {
+ // Open a channel
+ Tcf.getChannelManager().openChannel(peerModel.getPeer(), null, new IChannelManager.DoneOpenChannel() {
+ @Override
+ public void doneOpenChannel(final Throwable error, final IChannel channel) {
+ if (error == null) {
+ final IProcesses service = channel.getRemoteService(IProcesses.class);
+ if (service != null) {
+ // Create the callback collector
+ AsyncCallbackCollector collector = new AsyncCallbackCollector(new Callback() {
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ if (status.getSeverity() == IStatus.ERROR) {
+ onError(peerModel, status.getMessage(), status.getException(), callback);
+ } else {
+ onDone(callback);
+ }
+ }
+ }, new CallbackInvocationDelegate());
+
+ for (final IProcessContextNode node: nodes) {
+ final ICallback callback2 = new AsyncCallbackCollector.SimpleCollectorCallback(collector);
+ service.getContext(node.getStringProperty(IModelNode.PROPERTY_ID), new IProcesses.DoneGetContext() {
+ @Override
+ public void doneGetContext(IToken token, Exception error, ProcessContext context) {
+ if (error == null && context != null) {
+ context.attach(new IProcesses.DoneCommand() {
+ @Override
+ public void doneCommand(IToken token, Exception error) {
+ if (error == null) {
+ // We are attached now, trigger a refresh of the node
+ IModel model = node.getParent(IModel.class);
+ Assert.isNotNull(model);
+ model.getService(IModelRefreshService.class).refresh(node, new Callback() {
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ callback2.done(AttachStep.this, Status.OK_STATUS);
+ }
+ });
+ } else {
+ IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(),
+ NLS.bind(Messages.AttachStep_error_attach, node.getName()), error);
+ callback2.done(AttachStep.this, status);
}
- });
- } else {
- onError(node, Messages.AttachStep_error_attach, error, callback);
- }
+ }
+ });
+ } else {
+ IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(),
+ NLS.bind(Messages.AttachStep_error_getContext, node.getName()), error);
+ callback2.done(AttachStep.this, status);
}
- });
- } else {
- onError(node, Messages.AttachStep_error_getContext, error, callback);
- }
+ }
+ });
}
- });
+
+ // Mark the collector initialization done
+ collector.initDone();
+ } else {
+ onError(peerModel, NLS.bind(Messages.AttachStep_error_missingService, peerModel.getName()), null, callback);
+ }
} else {
- onError(node, Messages.AttachStep_error_connect, null, callback);
+ onError(peerModel, NLS.bind(Messages.AttachStep_error_openChannel, peerModel.getName()), error, callback);
}
- } else {
- onError(node, Messages.AttachStep_error_openChannel, error, callback);
}
- }
- });
+ });
+ } else {
+ onDone(callback);
+ }
}
/**
@@ -170,8 +208,12 @@ public class AttachStep {
}
String fullMessage = message;
- if (fullMessage != null) fullMessage = NLS.bind(fullMessage, detailMessage != null ? detailMessage : ""); //$NON-NLS-1$
- else fullMessage = detailMessage;
+ if (fullMessage != null && detailMessage != null) {
+ fullMessage += NLS.bind(Messages.AttachStep_error_possibleCause, detailMessage);
+ }
+ else if (fullMessage == null) {
+ fullMessage = detailMessage;
+ }
if (fullMessage != null) {
IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), fullMessage, error);
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/nls/Messages.java
index 76a103c07..231162619 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/nls/Messages.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/nls/Messages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -52,10 +52,11 @@ public class Messages extends NLS {
public static String PendingOperation_label;
- public static String AttachStep_error_connect;
- public static String AttachStep_error_attach;
- public static String AttachStep_error_getContext;
+ public static String AttachStep_error_possibleCause;
+ public static String AttachStep_error_missingService;
public static String AttachStep_error_openChannel;
+ public static String AttachStep_error_getContext;
+ public static String AttachStep_error_attach;
public static String AttachStep_error_title;
public static String DetachStep_error_title;
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/nls/Messages.properties
index 4c2f77404..dd06d09dc 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/nls/Messages.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/nls/Messages.properties
@@ -31,10 +31,11 @@ ProcessStreamReaderRunnable_error_appendFailed=Failed to append data from stream
PendingOperation_label=Pending...
-AttachStep_error_connect=Failed to attach to context: {0}
-AttachStep_error_attach=Failed to attach context: {0}
-AttachStep_error_getContext=Failed to get context: {0}
-AttachStep_error_openChannel=Failed to open channel: {0}
+AttachStep_error_possibleCause=\n\nPossible Cause:\n{0}
+AttachStep_error_missingService=Failed to attach to selected context(s). The required service is missing on target ''{0}''.
+AttachStep_error_openChannel=Failed to attach to selected context(s). A channel to target ''{0}'' cannot be opened.
+AttachStep_error_getContext=Failed to query properties for context ''{0}''.
+AttachStep_error_attach=Failed to attach to context ''{0}''.
AttachStep_error_title=Error
DetachStep_error_title=Error
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/handler/AttachHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/handler/AttachHandler.java
index d36091918..88c076a9c 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/handler/AttachHandler.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/handler/AttachHandler.java
@@ -9,30 +9,25 @@
*******************************************************************************/
package org.eclipse.tcf.te.tcf.processes.ui.handler;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.commands.ParameterizedCommand;
-import org.eclipse.core.expressions.EvaluationContext;
import org.eclipse.core.runtime.Assert;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.tcf.protocol.Protocol;
import org.eclipse.tcf.te.runtime.callback.Callback;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNode;
import org.eclipse.tcf.te.tcf.processes.core.model.steps.AttachStep;
-import org.eclipse.tcf.te.tcf.processes.ui.activator.UIPlugin;
-import org.eclipse.ui.ISources;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.handlers.HandlerUtil;
-import org.eclipse.ui.handlers.IHandlerService;
/**
* Attach to process command handler implementation.
@@ -46,76 +41,76 @@ public class AttachHandler extends AbstractHandler {
public Object execute(final ExecutionEvent event) throws ExecutionException {
final ISelection selection = HandlerUtil.getCurrentSelection(event);
if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
- Iterator<?> iterator = ((IStructuredSelection)selection).iterator();
- while (iterator.hasNext()) {
- final Object candidate = iterator.next();
- if (candidate instanceof IProcessContextNode) {
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- IProcessContextNode node = (IProcessContextNode)candidate;
- doAttach(event, node);
- }
- };
-
- Protocol.invokeLater(runnable);
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ execute(event, (IStructuredSelection)selection);
}
- }
+ };
+
+ Protocol.invokeLater(runnable);
}
return null;
}
/**
- * Executes the attach to the given node.
+ * Executes the attach for the given selection.
* <p>
* <b>Note:</b> This method must be called from within the TCF dispatch thread.
*
* @param event The execution event.
- * @param node The context to attach. Must not be <code>null</code>.
+ * @param selection The selection. Must not be <code>null</code>.
*/
- protected void doAttach(final ExecutionEvent event, final IProcessContextNode node) {
+ protected void execute(final ExecutionEvent event, final IStructuredSelection selection) {
Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
- Assert.isNotNull(node);
-
- AttachStep step = new AttachStep();
- step.executeAttach(node, new Callback() {
- @Override
- protected void internalDone(Object caller, IStatus status) {
- if (status.getSeverity() == IStatus.OK) {
- // Get the launch instance from the callback properties
- Object launch = getProperty("launch"); //$NON-NLS-1$
- if (launch != null) {
- ICommandService service = (ICommandService)PlatformUI.getWorkbench().getService(ICommandService.class);
- Command command = service != null ? service.getCommand("org.eclipse.tcf.te.launch.command.showInDebugView") : null; //$NON-NLS-1$
- if (command != null && command.isDefined() && command.isEnabled()) {
- try {
- IHandlerService handlerSvc = (IHandlerService)PlatformUI.getWorkbench().getService(IHandlerService.class);
- Assert.isNotNull(handlerSvc);
-
- ISelection selection = HandlerUtil.getCurrentSelection(event);
- EvaluationContext ctx = new EvaluationContext(handlerSvc.getCurrentState(), selection);
- ctx.addVariable("launch", launch); //$NON-NLS-1$
- ctx.addVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME, selection);
- ctx.addVariable(ISources.ACTIVE_MENU_SELECTION_NAME, selection);
- ctx.setAllowPluginActivation(true);
-
- ParameterizedCommand pCmd = ParameterizedCommand.generateCommand(command, null);
- Assert.isNotNull(pCmd);
-
- handlerSvc.executeCommandInContext(pCmd, null, ctx);
- } catch (Exception e) {
- // If the platform is in debug mode, we print the exception to the log view
- if (Platform.inDebugMode()) {
- status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), e.getMessage(), e);
- UIPlugin.getDefault().getLog().log(status);
- }
- }
- }
+ Assert.isNotNull(selection);
+ // Analyze the selection and collect all nodes per parent peer model node.
+ final Map<IPeerModel, List<IProcessContextNode>> contexts = new HashMap<IPeerModel, List<IProcessContextNode>>();
+ Iterator<?> iterator = selection.iterator();
+ while (iterator.hasNext()) {
+ Object candidate = iterator.next();
+ if (candidate instanceof IProcessContextNode) {
+ IProcessContextNode node = (IProcessContextNode)candidate;
+ IPeerModel peerModel = (IPeerModel)node.getAdapter(IPeerModel.class);
+ if (peerModel != null) {
+ List<IProcessContextNode> nodes = contexts.get(peerModel);
+ if (nodes == null) {
+ nodes = new ArrayList<IProcessContextNode>();
+ contexts.put(peerModel, nodes);
}
+ if (!nodes.contains(node)) nodes.add(node);
}
}
- });
+ }
+
+ // If not empty, attach to all nodes of the original selection per parent peer model node.
+ if (!contexts.isEmpty()) {
+ for (Entry<IPeerModel, List<IProcessContextNode>> entry : contexts.entrySet()) {
+ IPeerModel peerModel = entry.getKey();
+ List<IProcessContextNode> nodes = entry.getValue();
+ doAttach(event, peerModel, nodes.toArray(new IProcessContextNode[nodes.size()]));
+ }
+ }
+ }
+
+ /**
+ * Executes the attach to the given process context nodes.
+ * <p>
+ * <b>Note:</b> This method must be called from within the TCF dispatch thread.
+ *
+ * @param event The execution event.
+ * @param nodes The list of process context nodes. Must not be <code>null</code>.
+ */
+ protected void doAttach(final ExecutionEvent event, final IPeerModel peerModel, final IProcessContextNode[] nodes) {
+ Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
+ Assert.isNotNull(peerModel);
+ Assert.isNotNull(nodes);
+
+ if (nodes.length > 0) {
+ AttachStep step = new AttachStep();
+ step.executeAttach(peerModel, nodes, new Callback());
+ }
}
}

Back to the top