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/plugins/org.eclipse.tcf.te.tcf.processes.core
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/plugins/org.eclipse.tcf.te.tcf.processes.core')
-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
3 files changed, 134 insertions, 90 deletions
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

Back to the top