diff options
Diffstat (limited to 'plugins')
11 files changed, 666 insertions, 78 deletions
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/icons/attribute.gif b/plugins/org.eclipse.tm.tcf.debug.ui/icons/attribute.gif Binary files differnew file mode 100644 index 000000000..0f0769269 --- /dev/null +++ b/plugins/org.eclipse.tm.tcf.debug.ui/icons/attribute.gif diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/PeerPropsDialog.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/PeerPropsDialog.java new file mode 100644 index 000000000..8d5d8d60f --- /dev/null +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/PeerPropsDialog.java @@ -0,0 +1,363 @@ +package org.eclipse.tm.internal.tcf.debug.ui.launch; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Map; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; +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.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +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.Item; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tm.internal.tcf.debug.ui.ImageCache; +import org.eclipse.tm.tcf.protocol.IPeer; + +class PeerPropsDialog extends Dialog { + + private static final int + SIZING_TABLE_WIDTH = 400, + SIZING_TABLE_HEIGHT = 200; + + private static final String[] column_names = { "Name", "Value" }; + + /* + private static final String[] attr_names = { + IPeer.ATTR_TRANSPORT_NAME, + IPeer.ATTR_IP_HOST, + IPeer.ATTR_IP_PORT, + IPeer.ATTR_IP_ALIASES, + IPeer.ATTR_IP_ADDRESSES, + IPeer.ATTR_OS_NAME, + IPeer.ATTR_PROXY, + }; + */ + + private final Image image; + private final Map<String,String> attrs; + private final ArrayList<Attribute> attr_list; + private final boolean create_new; + private final boolean enable_editing; + + private Text id_text; + private Text name_text; + private Table attr_table; + private TableViewer table_viewer; + private Image attr_image; + + private class Attribute { + String name; + String value; + } + + private class AttributeLabelProvider extends LabelProvider implements ITableLabelProvider { + + public Image getColumnImage(Object element, int column) { + if (column == 0) return attr_image; + return null; + } + + public String getColumnText(Object element, int column) { + Attribute a = (Attribute)element; + return column == 0 ? a.name : a.value; + } + + public String getText(Object element) { + TableColumn column = attr_table.getSortColumn(); + if (column == null) return ""; + return getColumnText(element, attr_table.indexOf(column)); + } + } + + protected PeerPropsDialog(Shell parent, Image image, Map<String,String> attrs, boolean enable_editing) { + super(parent); + this.image = image; + this.attrs = attrs; + create_new = attrs.isEmpty(); + if (create_new) { + attrs.put(IPeer.ATTR_ID, "USR:" + System.currentTimeMillis()); + } + this.enable_editing = enable_editing; + attr_list = new ArrayList<Attribute>(); + } + + @Override + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText("TCF Peer Properties"); + shell.setImage(image); + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, "&OK", true); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite)super.createDialogArea(parent); + + createTextFields(composite); + createAttrTable(composite); + + composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + return composite; + } + + private void createTextFields(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_HORIZONTAL)); + + Label id_label = new Label(composite, SWT.WRAP); + id_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); + id_label.setFont(font); + id_label.setText("Peer &ID:"); + + id_text = new Text(composite, SWT.SINGLE | SWT.BORDER); + id_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + id_text.setFont(font); + id_text.setEditable(false); + + Label name_label = new Label(composite, SWT.WRAP); + name_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); + name_label.setFont(font); + name_label.setText("Peer &name:"); + + name_text = new Text(composite, SWT.SINGLE | SWT.BORDER); + name_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + name_text.setFont(font); + name_text.setEditable(create_new || enable_editing); + } + + private void createAttrTable(Composite parent) { + Font font = parent.getFont(); + Label props_label = new Label(parent, SWT.WRAP); + props_label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + props_label.setFont(font); + props_label.setText("Peer &properties:"); + + 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)); + + attr_table = new Table(composite, SWT.SINGLE | SWT.BORDER | + SWT.H_SCROLL | SWT.V_SCROLL | + SWT.FULL_SELECTION | SWT.HIDE_SELECTION); + attr_table.setFont(font); + GridData data = new GridData(GridData.FILL_BOTH); + data.widthHint = SIZING_TABLE_WIDTH; + data.heightHint = SIZING_TABLE_HEIGHT; + attr_table.setLayoutData(data); + + for (int i = 0; i < column_names.length; i++) { + final TableColumn column = new TableColumn(attr_table, SWT.LEAD, i); + column.setMoveable(false); + column.setText(column_names[i]); + column.setWidth(SIZING_TABLE_WIDTH / column_names.length); + column.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent e) { + if (column == attr_table.getSortColumn()) { + switch (attr_table.getSortDirection()) { + case SWT.NONE: + attr_table.setSortDirection(SWT.DOWN); + break; + case SWT.DOWN: + attr_table.setSortDirection(SWT.UP); + break; + case SWT.UP: + attr_table.setSortDirection(SWT.NONE); + break; + } + } + else { + attr_table.setSortColumn(column); + attr_table.setSortDirection(SWT.DOWN); + } + table_viewer.refresh(); + } + }); + } + attr_table.setHeaderVisible(true); + attr_table.setLinesVisible(true); + + attr_image = ImageCache.getImageDescriptor("icons/attribute.gif").createImage(); + attr_table.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + attr_image.dispose(); + attr_image = null; + } + }); + + table_viewer = new TableViewer(attr_table); + table_viewer.setUseHashlookup(true); + table_viewer.setColumnProperties(column_names); + + CellEditor[] editors = new CellEditor[column_names.length]; + for (int i = 0; i < column_names.length; i++) { + TextCellEditor editor = new TextCellEditor(attr_table); + ((Text)editor.getControl()).setTextLimit(250); + editors[i] = editor; + } + table_viewer.setCellEditors(editors); + + table_viewer.setCellModifier(new ICellModifier() { + + public boolean canModify(Object element, String property) { + return enable_editing; + } + + public Object getValue(Object element, String property) { + if (element instanceof Item) element = ((Item)element).getData(); + Attribute a = (Attribute)element; + return property.equals(column_names[0]) ? a.name : a.value; + } + + public void modify(Object element, String property, Object value) { + if (element instanceof Item) element = ((Item)element).getData(); + Attribute a = (Attribute)element; + if (property.equals(column_names[0])) { + a.name = (String)value; + } + else { + a.value = (String)value; + } + table_viewer.update(element, new String[] { property }); + } + }); + + String[] keys = attrs.keySet().toArray(new String[attrs.size()]); + Arrays.sort(keys); + for (String key : keys) { + if (key.equals(IPeer.ATTR_ID)) { + id_text.setText(attrs.get(key)); + } + else if (key.equals(IPeer.ATTR_NAME)) { + name_text.setText(attrs.get(key)); + } + else { + Attribute a = new Attribute(); + a.name = key; + a.value = attrs.get(key); + attr_list.add(a); + } + } + + table_viewer.setContentProvider(new IStructuredContentProvider() { + + public Object[] getElements(Object input) { + assert input == attr_list; + return attr_list.toArray(); + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + }); + + table_viewer.setLabelProvider(new AttributeLabelProvider()); + table_viewer.setInput(attr_list); + table_viewer.setComparator(new ViewerComparator() { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + switch (attr_table.getSortDirection()) { + case SWT.UP : return -super.compare(viewer, e1, e2); + case SWT.DOWN: return +super.compare(viewer, e1, e2); + } + return 0; + } + }); + + createTableButtons(composite); + } + + private void createTableButtons(Composite parent) { + Font font = parent.getFont(); + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + composite.setFont(font); + composite.setLayout(layout); + composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL)); + + final Button button_new = new Button(composite, SWT.PUSH); + button_new.setText("&Add"); + button_new.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); + button_new.setEnabled(enable_editing); + button_new.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + Attribute a = new Attribute(); + a.name = ""; + a.value = ""; + attr_list.add(a); + table_viewer.add(a); + table_viewer.setSelection(new StructuredSelection(a), true); + attr_table.setFocus(); + } + }); + + final Button button_remove = new Button(composite, SWT.PUSH); + button_remove.setText("&Remove"); + button_remove.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); + button_remove.setEnabled(enable_editing); + button_remove.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + Attribute a = (Attribute) ((IStructuredSelection) + table_viewer.getSelection()).getFirstElement(); + if (a == null) return; + attr_list.remove(a); + table_viewer.remove(a); + } + }); + } + + @Override + protected void okPressed() { + if (enable_editing) { + String id = attrs.get(IPeer.ATTR_ID); + String nm = name_text.getText(); + attrs.clear(); + for (Attribute a : attr_list) attrs.put(a.name, a.value); + attrs.put(IPeer.ATTR_ID, id); + attrs.put(IPeer.ATTR_NAME, nm); + } + else if (create_new) { + attrs.put(IPeer.ATTR_NAME, name_text.getText()); + } + super.okPressed(); + } +} diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java index 07bc42b13..c6113dab6 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java @@ -24,13 +24,13 @@ import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; 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.events.SelectionListener; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Rectangle; @@ -50,6 +50,7 @@ import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate; +import org.eclipse.tm.internal.tcf.debug.launch.TCFUserDefPeer; import org.eclipse.tm.internal.tcf.debug.ui.Activator; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IPeer; @@ -67,6 +68,7 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab { private Text peer_id_text; private Text program_text; private Tree peer_tree; + private Runnable update_peer_buttons; private final PeerInfo peer_info = new PeerInfo(); private Display display; @@ -222,15 +224,26 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab { createVerticalSpacer(group, top_layout.numColumns); Label peer_label = new Label(group, SWT.NONE); - peer_label.setText("Available targets:"); + peer_label.setText("&Available targets:"); 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(group, SWT.VIRTUAL | SWT.BORDER | SWT.SINGLE); - GridData gd = 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 < 5; i++) { @@ -283,10 +296,27 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab { } } }); - peer_tree.addSelectionListener(new SelectionListener() { + peer_tree.addSelectionListener(new SelectionAdapter() { + @Override public void widgetDefaultSelected(SelectionEvent e) { + TreeItem[] selections = peer_tree.getSelection(); + if (selections.length == 0) return; + assert selections.length == 1; + final PeerInfo info = findPeerInfo(selections[0]); + 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(); + } + }); } + @Override public void widgetSelected(SelectionEvent e) { + update_peer_buttons.run(); TreeItem[] selections = peer_tree.getSelection(); if (selections.length > 0) { assert selections.length == 1; @@ -295,13 +325,84 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab { } } }); + + createPeerButtons(composite); + } + + private void createPeerButtons(Composite parent) { + Font font = parent.getFont(); + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + composite.setFont(font); + composite.setLayout(layout); + composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL)); + + final Button button_new = new Button(composite, SWT.PUSH); + button_new.setText("N&ew..."); + button_new.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); + button_new.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + final Map<String,String> attrs = new HashMap<String,String>(); + if (new PeerPropsDialog(getShell(), getImage(), attrs, true).open() != Window.OK) return; + Protocol.invokeLater(new Runnable() { + public void run() { + new TCFUserDefPeer(attrs); + TCFUserDefPeer.savePeers(); + } + }); + } + }); - createVerticalSpacer(group, top_layout.numColumns); + final Button button_edit = new Button(composite, SWT.PUSH); + button_edit.setText("E&dit..."); + button_edit.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); + button_edit.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TreeItem[] selection = peer_tree.getSelection(); + if (selection.length == 0) return; + final PeerInfo info = findPeerInfo(selection[0]); + if (info == null) return; + if (new PeerPropsDialog(getShell(), getImage(), info.attrs, + info.peer instanceof TCFUserDefPeer).open() != Window.OK) return; + if (!(info.peer instanceof TCFUserDefPeer)) return; + Protocol.invokeLater(new Runnable() { + public void run() { + ((TCFUserDefPeer)info.peer).updateAttributes(info.attrs); + TCFUserDefPeer.savePeers(); + } + }); + } + }); + + final Button button_remove = new Button(composite, SWT.PUSH); + button_remove.setText("&Remove"); + button_remove.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); + button_remove.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TreeItem[] selection = peer_tree.getSelection(); + if (selection.length == 0) return; + final PeerInfo info = findPeerInfo(selection[0]); + if (info == null) return; + if (!(info.peer instanceof TCFUserDefPeer)) return; + Protocol.invokeLater(new Runnable() { + public void run() { + ((TCFUserDefPeer)info.peer).dispose(); + TCFUserDefPeer.savePeers(); + } + }); + } + }); - Button button_test = new Button(group, SWT.PUSH); - button_test.setText("Run &Diagnostics"); - button_test.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); + createVerticalSpacer(composite, 20); + + final Button button_test = new Button(composite, SWT.PUSH); + button_test.setText("Run &Tests"); + button_test.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); button_test.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { TreeItem[] selection = peer_tree.getSelection(); if (selection.length > 0) { @@ -311,10 +412,11 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab { } }); - Button button_loop = new Button(group, SWT.PUSH); - button_loop.setText("Diagnostics &Loop"); - button_loop.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); + final Button button_loop = new Button(composite, SWT.PUSH); + button_loop.setText("Tests &Loop"); + button_loop.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); button_loop.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { TreeItem[] selection = peer_tree.getSelection(); if (selection.length > 0) { @@ -323,6 +425,20 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab { } } }); + + update_peer_buttons = new Runnable() { + + public void run() { + PeerInfo info = null; + TreeItem[] selection = peer_tree.getSelection(); + if (selection.length > 0) info = findPeerInfo(selection[0]); + button_edit.setEnabled(info != null); + button_remove.setEnabled(info != null && info.peer instanceof TCFUserDefPeer); + button_test.setEnabled(info != null); + button_loop.setEnabled(info != null); + } + }; + update_peer_buttons.run(); } private void createProgramGroup(Composite parent) { @@ -380,7 +496,10 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab { if (id != null) { peer_id_text.setText(id); TreeItem item = findItem(findPeerInfo(id)); - if (item != null) peer_tree.setSelection(item); + if (item != null) { + peer_tree.setSelection(item); + update_peer_buttons.run(); + } } program_text.setText(configuration.getAttribute( TCFLaunchDelegate.ATTR_PROGRAM_FILE, "")); //$NON-NLS-1$ @@ -540,7 +659,10 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab { for (int i = 0; i < items.length; i++) fillItem(items[i], arr[i]); String id = peer_id_text.getText(); TreeItem item = findItem(findPeerInfo(id)); - if (item != null) peer_tree.setSelection(item); + if (item != null) { + peer_tree.setSelection(item); + update_peer_buttons.run(); + } } } @@ -606,6 +728,7 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab { button_cancel.setText("&Cancel"); button_cancel.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); button_cancel.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { Protocol.invokeLater(new Runnable() { public void run() { diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TestErrorsDialog.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TestErrorsDialog.java index e351548f9..55b140a91 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TestErrorsDialog.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TestErrorsDialog.java @@ -29,8 +29,9 @@ import org.eclipse.swt.widgets.Text; class TestErrorsDialog extends Dialog { - private final int SIZING_TEXT_WIDTH = 600; - private final int SIZING_TEXT_HEIGHT = 400; + private static final int + SIZING_TEXT_WIDTH = 600, + SIZING_TEXT_HEIGHT = 400; private Collection<Throwable> errors; private Image image; @@ -42,16 +43,19 @@ class TestErrorsDialog extends Dialog { this.errors = errors; } + @Override protected void configureShell(Shell shell) { super.configureShell(shell); shell.setText("Connection Diagnostic errors"); shell.setImage(image); } + @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, "&OK", true); } + @Override protected Control createDialogArea(Composite parent) { Composite composite = (Composite)super.createDialogArea(parent); composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/Activator.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/Activator.java index 6294a5665..80a7ef4b2 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/Activator.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/Activator.java @@ -13,7 +13,9 @@ package org.eclipse.tm.internal.tcf.debug; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Status; +import org.eclipse.tm.internal.tcf.debug.launch.TCFUserDefPeer; import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpointsModel; +import org.eclipse.tm.tcf.protocol.Protocol; import org.osgi.framework.BundleContext; @@ -37,6 +39,12 @@ public class Activator extends Plugin { public void start(BundleContext context) throws Exception { super.start(context); bp_model = new TCFBreakpointsModel(); + Protocol.invokeLater(new Runnable() { + + public void run() { + TCFUserDefPeer.loadPeers(); + } + }); } @Override diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFUserDefPeer.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFUserDefPeer.java new file mode 100644 index 000000000..1a757ad49 --- /dev/null +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFUserDefPeer.java @@ -0,0 +1,88 @@ +package org.eclipse.tm.internal.tcf.debug.launch; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.tm.internal.tcf.debug.Activator; +import org.eclipse.tm.tcf.core.AbstractPeer; +import org.eclipse.tm.tcf.protocol.IPeer; +import org.eclipse.tm.tcf.protocol.Protocol; + +/** + * The class represents manually configured (user defined) TCF peers (targets). + * Unlike auto-discovered peers, manually configured ones are persistent - + * they exist until explicitly deleted by user. + * Eclipse plug-in state storage is used to keep the configuration data. + */ +public class TCFUserDefPeer extends AbstractPeer { + + public TCFUserDefPeer(Map<String, String> attrs) { + super(attrs); + } + + /** + * Load manually configured peers from persistent storage. + */ + public static void loadPeers() { + try { + assert Protocol.isDispatchThread(); + IPath path = Activator.getDefault().getStateLocation(); + File f = path.append("peers.ini").toFile(); + if (!f.exists()) return; + HashMap<String,String> attrs = new HashMap<String,String>(); + BufferedReader rd = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8")); + for (;;) { + String s = rd.readLine(); + if (s == null) break; + if (s.length() == 0) { + new TCFUserDefPeer(attrs); + attrs = new HashMap<String,String>(); + } + else { + int i = s.indexOf('='); + if (i > 0) attrs.put(s.substring(0, i), s.substring(i + 1)); + } + } + rd.close(); + } + catch (Exception x) { + Activator.log("Cannot read peer list", x); + } + } + + /** + * Save manually configured peers to persistent storage. + */ + public static void savePeers() { + try { + assert Protocol.isDispatchThread(); + IPath path = Activator.getDefault().getStateLocation(); + File f = path.append("peers.ini").toFile(); + BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8")); + for (IPeer peer : Protocol.getLocator().getPeers().values()) { + if (peer instanceof TCFUserDefPeer) { + Map<String,String> attrs = peer.getAttributes(); + for (String nm : attrs.keySet()) { + wr.write(nm); + wr.write('='); + wr.write(attrs.get(nm)); + wr.newLine(); + } + wr.newLine(); + } + } + wr.close(); + } + catch (Exception x) { + Activator.log("Cannot read peer list", x); + } + } +} diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/core/LocalPeer.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/core/LocalPeer.java index b571c4db6..11a29fed3 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/core/LocalPeer.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/core/LocalPeer.java @@ -14,12 +14,10 @@ import java.util.HashMap; import java.util.Map; import org.eclipse.tm.tcf.core.AbstractPeer; -import org.eclipse.tm.tcf.protocol.IChannel; - public class LocalPeer extends AbstractPeer { - private static Map<String, String> createAttributes() { + private static Map<String,String> createAttributes() { Map<String, String> attrs = new HashMap<String, String>(); attrs.put(ATTR_ID, "TCFLocal"); attrs.put(ATTR_NAME, "Local Peer"); @@ -31,8 +29,4 @@ public class LocalPeer extends AbstractPeer { public LocalPeer() { super(createAttributes()); } - - public IChannel openChannel() { - return new ChannelLoop(this); - } }
\ No newline at end of file diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/core/RemotePeer.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/core/RemotePeer.java index 3a97f975c..4223ac636 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/core/RemotePeer.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/core/RemotePeer.java @@ -10,57 +10,13 @@ *******************************************************************************/ package org.eclipse.tm.internal.tcf.core; -import java.util.Iterator; import java.util.Map; import org.eclipse.tm.tcf.core.AbstractPeer; -import org.eclipse.tm.tcf.core.ChannelTCP; -import org.eclipse.tm.tcf.protocol.IChannel; - public class RemotePeer extends AbstractPeer { public RemotePeer(Map<String,String> attrs) { super(attrs); } - - public boolean updateAttributes(Map<String,String> attrs1) { - boolean equ = true; - Map<String,String> attrs0 = getAttributesStorage(); - assert attrs1.get(ATTR_ID).equals(attrs0.get(ATTR_ID)); - for (Iterator<String> i = attrs0.keySet().iterator(); i.hasNext();) { - String key = i.next(); - if (!attrs0.get(key).equals(attrs1.get(key))) { - equ = false; - break; - } - } - for (Iterator<String> i = attrs1.keySet().iterator(); i.hasNext();) { - String key = i.next(); - if (!attrs1.get(key).equals(attrs0.get(key))) { - equ = false; - break; - } - } - if (!equ) { - attrs0.clear(); - attrs0.putAll(attrs1); - } - return !equ; - } - - public IChannel openChannel() { - String transport = getTransportName(); - if (transport.equals("TCP")) { - Map<String,String> attrs = getAttributes(); - String host = attrs.get(ATTR_IP_HOST); - String port = attrs.get(ATTR_IP_PORT); - if (host == null) throw new Error("No host name"); - if (port == null) throw new Error("No port number"); - return new ChannelTCP(this, host, Integer.parseInt(port)); - } - else { - throw new Error("Unknow transport name: " + transport); - } - } } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/core/Transport.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/core/Transport.java index d6622d16b..777bc340f 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/core/Transport.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/core/Transport.java @@ -15,12 +15,15 @@ import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; +import java.util.Map; import java.util.Set; import org.eclipse.tm.tcf.Activator; import org.eclipse.tm.tcf.core.AbstractChannel; import org.eclipse.tm.tcf.core.AbstractPeer; +import org.eclipse.tm.tcf.core.ChannelTCP; import org.eclipse.tm.tcf.protocol.IChannel; +import org.eclipse.tm.tcf.protocol.IPeer; import org.eclipse.tm.tcf.protocol.IService; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.protocol.Protocol; @@ -33,6 +36,24 @@ public class Transport { new LinkedList<AbstractChannel>(); private static final Collection<Protocol.ChannelOpenListener> listeners = new LinkedList<Protocol.ChannelOpenListener>(); + + + public static IChannel openChannel(IPeer peer) { + String transport = peer.getTransportName(); + if (transport == null) throw new Error("Unknown transport"); + if (transport.equals("Loop")) { + return new ChannelLoop(peer); + } + if (transport.equals("TCP")) { + Map<String,String> attrs = peer.getAttributes(); + String host = attrs.get(IPeer.ATTR_IP_HOST); + String port = attrs.get(IPeer.ATTR_IP_PORT); + if (host == null) throw new Error("No host name"); + if (port == null) throw new Error("No port number"); + return new ChannelTCP(peer, host, Integer.parseInt(port)); + } + throw new Error("Unknown transport name: " + transport); + } public static void channelOpened(final AbstractChannel channel) { channels.add(channel); diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java index dda4db59e..75c0117fa 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java @@ -107,6 +107,10 @@ public class LocatorService implements ILocator { public static LocalPeer getLocalPeer() { return local_peer; } + + public static Collection<LocatorListener> getListeners() { + return listeners; + } public static void addPeer(IPeer peer) { assert peers.get(peer.getID()) == null; @@ -116,9 +120,9 @@ public class LocatorService implements ILocator { } public static void removePeer(IPeer peer) { - assert peers.get(peer.getID()) == peer; - peers.remove(peer); String id = peer.getID(); + assert peers.get(id) == peer; + peers.remove(id); for (LocatorListener l : listeners) l.peerRemoved(id); } @@ -284,12 +288,7 @@ public class LocatorService implements ILocator { if (id == null) throw new Exception("Invalid peer info: no ID"); IPeer peer = peers.get(id); if (peer instanceof RemotePeer) { - if (((RemotePeer)peer).updateAttributes(map)) { - for (LocatorListener l : listeners) l.peerChanged(peer); - } - else { - for (LocatorListener l : listeners) l.peerHeartBeat(id); - } + ((RemotePeer)peer).updateAttributes(map); } else { new RemotePeer(map); diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractPeer.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractPeer.java index e75514542..9171cf600 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractPeer.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/core/AbstractPeer.java @@ -10,14 +10,18 @@ *******************************************************************************/ package org.eclipse.tm.tcf.core; +import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import org.eclipse.tm.internal.tcf.core.ReadOnlyMap; import org.eclipse.tm.internal.tcf.core.Transport; import org.eclipse.tm.internal.tcf.services.local.LocatorService; +import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IPeer; import org.eclipse.tm.tcf.protocol.Protocol; +import org.eclipse.tm.tcf.services.ILocator.LocatorListener; public abstract class AbstractPeer implements IPeer { @@ -26,6 +30,7 @@ public abstract class AbstractPeer implements IPeer { private final Map<String, String> rw_attrs; public AbstractPeer(Map<String, String> attrs) { + assert Protocol.isDispatchThread(); if (attrs != null) { rw_attrs = new HashMap<String, String>(attrs); } @@ -37,9 +42,32 @@ public abstract class AbstractPeer implements IPeer { LocatorService.addPeer(this); } - protected Map<String, String> getAttributesStorage() { - assert Protocol.isDispatchThread(); - return rw_attrs; + public void updateAttributes(Map<String,String> attrs) { + boolean equ = true; + assert attrs.get(ATTR_ID).equals(rw_attrs.get(ATTR_ID)); + for (Iterator<String> i = rw_attrs.keySet().iterator(); i.hasNext();) { + String key = i.next(); + if (!rw_attrs.get(key).equals(attrs.get(key))) { + equ = false; + break; + } + } + for (Iterator<String> i = attrs.keySet().iterator(); i.hasNext();) { + String key = i.next(); + if (!attrs.get(key).equals(rw_attrs.get(key))) { + equ = false; + break; + } + } + Collection<LocatorListener> listeners = LocatorService.getListeners(); + if (!equ) { + rw_attrs.clear(); + rw_attrs.putAll(attrs); + for (LocatorListener l : listeners) l.peerChanged(this); + } + else { + for (LocatorListener l : listeners) l.peerHeartBeat(attrs.get(ATTR_ID)); + } } public void dispose() { @@ -72,4 +100,8 @@ public abstract class AbstractPeer implements IPeer { assert Protocol.isDispatchThread(); return ro_attrs.get(ATTR_TRANSPORT_NAME); } + + public IChannel openChannel() { + return Transport.openChannel(this); + } } |