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:
|
||||
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||
* David Dykstal (IBM) - 168977: refactoring IConnectorService and ServerLauncher hierarchies
|
||||
* Sheldon D'souza (Celunite) - adapted from SshConnectorService
|
||||
* David Dykstal (IBM) - [168977] refactoring IConnectorService and ServerLauncher hierarchies
|
||||
* Sheldon D'souza (Celunite) - adapted from SshConnectorService
|
||||
* Martin Oberhuber (Wind River) - apply refactorings for StandardConnectorService
|
||||
* 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) - [186570] handle invalid user id and password more gracefully
|
||||
* Sheldon D'souza (Celunite) - [186536] login and password should be configurable
|
||||
* Sheldon D'souza (Celunite) - [186570] handle invalid user id and password more gracefully
|
||||
* Martin Oberhuber (Wind River) - [187218] Fix error reporting for connect()
|
||||
* Sheldon D'souza (Celunite) - [187301] support multiple telnet shells
|
||||
* Sheldon D'souza (Celunite) - [194464] fix create multiple telnet shells quickly
|
||||
* Sheldon D'souza (Celunite) - [187301] support multiple telnet shells
|
||||
* Sheldon D'souza (Celunite) - [194464] fix create multiple telnet shells quickly
|
||||
* 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) - [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;
|
||||
|
||||
|
@ -148,8 +149,12 @@ public class TelnetConnectorService extends StandardConnectorService implements
|
|||
return port;
|
||||
}
|
||||
|
||||
public TelnetClient makeNewTelnetClient( IProgressMonitor monitor ) throws Exception {
|
||||
public TelnetClient makeNewTelnetClient(IProgressMonitor monitor ) throws Exception {
|
||||
TelnetClient client = new TelnetClient();
|
||||
return makeNewTelnetClient(client, monitor);
|
||||
}
|
||||
|
||||
public TelnetClient makeNewTelnetClient(TelnetClient client, IProgressMonitor monitor ) throws Exception {
|
||||
String host = getHostName();
|
||||
String user = getUserId();
|
||||
String password = ""; //$NON-NLS-1$
|
||||
|
|
|
@ -2,14 +2,15 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %pluginName
|
||||
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-Localization: plugin
|
||||
Require-Bundle: org.eclipse.core.runtime,
|
||||
org.eclipse.rse.services;bundle-version="[3.0.0,4.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",
|
||||
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
|
||||
Eclipse-LazyStart: true
|
||||
Bundle-Vendor: %providerName
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||
*
|
||||
* Contributors:
|
||||
* Sheldon D'souza (Celunite) - adapted from ISshSessionProvider
|
||||
* Sheldon D'souza (Celunite) - [187301] support multiple telnet shells
|
||||
* Sheldon D'souza (Celunite) - adapted from ISshSessionProvider
|
||||
* 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;
|
||||
|
||||
|
@ -29,5 +30,14 @@ public interface ITelnetSessionProvider {
|
|||
* @throws Exception in case of any error
|
||||
*/
|
||||
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"?>
|
||||
<!--
|
||||
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"?>
|
||||
<plugin>
|
||||
<extension-point id="archivehandlers" name="%extPoint.archivehandlers" schema="schema/archivehandlers.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>
|
||||
|
|
|
@ -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:
|
||||
* 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
|
||||
* 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;
|
||||
|
||||
|
@ -25,6 +26,7 @@ import org.eclipse.core.runtime.IPath;
|
|||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
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.services.shells.IHostOutput;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
|
@ -175,6 +177,9 @@ public class TelnetServiceCommandShell extends ServiceCommandShell {
|
|||
protected String getPromptCommand() {
|
||||
IHostShell shell = getHostShell();
|
||||
//assert shell instanceof TelnetHostShell;
|
||||
if (shell instanceof TerminalServiceHostShell) {
|
||||
return ((TerminalServiceHostShell)shell).getPromptCommand();
|
||||
}
|
||||
if (shell instanceof TelnetHostShell) {
|
||||
return ((TelnetHostShell)shell).getPromptCommand();
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
*
|
||||
* Contributors:
|
||||
* 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;
|
||||
|
||||
|
@ -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.TelnetConnectorServiceManager;
|
||||
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.services.shells.IHostShell;
|
||||
import org.eclipse.rse.services.shells.IShellService;
|
||||
|
@ -61,7 +62,7 @@ public class TelnetShellSubSystemConfiguration extends
|
|||
|
||||
public IShellService createShellService(IHost host) {
|
||||
TelnetConnectorService cserv = (TelnetConnectorService)getConnectorService(host);
|
||||
return new TelnetShellService(cserv);
|
||||
return (IShellService) (new TelnetTerminalService(cserv)).getAdapter(IShellService.class);
|
||||
}
|
||||
|
||||
public IConnectorService getConnectorService(IHost host) {
|
||||
|
|
|
@ -13,5 +13,6 @@ output.. = bin/
|
|||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
plugin.properties,\
|
||||
about.html
|
||||
about.html,\
|
||||
plugin.xml
|
||||
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)
|
||||
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
|
||||
*
|
||||
* Contributors:
|
||||
* 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
|
||||
* Anna Dushistova (MontaVista) - [228577] [rseterminal] Clean up RSE Terminal impl
|
||||
* 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
|
||||
* Anna Dushistova (MontaVista) - [228577] [rseterminal] Clean up RSE Terminal impl
|
||||
* 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;
|
||||
|
@ -26,6 +27,7 @@ import org.eclipse.rse.core.model.ISystemRegistry;
|
|||
import org.eclipse.rse.core.subsystems.CommunicationsEvent;
|
||||
import org.eclipse.rse.core.subsystems.ICommunicationsListener;
|
||||
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.internal.services.terminals.ITerminalService;
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public TerminalServiceSubSystem(IHost host,
|
||||
IConnectorService connectorService, ITerminalService hostService) {
|
||||
super(host, connectorService);
|
||||
_hostService = hostService;
|
||||
}
|
||||
public TerminalServiceSubSystem(IHost host,
|
||||
IConnectorService connectorService, ITerminalService hostService) {
|
||||
super(host, connectorService);
|
||||
_hostService = hostService;
|
||||
}
|
||||
|
||||
private void fireAsyncRefresh(final Object target) {
|
||||
private void fireAsyncRefresh(final Object target) {
|
||||
Display.getDefault().asyncExec(new Runnable() {
|
||||
public void run() {
|
||||
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.
|
||||
*/
|
||||
public ITerminalService getTerminalService() {
|
||||
return _hostService;
|
||||
}
|
||||
public ITerminalService getTerminalService() {
|
||||
return _hostService;
|
||||
}
|
||||
|
||||
public Class getServiceType() {
|
||||
public Class getServiceType() {
|
||||
return ITerminalService.class;
|
||||
}
|
||||
|
||||
|
@ -78,81 +81,81 @@ public class TerminalServiceSubSystem extends SubSystem implements
|
|||
}
|
||||
fireAsyncRefresh(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeChild(TerminalElement element) {
|
||||
if(element!=null){
|
||||
synchronized (children) {
|
||||
children.remove(element);
|
||||
}
|
||||
public void removeChild(TerminalElement element) {
|
||||
if (element != null) {
|
||||
synchronized (children) {
|
||||
children.remove(element);
|
||||
}
|
||||
fireAsyncRefresh(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeChild(String terminalTitle) {
|
||||
removeChild(getChild(terminalTitle));
|
||||
}
|
||||
public void removeChild(String terminalTitle) {
|
||||
removeChild(getChild(terminalTitle));
|
||||
}
|
||||
|
||||
public TerminalElement getChild(String terminalTitle) {
|
||||
synchronized (children) {
|
||||
public TerminalElement getChild(String terminalTitle) {
|
||||
synchronized (children) {
|
||||
for (Iterator it = children.iterator(); it.hasNext();) {
|
||||
TerminalElement element = (TerminalElement) it.next();
|
||||
if (element.getName().equals(terminalTitle))
|
||||
return element;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object[] getChildren() {
|
||||
synchronized (children) {
|
||||
return children.toArray();
|
||||
}
|
||||
}
|
||||
public Object[] getChildren() {
|
||||
synchronized (children) {
|
||||
return children.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasChildren() {
|
||||
synchronized (children) {
|
||||
return !children.isEmpty();
|
||||
}
|
||||
}
|
||||
public boolean hasChildren() {
|
||||
synchronized (children) {
|
||||
return !children.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Set the terminal service associated with this subsystem.
|
||||
*/
|
||||
public void setTerminalService(ITerminalService service) {
|
||||
_hostService = service;
|
||||
}
|
||||
public void setTerminalService(ITerminalService service) {
|
||||
_hostService = service;
|
||||
}
|
||||
|
||||
public void communicationsStateChange(CommunicationsEvent e) {
|
||||
switch (e.getState()) {
|
||||
case CommunicationsEvent.AFTER_DISCONNECT:
|
||||
// no longer listen
|
||||
getConnectorService().removeCommunicationsListener(this);
|
||||
break;
|
||||
public void communicationsStateChange(CommunicationsEvent e) {
|
||||
switch (e.getState()) {
|
||||
case CommunicationsEvent.AFTER_DISCONNECT:
|
||||
// no longer listen
|
||||
getConnectorService().removeCommunicationsListener(this);
|
||||
break;
|
||||
|
||||
case CommunicationsEvent.BEFORE_DISCONNECT:
|
||||
case CommunicationsEvent.CONNECTION_ERROR:
|
||||
Display.getDefault().asyncExec(new Runnable(){
|
||||
public void run() {
|
||||
cancelAllTerminals();
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case CommunicationsEvent.BEFORE_DISCONNECT:
|
||||
case CommunicationsEvent.CONNECTION_ERROR:
|
||||
Display.getDefault().asyncExec(new Runnable() {
|
||||
public void run() {
|
||||
cancelAllTerminals();
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPassiveCommunicationsListener() {
|
||||
return true;
|
||||
}
|
||||
public boolean isPassiveCommunicationsListener() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Set the terminal service associated with this subsystem.
|
||||
*/
|
||||
public void cancelAllTerminals() {
|
||||
Object[] terminals;
|
||||
public void cancelAllTerminals() {
|
||||
Object[] terminals;
|
||||
synchronized (children) {
|
||||
terminals = getChildren();
|
||||
children.clear();
|
||||
|
@ -163,26 +166,32 @@ public class TerminalServiceSubSystem extends SubSystem implements
|
|||
try {
|
||||
removeTerminalElement(element);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeTerminalElement(TerminalElement element) {
|
||||
element.getTerminalShell().exit();
|
||||
ISystemRegistry registry = RSECorePlugin.getTheSystemRegistry();
|
||||
registry.fireEvent(new SystemResourceChangeEvent(element, ISystemResourceChangeEvents.EVENT_COMMAND_SHELL_REMOVED, null));
|
||||
}
|
||||
private void removeTerminalElement(TerminalElement element) {
|
||||
element.getTerminalShell().exit();
|
||||
ISystemRegistry registry = RSECorePlugin.getTheSystemRegistry();
|
||||
registry.fireEvent(new SystemResourceChangeEvent(element,
|
||||
ISystemResourceChangeEvents.EVENT_COMMAND_SHELL_REMOVED, null));
|
||||
}
|
||||
|
||||
public void initializeSubSystem(IProgressMonitor monitor) {
|
||||
super.initializeSubSystem(monitor);
|
||||
getConnectorService().addCommunicationsListener(this);
|
||||
}
|
||||
public void initializeSubSystem(IProgressMonitor monitor) {
|
||||
super.initializeSubSystem(monitor);
|
||||
getConnectorService().addCommunicationsListener(this);
|
||||
}
|
||||
|
||||
public void uninitializeSubSystem(IProgressMonitor monitor) {
|
||||
getConnectorService().removeCommunicationsListener(this);
|
||||
super.uninitializeSubSystem(monitor);
|
||||
}
|
||||
public void uninitializeSubSystem(IProgressMonitor monitor) {
|
||||
getConnectorService().removeCommunicationsListener(this);
|
||||
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
|
||||
*
|
||||
* 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;
|
||||
|
@ -18,21 +19,20 @@ import org.eclipse.rse.core.subsystems.SubSystemConfiguration;
|
|||
import org.eclipse.rse.internal.services.terminals.ITerminalService;
|
||||
import org.eclipse.rse.services.IService;
|
||||
|
||||
|
||||
public abstract class TerminalServiceSubSystemConfiguration extends
|
||||
SubSystemConfiguration implements
|
||||
ITerminalServiceSubSystemConfiguration {
|
||||
SubSystemConfiguration implements
|
||||
ITerminalServiceSubSystemConfiguration {
|
||||
|
||||
private Map _services;
|
||||
|
||||
protected TerminalServiceSubSystemConfiguration() {
|
||||
super();
|
||||
_services = new HashMap();
|
||||
}
|
||||
protected TerminalServiceSubSystemConfiguration() {
|
||||
super();
|
||||
_services = new HashMap();
|
||||
}
|
||||
|
||||
public boolean supportsFilters() {
|
||||
return false;
|
||||
}
|
||||
public boolean supportsFilters() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public final ITerminalService getTerminalService(IHost host) {
|
||||
ITerminalService service = (ITerminalService) _services.get(host);
|
||||
|
@ -51,4 +51,9 @@ public abstract class TerminalServiceSubSystemConfiguration extends
|
|||
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
|
||||
*
|
||||
* Contributors:
|
||||
* 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) - initial API and implementation
|
||||
* 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) - [227569] [rseterminal][api] Provide a "generic" Terminal subsystem
|
||||
********************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.terminals.ui;
|
||||
|
@ -42,8 +43,7 @@ public class TerminalServiceHelper {
|
|||
ISystemRegistry systemRegistry = RSECorePlugin.getTheSystemRegistry();
|
||||
ISubSystem[] subsystems = systemRegistry.getSubSystems(connection);
|
||||
for (int i = 0; i < subsystems.length; i++) {
|
||||
if ("ssh.terminals".equals(subsystems[i]
|
||||
.getSubSystemConfiguration().getId())) {
|
||||
if (subsystems[i] instanceof ITerminalServiceSubSystem) {
|
||||
ITerminalServiceSubSystem subSystem = (ITerminalServiceSubSystem) subsystems[i];
|
||||
return subSystem;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,8 @@ Require-Bundle: org.junit,
|
|||
org.eclipse.rse.files.ui,
|
||||
org.eclipse.rse.efs,
|
||||
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
|
||||
Eclipse-LazyStart: true
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.4
|
||||
|
|
|
@ -96,6 +96,13 @@
|
|||
value="true">
|
||||
</property>
|
||||
</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 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.model.IHost;
|
||||
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.IHostShell;
|
||||
import org.eclipse.rse.services.shells.IShellService;
|
||||
|
@ -30,13 +31,13 @@ import org.eclipse.rse.tests.core.connection.RSEBaseConnectionTestCase;
|
|||
|
||||
public class ShellServiceTest extends RSEBaseConnectionTestCase {
|
||||
|
||||
private String fPropertiesFileName;
|
||||
protected String fPropertiesFileName;
|
||||
// For testing the test: verify methods on Local
|
||||
public static String fDefaultPropertiesFile = "localConnection.properties";
|
||||
|
||||
private IShellServiceSubSystem shellSubSystem;
|
||||
private IShellService shellService;
|
||||
private IProgressMonitor mon = new NullProgressMonitor();
|
||||
protected IShellServiceSubSystem shellSubSystem;
|
||||
protected IShellService shellService;
|
||||
protected IProgressMonitor mon = new NullProgressMonitor();
|
||||
|
||||
/**
|
||||
* Constructor with specific test name.
|
||||
|
@ -71,9 +72,7 @@ public class ShellServiceTest extends RSEBaseConnectionTestCase {
|
|||
TestSuite suite = new TestSuite(baseName);
|
||||
|
||||
// // Add a test suite for each connection type
|
||||
String[] connTypes = { "local", "ssh", "telnet", "linux" };
|
||||
// String[] connTypes = { "local" };
|
||||
// String[] connTypes = { "ssh" };
|
||||
String[] connTypes = { "local", "ssh", "telnet" };
|
||||
|
||||
for (int i = 0; i < connTypes.length; i++) {
|
||||
String suiteName = connTypes[i];
|
||||
|
@ -110,6 +109,10 @@ public class ShellServiceTest extends RSEBaseConnectionTestCase {
|
|||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
initShellService();
|
||||
}
|
||||
|
||||
protected void initShellService() throws SystemMessageException {
|
||||
shellSubSystem = getShellServiceSubSystem();
|
||||
shellService = shellSubSystem.getShellService();
|
||||
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