From 307a85d9ac83701e2d5b8d8806674fe540f446e2 Mon Sep 17 00:00:00 2001 From: Martin Oberhuber < martin.oberhuber@windriver.com> Date: Wed, 24 May 2006 16:39:41 +0000 Subject: [PATCH] Add remotecdt example - bug 137839 --- .../org.eclipse.rse.remotecdt/.classpath | 7 + .../org.eclipse.rse.remotecdt/.project | 28 ++ .../META-INF/MANIFEST.MF | 27 ++ .../build.properties | 12 + .../icons/full/obj16/c_app.gif | Bin 0 -> 606 bytes .../icons/full/obj16/systemlocal_obj.gif | Bin 0 -> 580 bytes .../icons/full/obj16/systemlocallive_obj.gif | Bin 0 -> 592 bytes .../instructions.txt | 39 +++ .../org.eclipse.rse.remotecdt/plugin.xml | 42 +++ .../org/eclipse/rse/remotecdt/Activator.java | 56 +++ ...emoteConnectionConfigurationConstants.java | 39 +++ .../eclipse/rse/remotecdt/RemoteCMainTab.java | 331 ++++++++++++++++++ .../RemoteLaunchConfigurationTabGroup.java | 36 ++ .../remotecdt/RemoteRunLaunchDelegate.java | 268 ++++++++++++++ 14 files changed, 885 insertions(+) create mode 100644 rse/examples/org.eclipse.rse.remotecdt/.classpath create mode 100644 rse/examples/org.eclipse.rse.remotecdt/.project create mode 100644 rse/examples/org.eclipse.rse.remotecdt/META-INF/MANIFEST.MF create mode 100644 rse/examples/org.eclipse.rse.remotecdt/build.properties create mode 100644 rse/examples/org.eclipse.rse.remotecdt/icons/full/obj16/c_app.gif create mode 100644 rse/examples/org.eclipse.rse.remotecdt/icons/full/obj16/systemlocal_obj.gif create mode 100644 rse/examples/org.eclipse.rse.remotecdt/icons/full/obj16/systemlocallive_obj.gif create mode 100644 rse/examples/org.eclipse.rse.remotecdt/instructions.txt create mode 100644 rse/examples/org.eclipse.rse.remotecdt/plugin.xml create mode 100644 rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/Activator.java create mode 100644 rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/IRemoteConnectionConfigurationConstants.java create mode 100644 rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/RemoteCMainTab.java create mode 100644 rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/RemoteLaunchConfigurationTabGroup.java create mode 100644 rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/RemoteRunLaunchDelegate.java diff --git a/rse/examples/org.eclipse.rse.remotecdt/.classpath b/rse/examples/org.eclipse.rse.remotecdt/.classpath new file mode 100644 index 00000000000..751c8f2e504 --- /dev/null +++ b/rse/examples/org.eclipse.rse.remotecdt/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/rse/examples/org.eclipse.rse.remotecdt/.project b/rse/examples/org.eclipse.rse.remotecdt/.project new file mode 100644 index 00000000000..da5ae4bbbed --- /dev/null +++ b/rse/examples/org.eclipse.rse.remotecdt/.project @@ -0,0 +1,28 @@ + + + org.eclipse.rse.remotecdt + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/rse/examples/org.eclipse.rse.remotecdt/META-INF/MANIFEST.MF b/rse/examples/org.eclipse.rse.remotecdt/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..1b82bbf9872 --- /dev/null +++ b/rse/examples/org.eclipse.rse.remotecdt/META-INF/MANIFEST.MF @@ -0,0 +1,27 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Remote CDT Plug-in +Bundle-SymbolicName: org.eclipse.rse.remotecdt;singleton:=true +Bundle-Version: 1.0.0 +Bundle-Activator: org.eclipse.rse.remotecdt.Activator +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.rse.ui, + org.eclipse.rse.files.ui, + org.eclipse.rse.subsystems.files.ftp, + org.eclipse.debug.ui, + org.eclipse.cdt.launch, + org.eclipse.swt, + org.eclipse.ui, + org.eclipse.rse.subsystems.shells.dstore, + org.eclipse.rse.subsystems.shells.local, + org.eclipse.debug.core, + org.eclipse.core.resources, + org.eclipse.cdt.core, + org.eclipse.cdt.debug.mi.core, + org.eclipse.rse.subsystems.shells.core, + org.eclipse.rse.services, + org.eclipse.cdt.debug.core, + org.eclipse.cdt.debug.mi.ui +Eclipse-LazyStart: true +Bundle-Vendor: Eclipse.org diff --git a/rse/examples/org.eclipse.rse.remotecdt/build.properties b/rse/examples/org.eclipse.rse.remotecdt/build.properties new file mode 100644 index 00000000000..beca433fc77 --- /dev/null +++ b/rse/examples/org.eclipse.rse.remotecdt/build.properties @@ -0,0 +1,12 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml +src.includes = .classpath,\ + .project,\ + META-INF/,\ + build.properties,\ + icons/,\ + plugin.xml,\ + src/ diff --git a/rse/examples/org.eclipse.rse.remotecdt/icons/full/obj16/c_app.gif b/rse/examples/org.eclipse.rse.remotecdt/icons/full/obj16/c_app.gif new file mode 100644 index 0000000000000000000000000000000000000000..504ef509f9c5d688491dd731cb67e5f74ed2ceb2 GIT binary patch literal 606 zcmZ?wbhEHb6krfwc*el+^ueQyzCAe;_vKICA5^~~tZ8#t^X915t{lcYem0S60w~E!Cm1}%!*ZbD23vAe^ku>e{(=UZn)}MLw z`TE0`t1rFXe&hY&dml44Kg`|wD1Y0did|1y4m_K1?8Uq@udclO{QlSfPrv_P{rvyY zw||en{d@KE|LdRsKmPvz`1`*n-~YY*`Ty;&|IdE>d-d!8>tFxh{r>;{_y5m-{=fM7 z@6(_E-~Rsp`S1VEW5=7y9eZo-I;tF+%N(1_9s6qRIw~DzH(O1ux0%vlv%b${eV^&F zPVNi>4ZTA2Fe}+K=6o0ZXGB5-(=zv@ViW3I*-3@_F%`L4>f`USw zBBJ7~?3~<;O#Fcg3W^F!$||aAvU2j$lFWe}UBV(_ENmQHJiL5M{k67k+rG^|aEsC2 zeMUC>cX?`ATFOXCNa$MX>6+?#1qNtYTb{JDlQ?FpuOATTtz}_x(p*F1iLsfPcc71! zk?u*&d%C(-CMLdtep-fxlNc|s2^{MZbz7tmxUq?~B}Kw-LqcJ}(TN%kAwG9b6e>^D ea5O2CiB##DAnzQ+_p{MR)oV&y5+4@}gEauGD&+Y9 literal 0 HcmV?d00001 diff --git a/rse/examples/org.eclipse.rse.remotecdt/icons/full/obj16/systemlocal_obj.gif b/rse/examples/org.eclipse.rse.remotecdt/icons/full/obj16/systemlocal_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..d60c188caa989f405c3d090d48ad7c437ceb36db GIT binary patch literal 580 zcmZ?wbhEHb6krfwc*el+`RniRKYm;JH9CfMI7f7QB}@uPn-P{fFQI%zZ0WMJ`t>0x z&Ee^7-+ugw&hCuQ?@1|{@bKl2hcCZJWp`v&P0g&Fl2@qPnpVX*lfh( zJ7?}(9;0SsVP79bMn!L4MP5FWW;1?YE>1QUCVfu^e$!@i0be~muS18V1T2~@MK*JB zu(L8VNs3xETTA;&C@4tWme3WmX|~ny)e)4J6BH7Z6Sr%&*VL5Nl+n`E_V}XItmf3h l!YRShF+q^YSH{ROi9@iJyH{pn#S)i^LaGW%w&KYm;JH9CfMI7f7QB}@uPn-P{fFQI%zZ0WMJ`t>0x z&Ee^7-+ugw&+kboneg!CkB2Y6M`d?pR!z;UoRU{Jqqup_(>Fg}zWTetG-6 zhp&D-eD(dwn;$=Z{r&diw|2}N?WpP65tFsUC%6@_jjCT?)I7TksIp^zS^K;Puf9Kh z`{Ui`U!TAIdiL_IX8sY)yhEBf`!ut6X=QBHOxvK9woxm2jaJHPt;A*8iOaO&7it4h z%xtZw=~~g#wWFtNMNHO;oU9c-K|5lCc6fhT$Nam`KY#l6`|amn-+uo2`|tm^pTEz) z{r%<#(69gGYMf0vLoYqO$&e=8@zHtv_r421xBUPApJ9N2;!hSv28M739gzK?IALI4 z+YsK=+|m@#+R+lw-lS&GKcPRUJFLf$d&bNep&@fag2Rn?e3vZs3knRF-()Q0>!ZM^ z;Kl3j9k8IugwL0YlZ}N*&x0Yrz1fuCS6A2b%o%xovu1PQy<8mZtjtUjA{Nb-lD^_{ za^g?LbwsV2t<` + + + + + + + + + + + + + + + + + + + + + + diff --git a/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/Activator.java b/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/Activator.java new file mode 100644 index 00000000000..3c14ea97c0a --- /dev/null +++ b/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/Activator.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2006 PalmSource, Inc. + * 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: + * Ewa Matejska (PalmSource) + *******************************************************************************/ + +package org.eclipse.rse.remotecdt; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class Activator extends Plugin { + + //The shared instance. + private static Activator plugin; + + /** + * The constructor. + */ + public Activator() { + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + plugin = null; + } + + /** + * Returns the shared instance. + * + * @return the shared instance. + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/IRemoteConnectionConfigurationConstants.java b/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/IRemoteConnectionConfigurationConstants.java new file mode 100644 index 00000000000..a61d9232dac --- /dev/null +++ b/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/IRemoteConnectionConfigurationConstants.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2006 PalmSource, Inc. + * 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: + * Ewa Matejska (PalmSource) - Adapted from IGDBServerMILaunchConfigurationConstants + *******************************************************************************/ + + +package org.eclipse.rse.remotecdt; + +import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants; +import org.eclipse.debug.core.DebugPlugin; + +public interface IRemoteConnectionConfigurationConstants extends + IMILaunchConfigurationConstants { + + public static final String ATTR_REMOTE_CONNECTION = + DebugPlugin.getUniqueIdentifier() + ".REMOTE_TCP"; + + /* + * ATTR_TCP_PORT: gdbserver port. + */ + public static final String ATTR_TCP_PORT = "2345"; + + /* + * Generic Remote Path and Download options + * ATTR_REMOTE_PATH: Path of the binary on the remote. + * ATTR_SKIP_DOWNLOAD_TO_TARGET: true if download to remote is not desired. + */ + public static final String ATTR_REMOTE_PATH = + DebugPlugin.getUniqueIdentifier() + ".ATTR_TARGET_PATH"; + public static final String ATTR_SKIP_DOWNLOAD_TO_TARGET = + DebugPlugin.getUniqueIdentifier() + ".ATTR_SKIP_DOWNLOAD_TO_TARGET"; + +} diff --git a/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/RemoteCMainTab.java b/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/RemoteCMainTab.java new file mode 100644 index 00000000000..2dbae1419da --- /dev/null +++ b/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/RemoteCMainTab.java @@ -0,0 +1,331 @@ +/******************************************************************************* + * Copyright (c) 2006 PalmSource, Inc. + * 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: + * Ewa Matejska (PalmSource) + *******************************************************************************/ + +package org.eclipse.rse.remotecdt; + +import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin; +import org.eclipse.cdt.launch.ui.CMainTab; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.rse.model.IHost; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemNewConnectionAction; +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.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + + +public class RemoteCMainTab extends CMainTab { + + private static final String[] SYSTEM_TYPE = {"Ssh/Gdbserver"}; + /* Labels and Error Messages */ + private static final String REMOTE_PROG_LABEL_TEXT = "Remote Path for C/C++ Application:"; + private static final String SKIP_DOWNLOAD_BUTTON_TEXT = "Skip download to target path."; + private static final String REMOTE_PROG_TEXT_ERROR = "Remote executable path is not specified."; + private static final String CONNECTION_TEXT_ERROR = "Remote Connection must be selected."; + + /* Defaults */ + private static final String REMOTE_PATH_DEFAULT = EMPTY_STRING; + private static final boolean SKIP_DOWNLOAD_TO_REMOTE_DEFAULT = false; + + protected Button newRemoteConnectionButton; + protected Label connectionLabel; + protected Combo connectionCombo; + protected Label remoteProgLabel; + protected Text remoteProgText; + protected Button skipDownloadButton; + protected Button useLocalPathButton; + + private boolean initialized = false; + SystemNewConnectionAction action = null; + + public RemoteCMainTab(boolean terminalOption) { + super(terminalOption); + } + + /* + * createControl + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl + */ + public void createControl(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE); + GridLayout topLayout = new GridLayout(); + setControl(comp); + comp.setLayout(topLayout); + + /* The RSE Connection dropdown with New button. */ + createVerticalSpacer(comp, 1); + createRemoteConnectionGroup(comp, 3); + + /* The Project and local binary location */ + createVerticalSpacer(comp, 1); + createProjectGroup(comp, 1); + createExeFileGroup(comp, 1); + + /* The remote binary location and skip download option */ + createVerticalSpacer(comp, 1); + createTargetExePath(comp); + createDownloadOption(comp); + + /* If the local binary path changes, modify the remote binary location */ + fProgText.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent evt) { + if(initialized) + setLocalPathForRemotePath(); + else + initialized = true; + } + }); + + LaunchUIPlugin.setDialogShell(parent.getShell()); + } + + /* + * isValid + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid + */ + public boolean isValid(ILaunchConfiguration config) { + boolean retVal = super.isValid(config); + if(retVal == true) { + setErrorMessage(null); + int currentSelection = connectionCombo.getSelectionIndex(); + String connection_name = currentSelection >= 0 ? connectionCombo.getItem(currentSelection) : ""; + if(connection_name.equals("")) { + setErrorMessage(CONNECTION_TEXT_ERROR); + retVal = false; + } + if(retVal) { + String name = remoteProgText.getText().trim(); + if (name.length() == 0) { + setErrorMessage(REMOTE_PROG_TEXT_ERROR); + retVal = false; + } + } + } + return retVal; + } + + protected void createRemoteConnectionGroup(Composite parent, int colSpan) { + Composite projComp = new Composite(parent, SWT.NONE); + GridLayout projLayout = new GridLayout(); + projLayout.numColumns = 3; + projLayout.marginHeight = 0; + projLayout.marginWidth = 0; + projComp.setLayout(projLayout); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = colSpan; + projComp.setLayoutData(gd); + + connectionLabel = new Label(projComp, SWT.NONE); + connectionLabel.setText("Connection:"); + gd = new GridData(); + gd.horizontalSpan = 1; + connectionLabel.setLayoutData(gd); + + connectionCombo = new Combo(projComp, SWT.DROP_DOWN | SWT.READ_ONLY); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 1; + connectionCombo.setLayoutData(gd); + connectionCombo.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent e) { + setDirty(true); + updateLaunchConfigurationDialog(); + } + }); + updateConnectionPulldown(); + + newRemoteConnectionButton = createPushButton(projComp, "New", null); + newRemoteConnectionButton.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) { + handleNewRemoteConnectionSelected(); + updateLaunchConfigurationDialog(); + updateConnectionPulldown(); + } + }); + + } + + /* + * createTargetExePath + * This creates the remote path user-editable textfield on the Main Tab. + */ + protected void createTargetExePath(Composite parent) { + Composite mainComp = new Composite(parent, SWT.NONE); + GridLayout mainLayout = new GridLayout(); + mainLayout.marginHeight = 0; + mainLayout.marginWidth = 0; + mainComp.setLayout(mainLayout); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + mainComp.setLayoutData(gd); + remoteProgLabel = new Label(mainComp, SWT.NONE); + remoteProgLabel.setText(REMOTE_PROG_LABEL_TEXT); + gd = new GridData(); + remoteProgLabel.setLayoutData(gd); + remoteProgText = new Text(mainComp, SWT.SINGLE | SWT.BORDER); + gd = new GridData(GridData.FILL_HORIZONTAL); + remoteProgText.setLayoutData(gd); + remoteProgText.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent evt) { + updateLaunchConfigurationDialog(); + } + }); + } + + /* + * createDownloadOption + * This creates the skip download check button. + */ + protected void createDownloadOption(Composite parent) { + Composite mainComp = new Composite(parent, SWT.NONE); + GridLayout mainLayout = new GridLayout(); + mainLayout.marginHeight = 0; + mainLayout.marginWidth = 0; + mainComp.setLayout(mainLayout); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + mainComp.setLayoutData(gd); + + skipDownloadButton = createCheckButton(mainComp, SKIP_DOWNLOAD_BUTTON_TEXT); + skipDownloadButton.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) { + updateLaunchConfigurationDialog(); + } + }); + skipDownloadButton.setEnabled(true); + } + + /* + * performApply + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply + */ + public void performApply(ILaunchConfigurationWorkingCopy config) { + + int currentSelection = connectionCombo.getSelectionIndex(); + config.setAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION, + currentSelection >= 0 ? connectionCombo.getItem(currentSelection) : null); + config.setAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH, + remoteProgText.getText()); + config.setAttribute(IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, + skipDownloadButton.getSelection()); + super.performApply(config); + } + + /* + * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom + */ + public void initializeFrom(ILaunchConfiguration config) { + String remoteConnection = null; + try { + remoteConnection = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION, + ""); + } catch (CoreException ce) { + /* default to doing nothing */ + } + + String[] items = connectionCombo.getItems(); + int i = 0; + for(i = 0; i < items.length; i++) + if(items[i].equals(remoteConnection)) + break; + /* Select the last used connection in the connecion pulldown if it still exists. */ + if(i < items.length) + connectionCombo.select(i); + else if(items.length > 0) + connectionCombo.select(0); + + super.initializeFrom(config); + + updateTargetProgFromConfig(config); + updateSkipDownloadFromConfig(config); + } + + protected void handleNewRemoteConnectionSelected() { + if (action == null) + { + action = new SystemNewConnectionAction(getControl().getShell(), false, false, null); + } + action.restrictSystemTypes(SYSTEM_TYPE); + + try + { + action.run(); + } catch (Exception exc) + { + /* Ignore for now */ + } + } + + protected void updateConnectionPulldown() { + connectionCombo.removeAll(); + IHost[] connections = RSEUIPlugin.getTheSystemRegistry().getHostsBySystemType(SYSTEM_TYPE[0]); + for(int i = 0; i < connections.length; i++) + connectionCombo.add(connections[i].getAliasName()); + if(connections.length > 0) + connectionCombo.select(0); + } + + protected void updateTargetProgFromConfig(ILaunchConfiguration config) { + String targetPath = null; + try { + targetPath = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH, + REMOTE_PATH_DEFAULT); + } catch (CoreException ce) { + /* Ignore for now */ + } + remoteProgText.setText(targetPath); + } + + protected void updateSkipDownloadFromConfig(ILaunchConfiguration config) { + boolean downloadToTarget = true; + try { + downloadToTarget = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, + SKIP_DOWNLOAD_TO_REMOTE_DEFAULT); + } catch (CoreException e) { + /* Ignore for now */ + } + skipDownloadButton.setSelection(downloadToTarget); + } + + /* + * setLocalPathForRemotePath + * This function sets the remote path text field with the value of the + * local executable path. + */ + private void setLocalPathForRemotePath() { + String name = fProgText.getText().trim(); + if (name.length() != 0) { + IProject project = getCProject().getProject(); + IPath exePath = new Path(name); + if (!exePath.isAbsolute()) { + exePath = project.getFile(name).getLocation(); + } + String path = exePath.toString(); + remoteProgText.setText(path); + } + } +} diff --git a/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/RemoteLaunchConfigurationTabGroup.java b/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/RemoteLaunchConfigurationTabGroup.java new file mode 100644 index 00000000000..3e97877a172 --- /dev/null +++ b/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/RemoteLaunchConfigurationTabGroup.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2006 PalmSource, Inc. + * 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: + * Ewa Matejska (PalmSource) - Adapted from LocalRunLaunchConfigurationTabGroup + *******************************************************************************/ + + +package org.eclipse.rse.remotecdt; +import org.eclipse.cdt.launch.ui.CArgumentsTab; +import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; +import org.eclipse.debug.ui.CommonTab; +import org.eclipse.debug.ui.ILaunchConfigurationDialog; +import org.eclipse.debug.ui.ILaunchConfigurationTab; +import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; + +/** + * This class defines the tab group for the Remote C++ Launch + * Configuration. + */ +public class RemoteLaunchConfigurationTabGroup extends + AbstractLaunchConfigurationTabGroup { + public void createTabs(ILaunchConfigurationDialog dialog, String mode) { + ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] { + new RemoteCMainTab(true), + new CArgumentsTab(), + new SourceLookupTab(), + new CommonTab() + }; + setTabs(tabs); + } +} \ No newline at end of file diff --git a/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/RemoteRunLaunchDelegate.java b/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/RemoteRunLaunchDelegate.java new file mode 100644 index 00000000000..32b76b252fa --- /dev/null +++ b/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/remotecdt/RemoteRunLaunchDelegate.java @@ -0,0 +1,268 @@ +/******************************************************************************* + * Copyright (c) 2006 PalmSource, Inc. + * 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: + * Ewa Matejska (PalmSource) - Adapted from LocalRunLaunchDelegate + *******************************************************************************/ + + + +package org.eclipse.rse.remotecdt; + +import java.io.IOException; +import java.io.OutputStream; + +import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.debug.core.CDIDebugModel; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.debug.core.cdi.CDIException; +import org.eclipse.cdt.debug.core.cdi.ICDISession; +import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; +import org.eclipse.cdt.debug.mi.core.GDBServerCDIDebugger; +import org.eclipse.cdt.debug.mi.core.IGDBServerMILaunchConfigurationConstants; +import org.eclipse.cdt.launch.AbstractCLaunchDelegate; +import org.eclipse.cdt.utils.spawner.Spawner; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.core.model.IProcess; +import org.eclipse.rse.model.IHost; +import org.eclipse.rse.ui.RSEUIPlugin; + + +public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate { + + private final static String REMOTE_GDBSERVER_COMMAND = "gdbserver"; + private final static String SFTP_COMMAND = "sftp"; + private final static String SFTP_COMMAND_ARGS = "-b -"; + private final static String SSH_COMMAND = "ssh"; + private final static String SYSTEM_TYPE = "Ssh/Gdbserver"; + /* + * (non-Javadoc) + * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch + */ + public void launch(ILaunchConfiguration config, String mode, ILaunch launch, + IProgressMonitor monitor) throws CoreException { + + IBinaryObject exeFile = null; + IPath exePath = verifyProgramPath(config); + ICProject project = verifyCProject(config); + if (exePath != null) { + exeFile = verifyBinary(project, exePath); + } + + String arguments = getProgramArguments(config); + String remoteExePath = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH, + ""); + + if(mode.equals(ILaunchManager.DEBUG_MODE)){ + setDefaultSourceLocator(launch, config); + ICDISession dsession = null; + String debugMode = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN); + if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) { + /* Download the binary to the remote before debugging using the scp program*/ + remoteSftpDownload(config, launch, exePath.toString(), remoteExePath); + + /* Default to using the GDBServerCDIDebugger. */ + GDBServerCDIDebugger debugger = new GDBServerCDIDebugger(); + + /* Automatically start up the gdbserver to be used by the GDBServerCDIDebugger on the remote + * using ssh. + */ + String command_arguments = ":" + IRemoteConnectionConfigurationConstants.ATTR_TCP_PORT + " " + remoteExePath; + if(arguments != null && !arguments.equals("")) + command_arguments += " " + arguments; + Process sshProcess = remoteSshExec(config, REMOTE_GDBSERVER_COMMAND, command_arguments); + DebugPlugin.newProcess(launch, sshProcess, renderProcessLabel(REMOTE_GDBSERVER_COMMAND)); + /* Pre-set configuration constants for the GDBSERVERCDIDebugger to indicate how the gdbserver + * was automatically started on the remote. GDBServerCDIDebugger uses these to figure out how + * to connect to the remote gdbserver. + */ + ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy(); + wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_REMOTE_TCP, true); + wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_HOST, getRemoteHostname(config)); + wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_PORT, + IRemoteConnectionConfigurationConstants.ATTR_TCP_PORT); + + dsession = debugger.createLaunchSession(wc.doSave(), exeFile, new SubProgressMonitor(monitor, 8)); + + try { + /* Assume that stopInMain is true until the Debugger tab is added */ + boolean stopInMain = true; + String stopSymbol = null; + if ( stopInMain ) + stopSymbol = launch.getLaunchConfiguration(). + getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, + ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT ); + + ICDITarget[] targets = dsession.getTargets(); + for (int i = 0; i < targets.length; i++) { + Process process = targets[i].getProcess(); + IProcess iprocess = null; + if (process != null) { + iprocess = DebugPlugin.newProcess(launch, process, + renderProcessLabel(exePath.toOSString()), getDefaultProcessMap()); + } + CDIDebugModel.newDebugTarget(launch, project.getProject(), targets[i], + renderProcessLabel("gdbserver debugger"), + iprocess, exeFile, true, false, stopSymbol, true); + } + } catch (CoreException e) { + try { + dsession.terminate(); + } catch (CDIException e1) { + // ignore + } + throw e; + } + } + + } else if(mode.equals(ILaunchManager.RUN_MODE)) { + /* Download the binary to the remote before debugging */ + remoteSftpDownload(config, launch, exePath.toString(),remoteExePath ); + + /* Use ssh to launch the binary on the remote */ + Process process = remoteSshExec(config, remoteExePath, arguments); + DebugPlugin.newProcess(launch, process, renderProcessLabel(exePath.toOSString())); + + } else { + IStatus status = new Status(IStatus.ERROR, getPluginID(), + IStatus.OK, "Unidentified mode " + mode + " passed to RemoteRunLaunchDelegate", null); + throw new CoreException(status); + } + } + + private String quotify(String inputString) { + if(inputString == null) + return null; + return '"' + inputString + '"'; + } + + private String spaceEscapify(String inputString) { + if(inputString == null) + return null; + + return inputString.replaceAll(" ", "\\\\ "); + } + + protected Process remoteSftpDownload(ILaunchConfiguration config, ILaunch launch, String localExePath, String remoteExePath) + throws CoreException { + boolean skipDownload = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, + false); + + if(skipDownload) + //Nothing to do. Download is skipped. + return null; + + String arguments = SFTP_COMMAND_ARGS + " " + getRemoteHostname(config); + Process p = null; + try { + p = execLocal(SFTP_COMMAND, arguments); + DebugPlugin.newProcess(launch, p, renderProcessLabel(SFTP_COMMAND)); + OutputStream outStream = p.getOutputStream(); + String putCommand = "put " + quotify(localExePath) + " " + quotify(remoteExePath) + "\n"; + String exitCommand = "exit\n"; + // Execute the put and then the exit command. + outStream.write(putCommand.getBytes()); + outStream.write(exitCommand.getBytes()); + if(p.waitFor() != 0) { + IStatus status = new Status(IStatus.ERROR, getPluginID(), + IStatus.OK, "Couldn't download program to remote. See console for reason.", null); + throw new CoreException(status); + } + } catch (InterruptedException e) { + } catch (IOException e) { + } + + return null; + } + + protected String getRemoteHostname(ILaunchConfiguration config) throws CoreException{ + String remoteConnection = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION, + ""); + + IHost[] connections = RSEUIPlugin.getTheSystemRegistry().getHostsBySystemType(SYSTEM_TYPE); + int i = 0; + for(i = 0; i < connections.length; i++) + if(connections[i].getAliasName().equals(remoteConnection)) + break; + if(i >= connections.length) { + IStatus status = new Status(IStatus.ERROR, getPluginID(), + IStatus.OK, "Internal Error: Could not find the remote connection.\n", null); + throw new CoreException(status); + } + return connections[i].getHostName(); + } + + protected Process remoteSshExec(ILaunchConfiguration config, String remoteCommandPath, + String arguments) throws CoreException { + String remote_command = arguments == null ? spaceEscapify(remoteCommandPath) : + spaceEscapify(remoteCommandPath) + " " + arguments; + String ssh_arguments = getRemoteHostname(config) + " " + remote_command; + + Process p = execLocal(SSH_COMMAND, ssh_arguments); + return p; + + /* In the future the Shell subsystem from RSE should be used instead of invoking ssh and scp + * directly. The code to accomplish this might look like below. + */ + + /*ISubSystem[] subSystems = connections[i].getSubSystems(); + for(i = 0; i < subSystems.length; i++) + if(subSystems[i] instanceof IShellServiceSubSystem) + break; + if(i >= subSystems.length) + abort("Internal Error: No shell subsystem found.\n", null, 0); + IShellServiceSubSystem shellSubSystem = (IShellServiceSubSystem) subSystems[i]; + IShellService shellService = shellSubSystem.getShellService(); + String command = arguments == null ? file.toOSString() : file.toOSString() + " " + arguments; + + IHostShell hostShell = shellService.runCommand(null, file.removeLastSegments(1).toOSString(),command, null); + + Process p = null; + try { + p = new HostShellProcess(hostShell); + } catch (Exception e) { + if (p != null) { + p.destroy(); + } + abort("Internal Error: Could not create the hostShellProcess.\n", null, 0); + } + */ + } + + protected Process execLocal(String file, String arguments) throws CoreException { + Process p = null; + String command = file + " " + arguments; + try { + p = new Spawner(command, false); + } catch (Exception e) { + if (p != null) { + p.destroy(); + } + IStatus status = new Status(IStatus.ERROR, getPluginID(), + IStatus.OK, "Internal Error: Could not execute command.\n", null); + throw new CoreException(status); + } + + return p; + } + + protected String getPluginID() { + return "org.eclipse.rse.remotecdt"; + } +}