Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2013-03-09 14:23:06 -0500
committerEugene Tarassov2013-03-09 14:23:06 -0500
commit560b6c1f33f035667c21940903ef17806c126173 (patch)
tree73a7aff5379fabf93d7daff4523fcd2b0ab7347f /plugins
parentd7b4a384b0a241fc473f7e58e12fcc2920b4bc33 (diff)
downloadorg.eclipse.tcf-560b6c1f33f035667c21940903ef17806c126173.tar.gz
org.eclipse.tcf-560b6c1f33f035667c21940903ef17806c126173.tar.xz
org.eclipse.tcf-560b6c1f33f035667c21940903ef17806c126173.zip
TCF Debugger: re-designed TCF launch configuration dialog:
1. The Target page is now first page in the dialog - target should be selected before other configuration steps. 2. New page added: Download. The page allows to download ELF files to the target during launch. 3. The Main page renamed to Application. 4. Implementation of context, process and remote file selection dialogs and controls is moved from o.e.tcf.cdt.ui to o.e.tcf.debug.ui, because it has no CDT dependencies.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/launch/TCFCDTLaunchDelegate.java3
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/disassembly/TCFDisassemblyBackend.java2
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/ProcessListControl.java505
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/ProcessPrompter.java16
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/RemoteCMainTab.java18
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/application_tab.gifbin0 -> 570 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/download_tab.gifbin0 -> 332 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java2
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ContextListControl.java653
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ContextSelection.java (renamed from plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/launch/ContextSelection.java)14
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ContextSelectionDialog.java (renamed from plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/ProcessSelectionDialog.java)83
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/DownloadFileDialog.java400
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/FileSystemBrowserControl.java (renamed from plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/FileSystemBrowserControl.java)4
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/PeerListControl.java (renamed from plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/PeerListControl.java)466
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/RemoteFileSelectionDialog.java (renamed from plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/RemoteFileSelectionDialog.java)8
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFDownloadTab.java361
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMainTab.java13
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPathMapTab.java4
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTabGroup.java3
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java619
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java8
-rw-r--r--plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java17
-rw-r--r--plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/ElfLoader.java470
-rw-r--r--plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java73
24 files changed, 2361 insertions, 1381 deletions
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/launch/TCFCDTLaunchDelegate.java b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/launch/TCFCDTLaunchDelegate.java
index f15b68f35..4c254cf5b 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/launch/TCFCDTLaunchDelegate.java
+++ b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/launch/TCFCDTLaunchDelegate.java
@@ -22,6 +22,7 @@ import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.tcf.internal.debug.launch.TCFLaunchDelegate;
import org.eclipse.tcf.internal.debug.model.TCFLaunch;
+import org.eclipse.tcf.internal.debug.ui.launch.ContextSelection;
import org.eclipse.tcf.util.TCFTask;
/**
@@ -90,7 +91,7 @@ public class TCFCDTLaunchDelegate extends TCFLaunchDelegate {
if (prompter != null) {
Object result = prompter.handleStatus(contextPrompt, config);
if (result instanceof ContextSelection) {
- return (ContextSelection) result;
+ return (ContextSelection)result;
}
}
return null;
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/disassembly/TCFDisassemblyBackend.java b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/disassembly/TCFDisassemblyBackend.java
index 51068758a..37df306f7 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/disassembly/TCFDisassemblyBackend.java
+++ b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/disassembly/TCFDisassemblyBackend.java
@@ -266,7 +266,7 @@ public class TCFDisassemblyBackend extends AbstractDisassemblyBackend {
done = true;
/* Don't call setUpdatePending() if pending state was reset by the view */
if (context_cnt != fContextCount) return;
- assert fCallback.getUpdatePending();
+ if (!fCallback.getUpdatePending()) return;
fCallback.setUpdatePending(false);
}
}
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/ProcessListControl.java b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/ProcessListControl.java
deleted file mode 100644
index 616329d6c..000000000
--- a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/ProcessListControl.java
+++ /dev/null
@@ -1,505 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011 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.internal.cdt.ui.launch;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.debug.ui.DebugUITools;
-import org.eclipse.debug.ui.IDebugUIConstants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeItem;
-import org.eclipse.tcf.protocol.IChannel;
-import org.eclipse.tcf.protocol.IChannel.IChannelListener;
-import org.eclipse.tcf.protocol.IPeer;
-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;
-
-public class ProcessListControl {
-
- private final class ProcessListener implements IProcesses.ProcessesListener {
- public void exited(final String process_id, int exit_code) {
- if (display != null) {
- display.asyncExec(new Runnable() {
- public void run() {
- ProcessInfo info = findProcessInfo(root_info, process_id);
- if (info != null && info.parent != null && info.parent.children != null) {
- info.parent.children = null;
- loadChildren(info.parent);
- }
- }
- });
- }
- }
- }
-
- static class ProcessInfo {
- String name;
- String id;
- boolean isContainer;
- ProcessInfo[] children;
- Throwable children_error;
- int index;
- boolean children_pending;
- ProcessInfo parent;
- protected boolean isAttached;
- }
-
- private Tree fProcessTree;
- private Display display;
- private IPeer fPeer;
- private final ProcessInfo root_info = new ProcessInfo();
- private IChannel fChannel;
- private IProcesses fProcesses;
- protected final ProcessListener fProcessListener = new ProcessListener();
- private String fContextToSelect;
- private LinkedList<String> fPathToSelect;
- private Composite fComposite;
-
- public ProcessListControl(Composite parent) {
- display = parent.getDisplay();
- parent.addDisposeListener(new DisposeListener() {
- public void widgetDisposed(DisposeEvent e) {
- handleDispose();
- }
- });
- createProcessListArea(parent);
- }
-
- public void setInput(IPeer peer) {
- if (peer == fPeer) {
- return;
- }
- if (fPeer != null) {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- disconnectPeer();
- }
- });
- }
- fProcessTree.setItemCount(0);
- root_info.children = null;
- fPeer = peer;
- if (fPeer != null) {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- connectPeer();
- }
- });
- }
- }
-
- public Control getControl() {
- return fComposite;
- }
-
- public Tree getTree() {
- return fProcessTree;
- }
-
- public ProcessInfo getSelection() {
- if (fProcessTree != null) {
- TreeItem[] items = fProcessTree.getSelection();
- if (items.length > 0) {
- ProcessInfo info = findProcessInfo(items[0]);
- return info;
- }
- }
- return null;
- }
-
- private void createProcessListArea(Composite parent) {
- Font font = parent.getFont();
- Composite composite = new Composite(parent, SWT.NONE);
- composite.setFont(font);
- GridLayout layout = new GridLayout(1, false);
- layout.marginWidth = 0;
- layout.marginHeight = 0;
- composite.setLayout(layout);
- composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
- fComposite = composite;
-
- fProcessTree = new Tree(composite, SWT.VIRTUAL | SWT.BORDER | SWT.SINGLE);
- GridData gd = new GridData(GridData.FILL_BOTH);
- gd.minimumHeight = 150;
- gd.minimumWidth = 470;
- fProcessTree.setLayoutData(gd);
- fProcessTree.setFont(font);
- fProcessTree.addListener(SWT.SetData, new Listener() {
- public void handleEvent(Event event) {
- TreeItem item = (TreeItem)event.item;
- ProcessInfo info = findProcessInfo(item);
- if (info == null) {
- updateItems(item.getParentItem(), false);
- }
- else {
- fillItem(item, info);
- }
- }
- });
- }
-
- private void handleDispose() {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- disconnectPeer();
- if (fProcesses != null) {
- fProcesses.removeListener(fProcessListener);
- fProcesses = null;
- }
- display = null;
- }
- });
- }
-
- protected void disconnectPeer() {
- if (fChannel != null && fChannel.getState() != IChannel.STATE_CLOSED) {
- fChannel.close();
- }
- }
-
- protected void connectPeer() {
- final IChannel channel = fPeer.openChannel();
- fChannel = channel;
- fProcesses = null;
- channel.addChannelListener(new IChannelListener() {
- public void congestionLevel(int level) {
- }
- public void onChannelClosed(final Throwable error) {
- if (fChannel != channel) return;
- fChannel = null;
- if (display != null) {
- display.asyncExec(new Runnable() {
- public void run() {
- if (root_info.children_pending) return;
- root_info.children = null;
- root_info.children_error = error;
- updateItems(root_info);
- }
- });
- }
- }
- public void onChannelOpened() {
- if (fChannel != channel) return;
- fProcesses = fChannel.getRemoteService(IProcesses.class);
- if (fProcesses != null) {
- fProcesses.addListener(fProcessListener);
- if (fContextToSelect != null) {
- final LinkedList<String> contextPath = new LinkedList<String>();
- contextPath.addFirst(fContextToSelect);
- fProcesses.getContext(fContextToSelect, new IProcesses.DoneGetContext() {
- public void doneGetContext(IToken token, Exception error, ProcessContext context) {
- if (error == null) {
- String parentId = context.getParentID();
- if (parentId != null) {
- contextPath.addFirst(parentId);
- fProcesses.getContext(parentId, this);
- return;
- }
- if (display != null) {
- display.asyncExec(new Runnable() {
- public void run() {
- fPathToSelect = contextPath;
- expandSelect();
- }
- });
- }
- }
- }
- });
- }
- }
- if (display != null) {
- display.asyncExec(new Runnable() {
- public void run() {
- if (root_info.children_pending) return;
- root_info.children = null;
- root_info.children_error = null;
- updateItems(root_info);
- }
- });
- }
- }
- });
- }
-
- private void updateItems(TreeItem parent_item, boolean reload) {
- final ProcessInfo parent_info = findProcessInfo(parent_item);
- if (parent_info == null) {
- parent_item.setText("Invalid");
- }
- else {
- if (reload && parent_info.children_error != null) {
- loadChildren(parent_info);
- }
- display.asyncExec(new Runnable() {
- public void run() {
- updateItems(parent_info);
- }
- });
- }
- }
-
- private void updateItems(final ProcessInfo parent) {
- if (display == null) return;
- assert Thread.currentThread() == display.getThread();
- TreeItem[] items = null;
- boolean expanded = true;
- if (parent.children == null || parent.children_error != null) {
- if (parent == root_info) {
- fProcessTree.setItemCount(1);
- items = fProcessTree.getItems();
- }
- else {
- TreeItem item = findItem(parent);
- if (item == null) return;
- expanded = item.getExpanded();
- item.setItemCount(1);
- items = item.getItems();
- }
- assert items.length == 1;
- items[0].removeAll();
- if (parent.children_pending) {
- items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
- items[0].setText("Pending...");
- }
- else if (parent.children_error != null) {
- String msg = parent.children_error.getMessage();
- if (msg == null) msg = parent.children_error.getClass().getName();
- else msg = msg.replace('\n', ' ');
- items[0].setForeground(display.getSystemColor(SWT.COLOR_RED));
- items[0].setText(msg);
- items[0].setImage((Image) null);
- }
- else if (expanded) {
- loadChildren(parent);
- items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
- items[0].setText("Pending...");
- }
- else {
- items[0].setText("");
- }
- }
- else {
- ProcessInfo[] arr = parent.children;
- if (parent == root_info) {
- fProcessTree.setItemCount(arr.length);
- items = fProcessTree.getItems();
- }
- else {
- TreeItem item = findItem(parent);
- if (item == null) return;
- expanded = item.getExpanded();
- item.setItemCount(expanded ? arr.length : 1);
- items = item.getItems();
- }
- if (expanded) {
- assert items.length == arr.length;
- for (int i = 0; i < items.length; i++) fillItem(items[i], arr[i]);
- // auto-expand single children
- if (items.length == 1 && !items[0].getExpanded()) {
- items[0].setExpanded(true);
- }
- expandSelect();
- }
- else {
- items[0].setText("");
- }
- }
- }
-
- private void expandSelect() {
- if (fPathToSelect == null) return;
- if (fPathToSelect.isEmpty()) {
- fPathToSelect = null;
- fContextToSelect = null;
- return;
- }
- do {
- String id = fPathToSelect.get(0);
- ProcessInfo info = findProcessInfo(root_info, id);
- if (info == null) break;
- TreeItem item = findItem(info);
- if (item == null) break;
- fPathToSelect.removeFirst();
- if (fPathToSelect.isEmpty()) {
- fProcessTree.setSelection(item);
- } else {
- item.setExpanded(true);
- }
- } while (!fPathToSelect.isEmpty());
- }
-
- private void loadChildren(final ProcessInfo parent) {
- assert Thread.currentThread() == display.getThread();
- if (parent.children_pending) return;
- assert parent.children == null;
- parent.children_pending = true;
- parent.children_error = null;
- Protocol.invokeLater(new Runnable() {
- public void run() {
- final IProcesses proc = fProcesses;
- if (proc == null || !canHaveChildren(parent)) {
- doneLoadChildren(parent, null, new ProcessInfo[0]);
- }
- else {
- proc.getChildren(parent.id, false, new IProcesses.DoneGetChildren() {
- public void doneGetChildren(IToken token, Exception error, String[] context_ids) {
- if (error != null) {
- doneLoadChildren(parent, error, null);
- } else if (context_ids.length > 0){
- final List<ProcessInfo> contextInfos = new ArrayList<ProcessInfo>(context_ids.length);
- final Set<IToken> pending = new HashSet<IToken>();
- for (String id : context_ids) {
- pending.add(proc.getContext(id, new IProcesses.DoneGetContext() {
- public void doneGetContext(IToken token, Exception error, ProcessContext context) {
- if (context != null) {
- ProcessInfo info = new ProcessInfo();
- info.parent = parent;
- info.id = context.getID();
- info.name = context.getName();
- if (info.name == null || info.name.length() == 0) {
- info.name = info.id;
- } else {
- info.name += " [" + info.id + ']';
- }
- info.isContainer = false;
- info.isAttached = context.isAttached();
- info.index = contextInfos.size();
- contextInfos.add(info);
- }
- pending.remove(token);
- if (pending.isEmpty()) {
- doneLoadChildren(parent, null, contextInfos.toArray(new ProcessInfo[contextInfos.size()]));
- }
- }
- }));
- }
- } else {
- doneLoadChildren(parent, null, new ProcessInfo[0]);
- }
- }
- });
- }
- }
- });
- }
-
- private void doneLoadChildren(final ProcessInfo parent, final Throwable error, final ProcessInfo[] children) {
- assert Protocol.isDispatchThread();
- assert error == null || children == null;
- if (display == null) return;
- display.asyncExec(new Runnable() {
- public void run() {
- assert parent.children_pending;
- assert parent.children == null;
- parent.children_pending = false;
- parent.children = children;
- parent.children_error = error;
- updateItems(parent);
- }
- });
- }
-
- public ProcessInfo findProcessInfo(TreeItem item) {
- assert Thread.currentThread() == display.getThread();
- if (item == null) return root_info ;
- TreeItem parent = item.getParentItem();
- ProcessInfo info = findProcessInfo(parent);
- if (info == null) return null;
- if (info.children == null) return null;
- if (info.children_error != null) return null;
- int i = parent == null ? fProcessTree.indexOf(item) : parent.indexOf(item);
- if (i < 0 || i >= info.children.length) return null;
- assert info.children[i].index == i;
- return info.children[i];
- }
-
- public ProcessInfo findProcessInfo(ProcessInfo parent, String id) {
- assert Thread.currentThread() == display.getThread();
- if (id == null) return root_info;
- if (id.equals(parent.id)) return parent;
- ProcessInfo[] childInfos = parent.children;
- if (childInfos != null) {
- for (ProcessInfo contextInfo : childInfos) {
- ProcessInfo found = findProcessInfo(contextInfo, id);
- if (found != null) {
- return found;
- }
- }
- }
- return null;
- }
-
- private TreeItem findItem(ProcessInfo info) {
- if (info == null) return null;
- assert info.parent != null;
- if (info.parent == root_info) {
- int n = fProcessTree.getItemCount();
- if (info.index >= n) return null;
- return fProcessTree.getItem(info.index);
- }
- TreeItem i = findItem(info.parent);
- if (i == null) return null;
- int n = i.getItemCount();
- if (info.index >= n) return null;
- return i.getItem(info.index);
- }
-
- private void fillItem(TreeItem item, ProcessInfo info) {
- assert Thread.currentThread() == display.getThread();
- Object data = item.getData("TCFContextInfo");
- if (data != null && data != info) item.removeAll();
- item.setData("TCFContextInfo", info);
- String text = info.name != null ? info.name : info.id;
- item.setText(text);
- item.setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
- item.setImage(getImage(info));
- if (!canHaveChildren(info)) item.setItemCount(0);
- else if (info.children == null || info.children_error != null) item.setItemCount(1);
- else item.setItemCount(info.children.length);
- }
-
- private boolean canHaveChildren(ProcessInfo info) {
- return info.isContainer || info == root_info;
- }
-
- private Image getImage(ProcessInfo info) {
- return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_OS_PROCESS);
- }
-
- public void selectContext(final String contextId) {
- fPathToSelect = null;
- Protocol.invokeLater(new Runnable() {
- public void run() {
- fContextToSelect = contextId;
- }
- });
- }
-
-}
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/ProcessPrompter.java b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/ProcessPrompter.java
index 4a0fa0294..a87c88c8a 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/ProcessPrompter.java
+++ b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/ProcessPrompter.java
@@ -15,19 +15,22 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.jface.window.Window;
-import org.eclipse.tcf.internal.cdt.launch.ContextSelection;
import org.eclipse.tcf.internal.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tcf.internal.debug.ui.launch.ContextSelection;
+import org.eclipse.tcf.internal.debug.ui.launch.ContextSelectionDialog;
import org.eclipse.ui.PlatformUI;
public class ProcessPrompter implements IStatusHandler {
public Object handleStatus(IStatus status, Object source) throws CoreException {
ILaunchConfiguration config = (ILaunchConfiguration) source;
- String peerId = config.getAttribute(TCFLaunchDelegate.ATTR_PEER_ID, (String) null);
- String contextId = config.getAttribute("attach_to_process", (String) null);
- if (peerId == null || contextId == null) {
- ContextSelection selection = new ContextSelection(peerId, contextId);
- ProcessSelectionDialog diag = new ProcessSelectionDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow());
+ String peerId = config.getAttribute(TCFLaunchDelegate.ATTR_PEER_ID, (String)null);
+ String contextPath = config.getAttribute(TCFLaunchDelegate.ATTR_ATTACH_PATH, (String)null);
+ if (peerId == null || contextPath == null) {
+ ContextSelection selection = new ContextSelection();
+ selection.fPeerId = peerId;
+ selection.fContextFullName = contextPath;
+ ContextSelectionDialog diag = new ContextSelectionDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow(), true);
diag.setSelection(selection);
if (diag.open() == Window.OK) {
return diag.getSelection();
@@ -35,5 +38,4 @@ public class ProcessPrompter implements IStatusHandler {
}
return null;
}
-
}
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/RemoteCMainTab.java b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/RemoteCMainTab.java
index 64f0cbda0..79ece2719 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/RemoteCMainTab.java
+++ b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/RemoteCMainTab.java
@@ -22,7 +22,6 @@ import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
@@ -37,8 +36,10 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
-import org.eclipse.tcf.internal.cdt.ui.launch.PeerListControl.PeerInfo;
import org.eclipse.tcf.internal.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tcf.internal.debug.ui.launch.PeerListControl;
+import org.eclipse.tcf.internal.debug.ui.launch.PeerListControl.PeerInfo;
+import org.eclipse.tcf.internal.debug.ui.launch.RemoteFileSelectionDialog;
import org.eclipse.tcf.protocol.IChannel;
import org.eclipse.tcf.protocol.IChannel.IChannelListener;
import org.eclipse.tcf.services.IFileSystem;
@@ -122,7 +123,8 @@ public class RemoteCMainTab extends CMainTab implements IShellProvider {
if (fSelectedPeer == null) {
setErrorMessage("No target selected.");
valid = false;
- } else if (!fPeerHasProcessesService) {
+ }
+ else if (!fPeerHasProcessesService) {
setErrorMessage("Selected target does not support 'Processes' service");
valid = false;
}
@@ -242,15 +244,7 @@ public class RemoteCMainTab extends CMainTab implements IShellProvider {
protected void updatePeerFromConfig(ILaunchConfiguration config) {
try {
String peerId = config.getAttribute(TCFLaunchDelegate.ATTR_PEER_ID, (String) null);
- if (peerId != null) {
- PeerInfo info = fPeerList.findPeerInfo(peerId);
- if (info != null) {
- fPeerList.setSelection(new StructuredSelection(info));
- handlePeerSelectionChanged();
- } else {
- fPeerList.setInitialSelectedPeerId(peerId);
- }
- }
+ fPeerList.setInitialSelection(peerId);
}
catch (CoreException e) {
// Ignore
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/application_tab.gif b/plugins/org.eclipse.tcf.debug.ui/icons/application_tab.gif
new file mode 100644
index 000000000..aa15e0a47
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/application_tab.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/download_tab.gif b/plugins/org.eclipse.tcf.debug.ui/icons/download_tab.gif
new file mode 100644
index 000000000..ad5e74dec
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/download_tab.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java
index c16467746..c195b5c61 100644
--- a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java
@@ -30,7 +30,9 @@ public class ImageCache {
public static final String
IMG_TCF = "icons/tcf.gif",
IMG_TARGET_TAB = "icons/target_tab.gif",
+ IMG_DOWNLOAD_TAB = "icons/download_tab.gif",
IMG_TARGET_WIZARD = "icons/full/wizban/debug_wiz.png",
+ IMG_APPLICATION_TAB = "icons/application_tab.gif",
IMG_ARGUMENTS_TAB = "icons/arguments_tab.gif",
IMG_ATTRIBUTE = "icons/attribute.gif",
IMG_PATH = "icons/path.gif",
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ContextListControl.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ContextListControl.java
new file mode 100644
index 000000000..ee93d532b
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ContextListControl.java
@@ -0,0 +1,653 @@
+/*******************************************************************************
+ * 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
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.internal.debug.ui.launch;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.tcf.internal.debug.ui.ImageCache;
+import org.eclipse.tcf.internal.debug.ui.model.TCFModel;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IChannel.IChannelListener;
+import org.eclipse.tcf.protocol.IPeer;
+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.services.IRunControl;
+import org.eclipse.tcf.services.IRunControl.RunControlContext;
+import org.eclipse.tcf.services.ISysMonitor;
+import org.eclipse.tcf.services.ISysMonitor.SysMonitorContext;
+import org.eclipse.tcf.util.TCFTask;
+
+public class ContextListControl {
+
+ private final class ProcessListener implements IProcesses.ProcessesListener {
+ public void exited(final String process_id, int exit_code) {
+ onContextRemoved(process_id);
+ }
+ }
+
+ private final class ContextListener implements IRunControl.RunControlListener {
+ @Override
+ public void contextAdded(RunControlContext[] contexts) {
+ for (RunControlContext ctx : contexts) {
+ onContextAdded(ctx.getParentID());
+ }
+ }
+ @Override
+ public void contextChanged(RunControlContext[] contexts) {
+ }
+ @Override
+ public void contextRemoved(String[] context_ids) {
+ for (String id : context_ids) {
+ onContextRemoved(id);
+ }
+ }
+ @Override
+ public void contextSuspended(String context, String pc, String reason, Map<String, Object> params) {
+ }
+ @Override
+ public void contextResumed(String context) {
+ }
+ @Override
+ public void containerSuspended(String context, String pc, String reason, Map<String, Object> params, String[] suspended_ids) {
+ }
+ @Override
+ public void containerResumed(String[] context_ids) {
+ }
+ @Override
+ public void contextException(String context, String msg) {
+ }
+ }
+
+ static class ContextInfo {
+ String name;
+ String id;
+ boolean is_attached;
+ boolean is_container;
+ boolean has_state;
+ long pid;
+ String[] cmd_line;
+ ContextInfo[] children;
+ Throwable children_error;
+ boolean children_pending;
+ boolean children_reload;
+ ContextInfo parent;
+ }
+
+ private Composite composite;
+ private Tree ctx_tree;
+ private Display display;
+ private IChannel channel;
+ private String channel_state;
+ private final ContextInfo root_info = new ContextInfo();
+ private final ProcessListener prs_listener = new ProcessListener();
+ private final ContextListener ctx_listener = new ContextListener();
+ private final boolean processes;
+ private String initial_selection;
+
+ public ContextListControl(Composite parent, boolean processes) {
+ this.processes = processes;
+ display = parent.getDisplay();
+ parent.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ disconnectPeer();
+ display = null;
+ }
+ });
+ }
+ });
+ createContextListArea(parent);
+ }
+
+ public void setInput(final IPeer peer) {
+ assert Thread.currentThread() == display.getThread();
+ channel = new TCFTask<IChannel>() {
+ public void run() {
+ disconnectPeer();
+ done(connectPeer(peer));
+ }
+ }.getE();
+ root_info.children = null;
+ root_info.children_error = null;
+ root_info.children_pending = false;
+ root_info.children_reload = false;
+ loadChildren(root_info);
+ }
+
+ public Control getControl() {
+ return composite;
+ }
+
+ public Tree getTree() {
+ return ctx_tree;
+ }
+
+ public ContextInfo getSelection() {
+ if (ctx_tree != null) {
+ initial_selection = null;
+ TreeItem[] items = ctx_tree.getSelection();
+ if (items.length > 0) {
+ ContextInfo info = findInfo(items[0]);
+ return info;
+ }
+ }
+ return null;
+ }
+
+ private void createContextListArea(Composite parent) {
+ Font font = parent.getFont();
+ composite = new Composite(parent, SWT.NONE);
+ composite.setFont(font);
+ GridLayout layout = new GridLayout(1, false);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
+
+ ctx_tree = new Tree(composite, SWT.VIRTUAL | SWT.BORDER | SWT.SINGLE);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ gd.minimumHeight = 150;
+ gd.minimumWidth = 470;
+ ctx_tree.setLayoutData(gd);
+ ctx_tree.setFont(font);
+ ctx_tree.addListener(SWT.SetData, new Listener() {
+ public void handleEvent(Event event) {
+ TreeItem item = (TreeItem)event.item;
+ ContextInfo info = findInfo(item);
+ if (info == null) {
+ updateItems(item.getParentItem(), false);
+ }
+ else {
+ fillItem(item, info);
+ }
+ }
+ });
+ }
+
+ protected void disconnectPeer() {
+ if (channel != null && channel.getState() != IChannel.STATE_CLOSED) {
+ channel.close();
+ }
+ }
+
+ protected IChannel connectPeer(IPeer peer) {
+ if (peer == null) return null;
+ final IChannel channel = peer.openChannel();
+ channel.addChannelListener(new IChannelListener() {
+ public void congestionLevel(int level) {
+ }
+ public void onChannelClosed(final Throwable error) {
+ if (display != null) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (ContextListControl.this.channel != channel) return;
+ root_info.children_error = error;
+ loadChildren(root_info);
+ }
+ });
+ }
+ }
+ public void onChannelOpened() {
+ if (processes) {
+ IProcesses service = channel.getRemoteService(IProcesses.class);
+ if (service != null) service.addListener(prs_listener);
+ }
+ else {
+ IRunControl service = channel.getRemoteService(IRunControl.class);
+ if (service != null) service.addListener(ctx_listener);
+ }
+ if (display != null) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (ContextListControl.this.channel != channel) return;
+ loadChildren(root_info);
+ updateItems(root_info);
+ }
+ });
+ }
+ }
+ });
+ return channel;
+ }
+
+ private void updateItems(TreeItem parent_item, boolean reload) {
+ final ContextInfo parent_info = findInfo(parent_item);
+ if (parent_info == null) {
+ parent_item.setText("Invalid");
+ }
+ else {
+ if (reload && parent_info.children_error != null) {
+ loadChildren(parent_info);
+ }
+ display.asyncExec(new Runnable() {
+ public void run() {
+ updateItems(parent_info);
+ }
+ });
+ }
+ }
+
+ private void updateItems(final ContextInfo parent) {
+ if (display == null) return;
+ assert Thread.currentThread() == display.getThread();
+ TreeItem[] items = null;
+ boolean expanded = true;
+ if (parent.children == null || parent.children_error != null) {
+ if (parent == root_info) {
+ ctx_tree.deselectAll();
+ ctx_tree.setItemCount(1);
+ items = ctx_tree.getItems();
+ }
+ else {
+ TreeItem item = findItem(parent);
+ if (item == null) return;
+ expanded = item.getExpanded();
+ item.setItemCount(1);
+ items = item.getItems();
+ }
+ assert items.length == 1;
+ items[0].removeAll();
+ items[0].setImage((Image)null);
+ items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+ if (parent.children_pending) {
+ items[0].setText("Pending...");
+ }
+ else if (parent.children_error != null) {
+ String msg = TCFModel.getErrorMessage(parent.children_error, false);
+ items[0].setForeground(display.getSystemColor(SWT.COLOR_RED));
+ items[0].setText(msg);
+ }
+ else if (channel_state != null) {
+ items[0].setText(channel_state);
+ }
+ else if (expanded) {
+ loadChildren(parent);
+ items[0].setText("Pending...");
+ }
+ else {
+ items[0].setText("");
+ }
+ }
+ else {
+ ContextInfo[] arr = parent.children;
+ if (parent == root_info) {
+ ctx_tree.setItemCount(arr.length);
+ items = ctx_tree.getItems();
+ }
+ else {
+ TreeItem item = findItem(parent);
+ if (item == null) return;
+ expanded = item.getExpanded();
+ item.setItemCount(expanded ? arr.length : 1);
+ items = item.getItems();
+ }
+ if (expanded) {
+ assert items.length == arr.length;
+ for (int i = 0; i < items.length; i++) fillItem(items[i], arr[i]);
+ // auto-expand single children
+ if (items.length == 1 && !items[0].getExpanded()) {
+ items[0].setExpanded(true);
+ }
+ }
+ else {
+ items[0].setText("");
+ }
+ }
+ if (initial_selection != null) {
+ setInitialSelection(initial_selection);
+ }
+ }
+
+ private void loadChildren(final ContextInfo parent) {
+ assert Thread.currentThread() == display.getThread();
+ final IChannel channel = this.channel;
+ parent.children_reload = true;
+ if (parent.children_pending) return;
+ parent.children_reload = false;
+ parent.children_pending = true;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ if (channel == null || channel.getState() != IChannel.STATE_OPEN) {
+ doneLoadChildren(channel, parent, null, new ContextInfo[0]);
+ }
+ else if (processes) {
+ loadProcessChildren(channel, parent);
+ }
+ else {
+ loadContextChildren(channel, parent);
+ }
+ }
+ });
+ }
+
+ private void loadProcessChildren(final IChannel channel, final ContextInfo parent) {
+ final IProcesses service = channel.getRemoteService(IProcesses.class);
+ final ISysMonitor sysmon = channel.getRemoteService(ISysMonitor.class);
+ if (service == null) {
+ doneLoadChildren(channel, parent, new Exception("Peer does not support Processes service"), null);
+ }
+ else if (!canHaveChildren(parent)) {
+ doneLoadChildren(channel, parent, null, new ContextInfo[0]);
+ }
+ else {
+ service.getChildren(parent.id, false, new IProcesses.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception error, String[] context_ids) {
+ if (error != null) {
+ doneLoadChildren(channel, parent, error, null);
+ }
+ else if (context_ids == null || context_ids.length == 0) {
+ doneLoadChildren(channel, parent, null, new ContextInfo[0]);
+ }
+ else {
+ final List<ContextInfo> infos = new ArrayList<ContextInfo>(context_ids.length);
+ final Set<IToken> pending = new HashSet<IToken>();
+ for (final String id : context_ids) {
+ final ContextInfo info = new ContextInfo();
+ info.parent = parent;
+ info.id = id;
+ pending.add(service.getContext(id, new IProcesses.DoneGetContext() {
+ public void doneGetContext(IToken token, Exception error, ProcessContext context) {
+ if (context != null) {
+ info.name = context.getName();
+ info.is_attached = context.isAttached();
+ infos.add(info);
+ }
+ pending.remove(token);
+ if (!pending.isEmpty()) return;
+ doneLoadChildren(channel, parent, null, infos.toArray(new ContextInfo[infos.size()]));
+ }
+ }));
+ if (sysmon != null) {
+ pending.add(sysmon.getContext(id, new ISysMonitor.DoneGetContext() {
+ @Override
+ public void doneGetContext(IToken token, Exception error, SysMonitorContext context) {
+ if (context != null) {
+ info.pid = context.getPID();
+ }
+ pending.remove(token);
+ if (!pending.isEmpty()) return;
+ doneLoadChildren(channel, parent, null, infos.toArray(new ContextInfo[infos.size()]));
+ }
+ }));
+ pending.add(sysmon.getCommandLine(id, new ISysMonitor.DoneGetCommandLine() {
+ @Override
+ public void doneGetCommandLine(IToken token, Exception error, String[] cmd_line) {
+ if (cmd_line != null) {
+ info.cmd_line = cmd_line;
+ }
+ pending.remove(token);
+ if (!pending.isEmpty()) return;
+ doneLoadChildren(channel, parent, null, infos.toArray(new ContextInfo[infos.size()]));
+ }
+ }));
+ }
+ }
+ }
+ }
+ });
+ }
+ }
+
+ private void loadContextChildren(final IChannel channel, final ContextInfo parent) {
+ final IRunControl service = channel.getRemoteService(IRunControl.class);
+ if (service == null) {
+ doneLoadChildren(channel, parent, new Exception("Peer does not support Run Control service"), null);
+ }
+ else if (!canHaveChildren(parent)) {
+ doneLoadChildren(channel, parent, null, new ContextInfo[0]);
+ }
+ else {
+ service.getChildren(parent.id, new IRunControl.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception error, String[] context_ids) {
+ if (error != null) {
+ doneLoadChildren(channel, parent, error, null);
+ }
+ else if (context_ids != null && context_ids.length > 0) {
+ final List<ContextInfo> infos = new ArrayList<ContextInfo>(context_ids.length);
+ final Set<IToken> pending = new HashSet<IToken>();
+ for (String id : context_ids) {
+ pending.add(service.getContext(id, new IRunControl.DoneGetContext() {
+ public void doneGetContext(IToken token, Exception error, RunControlContext context) {
+ if (context != null) {
+ ContextInfo info = new ContextInfo();
+ info.parent = parent;
+ info.id = context.getID();
+ info.name = context.getName();
+ info.is_container = context.isContainer();
+ info.has_state = context.hasState();
+ info.is_attached = true;
+ infos.add(info);
+ }
+ pending.remove(token);
+ if (!pending.isEmpty()) return;
+ doneLoadChildren(channel, parent, null, infos.toArray(new ContextInfo[infos.size()]));
+ }
+ }));
+ }
+ }
+ else {
+ doneLoadChildren(channel, parent, null, new ContextInfo[0]);
+ }
+ }
+ });
+ }
+ }
+
+ private void doneLoadChildren(final IChannel channel, final ContextInfo parent, final Throwable error, final ContextInfo[] children) {
+ assert Protocol.isDispatchThread();
+ assert error == null || children == null;
+ if (display == null) return;
+ final String state = getChannelState(channel);
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (ContextListControl.this.channel != channel) return;
+ assert parent.children_pending;
+ parent.children_pending = false;
+ if (state == null) {
+ parent.children = children;
+ parent.children_error = error;
+ if (parent.children_reload) {
+ loadChildren(parent);
+ }
+ }
+ else {
+ parent.children = null;
+ parent.children_reload = false;
+ }
+ channel_state = state;
+ updateItems(parent);
+ }
+ });
+ }
+
+ private String getChannelState(IChannel channel) {
+ if (channel == null) return "Not connected";
+ switch (channel.getState()) {
+ case IChannel.STATE_OPENING: return "Connecting...";
+ case IChannel.STATE_CLOSED: return "Disconnected";
+ }
+ return null;
+ }
+
+ private void onContextRemoved(final String id) {
+ if (display == null) return;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ ContextInfo info = findInfo(root_info, id);
+ if (info != null && info.parent != null) loadChildren(info.parent);
+ }
+ });
+ }
+
+ private void onContextAdded(final String parent_id) {
+ if (display == null) return;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ ContextInfo info = findInfo(root_info, parent_id);
+ if (info != null) loadChildren(info);
+ }
+ });
+ }
+
+ public String getFullName(ContextInfo info) {
+ if (info == null) return null;
+ String name = info.name;
+ if (name == null) name = info.id;
+ if (info.parent == root_info) return "/" + name;
+ if (info.parent == null) return null;
+ String path = getFullName(info.parent);
+ if (path == null) return null;
+ return path + '/' + name;
+ }
+
+ private ContextInfo findInfoByFullName(ContextInfo parent, String name, boolean expand) {
+ if (name == null) return null;
+ if (name.startsWith("/")) return findInfoByFullName(root_info, name.substring(1), expand);
+ if (parent.children_pending) return null;
+ String head = name;
+ String tail = null;
+ int i = name.indexOf('/');
+ if (i >= 0) {
+ head = name.substring(0, i);
+ tail = name.substring(i + 1);
+ }
+ ContextInfo[] children = parent.children;
+ if (children != null) {
+ for (ContextInfo info : children) {
+ if (head.equals(info.name)) {
+ if (tail == null) return info;
+ if (expand) {
+ TreeItem item = findItem(info);
+ if (item != null) item.setExpanded(true);
+ }
+ return findInfoByFullName(info, tail, expand);
+ }
+ }
+ }
+ else if (expand) {
+ loadChildren(parent);
+ }
+ return null;
+ }
+
+ public ContextInfo findInfo(TreeItem item) {
+ assert Thread.currentThread() == display.getThread();
+ if (item == null) return root_info;
+ return (ContextInfo)item.getData("TCFContextInfo");
+ }
+
+ public ContextInfo findInfo(ContextInfo parent, String id) {
+ assert Thread.currentThread() == display.getThread();
+ if (id == null) return root_info;
+ if (id.equals(parent.id)) return parent;
+ ContextInfo[] children = parent.children;
+ if (children != null) {
+ for (ContextInfo info : children) {
+ ContextInfo found = findInfo(info, id);
+ if (found != null) return found;
+ }
+ }
+ return null;
+ }
+
+ private TreeItem findItem(ContextInfo info) {
+ assert Thread.currentThread() == display.getThread();
+ if (info == null) return null;
+ assert info.parent != null;
+ if (info.parent == root_info) {
+ TreeItem[] items = ctx_tree.getItems();
+ for (TreeItem item : items) {
+ if (item.getData("TCFContextInfo") == info) return item;
+ }
+ return null;
+ }
+ TreeItem parent = findItem(info.parent);
+ if (parent == null) return null;
+ TreeItem[] items = parent.getItems();
+ for (TreeItem item : items) {
+ if (item.getData("TCFContextInfo") == info) return item;
+ }
+ return null;
+ }
+
+ private void fillItem(TreeItem item, ContextInfo info) {
+ assert Thread.currentThread() == display.getThread();
+ Object data = item.getData("TCFContextInfo");
+ if (data != null && data != info) item.removeAll();
+ item.setData("TCFContextInfo", info);
+ StringBuffer bf = new StringBuffer();
+ if (info.pid > 0) {
+ bf.append(info.pid);
+ bf.append(": ");
+ }
+ if (info.cmd_line != null && info.cmd_line.length > 0) {
+ for (String s : info.cmd_line) {
+ bf.append(' ');
+ bf.append(s);
+ }
+ }
+ else if (info.name != null) {
+ bf.append(info.name);
+ }
+ else {
+ bf.append(info.id);
+ }
+ item.setText(bf.toString());
+ item.setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+ item.setImage(getImage(info));
+ if (!canHaveChildren(info)) item.setItemCount(0);
+ else if (info.children == null || info.children_error != null) item.setItemCount(1);
+ else item.setItemCount(info.children.length);
+ }
+
+ private boolean canHaveChildren(ContextInfo info) {
+ return !info.has_state && (info.is_container || info == root_info);
+ }
+
+ private Image getImage(ContextInfo info) {
+ return ImageCache.getImage(info.has_state ? ImageCache.IMG_THREAD_UNKNOWN_STATE : ImageCache.IMG_PROCESS_RUNNING);
+ }
+
+ public void setInitialSelection(String full_name) {
+ if (full_name == null) return;
+ if (full_name.length() == 0) return;
+ initial_selection = full_name;
+ ContextInfo info = findInfoByFullName(null, full_name, true);
+ if (info != null) {
+ TreeItem item = findItem(info);
+ if (item != null) {
+ ctx_tree.setSelection(item);
+ initial_selection = null;
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/launch/ContextSelection.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ContextSelection.java
index 0cc2b0644..3337782ea 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/launch/ContextSelection.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ContextSelection.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 Wind River Systems, Inc. and others.
+ * 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
@@ -8,18 +8,12 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
-package org.eclipse.tcf.internal.cdt.launch;
+package org.eclipse.tcf.internal.debug.ui.launch;
public class ContextSelection {
public String fPeerId;
public String fContextId;
+ public String fContextFullName;
+ public String fContextName;
public boolean fIsAttached;
- public ContextSelection(String peerId, String contextId) {
- this(peerId, contextId, true);
- }
- public ContextSelection(String peerId, String contextId, boolean isAttached) {
- fPeerId = peerId;
- fContextId = contextId;
- fIsAttached = isAttached;
- }
}
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/ProcessSelectionDialog.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ContextSelectionDialog.java
index 15fa82bad..5c284d425 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/ProcessSelectionDialog.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ContextSelectionDialog.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 Wind River Systems, Inc. and others.
+ * 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
@@ -8,14 +8,10 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
-package org.eclipse.tcf.internal.cdt.ui.launch;
+package org.eclipse.tcf.internal.debug.ui.launch;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
@@ -25,34 +21,35 @@ import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TreeItem;
-import org.eclipse.tcf.internal.cdt.launch.ContextSelection;
-import org.eclipse.tcf.internal.cdt.ui.launch.PeerListControl.PeerInfo;
-import org.eclipse.tcf.internal.cdt.ui.launch.ProcessListControl.ProcessInfo;
+import org.eclipse.tcf.internal.debug.ui.launch.PeerListControl.PeerInfo;
+import org.eclipse.tcf.internal.debug.ui.launch.ContextListControl.ContextInfo;
/**
* Dialog to select a peer and context.
*/
-public class ProcessSelectionDialog extends Dialog {
+public class ContextSelectionDialog extends Dialog {
- private ContextSelection fSelection;
- private ProcessListControl fContextList;
+ private final boolean processes;
+ private ContextSelection selection;
+ private ContextListControl context_list;
- protected ProcessSelectionDialog(IShellProvider parentShell) {
+ public ContextSelectionDialog(IShellProvider parentShell, boolean processes) {
super(parentShell);
+ this.processes = processes;
}
public void setSelection(ContextSelection selection) {
- fSelection = selection;
+ this.selection = selection;
}
public ContextSelection getSelection() {
- return fSelection;
+ return selection;
}
@Override
- protected void configureShell(Shell newShell) {
- newShell.setText("Select Peer and Context");
- super.configureShell(newShell);
+ protected void configureShell(Shell shell) {
+ shell.setText("Select Peer and Context");
+ super.configureShell(shell);
}
@Override
@@ -65,26 +62,19 @@ public class ProcessSelectionDialog extends Dialog {
@Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
- new Label(composite, SWT.NONE).setText("TCF Peers:");
- final PeerListControl peerList = new PeerListControl(composite);
- new Label(composite, SWT.NONE).setText("Contexts:");
- fContextList = new ProcessListControl(composite);
- peerList.addSelectionChangedListener(new ISelectionChangedListener() {
- public void selectionChanged(SelectionChangedEvent event) {
- ISelection selection = event.getSelection();
- if (selection instanceof IStructuredSelection) {
- IStructuredSelection ss = (IStructuredSelection) selection;
- Object element = ss.getFirstElement();
- if (element instanceof PeerInfo) {
- handlePeerSelected((PeerInfo) element);
- }
- }
+ new Label(composite, SWT.NONE).setText("Peers:");
+ final PeerListControl peerList = new PeerListControl(composite) {
+ @Override
+ protected void onPeerSelected(PeerInfo info) {
+ handlePeerSelected(info);
}
- });
- fContextList.getTree().addSelectionListener(new SelectionAdapter() {
+ };
+ new Label(composite, SWT.NONE).setText("Contexts:");
+ context_list = new ContextListControl(composite, processes);
+ context_list.getTree().addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- ProcessInfo contextInfo = fContextList.findProcessInfo((TreeItem) e.item);
+ ContextInfo contextInfo = context_list.findInfo((TreeItem) e.item);
if (contextInfo != null) {
handleContextSelected(contextInfo);
}
@@ -97,24 +87,29 @@ public class ProcessSelectionDialog extends Dialog {
}
}
});
- if (fSelection.fContextId != null) {
- fContextList.selectContext(fSelection.fContextId);
+ if (selection.fPeerId != null) {
+ peerList.setInitialSelection(selection.fPeerId);
+ }
+ if (selection.fContextFullName != null) {
+ context_list.setInitialSelection(selection.fContextFullName);
}
return composite;
}
private void updateButtonState() {
- getButton(IDialogConstants.OK_ID).setEnabled(fSelection.fContextId != null);
+ getButton(IDialogConstants.OK_ID).setEnabled(selection.fContextId != null);
}
- protected void handleContextSelected(ProcessInfo contextInfo) {
- fSelection.fContextId = contextInfo.id;
+ protected void handleContextSelected(ContextInfo info) {
+ selection.fContextId = info.id;
+ selection.fContextName = info.name;
+ selection.fContextFullName = context_list.getFullName(info);
+ selection.fIsAttached = info.is_attached;
updateButtonState();
}
- protected void handlePeerSelected(PeerInfo peerInfo) {
- fSelection.fPeerId = peerInfo.id;
- fContextList.setInput(peerInfo.peer);
+ protected void handlePeerSelected(PeerInfo info) {
+ selection.fPeerId = info.id;
+ context_list.setInput(info.peer);
}
-
}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/DownloadFileDialog.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/DownloadFileDialog.java
new file mode 100644
index 000000000..dde60d720
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/DownloadFileDialog.java
@@ -0,0 +1,400 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Xilinx, 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:
+ * Xilinx - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.internal.debug.ui.launch;
+
+import java.math.BigInteger;
+import java.util.Map;
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tcf.internal.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tcf.internal.debug.ui.ImageCache;
+import org.eclipse.tcf.internal.debug.ui.model.TCFModel;
+import org.eclipse.tcf.protocol.JSON;
+
+class DownloadFileDialog extends Dialog {
+
+ private final Image image;
+ private final String peer_id;
+ private final Map<String,Object> map;
+
+ private Text context_text;
+ private Text file_text;
+ private Text addr_text;
+ private Text size_text;
+ private Text offs_text;
+ private Button file_button;
+ private Button context_button;
+ private Button load_syms_button;
+ private Button relocate_button;
+ private Button download_button;
+ private Button set_pc_button;
+ private Button osa_button;
+
+ DownloadFileDialog(Shell parentShell, String peer_id, Map<String,Object> map) {
+ super(parentShell);
+ this.image = ImageCache.getImage(ImageCache.IMG_DOWNLOAD_TAB);
+ this.peer_id = peer_id;
+ this.map = map;
+ }
+
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("Download File"); //$NON-NLS-1$
+ shell.setImage(image);
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+ createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+ updateButtons();
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite)super.createDialogArea(parent);
+ createFileFields(composite);
+ setData();
+ composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ return composite;
+ }
+
+ private void createFileFields(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(3, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label context_label = new Label(composite, SWT.NONE);
+ context_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ context_label.setFont(font);
+ context_label.setText("Context:"); //$NON-NLS-1$
+
+ context_text = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.widthHint = 400;
+ context_text.setLayoutData(gd);
+ context_text.setFont(font);
+
+ context_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updateButtons();
+ }
+ });
+
+ context_button = new Button(composite, SWT.PUSH);
+ context_button.setText("Select..."); //$NON-NLS-1$
+ context_button.setFont(font);
+ context_button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ context_button.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ String context = context_text.getText().trim();
+ ContextSelection selection = new ContextSelection();
+ selection.fPeerId = peer_id;
+ selection.fContextFullName = context;
+ ContextSelectionDialog diag = new ContextSelectionDialog(DownloadFileDialog.this, false);
+ diag.setSelection(selection);
+ if (diag.open() == Window.OK) {
+ selection = diag.getSelection();
+ context_text.setText(selection.fContextFullName);
+ }
+ }
+ });
+
+ Label file_label = new Label(composite, SWT.NONE);
+ file_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ file_label.setFont(font);
+ file_label.setText("File:"); //$NON-NLS-1$
+
+ file_text = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ file_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ file_text.setFont(font);
+
+ file_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updateButtons();
+ }
+ });
+
+ file_button = new Button(composite, SWT.PUSH);
+ file_button.setText("Browse..."); //$NON-NLS-1$
+ file_button.setFont(font);
+ file_button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ file_button.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ String path = file_text.getText().trim();
+ if (path.length() == 0) path = ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString();
+ FileDialog dialog = new FileDialog(getShell(), SWT.NONE);
+ dialog.setFilterPath(path);
+ path = dialog.open();
+ if (path != null) file_text.setText(path);
+ }
+ });
+
+ load_syms_button = new Button(composite, SWT.CHECK);
+ load_syms_button.setText("Load symbols");
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 3;
+ load_syms_button.setLayoutData(gd);
+ load_syms_button.setFont(font);
+ load_syms_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateButtons();
+ }
+ });
+ load_syms_button.setEnabled(true);
+
+ relocate_button = new Button(composite, SWT.CHECK);
+ relocate_button.setText("Relocate the file");
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 3;
+ relocate_button.setLayoutData(gd);
+ relocate_button.setFont(font);
+ relocate_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateButtons();
+ }
+ });
+ relocate_button.setEnabled(true);
+ Composite rel_group = createRelocateGroup(composite);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 3;
+ rel_group.setLayoutData(gd);
+
+ download_button = new Button(composite, SWT.CHECK);
+ download_button.setText("Download the file into the context memory");
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 3;
+ download_button.setLayoutData(gd);
+ download_button.setFont(font);
+ download_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateButtons();
+ }
+ });
+ download_button.setEnabled(true);
+
+ set_pc_button = new Button(composite, SWT.CHECK);
+ set_pc_button.setText("Set PC to program entry address");
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 3;
+ set_pc_button.setLayoutData(gd);
+ set_pc_button.setFont(font);
+ set_pc_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateButtons();
+ }
+ });
+ set_pc_button.setEnabled(true);
+
+ osa_button = new Button(composite, SWT.CHECK);
+ osa_button.setText("Enable OS awarennes - the file is an OS kernel");
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 3;
+ osa_button.setLayoutData(gd);
+ osa_button.setFont(font);
+ osa_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateButtons();
+ }
+ });
+ osa_button.setEnabled(true);
+ }
+
+ private Composite createRelocateGroup(Composite parent) {
+ Font font = parent.getFont();
+
+ Group group = new Group(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.verticalSpacing = 0;
+ layout.numColumns = 2;
+ group.setLayout(layout);
+ group.setLayoutData(new GridData(GridData.FILL_BOTH));
+ group.setFont(font);
+ group.setText("File location in the context memory");
+
+ Label addr_label = new Label(group, SWT.WRAP);
+ addr_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ addr_label.setFont(font);
+ addr_label.setText("Address:");
+
+ addr_text = new Text(group, SWT.SINGLE | SWT.BORDER);
+ addr_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ addr_text.setFont(font);
+
+ Label size_label = new Label(group, SWT.WRAP);
+ size_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ size_label.setFont(font);
+ size_label.setText("Size:");
+
+ size_text = new Text(group, SWT.SINGLE | SWT.BORDER);
+ size_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ size_text.setFont(font);
+
+ Label offset_label = new Label(group, SWT.WRAP);
+ offset_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ offset_label.setFont(font);
+ offset_label.setText("File offset:");
+
+ offs_text = new Text(group, SWT.SINGLE | SWT.BORDER);
+ offs_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ offs_text.setFont(font);
+
+ return group;
+ }
+
+ private String toHex(Number n) {
+ if (n == null) return null;
+ BigInteger x = JSON.toBigInteger(n);
+ String s = x.toString(16);
+ int l = 16 - s.length();
+ if (l < 0) l = 0;
+ if (l > 16) l = 16;
+ return "0x0000000000000000".substring(0, 2 + l) + s;
+ }
+
+ private void setString(Text text, String key) {
+ String s = (String)map.get(key);
+ if (s == null) s = "";
+ text.setText(s);
+ }
+
+ private void setBoolean(Button btn, String key) {
+ Boolean b = (Boolean)map.get(key);
+ if (b == null) btn.setSelection(false);
+ else btn.setSelection(b.booleanValue());
+ }
+
+ private void setNumber(Text text, String key) {
+ Number n = (Number)map.get(key);
+ if (n == null) text.setText("");
+ else text.setText(toHex(n));
+ }
+
+ private void setData() {
+ setString(context_text, TCFLaunchDelegate.FILES_CONTEXT_FULL_NAME);
+ setString(file_text, TCFLaunchDelegate.FILES_FILE_NAME);
+ setBoolean(load_syms_button, TCFLaunchDelegate.FILES_LOAD_SYMBOLS);
+ setBoolean(relocate_button, TCFLaunchDelegate.FILES_RELOCATE);
+ setBoolean(download_button, TCFLaunchDelegate.FILES_DOWNLOAD);
+ setBoolean(set_pc_button, TCFLaunchDelegate.FILES_SET_PC);
+ setBoolean(osa_button, TCFLaunchDelegate.FILES_ENABLE_OSA);
+ setNumber(addr_text, TCFLaunchDelegate.FILES_ADDRESS);
+ setNumber(offs_text, TCFLaunchDelegate.FILES_OFFSET);
+ setNumber(size_text, TCFLaunchDelegate.FILES_SIZE);
+ updateButtons();
+ }
+
+ private void getBoolean(Button btn, String key) {
+ boolean b = btn.getSelection();
+ if (!b) {
+ map.remove(key);
+ }
+ else {
+ map.put(key, Boolean.TRUE);
+ }
+ }
+
+ private void getString(Text text, String key) {
+ String s = text.getText().trim();
+ if (s == null || s.length() == 0) {
+ map.remove(key);
+ }
+ else {
+ map.put(key, s);
+ }
+ }
+
+ private void getNumber(Text text, String key) {
+ String s = text.getText().trim();
+ if (s == null || s.length() == 0) {
+ map.remove(key);
+ }
+ else if (s.startsWith("0x")) {
+ map.put(key, new BigInteger(s.substring(2), 16));
+ }
+ else {
+ map.put(key, new BigInteger(s));
+ }
+ }
+
+ private void getData() {
+ getString(context_text, TCFLaunchDelegate.FILES_CONTEXT_FULL_NAME);
+ getString(file_text, TCFLaunchDelegate.FILES_FILE_NAME);
+ getBoolean(load_syms_button, TCFLaunchDelegate.FILES_LOAD_SYMBOLS);
+ getBoolean(relocate_button, TCFLaunchDelegate.FILES_RELOCATE);
+ getBoolean(download_button, TCFLaunchDelegate.FILES_DOWNLOAD);
+ getBoolean(set_pc_button, TCFLaunchDelegate.FILES_SET_PC);
+ getBoolean(osa_button, TCFLaunchDelegate.FILES_ENABLE_OSA);
+ getNumber(addr_text, TCFLaunchDelegate.FILES_ADDRESS);
+ getNumber(offs_text, TCFLaunchDelegate.FILES_OFFSET);
+ getNumber(size_text, TCFLaunchDelegate.FILES_SIZE);
+ }
+
+ private void updateButtons() {
+ Button btn = getButton(IDialogConstants.OK_ID);
+ if (btn != null && context_text != null && file_text != null) {
+ String context = context_text.getText().trim();
+ String file = file_text.getText().trim();
+ btn.setEnabled(context.length() > 0 && file.length() > 0);
+ }
+ if (relocate_button != null) {
+ boolean reloc = relocate_button.getSelection();
+ addr_text.setEnabled(reloc);
+ size_text.setEnabled(reloc);
+ offs_text.setEnabled(reloc);
+ }
+ }
+
+ @Override
+ protected void okPressed() {
+ try {
+ getData();
+ }
+ catch (Throwable x) {
+ MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK);
+ mb.setText("Invalid data"); //$NON-NLS-1$
+ mb.setMessage(TCFModel.getErrorMessage(x, true));
+ mb.open();
+ return;
+ }
+ super.okPressed();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/FileSystemBrowserControl.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/FileSystemBrowserControl.java
index e6ee9453a..ce8da20bf 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/FileSystemBrowserControl.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/FileSystemBrowserControl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 Wind River Systems, Inc. and others.
+ * 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
@@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
-package org.eclipse.tcf.internal.cdt.ui.launch;
+package org.eclipse.tcf.internal.debug.ui.launch;
import java.util.ArrayList;
import java.util.Arrays;
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/PeerListControl.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/PeerListControl.java
index 69174d524..82f7aadb8 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/PeerListControl.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/PeerListControl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 Wind River Systems, Inc. and others.
+ * 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
@@ -8,14 +8,12 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
-package org.eclipse.tcf.internal.cdt.ui.launch;
+package org.eclipse.tcf.internal.debug.ui.launch;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.viewers.ISelection;
@@ -42,10 +40,11 @@ import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
-import org.eclipse.tcf.internal.cdt.ui.Activator;
-import org.eclipse.tcf.internal.cdt.ui.ImageCache;
+import org.eclipse.tcf.internal.debug.launch.TCFUserDefPeer;
+import org.eclipse.tcf.internal.debug.ui.Activator;
+import org.eclipse.tcf.internal.debug.ui.ImageCache;
+import org.eclipse.tcf.internal.debug.ui.model.TCFModel;
import org.eclipse.tcf.protocol.IChannel;
-import org.eclipse.tcf.protocol.IChannel.IChannelListener;
import org.eclipse.tcf.protocol.IPeer;
import org.eclipse.tcf.protocol.Protocol;
import org.eclipse.tcf.services.ILocator;
@@ -56,21 +55,22 @@ public class PeerListControl implements ISelectionProvider {
private Tree peer_tree;
private final PeerInfo peer_info = new PeerInfo();
private Display display;
- private final ListenerList fSelectionListeners = new ListenerList(ListenerList.IDENTITY);
- private String fInitialPeerId = "*";
+ private final ListenerList selection_listeners = new ListenerList(ListenerList.IDENTITY);
+ private String initial_peer_id;
+
+ public static class PeerInfo {
+ public String id;
+ public IPeer peer;
- static class PeerInfo {
PeerInfo parent;
- int index;
- String id;
Map<String,String> attrs;
PeerInfo[] children;
boolean children_pending;
Throwable children_error;
- IPeer peer;
IChannel channel;
ILocator locator;
LocatorListener listener;
+ Runnable item_update;
}
private class LocatorListener implements ILocator.LocatorListener {
@@ -89,17 +89,11 @@ public class PeerListControl implements ISelectionProvider {
public void run() {
if (parent.children_error != null) return;
PeerInfo[] arr = parent.children;
- String agentId = attrs.get(IPeer.ATTR_AGENT_ID);
- for (PeerInfo p : arr) {
- assert !p.id.equals(id);
- if (agentId != null && agentId.equals(p.attrs.get(IPeer.ATTR_AGENT_ID)))
- return;
- }
+ for (PeerInfo p : arr) assert !p.id.equals(id);
PeerInfo[] buf = new PeerInfo[arr.length + 1];
System.arraycopy(arr, 0, buf, 0, arr.length);
PeerInfo info = new PeerInfo();
info.parent = parent;
- info.index = arr.length;
info.id = id;
info.attrs = attrs;
info.peer = peer;
@@ -147,7 +141,6 @@ public class PeerListControl implements ISelectionProvider {
});
}
else {
- arr[i].index = j;
buf[j++] = arr[i];
}
}
@@ -193,8 +186,26 @@ public class PeerListControl implements ISelectionProvider {
createPeerListArea(parent);
}
- public void setInitialSelectedPeerId(String peerId) {
- fInitialPeerId = peerId;
+ public void setInitialSelection(String id) {
+ if (id == null) return;
+ if (id.length() == 0) return;
+ PeerInfo info = findPeerInfo(id);
+ if (info != null) {
+ setSelection(new StructuredSelection(info));
+ fireSelectionChangedEvent();
+ onPeerSelected(info);
+ }
+ else {
+ String p = id;
+ for (;;) {
+ int i = p.lastIndexOf('/');
+ if (i < 0) break;
+ p = p.substring(0, i);
+ TreeItem item = findItem(p);
+ if (item != null) item.setExpanded(true);
+ }
+ initial_peer_id = id;
+ }
}
public Tree getTree() {
@@ -204,20 +215,18 @@ public class PeerListControl implements ISelectionProvider {
private void createPeerListArea(Composite parent) {
Font font = parent.getFont();
Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
composite.setFont(font);
- GridLayout layout = new GridLayout(1, false);
- layout.marginWidth = 0;
- layout.marginHeight = 0;
composite.setLayout(layout);
- composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
+ composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1));
peer_tree = new Tree(composite, SWT.VIRTUAL | SWT.BORDER | SWT.SINGLE);
GridData gd = new GridData(GridData.FILL_BOTH);
- gd.heightHint = 80;
- gd.minimumWidth = 400;
+ gd.minimumHeight = 150;
+ gd.minimumWidth = 470;
peer_tree.setLayoutData(gd);
- for (int i = 0; i < 5; i++) {
+ for (int i = 0; i < 6; i++) {
TreeColumn column = new TreeColumn(peer_tree, SWT.LEAD, i);
column.setMoveable(true);
switch (i) {
@@ -230,14 +239,18 @@ public class PeerListControl implements ISelectionProvider {
column.setWidth(100);
break;
case 2:
+ column.setText("User");
+ column.setWidth(100);
+ break;
+ case 3:
column.setText("Transport");
column.setWidth(60);
break;
- case 3:
+ case 4:
column.setText("Host");
column.setWidth(100);
break;
- case 4:
+ case 5:
column.setText("Port");
column.setWidth(40);
break;
@@ -247,6 +260,7 @@ public class PeerListControl implements ISelectionProvider {
peer_tree.setHeaderVisible(true);
peer_tree.setFont(font);
peer_tree.addListener(SWT.SetData, new Listener() {
+ @Override
public void handleEvent(Event event) {
TreeItem item = (TreeItem)event.item;
PeerInfo info = findPeerInfo(item);
@@ -255,23 +269,52 @@ public class PeerListControl implements ISelectionProvider {
}
else {
fillItem(item, info);
+ onPeerListChanged();
}
}
});
+ peer_tree.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ TreeItem[] selections = peer_tree.getSelection();
+ if (selections.length == 0) return;
+ final PeerInfo info = findPeerInfo(selections[0]);
+ if (info == null) return;
+ new PeerPropsDialog(peer_tree.getShell(), getImage(info), info.attrs,
+ info.peer instanceof TCFUserDefPeer).open();
+ if (!(info.peer instanceof TCFUserDefPeer)) return;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ ((TCFUserDefPeer)info.peer).updateAttributes(info.attrs);
+ TCFUserDefPeer.savePeers();
+ }
+ });
+ }
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ fireSelectionChangedEvent();
+ TreeItem[] selections = peer_tree.getSelection();
+ if (selections.length > 0) {
+ assert selections.length == 1;
+ PeerInfo info = findPeerInfo(selections[0]);
+ if (info != null) {
+ initial_peer_id = null;
+ onPeerSelected(info);
+ }
+ }
+ onPeerListChanged();
+ }
+ });
peer_tree.addTreeListener(new TreeListener() {
+ @Override
public void treeCollapsed(TreeEvent e) {
updateItems((TreeItem)e.item, false);
}
+ @Override
public void treeExpanded(TreeEvent e) {
updateItems((TreeItem)e.item, true);
}
});
- peer_tree.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- fireSelectionChangedEvent();
- }
- });
}
private void handleDispose() {
@@ -322,7 +365,7 @@ public class PeerListControl implements ISelectionProvider {
else {
final IChannel channel = parent.peer.openChannel();
parent.channel = channel;
- parent.channel.addChannelListener(new IChannelListener() {
+ parent.channel.addChannelListener(new IChannel.IChannelListener() {
boolean opened = false;
boolean closed = false;
public void congestionLevel(int level) {
@@ -357,8 +400,7 @@ public class PeerListControl implements ISelectionProvider {
opened = true;
parent.locator = parent.channel.getRemoteService(ILocator.class);
if (parent.locator == null) {
- doneLoadChildren(parent, new Exception("Service not supported: " + ILocator.NAME), null);
- parent.channel.close();
+ parent.channel.terminate(new Exception("Service not supported: " + ILocator.NAME));
}
else {
doneLoadChildren(parent, null, createLocatorListener(parent));
@@ -373,21 +415,16 @@ public class PeerListControl implements ISelectionProvider {
private PeerInfo[] createLocatorListener(PeerInfo peer) {
assert Protocol.isDispatchThread();
Map<String,IPeer> map = peer.locator.getPeers();
- List<PeerInfo> filteredPeers = new ArrayList<PeerInfo>();
- Set<String> agentIds = new HashSet<String>();
+ PeerInfo[] buf = new PeerInfo[map.size()];
+ int n = 0;
for (IPeer p : map.values()) {
- String agentID = p.getAgentID();
- if (agentID != null && agentIds.add(agentID)) {
- PeerInfo info = new PeerInfo();
- info.parent = peer;
- info.index = filteredPeers.size();
- info.id = p.getID();
- info.attrs = new HashMap<String,String>(p.getAttributes());
- info.peer = p;
- filteredPeers.add(info);
- }
+ PeerInfo info = new PeerInfo();
+ info.parent = peer;
+ info.id = p.getID();
+ info.attrs = new HashMap<String,String>(p.getAttributes());
+ info.peer = p;
+ buf[n++] = info;
}
- PeerInfo[] buf = filteredPeers.toArray(new PeerInfo[filteredPeers.size()]);
peer.listener = new LocatorListener(peer);
peer.locator.addListener(peer.listener);
return buf;
@@ -409,6 +446,39 @@ public class PeerListControl implements ISelectionProvider {
});
}
+ private ArrayList<PeerInfo> filterPeerList(PeerInfo parent, boolean expanded) {
+ ArrayList<PeerInfo> lst = new ArrayList<PeerInfo>();
+ HashMap<String,PeerInfo> local_agents = new HashMap<String,PeerInfo>();
+ HashSet<String> ids = new HashSet<String>();
+ for (PeerInfo p : parent.children) {
+ String id = p.attrs.get(IPeer.ATTR_AGENT_ID);
+ if (id == null) continue;
+ if (!"TCP".equals(p.attrs.get(IPeer.ATTR_TRANSPORT_NAME))) continue;
+ if (!"127.0.0.1".equals(p.attrs.get(IPeer.ATTR_IP_HOST))) continue;
+ local_agents.put(id, p);
+ ids.add(p.id);
+ }
+ for (PeerInfo p : parent.children) {
+ PeerInfo i = local_agents.get(p.attrs.get(IPeer.ATTR_AGENT_ID));
+ if (i != null && i != p) continue;
+ lst.add(p);
+ }
+ if (parent != peer_info && expanded) {
+ for (PeerInfo p : peer_info.children) {
+ if (p.peer instanceof TCFUserDefPeer && !ids.contains(p.id)) {
+ PeerInfo x = new PeerInfo();
+ x.parent = parent;
+ x.id = p.id;
+ x.attrs = p.attrs;
+ x.peer = p.peer;
+ ids.add(x.id);
+ lst.add(x);
+ }
+ }
+ }
+ return lst;
+ }
+
private void updateItems(TreeItem parent_item, boolean reload) {
final PeerInfo parent_info = findPeerInfo(parent_item);
if (parent_info == null) {
@@ -429,140 +499,158 @@ public class PeerListControl implements ISelectionProvider {
private void updateItems(final PeerInfo parent) {
if (display == null) return;
assert Thread.currentThread() == display.getThread();
- TreeItem[] items = null;
- boolean expanded = true;
- if (parent.children == null || parent.children_error != null) {
- if (parent == peer_info) {
- peer_tree.setItemCount(1);
- items = peer_tree.getItems();
- }
- else {
- TreeItem item = findItem(parent);
- if (item == null) return;
- expanded = item.getExpanded();
- item.setItemCount(1);
- items = item.getItems();
- }
- assert items.length == 1;
- items[0].removeAll();
- if (parent.children_pending) {
- items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
- items[0].setText("Connecting...");
- }
- else if (parent.children_error != null) {
- String msg = parent.children_error.getMessage();
- if (msg == null) msg = parent.children_error.getClass().getName();
- else msg = msg.replace('\n', ' ');
- items[0].setForeground(display.getSystemColor(SWT.COLOR_RED));
- items[0].setText(msg);
- }
- else if (expanded) {
- loadChildren(parent);
- items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
- items[0].setText("Connecting...");
- }
- else {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- disconnectPeer(parent);
+ parent.item_update = new Runnable() {
+ public void run() {
+ if (display == null) return;
+ if (parent.item_update != this) return;
+ if (Thread.currentThread() != display.getThread()) {
+ display.asyncExec(this);
+ return;
+ }
+ parent.item_update = null;
+ TreeItem[] items = null;
+ boolean expanded = true;
+ if (parent.children == null || parent.children_error != null) {
+ if (parent == peer_info) {
+ peer_tree.setItemCount(1);
+ items = peer_tree.getItems();
}
- });
- items[0].setText("");
- }
- int n = peer_tree.getColumnCount();
- for (int i = 1; i < n; i++) items[0].setText(i, "");
- items[0].setImage((Image)null);
- }
- else {
- PeerInfo[] arr = parent.children;
- if (parent == peer_info) {
- peer_tree.setItemCount(arr.length);
- items = peer_tree.getItems();
- }
- else {
- TreeItem item = findItem(parent);
- if (item == null) return;
- expanded = item.getExpanded();
- item.setItemCount(expanded ? arr.length : 1);
- items = item.getItems();
- }
- if (expanded) {
- assert items.length == arr.length;
- for (int i = 0; i < items.length; i++) fillItem(items[i], arr[i]);
- if (fInitialPeerId != null && items.length > 0) {
- if ("*".equals(fInitialPeerId)) {
- fInitialPeerId = null;
- peer_tree.setSelection(items[0]);
- fireSelectionChangedEvent();
- } else {
- int i = 0;
- for (PeerInfo peerInfo : arr) {
- if (fInitialPeerId.equals(peerInfo.id)) {
- fInitialPeerId = null;
- peer_tree.setSelection(items[i]);
- fireSelectionChangedEvent();
- break;
+ else {
+ TreeItem item = findItem(parent);
+ if (item == null) return;
+ expanded = item.getExpanded();
+ item.setItemCount(1);
+ items = item.getItems();
+ }
+ assert items.length == 1;
+ if (parent.children_pending) {
+ items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+ fillItem(items[0], "Connecting...");
+ }
+ else if (parent.children_error != null) {
+ String msg = TCFModel.getErrorMessage(parent.children_error, false);
+ items[0].setForeground(display.getSystemColor(SWT.COLOR_RED));
+ fillItem(items[0], msg);
+ }
+ else if (expanded) {
+ loadChildren(parent);
+ items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+ fillItem(items[0], "Connecting...");
+ }
+ else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ disconnectPeer(parent);
}
- i++;
- }
+ });
+ fillItem(items[0], "");
}
}
- }
- else {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- disconnectPeer(parent);
+ else {
+ ArrayList<PeerInfo> lst = null;
+ if (parent == peer_info) {
+ lst = filterPeerList(parent, expanded);
+ peer_tree.setItemCount(lst.size() > 0 ? lst.size() : 1);
+ items = peer_tree.getItems();
}
- });
- items[0].setText("");
- int n = peer_tree.getColumnCount();
- for (int i = 1; i < n; i++) items[0].setText(i, "");
+ else {
+ TreeItem item = findItem(parent);
+ if (item == null) return;
+ expanded = item.getExpanded();
+ lst = filterPeerList(parent, expanded);
+ item.setItemCount(expanded && lst.size() > 0 ? lst.size() : 1);
+ items = item.getItems();
+ }
+ if (expanded && lst.size() > 0) {
+ assert items.length == lst.size();
+ for (int i = 0; i < items.length; i++) fillItem(items[i], lst.get(i));
+ }
+ else if (expanded) {
+ fillItem(items[0], "No peers");
+ }
+ else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ disconnectPeer(parent);
+ }
+ });
+ fillItem(items[0], "");
+ }
+ }
+ onPeerListChanged();
+ if (initial_peer_id != null) {
+ setInitialSelection(initial_peer_id);
+ }
}
- }
+ };
+ if (parent.children_pending) parent.item_update.run();
+ else Protocol.invokeLater(200, parent.item_update);
}
- public PeerInfo findPeerInfo(String peerId) {
- return findPeerInfo(peer_info, peerId);
- }
-
- private PeerInfo findPeerInfo(PeerInfo parent, String peerId) {
- if (peerId.equals(parent.id)) return parent;
- PeerInfo[] children = parent.children;
- if (children == null) return null;
- for (PeerInfo child : children) {
- PeerInfo info = findPeerInfo(child, peerId);
- if (info != null) return info;
+ public TreeItem findItem(String path) {
+ assert Thread.currentThread() == display.getThread();
+ if (path == null) return null;
+ int z = path.lastIndexOf('/');
+ if (z < 0) {
+ int n = peer_tree.getItemCount();
+ for (int i = 0; i < n; i++) {
+ TreeItem x = peer_tree.getItem(i);
+ PeerInfo p = (PeerInfo)x.getData("TCFPeerInfo");
+ if (p != null && p.id.equals(path)) return x;
+ }
+ }
+ else {
+ TreeItem y = findItem(path.substring(0, z));
+ if (y == null) return null;
+ String id = path.substring(z + 1);
+ int n = y.getItemCount();
+ for (int i = 0; i < n; i++) {
+ TreeItem x = y.getItem(i);
+ PeerInfo p = (PeerInfo)x.getData("TCFPeerInfo");
+ if (p != null && p.id.equals(id)) return x;
+ }
}
return null;
}
- public PeerInfo findPeerInfo(TreeItem item) {
- assert Thread.currentThread() == display.getThread();
- if (item == null) return peer_info;
- TreeItem parent = item.getParentItem();
- PeerInfo info = findPeerInfo(parent);
- if (info == null) return null;
- if (info.children == null) return null;
- if (info.children_error != null) return null;
- int i = parent == null ? peer_tree.indexOf(item) : parent.indexOf(item);
- if (i < 0 || i >= info.children.length) return null;
- assert info.children[i].index == i;
- return info.children[i];
- }
-
- private TreeItem findItem(PeerInfo info) {
+ public TreeItem findItem(PeerInfo info) {
if (info == null) return null;
assert info.parent != null;
if (info.parent == peer_info) {
int n = peer_tree.getItemCount();
- if (info.index >= n) return null;
- return peer_tree.getItem(info.index);
+ for (int i = 0; i < n; i++) {
+ TreeItem x = peer_tree.getItem(i);
+ if (x.getData("TCFPeerInfo") == info) return x;
+ }
}
- TreeItem i = findItem(info.parent);
+ else {
+ TreeItem y = findItem(info.parent);
+ if (y == null) return null;
+ int n = y.getItemCount();
+ for (int i = 0; i < n; i++) {
+ TreeItem x = y.getItem(i);
+ if (x.getData("TCFPeerInfo") == info) return x;
+ }
+ }
+ return null;
+ }
+
+ public String getPath(PeerInfo info) {
+ if (info == peer_info) return "";
+ if (info.parent == peer_info) return info.id;
+ return getPath(info.parent) + "/" + info.id;
+ }
+
+ public PeerInfo findPeerInfo(String path) {
+ TreeItem i = findItem(path);
if (i == null) return null;
- int n = i.getItemCount();
- if (info.index >= n) return null;
- return i.getItem(info.index);
+ return (PeerInfo)i.getData("TCFPeerInfo");
+ }
+
+ private PeerInfo findPeerInfo(TreeItem item) {
+ assert Thread.currentThread() == display.getThread();
+ if (item == null) return peer_info;
+ return (PeerInfo)item.getData("TCFPeerInfo");
}
private void fillItem(TreeItem item, PeerInfo info) {
@@ -570,29 +658,39 @@ public class PeerListControl implements ISelectionProvider {
Object data = item.getData("TCFPeerInfo");
if (data != null && data != info) item.removeAll();
item.setData("TCFPeerInfo", info);
- String text[] = new String[5];
+ String text[] = new String[6];
text[0] = info.attrs.get(IPeer.ATTR_NAME);
text[1] = info.attrs.get(IPeer.ATTR_OS_NAME);
- text[2] = info.attrs.get(IPeer.ATTR_TRANSPORT_NAME);
- text[3] = info.attrs.get(IPeer.ATTR_IP_HOST);
- text[4] = info.attrs.get(IPeer.ATTR_IP_PORT);
+ text[2] = info.attrs.get(IPeer.ATTR_USER_NAME);
+ text[3] = info.attrs.get(IPeer.ATTR_TRANSPORT_NAME);
+ text[4] = info.attrs.get(IPeer.ATTR_IP_HOST);
+ text[5] = info.attrs.get(IPeer.ATTR_IP_PORT);
for (int i = 0; i < text.length; i++) {
if (text[i] == null) text[i] = "";
}
item.setText(text);
item.setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
- item.setImage(ImageCache.getImage(getImageName(info)));
+ item.setImage(getImage(info));
if (!canHaveChildren(info)) item.setItemCount(0);
else if (info.children == null || info.children_error != null) item.setItemCount(1);
else item.setItemCount(info.children.length);
}
- private String getImageName(PeerInfo info) {
- return ImageCache.IMG_TARGET_TAB;
+ private void fillItem(TreeItem item, String text) {
+ item.setText(text);
+ item.setData("TCFPeerInfo", null);
+ int n = peer_tree.getColumnCount();
+ for (int i = 1; i < n; i++) item.setText(i, "");
+ item.setImage((Image)null);
+ item.removeAll();
+ }
+
+ private Image getImage(PeerInfo info) {
+ return ImageCache.getImage(ImageCache.IMG_TARGET_TAB);
}
public void addSelectionChangedListener(ISelectionChangedListener listener) {
- fSelectionListeners .add(listener);
+ selection_listeners.add(listener);
}
public ISelection getSelection() {
@@ -606,7 +704,7 @@ public class PeerListControl implements ISelectionProvider {
}
public void removeSelectionChangedListener(ISelectionChangedListener listener) {
- fSelectionListeners.remove(listener);
+ selection_listeners.remove(listener);
}
public void setSelection(ISelection selection) {
@@ -626,14 +724,20 @@ public class PeerListControl implements ISelectionProvider {
private void fireSelectionChangedEvent() {
SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());
- Object[] listeners = fSelectionListeners.getListeners();
+ Object[] listeners = selection_listeners.getListeners();
for (Object listener : listeners) {
try {
((ISelectionChangedListener) listener).selectionChanged(event);
- } catch (Exception e) {
+ }
+ catch (Exception e) {
Activator.log(e);
}
}
}
+ protected void onPeerListChanged() {
+ }
+
+ protected void onPeerSelected(PeerInfo info) {
+ }
}
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/RemoteFileSelectionDialog.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/RemoteFileSelectionDialog.java
index 23af441d2..ca8b5e949 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/launch/RemoteFileSelectionDialog.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/RemoteFileSelectionDialog.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 Wind River Systems, Inc. and others.
+ * 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
@@ -8,7 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
-package org.eclipse.tcf.internal.cdt.ui.launch;
+package org.eclipse.tcf.internal.debug.ui.launch;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.Dialog;
@@ -27,7 +27,7 @@ import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeItem;
-import org.eclipse.tcf.internal.cdt.ui.launch.FileSystemBrowserControl.FileInfo;
+import org.eclipse.tcf.internal.debug.ui.launch.FileSystemBrowserControl.FileInfo;
import org.eclipse.tcf.protocol.IPeer;
/**
@@ -41,7 +41,7 @@ public class RemoteFileSelectionDialog extends Dialog {
private boolean fForSave;
private Text fFileNameText;
- protected RemoteFileSelectionDialog(IShellProvider parentShell, int style) {
+ public RemoteFileSelectionDialog(IShellProvider parentShell, int style) {
super(parentShell);
setShellStyle(getShellStyle() | SWT.RESIZE);
fForSave = (style & SWT.SAVE) != 0;
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFDownloadTab.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFDownloadTab.java
new file mode 100644
index 000000000..e31dd31a1
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFDownloadTab.java
@@ -0,0 +1,361 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Xilinx, 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:
+ * Xilinx - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.internal.debug.ui.launch;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.tcf.internal.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tcf.internal.debug.ui.Activator;
+import org.eclipse.tcf.internal.debug.ui.ImageCache;
+import org.eclipse.tcf.protocol.JSON;
+import org.eclipse.tcf.util.TCFTask;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+public class TCFDownloadTab extends AbstractLaunchConfigurationTab {
+
+ private TableViewer viewer;
+ private Button button_add;
+ private Button button_edit;
+ private Button button_remove;
+ private MenuItem item_add;
+ private MenuItem item_edit;
+ private MenuItem item_remove;
+
+ private static final String[] column_ids = {
+ TCFLaunchDelegate.FILES_CONTEXT_FULL_NAME,
+ TCFLaunchDelegate.FILES_FILE_NAME,
+ };
+
+ private static final int[] column_size = {
+ 300,
+ 400,
+ };
+
+ private final List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
+
+ private static final String TAB_ID = "org.eclipse.tcf.launch.downloadTab"; //$NON-NLS-1$
+
+ private class FileListContentProvider implements IStructuredContentProvider {
+
+ public Object[] getElements(Object input) {
+ return list.toArray(new Map[list.size()]);
+ }
+
+ public void inputChanged(Viewer viewer, Object old_input, Object new_input) {
+ }
+
+ public void dispose() {
+ }
+ }
+
+ private class FileListLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+ public Image getColumnImage(Object element, int column) {
+ if (column == 0) return ImageCache.getImage(ImageCache.IMG_ATTRIBUTE);
+ return null;
+ }
+
+ public String getColumnText(Object element, int column) {
+ @SuppressWarnings("unchecked")
+ Map<String,String> e = (Map<String,String>)element;
+ Object o = e.get(column_ids[column]);
+ if (o == null) return ""; //$NON-NLS-1$
+ return o.toString();
+ }
+ }
+
+ private Exception init_error;
+
+ public String getName() {
+ return "Download"; //$NON-NLS-1$
+ }
+
+ @Override
+ public Image getImage() {
+ return ImageCache.getImage(ImageCache.IMG_DOWNLOAD_TAB);
+ }
+
+ @Override
+ public String getId() {
+ return TAB_ID;
+ }
+
+ public void createControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(1, false);
+ composite.setFont(parent.getFont());
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1));
+ createTable(composite);
+ setControl(composite);
+ }
+
+ private void createTable(Composite parent) {
+ Font font = parent.getFont();
+ Label map_label = new Label(parent, SWT.WRAP);
+ map_label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ map_label.setFont(font);
+ map_label.setText("Files to download during launch:"); //$NON-NLS-1$
+
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1));
+
+ viewer = new TableViewer(composite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
+ Table table = viewer.getTable();
+ table.setLayoutData(new GridData(GridData.FILL_BOTH));
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+ table.setFont(font);
+ viewer.setContentProvider(new FileListContentProvider());
+ viewer.setLabelProvider(new FileListLabelProvider());
+ viewer.setColumnProperties(column_ids);
+
+ for (int i = 0; i < column_ids.length; i++) {
+ TableColumn c = new TableColumn(table, SWT.NONE, i);
+ c.setText(column_ids[i]);
+ c.setWidth(column_size[i]);
+ }
+ createTableButtons(composite);
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ viewer.addDoubleClickListener(new IDoubleClickListener() {
+ @Override
+ public void doubleClick(DoubleClickEvent event) {
+ if (button_edit.isEnabled()) {
+ onEdit((IStructuredSelection)viewer.getSelection());
+ }
+ }
+ });
+ }
+
+ private void createTableButtons(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ composite.setFont(font);
+ composite.setLayout(layout);
+ GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
+ composite.setLayoutData(gd);
+
+ Menu menu = new Menu(viewer.getTable());
+ SelectionAdapter sel_adapter = null;
+
+ button_add = new Button(composite, SWT.PUSH);
+ button_add.setText(" &Add... "); //$NON-NLS-1$
+ gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+ button_add.setLayoutData(gd);
+ button_add.addSelectionListener(sel_adapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Map<String,Object> m = new HashMap<String,Object>();
+ DownloadFileDialog dialog = new DownloadFileDialog(getShell(), getPeerID(), m);
+ if (dialog.open() == Window.OK) {
+ list.add(m);
+ viewer.add(m);
+ viewer.setSelection(new StructuredSelection(m), true);
+ viewer.getTable().setFocus();
+ updateLaunchConfigurationDialog();
+ }
+ }
+ });
+ item_add = new MenuItem(menu, SWT.PUSH);
+ item_add.setText("&Add..."); //$NON-NLS-1$
+ item_add.addSelectionListener(sel_adapter);
+ item_add.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ADD));
+
+ button_edit = new Button(composite, SWT.PUSH);
+ button_edit.setText(" &Edit... "); //$NON-NLS-1$
+ button_edit.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_edit.addSelectionListener(sel_adapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ onEdit((IStructuredSelection)viewer.getSelection());
+ }
+ });
+ item_edit= new MenuItem(menu, SWT.PUSH);
+ item_edit.setText("&Edit..."); //$NON-NLS-1$
+ item_edit.addSelectionListener(sel_adapter);
+
+ button_remove = new Button(composite, SWT.PUSH);
+ button_remove.setText(" &Remove "); //$NON-NLS-1$
+ button_remove.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_remove.addSelectionListener(sel_adapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ for (Iterator<?> i = ((IStructuredSelection)viewer.getSelection()).iterator(); i.hasNext();) {
+ @SuppressWarnings("unchecked")
+ Map<String,String> m = (Map<String,String>)i.next();
+ list.remove(m);
+ viewer.remove(m);
+ }
+ updateLaunchConfigurationDialog();
+ }
+ });
+ item_remove = new MenuItem(menu, SWT.PUSH);
+ item_remove.setText("&Remove"); //$NON-NLS-1$
+ item_remove.addSelectionListener(sel_adapter);
+ item_remove.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ETOOL_DELETE));
+
+ viewer.getTable().setMenu(menu);
+ }
+
+ private void onEdit(IStructuredSelection selection) {
+ @SuppressWarnings("unchecked")
+ Map<String,Object> m = (Map<String,Object>)selection.getFirstElement();
+ DownloadFileDialog dialog = new DownloadFileDialog(getShell(), getPeerID(), m);
+ dialog.open();
+ viewer.refresh(m);
+ viewer.setSelection(new StructuredSelection(m), true);
+ viewer.getTable().setFocus();
+ updateLaunchConfigurationDialog();
+ }
+
+ private String getPeerID() {
+ String peer_id = "TCP:127.0.0.1:1534";
+ for (ILaunchConfigurationTab t : getLaunchConfigurationDialog().getTabs()) {
+ if (t instanceof TCFTargetTab) peer_id = ((TCFTargetTab)t).getPeerID();
+ }
+ return peer_id;
+ }
+
+ protected final TableViewer getViewer() {
+ return viewer;
+ }
+
+ public void initializeFrom(ILaunchConfiguration config) {
+ setErrorMessage(null);
+ setMessage(null);
+ try {
+ list.clear();
+ final String s = config.getAttribute(TCFLaunchDelegate.ATTR_FILES, ""); //$NON-NLS-1$
+ list.addAll(new TCFTask<Collection<Map<String,Object>>>(10000) {
+ @Override
+ public void run() {
+ try {
+ ArrayList<Map<String,Object>> l = new ArrayList<Map<String,Object>>();
+ if (s != null && s.length() > 0) {
+ @SuppressWarnings("unchecked")
+ Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)JSON.parseOne(s.getBytes("UTF-8"));
+ for (Map<String,Object> m : c) l.add(new HashMap<String,Object>(m));
+ }
+ done(l);
+ }
+ catch (Throwable e) {
+ error(e);
+ }
+ }
+ }.get());
+ viewer.setInput(config);
+ button_remove.setEnabled(!viewer.getSelection().isEmpty());
+ button_edit.setEnabled(((IStructuredSelection)viewer.getSelection()).size()==1);
+ item_remove.setEnabled(!viewer.getSelection().isEmpty());
+ item_edit.setEnabled(((IStructuredSelection)viewer.getSelection()).size()==1);
+ }
+ catch (Exception e) {
+ init_error = e;
+ setErrorMessage("Cannot read launch configuration: " + e); //$NON-NLS-1$
+ Activator.log(e);
+ }
+ }
+
+ public void performApply(ILaunchConfigurationWorkingCopy config) {
+ if (list.size() == 0) {
+ config.removeAttribute(TCFLaunchDelegate.ATTR_FILES);
+ }
+ else {
+ String s = new TCFTask<String>(10000) {
+ @Override
+ public void run() {
+ try {
+ done(JSON.toJSON(list));
+ }
+ catch (Throwable e) {
+ error(e);
+ }
+ }
+ }.getE();
+ config.setAttribute(TCFLaunchDelegate.ATTR_FILES, s);
+ }
+ }
+
+ public void setDefaults(ILaunchConfigurationWorkingCopy config) {
+ config.removeAttribute(TCFLaunchDelegate.ATTR_FILES);
+ }
+
+ @Override
+ protected void updateLaunchConfigurationDialog() {
+ super.updateLaunchConfigurationDialog();
+ button_remove.setEnabled(!viewer.getSelection().isEmpty());
+ button_edit.setEnabled(((IStructuredSelection)viewer.getSelection()).size() == 1);
+ item_remove.setEnabled(!viewer.getSelection().isEmpty());
+ item_edit.setEnabled(((IStructuredSelection)viewer.getSelection()).size() == 1);
+ }
+
+ @Override
+ public boolean isValid(ILaunchConfiguration config) {
+ setMessage(null);
+
+ if (init_error != null) {
+ setErrorMessage("Cannot read launch configuration: " + init_error); //$NON-NLS-1$
+ return false;
+ }
+
+ setErrorMessage(null);
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMainTab.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMainTab.java
index 8952dadd6..803cd369c 100644
--- a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMainTab.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMainTab.java
@@ -66,6 +66,8 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
comp.setLayout(topLayout);
createVerticalSpacer(comp, 1);
+ createHeader(comp);
+ createVerticalSpacer(comp, 1);
createProjectGroup(comp);
createApplicationGroup(comp);
createWorkingDirGroup(comp);
@@ -73,6 +75,13 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
createOptionButtons(comp, 1);
}
+ private void createHeader(Composite parent) {
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("Launching an application requires a target that supports Processes service");
+ GridData gd = new GridData();
+ label.setLayoutData(gd);
+ }
+
private void createProjectGroup(Composite parent) {
Group group = new Group(parent, SWT.NONE);
GridLayout layout = new GridLayout();
@@ -493,11 +502,11 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab {
}
public String getName() {
- return "Main";
+ return "Application";
}
@Override
public Image getImage() {
- return ImageCache.getImage(ImageCache.IMG_TCF);
+ return ImageCache.getImage(ImageCache.IMG_APPLICATION_TAB);
}
}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPathMapTab.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPathMapTab.java
index e02b3bcc3..2b35c3817 100644
--- a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPathMapTab.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPathMapTab.java
@@ -310,9 +310,9 @@ public class TCFPathMapTab extends AbstractLaunchConfigurationTab {
protected void updateLaunchConfigurationDialog() {
super.updateLaunchConfigurationDialog();
button_remove.setEnabled(!viewer.getSelection().isEmpty());
- button_edit.setEnabled(((IStructuredSelection)viewer.getSelection()).size()==1);
+ button_edit.setEnabled(((IStructuredSelection)viewer.getSelection()).size() == 1);
item_remove.setEnabled(!viewer.getSelection().isEmpty());
- item_edit.setEnabled(((IStructuredSelection)viewer.getSelection()).size()==1);
+ item_edit.setEnabled(((IStructuredSelection)viewer.getSelection()).size() == 1);
}
@Override
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTabGroup.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTabGroup.java
index 3d8f8c435..87a1dc941 100644
--- a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTabGroup.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTabGroup.java
@@ -24,8 +24,9 @@ public class TCFTabGroup extends AbstractLaunchConfigurationTabGroup {
public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
setTabs(new ILaunchConfigurationTab[] {
- new TCFMainTab(),
new TCFTargetTab(),
+ new TCFDownloadTab(),
+ new TCFMainTab(),
new TCFArgumentsTab(),
new EnvironmentTab(),
new TCFMemoryMapTab(),
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java
index c8738766f..60ef4b29c 100644
--- a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java
@@ -13,7 +13,6 @@ package org.eclipse.tcf.internal.debug.ui.launch;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -29,8 +28,6 @@ import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.TreeEvent;
-import org.eclipse.swt.events.TreeListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
@@ -39,10 +36,8 @@ import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
@@ -50,7 +45,6 @@ import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.tcf.internal.debug.launch.TCFLaunchDelegate;
import org.eclipse.tcf.internal.debug.launch.TCFLocalAgent;
@@ -58,11 +52,10 @@ import org.eclipse.tcf.internal.debug.launch.TCFUserDefPeer;
import org.eclipse.tcf.internal.debug.tests.TCFTestSuite;
import org.eclipse.tcf.internal.debug.ui.Activator;
import org.eclipse.tcf.internal.debug.ui.ImageCache;
+import org.eclipse.tcf.internal.debug.ui.launch.PeerListControl.PeerInfo;
import org.eclipse.tcf.internal.debug.ui.launch.setup.SetupWizardDialog;
-import org.eclipse.tcf.protocol.IChannel;
import org.eclipse.tcf.protocol.IPeer;
import org.eclipse.tcf.protocol.Protocol;
-import org.eclipse.tcf.services.ILocator;
import org.eclipse.tcf.services.IMemoryMap;
import org.eclipse.tcf.services.IPathMap;
import org.eclipse.tcf.util.TCFTask;
@@ -79,129 +72,13 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
private Button run_local_agent_button;
private Button use_local_agent_button;
private Text peer_id_text;
+ private PeerListControl peer_list;
private Tree peer_tree;
private Runnable update_peer_buttons;
- private final PeerInfo peer_info = new PeerInfo();
private Display display;
private Exception init_error;
private String mem_map_cfg;
- private static class PeerInfo {
- PeerInfo parent;
- String id;
- Map<String,String> attrs;
- PeerInfo[] children;
- boolean children_pending;
- Throwable children_error;
- IPeer peer;
- IChannel channel;
- ILocator locator;
- LocatorListener listener;
- Runnable item_update;
- }
-
- private class LocatorListener implements ILocator.LocatorListener {
-
- private final PeerInfo parent;
-
- LocatorListener(PeerInfo parent) {
- this.parent = parent;
- }
-
- public void peerAdded(final IPeer peer) {
- if (display == null) return;
- final String id = peer.getID();
- final HashMap<String,String> attrs = new HashMap<String,String>(peer.getAttributes());
- display.asyncExec(new Runnable() {
- public void run() {
- if (parent.children_error != null) return;
- PeerInfo[] arr = parent.children;
- for (PeerInfo p : arr) assert !p.id.equals(id);
- PeerInfo[] buf = new PeerInfo[arr.length + 1];
- System.arraycopy(arr, 0, buf, 0, arr.length);
- PeerInfo info = new PeerInfo();
- info.parent = parent;
- info.id = id;
- info.attrs = attrs;
- info.peer = peer;
- buf[arr.length] = info;
- parent.children = buf;
- updateItems(parent);
- }
- });
- }
-
- public void peerChanged(final IPeer peer) {
- if (display == null) return;
- final String id = peer.getID();
- final HashMap<String,String> attrs = new HashMap<String,String>(peer.getAttributes());
- display.asyncExec(new Runnable() {
- public void run() {
- if (parent.children_error != null) return;
- PeerInfo[] arr = parent.children;
- for (int i = 0; i < arr.length; i++) {
- if (arr[i].id.equals(id)) {
- arr[i].attrs = attrs;
- arr[i].peer = peer;
- updateItems(parent);
- }
- }
- }
- });
- }
-
- public void peerRemoved(final String id) {
- if (display == null) return;
- display.asyncExec(new Runnable() {
- public void run() {
- if (parent.children_error != null) return;
- PeerInfo[] arr = parent.children;
- PeerInfo[] buf = new PeerInfo[arr.length - 1];
- int j = 0;
- for (int i = 0; i < arr.length; i++) {
- if (arr[i].id.equals(id)) {
- final PeerInfo info = arr[i];
- Protocol.invokeLater(new Runnable() {
- public void run() {
- disconnectPeer(info);
- }
- });
- }
- else {
- buf[j++] = arr[i];
- }
- }
- parent.children = buf;
- updateItems(parent);
- }
- });
- }
-
- public void peerHeartBeat(final String id) {
- if (display == null) return;
- display.asyncExec(new Runnable() {
- public void run() {
- if (parent.children_error != null) return;
- PeerInfo[] arr = parent.children;
- for (int i = 0; i < arr.length; i++) {
- if (arr[i].id.equals(id)) {
- if (arr[i].children_error != null) {
- TreeItem item = findItem(arr[i]);
- boolean visible = item != null;
- while (visible && item != null) {
- if (!item.getExpanded()) visible = false;
- item = item.getParentItem();
- }
- if (visible) loadChildren(arr[i]);
- }
- break;
- }
- }
- }
- });
- }
- }
-
public void createControl(Composite parent) {
display = parent.getDisplay();
assert display != null;
@@ -281,108 +158,18 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
peer_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
peer_label.setFont(font);
- loadChildren(peer_info);
- createPeerListArea(group);
- }
-
- private void createPeerListArea(Composite parent) {
- Font font = parent.getFont();
- Composite composite = new Composite(parent, SWT.NONE);
- GridLayout layout = new GridLayout(2, false);
- composite.setFont(font);
- composite.setLayout(layout);
- composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1));
-
- peer_tree = new Tree(composite, SWT.VIRTUAL | SWT.BORDER | SWT.SINGLE);
- GridData gd = new GridData(GridData.FILL_BOTH);
- gd.minimumHeight = 150;
- gd.minimumWidth = 470;
- peer_tree.setLayoutData(gd);
-
- for (int i = 0; i < 6; i++) {
- TreeColumn column = new TreeColumn(peer_tree, SWT.LEAD, i);
- column.setMoveable(true);
- switch (i) {
- case 0:
- column.setText("Name");
- column.setWidth(160);
- break;
- case 1:
- column.setText("OS");
- column.setWidth(100);
- break;
- case 2:
- column.setText("User");
- column.setWidth(100);
- break;
- case 3:
- column.setText("Transport");
- column.setWidth(60);
- break;
- case 4:
- column.setText("Host");
- column.setWidth(100);
- break;
- case 5:
- column.setText("Port");
- column.setWidth(40);
- break;
- }
- }
-
- peer_tree.setHeaderVisible(true);
- peer_tree.setFont(font);
- peer_tree.addListener(SWT.SetData, new Listener() {
- public void handleEvent(Event event) {
- TreeItem item = (TreeItem)event.item;
- PeerInfo info = findPeerInfo(item);
- if (info == null) {
- updateItems(item.getParentItem(), false);
- }
- else {
- fillItem(item, info);
- updateLaunchConfigurationDialog();
- }
- }
- });
- peer_tree.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- final PeerInfo info = findPeerInfo(peer_id_text.getText());
- if (info == null) return;
- new PeerPropsDialog(getShell(), getImage(), info.attrs,
- info.peer instanceof TCFUserDefPeer).open();
- if (!(info.peer instanceof TCFUserDefPeer)) return;
- Protocol.invokeLater(new Runnable() {
- public void run() {
- ((TCFUserDefPeer)info.peer).updateAttributes(info.attrs);
- TCFUserDefPeer.savePeers();
- }
- });
- }
+ peer_list = new PeerListControl(group) {
@Override
- public void widgetSelected(SelectionEvent e) {
- TreeItem[] selections = peer_tree.getSelection();
- if (selections.length > 0) {
- assert selections.length == 1;
- PeerInfo info = findPeerInfo(selections[0]);
- if (info != null) peer_id_text.setText(getPath(info));
- }
+ protected void onPeerListChanged() {
updateLaunchConfigurationDialog();
}
- });
- peer_tree.addTreeListener(new TreeListener() {
-
- public void treeCollapsed(TreeEvent e) {
- updateItems((TreeItem)e.item, false);
- }
-
- public void treeExpanded(TreeEvent e) {
- updateItems((TreeItem)e.item, true);
+ @Override
+ protected void onPeerSelected(PeerInfo info) {
+ peer_id_text.setText(peer_list.getPath(info));
}
- });
-
- createPeerButtons(composite);
+ };
+ peer_tree = peer_list.getTree();
+ createPeerButtons(peer_tree.getParent());
}
private void createPeerButtons(Composite parent) {
@@ -425,7 +212,7 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
button_edit.addSelectionListener(sel_adapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- final PeerInfo info = findPeerInfo(peer_id_text.getText());
+ final PeerInfo info = peer_list.findPeerInfo(peer_id_text.getText());
if (info == null) return;
if (new PeerPropsDialog(getShell(), getImage(), info.attrs,
info.peer instanceof TCFUserDefPeer).open() != Window.OK) return;
@@ -448,7 +235,7 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
button_remove.addSelectionListener(sel_adapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- final PeerInfo info = findPeerInfo(peer_id_text.getText());
+ final PeerInfo info = peer_list.findPeerInfo(peer_id_text.getText());
if (info == null) return;
if (!(info.peer instanceof TCFUserDefPeer)) return;
peer_id_text.setText("");
@@ -500,7 +287,7 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
public void run() {
boolean local = use_local_agent_button.getSelection();
- PeerInfo info = findPeerInfo(peer_id_text.getText());
+ PeerInfo info = peer_list.findPeerInfo(peer_id_text.getText());
button_new.setEnabled(!local);
button_edit.setEnabled(info != null && !local);
button_remove.setEnabled(info != null && info.peer instanceof TCFUserDefPeer && !local);
@@ -530,7 +317,7 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
peer_tree.setEnabled(true);
peer_id_text.setEnabled(true);
String id = peer_id_text.getText();
- TreeItem item = findItem(id);
+ TreeItem item = peer_list.findItem(id);
if (item != null) peer_tree.setSelection(item);
else peer_tree.deselectAll();
}
@@ -538,17 +325,6 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
super.updateLaunchConfigurationDialog();
}
- @Override
- public void dispose() {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- disconnectPeer(peer_info);
- display = null;
- }
- });
- super.dispose();
- }
-
public String getName() {
return "Target";
}
@@ -568,9 +344,8 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
setMessage(null);
try {
String id = configuration.getAttribute(TCFLaunchDelegate.ATTR_PEER_ID, "");
- TreeItem item = findItem(id);
- if (item != null) peer_tree.setSelection(item);
peer_id_text.setText(id);
+ peer_list.setInitialSelection(id);
run_local_agent_button.setSelection(configuration.getAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_AGENT, false));
use_local_agent_button.setSelection(configuration.getAttribute(TCFLaunchDelegate.ATTR_USE_LOCAL_AGENT, true));
mem_map_cfg = configuration.getAttribute(TCFLaunchDelegate.ATTR_MEMORY_MAP, "null");
@@ -613,324 +388,8 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
return true;
}
- private void disconnectPeer(final PeerInfo info) {
- assert Protocol.isDispatchThread();
- if (info.children != null) {
- for (PeerInfo p : info.children) disconnectPeer(p);
- }
- if (info.listener != null) {
- info.locator.removeListener(info.listener);
- info.listener = null;
- info.locator = null;
- }
- if (info.channel != null) {
- info.channel.close();
- }
- }
-
- private boolean canHaveChildren(PeerInfo parent) {
- return parent == peer_info || parent.attrs.get(IPeer.ATTR_PROXY) != null;
- }
-
- private void loadChildren(final PeerInfo parent) {
- assert Thread.currentThread() == display.getThread();
- if (parent.children_pending) return;
- assert parent.children == null;
- parent.children_pending = true;
- parent.children_error = null;
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- assert parent.listener == null;
- assert parent.channel == null;
- if (!canHaveChildren(parent)) {
- doneLoadChildren(parent, null, new PeerInfo[0]);
- }
- else if (parent == peer_info) {
- peer_info.locator = Protocol.getLocator();
- doneLoadChildren(parent, null, createLocatorListener(peer_info));
- }
- else {
- final IChannel channel = parent.peer.openChannel();
- parent.channel = channel;
- parent.channel.addChannelListener(new IChannel.IChannelListener() {
- boolean opened = false;
- boolean closed = false;
- public void congestionLevel(int level) {
- }
- public void onChannelClosed(final Throwable error) {
- assert !closed;
- if (parent.channel != channel) return;
- if (!opened) {
- doneLoadChildren(parent, error, null);
- }
- else {
- if (display != null) {
- display.asyncExec(new Runnable() {
- public void run() {
- if (parent.children_pending) return;
- parent.children = null;
- parent.children_error = error;
- updateItems(parent);
- }
- });
- }
- }
- closed = true;
- parent.channel = null;
- parent.locator = null;
- parent.listener = null;
- }
- public void onChannelOpened() {
- assert !opened;
- assert !closed;
- if (parent.channel != channel) return;
- opened = true;
- parent.locator = parent.channel.getRemoteService(ILocator.class);
- if (parent.locator == null) {
- parent.channel.terminate(new Exception("Service not supported: " + ILocator.NAME));
- }
- else {
- doneLoadChildren(parent, null, createLocatorListener(parent));
- }
- }
- });
- }
- }
- });
- }
-
- private PeerInfo[] createLocatorListener(PeerInfo peer) {
- assert Protocol.isDispatchThread();
- Map<String,IPeer> map = peer.locator.getPeers();
- PeerInfo[] buf = new PeerInfo[map.size()];
- int n = 0;
- for (IPeer p : map.values()) {
- PeerInfo info = new PeerInfo();
- info.parent = peer;
- info.id = p.getID();
- info.attrs = new HashMap<String,String>(p.getAttributes());
- info.peer = p;
- buf[n++] = info;
- }
- peer.listener = new LocatorListener(peer);
- peer.locator.addListener(peer.listener);
- return buf;
- }
-
- private void doneLoadChildren(final PeerInfo parent, final Throwable error, final PeerInfo[] children) {
- assert Protocol.isDispatchThread();
- assert error == null || children == null;
- if (display == null) return;
- display.asyncExec(new Runnable() {
- public void run() {
- assert parent.children_pending;
- assert parent.children == null;
- parent.children_pending = false;
- parent.children = children;
- parent.children_error = error;
- updateItems(parent);
- }
- });
- }
-
- private ArrayList<PeerInfo> filterPeerList(PeerInfo parent, boolean expanded) {
- ArrayList<PeerInfo> lst = new ArrayList<PeerInfo>();
- HashMap<String,PeerInfo> local_agents = new HashMap<String,PeerInfo>();
- HashSet<String> ids = new HashSet<String>();
- for (PeerInfo p : parent.children) {
- String id = p.attrs.get(IPeer.ATTR_AGENT_ID);
- if (id == null) continue;
- if (!"TCP".equals(p.attrs.get(IPeer.ATTR_TRANSPORT_NAME))) continue;
- if (!"127.0.0.1".equals(p.attrs.get(IPeer.ATTR_IP_HOST))) continue;
- local_agents.put(id, p);
- ids.add(p.id);
- }
- for (PeerInfo p : parent.children) {
- PeerInfo i = local_agents.get(p.attrs.get(IPeer.ATTR_AGENT_ID));
- if (i != null && i != p) continue;
- lst.add(p);
- }
- if (parent != peer_info && expanded) {
- for (PeerInfo p : peer_info.children) {
- if (p.peer instanceof TCFUserDefPeer && !ids.contains(p.id)) {
- PeerInfo x = new PeerInfo();
- x.parent = parent;
- x.id = p.id;
- x.attrs = p.attrs;
- x.peer = p.peer;
- ids.add(x.id);
- lst.add(x);
- }
- }
- }
- return lst;
- }
-
- private void updateItems(TreeItem parent_item, boolean reload) {
- final PeerInfo parent_info = findPeerInfo(parent_item);
- if (parent_info == null) {
- parent_item.setText("Invalid");
- }
- else {
- if (reload && parent_info.children_error != null) {
- loadChildren(parent_info);
- }
- display.asyncExec(new Runnable() {
- public void run() {
- updateItems(parent_info);
- }
- });
- }
- }
-
- private void updateItems(final PeerInfo parent) {
- if (display == null) return;
- assert Thread.currentThread() == display.getThread();
- parent.item_update = new Runnable() {
- public void run() {
- if (display == null) return;
- if (parent.item_update != this) return;
- if (Thread.currentThread() != display.getThread()) {
- display.asyncExec(this);
- return;
- }
- parent.item_update = null;
- TreeItem[] items = null;
- boolean expanded = true;
- if (parent.children == null || parent.children_error != null) {
- if (parent == peer_info) {
- peer_tree.setItemCount(1);
- items = peer_tree.getItems();
- }
- else {
- TreeItem item = findItem(parent);
- if (item == null) return;
- expanded = item.getExpanded();
- item.setItemCount(1);
- items = item.getItems();
- }
- assert items.length == 1;
- if (parent.children_pending) {
- items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
- fillItem(items[0], "Connecting...");
- }
- else if (parent.children_error != null) {
- String msg = parent.children_error.getMessage();
- if (msg == null) msg = parent.children_error.getClass().getName();
- else msg = msg.replace('\n', ' ');
- items[0].setForeground(display.getSystemColor(SWT.COLOR_RED));
- fillItem(items[0], msg);
- }
- else if (expanded) {
- loadChildren(parent);
- items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
- fillItem(items[0], "Connecting...");
- }
- else {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- disconnectPeer(parent);
- }
- });
- fillItem(items[0], "");
- }
- }
- else {
- ArrayList<PeerInfo> lst = null;
- if (parent == peer_info) {
- lst = filterPeerList(parent, expanded);
- peer_tree.setItemCount(lst.size() > 0 ? lst.size() : 1);
- items = peer_tree.getItems();
- }
- else {
- TreeItem item = findItem(parent);
- if (item == null) return;
- expanded = item.getExpanded();
- lst = filterPeerList(parent, expanded);
- item.setItemCount(expanded && lst.size() > 0 ? lst.size() : 1);
- items = item.getItems();
- }
- if (expanded && lst.size() > 0) {
- assert items.length == lst.size();
- for (int i = 0; i < items.length; i++) fillItem(items[i], lst.get(i));
- }
- else if (expanded) {
- fillItem(items[0], "No peers");
- }
- else {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- disconnectPeer(parent);
- }
- });
- fillItem(items[0], "");
- }
- }
- updateLaunchConfigurationDialog();
- }
- };
- if (parent.children_pending) parent.item_update.run();
- else Protocol.invokeLater(200, parent.item_update);
- }
-
- private TreeItem findItem(String path) {
- assert Thread.currentThread() == display.getThread();
- if (path == null) return null;
- int z = path.lastIndexOf('/');
- if (z < 0) {
- int n = peer_tree.getItemCount();
- for (int i = 0; i < n; i++) {
- TreeItem x = peer_tree.getItem(i);
- PeerInfo p = (PeerInfo)x.getData("TCFPeerInfo");
- if (p != null && p.id.equals(path)) return x;
- }
- }
- else {
- TreeItem y = findItem(path.substring(0, z));
- if (y == null) return null;
- String id = path.substring(z + 1);
- int n = y.getItemCount();
- for (int i = 0; i < n; i++) {
- TreeItem x = y.getItem(i);
- PeerInfo p = (PeerInfo)x.getData("TCFPeerInfo");
- if (p != null && p.id.equals(id)) return x;
- }
- }
- return null;
- }
-
- private TreeItem findItem(PeerInfo info) {
- if (info == null) return null;
- assert info.parent != null;
- if (info.parent == peer_info) {
- int n = peer_tree.getItemCount();
- for (int i = 0; i < n; i++) {
- TreeItem x = peer_tree.getItem(i);
- if (x.getData("TCFPeerInfo") == info) return x;
- }
- }
- else {
- TreeItem y = findItem(info.parent);
- if (y == null) return null;
- int n = y.getItemCount();
- for (int i = 0; i < n; i++) {
- TreeItem x = y.getItem(i);
- if (x.getData("TCFPeerInfo") == info) return x;
- }
- }
- return null;
- }
-
- private PeerInfo findPeerInfo(String path) {
- TreeItem i = findItem(path);
- if (i == null) return null;
- return (PeerInfo)i.getData("TCFPeerInfo");
- }
-
- private PeerInfo findPeerInfo(TreeItem item) {
- assert Thread.currentThread() == display.getThread();
- if (item == null) return peer_info;
- return (PeerInfo)item.getData("TCFPeerInfo");
+ public String getPeerID() {
+ return peer_id_text.getText();
}
private void runDiagnostics(boolean loop) {
@@ -955,7 +414,7 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
}
}
else {
- PeerInfo info = findPeerInfo(peer_id_text.getText());
+ PeerInfo info = peer_list.findPeerInfo(peer_id_text.getText());
if (info == null) return;
peer = info.peer;
}
@@ -1066,46 +525,4 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
}
});
}
-
- private void fillItem(TreeItem item, PeerInfo info) {
- assert Thread.currentThread() == display.getThread();
- Object data = item.getData("TCFPeerInfo");
- if (data != null && data != info) item.removeAll();
- item.setData("TCFPeerInfo", info);
- String text[] = new String[6];
- text[0] = info.attrs.get(IPeer.ATTR_NAME);
- text[1] = info.attrs.get(IPeer.ATTR_OS_NAME);
- text[2] = info.attrs.get(IPeer.ATTR_USER_NAME);
- text[3] = info.attrs.get(IPeer.ATTR_TRANSPORT_NAME);
- text[4] = info.attrs.get(IPeer.ATTR_IP_HOST);
- text[5] = info.attrs.get(IPeer.ATTR_IP_PORT);
- for (int i = 0; i < text.length; i++) {
- if (text[i] == null) text[i] = "";
- }
- item.setText(text);
- item.setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
- item.setImage(ImageCache.getImage(getImageName(info)));
- if (!canHaveChildren(info)) item.setItemCount(0);
- else if (info.children == null || info.children_error != null) item.setItemCount(1);
- else item.setItemCount(info.children.length);
- }
-
- private void fillItem(TreeItem item, String text) {
- item.setText(text);
- item.setData("TCFPeerInfo", null);
- int n = peer_tree.getColumnCount();
- for (int i = 1; i < n; i++) item.setText(i, "");
- item.setImage((Image)null);
- item.removeAll();
- }
-
- private String getPath(PeerInfo info) {
- if (info == peer_info) return "";
- if (info.parent == peer_info) return info.id;
- return getPath(info.parent) + "/" + info.id;
- }
-
- private String getImageName(PeerInfo info) {
- return ImageCache.IMG_TARGET_TAB;
- }
}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java
index 056f21049..b2274c526 100644
--- a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.tcf.internal.debug.ui.model;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -1962,6 +1963,9 @@ public class TCFModel implements ITCFModel, IElementContentProvider, IElementLab
if (!multiline && error instanceof IErrorReport) {
msg = Command.toErrorString(((IErrorReport)error).getAttributes());
}
+ else if (error instanceof UnknownHostException) {
+ msg = "Unknown host: " + error.getMessage();
+ }
else {
msg = error.getLocalizedMessage();
}
@@ -1976,8 +1980,8 @@ public class TCFModel implements ITCFModel, IElementContentProvider, IElementLab
else if (ch != '.' && ch != ';') {
buf.append(';');
}
- buf.append("Caused by:");
- buf.append(multiline ? '\n' : ' ');
+ if (multiline) buf.append("Caused by:\n");
+ else buf.append(' ');
}
}
if (buf.length() > 0) {
diff --git a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java
index e58b05355..edac36a91 100644
--- a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java
+++ b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/launch/TCFLaunchDelegate.java
@@ -62,8 +62,23 @@ public class TCFLaunchDelegate extends LaunchConfigurationDelegate {
ATTR_USE_LOCAL_AGENT = ITCFConstants.ID_TCF_DEBUG_MODEL + ".UseLocalAgent",
ATTR_SIGNALS_DONT_STOP = ITCFConstants.ID_TCF_DEBUG_MODEL + ".SignalsDontStop",
ATTR_SIGNALS_DONT_PASS = ITCFConstants.ID_TCF_DEBUG_MODEL + ".SignalsDontPath",
+ ATTR_FILES = ITCFConstants.ID_TCF_DEBUG_MODEL + ".Files",
ATTR_PATH_MAP = ITCFConstants.ID_TCF_DEBUG_MODEL + ".PathMap",
- ATTR_MEMORY_MAP = ITCFConstants.ID_TCF_DEBUG_MODEL + ".MemoryMap";
+ ATTR_MEMORY_MAP = ITCFConstants.ID_TCF_DEBUG_MODEL + ".MemoryMap",
+ ATTR_ATTACH_PATH = ITCFConstants.ID_TCF_DEBUG_MODEL + ".Attach";
+
+ public static final String
+ FILES_CONTEXT_FULL_NAME = "Context",
+ FILES_CONTEXT_ID = "ContextID",
+ FILES_FILE_NAME = "File",
+ FILES_LOAD_SYMBOLS = "LoadSymbols",
+ FILES_RELOCATE = "Relocate",
+ FILES_ADDRESS = IMemoryMap.PROP_ADDRESS,
+ FILES_OFFSET = IMemoryMap.PROP_OFFSET,
+ FILES_SIZE = IMemoryMap.PROP_SIZE,
+ FILES_DOWNLOAD = "Download",
+ FILES_SET_PC = "SetPC",
+ FILES_ENABLE_OSA = "EnableOSA";
public static class PathMapRule extends TCFPathMapRule {
diff --git a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/ElfLoader.java b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/ElfLoader.java
new file mode 100644
index 000000000..043682617
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/ElfLoader.java
@@ -0,0 +1,470 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Xilinx, 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:
+ * Xilinx - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.internal.debug.model;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.tcf.internal.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IToken;
+import org.eclipse.tcf.protocol.Protocol;
+import org.eclipse.tcf.services.IMemory;
+import org.eclipse.tcf.services.IRegisters;
+import org.eclipse.tcf.services.IRegisters.RegistersContext;
+import org.eclipse.tcf.services.IRunControl;
+
+public class ElfLoader implements Runnable {
+
+ private final IChannel channel;
+
+ /* Loader parameters */
+ private Map<String,Object> args;
+ private boolean download;
+ private boolean set_pc;
+ private Runnable done;
+
+ /* Services */
+ private final IRunControl service_rc;
+ private final IMemory service_mem;
+ private final IRegisters service_regs;
+
+ /* Pending commands */
+ private final Set<IToken> cmds = new HashSet<IToken>();
+
+ /* Debug contexts */
+ private final Map<String,IRunControl.RunControlContext> contexts =
+ new HashMap<String,IRunControl.RunControlContext>();
+
+ /* Running debug contexts */
+ private final Set<String> running = new HashSet<String>();
+
+ private List<Throwable> errors = new ArrayList<Throwable>();
+
+ private final IRunControl.RunControlListener rc_listener= new IRunControl.RunControlListener() {
+ @Override
+ public void contextSuspended(String id, String pc, String reason, Map<String, Object> params) {
+ running.remove(id);
+ run();
+ }
+ @Override
+ public void contextResumed(String id) {
+ running.add(id);
+ run();
+ }
+ @Override
+ public void contextRemoved(String[] context_ids) {
+ for (String id : context_ids) {
+ contexts.remove(id);
+ running.remove(id);
+ }
+ run();
+ }
+ @Override
+ public void contextException(String context, String msg) {
+ }
+ @Override
+ public void contextChanged(IRunControl.RunControlContext[] contexts) {
+ }
+ @Override
+ public void contextAdded(IRunControl.RunControlContext[] arr) {
+ for (IRunControl.RunControlContext ctx : arr) {
+ String id = ctx.getID();
+ contexts.put(id, ctx);
+ if (ctx.hasState()) running.add(id);
+ }
+ run();
+ }
+ @Override
+ public void containerSuspended(String context, String pc, String reason,
+ Map<String, Object> params, String[] suspended_ids) {
+ for (String id : suspended_ids) running.remove(id);
+ run();
+ }
+ @Override
+ public void containerResumed(String[] context_ids) {
+ for (String id : context_ids) running.add(id);
+ run();
+ }
+ };
+
+ private final IRunControl.DoneGetContext done_ctx_get_context = new IRunControl.DoneGetContext() {
+ @Override
+ public void doneGetContext(IToken token, Exception error, final IRunControl.RunControlContext context) {
+ cmds.remove(token);
+ if (error != null) {
+ errors.add(error);
+ }
+ else {
+ final String id = context.getID();
+ contexts.put(id, context);
+ if (context.hasState()) {
+ cmds.add(context.getState(new IRunControl.DoneGetState() {
+ @Override
+ public void doneGetState(IToken token, Exception error,
+ boolean suspended, String pc, String reason, Map<String, Object> params) {
+ cmds.remove(token);
+ if (error != null) {
+ errors.add(error);
+ }
+ else if (!suspended) {
+ running.add(id);
+ }
+ run();
+ }
+ }));
+ }
+ }
+ run();
+ }
+ };
+
+ private final IRunControl.DoneGetChildren done_ctx_get_children = new IRunControl.DoneGetChildren() {
+ @Override
+ public void doneGetChildren(IToken token, Exception error, String[] context_ids) {
+ cmds.remove(token);
+ if (error != null) {
+ errors.add(error);
+ }
+ else if (context_ids != null) {
+ for (String id : context_ids) {
+ cmds.add(service_rc.getContext(id, done_ctx_get_context));
+ cmds.add(service_rc.getChildren(id, this));
+ }
+ }
+ run();
+ }
+ };
+
+ private final IMemory.DoneGetContext done_mem_get_context = new IMemory.DoneGetContext() {
+ @Override
+ public void doneGetContext(IToken token, Exception error, IMemory.MemoryContext context) {
+ cmds.remove(token);
+ if (error != null) {
+ errors.add(error);
+ }
+ else {
+ assert context != null;
+ mem_ctx = context;
+ File fnm = null;
+ try {
+ fnm = new File((String)args.get(TCFLaunchDelegate.FILES_FILE_NAME));
+ file = new RandomAccessFile(fnm, "r");
+ try {
+ downloadFile(context);
+ }
+ finally {
+ file.close();
+ }
+ }
+ catch (Exception e) {
+ if (fnm != null) e = new Exception("Cannot read '" + fnm.getName() + "'", e);
+ errors.add(e);
+ }
+ file = null;
+ }
+ run();
+ }
+ };
+
+ private final IRegisters.DoneGetChildren done_regs_get_children = new IRegisters.DoneGetChildren() {
+ @Override
+ public void doneGetChildren(IToken token, Exception error, String[] context_ids) {
+ cmds.remove(token);
+ if (error != null) errors.add(error);
+ if (context_ids != null) {
+ for (String id : context_ids) {
+ cmds.add(service_regs.getContext(id, new IRegisters.DoneGetContext() {
+ @Override
+ public void doneGetContext(IToken token, Exception error, RegistersContext context) {
+ cmds.remove(token);
+ if (error != null) errors.add(error);
+ if (context != null) {
+ if (IRegisters.ROLE_PC.equals(context.getRole())) {
+ reg_pc = context;
+ setEntryAddress();
+ }
+ else if (reg_pc == null && errors.size() == 0) {
+ cmds.add(service_regs.getChildren(context.getID(), done_regs_get_children));
+ }
+ }
+ run();
+ }
+ }));
+ }
+ }
+ run();
+ }
+ };
+
+ private static final int PT_LOAD = 1;
+
+ private boolean listener_ok;
+ private boolean started_context_retrieval;
+ private boolean started_reginfo_retrieval;
+ private boolean disposed;
+
+ private RandomAccessFile file;
+ private boolean big_endian;
+ private boolean elf64;
+ private IMemory.MemoryContext mem_ctx;
+ private BigInteger entry_addr;
+ private RegistersContext reg_pc;
+ private long start_time;
+
+ ElfLoader(IChannel channel) {
+ this.channel = channel;
+ service_rc = channel.getRemoteService(IRunControl.class);
+ service_mem = channel.getRemoteService(IMemory.class);
+ service_regs = channel.getRemoteService(IRegisters.class);
+ }
+
+ void load(Map<String,Object> args, Runnable done) {
+ this.args = args;
+ this.done = done;
+ Boolean b1 = (Boolean)args.get(TCFLaunchDelegate.FILES_DOWNLOAD);
+ Boolean b2 = (Boolean)args.get(TCFLaunchDelegate.FILES_SET_PC);
+ download = b1 != null && b1.booleanValue();
+ set_pc = b2 != null && b2.booleanValue();
+ start_time = System.currentTimeMillis();
+ started_reginfo_retrieval = false;
+ entry_addr = null;
+ mem_ctx = null;
+ reg_pc = null;
+ Protocol.invokeLater(this);
+ }
+
+ void dispose() {
+ if (service_rc != null) service_rc.removeListener(rc_listener);
+ disposed = true;
+ }
+
+ private BigInteger readNumberX() throws IOException {
+ int size = elf64 ? 8 : 4;
+ byte[] buf = new byte[size + 1];
+ file.readFully(buf, 1, size);
+ if (!big_endian) {
+ for (int i = 0; i < size / 2; i++) {
+ byte x = buf[i + 1];
+ buf[i + 1] = buf[size - i];
+ buf[size - i] = x;
+ }
+ }
+ return new BigInteger(buf);
+ }
+
+ private int readInt2() throws IOException {
+ int x = file.readUnsignedByte();
+ int y = file.readUnsignedByte();
+ return big_endian ? (x << 8) + y : x + (y << 8);
+ }
+
+ private int readInt4() throws IOException {
+ int x = readInt2();
+ int y = readInt2();
+ return big_endian ? (x << 16) + y : x + (y << 16);
+ }
+
+ private void downloadFile(IMemory.MemoryContext context) throws Exception {
+ if (file.readByte() != 0x7f || file.readByte() != 'E' ||
+ file.readByte() != 'L' || file.readByte() != 'F')
+ throw new IOException("Not an ELF file");
+ switch (file.readByte()) {
+ case 1:
+ elf64 = false;
+ break;
+ case 2:
+ elf64 = true;
+ break;
+ default:
+ throw new IOException("Invalid ELF file");
+ }
+ switch (file.readByte()) {
+ case 1:
+ big_endian = false;
+ break;
+ case 2:
+ big_endian = true;
+ break;
+ default:
+ throw new IOException("Invalid ELF file");
+ }
+
+ file.seek(24);
+
+ entry_addr = readNumberX();
+ if (download) {
+ BigInteger phoff = readNumberX();
+ @SuppressWarnings("unused")
+ BigInteger shoff = readNumberX();
+ file.skipBytes(6);
+ int phentsize = readInt2();
+ int phnum = readInt2();
+
+ for (int n = 0; n < phnum; n++) {
+ file.seek(phoff.longValue() + n * phentsize);
+ int p_type = readInt4();
+ if (p_type != PT_LOAD) continue;
+ if (elf64) readInt4();
+ BigInteger p_offset = readNumberX();
+ BigInteger p_vaddr = readNumberX();
+ @SuppressWarnings("unused")
+ BigInteger p_paddr = readNumberX();
+ BigInteger p_filesz = readNumberX();
+ BigInteger p_memsz = readNumberX();
+ byte buf[] = new byte[p_filesz.intValue()];
+ file.seek(p_offset.longValue());
+ file.readFully(buf);
+ cmds.add(context.set(p_vaddr, 4, buf, 0, buf.length, 0, new IMemory.DoneMemory() {
+ @Override
+ public void doneMemory(IToken token, IMemory.MemoryError error) {
+ cmds.remove(token);
+ if (error != null) errors.add(error);
+ run();
+ }
+ }));
+ BigInteger fill = p_memsz.subtract(p_filesz);
+ if (fill.compareTo(BigInteger.ZERO) > 0) {
+ buf = new byte[4];
+ cmds.add(context.fill(p_vaddr.add(p_filesz), 4, buf, fill.intValue(), 0, new IMemory.DoneMemory() {
+ @Override
+ public void doneMemory(IToken token, IMemory.MemoryError error) {
+ cmds.remove(token);
+ if (error != null) errors.add(error);
+ run();
+ }
+ }));
+ }
+ }
+ }
+ }
+
+ private void setEntryAddress() {
+ byte[] value = new byte[reg_pc.getSize()];
+ boolean big_endian = reg_pc.isBigEndian();
+
+ BigInteger n = entry_addr;
+ for (int i = 0; i < value.length; i++) {
+ value[big_endian ? value.length - i - 1 : i] = n.byteValue();
+ n = n.shiftRight(8);
+ }
+
+ cmds.add(reg_pc.set(value, new IRegisters.DoneSet() {
+ @Override
+ public void doneSet(IToken token, Exception error) {
+ cmds.remove(token);
+ if (error != null) errors.add(error);
+ run();
+ }
+ }));
+ }
+
+ private String getFullName(IRunControl.RunControlContext ctx) {
+ if (ctx == null) return null;
+ String name = ctx.getName();
+ if (name == null) name = ctx.getID();
+ String parent = ctx.getParentID();
+ if (parent == null) return "/" + name;
+ String path = getFullName(contexts.get(parent));
+ if (path == null) return null;
+ return path + '/' + name;
+ }
+
+ public void run() {
+ /* Wait for pending commands */
+ if (cmds.size() > 0) return;
+
+ if (disposed) return;
+ if (done == null) return;
+
+ if (service_rc == null || service_mem == null) {
+ errors.add(new Error("No services, cannot do anything"));
+ }
+
+ if (!listener_ok) {
+ service_rc.addListener(rc_listener);
+ listener_ok = true;
+ }
+
+ if (errors.size() == 0 && !started_context_retrieval) {
+ /* Retrieve debug context information */
+ cmds.add(service_rc.getChildren(null, done_ctx_get_children));
+ started_context_retrieval = true;
+ return;
+ }
+
+ /* Suspend everything */
+ if (errors.size() == 0 && running.size() > 0) {
+ if (System.currentTimeMillis() - start_time < 5000) {
+ for (final String id : running) {
+ IRunControl.RunControlContext ctx = contexts.get(id);
+ if (ctx != null) {
+ cmds.add(ctx.suspend(new IRunControl.DoneCommand() {
+ @Override
+ public void doneCommand(IToken token, Exception error) {
+ cmds.remove(token);
+ if (error != null && running.contains(id)) errors.add(error);
+ run();
+ }
+ }));
+ }
+ }
+ if (cmds.size() > 0) return;
+ }
+ errors.add(new Exception("Cannot stop the target"));
+ }
+
+ if (errors.size() == 0 && mem_ctx == null) {
+ /* Download the file */
+ String id = (String)args.get(TCFLaunchDelegate.FILES_CONTEXT_ID);
+ if (id != null) {
+ cmds.add(service_mem.getContext(id, done_mem_get_context));
+ return;
+ }
+ String name = (String)args.get(TCFLaunchDelegate.FILES_CONTEXT_FULL_NAME);
+ if (name != null) {
+ for (IRunControl.RunControlContext ctx : contexts.values()) {
+ if (name.equals(getFullName(ctx))) {
+ cmds.add(service_mem.getContext(ctx.getID(), done_mem_get_context));
+ }
+ }
+ if (cmds.size() > 0) return;
+ }
+ /* Wait for context */
+ if (System.currentTimeMillis() - start_time < 5000) {
+ Protocol.invokeLater(200, this);
+ return;
+ }
+ errors.add(new Exception(
+ "Context not found: " +
+ (name != null ? name : id)));
+ }
+
+ if (errors.size() == 0 && mem_ctx != null && entry_addr != null &&
+ set_pc && !started_reginfo_retrieval && service_regs != null) {
+ started_reginfo_retrieval = true;
+ cmds.add(service_regs.getChildren(mem_ctx.getID(), done_regs_get_children));
+ return;
+ }
+ /* All done */
+ if (errors.size() > 0) channel.terminate(new Exception("Download error", errors.get(0)));
+ Protocol.invokeLater(done);
+ done = null;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java
index b926b9889..5535096a9 100644
--- a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java
+++ b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java
@@ -40,6 +40,7 @@ import org.eclipse.tcf.protocol.IChannel;
import org.eclipse.tcf.protocol.IPeer;
import org.eclipse.tcf.protocol.IService;
import org.eclipse.tcf.protocol.IToken;
+import org.eclipse.tcf.protocol.JSON;
import org.eclipse.tcf.protocol.Protocol;
import org.eclipse.tcf.services.IContextQuery;
import org.eclipse.tcf.services.IFileSystem;
@@ -412,6 +413,34 @@ public class TCFLaunch extends Launch {
}
}
+ if (cfg != null && getService(IMemory.class) != null) {
+ String s = cfg.getAttribute(TCFLaunchDelegate.ATTR_FILES, (String)null);
+ if (s != null) {
+ @SuppressWarnings("unchecked")
+ Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)JSON.parseOne(s.getBytes("UTF-8"));
+ final ElfLoader loader = new ElfLoader(channel);
+ for (final Map<String,Object> m : c) {
+ Boolean b1 = (Boolean)m.get(TCFLaunchDelegate.FILES_DOWNLOAD);
+ Boolean b2 = (Boolean)m.get(TCFLaunchDelegate.FILES_SET_PC);
+ if (b1 != null && b1.booleanValue() || b2 != null && b2.booleanValue()) {
+ new LaunchStep() {
+ @Override
+ void start() throws Exception {
+ loader.load(m, this);
+ }
+ };
+ }
+ }
+ new LaunchStep() {
+ @Override
+ void start() throws Exception {
+ loader.dispose();
+ done();
+ }
+ };
+ }
+ }
+
// Call client launch sequence:
new LaunchStep() {
@Override
@@ -478,7 +507,7 @@ public class TCFLaunch extends Launch {
return;
}
final HashMap<String,ArrayList<IMemoryMap.MemoryRegion>> maps = new HashMap<String,ArrayList<IMemoryMap.MemoryRegion>>();
- TCFLaunchDelegate.getMemMapsAttribute(maps, cfg);
+ getMemMaps(maps, cfg);
final HashSet<IToken> cmds = new HashSet<IToken>(); // Pending commands
final Runnable done_all = new Runnable() {
boolean launch_done;
@@ -506,7 +535,7 @@ public class TCFLaunch extends Launch {
try {
Set<String> set = new HashSet<String>(maps.keySet());
maps.clear();
- TCFLaunchDelegate.getMemMapsAttribute(maps, getLaunchConfiguration());
+ getMemMaps(maps, getLaunchConfiguration());
for (String id : maps.keySet()) {
ArrayList<IMemoryMap.MemoryRegion> map = maps.get(id);
TCFMemoryRegion[] arr = map.toArray(new TCFMemoryRegion[map.size()]);
@@ -534,7 +563,7 @@ public class TCFLaunch extends Launch {
}
final HashSet<String> deleted_maps = new HashSet<String>();
final HashMap<String,ArrayList<IMemoryMap.MemoryRegion>> maps = new HashMap<String,ArrayList<IMemoryMap.MemoryRegion>>();
- TCFLaunchDelegate.getMemMapsAttribute(maps, cfg);
+ getMemMaps(maps, cfg);
final HashSet<String> mems = new HashSet<String>(); // Already processed memory IDs
final HashSet<IToken> cmds = new HashSet<IToken>(); // Pending commands
final HashMap<String,String> mem2map = new HashMap<String,String>();
@@ -631,7 +660,7 @@ public class TCFLaunch extends Launch {
try {
maps.clear();
mems.clear();
- TCFLaunchDelegate.getMemMapsAttribute(maps, getLaunchConfiguration());
+ getMemMaps(maps, getLaunchConfiguration());
for (String id : mem2map.values()) {
if (maps.get(id) == null) deleted_maps.add(id);
}
@@ -644,6 +673,40 @@ public class TCFLaunch extends Launch {
};
}
+ @SuppressWarnings("unchecked")
+ private void getMemMaps(Map<String,ArrayList<IMemoryMap.MemoryRegion>> maps, ILaunchConfiguration cfg) throws Exception {
+ // Parse ATTR_FILES
+ String s = cfg.getAttribute(TCFLaunchDelegate.ATTR_FILES, (String)null);
+ if (s != null) {
+ Collection<Map<String,Object>> c = (Collection<Map<String,Object>>)JSON.parseOne(s.getBytes("UTF-8"));
+ for (Map<String,Object> m : c) {
+ Boolean b = (Boolean)m.get(TCFLaunchDelegate.FILES_LOAD_SYMBOLS);
+ if (b != null && b.booleanValue()) {
+ String id = (String)m.get(TCFLaunchDelegate.FILES_CONTEXT_ID);
+ if (id == null) id = (String)m.get(TCFLaunchDelegate.FILES_CONTEXT_FULL_NAME);
+ if (id != null) {
+ Map<String,Object> map = new HashMap<String,Object>();
+ map.put(IMemoryMap.PROP_FILE_NAME, m.get(TCFLaunchDelegate.FILES_FILE_NAME));
+ b = (Boolean)m.get(TCFLaunchDelegate.FILES_RELOCATE);
+ if (b != null && b.booleanValue()) {
+ map.put(IMemoryMap.PROP_ADDRESS, m.get(TCFLaunchDelegate.FILES_ADDRESS));
+ map.put(IMemoryMap.PROP_OFFSET, m.get(TCFLaunchDelegate.FILES_OFFSET));
+ map.put(IMemoryMap.PROP_SIZE, m.get(TCFLaunchDelegate.FILES_SIZE));
+ }
+ ArrayList<IMemoryMap.MemoryRegion> l = maps.get(id);
+ if (l == null) {
+ l = new ArrayList<IMemoryMap.MemoryRegion>();
+ maps.put(id, l);
+ }
+ l.add(new TCFMemoryRegion(map));
+ }
+ }
+ }
+ }
+ // Parse ATTR_MEMORY_MAP
+ TCFLaunchDelegate.getMemMapsAttribute(maps, cfg);
+ }
+
private void readPathMapConfiguration(ILaunchConfiguration cfg) throws CoreException {
String s = cfg.getAttribute(TCFLaunchDelegate.ATTR_PATH_MAP, "");
host_path_map = TCFLaunchDelegate.parsePathMapAttribute(s);
@@ -1212,7 +1275,7 @@ public class TCFLaunch extends Launch {
public void onLastContextRemoved() {
ILaunchConfiguration cfg = getLaunchConfiguration();
try {
- if (cfg.getAttribute(TCFLaunchDelegate.ATTR_DISCONNECT_ON_CTX_EXIT, true)) {
+ if (process != null && cfg.getAttribute(TCFLaunchDelegate.ATTR_DISCONNECT_ON_CTX_EXIT, true)) {
last_context_exited = true;
closeChannel();
}

Back to the top