mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-21 16:05:25 +02:00
[240523][227569] added new generic terminal shell service, generic terminal subsystem and telnet reference implementation.
This commit is contained in:
parent
24908d60f5
commit
250119f1db
32 changed files with 1671 additions and 126 deletions
|
@ -7,18 +7,19 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Martin Oberhuber (Wind River) - initial API and implementation
|
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||||
* David Dykstal (IBM) - 168977: refactoring IConnectorService and ServerLauncher hierarchies
|
* David Dykstal (IBM) - [168977] refactoring IConnectorService and ServerLauncher hierarchies
|
||||||
* Sheldon D'souza (Celunite) - adapted from SshConnectorService
|
* Sheldon D'souza (Celunite) - adapted from SshConnectorService
|
||||||
* Martin Oberhuber (Wind River) - apply refactorings for StandardConnectorService
|
* Martin Oberhuber (Wind River) - apply refactorings for StandardConnectorService
|
||||||
* Martin Oberhuber (Wind River) - [178606] fix endless loop in readUntil()
|
* Martin Oberhuber (Wind River) - [178606] fix endless loop in readUntil()
|
||||||
* Sheldon D'souza (Celunite) - [186536] login and password should be configurable
|
* Sheldon D'souza (Celunite) - [186536] login and password should be configurable
|
||||||
* Sheldon D'souza (Celunite) - [186570] handle invalid user id and password more gracefully
|
* Sheldon D'souza (Celunite) - [186570] handle invalid user id and password more gracefully
|
||||||
* Martin Oberhuber (Wind River) - [187218] Fix error reporting for connect()
|
* Martin Oberhuber (Wind River) - [187218] Fix error reporting for connect()
|
||||||
* Sheldon D'souza (Celunite) - [187301] support multiple telnet shells
|
* Sheldon D'souza (Celunite) - [187301] support multiple telnet shells
|
||||||
* Sheldon D'souza (Celunite) - [194464] fix create multiple telnet shells quickly
|
* Sheldon D'souza (Celunite) - [194464] fix create multiple telnet shells quickly
|
||||||
* Martin Oberhuber (Wind River) - [186761] make the port setting configurable
|
* Martin Oberhuber (Wind River) - [186761] make the port setting configurable
|
||||||
* David McKnight (IBM) - [216252] [api][nls] Resource Strings specific to subsystems should be moved from rse.ui into files.ui / shells.ui / processes.ui where possible
|
* David McKnight (IBM) - [216252] [api][nls] Resource Strings specific to subsystems should be moved from rse.ui into files.ui / shells.ui / processes.ui where possible
|
||||||
* David McKnight (IBM) - [220547] [api][breaking] SimpleSystemMessage needs to specify a message id and some messages should be shared
|
* David McKnight (IBM) - [220547] [api][breaking] SimpleSystemMessage needs to specify a message id and some messages should be shared
|
||||||
|
* Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.rse.internal.connectorservice.telnet;
|
package org.eclipse.rse.internal.connectorservice.telnet;
|
||||||
|
|
||||||
|
@ -148,8 +149,12 @@ public class TelnetConnectorService extends StandardConnectorService implements
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TelnetClient makeNewTelnetClient( IProgressMonitor monitor ) throws Exception {
|
public TelnetClient makeNewTelnetClient(IProgressMonitor monitor ) throws Exception {
|
||||||
TelnetClient client = new TelnetClient();
|
TelnetClient client = new TelnetClient();
|
||||||
|
return makeNewTelnetClient(client, monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TelnetClient makeNewTelnetClient(TelnetClient client, IProgressMonitor monitor ) throws Exception {
|
||||||
String host = getHostName();
|
String host = getHostName();
|
||||||
String user = getUserId();
|
String user = getUserId();
|
||||||
String password = ""; //$NON-NLS-1$
|
String password = ""; //$NON-NLS-1$
|
||||||
|
|
|
@ -2,14 +2,15 @@ Manifest-Version: 1.0
|
||||||
Bundle-ManifestVersion: 2
|
Bundle-ManifestVersion: 2
|
||||||
Bundle-Name: %pluginName
|
Bundle-Name: %pluginName
|
||||||
Bundle-SymbolicName: org.eclipse.rse.services.telnet
|
Bundle-SymbolicName: org.eclipse.rse.services.telnet
|
||||||
Bundle-Version: 1.1.100.qualifier
|
Bundle-Version: 1.2.0.qualifier
|
||||||
Bundle-Activator: org.eclipse.rse.internal.services.telnet.Activator
|
Bundle-Activator: org.eclipse.rse.internal.services.telnet.Activator
|
||||||
Bundle-Localization: plugin
|
Bundle-Localization: plugin
|
||||||
Require-Bundle: org.eclipse.core.runtime,
|
Require-Bundle: org.eclipse.core.runtime,
|
||||||
org.eclipse.rse.services;bundle-version="[3.0.0,4.0.0)",
|
org.eclipse.rse.services;bundle-version="[3.0.0,4.0.0)",
|
||||||
org.apache.commons.net;bundle-version="[1.4.1,2.0.0)"
|
org.apache.commons.net;bundle-version="[1.4.1,2.0.0)"
|
||||||
Export-Package: org.eclipse.rse.internal.services.telnet;x-friends:="org.eclipse.rse.connectorservice.telnet,org.eclipse.rse.subsystems.files.telnet,org.eclipse.rse.subsystems.shells.telnet",
|
Export-Package: org.eclipse.rse.internal.services.telnet;x-friends:="org.eclipse.rse.connectorservice.telnet,org.eclipse.rse.subsystems.files.telnet,org.eclipse.rse.subsystems.shells.telnet",
|
||||||
org.eclipse.rse.internal.services.telnet.shell;x-friends:="org.eclipse.rse.connectorservice.telnet,org.eclipse.rse.subsystems.shells.telnet"
|
org.eclipse.rse.internal.services.telnet.shell;x-friends:="org.eclipse.rse.connectorservice.telnet,org.eclipse.rse.subsystems.shells.telnet",
|
||||||
|
org.eclipse.rse.internal.services.telnet.terminal;x-friends:="org.eclipse.rse.subsystems.shells.telnet"
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Eclipse-LazyStart: true
|
Eclipse-LazyStart: true
|
||||||
Bundle-Vendor: %providerName
|
Bundle-Vendor: %providerName
|
||||||
|
|
|
@ -12,8 +12,9 @@
|
||||||
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Sheldon D'souza (Celunite) - adapted from ISshSessionProvider
|
* Sheldon D'souza (Celunite) - adapted from ISshSessionProvider
|
||||||
* Sheldon D'souza (Celunite) - [187301] support multiple telnet shells
|
* Sheldon D'souza (Celunite) - [187301] support multiple telnet shells
|
||||||
|
* Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.rse.internal.services.telnet;
|
package org.eclipse.rse.internal.services.telnet;
|
||||||
|
|
||||||
|
@ -30,4 +31,13 @@ public interface ITelnetSessionProvider {
|
||||||
*/
|
*/
|
||||||
public TelnetClient makeNewTelnetClient(IProgressMonitor monitor) throws Exception ;
|
public TelnetClient makeNewTelnetClient(IProgressMonitor monitor) throws Exception ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new Commons.Net TelnetClient with a given ptyType.
|
||||||
|
* @param client telnet client already created
|
||||||
|
* @param monitor progress monitor
|
||||||
|
* @return authenticated client for the given connection
|
||||||
|
* @throws Exception in case of any error
|
||||||
|
*/
|
||||||
|
public TelnetClient makeNewTelnetClient(TelnetClient client, IProgressMonitor monitor) throws Exception ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 MontaVista Software, 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:
|
||||||
|
* Anna Dushistova (MontaVista) - initial API and implementation
|
||||||
|
* Martin Oberhuber (Wind River) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.rse.internal.services.telnet.terminal;
|
||||||
|
|
||||||
|
import java.io.FilterInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 1.2
|
||||||
|
*/
|
||||||
|
public class EOFDetectingInputStreamWrapper extends FilterInputStream {
|
||||||
|
|
||||||
|
private boolean fEOF = false;
|
||||||
|
|
||||||
|
public EOFDetectingInputStreamWrapper(InputStream origStream) {
|
||||||
|
super(origStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean isEOF() {
|
||||||
|
return fEOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setEOF(boolean eof) {
|
||||||
|
fEOF = eof;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() throws IOException {
|
||||||
|
try {
|
||||||
|
int result = in.read();
|
||||||
|
if (result < 0) {
|
||||||
|
setEOF(true);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} catch (IOException e) {
|
||||||
|
setEOF(true);
|
||||||
|
throw (e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see java.io.InputStream#close()
|
||||||
|
*/
|
||||||
|
public void close() throws IOException {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
} finally {
|
||||||
|
setEOF(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see java.io.InputStream#read(byte[], int, int)
|
||||||
|
*/
|
||||||
|
public int read(byte[] b, int off, int len) throws IOException {
|
||||||
|
try {
|
||||||
|
int result = in.read(b, off, len);
|
||||||
|
if (result < 0)
|
||||||
|
setEOF(true);
|
||||||
|
return result;
|
||||||
|
} catch (IOException e) {
|
||||||
|
setEOF(true);
|
||||||
|
throw (e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 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:
|
||||||
|
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||||
|
* Anna Dushistova (MontaVista) - adapted from SshTerminalService
|
||||||
|
* Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.rse.internal.services.telnet.terminal;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IAdaptable;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.PlatformObject;
|
||||||
|
import org.eclipse.rse.internal.services.shells.TerminalShellService;
|
||||||
|
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.internal.services.terminals.AbstractTerminalService;
|
||||||
|
import org.eclipse.rse.internal.services.terminals.ITerminalShell;
|
||||||
|
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||||
|
import org.eclipse.rse.services.shells.IShellService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Terminal Service for telnet.
|
||||||
|
* @since 1.2
|
||||||
|
*/
|
||||||
|
public class TelnetTerminalService extends AbstractTerminalService implements ITelnetService {
|
||||||
|
|
||||||
|
private final ITelnetSessionProvider fSessionProvider;
|
||||||
|
private IShellService fRelatedShellService;
|
||||||
|
|
||||||
|
public TelnetTerminalService(ITelnetSessionProvider sessionProvider) {
|
||||||
|
fSessionProvider = sessionProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITelnetSessionProvider getSessionProvider() {
|
||||||
|
return fSessionProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITerminalShell launchTerminal(String ptyType, String encoding, String[] environment, String initialWorkingDirectory, String commandToRun,
|
||||||
|
IProgressMonitor monitor) throws SystemMessageException {
|
||||||
|
TelnetTerminalShell hostShell = new TelnetTerminalShell(fSessionProvider, ptyType, encoding, environment, initialWorkingDirectory, commandToRun);
|
||||||
|
return hostShell;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an RSE IShellService related to this Terminal Service.
|
||||||
|
*/
|
||||||
|
protected synchronized IShellService getRelatedShellService() {
|
||||||
|
if (fRelatedShellService == null) {
|
||||||
|
fRelatedShellService = new TerminalShellService(this);
|
||||||
|
}
|
||||||
|
return fRelatedShellService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapt this terminal service to different (potentially contributed)
|
||||||
|
* interfaces, in order to provide additional functionality.
|
||||||
|
*
|
||||||
|
* Asks the adapter manager first whether it got any contributed adapter; if
|
||||||
|
* none is found contributed externally, try to adapt to an SshShellService.
|
||||||
|
* That way, clients can easily convert this ITerminalService into an
|
||||||
|
* IShellService:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* IShellService ss = (IShellService) myTerminalService.getAdapter(IShellService.class);
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @see IAdaptable
|
||||||
|
* @see PlatformObject#getAdapter(Class)
|
||||||
|
*/
|
||||||
|
public Object getAdapter(Class adapter) {
|
||||||
|
// TODO I'm not sure if this is the right way doing things. First of
|
||||||
|
// all, we're holding on to the created terminal service forever if
|
||||||
|
// we're asked for it, thus needing extra memory.
|
||||||
|
// Second, by asking the adapter manager first, we might get no chance
|
||||||
|
// returning what we think is right.
|
||||||
|
Object o = super.getAdapter(adapter);
|
||||||
|
if (o==null && adapter.isAssignableFrom(IShellService.class)) {
|
||||||
|
return getRelatedShellService();
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return TelnetServiceResources.TelnetShellService_Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return TelnetServiceResources.TelnetShellService_Description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,274 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 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:
|
||||||
|
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||||
|
* Anna Dushistova (MontaVista) - [170910] Integrate the TM Terminal View with RSE
|
||||||
|
* Martin Oberhuber (Wind River) - [227320] Fix endless loop in TelnetTerminalShell
|
||||||
|
* Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.rse.internal.services.telnet.terminal;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
import org.apache.commons.net.io.ToNetASCIIInputStream;
|
||||||
|
import org.apache.commons.net.telnet.EchoOptionHandler;
|
||||||
|
import org.apache.commons.net.telnet.SuppressGAOptionHandler;
|
||||||
|
import org.apache.commons.net.telnet.TelnetClient;
|
||||||
|
import org.apache.commons.net.telnet.TelnetOption;
|
||||||
|
import org.apache.commons.net.telnet.TerminalTypeOptionHandler;
|
||||||
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
|
import org.eclipse.rse.internal.services.telnet.ITelnetSessionProvider;
|
||||||
|
import org.eclipse.rse.internal.services.terminals.AbstractTerminalShell;
|
||||||
|
import org.eclipse.rse.internal.services.terminals.ITerminalService;
|
||||||
|
import org.eclipse.rse.services.clientserver.PathUtility;
|
||||||
|
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||||
|
import org.eclipse.rse.services.files.RemoteFileException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A remote shell connection supporting Streams for I/O.
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
|
*/
|
||||||
|
public class TelnetTerminalShell extends AbstractTerminalShell {
|
||||||
|
|
||||||
|
private ITelnetSessionProvider fSessionProvider;
|
||||||
|
private TelnetClient fTelnetClient;
|
||||||
|
private String fEncoding;
|
||||||
|
private EOFDetectingInputStreamWrapper fInputStream;
|
||||||
|
private OutputStream fOutputStream;
|
||||||
|
private Writer fOutputStreamWriter;
|
||||||
|
private int fWidth = 0;
|
||||||
|
private int fHeight = 0;
|
||||||
|
private static String defaultEncoding = new java.io.InputStreamReader(
|
||||||
|
new java.io.ByteArrayInputStream(new byte[0])).getEncoding();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new Terminal connection.
|
||||||
|
*
|
||||||
|
* The SSH channel is immediately connected in the Constructor.
|
||||||
|
*
|
||||||
|
* @param sessionProvider
|
||||||
|
* SSH session provider
|
||||||
|
* @param ptyType
|
||||||
|
* Terminal type to set, or <code>null</code> if not relevant
|
||||||
|
* @param encoding
|
||||||
|
* The default encoding to use for initial command.
|
||||||
|
* @param environment
|
||||||
|
* Environment array to set, or <code>null</code> if not
|
||||||
|
* relevant.
|
||||||
|
* @param initialWorkingDirectory
|
||||||
|
* initial directory to open the Terminal in. Use
|
||||||
|
* <code>null</code> or empty String ("") to start in a default
|
||||||
|
* directory. Empty String will typically start in the home
|
||||||
|
* directory.
|
||||||
|
* @param commandToRun
|
||||||
|
* initial command to send.
|
||||||
|
* @throws SystemMessageException
|
||||||
|
* in case anything goes wrong. Channels and Streams are all
|
||||||
|
* cleaned up again in this case.
|
||||||
|
* @see ITerminalService
|
||||||
|
*/
|
||||||
|
public TelnetTerminalShell(ITelnetSessionProvider sessionProvider,
|
||||||
|
String ptyType, String encoding, String[] environment,
|
||||||
|
String initialWorkingDirectory, String commandToRun)
|
||||||
|
throws SystemMessageException {
|
||||||
|
try {
|
||||||
|
fSessionProvider = sessionProvider;
|
||||||
|
boolean onUNIX = System.getProperty("os.name").toLowerCase()//$NON-NLS-1$
|
||||||
|
.startsWith("unix")//$NON-NLS-1$
|
||||||
|
|| System.getProperty("os.name").toLowerCase().startsWith( //$NON-NLS-1$
|
||||||
|
"linux");//$NON-NLS-1$
|
||||||
|
fEncoding = encoding;
|
||||||
|
fTelnetClient = new TelnetClient(ptyType);
|
||||||
|
// request remote echo, but accept local if desired
|
||||||
|
fTelnetClient.addOptionHandler(new EchoOptionHandler(false, true,
|
||||||
|
true, true));
|
||||||
|
fTelnetClient.addOptionHandler(new SuppressGAOptionHandler(true,
|
||||||
|
true, true, true));
|
||||||
|
fTelnetClient.addOptionHandler(new TerminalTypeOptionHandler(
|
||||||
|
ptyType, true, true, true, true));
|
||||||
|
fTelnetClient = fSessionProvider.makeNewTelnetClient(fTelnetClient,
|
||||||
|
new NullProgressMonitor());
|
||||||
|
fOutputStream = fTelnetClient.getOutputStream();
|
||||||
|
if (onUNIX)
|
||||||
|
fInputStream = new EOFDetectingInputStreamWrapper(
|
||||||
|
new ToNetASCIIInputStream(fTelnetClient
|
||||||
|
.getInputStream()));
|
||||||
|
else
|
||||||
|
fInputStream = new EOFDetectingInputStreamWrapper(fTelnetClient
|
||||||
|
.getInputStream());
|
||||||
|
if (fEncoding != null) {
|
||||||
|
fOutputStreamWriter = new BufferedWriter(
|
||||||
|
new OutputStreamWriter(fOutputStream, encoding));
|
||||||
|
} else {
|
||||||
|
// default encoding == System.getProperty("file.encoding")
|
||||||
|
// TODO should try to determine remote encoding if possible
|
||||||
|
fOutputStreamWriter = new BufferedWriter(
|
||||||
|
new OutputStreamWriter(fOutputStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initialWorkingDirectory != null
|
||||||
|
&& initialWorkingDirectory.length() > 0
|
||||||
|
&& !initialWorkingDirectory.equals(".") //$NON-NLS-1$
|
||||||
|
&& !initialWorkingDirectory.equals("Command Shell") //$NON-NLS-1$ //FIXME workaround for bug 153047
|
||||||
|
) {
|
||||||
|
writeToShell("cd " + PathUtility.enQuoteUnix(initialWorkingDirectory)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (commandToRun != null && commandToRun.length() > 0) {
|
||||||
|
writeToShell(commandToRun);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RemoteFileException("Error creating Terminal", e); //$NON-NLS-1$
|
||||||
|
} finally {
|
||||||
|
isActive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefaultEncoding() {
|
||||||
|
return fEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode String with requested user encoding, in case it differs from
|
||||||
|
* Platform default encoding.
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
* String to encode
|
||||||
|
* @param encoding
|
||||||
|
* Encoding to use
|
||||||
|
* @return encoded String
|
||||||
|
* @throws UnsupportedEncodingException
|
||||||
|
* in case the requested encoding is not supported
|
||||||
|
*/
|
||||||
|
protected String recode(String s, String encoding)
|
||||||
|
throws UnsupportedEncodingException {
|
||||||
|
if (encoding == null) {
|
||||||
|
return s;
|
||||||
|
} else if (encoding.equals(defaultEncoding)) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
// what we want on the wire:
|
||||||
|
byte[] bytes = s.getBytes(encoding);
|
||||||
|
// what we need to tell Jsch to get this on the wire:
|
||||||
|
return new String(bytes, defaultEncoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see ITerminalHostShell#getInputStream(Object)
|
||||||
|
*/
|
||||||
|
public InputStream getInputStream() {
|
||||||
|
return fInputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see ITerminalHostShell#getOutputStream(Object)
|
||||||
|
*/
|
||||||
|
public OutputStream getOutputStream() {
|
||||||
|
return fOutputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a command to the shell, honoring specified Encoding. Can only be
|
||||||
|
* done before an outputStream is obtained, since these commands would
|
||||||
|
* interfere with the outputStream.
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* Command String to send, or "#break" to send a Ctrl+C command.
|
||||||
|
*/
|
||||||
|
public void writeToShell(String command) throws IOException {
|
||||||
|
if (isActive()) {
|
||||||
|
if ("#break".equals(command)) { //$NON-NLS-1$
|
||||||
|
command = "\u0003"; // Unicode 3 == Ctrl+C //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
command += "\r\n"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
fOutputStreamWriter.write(command);
|
||||||
|
fOutputStreamWriter.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void exit() {
|
||||||
|
if (fTelnetClient != null) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
getInputStream().close();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
getOutputStream().close();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
/* ignore */
|
||||||
|
ioe.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// TODO disconnect should better be done via the
|
||||||
|
// ConnectorService!!
|
||||||
|
// Because like we do it here, the connector service is not
|
||||||
|
// notified!
|
||||||
|
synchronized (fTelnetClient) {
|
||||||
|
if (fTelnetClient.isConnected())
|
||||||
|
fTelnetClient.disconnect();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
fTelnetClient = null;
|
||||||
|
isActive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
if (fTelnetClient != null && fTelnetClient.isConnected()
|
||||||
|
&& !isDisconnected()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// shell is not active: check for session lost
|
||||||
|
exit();
|
||||||
|
|
||||||
|
// //MOB: Telnet sessions are really independent of each other.
|
||||||
|
// //So if one telnet session disconnects, it must not disconnect
|
||||||
|
// //the other sessions.
|
||||||
|
// if (fTelnetClient!=null && !fTelnetClient.isConnected()) {
|
||||||
|
// fSessionProvider.handleSessionLost();
|
||||||
|
// }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isDisconnected() {
|
||||||
|
return fInputStream.isEOF();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLocalEcho() {
|
||||||
|
return fTelnetClient.getLocalOptionState(TelnetOption.ECHO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTerminalSize(int newWidth, int newHeight) {
|
||||||
|
if (fTelnetClient != null
|
||||||
|
&& (newWidth != fWidth || newHeight != fHeight)) {
|
||||||
|
// avoid excessive communications due to change size requests by
|
||||||
|
// caching previous size
|
||||||
|
fWidth = newWidth;
|
||||||
|
fHeight = newHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,27 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (c) 2007,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 available at
|
||||||
|
http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Anna Dushistova (MontaVista)- initial API and implementation
|
||||||
|
-->
|
||||||
<?eclipse version="3.2"?>
|
<?eclipse version="3.2"?>
|
||||||
<plugin>
|
<plugin>
|
||||||
<extension-point id="archivehandlers" name="%extPoint.archivehandlers" schema="schema/archivehandlers.exsd"/>
|
<extension-point id="archivehandlers" name="%extPoint.archivehandlers" schema="schema/archivehandlers.exsd"/>
|
||||||
<extension-point id="codePageConverters" name="%extPoint.codePageConverters" schema="schema/codePageConverters.exsd"/>
|
<extension-point id="codePageConverters" name="%extPoint.codePageConverters" schema="schema/codePageConverters.exsd"/>
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.core.runtime.adapters">
|
||||||
|
<factory
|
||||||
|
adaptableType="org.eclipse.rse.internal.services.terminals.ITerminalService"
|
||||||
|
class="org.eclipse.rse.internal.services.shells.TerminalShellAdapterFactory">
|
||||||
|
<adapter
|
||||||
|
type="org.eclipse.rse.services.shells.IShellService">
|
||||||
|
</adapter>
|
||||||
|
</factory>
|
||||||
|
</extension>
|
||||||
|
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 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,
|
||||||
|
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Martin Oberhuber (Wind River) - Adapted from LocalHostShell.
|
||||||
|
* David McKnight (IBM) - [191599] Use the remote encoding specified in the host property page
|
||||||
|
* David McKnight (IBM) - [196301] Check that the remote encoding isn't null before using it
|
||||||
|
* Martin Oberhuber (Wind River) - [204744] Honor encoding in SSH command input field
|
||||||
|
* Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable
|
||||||
|
* Anna Dushistova (MontaVista) - adapted from SshHostShell
|
||||||
|
* Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.rse.internal.services.shells;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.eclipse.rse.internal.services.terminals.ITerminalShell;
|
||||||
|
import org.eclipse.rse.services.clientserver.PathUtility;
|
||||||
|
import org.eclipse.rse.services.shells.AbstractHostShell;
|
||||||
|
import org.eclipse.rse.services.shells.IHostShellOutputReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class TerminalServiceHostShell extends AbstractHostShell {
|
||||||
|
|
||||||
|
public static final String SHELL_INVOCATION = ">"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
ITerminalShell fTerminalShell;
|
||||||
|
|
||||||
|
private TerminalServiceShellOutputReader fStdoutHandler;
|
||||||
|
|
||||||
|
private TerminalServiceShellOutputReader fStderrHandler;
|
||||||
|
|
||||||
|
private TerminalServiceShellWriterThread fShellWriter;
|
||||||
|
|
||||||
|
public TerminalServiceHostShell(ITerminalShell terminalShell,
|
||||||
|
String initialWorkingDirectory, String commandToRun,
|
||||||
|
String[] environment) {
|
||||||
|
try {
|
||||||
|
fTerminalShell = terminalShell;
|
||||||
|
String encoding = fTerminalShell.getDefaultEncoding();
|
||||||
|
if (encoding != null) {
|
||||||
|
fStdoutHandler = new TerminalServiceShellOutputReader(this,
|
||||||
|
new BufferedReader(new InputStreamReader(fTerminalShell
|
||||||
|
.getInputStream(), encoding)), false);
|
||||||
|
} else {
|
||||||
|
fStdoutHandler = new TerminalServiceShellOutputReader(this,
|
||||||
|
new BufferedReader(new InputStreamReader(fTerminalShell
|
||||||
|
.getInputStream())), false);
|
||||||
|
}
|
||||||
|
fStderrHandler = new TerminalServiceShellOutputReader(this, null,
|
||||||
|
true);
|
||||||
|
OutputStream outputStream = fTerminalShell.getOutputStream();
|
||||||
|
if (encoding != null) {
|
||||||
|
// use specified encoding
|
||||||
|
Charset cs = Charset.forName(encoding);
|
||||||
|
PrintWriter outputWriter = new PrintWriter(
|
||||||
|
new OutputStreamWriter(outputStream, cs));
|
||||||
|
fShellWriter = new TerminalServiceShellWriterThread(
|
||||||
|
outputWriter);
|
||||||
|
} else {
|
||||||
|
PrintWriter outputWriter = new PrintWriter(outputStream);
|
||||||
|
fShellWriter = new TerminalServiceShellWriterThread(
|
||||||
|
outputWriter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initialWorkingDirectory != null
|
||||||
|
&& initialWorkingDirectory.length() > 0
|
||||||
|
&& !initialWorkingDirectory.equals(".") //$NON-NLS-1$
|
||||||
|
&& !initialWorkingDirectory.equals("Command Shell") //$NON-NLS-1$ //FIXME workaround for bug 153047
|
||||||
|
) {
|
||||||
|
writeToShell("cd " + PathUtility.enQuoteUnix(initialWorkingDirectory)); //$NON-NLS-1$
|
||||||
|
} else if (SHELL_INVOCATION.equals(commandToRun)) {
|
||||||
|
writeToShell(getPromptCommand());
|
||||||
|
} else if (commandToRun != null && commandToRun.length() > 0) {
|
||||||
|
writeToShell(commandToRun);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO [209043] Forward exception to RSE properly
|
||||||
|
e.printStackTrace();
|
||||||
|
if (fShellWriter != null) {
|
||||||
|
fShellWriter.stopThread();
|
||||||
|
fShellWriter = null;
|
||||||
|
}
|
||||||
|
if (fStderrHandler != null) {
|
||||||
|
fStderrHandler.interrupt();
|
||||||
|
fStderrHandler = null;
|
||||||
|
}
|
||||||
|
if (fStdoutHandler != null) {
|
||||||
|
fStdoutHandler.interrupt();
|
||||||
|
fStdoutHandler = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void exit() {
|
||||||
|
if (fShellWriter != null) {
|
||||||
|
fShellWriter.stopThread();
|
||||||
|
}
|
||||||
|
fTerminalShell.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IHostShellOutputReader getStandardErrorReader() {
|
||||||
|
return fStderrHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IHostShellOutputReader getStandardOutputReader() {
|
||||||
|
return fStdoutHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return fTerminalShell.isActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Pattern cdCommands = Pattern
|
||||||
|
.compile("\\A\\s*(cd|chdir|ls)\\b"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
public void writeToShell(String command) {
|
||||||
|
if (isActive()) {
|
||||||
|
if ("#break".equals(command)) { //$NON-NLS-1$
|
||||||
|
command = "\u0003"; //Unicode 3 == Ctrl+C //$NON-NLS-1$
|
||||||
|
} else if (cdCommands.matcher(command).find()) {
|
||||||
|
command += "\r\n" + getPromptCommand(); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (!fShellWriter.sendCommand(command)) {
|
||||||
|
// exception occurred: terminate writer thread, cancel
|
||||||
|
// connection
|
||||||
|
exit();
|
||||||
|
isActive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPromptCommand() {
|
||||||
|
return "echo $PWD'>'"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 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,
|
||||||
|
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Martin Oberhuber (Wind River) - Adapted from LocalShellOutputReader.
|
||||||
|
* Martin Oberhuber (Wind River) - Added vt100 escape sequence ignoring.
|
||||||
|
* Anna Dushistova (MontaVista) - adapted from SshShellOutputReader
|
||||||
|
* Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.rse.internal.services.shells;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.rse.internal.services.Activator;
|
||||||
|
import org.eclipse.rse.services.shells.AbstractHostShellOutputReader;
|
||||||
|
import org.eclipse.rse.services.shells.IHostOutput;
|
||||||
|
import org.eclipse.rse.services.shells.IHostShell;
|
||||||
|
import org.eclipse.rse.services.shells.SimpleHostOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class TerminalServiceShellOutputReader extends
|
||||||
|
AbstractHostShellOutputReader {
|
||||||
|
protected BufferedReader fReader;
|
||||||
|
private String fPromptChars = ">$%#]"; //Characters we accept as the end of a prompt //$NON-NLS-1$;
|
||||||
|
|
||||||
|
public TerminalServiceShellOutputReader(IHostShell hostShell,
|
||||||
|
BufferedReader reader, boolean isErrorReader) {
|
||||||
|
super(hostShell, isErrorReader);
|
||||||
|
setName("Terminal Service ShellOutputReader" + getName()); //$NON-NLS-1$
|
||||||
|
fReader = reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IHostOutput internalReadLine() {
|
||||||
|
if (fReader == null) {
|
||||||
|
//Our workaround sets the stderr reader to null, so we never give any stderr output.
|
||||||
|
//TODO Check if ssh supports some method of having separate stdout and stderr streams
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
StringBuffer theLine = new StringBuffer();
|
||||||
|
StringBuffer theDebugLine = null;
|
||||||
|
theDebugLine = new StringBuffer();
|
||||||
|
int ch;
|
||||||
|
boolean done = false;
|
||||||
|
while (!done && !isFinished()) {
|
||||||
|
try {
|
||||||
|
ch = fReader.read();
|
||||||
|
switch (ch) {
|
||||||
|
case -1:
|
||||||
|
case 65535:
|
||||||
|
if (theLine.length() == 0) // End of Reader
|
||||||
|
return null;
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
case '\b': //backspace
|
||||||
|
if(theDebugLine!=null) theDebugLine.append((char)ch);
|
||||||
|
int len = theLine.length()-1;
|
||||||
|
if (len>=0) theLine.deleteCharAt(len);
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
if(theDebugLine!=null) theDebugLine.append((char)ch);
|
||||||
|
break; // Carriage Return: dont append to the buffer
|
||||||
|
case 10:
|
||||||
|
if(theDebugLine!=null) theDebugLine.append((char)ch);
|
||||||
|
done = true; // Newline
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
//Tab: we count tabs at column 8
|
||||||
|
//TODO Check: SystemViewRemoteOutputAdapter.translateTabs() also translates
|
||||||
|
//Therefore this special handling here might be unnecessary
|
||||||
|
if(theDebugLine!=null) theDebugLine.append((char)ch);
|
||||||
|
int tabIndex = theLine.length() % 8;
|
||||||
|
while (tabIndex < 8) {
|
||||||
|
theLine.append(' ');
|
||||||
|
tabIndex++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
char tch = (char) ch;
|
||||||
|
if(theDebugLine!=null) theDebugLine.append(tch);
|
||||||
|
if (!Character.isISOControl(tch)) {
|
||||||
|
theLine.append(tch); // Any other character
|
||||||
|
} else if (ch == 27) {
|
||||||
|
// Escape: ignore next char too
|
||||||
|
int nch = fReader.read();
|
||||||
|
if (theDebugLine!=null) theDebugLine.append((char)nch);
|
||||||
|
if (nch == 91) {
|
||||||
|
//vt100 escape sequence: read until end-of-command (skip digits and semicolon)
|
||||||
|
//e.g. \x1b;13;m --> ignore the entire command, including the trailing m
|
||||||
|
do {
|
||||||
|
nch = fReader.read();
|
||||||
|
if (theDebugLine!=null) theDebugLine.append((char)nch);
|
||||||
|
} while (Character.isDigit((char)nch) || nch == ';');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if the BufferedReader is still ready which means
|
||||||
|
// there are more characters
|
||||||
|
// in the Buffer...If not, then we assume it is waiting for
|
||||||
|
// input.
|
||||||
|
if (!done && !fReader.ready()) {
|
||||||
|
// wait to make sure -- max. 500 msec to wait for new chars
|
||||||
|
// if we are not at a CRLF seems to be appropriate for the
|
||||||
|
// Pipes and Threads in ssh.
|
||||||
|
long waitIncrement = 500;
|
||||||
|
// Check if we think we are at a prompt
|
||||||
|
int len = theLine.length()-1;
|
||||||
|
while (len>0 && Character.isSpaceChar(theLine.charAt(len))) {
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
if (len>=0 && fPromptChars.indexOf(theLine.charAt(len))>=0) {
|
||||||
|
waitIncrement = 5; //wait only 5 msec if we think it's a prompt
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(waitIncrement);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
if (!fReader.ready()) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
//FIXME it's dangerous to return null here since this will end
|
||||||
|
//our reader thread completely... the exception could just be
|
||||||
|
//temporary, and we should keep running!
|
||||||
|
Activator.getDefault().logException(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (theDebugLine!=null) {
|
||||||
|
String debugLine = theDebugLine.toString();
|
||||||
|
debugLine.compareTo(""); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
return new SimpleHostOutput(theLine.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2006, 2008 Wind River Systems, 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:
|
||||||
|
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||||
|
* Anna Dushistova (MontaVista) - adapted from SshShellWriterThread
|
||||||
|
* Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.rse.internal.services.shells;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class TerminalServiceShellWriterThread extends Thread {
|
||||||
|
private PrintWriter fOutputWriter;
|
||||||
|
private String fNextCommand;
|
||||||
|
private boolean fIsCancelled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor for terminal service shell writer thread
|
||||||
|
*
|
||||||
|
* @param outputWriter
|
||||||
|
* PrintWriter to write to in separate Thread
|
||||||
|
*/
|
||||||
|
public TerminalServiceShellWriterThread(PrintWriter outputWriter) {
|
||||||
|
super();
|
||||||
|
fOutputWriter = outputWriter;
|
||||||
|
setName("Terminal Service ShellWriter" + getName()); //$NON-NLS-1$
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean isDone() {
|
||||||
|
return fIsCancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void stopThread() {
|
||||||
|
fIsCancelled = true;
|
||||||
|
notifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write command to remote side. Wait until the thread takes the command (no
|
||||||
|
* queuing).
|
||||||
|
*
|
||||||
|
* @param command
|
||||||
|
* to send
|
||||||
|
* @return boolean true if command was sent ok
|
||||||
|
*/
|
||||||
|
public synchronized boolean sendCommand(String command) {
|
||||||
|
try {
|
||||||
|
// In case multiple commands try to send:
|
||||||
|
// wait until it's our turn
|
||||||
|
while (!fIsCancelled && fNextCommand != null) {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
if (!fIsCancelled) {
|
||||||
|
// Now it's our turn
|
||||||
|
fNextCommand = command;
|
||||||
|
notifyAll();
|
||||||
|
// Wait until our command is processed
|
||||||
|
while (!fIsCancelled && fNextCommand != null) {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
stopThread();
|
||||||
|
}
|
||||||
|
return !fIsCancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void run() {
|
||||||
|
try {
|
||||||
|
while (!fIsCancelled) {
|
||||||
|
while (fNextCommand == null && !fIsCancelled) {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
if (!fIsCancelled) {
|
||||||
|
fOutputWriter.println(fNextCommand);
|
||||||
|
fNextCommand = null;
|
||||||
|
notifyAll();
|
||||||
|
if (fOutputWriter.checkError()) { // flush AND get error
|
||||||
|
stopThread();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
/* no special handling -> close stream */
|
||||||
|
} finally {
|
||||||
|
stopThread();
|
||||||
|
fOutputWriter.close();
|
||||||
|
fOutputWriter = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 MontaVista Software, 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:
|
||||||
|
* Anna Dushistova (MontaVista)- initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.rse.internal.services.shells;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IAdapterFactory;
|
||||||
|
|
||||||
|
import org.eclipse.rse.internal.services.terminals.ITerminalService;
|
||||||
|
import org.eclipse.rse.services.shells.IShellService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class TerminalShellAdapterFactory implements IAdapterFactory {
|
||||||
|
|
||||||
|
public Object getAdapter(Object adaptableObject, Class adapterType) {
|
||||||
|
Object result = null;
|
||||||
|
if (adaptableObject instanceof ITerminalService) {
|
||||||
|
if (adapterType == IShellService.class) {
|
||||||
|
result = new TerminalShellService(
|
||||||
|
(ITerminalService) adaptableObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class[] getAdapterList() {
|
||||||
|
return new Class[] { IShellService.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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 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,
|
||||||
|
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* 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
|
||||||
|
* Martin Oberhuber (Wind River) - [170910] Adopt RSE ITerminalService API for SSH
|
||||||
|
* Anna Dushistova (MontaVista) - adapted from SshShellService
|
||||||
|
* Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.rse.internal.services.shells;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IAdaptable;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.PlatformObject;
|
||||||
|
|
||||||
|
import org.eclipse.rse.internal.services.terminals.ITerminalService;
|
||||||
|
import org.eclipse.rse.internal.services.terminals.ITerminalShell;
|
||||||
|
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||||
|
import org.eclipse.rse.services.shells.AbstractShellService;
|
||||||
|
import org.eclipse.rse.services.shells.IHostShell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class TerminalShellService extends AbstractShellService {
|
||||||
|
|
||||||
|
ITerminalService fTerminalService;
|
||||||
|
|
||||||
|
public TerminalShellService(ITerminalService terminalService) {
|
||||||
|
super();
|
||||||
|
fTerminalService = terminalService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IHostShell launchShell(String initialWorkingDirectory,
|
||||||
|
String encoding, String[] environment, IProgressMonitor monitor)
|
||||||
|
throws SystemMessageException {
|
||||||
|
ITerminalShell terminalShell = fTerminalService.launchTerminal(null,
|
||||||
|
encoding, environment, initialWorkingDirectory, null, monitor);
|
||||||
|
TerminalServiceHostShell hostShell = new TerminalServiceHostShell(
|
||||||
|
terminalShell, initialWorkingDirectory,
|
||||||
|
TerminalServiceHostShell.SHELL_INVOCATION, environment);
|
||||||
|
return hostShell;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IHostShell runCommand(String initialWorkingDirectory,
|
||||||
|
String command, String encoding, String[] environment,
|
||||||
|
IProgressMonitor monitor) throws SystemMessageException {
|
||||||
|
ITerminalShell terminalShell = fTerminalService.launchTerminal(null,
|
||||||
|
encoding, environment, initialWorkingDirectory, null, monitor);
|
||||||
|
TerminalServiceHostShell hostShell = new TerminalServiceHostShell(
|
||||||
|
terminalShell, initialWorkingDirectory, command, environment);
|
||||||
|
return hostShell;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapt this shell service to different (potentially contributed)
|
||||||
|
* interfaces.
|
||||||
|
*
|
||||||
|
* Asks the adapter manager first whether it got any contributed adapter; if
|
||||||
|
* none is found contributed externally, try to adapt to an
|
||||||
|
* SshTerminalService. That way, clients can easily convert this
|
||||||
|
* IShellService into an ITerminalService:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* ITerminalService ts = (ITerminalService) myShellService.getAdapter(ITerminalService.class);
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @see IAdaptable
|
||||||
|
* @see PlatformObject#getAdapter(Class)
|
||||||
|
*/
|
||||||
|
public Object getAdapter(Class adapter) {
|
||||||
|
// TODO I'm not sure if this is the right way doing things. First of
|
||||||
|
// all, we're holding on to the created terminal service forever if
|
||||||
|
// we're asked for it, thus needing extra memory.
|
||||||
|
// Second, by asking the adapter manager first, we might get no chance
|
||||||
|
// returning what we think is right.
|
||||||
|
Object o = super.getAdapter(adapter);
|
||||||
|
if (o == null && adapter.isAssignableFrom(ITerminalService.class)) {
|
||||||
|
return fTerminalService;
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,8 +13,9 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Martin Oberhuber (Wind River) - Adapted from LocalServiceCommandShell
|
* Martin Oberhuber (Wind River) - Adapted from LocalServiceCommandShell
|
||||||
* Sheldon D'souza (Celunite) - Adapted from SshServiceCommandShell
|
* Sheldon D'souza (Celunite) - Adapted from SshServiceCommandShell
|
||||||
* Martin Oberhuber (Wind River) - [225510][api] Fix OutputRefreshJob API leakage
|
* Martin Oberhuber (Wind River) - [225510][api] Fix OutputRefreshJob API leakage
|
||||||
|
* Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.rse.internal.subsystems.shells.telnet;
|
package org.eclipse.rse.internal.subsystems.shells.telnet;
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
import org.eclipse.core.runtime.Path;
|
import org.eclipse.core.runtime.Path;
|
||||||
import org.eclipse.rse.core.subsystems.ISubSystem;
|
import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||||
|
import org.eclipse.rse.internal.services.shells.TerminalServiceHostShell;
|
||||||
import org.eclipse.rse.internal.services.telnet.shell.TelnetHostShell;
|
import org.eclipse.rse.internal.services.telnet.shell.TelnetHostShell;
|
||||||
import org.eclipse.rse.services.shells.IHostOutput;
|
import org.eclipse.rse.services.shells.IHostOutput;
|
||||||
import org.eclipse.rse.services.shells.IHostShell;
|
import org.eclipse.rse.services.shells.IHostShell;
|
||||||
|
@ -175,6 +177,9 @@ public class TelnetServiceCommandShell extends ServiceCommandShell {
|
||||||
protected String getPromptCommand() {
|
protected String getPromptCommand() {
|
||||||
IHostShell shell = getHostShell();
|
IHostShell shell = getHostShell();
|
||||||
//assert shell instanceof TelnetHostShell;
|
//assert shell instanceof TelnetHostShell;
|
||||||
|
if (shell instanceof TerminalServiceHostShell) {
|
||||||
|
return ((TerminalServiceHostShell)shell).getPromptCommand();
|
||||||
|
}
|
||||||
if (shell instanceof TelnetHostShell) {
|
if (shell instanceof TelnetHostShell) {
|
||||||
return ((TelnetHostShell)shell).getPromptCommand();
|
return ((TelnetHostShell)shell).getPromptCommand();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Martin Oberhuber (Wind River) - Adapted template for ssh service.
|
* Martin Oberhuber (Wind River) - Adapted template for ssh service.
|
||||||
* Sheldon D'souza (Celunite) - Adapted template for telnet service
|
* Sheldon D'souza (Celunite) - Adapted template for telnet service
|
||||||
|
* Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.rse.subsystems.shells.telnet;
|
package org.eclipse.rse.subsystems.shells.telnet;
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||||
import org.eclipse.rse.internal.connectorservice.telnet.TelnetConnectorService;
|
import org.eclipse.rse.internal.connectorservice.telnet.TelnetConnectorService;
|
||||||
import org.eclipse.rse.internal.connectorservice.telnet.TelnetConnectorServiceManager;
|
import org.eclipse.rse.internal.connectorservice.telnet.TelnetConnectorServiceManager;
|
||||||
import org.eclipse.rse.internal.services.telnet.ITelnetService;
|
import org.eclipse.rse.internal.services.telnet.ITelnetService;
|
||||||
import org.eclipse.rse.internal.services.telnet.shell.TelnetShellService;
|
import org.eclipse.rse.internal.services.telnet.terminal.TelnetTerminalService;
|
||||||
import org.eclipse.rse.internal.subsystems.shells.telnet.TelnetServiceCommandShell;
|
import org.eclipse.rse.internal.subsystems.shells.telnet.TelnetServiceCommandShell;
|
||||||
import org.eclipse.rse.services.shells.IHostShell;
|
import org.eclipse.rse.services.shells.IHostShell;
|
||||||
import org.eclipse.rse.services.shells.IShellService;
|
import org.eclipse.rse.services.shells.IShellService;
|
||||||
|
@ -61,7 +62,7 @@ public class TelnetShellSubSystemConfiguration extends
|
||||||
|
|
||||||
public IShellService createShellService(IHost host) {
|
public IShellService createShellService(IHost host) {
|
||||||
TelnetConnectorService cserv = (TelnetConnectorService)getConnectorService(host);
|
TelnetConnectorService cserv = (TelnetConnectorService)getConnectorService(host);
|
||||||
return new TelnetShellService(cserv);
|
return (IShellService) (new TelnetTerminalService(cserv)).getAdapter(IShellService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IConnectorService getConnectorService(IHost host) {
|
public IConnectorService getConnectorService(IHost host) {
|
||||||
|
|
|
@ -13,5 +13,6 @@ output.. = bin/
|
||||||
bin.includes = META-INF/,\
|
bin.includes = META-INF/,\
|
||||||
.,\
|
.,\
|
||||||
plugin.properties,\
|
plugin.properties,\
|
||||||
about.html
|
about.html,\
|
||||||
|
plugin.xml
|
||||||
src.includes = about.html
|
src.includes = about.html
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 938 B |
Binary file not shown.
After Width: | Height: | Size: 938 B |
|
@ -14,3 +14,6 @@
|
||||||
|
|
||||||
pluginName = RSE Terminals Core (Incubation)
|
pluginName = RSE Terminals Core (Incubation)
|
||||||
providerName = Eclipse.org
|
providerName = Eclipse.org
|
||||||
|
|
||||||
|
TerminalSubsystemName = Terminals
|
||||||
|
TerminalSubsystemDescription = Work with terminals and commands on remote systems.
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (c) 2008 MontaVista Software, 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:
|
||||||
|
Yu-Fen Kuo (MontaVista)- initial API and implementation
|
||||||
|
-->
|
||||||
|
<?eclipse version="3.1"?>
|
||||||
|
<plugin>
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.rse.core.subsystemConfigurations">
|
||||||
|
<configuration
|
||||||
|
category="terminals"
|
||||||
|
class="org.eclipse.rse.internal.subsystems.terminals.core.TerminalSubSystemConfigurationImpl"
|
||||||
|
description="%TerminalSubsystemDescription"
|
||||||
|
icon="icons/full/obj16/terminalcommands_obj.gif"
|
||||||
|
iconlive="icons/full/obj16/terminalcommandslive_obj.gif"
|
||||||
|
id="terminals"
|
||||||
|
name="%TerminalSubsystemName"
|
||||||
|
priority="300"
|
||||||
|
systemTypeIds="org.eclipse.rse.systemtype.telnet"
|
||||||
|
vendor="%providerName">
|
||||||
|
</configuration>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
</plugin>
|
|
@ -0,0 +1,66 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2007, 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
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Anna Dushistova (MontaVista) - [239159] The shell process subsystem not working without the shells subsystem present for the systemType
|
||||||
|
* David McKnight (IBM) - adapted from DelegatingShellProcessConnectorService
|
||||||
|
********************************************************************************/
|
||||||
|
package org.eclipse.rse.internal.subsystems.terminals.core;
|
||||||
|
|
||||||
|
import org.eclipse.rse.core.model.IHost;
|
||||||
|
import org.eclipse.rse.core.subsystems.AbstractDelegatingConnectorService;
|
||||||
|
import org.eclipse.rse.core.subsystems.IConnectorService;
|
||||||
|
import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||||
|
import org.eclipse.rse.subsystems.terminals.core.ITerminalServiceSubSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class delegates the connector service requests for the terminal
|
||||||
|
* subsystem to the connector service of any subsystem that has service which
|
||||||
|
* can be adopted to ITerminalService.
|
||||||
|
*/
|
||||||
|
public class DelegatingTerminalConnectorService extends
|
||||||
|
AbstractDelegatingConnectorService {
|
||||||
|
private IConnectorService _realService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param host
|
||||||
|
* the linux host that is the target for this connector service.
|
||||||
|
*/
|
||||||
|
public DelegatingTerminalConnectorService(IHost host) {
|
||||||
|
super(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @seeorg.eclipse.rse.core.subsystems.AbstractDelegatingConnectorService#
|
||||||
|
* getRealConnectorService()
|
||||||
|
*/
|
||||||
|
public IConnectorService getRealConnectorService() {
|
||||||
|
if (_realService != null) {
|
||||||
|
return _realService;
|
||||||
|
} else {
|
||||||
|
ISubSystem ss = TerminalSubSystemHelper
|
||||||
|
.getSuitableSubSystem(getHost());
|
||||||
|
if (ss != null) {
|
||||||
|
_realService = ss.getConnectorService();
|
||||||
|
|
||||||
|
// register the process subsystem
|
||||||
|
ITerminalServiceSubSystem ts = TerminalSubSystemHelper
|
||||||
|
.getTerminalServiceSubSystem(getHost());
|
||||||
|
_realService.registerSubSystem(ts);
|
||||||
|
return _realService;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2008 IBM Corporation. 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
|
||||||
|
*
|
||||||
|
* Initial Contributors:
|
||||||
|
* The following IBM employees contributed to the Remote System Explorer
|
||||||
|
* component that contains this file: David McKnight.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* {Name} (company) - description of contribution.
|
||||||
|
********************************************************************************/
|
||||||
|
package org.eclipse.rse.internal.subsystems.terminals.core;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.rse.core.model.IHost;
|
||||||
|
import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||||
|
import org.eclipse.rse.internal.services.terminals.ITerminalService;
|
||||||
|
import org.eclipse.rse.internal.services.terminals.ITerminalShell;
|
||||||
|
import org.eclipse.rse.services.IService;
|
||||||
|
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||||
|
|
||||||
|
public class DelegatingTerminalService implements ITerminalService {
|
||||||
|
|
||||||
|
private IHost _host;
|
||||||
|
private ITerminalService _realService;
|
||||||
|
|
||||||
|
public DelegatingTerminalService(IHost host) {
|
||||||
|
_host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ITerminalService getRealService() {
|
||||||
|
if (_host != null && _realService == null) {
|
||||||
|
ISubSystem[] subSystems = _host.getSubSystems();
|
||||||
|
if (subSystems != null) {
|
||||||
|
for (int i = 0; i < subSystems.length && _realService == null; i++) {
|
||||||
|
ISubSystem subsys = subSystems[i];
|
||||||
|
|
||||||
|
IService svc = subsys.getSubSystemConfiguration()
|
||||||
|
.getService(_host);
|
||||||
|
if (svc != null) {
|
||||||
|
ITerminalService tsvc = (ITerminalService) svc
|
||||||
|
.getAdapter(ITerminalService.class);
|
||||||
|
if (tsvc != null && tsvc != this) {
|
||||||
|
_realService = tsvc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _realService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITerminalShell launchTerminal(String ptyType, String encoding,
|
||||||
|
String[] environment, String initialWorkingDirectory,
|
||||||
|
String commandToRun, IProgressMonitor monitor)
|
||||||
|
throws SystemMessageException {
|
||||||
|
return getRealService().launchTerminal(ptyType, encoding, environment,
|
||||||
|
initialWorkingDirectory, commandToRun, monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return "Generic Terminal Service";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return "Terminal Service";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initService(IProgressMonitor monitor) {
|
||||||
|
getRealService().initService(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void uninitService(IProgressMonitor monitor) {
|
||||||
|
getRealService().uninitService(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getAdapter(Class adapter) {
|
||||||
|
return getRealService().getAdapter(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 MontaVista Software, 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:
|
||||||
|
* Yu-Fen Kuo (MontaVista) - initial API and implementation
|
||||||
|
* Anna Dushistova (MontaVista) - adapted from SshTerminalSubsystemConfiguration
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.rse.internal.subsystems.terminals.core;
|
||||||
|
|
||||||
|
import org.eclipse.rse.core.model.IHost;
|
||||||
|
import org.eclipse.rse.core.subsystems.IConnectorService;
|
||||||
|
import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||||
|
import org.eclipse.rse.internal.services.terminals.ITerminalService;
|
||||||
|
import org.eclipse.rse.subsystems.terminals.core.TerminalServiceSubSystem;
|
||||||
|
import org.eclipse.rse.subsystems.terminals.core.TerminalServiceSubSystemConfiguration;
|
||||||
|
|
||||||
|
public class TerminalSubSystemConfigurationImpl extends
|
||||||
|
TerminalServiceSubSystemConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate and return an instance of OUR subsystem. Do not populate it
|
||||||
|
* yet though!
|
||||||
|
*
|
||||||
|
* @see org.eclipse.rse.core.subsystems.SubSystemConfiguration#createSubSystemInternal(IHost)
|
||||||
|
*/
|
||||||
|
public ISubSystem createSubSystemInternal(IHost host) {
|
||||||
|
IConnectorService connectorService = getConnectorService(host);
|
||||||
|
ISubSystem subsys = new TerminalServiceSubSystem(host,
|
||||||
|
connectorService, getTerminalService(host));
|
||||||
|
return subsys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITerminalService createTerminalService(IHost host) {
|
||||||
|
|
||||||
|
ISubSystem ss = TerminalSubSystemHelper.getSuitableSubSystem(host);
|
||||||
|
if (ss != null) {
|
||||||
|
return (ITerminalService) (ss.getSubSystemConfiguration()
|
||||||
|
.getService(host)).getAdapter(ITerminalService.class);
|
||||||
|
} else {
|
||||||
|
return new DelegatingTerminalService(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConnectorService(IHost host,
|
||||||
|
IConnectorService connectorService) {
|
||||||
|
// SshConnectorServiceManager.getInstance().setConnectorService(host,
|
||||||
|
// ISshService.class, connectorService);
|
||||||
|
// Nothing to do here since we just re-use the existing suitable
|
||||||
|
// subsystem
|
||||||
|
}
|
||||||
|
|
||||||
|
public IConnectorService getConnectorService(IHost host) {
|
||||||
|
ISubSystem ss = TerminalSubSystemHelper.getSuitableSubSystem(host);
|
||||||
|
if (ss != null) {
|
||||||
|
return ss.getConnectorService();
|
||||||
|
} else {
|
||||||
|
return new DelegatingTerminalConnectorService(host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2008 IBM Corporation. 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
|
||||||
|
*
|
||||||
|
* Initial Contributors:
|
||||||
|
* The following IBM employees contributed to the Remote System Explorer
|
||||||
|
* component that contains this file: David McKnight.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* {Name} (company) - description of contribution.
|
||||||
|
********************************************************************************/
|
||||||
|
package org.eclipse.rse.internal.subsystems.terminals.core;
|
||||||
|
|
||||||
|
import org.eclipse.rse.core.model.IHost;
|
||||||
|
import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||||
|
import org.eclipse.rse.internal.services.terminals.ITerminalService;
|
||||||
|
import org.eclipse.rse.services.IService;
|
||||||
|
import org.eclipse.rse.subsystems.terminals.core.ITerminalServiceSubSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class that helps to get subsystem with service that can be adapted to
|
||||||
|
* ITerminalService most of the code
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TerminalSubSystemHelper {
|
||||||
|
/**
|
||||||
|
* Find the first ITerminalServiceSubSystem service associated with the
|
||||||
|
* host.
|
||||||
|
*
|
||||||
|
* @param host
|
||||||
|
* the connection
|
||||||
|
* @return shell service subsystem, or <code>null</code> if not found.
|
||||||
|
*/
|
||||||
|
public static ISubSystem getSuitableSubSystem(IHost host) {
|
||||||
|
if (host == null)
|
||||||
|
return null;
|
||||||
|
ISubSystem[] subSystems = host.getSubSystems();
|
||||||
|
ITerminalService ssvc = null;
|
||||||
|
for (int i = 0; subSystems != null && i < subSystems.length; i++) {
|
||||||
|
IService svc = subSystems[i].getSubSystemConfiguration()
|
||||||
|
.getService(host);
|
||||||
|
if (svc != null) {
|
||||||
|
ssvc = (ITerminalService) svc
|
||||||
|
.getAdapter(ITerminalService.class);
|
||||||
|
if (ssvc != null) {
|
||||||
|
return subSystems[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns ITerminalServiceSubSystem associated with the host.
|
||||||
|
*
|
||||||
|
* @param host
|
||||||
|
* the connection
|
||||||
|
* @return shell service subsystem, or <code>null</code> if not found.
|
||||||
|
*/
|
||||||
|
public static ITerminalServiceSubSystem getTerminalServiceSubSystem(
|
||||||
|
IHost host) {
|
||||||
|
if (host == null)
|
||||||
|
return null;
|
||||||
|
ISubSystem[] subSystems = host.getSubSystems();
|
||||||
|
for (int i = 0; subSystems != null && i < subSystems.length; i++) {
|
||||||
|
if (subSystems[i] instanceof ITerminalServiceSubSystem) {
|
||||||
|
return (ITerminalServiceSubSystem) subSystems[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,10 +6,11 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Yu-Fen Kuo (MontaVista) - initial API and implementation
|
* Yu-Fen Kuo (MontaVista) - initial API and implementation
|
||||||
* Yu-Fen Kuo (MontaVista) - [227572] RSE Terminal doesn't reset the "connected" state when the shell exits
|
* Yu-Fen Kuo (MontaVista) - [227572] RSE Terminal doesn't reset the "connected" state when the shell exits
|
||||||
* Anna Dushistova (MontaVista) - [228577] [rseterminal] Clean up RSE Terminal impl
|
* Anna Dushistova (MontaVista) - [228577] [rseterminal] Clean up RSE Terminal impl
|
||||||
* Martin Oberhuber (Wind River) - [228577] [rseterminal] Further cleanup
|
* Martin Oberhuber (Wind River) - [228577] [rseterminal] Further cleanup
|
||||||
|
* Anna Dushistova (MontaVista) - [227569] [rseterminal][api] Provide a "generic" Terminal subsystem
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.rse.subsystems.terminals.core;
|
package org.eclipse.rse.subsystems.terminals.core;
|
||||||
|
@ -26,6 +27,7 @@ import org.eclipse.rse.core.model.ISystemRegistry;
|
||||||
import org.eclipse.rse.core.subsystems.CommunicationsEvent;
|
import org.eclipse.rse.core.subsystems.CommunicationsEvent;
|
||||||
import org.eclipse.rse.core.subsystems.ICommunicationsListener;
|
import org.eclipse.rse.core.subsystems.ICommunicationsListener;
|
||||||
import org.eclipse.rse.core.subsystems.IConnectorService;
|
import org.eclipse.rse.core.subsystems.IConnectorService;
|
||||||
|
import org.eclipse.rse.core.subsystems.ISubSystemConfiguration;
|
||||||
import org.eclipse.rse.core.subsystems.SubSystem;
|
import org.eclipse.rse.core.subsystems.SubSystem;
|
||||||
import org.eclipse.rse.internal.services.terminals.ITerminalService;
|
import org.eclipse.rse.internal.services.terminals.ITerminalService;
|
||||||
import org.eclipse.rse.subsystems.terminals.core.elements.TerminalElement;
|
import org.eclipse.rse.subsystems.terminals.core.elements.TerminalElement;
|
||||||
|
@ -35,39 +37,40 @@ import org.eclipse.swt.widgets.Display;
|
||||||
* A Subsystem that has terminal instances as children.
|
* A Subsystem that has terminal instances as children.
|
||||||
*/
|
*/
|
||||||
public class TerminalServiceSubSystem extends SubSystem implements
|
public class TerminalServiceSubSystem extends SubSystem implements
|
||||||
ITerminalServiceSubSystem, ICommunicationsListener {
|
ITerminalServiceSubSystem, ICommunicationsListener {
|
||||||
|
|
||||||
private ITerminalService _hostService = null;
|
private ITerminalService _hostService = null;
|
||||||
|
|
||||||
private ArrayList children = new ArrayList();
|
private ArrayList children = new ArrayList();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public TerminalServiceSubSystem(IHost host,
|
public TerminalServiceSubSystem(IHost host,
|
||||||
IConnectorService connectorService, ITerminalService hostService) {
|
IConnectorService connectorService, ITerminalService hostService) {
|
||||||
super(host, connectorService);
|
super(host, connectorService);
|
||||||
_hostService = hostService;
|
_hostService = hostService;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fireAsyncRefresh(final Object target) {
|
private void fireAsyncRefresh(final Object target) {
|
||||||
Display.getDefault().asyncExec(new Runnable() {
|
Display.getDefault().asyncExec(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
ISystemRegistry registry = RSECorePlugin.getTheSystemRegistry();
|
ISystemRegistry registry = RSECorePlugin.getTheSystemRegistry();
|
||||||
registry.fireEvent(new SystemResourceChangeEvent(target, ISystemResourceChangeEvents.EVENT_REFRESH, target));
|
registry.fireEvent(new SystemResourceChangeEvent(target,
|
||||||
|
ISystemResourceChangeEvents.EVENT_REFRESH, target));
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Terminal Service associated with this subsystem.
|
* Return the Terminal Service associated with this subsystem.
|
||||||
*/
|
*/
|
||||||
public ITerminalService getTerminalService() {
|
public ITerminalService getTerminalService() {
|
||||||
return _hostService;
|
return _hostService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class getServiceType() {
|
public Class getServiceType() {
|
||||||
return ITerminalService.class;
|
return ITerminalService.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,81 +81,81 @@ public class TerminalServiceSubSystem extends SubSystem implements
|
||||||
}
|
}
|
||||||
fireAsyncRefresh(this);
|
fireAsyncRefresh(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeChild(TerminalElement element) {
|
public void removeChild(TerminalElement element) {
|
||||||
if(element!=null){
|
if (element != null) {
|
||||||
synchronized (children) {
|
synchronized (children) {
|
||||||
children.remove(element);
|
children.remove(element);
|
||||||
}
|
}
|
||||||
fireAsyncRefresh(this);
|
fireAsyncRefresh(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeChild(String terminalTitle) {
|
public void removeChild(String terminalTitle) {
|
||||||
removeChild(getChild(terminalTitle));
|
removeChild(getChild(terminalTitle));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TerminalElement getChild(String terminalTitle) {
|
public TerminalElement getChild(String terminalTitle) {
|
||||||
synchronized (children) {
|
synchronized (children) {
|
||||||
for (Iterator it = children.iterator(); it.hasNext();) {
|
for (Iterator it = children.iterator(); it.hasNext();) {
|
||||||
TerminalElement element = (TerminalElement) it.next();
|
TerminalElement element = (TerminalElement) it.next();
|
||||||
if (element.getName().equals(terminalTitle))
|
if (element.getName().equals(terminalTitle))
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object[] getChildren() {
|
public Object[] getChildren() {
|
||||||
synchronized (children) {
|
synchronized (children) {
|
||||||
return children.toArray();
|
return children.toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasChildren() {
|
public boolean hasChildren() {
|
||||||
synchronized (children) {
|
synchronized (children) {
|
||||||
return !children.isEmpty();
|
return !children.isEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the terminal service associated with this subsystem.
|
* Set the terminal service associated with this subsystem.
|
||||||
*/
|
*/
|
||||||
public void setTerminalService(ITerminalService service) {
|
public void setTerminalService(ITerminalService service) {
|
||||||
_hostService = service;
|
_hostService = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void communicationsStateChange(CommunicationsEvent e) {
|
public void communicationsStateChange(CommunicationsEvent e) {
|
||||||
switch (e.getState()) {
|
switch (e.getState()) {
|
||||||
case CommunicationsEvent.AFTER_DISCONNECT:
|
case CommunicationsEvent.AFTER_DISCONNECT:
|
||||||
// no longer listen
|
// no longer listen
|
||||||
getConnectorService().removeCommunicationsListener(this);
|
getConnectorService().removeCommunicationsListener(this);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CommunicationsEvent.BEFORE_DISCONNECT:
|
case CommunicationsEvent.BEFORE_DISCONNECT:
|
||||||
case CommunicationsEvent.CONNECTION_ERROR:
|
case CommunicationsEvent.CONNECTION_ERROR:
|
||||||
Display.getDefault().asyncExec(new Runnable(){
|
Display.getDefault().asyncExec(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
cancelAllTerminals();
|
cancelAllTerminals();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPassiveCommunicationsListener() {
|
public boolean isPassiveCommunicationsListener() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the terminal service associated with this subsystem.
|
* Set the terminal service associated with this subsystem.
|
||||||
*/
|
*/
|
||||||
public void cancelAllTerminals() {
|
public void cancelAllTerminals() {
|
||||||
Object[] terminals;
|
Object[] terminals;
|
||||||
synchronized (children) {
|
synchronized (children) {
|
||||||
terminals = getChildren();
|
terminals = getChildren();
|
||||||
children.clear();
|
children.clear();
|
||||||
|
@ -163,26 +166,32 @@ public class TerminalServiceSubSystem extends SubSystem implements
|
||||||
try {
|
try {
|
||||||
removeTerminalElement(element);
|
removeTerminalElement(element);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
RSECorePlugin.getDefault().getLogger().logError("Error removing terminal", e); //$NON-NLS-1$
|
RSECorePlugin.getDefault().getLogger().logError(
|
||||||
|
"Error removing terminal", e); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fireAsyncRefresh(this);
|
fireAsyncRefresh(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeTerminalElement(TerminalElement element) {
|
private void removeTerminalElement(TerminalElement element) {
|
||||||
element.getTerminalShell().exit();
|
element.getTerminalShell().exit();
|
||||||
ISystemRegistry registry = RSECorePlugin.getTheSystemRegistry();
|
ISystemRegistry registry = RSECorePlugin.getTheSystemRegistry();
|
||||||
registry.fireEvent(new SystemResourceChangeEvent(element, ISystemResourceChangeEvents.EVENT_COMMAND_SHELL_REMOVED, null));
|
registry.fireEvent(new SystemResourceChangeEvent(element,
|
||||||
}
|
ISystemResourceChangeEvents.EVENT_COMMAND_SHELL_REMOVED, null));
|
||||||
|
}
|
||||||
|
|
||||||
public void initializeSubSystem(IProgressMonitor monitor) {
|
public void initializeSubSystem(IProgressMonitor monitor) {
|
||||||
super.initializeSubSystem(monitor);
|
super.initializeSubSystem(monitor);
|
||||||
getConnectorService().addCommunicationsListener(this);
|
getConnectorService().addCommunicationsListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void uninitializeSubSystem(IProgressMonitor monitor) {
|
public void uninitializeSubSystem(IProgressMonitor monitor) {
|
||||||
getConnectorService().removeCommunicationsListener(this);
|
getConnectorService().removeCommunicationsListener(this);
|
||||||
super.uninitializeSubSystem(monitor);
|
super.uninitializeSubSystem(monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean canSwitchTo(ISubSystemConfiguration configuration) {
|
||||||
|
return (configuration instanceof ITerminalServiceSubSystemConfiguration);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,8 @@
|
||||||
* available at http://www.eclipse.org/legal/epl-v10.html
|
* available at http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Yu-Fen Kuo (MontaVista) - initial API and implementation
|
* Yu-Fen Kuo (MontaVista) - initial API and implementation
|
||||||
|
* Anna Dushistova (MontaVista) - [227569] [rseterminal][api] Provide a "generic" Terminal subsystem
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.rse.subsystems.terminals.core;
|
package org.eclipse.rse.subsystems.terminals.core;
|
||||||
|
@ -18,21 +19,20 @@ import org.eclipse.rse.core.subsystems.SubSystemConfiguration;
|
||||||
import org.eclipse.rse.internal.services.terminals.ITerminalService;
|
import org.eclipse.rse.internal.services.terminals.ITerminalService;
|
||||||
import org.eclipse.rse.services.IService;
|
import org.eclipse.rse.services.IService;
|
||||||
|
|
||||||
|
|
||||||
public abstract class TerminalServiceSubSystemConfiguration extends
|
public abstract class TerminalServiceSubSystemConfiguration extends
|
||||||
SubSystemConfiguration implements
|
SubSystemConfiguration implements
|
||||||
ITerminalServiceSubSystemConfiguration {
|
ITerminalServiceSubSystemConfiguration {
|
||||||
|
|
||||||
private Map _services;
|
private Map _services;
|
||||||
|
|
||||||
protected TerminalServiceSubSystemConfiguration() {
|
protected TerminalServiceSubSystemConfiguration() {
|
||||||
super();
|
super();
|
||||||
_services = new HashMap();
|
_services = new HashMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean supportsFilters() {
|
public boolean supportsFilters() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final ITerminalService getTerminalService(IHost host) {
|
public final ITerminalService getTerminalService(IHost host) {
|
||||||
ITerminalService service = (ITerminalService) _services.get(host);
|
ITerminalService service = (ITerminalService) _services.get(host);
|
||||||
|
@ -51,4 +51,9 @@ public abstract class TerminalServiceSubSystemConfiguration extends
|
||||||
return ITerminalService.class;
|
return ITerminalService.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isFactoryFor(Class subSystemType) {
|
||||||
|
boolean isFor = TerminalServiceSubSystem.class.equals(subSystemType);
|
||||||
|
return isFor;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
* available at http://www.eclipse.org/legal/epl-v10.html
|
* available at http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Yu-Fen Kuo (MontaVista) - initial API and implementation
|
* Yu-Fen Kuo (MontaVista) - initial API and implementation
|
||||||
* Yu-Fen Kuo (MontaVista) - [227572] RSE Terminal doesn't reset the "connected" state when the shell exits
|
* Yu-Fen Kuo (MontaVista) - [227572] RSE Terminal doesn't reset the "connected" state when the shell exits
|
||||||
* Anna Dushistova (MontaVista) - [227535] [rseterminal][api] terminals.ui should not depend on files.core
|
* Anna Dushistova (MontaVista) - [227535] [rseterminal][api] terminals.ui should not depend on files.core
|
||||||
|
* Anna Dushistova (MontaVista) - [227569] [rseterminal][api] Provide a "generic" Terminal subsystem
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.rse.internal.terminals.ui;
|
package org.eclipse.rse.internal.terminals.ui;
|
||||||
|
@ -42,8 +43,7 @@ public class TerminalServiceHelper {
|
||||||
ISystemRegistry systemRegistry = RSECorePlugin.getTheSystemRegistry();
|
ISystemRegistry systemRegistry = RSECorePlugin.getTheSystemRegistry();
|
||||||
ISubSystem[] subsystems = systemRegistry.getSubSystems(connection);
|
ISubSystem[] subsystems = systemRegistry.getSubSystems(connection);
|
||||||
for (int i = 0; i < subsystems.length; i++) {
|
for (int i = 0; i < subsystems.length; i++) {
|
||||||
if ("ssh.terminals".equals(subsystems[i]
|
if (subsystems[i] instanceof ITerminalServiceSubSystem) {
|
||||||
.getSubSystemConfiguration().getId())) {
|
|
||||||
ITerminalServiceSubSystem subSystem = (ITerminalServiceSubSystem) subsystems[i];
|
ITerminalServiceSubSystem subSystem = (ITerminalServiceSubSystem) subsystems[i];
|
||||||
return subSystem;
|
return subSystem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,8 @@ Require-Bundle: org.junit,
|
||||||
org.eclipse.rse.files.ui,
|
org.eclipse.rse.files.ui,
|
||||||
org.eclipse.rse.efs,
|
org.eclipse.rse.efs,
|
||||||
org.eclipse.rse.tests.framework;bundle-version="[2.0.0,3.0.0)",
|
org.eclipse.rse.tests.framework;bundle-version="[2.0.0,3.0.0)",
|
||||||
org.apache.commons.net;bundle-version="[1.4.1,2.0.0)"
|
org.apache.commons.net;bundle-version="[1.4.1,2.0.0)",
|
||||||
|
org.eclipse.rse.subsystems.terminals.core;bundle-version="0.1.1"
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Eclipse-LazyStart: true
|
Eclipse-LazyStart: true
|
||||||
Bundle-RequiredExecutionEnvironment: J2SE-1.4
|
Bundle-RequiredExecutionEnvironment: J2SE-1.4
|
||||||
|
|
|
@ -96,6 +96,13 @@
|
||||||
value="true">
|
value="true">
|
||||||
</property>
|
</property>
|
||||||
</systemType>
|
</systemType>
|
||||||
|
<systemType
|
||||||
|
description="Linux without shells subsystem"
|
||||||
|
id="org.eclipse.rse.tests.sshTerminal"
|
||||||
|
label="Ssh without shells"
|
||||||
|
name="Ssh without shells"
|
||||||
|
subsystemConfigurationIds="ssh.terminals;ssh.files;processes.shell.linux">
|
||||||
|
</systemType>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension point="org.eclipse.rse.core.modelInitializers">
|
<extension point="org.eclipse.rse.core.modelInitializers">
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
import org.eclipse.rse.core.RSECorePlugin;
|
import org.eclipse.rse.core.RSECorePlugin;
|
||||||
import org.eclipse.rse.core.model.IHost;
|
import org.eclipse.rse.core.model.IHost;
|
||||||
import org.eclipse.rse.core.subsystems.ISubSystem;
|
import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||||
|
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||||
import org.eclipse.rse.services.shells.IHostOutput;
|
import org.eclipse.rse.services.shells.IHostOutput;
|
||||||
import org.eclipse.rse.services.shells.IHostShell;
|
import org.eclipse.rse.services.shells.IHostShell;
|
||||||
import org.eclipse.rse.services.shells.IShellService;
|
import org.eclipse.rse.services.shells.IShellService;
|
||||||
|
@ -30,13 +31,13 @@ import org.eclipse.rse.tests.core.connection.RSEBaseConnectionTestCase;
|
||||||
|
|
||||||
public class ShellServiceTest extends RSEBaseConnectionTestCase {
|
public class ShellServiceTest extends RSEBaseConnectionTestCase {
|
||||||
|
|
||||||
private String fPropertiesFileName;
|
protected String fPropertiesFileName;
|
||||||
// For testing the test: verify methods on Local
|
// For testing the test: verify methods on Local
|
||||||
public static String fDefaultPropertiesFile = "localConnection.properties";
|
public static String fDefaultPropertiesFile = "localConnection.properties";
|
||||||
|
|
||||||
private IShellServiceSubSystem shellSubSystem;
|
protected IShellServiceSubSystem shellSubSystem;
|
||||||
private IShellService shellService;
|
protected IShellService shellService;
|
||||||
private IProgressMonitor mon = new NullProgressMonitor();
|
protected IProgressMonitor mon = new NullProgressMonitor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor with specific test name.
|
* Constructor with specific test name.
|
||||||
|
@ -71,9 +72,7 @@ public class ShellServiceTest extends RSEBaseConnectionTestCase {
|
||||||
TestSuite suite = new TestSuite(baseName);
|
TestSuite suite = new TestSuite(baseName);
|
||||||
|
|
||||||
// // Add a test suite for each connection type
|
// // Add a test suite for each connection type
|
||||||
String[] connTypes = { "local", "ssh", "telnet", "linux" };
|
String[] connTypes = { "local", "ssh", "telnet" };
|
||||||
// String[] connTypes = { "local" };
|
|
||||||
// String[] connTypes = { "ssh" };
|
|
||||||
|
|
||||||
for (int i = 0; i < connTypes.length; i++) {
|
for (int i = 0; i < connTypes.length; i++) {
|
||||||
String suiteName = connTypes[i];
|
String suiteName = connTypes[i];
|
||||||
|
@ -110,6 +109,10 @@ public class ShellServiceTest extends RSEBaseConnectionTestCase {
|
||||||
|
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
initShellService();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initShellService() throws SystemMessageException {
|
||||||
shellSubSystem = getShellServiceSubSystem();
|
shellSubSystem = getShellServiceSubSystem();
|
||||||
shellService = shellSubSystem.getShellService();
|
shellService = shellSubSystem.getShellService();
|
||||||
shellSubSystem.checkIsConnected(getDefaultProgressMonitor());
|
shellSubSystem.checkIsConnected(getDefaultProgressMonitor());
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 MontaVista Software, 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:
|
||||||
|
* Anna Dushistova (MontaVista)- initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.rse.tests.subsystems.shells;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
import org.eclipse.rse.core.RSECorePlugin;
|
||||||
|
import org.eclipse.rse.core.model.IHost;
|
||||||
|
import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||||
|
import org.eclipse.rse.internal.services.terminals.ITerminalService;
|
||||||
|
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||||
|
import org.eclipse.rse.services.shells.IShellService;
|
||||||
|
import org.eclipse.rse.subsystems.terminals.core.TerminalServiceSubSystem;
|
||||||
|
|
||||||
|
public class TerminalShellServiceTest extends ShellServiceTest{
|
||||||
|
|
||||||
|
protected ITerminalService terminalService;
|
||||||
|
protected TerminalServiceSubSystem terminalSubSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
* @param propertiesFileName
|
||||||
|
*/
|
||||||
|
public TerminalShellServiceTest(String name, String propertiesFileName) {
|
||||||
|
super(name, propertiesFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public TerminalShellServiceTest(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Test suite() {
|
||||||
|
String baseName = TerminalShellServiceTest.class.getName();
|
||||||
|
TestSuite suite = new TestSuite(baseName);
|
||||||
|
|
||||||
|
// // Add a test suite for each connection type
|
||||||
|
String[] connTypes = { "sshTerminal" };
|
||||||
|
// String[] connTypes = { "local" };
|
||||||
|
// String[] connTypes = { "ssh" };
|
||||||
|
|
||||||
|
for (int i = 0; i < connTypes.length; i++) {
|
||||||
|
String suiteName = connTypes[i];
|
||||||
|
String propFileName = connTypes[i] == null ? null : connTypes[i]
|
||||||
|
+ "Connection.properties";
|
||||||
|
TestSuite subSuite = new TestSuite(baseName + "." + suiteName);
|
||||||
|
Method[] m = TerminalShellServiceTest.class.getMethods();
|
||||||
|
for (int j = 0; j < m.length; j++) {
|
||||||
|
String testName = m[j].getName();
|
||||||
|
if (testName.startsWith("test")) {
|
||||||
|
subSuite.addTest(new TerminalShellServiceTest(testName,
|
||||||
|
propFileName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
suite.addTest(subSuite);
|
||||||
|
}
|
||||||
|
return suite;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TerminalServiceSubSystem getTerminalServiceSubSystem() {
|
||||||
|
if (fPropertiesFileName == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
IHost host = getHost(fPropertiesFileName);
|
||||||
|
ISubSystem[] ss = RSECorePlugin.getTheSystemRegistry()
|
||||||
|
.getServiceSubSystems(host, ITerminalService.class);
|
||||||
|
for (int i = 0; i < ss.length; i++) {
|
||||||
|
if (ss[i] instanceof TerminalServiceSubSystem) {
|
||||||
|
return (TerminalServiceSubSystem) ss[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.rse.tests.subsystems.shells.ShellServiceTest#initShellService()
|
||||||
|
*/
|
||||||
|
protected void initShellService() throws SystemMessageException {
|
||||||
|
terminalSubSystem = getTerminalServiceSubSystem();
|
||||||
|
terminalService = terminalSubSystem.getTerminalService();
|
||||||
|
terminalSubSystem.checkIsConnected(getDefaultProgressMonitor());
|
||||||
|
shellService = (IShellService) terminalService.getAdapter(IShellService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWindows() {
|
||||||
|
return terminalSubSystem.getHost().getSystemType().isWindows();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
###############################################################################
|
||||||
|
# Copyright (c) 2008 IBM Corporation and others. All rights reserved.
|
||||||
|
# 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:
|
||||||
|
# IBM Corporation - initial API and implementation
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# name/label for this windows connection
|
||||||
|
name = test_ssh_terminals_only
|
||||||
|
|
||||||
|
# profile name this connection should be created for
|
||||||
|
profile_name = junit_test_profile
|
||||||
|
|
||||||
|
# SSH system ID
|
||||||
|
system_type_id = org.eclipse.rse.tests.sshTerminal
|
||||||
|
|
||||||
|
# Address of ssh connection
|
||||||
|
address = unknown
|
||||||
|
|
||||||
|
# userid to connect to ssh connection
|
||||||
|
#userid =
|
||||||
|
|
||||||
|
# password to connect to ssh connection
|
||||||
|
#password =
|
|
@ -0,0 +1,28 @@
|
||||||
|
###############################################################################
|
||||||
|
# Copyright (c) 2008 IBM Corporation and others. All rights reserved.
|
||||||
|
# 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:
|
||||||
|
# IBM Corporation - initial API and implementation
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# name/label for this windows connection
|
||||||
|
name = test_telnet_only
|
||||||
|
|
||||||
|
# profile name this connection should be created for
|
||||||
|
profile_name = junit_test_profile
|
||||||
|
|
||||||
|
# SSH system ID
|
||||||
|
system_type_id = org.eclipse.rse.systemtype.telnet
|
||||||
|
|
||||||
|
# Address of ssh connection
|
||||||
|
address = unknown
|
||||||
|
|
||||||
|
# userid to connect to ssh connection
|
||||||
|
#userid =
|
||||||
|
|
||||||
|
# password to connect to ssh connection
|
||||||
|
#password =
|
Loading…
Add table
Reference in a new issue