diff options
author | Uwe Stieber | 2013-01-19 05:56:30 +0000 |
---|---|---|
committer | Uwe Stieber | 2013-01-19 05:56:30 +0000 |
commit | b49dd63777380a0cd0d53202c3a882f30d7f3d9a (patch) | |
tree | bc3173249d87f8064463d86ff4d0edb5e419d8eb /target_explorer | |
parent | b17c812c54b20b866170bef7a2ccaecc72a0bf94 (diff) | |
download | org.eclipse.tcf-b49dd63777380a0cd0d53202c3a882f30d7f3d9a.tar.gz org.eclipse.tcf-b49dd63777380a0cd0d53202c3a882f30d7f3d9a.tar.xz org.eclipse.tcf-b49dd63777380a0cd0d53202c3a882f30d7f3d9a.zip |
Target Explorer: Fix Bugzilla 398504 - [SysMonitor] Provide command line for each process
Diffstat (limited to 'target_explorer')
8 files changed, 240 insertions, 53 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/listener/LocatorListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/listener/LocatorListener.java index 19f355761..7ff7c2237 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/listener/LocatorListener.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/listener/LocatorListener.java @@ -219,7 +219,7 @@ public class LocatorListener implements ILocator.LocatorListener { newId.append(id.substring(endIndex)); // Try the lookup again - peerNode = model.getService(ILocatorModelLookupService.class).lkupPeerModelById(id); + peerNode = model.getService(ILocatorModelLookupService.class).lkupPeerModelById(newId.toString()); } // If the model node is found in the model, process the removal. diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/IProcessContextNodeProperties.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/IProcessContextNodeProperties.java index 3de43db7a..6943f6ef0 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/IProcessContextNodeProperties.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/IProcessContextNodeProperties.java @@ -25,4 +25,9 @@ public interface IProcessContextNodeProperties { * The context name. If set, used in the UI to represent the context node. */ public static final String PROPERTY_NAME = IModelNode.PROPERTY_NAME; + + /** + * The command line of the context. The command line is a string array. + */ + public static final String PROPERTY_CMD_LINE = "cmdline"; //$NON-NLS-1$ } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelRefreshService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelRefreshService.java index d0afad1aa..84e693c95 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelRefreshService.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelRefreshService.java @@ -260,12 +260,20 @@ public class RuntimeModelRefreshService extends AbstractModelService<IRuntimeMod public void doneGetContext(IToken token, Exception error, SysMonitorContext context) { ((IProcessContextNode)node).setSysMonitorContext(context); - // Get the process context - service.getContext(contextId, new IProcesses.DoneGetContext() { + // Get the command line of the context + sysMonService.getCommandLine(contextId, new ISysMonitor.DoneGetCommandLine() { @Override - public void doneGetContext(IToken token, Exception error, IProcesses.ProcessContext context) { - ((IProcessContextNode)node).setProcessContext(context); - callback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); + public void doneGetCommandLine(IToken token, Exception error, String[] cmd_line) { + node.setProperty(IProcessContextNodeProperties.PROPERTY_CMD_LINE, error == null ? cmd_line : null); + + // Get the process context + service.getContext(contextId, new IProcesses.DoneGetContext() { + @Override + public void doneGetContext(IToken token, Exception error, IProcesses.ProcessContext context) { + ((IProcessContextNode)node).setProcessContext(context); + callback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); + } + }); } }); } @@ -345,51 +353,59 @@ public class RuntimeModelRefreshService extends AbstractModelService<IRuntimeMod node.setType(parent == null ? TYPE.Process : TYPE.Thread); contexts.put(node.getUUID(), node); - // Query the corresponding process context - service.getContext(contextId, new IProcesses.DoneGetContext() { + // Get the command line of the context + sysMonService.getCommandLine(contextId, new ISysMonitor.DoneGetCommandLine() { @Override - public void doneGetContext(IToken token, Exception error, IProcesses.ProcessContext context) { - // Errors are ignored - node.setProcessContext(context); - if (context != null) node.setProperty(IProcessContextNodeProperties.PROPERTY_NAME, context.getName()); - - // Get the asynchronous refresh context adapter - final IAsyncRefreshableCtx refreshable = (IAsyncRefreshableCtx)node.getAdapter(IAsyncRefreshableCtx.class); - - // Refresh the children of the node if the depth is still larger than 0 - if (depth - 1 > 0 && (refreshable == null || !refreshable.getQueryState(QueryType.CHILD_LIST).equals(QueryState.IN_PROGRESS))) { - if (refreshable != null) { - // Mark the refresh as in progress - refreshable.setQueryState(QueryType.CHILD_LIST, QueryState.IN_PROGRESS); - // Create a new pending operation node and associate it with the refreshable - PendingOperationModelNode pendingNode = new PendingOperationNode(); - pendingNode.setParent(node); - refreshable.setPendingOperationNode(pendingNode); - } - - // Don't send change events while refreshing - final boolean changed = node.setChangeEventsEnabled(false); - // Initiate the refresh - List<IProcessContextNode> oldChildren = node.getChildren(IProcessContextNode.class); - refreshContextChildren(oldChildren, model, node, depth - 1, new Callback() { - @Override - protected void internalDone(Object caller, IStatus status) { - // Mark the refresh as done - refreshable.setQueryState(QueryType.CHILD_LIST, QueryState.DONE); - // Reset the pending operation node - refreshable.setPendingOperationNode(null); - // Re-enable the change events if they had been enabled before - if (changed) node.setChangeEventsEnabled(true); - // Trigger a refresh of the view content - ChangeEvent event = new ChangeEvent(node, IContainerModelNode.NOTIFY_CHANGED, null, null); - EventManager.getInstance().fireEvent(event); - // Finally invoke the callback + public void doneGetCommandLine(IToken token, Exception error, String[] cmd_line) { + node.setProperty(IProcessContextNodeProperties.PROPERTY_CMD_LINE, error == null ? cmd_line : null); + + // Query the corresponding process context + service.getContext(contextId, new IProcesses.DoneGetContext() { + @Override + public void doneGetContext(IToken token, Exception error, IProcesses.ProcessContext context) { + // Errors are ignored + node.setProcessContext(context); + if (context != null) node.setProperty(IProcessContextNodeProperties.PROPERTY_NAME, context.getName()); + + // Get the asynchronous refresh context adapter + final IAsyncRefreshableCtx refreshable = (IAsyncRefreshableCtx)node.getAdapter(IAsyncRefreshableCtx.class); + + // Refresh the children of the node if the depth is still larger than 0 + if (depth - 1 > 0 && (refreshable == null || !refreshable.getQueryState(QueryType.CHILD_LIST).equals(QueryState.IN_PROGRESS))) { + if (refreshable != null) { + // Mark the refresh as in progress + refreshable.setQueryState(QueryType.CHILD_LIST, QueryState.IN_PROGRESS); + // Create a new pending operation node and associate it with the refreshable + PendingOperationModelNode pendingNode = new PendingOperationNode(); + pendingNode.setParent(node); + refreshable.setPendingOperationNode(pendingNode); + } + + // Don't send change events while refreshing + final boolean changed = node.setChangeEventsEnabled(false); + // Initiate the refresh + List<IProcessContextNode> oldChildren = node.getChildren(IProcessContextNode.class); + refreshContextChildren(oldChildren, model, node, depth - 1, new Callback() { + @Override + protected void internalDone(Object caller, IStatus status) { + // Mark the refresh as done + refreshable.setQueryState(QueryType.CHILD_LIST, QueryState.DONE); + // Reset the pending operation node + refreshable.setPendingOperationNode(null); + // Re-enable the change events if they had been enabled before + if (changed) node.setChangeEventsEnabled(true); + // Trigger a refresh of the view content + ChangeEvent event = new ChangeEvent(node, IContainerModelNode.NOTIFY_CHANGED, null, null); + EventManager.getInstance().fireEvent(event); + // Finally invoke the callback + innerCallback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); + } + }); + } else { innerCallback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); } - }); - } else { - innerCallback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); - } + } + }); } }); } else { diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelUpdateService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelUpdateService.java index 95ff83016..33db65f67 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelUpdateService.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelUpdateService.java @@ -16,6 +16,7 @@ import org.eclipse.tcf.te.runtime.model.interfaces.contexts.IAsyncRefreshableCtx import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelUpdateService; import org.eclipse.tcf.te.tcf.core.model.services.AbstractModelService; import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNode; +import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNodeProperties; import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.runtime.IRuntimeModel; /** @@ -76,6 +77,7 @@ public class RuntimeModelUpdateService extends AbstractModelService<IRuntimeMode if (dst instanceof IProcessContextNode && src instanceof IProcessContextNode) { ((IProcessContextNode)dst).setSysMonitorContext(((IProcessContextNode)src).getSysMonitorContext()); ((IProcessContextNode)dst).setProcessContext(((IProcessContextNode)src).getProcessContext()); + dst.setProperty(IProcessContextNodeProperties.PROPERTY_CMD_LINE, src.getProperty(IProcessContextNodeProperties.PROPERTY_CMD_LINE)); } // Re-enable the change events diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/plugin.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/plugin.properties index 755ee20c1..8b308205a 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/plugin.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/plugin.properties @@ -26,6 +26,7 @@ column.name.pid = PID column.name.ppid = PPID column.name.state = State column.name.user = User +column.name.cmdline = Command Line navigatorContent.name = Processes diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/plugin.xml index fafe53bad..c8139601f 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/plugin.xml +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/plugin.xml @@ -580,7 +580,6 @@ moveable="true" name="%column.name.pid" resizable="true" - style="SWT.RIGHT" visible="true" width="50"> </column> @@ -591,8 +590,7 @@ moveable="true" name="%column.name.ppid" resizable="true" - style="SWT.RIGHT" - visible="true" + visible="false" width="50"> </column> <column @@ -602,7 +600,6 @@ moveable="true" name="%column.name.state" resizable="true" - style="SWT.RIGHT" visible="true" width="50"> </column> @@ -613,7 +610,16 @@ moveable="true" name="%column.name.user" resizable="true" - style="SWT.RIGHT" + visible="true" + width="50"> + </column> + <column + comparator="org.eclipse.tcf.te.tcf.processes.ui.editor.tree.columns.CommandLineComparator" + id="cmdline" + labelProvider="org.eclipse.tcf.te.tcf.processes.ui.editor.tree.columns.CommandLineLabelProvider" + moveable="true" + name="%column.name.cmdline" + resizable="true" visible="true" width="100"> </column> diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/editor/tree/columns/CommandLineComparator.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/editor/tree/columns/CommandLineComparator.java new file mode 100644 index 000000000..f27a9194c --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/editor/tree/columns/CommandLineComparator.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * 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.processes.ui.editor.tree.columns; + +import java.io.Serializable; +import java.util.Comparator; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.tcf.protocol.Protocol; +import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNode; +import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNodeProperties; + +/** + * The comparator for the tree column "Command Line". + */ +public class CommandLineComparator implements Comparator<IProcessContextNode> , Serializable { + private static final long serialVersionUID = 1L; + + /* (non-Javadoc) + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + @Override + public int compare(final IProcessContextNode o1, final IProcessContextNode o2) { + final AtomicReference<String> cmd1 = new AtomicReference<String>(); + final AtomicReference<String> cmdArgs1 = new AtomicReference<String>(); + final AtomicReference<String> cmd2 = new AtomicReference<String>(); + final AtomicReference<String> cmdArgs2 = new AtomicReference<String>(); + + Runnable runnable = new Runnable() { + @Override + public void run() { + String[] cmdline1 = (String[])o1.getProperty(IProcessContextNodeProperties.PROPERTY_CMD_LINE); + if (cmdline1 != null && cmdline1.length > 0) { + cmd1.set(cmdline1[0]); + String[] args = new String[cmdline1.length - 1]; + System.arraycopy(cmdline1, 1, args, 0, cmdline1.length - 1); + cmdArgs1.set(CommandLineLabelProvider.makeString(args)); + } + + String[] cmdline2 = (String[])o2.getProperty(IProcessContextNodeProperties.PROPERTY_CMD_LINE); + if (cmdline2 != null && cmdline2.length > 0) { + cmd2.set(cmdline2[0]); + String[] args = new String[cmdline2.length - 1]; + System.arraycopy(cmdline2, 1, args, 0, cmdline2.length - 1); + cmdArgs2.set(CommandLineLabelProvider.makeString(args)); + } + } + }; + + Assert.isTrue(!Protocol.isDispatchThread()); + Protocol.invokeAndWait(runnable); + + if (cmd1.get() == null) { + if (cmd2.get() == null) return 0; + return -1; + } + if (cmd2.get() == null) return 1; + + // Compare the commands first + int result = cmd1.get().compareTo(cmd2.get()); + // If equal, compare the arguments + if (result == 0) { + if (cmdArgs1.get() == null) { + if (cmdArgs2.get() == null) return 0; + return -1; + } + if (cmdArgs2.get() == null) return 1; + + result = cmdArgs1.get().compareTo(cmdArgs2.get()); + } + + return result; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/editor/tree/columns/CommandLineLabelProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/editor/tree/columns/CommandLineLabelProvider.java new file mode 100644 index 000000000..5417d8a58 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/editor/tree/columns/CommandLineLabelProvider.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * 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.processes.ui.editor.tree.columns; + +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.tcf.protocol.Protocol; +import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IPendingOperationNode; +import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNode; +import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNodeProperties; +import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.runtime.IRuntimeModel; + +/** + * The label provider for the tree column "Command Line". + */ +public class CommandLineLabelProvider extends LabelProvider { + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int) + */ + @Override + public String getText(Object element) { + if (element instanceof IRuntimeModel || element instanceof IPendingOperationNode) { + return ""; //$NON-NLS-1$ + } + + if (element instanceof IProcessContextNode) { + final IProcessContextNode node = (IProcessContextNode)element; + + final AtomicReference<String> cmd = new AtomicReference<String>(); + + Runnable runnable = new Runnable() { + @Override + public void run() { + String[] cmdline = (String[])node.getProperty(IProcessContextNodeProperties.PROPERTY_CMD_LINE); + if (cmdline != null) cmd.set(makeString(cmdline)); + } + }; + + Assert.isTrue(!Protocol.isDispatchThread()); + Protocol.invokeAndWait(runnable); + + if (cmd.get() != null) return cmd.get(); + } + + return ""; //$NON-NLS-1$ + } + + /** + * Makes a string from the given string array. + * + * @param cmdline The string array. Must not be <code>null</code>. + * @return The array as string. + */ + public final static String makeString(String[] cmdline) { + Assert.isNotNull(cmdline); + + StringBuilder buffer = new StringBuilder(); + for (String arg : cmdline) { + buffer.append(arg.contains(" ") ? "\"" + arg + "\"" : arg); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + buffer.append(" "); //$NON-NLS-1$ + } + + return buffer.toString(); + } +} |