From 9c8e811837e8486cad35bc94b52a5d64437cd57a Mon Sep 17 00:00:00 2001 From: Martin Oberhuber < martin.oberhuber@windriver.com> Date: Wed, 9 Apr 2008 21:42:16 +0000 Subject: [PATCH] [226301][api][breaking] IShellService methods should throw SystemMessageException --- .../remotecdt/RemoteRunLaunchDelegate.java | 94 +++++++++---------- .../dstore/shells/DStoreShellService.java | 12 ++- .../local/shells/LocalShellService.java | 8 +- .../services/ssh/shell/SshShellService.java | 11 +-- .../telnet/shell/TelnetShellService.java | 12 +-- .../eclipse/rse/services/AbstractService.java | 4 +- .../services/shells/AbstractShellService.java | 23 +++-- .../rse/services/shells/IShellService.java | 60 +++++++----- .../shell/linux/LinuxProcessHelper.java | 24 ++--- .../shell/linux/LinuxShellProcessService.java | 8 +- .../ShellServiceSubSystem.java | 65 +++++++------ 11 files changed, 176 insertions(+), 145 deletions(-) diff --git a/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/internal/remotecdt/RemoteRunLaunchDelegate.java b/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/internal/remotecdt/RemoteRunLaunchDelegate.java index ff13e051d11..22404ed5ee4 100644 --- a/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/internal/remotecdt/RemoteRunLaunchDelegate.java +++ b/rse/examples/org.eclipse.rse.remotecdt/src/org/eclipse/rse/internal/remotecdt/RemoteRunLaunchDelegate.java @@ -1,14 +1,15 @@ /******************************************************************************* - * Copyright (c) 2006, 2007 PalmSource, 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: + * Copyright (c) 2006, 2008 PalmSource, 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: * Ewa Matejska (PalmSource) - Adapted from LocalRunLaunchDelegate * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry + * Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error *******************************************************************************/ @@ -55,19 +56,19 @@ import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.IShell import org.eclipse.swt.widgets.Display; public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate { - + private final static String SHELL_SERVICE = "shell.service"; //$NON-NLS-1$ private final static String FILE_SERVICE = "file.service"; //$NON-NLS-1$ private final static String EXIT_CMD = "exit"; //$NON-NLS-1$ private final static String CMD_DELIMITER = ";"; //$NON-NLS-1$ - + /* * (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); @@ -77,9 +78,9 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate { String arguments = getProgramArguments(config); String remoteExePath = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH, ""); //$NON-NLS-1$ - + if(mode.equals(ILaunchManager.DEBUG_MODE)){ - setDefaultSourceLocator(launch, config); + setDefaultSourceLocator(launch, config); String debugMode = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN); if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) { @@ -88,7 +89,7 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate { try { // Download the binary to the remote before debugging. remoteFileDownload(config, launch, exePath.toString(), remoteExePath); - + // Automatically start up the gdbserver. In the future this should be expanded to launch // an arbitrary remote damon. String gdbserver_port_number = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_PORT, @@ -102,28 +103,28 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate { remoteShellProcess = remoteShellExec(config, gdbserver_command, command_arguments); DebugPlugin.newProcess(launch, remoteShellProcess, Messages.RemoteRunLaunchDelegate_RemoteShell); - + // 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, + wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_HOST, getRemoteHostname(config)); + wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_PORT, gdbserver_port_number); wc.doSave(); // Default to using the GDBServerCDIDebugger. GDBServerCDIDebugger2 debugger = new GDBServerCDIDebugger2(); - dsession = ((ICDIDebugger2)debugger).createSession(launch, exePath.toFile(), + dsession = ((ICDIDebugger2)debugger).createSession(launch, exePath.toFile(), new SubProgressMonitor(monitor, 8)); boolean stopInMain = config .getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false); String stopSymbol = null; if ( stopInMain ) - stopSymbol = launch.getLaunchConfiguration().getAttribute( - ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, + stopSymbol = launch.getLaunchConfiguration().getAttribute( + ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT ); ICDITarget[] targets = dsession.getTargets(); @@ -133,8 +134,8 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate { if (process != null) { iprocess = DebugPlugin.newProcess(launch, process, renderProcessLabel(exePath.toOSString()), getDefaultProcessMap()); - } - CDIDebugModel.newDebugTarget(launch, project.getProject(), targets[i], + } + CDIDebugModel.newDebugTarget(launch, project.getProject(), targets[i], renderProcessLabel("gdbserver debugger"), //$NON-NLS-1$ iprocess, exeFile, true, false, stopSymbol, true); } @@ -164,21 +165,21 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate { remoteProcess.destroy(); throw e; } - + } else { IStatus status = new Status(IStatus.ERROR, getPluginID(), IStatus.OK, NLS.bind(Messages.RemoteRunLaunchDelegate_1, mode), null); throw new CoreException(status); - } + } } - + private String spaceEscapify(String inputString) { if(inputString == null) return null; - + return inputString.replaceAll(" ", "\\\\ "); //$NON-NLS-1$ //$NON-NLS-2$ } - + protected IHost getCurrentConnection(ILaunchConfiguration config) throws CoreException { String remoteConnection = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION, ""); //$NON-NLS-1$ @@ -192,16 +193,16 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate { } return connections[i]; } - + protected IService getConnectedRemoteService(ILaunchConfiguration config, String kindOfService) throws CoreException { - + // Check that the service requested is file or shell. if(!kindOfService.equals(SHELL_SERVICE) && !kindOfService.equals(FILE_SERVICE)) abort(Messages.RemoteRunLaunchDelegate_3, null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); - + IHost currentConnection = getCurrentConnection(config); - + ISubSystem[] subSystems = currentConnection.getSubSystems(); int i = 0; for(i = 0; i < subSystems.length; i++) { @@ -226,21 +227,21 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate { } } }); - + if(!subsystem.isConnected()) abort(Messages.RemoteRunLaunchDelegate_5, null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); - + if(kindOfService.equals(SHELL_SERVICE)) return ((IShellServiceSubSystem) subsystem).getShellService(); else return ((IFileServiceSubSystem) subsystem).getFileService(); } - + protected Process remoteFileDownload(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; @@ -257,44 +258,43 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate { p.destroy(); } catch (Exception e) { abort(Messages.RemoteRunLaunchDelegate_6, e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR ); - } + } return null; } - + protected String getRemoteHostname(ILaunchConfiguration config) throws CoreException { IHost currentConnection = getCurrentConnection(config); return currentConnection.getHostName(); } - + protected Process remoteShellExec(ILaunchConfiguration config, String remoteCommandPath, String arguments) throws CoreException { - // The exit command is called to force the remote shell to close after our command + // The exit command is called to force the remote shell to close after our command // is executed. This is to prevent a running process at the end of the debug session. // See Bug 158786. String real_remote_command = arguments == null ? spaceEscapify(remoteCommandPath) : spaceEscapify(remoteCommandPath) + " " + arguments; //$NON-NLS-1$ String remote_command = real_remote_command + CMD_DELIMITER + EXIT_CMD; - + IShellService shellService = (IShellService) getConnectedRemoteService(config, SHELL_SERVICE); - + // This is necessary because runCommand does not actually run the command right now. String env[] = new String[0]; - IHostShell hostShell = shellService.launchShell("", env,new NullProgressMonitor()); //$NON-NLS-1$ - hostShell.writeToShell(remote_command); - Process p = null; try { + IHostShell hostShell = shellService.launchShell("", env, new NullProgressMonitor()); //$NON-NLS-1$ + hostShell.writeToShell(remote_command); p = new HostShellProcessAdapter(hostShell); } catch (Exception e) { if (p != null) { p.destroy(); } - abort(Messages.RemoteRunLaunchDelegate_7, null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); + abort(Messages.RemoteRunLaunchDelegate_7, e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); } return p; - + } - + protected String getPluginID() { return "org.eclipse.rse.internal.remotecdt"; //$NON-NLS-1$ } diff --git a/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/internal/services/dstore/shells/DStoreShellService.java b/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/internal/services/dstore/shells/DStoreShellService.java index e39f08848b1..8322c759dac 100644 --- a/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/internal/services/dstore/shells/DStoreShellService.java +++ b/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/internal/services/dstore/shells/DStoreShellService.java @@ -17,6 +17,7 @@ * David McKnight (IBM) - [196624] dstore miner IDs should be String constants rather than dynamic lookup * David McKnight (IBM) - [216252] use SimpleSystemMessage instead of getMessage() * Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable and add Javadoc + * Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error *******************************************************************************/ package org.eclipse.rse.internal.services.dstore.shells; @@ -32,6 +33,7 @@ import org.eclipse.dstore.core.model.IDataStoreProvider; import org.eclipse.rse.dstore.universal.miners.IUniversalDataStoreConstants; import org.eclipse.rse.internal.services.dstore.ServiceResources; import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; import org.eclipse.rse.services.dstore.AbstractDStoreService; import org.eclipse.rse.services.dstore.util.DStoreStatusMonitor; import org.eclipse.rse.services.shells.IHostShell; @@ -60,7 +62,7 @@ public class DStoreShellService extends AbstractDStoreService implements IShellS } - public IHostShell launchShell(String initialWorkingDirectory, String[] environment, IProgressMonitor monitor) + public IHostShell launchShell(String initialWorkingDirectory, String[] environment, IProgressMonitor monitor) throws SystemMessageException { if (!isInitialized()) { @@ -69,7 +71,7 @@ public class DStoreShellService extends AbstractDStoreService implements IShellS return launchShell(initialWorkingDirectory, null, environment, monitor); } - public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, IProgressMonitor monitor) + public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, IProgressMonitor monitor) throws SystemMessageException { if (!isInitialized()) { @@ -79,7 +81,7 @@ public class DStoreShellService extends AbstractDStoreService implements IShellS } public IHostShell runCommand(String initialWorkingDirectory, String command, String[] environment, - IProgressMonitor monitor) + IProgressMonitor monitor) throws SystemMessageException { if (!isInitialized()) { @@ -89,7 +91,7 @@ public class DStoreShellService extends AbstractDStoreService implements IShellS } public IHostShell runCommand(String initialWorkingDirectory, String command, String encoding, - String[] environment, IProgressMonitor monitor) + String[] environment, IProgressMonitor monitor) throws SystemMessageException { if (!isInitialized()) { @@ -98,7 +100,7 @@ public class DStoreShellService extends AbstractDStoreService implements IShellS return new DStoreHostShell(getStatusMonitor(getDataStore()), getDataStore(), initialWorkingDirectory, command, encoding, environment); } - public String[] getHostEnvironment() + public String[] getHostEnvironment() throws SystemMessageException { if (_envVars == null || _envVars.length == 0) { diff --git a/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/shells/LocalShellService.java b/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/shells/LocalShellService.java index 0d2bee285ce..910d1b45287 100644 --- a/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/shells/LocalShellService.java +++ b/rse/plugins/org.eclipse.rse.services.local/src/org/eclipse/rse/internal/services/local/shells/LocalShellService.java @@ -13,6 +13,7 @@ * Contributors: * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable + * Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error ********************************************************************************/ package org.eclipse.rse.internal.services.local.shells; @@ -26,6 +27,7 @@ import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.rse.internal.services.local.ILocalService; import org.eclipse.rse.internal.services.local.LocalServiceResources; +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; import org.eclipse.rse.services.shells.AbstractShellService; import org.eclipse.rse.services.shells.IHostShell; @@ -48,21 +50,21 @@ public class LocalShellService extends AbstractShellService implements ILocalSer return LocalServiceResources.Local_Shell_Service_Description; } - public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, IProgressMonitor monitor) + public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, IProgressMonitor monitor) throws SystemMessageException { LocalHostShell hostShell = new LocalHostShell(initialWorkingDirectory,SHELL_INVOCATION, encoding, environment); hostShell.run(monitor); return hostShell; } - public IHostShell runCommand(String initialWorkingDirectory, String command, String encoding, String[] environment, IProgressMonitor monitor) + public IHostShell runCommand(String initialWorkingDirectory, String command, String encoding, String[] environment, IProgressMonitor monitor) throws SystemMessageException { LocalHostShell hostShell = new LocalHostShell(initialWorkingDirectory,command, encoding, environment); hostShell.run(monitor); return hostShell; } - public String[] getHostEnvironment() + public String[] getHostEnvironment() throws SystemMessageException { if (_envVars == null) { diff --git a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/shell/SshShellService.java b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/shell/SshShellService.java index 08471e83d59..9fd81e23113 100644 --- a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/shell/SshShellService.java +++ b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/shell/SshShellService.java @@ -15,6 +15,7 @@ * Martin Oberhuber (Wind River) - Adapted from LocalShellService. * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable + * Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error *******************************************************************************/ package org.eclipse.rse.internal.services.ssh.shell; @@ -24,6 +25,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.rse.internal.services.ssh.ISshService; import org.eclipse.rse.internal.services.ssh.ISshSessionProvider; import org.eclipse.rse.internal.services.ssh.SshServiceResources; +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; import org.eclipse.rse.services.shells.AbstractShellService; import org.eclipse.rse.services.shells.IHostShell; @@ -41,23 +43,18 @@ public class SshShellService extends AbstractShellService implements ISshService public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, - IProgressMonitor monitor) { + IProgressMonitor monitor) throws SystemMessageException { SshHostShell hostShell = new SshHostShell(fSessionProvider, initialWorkingDirectory, SshHostShell.SHELL_INVOCATION, encoding, environment); return hostShell; } public IHostShell runCommand(String initialWorkingDirectory, String command, String encoding, String[] environment, - IProgressMonitor monitor) { + IProgressMonitor monitor) throws SystemMessageException { SshHostShell hostShell = new SshHostShell(fSessionProvider, initialWorkingDirectory, command, encoding, environment); return hostShell; } - public String[] getHostEnvironment() { - //TODO getHostEnvironment is not yet implemented for ssh (needs running remote command and parsing) - return new String[0]; - } - public String getName() { return SshServiceResources.SshShellService_Name; } diff --git a/rse/plugins/org.eclipse.rse.services.telnet/src/org/eclipse/rse/internal/services/telnet/shell/TelnetShellService.java b/rse/plugins/org.eclipse.rse.services.telnet/src/org/eclipse/rse/internal/services/telnet/shell/TelnetShellService.java index d9b20a60018..d3c1142bcbc 100644 --- a/rse/plugins/org.eclipse.rse.services.telnet/src/org/eclipse/rse/internal/services/telnet/shell/TelnetShellService.java +++ b/rse/plugins/org.eclipse.rse.services.telnet/src/org/eclipse/rse/internal/services/telnet/shell/TelnetShellService.java @@ -15,13 +15,15 @@ * Martin Oberhuber (Wind River) - Adapted from LocalShellService. * Sheldon D'souza (Celunite) - Adapted from SshShellService. * Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable - *******************************************************************************/ + * Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error +s *******************************************************************************/ package org.eclipse.rse.internal.services.telnet.shell; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.rse.internal.services.telnet.ITelnetService; import org.eclipse.rse.internal.services.telnet.ITelnetSessionProvider; import org.eclipse.rse.internal.services.telnet.TelnetServiceResources; +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; import org.eclipse.rse.services.shells.AbstractShellService; import org.eclipse.rse.services.shells.IHostShell; @@ -33,20 +35,16 @@ public class TelnetShellService extends AbstractShellService implements ITelnetS this.fTelnetSessionProvider = sessionProvider; } - public String[] getHostEnvironment() { - return new String[0]; - } - public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, - IProgressMonitor monitor) { + IProgressMonitor monitor) throws SystemMessageException { TelnetHostShell hostShell = new TelnetHostShell(fTelnetSessionProvider, initialWorkingDirectory, TelnetHostShell.SHELL_INVOCATION, encoding, environment); return hostShell; } public IHostShell runCommand(String initialWorkingDirectory, String command, String encoding, String[] environment, - IProgressMonitor monitor) { + IProgressMonitor monitor) throws SystemMessageException { TelnetHostShell hostShell = new TelnetHostShell(fTelnetSessionProvider, initialWorkingDirectory, TelnetHostShell.SHELL_INVOCATION, encoding, environment); return hostShell; } diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/AbstractService.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/AbstractService.java index d004bc59c0a..aa86b33dd2f 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/AbstractService.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/AbstractService.java @@ -16,9 +16,9 @@ import org.eclipse.core.runtime.PlatformObject; /** * Abstract default implementation of an RSE Service. Clients are expected to * extend this class. - * + * * @see IService - * @since org.eclipse.rse.core 3.0 + * @since org.eclipse.rse.services 3.0 */ public abstract class AbstractService extends PlatformObject implements IService { diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/shells/AbstractShellService.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/shells/AbstractShellService.java index 256c2515e0b..8d4f5ef7b9a 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/shells/AbstractShellService.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/shells/AbstractShellService.java @@ -7,6 +7,7 @@ * * Contributors: * Martin Oberhuber (Wind River) - initial API and implementation + * Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error *******************************************************************************/ package org.eclipse.rse.services.shells; @@ -14,31 +15,41 @@ package org.eclipse.rse.services.shells; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.rse.services.AbstractService; +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; /** * Abstract base class for RSE Shell Service implementations. + * + * @since org.eclipse.rse.services 3.0 */ public abstract class AbstractShellService extends AbstractService implements IShellService { - /* (non-Javadoc) - * @see org.eclipse.rse.services.shells.IShellService#getHostEnvironment() + private static final String[] EMPTY_ARRAY = new String[0]; + + /** + * Return an empty host environment. Extenders should override this method + * if they are able to return environment on the remote side. If they do not + * implement this feature, they must not override this method. + * + * @see IShellService#getHostEnvironment() */ - public String[] getHostEnvironment() { + public String[] getHostEnvironment() throws SystemMessageException { // not implemented by default - return null; + // TODO SSH https://bugs.eclipse.org/bugs/show_bug.cgi?id=162018 + return EMPTY_ARRAY; } /* (non-Javadoc) * @see org.eclipse.rse.services.shells.IShellService#launchShell(java.lang.String, java.lang.String[], org.eclipse.core.runtime.IProgressMonitor) */ - public IHostShell launchShell(String initialWorkingDirectory, String[] environment, IProgressMonitor monitor) { + public IHostShell launchShell(String initialWorkingDirectory, String[] environment, IProgressMonitor monitor) throws SystemMessageException { return launchShell(initialWorkingDirectory, null, environment, monitor); } /* (non-Javadoc) * @see org.eclipse.rse.services.shells.IShellService#runCommand(java.lang.String, java.lang.String, java.lang.String[], org.eclipse.core.runtime.IProgressMonitor) */ - public IHostShell runCommand(String initialWorkingDirectory, String command, String[] environment, IProgressMonitor monitor) { + public IHostShell runCommand(String initialWorkingDirectory, String command, String[] environment, IProgressMonitor monitor) throws SystemMessageException { return runCommand(initialWorkingDirectory, command, null, environment, monitor); } diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/shells/IShellService.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/shells/IShellService.java index 28bb4a62823..ef93a372220 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/shells/IShellService.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/shells/IShellService.java @@ -13,6 +13,7 @@ * Contributors: * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable and add Javadoc + * Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error ********************************************************************************/ package org.eclipse.rse.services.shells; @@ -20,6 +21,7 @@ package org.eclipse.rse.services.shells; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.rse.services.IService; +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; /** * IShellService is an abstraction for running shells and shell commands. @@ -36,16 +38,19 @@ public interface IShellService extends IService * * This is a convenience method, passing null as encoding * into {@link #launchShell(String, String, String[], IProgressMonitor)}. + * + * @throws SystemMessageException in case an error occurred or the user + * chose to cancel the operation via the progress monitor. */ - public IHostShell launchShell(String initialWorkingDirectory, String[] environment, IProgressMonitor monitor); + public IHostShell launchShell(String initialWorkingDirectory, String[] environment, IProgressMonitor monitor) throws SystemMessageException; /** * Launch a new shell in the specified directory. * - * @param initialWorkingDirectory initial working directory or - * null if not relevant. The remote shell will - * launch in a directory of its own choice in that case - * (typically a user's home directory). + * @param initialWorkingDirectory initial working directory or empty String + * ("") if not relevant. The remote shell will launch in a + * directory of its own choice in that case (typically a user's + * home directory). * @param encoding Stream encoding to use, or null to fall * back to a default encoding. The Shell Service will make * efforts to determine a proper default encoding on the remote @@ -57,11 +62,13 @@ public interface IShellService extends IService * set. * @param monitor Progress Monitor for monitoring and cancellation * @return the shell object. Note that the shell may not actually be usable - * in case an error occurred or the operation was canceled. In this - * case, {@link IHostShell#isActive()} returns false - * on the created Shell object. + * in case the remote side allows opening a channel but immediately + * closes it again. In this case, {@link IHostShell#isActive()} + * returns false on the created Shell object. + * @throws SystemMessageException in case an error occurred or the user + * chose to cancel the operation via the progress monitor. */ - public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, IProgressMonitor monitor); + public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, IProgressMonitor monitor) throws SystemMessageException; /** * @@ -70,8 +77,11 @@ public interface IShellService extends IService * This is a convenience method, passing null as encoding * into * {@link #runCommand(String, String, String, String[], IProgressMonitor)}. + * + * @throws SystemMessageException in case an error occurred or the user + * chose to cancel the operation via the progress monitor. */ - public IHostShell runCommand(String initialWorkingDirectory, String command, String[] environment, IProgressMonitor monitor); + public IHostShell runCommand(String initialWorkingDirectory, String command, String[] environment, IProgressMonitor monitor) throws SystemMessageException; /** * Run a single command in it's own shell. @@ -85,10 +95,10 @@ public interface IShellService extends IService * connection automatically. Clients need to call {@link IHostShell#exit()} * in case the shell remains active after the initial command is completed. * - * @param initialWorkingDirectory initial working directory or - * null if not relevant. The remote shell will - * launch in a directory of its own choice in that case - * (typically a user's home directory). + * @param initialWorkingDirectory initial working directory or empty String + * ("") if not relevant. The remote command will launch in a + * directory of its own choice in that case (typically a user's + * home directory). * @param encoding Stream encoding to use, or null to fall * back to a default encoding. The Shell Service will make * efforts to determine a proper default encoding on the remote @@ -100,23 +110,27 @@ public interface IShellService extends IService * set. * @param monitor Progress Monitor for monitoring and cancellation * @return the shell object for getting output and error streams. Note that - * the shell may not actually be usable in case an error occurred or - * the operation was canceled. In this case, - * {@link IHostShell#isActive()} returns false on the - * created Shell object. + * the shell may not actually be usable in case an error occurred on + * the remote side, such as the command not being executable. In + * this case, {@link IHostShell#isActive()} returns + * false on the created Shell object. + * @throws SystemMessageException in case an error occurred or the user + * chose to cancel the operation via the progress monitor. */ - public IHostShell runCommand(String initialWorkingDirectory, String command, String encoding, String[] environment, IProgressMonitor monitor); + public IHostShell runCommand(String initialWorkingDirectory, String command, String encoding, String[] environment, IProgressMonitor monitor) throws SystemMessageException; /** * Return an array of environment variables that describe the environment on * the remote system. Each String returned is of the format "var=text": * Everything up to the first equals sign is the name of the given * environment variable, everything after the equals sign is its contents. - * + * * @return Array of environment variable Strings of the form "var=text" if - * supported by a shell service implementation. May return - * null in case environment variable retrieval is not + * supported by a shell service implementation. Should return an + * empty array in case environment variable retrieval is not * supported on a particular shell service implementation. + * @throws SystemMessageException in case an error occurred or the user + * chose to cancel the operation via the progress monitor. */ - public String[] getHostEnvironment(); + public String[] getHostEnvironment() throws SystemMessageException; } \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.subsystems.processes.shell.linux/src/org/eclipse/rse/internal/subsystems/processes/shell/linux/LinuxProcessHelper.java b/rse/plugins/org.eclipse.rse.subsystems.processes.shell.linux/src/org/eclipse/rse/internal/subsystems/processes/shell/linux/LinuxProcessHelper.java index 3ab020a0cec..cc9aaa21bd1 100644 --- a/rse/plugins/org.eclipse.rse.subsystems.processes.shell.linux/src/org/eclipse/rse/internal/subsystems/processes/shell/linux/LinuxProcessHelper.java +++ b/rse/plugins/org.eclipse.rse.subsystems.processes.shell.linux/src/org/eclipse/rse/internal/subsystems/processes/shell/linux/LinuxProcessHelper.java @@ -1,20 +1,21 @@ /******************************************************************************** - * Copyright (c) 2005, 2007 IBM Corporation and others. All rights reserved. + * Copyright (c) 2005, 2008 IBM Corporation 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 + * of the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html - * + * * Initial Contributors: * The following IBM employees contributed to the Remote System Explorer - * component that contains this file: David McKnight, Kushal Munir, - * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson, + * component that contains this file: David McKnight, Kushal Munir, + * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson, * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley. - * - * Contributors: + * + * Contributors: * Yu-Fen Kuo (MontaVista) - adapted from RSE UniversalLinuxProcessHandler * Martin Oberhuber (Wind River) - [refactor] "shell" instead of "ssh" everywhere * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * David McKnight (IBM) - [175308] Need to use a job to wait for shell to exit + * Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error *******************************************************************************/ package org.eclipse.rse.internal.subsystems.processes.shell.linux; @@ -34,7 +35,7 @@ import org.eclipse.rse.services.shells.IShellService; /** * Helper class that helps to get state code and user name info most of the code - * + * */ public class LinuxProcessHelper { private HashMap stateMap; @@ -92,11 +93,10 @@ public class LinuxProcessHelper { _uidsByUserName = new HashMap(); IShellService shellService = Activator.getShellService(host); - IHostShell hostShell = shellService.launchShell( - "", null, new NullProgressMonitor()); //$NON-NLS-1$ - hostShell.writeToShell(getUserNameCommand()); Process p = null; try { + IHostShell hostShell = shellService.launchShell("", null, new NullProgressMonitor()); //$NON-NLS-1$ + hostShell.writeToShell(getUserNameCommand()); p = new HostShellProcessAdapter(hostShell); // when p.waitFor() is called here, the hostShell.isActive() always // return true. @@ -131,7 +131,7 @@ public class LinuxProcessHelper { } catch (IOException e) { Activator.log(e); } - + // Wait for remote process to exit. WaiterJob waiter = new WaiterJob(p); waiter.schedule(); diff --git a/rse/plugins/org.eclipse.rse.subsystems.processes.shell.linux/src/org/eclipse/rse/internal/subsystems/processes/shell/linux/LinuxShellProcessService.java b/rse/plugins/org.eclipse.rse.subsystems.processes.shell.linux/src/org/eclipse/rse/internal/subsystems/processes/shell/linux/LinuxShellProcessService.java index 9e9716c180e..34c50d13c2c 100644 --- a/rse/plugins/org.eclipse.rse.subsystems.processes.shell.linux/src/org/eclipse/rse/internal/subsystems/processes/shell/linux/LinuxShellProcessService.java +++ b/rse/plugins/org.eclipse.rse.subsystems.processes.shell.linux/src/org/eclipse/rse/internal/subsystems/processes/shell/linux/LinuxShellProcessService.java @@ -11,6 +11,7 @@ * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * David McKnight (IBM) - [175308] Need to use a job to wait for shell to exit * Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable and add Javadoc + * Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error *******************************************************************************/ package org.eclipse.rse.internal.subsystems.processes.shell.linux; @@ -212,15 +213,14 @@ public class LinuxShellProcessService extends AbstractProcessService { */ protected String[] internalGetSignalTypes() { IShellService shellService = Activator.getShellService(host); - IHostShell hostShell = shellService.launchShell( - "", null, new NullProgressMonitor()); //$NON-NLS-1$ - hostShell.writeToShell(getSignalTypesCommand()); Process p = null; try { + IHostShell hostShell = shellService.launchShell("", null, new NullProgressMonitor()); //$NON-NLS-1$ + hostShell.writeToShell(getSignalTypesCommand()); p = new HostShellProcessAdapter(hostShell); // p.waitFor(); } catch (Exception e) { - e.printStackTrace(); + Activator.log(e); if (p != null) { p.destroy(); } diff --git a/rse/plugins/org.eclipse.rse.subsystems.shells.core/src/org/eclipse/rse/subsystems/shells/core/subsystems/servicesubsystem/ShellServiceSubSystem.java b/rse/plugins/org.eclipse.rse.subsystems.shells.core/src/org/eclipse/rse/subsystems/shells/core/subsystems/servicesubsystem/ShellServiceSubSystem.java index 5a5e485e11e..c740c1411eb 100644 --- a/rse/plugins/org.eclipse.rse.subsystems.shells.core/src/org/eclipse/rse/subsystems/shells/core/subsystems/servicesubsystem/ShellServiceSubSystem.java +++ b/rse/plugins/org.eclipse.rse.subsystems.shells.core/src/org/eclipse/rse/subsystems/shells/core/subsystems/servicesubsystem/ShellServiceSubSystem.java @@ -1,23 +1,24 @@ /******************************************************************************** * Copyright (c) 2006, 2008 IBM Corporation 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 + * of the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html - * + * * Initial Contributors: * The following IBM employees contributed to the Remote System Explorer - * component that contains this file: David McKnight, Kushal Munir, - * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson, + * component that contains this file: David McKnight, Kushal Munir, + * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson, * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley. - * + * * Contributors: - * Martin Oberhuber (Wind River) - [175262] IHost.getSystemType() should return IRSESystemType + * Martin Oberhuber (Wind River) - [175262] IHost.getSystemType() should return IRSESystemType * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API - * Martin Oberhuber (Wind River) - [186640] Add IRSESystemType.testProperty() + * Martin Oberhuber (Wind River) - [186640] Add IRSESystemType.testProperty() * David McKnight (IBM) - [191599] Need to pass in shell encoding * David Dykstal (IBM) - [197036] refactored switch configuration * David Dykstal (IBM) - [217556] remove service subsystem types * David McKnight (IBM) - [220524] internalSwitchServiceSubSystemConfiguration -> internalSwitchSubSystemConfiguration + * Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error ********************************************************************************/ package org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem; @@ -38,8 +39,9 @@ import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCmdSubSystem; import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCommandShell; import org.eclipse.rse.subsystems.shells.core.subsystems.RemoteCmdSubSystem; +import org.eclipse.rse.ui.SystemBasePlugin; -public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements IShellServiceSubSystem +public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements IShellServiceSubSystem { protected String _userHome = null; protected IShellService _hostService; @@ -49,17 +51,17 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I super(host, connectorService); _hostService = hostService; } - + public IShellService getShellService() { return _hostService; } - + public void setShellService(IShellService service) { _hostService = service; } - + protected String getUserHome() { if (_userHome == null) @@ -82,7 +84,7 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I return _userHome; } - + protected Object[] internalRunCommand(String cmd, Object context, IProgressMonitor monitor) throws InvocationTargetException, InterruptedException, SystemMessageException { return internalRunCommand(cmd, context, false, monitor); @@ -107,12 +109,12 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I } - IShellService service = getShellService(); + IShellService service = getShellService(); IHostShell hostShell = service.runCommand(cwd, cmd, getUserAndHostEnvVarsAsStringArray(), monitor); IServiceCommandShell cmdShell = createRemoteCommandShell(this, hostShell); hostShell.addOutputListener(cmdShell); - - + + if (_cmdShells.size() == 0) { // if this is first shell, start listening so that on disconnect, we persist @@ -144,15 +146,15 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I } - IShellService service = getShellService(); + IShellService service = getShellService(); String encoding = getHost().getDefaultEncoding(true); IHostShell hostShell = service.launchShell(cwd, encoding, getUserAndHostEnvVarsAsStringArray(), monitor); IServiceCommandShell cmdShell = createRemoteCommandShell(this, hostShell); if (cmdShell != null) { hostShell.addOutputListener(cmdShell); - - + + if (_cmdShells.size() == 0) { // if this is first shell, start listening so that on disconnect, we persist @@ -164,7 +166,7 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I return cmdShell; } - + protected void internalCancelShell(Object command, IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { @@ -182,20 +184,25 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I IServiceCommandShell cmdWrapper = (IServiceCommandShell)command; cmdWrapper.writeToShell(cmd); cmdWrapper.updateHistory(cmd); - } + } } - + protected IServiceCommandShell createRemoteCommandShell(IRemoteCmdSubSystem cmdSS, IHostShell hostShell) { IShellServiceSubSystemConfiguration config = (IShellServiceSubSystemConfiguration)getParentRemoteCmdSubSystemConfiguration(); return config.createRemoteCommandShell(cmdSS, hostShell); } - + public String[] getHostEnvironment() { - return getShellService().getHostEnvironment(); + try { + return getShellService().getHostEnvironment(); + } catch (SystemMessageException e) { + SystemBasePlugin.logError(e.getSystemMessage().getLevelOneText(), e); + } + return new String[0]; } - + public List getHostEnvironmentVariables() { List l = new ArrayList(); @@ -213,7 +220,7 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I public boolean canSwitchTo(ISubSystemConfiguration configuration) { return configuration instanceof IShellServiceSubSystemConfiguration; } - + /* (non-Javadoc) * @see org.eclipse.rse.core.subsystems.SubSystem#internalServiceSubSystemConfiguration(org.eclipse.rse.core.subsystems.ISubSystemConfiguration) */ @@ -222,7 +229,7 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I IHost host = getHost(); setShellService(configuration.getShellService(host)); } - + /* (non-Javadoc) * @see org.eclipse.rse.core.subsystems.SubSystem#getServiceType() */ @@ -232,7 +239,7 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I } public void initializeSubSystem(IProgressMonitor monitor) - { + { getShellService().initService(monitor); } @@ -241,5 +248,5 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I cancelAllShells(); getShellService().uninitService(monitor); } - -} \ No newline at end of file + +} \ No newline at end of file