/******************************************************************************* * Copyright (c) 2007, 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.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Platform; 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.window.Window; import org.eclipse.jface.wizard.WizardDialog; 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.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Rectangle; 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.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.MessageBox; 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.TreeItem; import org.eclipse.tcf.core.TransientPeer; import org.eclipse.tcf.internal.debug.launch.TCFLaunchDelegate; import org.eclipse.tcf.internal.debug.launch.TCFLocalAgent; 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.IMemoryMap; import org.eclipse.tcf.services.IPathMap; import org.eclipse.tcf.util.TCFTask; /** * Launch configuration dialog tab to specify the Target Communication Framework * configuration. */ public class TCFTargetTab extends AbstractLaunchConfigurationTab { private static final String TAB_ID = "org.eclipse.tcf.launch.targetTab"; private Button run_local_server_button; 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 Display display; private Exception init_error; private String mem_map_cfg; public void createControl(Composite parent) { display = parent.getDisplay(); assert display != null; Font font = parent.getFont(); Composite comp = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(1, true); comp.setLayout(layout); comp.setFont(font); GridData gd = new GridData(GridData.FILL_BOTH); comp.setLayoutData(gd); setControl(comp); createVerticalSpacer(comp, 1); createLocalAgentButtons(comp); createVerticalSpacer(comp, 1); createTargetGroup(comp); } private void createLocalAgentButtons(Composite parent) { Composite local_agent_comp = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 1; layout.marginHeight = 0; layout.marginWidth = 0; local_agent_comp.setLayout(layout); GridData gd = new GridData(GridData.FILL_HORIZONTAL); local_agent_comp.setLayoutData(gd); run_local_server_button = createCheckButton(local_agent_comp, "Run TCF symbols server on the local host"); run_local_server_button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent evt) { updateLaunchConfigurationDialog(); } }); run_local_server_button.setEnabled(true); run_local_agent_button = createCheckButton(local_agent_comp, "Run instance of TCF agent on the local host"); run_local_agent_button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent evt) { updateLaunchConfigurationDialog(); } }); run_local_agent_button.setEnabled(true); use_local_agent_button = createCheckButton(local_agent_comp, "Use local host as the target"); use_local_agent_button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent evt) { updateLaunchConfigurationDialog(); } }); use_local_agent_button.setEnabled(true); } private void createTargetGroup(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("Target"); createVerticalSpacer(group, layout.numColumns); Label host_label = new Label(group, SWT.NONE); host_label.setText("Target ID:"); host_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); host_label.setFont(font); peer_id_text = new Text(group, SWT.SINGLE | SWT.BORDER); peer_id_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); peer_id_text.setFont(font); peer_id_text.setEditable(false); createVerticalSpacer(group, layout.numColumns); Label peer_label = new Label(group, SWT.NONE); peer_label.setText("&Available targets:"); peer_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); peer_label.setFont(font); peer_list = new PeerListControl(group) { @Override protected void onPeerListChanged() { updateLaunchConfigurationDialog(); } @Override protected void onPeerSelected(PeerInfo info) { peer_id_text.setText(peer_list.getPath(info)); } }; peer_tree = peer_list.getTree(); createPeerButtons(peer_tree.getParent()); } 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)); Menu menu = new Menu(peer_tree); SelectionAdapter sel_adapter = null; 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(sel_adapter = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { final Map<String,String> attrs = new HashMap<String,String>(); attrs.put("TransportName", "TCP"); attrs.put("Host", "127.0.0.1"); attrs.put("Port", "1534"); SetupWizardDialog wizard = new SetupWizardDialog(attrs); WizardDialog dialog = new WizardDialog(getShell(), wizard); dialog.create(); if (dialog.open() != Window.OK) return; if (attrs.isEmpty()) return; Protocol.invokeLater(new Runnable() { public void run() { new TCFUserDefPeer(attrs); TCFUserDefPeer.savePeers(); } }); } }); final MenuItem item_new = new MenuItem(menu, SWT.PUSH); item_new.setText("N&ew..."); item_new.addSelectionListener(sel_adapter); 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(sel_adapter = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { 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; if (!(info.peer instanceof TCFUserDefPeer)) return; Protocol.invokeLater(new Runnable() { public void run() { ((TCFUserDefPeer)info.peer).updateAttributes(info.attrs); TCFUserDefPeer.savePeers(); } }); } }); final MenuItem item_edit = new MenuItem(menu, SWT.PUSH); item_edit.setText("E&dit..."); item_edit.addSelectionListener(sel_adapter); 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(sel_adapter = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { final PeerInfo info = peer_list.findPeerInfo(peer_id_text.getText()); if (info == null) return; if (!(info.peer instanceof TCFUserDefPeer)) return; peer_id_text.setText(""); updateLaunchConfigurationDialog(); Protocol.invokeAndWait(new Runnable() { public void run() { ((TCFUserDefPeer)info.peer).dispose(); TCFUserDefPeer.savePeers(); } }); } }); final MenuItem item_remove = new MenuItem(menu, SWT.PUSH); item_remove.setText("&Remove"); item_remove.addSelectionListener(sel_adapter); createVerticalSpacer(composite, 20); new MenuItem(menu, SWT.SEPARATOR); 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(sel_adapter = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { runDiagnostics(false); } }); final MenuItem item_test = new MenuItem(menu, SWT.PUSH); item_test.setText("Run &Tests"); item_test.addSelectionListener(sel_adapter); 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(sel_adapter = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { runDiagnostics(true); } }); final MenuItem item_loop = new MenuItem(menu, SWT.PUSH); item_loop.setText("Tests &Loop"); item_loop.addSelectionListener(sel_adapter); peer_tree.setMenu(menu); update_peer_buttons = new Runnable() { public void run() { boolean local = use_local_agent_button.getSelection(); 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); button_test.setEnabled(local || info != null); button_loop.setEnabled(local || info != null); item_new.setEnabled(!local); item_edit.setEnabled(info != null && !local); item_remove.setEnabled(info != null && info.peer instanceof TCFUserDefPeer && !local); item_test.setEnabled(info != null); item_loop.setEnabled(info != null); } }; update_peer_buttons.run(); } @Override protected void updateLaunchConfigurationDialog() { if (use_local_agent_button.getSelection()) { peer_tree.setEnabled(false); peer_tree.deselectAll(); String id = TCFLocalAgent.getLocalAgentID(TCFLocalAgent.AGENT_NAME); if (id == null) id = ""; peer_id_text.setText(id); peer_id_text.setEnabled(false); } else { peer_tree.setEnabled(true); peer_id_text.setEnabled(true); String id = peer_id_text.getText(); TreeItem item = peer_list.findItem(id); if (item != null) peer_tree.setSelection(item); else peer_tree.deselectAll(); } update_peer_buttons.run(); super.updateLaunchConfigurationDialog(); } public String getName() { return "Target"; } @Override public Image getImage() { return ImageCache.getImage(ImageCache.IMG_TARGET_TAB); } @Override public String getId() { return TAB_ID; } public void initializeFrom(ILaunchConfiguration configuration) { setErrorMessage(null); setMessage(null); try { String id = configuration.getAttribute(TCFLaunchDelegate.ATTR_PEER_ID, ""); peer_id_text.setText(id); peer_list.setInitialSelection(id); run_local_server_button.setSelection(configuration.getAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_SERVER, false)); 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"); } catch (CoreException e) { init_error = e; setErrorMessage("Cannot read launch configuration: " + e); Activator.log(e); } updateLaunchConfigurationDialog(); } public void performApply(ILaunchConfigurationWorkingCopy configuration) { if (use_local_agent_button.getSelection()) { configuration.removeAttribute(TCFLaunchDelegate.ATTR_PEER_ID); } else { configuration.setAttribute(TCFLaunchDelegate.ATTR_PEER_ID, peer_id_text.getText()); } configuration.setAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_SERVER, run_local_server_button.getSelection()); configuration.setAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_AGENT, run_local_agent_button.getSelection()); configuration.setAttribute(TCFLaunchDelegate.ATTR_USE_LOCAL_AGENT, use_local_agent_button.getSelection()); } public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_SERVER, false); configuration.setAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_AGENT, false); configuration.setAttribute(TCFLaunchDelegate.ATTR_USE_LOCAL_AGENT, true); configuration.removeAttribute(TCFLaunchDelegate.ATTR_PEER_ID); } @Override public boolean isValid(ILaunchConfiguration config) { setErrorMessage(null); setMessage(null); if (init_error != null) { setErrorMessage("Cannot read launch configuration: " + init_error); return false; } return true; } public String getPeerID() { return peer_id_text.getText(); } private void runDiagnostics(boolean loop) { IPeer peer = null; if (use_local_agent_button.getSelection()) { try { if (run_local_agent_button.getSelection()) TCFLocalAgent.runLocalAgent(TCFLocalAgent.AGENT_NAME); final String id = TCFLocalAgent.getLocalAgentID(TCFLocalAgent.AGENT_NAME); peer = new TCFTask<IPeer>() { public void run() { done(Protocol.getLocator().getPeers().get(id)); } }.get(); } catch (Throwable err) { String msg = err.getLocalizedMessage(); if (msg == null || msg.length() == 0) msg = err.getClass().getName(); MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK); mb.setText("Error"); mb.setMessage("Cannot start agent:\n" + msg); mb.open(); } } else { PeerInfo info = peer_list.findPeerInfo(peer_id_text.getText()); if (info == null) return; peer = info.peer; } if (peer == null) return; if (run_local_server_button.getSelection()) { try { final IPeer agent = peer; final String id = TCFLocalAgent.runLocalAgent(TCFLocalAgent.SERVER_NAME); IPeer server = new TCFTask<IPeer>() { public void run() { done(Protocol.getLocator().getPeers().get(id)); } }.get(); peer = new TransientPeer(server.getAttributes()) { public IChannel openChannel() { assert Protocol.isDispatchThread(); IChannel c = super.openChannel(); c.redirect(agent.getAttributes()); return c; } }; } catch (Throwable err) { String msg = err.getLocalizedMessage(); if (msg == null || msg.length() == 0) msg = err.getClass().getName(); MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK); mb.setText("Error"); mb.setMessage("Cannot start symbols server:\n" + msg); mb.open(); } } final Shell shell = new Shell(getShell(), SWT.TITLE | SWT.PRIMARY_MODAL); GridLayout layout = new GridLayout(); layout.verticalSpacing = 0; layout.numColumns = 2; shell.setLayout(layout); shell.setText("Running Diagnostics..."); CLabel label = new CLabel(shell, SWT.NONE); label.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); label.setText("Running Diagnostics..."); final TCFTestSuite[] test = new TCFTestSuite[1]; Button button_cancel = new Button(shell, SWT.PUSH); 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() { if (test[0] != null) test[0].cancel(); } }); } }); createVerticalSpacer(shell, 0); ProgressBar bar = new ProgressBar(shell, SWT.HORIZONTAL); bar.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1)); shell.setDefaultButton(button_cancel); shell.pack(); shell.setSize(483, shell.getSize().y); Rectangle rc0 = getShell().getBounds(); Rectangle rc1 = shell.getBounds(); shell.setLocation(rc0.x + (rc0.width - rc1.width) / 2, rc0.y + (rc0.height - rc1.height) / 2); shell.setVisible(true); runDiagnostics(peer, loop, test, shell, label, bar); } private void runDiagnostics(final IPeer peer, final boolean loop, final TCFTestSuite[] test, final Shell shell, final CLabel label, final ProgressBar bar) { final TCFTestSuite.TestListener done = new TCFTestSuite.TestListener() { private String last_text = ""; private int last_count = 0; private int last_total = 0; public void progress(final String label_text, final int count_done, final int count_total) { assert test[0] != null; if ((label_text == null || last_text.equals(label_text)) && last_total == count_total && (count_done - last_count) / (float)count_total < 0.02f) return; if (label_text != null) last_text = label_text; last_total = count_total; last_count = count_done; display.asyncExec(new Runnable() { public void run() { label.setText(last_text); bar.setMinimum(0); bar.setMaximum(last_total); bar.setSelection(last_count); } }); } public void done(final Collection<Throwable> errors) { assert test[0] != null; final boolean b = test[0].isCanceled(); test[0] = null; display.asyncExec(new Runnable() { public void run() { if (errors.size() > 0) { shell.dispose(); new TestErrorsDialog(getControl().getShell(), ImageCache.getImage(ImageCache.IMG_TCF), errors).open(); } else if (loop && !b && display != null) { runDiagnostics(peer, true, test, shell, label, bar); } else { shell.dispose(); } } }); } }; Protocol.invokeLater(new Runnable() { public void run() { try { List<IPathMap.PathMapRule> path_map = null; for (ILaunchConfigurationTab t : getLaunchConfigurationDialog().getTabs()) { if (t instanceof TCFPathMapTab) path_map = ((TCFPathMapTab)t).getPathMap(); } HashMap<String,ArrayList<IMemoryMap.MemoryRegion>> mem_map = null; if (mem_map_cfg != null) { mem_map = new HashMap<String,ArrayList<IMemoryMap.MemoryRegion>>(); TCFLaunchDelegate.parseMemMapsAttribute(mem_map, mem_map_cfg); } boolean enable_tracing = "true".equals(Platform.getDebugOption("org.eclipse.tcf.debug/debug")) && "true".equals(Platform.getDebugOption("org.eclipse.tcf.debug/debug/tests/runcontrol")); if (enable_tracing) System.setProperty("org.eclipse.tcf.debug.tracing.tests.runcontrol", "true"); test[0] = new TCFTestSuite(peer, done, path_map, mem_map); } catch (Throwable x) { ArrayList<Throwable> errors = new ArrayList<Throwable>(); errors.add(x); done.done(errors); } } }); } }