1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

Move IRemoteFileManager and IRemoteProcessBuilder interfaces to

IRemoteConnection.

Signed-off-by: Greg Watson <g.watson@computer.org>
This commit is contained in:
Greg Watson 2013-08-26 14:35:33 -04:00
parent 96b3b2b6e0
commit bb84e48cd4
26 changed files with 592 additions and 708 deletions

View file

@ -2,19 +2,11 @@ package org.eclipse.remote.core.tests;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import junit.framework.TestCase;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.IFileSystem;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionManager;
import org.eclipse.remote.core.IRemoteFileManager;
@ -25,12 +17,13 @@ import org.eclipse.remote.core.RemoteServices;
import org.eclipse.remote.core.exception.RemoteConnectionException;
public class ConnectionTests extends TestCase {
private static final String USERNAME = "user"; //$NON-NLS-1$
private static final String PASSWORD = "password"; //$NON-NLS-1$
private static final String USERNAME = "test"; //$NON-NLS-1$
private static final String PASSWORD = ""; //$NON-NLS-1$
private static final String HOST = "localhost"; //$NON-NLS-1$
private IRemoteServices fRemoteServices;
private IRemoteConnection fRemoteConnection;
private IRemoteConnectionManager fRemoteConnectionManager;
public void testEnv() {
String var = fRemoteConnection.getEnv("SHELL"); //$NON-NLS-1$
@ -46,7 +39,8 @@ public class ConnectionTests extends TestCase {
assertNotNull(fRemoteConnection.getProperty("path.separator")); //$NON-NLS-1$
assertNotNull(fRemoteConnection.getProperty("line.separator")); //$NON-NLS-1$
IRemoteProcessBuilder builder = fRemoteServices.getProcessBuilder(fRemoteConnection, "env"); //$NON-NLS-1$
IRemoteProcessBuilder builder = fRemoteConnection.getProcessBuilder("env"); //$NON-NLS-1$
assertNotNull(builder);
builder.environment().put("FOO", "BAR"); //$NON-NLS-1$ //$NON-NLS-2$
builder.environment().put("USER", "FOO"); //$NON-NLS-1$ //$NON-NLS-2$
try {
@ -69,51 +63,6 @@ public class ConnectionTests extends TestCase {
}
}
public void testCopy() {
final IRemoteFileManager fileManager = fRemoteServices.getFileManager(fRemoteConnection);
final IFileSystem fileSystem = EFS.getLocalFileSystem();
final IFileStore srcFileStore = fileSystem.getStore(new Path("/tmp/log_src.txt"));
final IFileStore dstFileStore = fileManager.getResource("/tmp").getChild("log_dst.txt");
try {
srcFileStore.delete(EFS.NONE, new NullProgressMonitor());
dstFileStore.delete(EFS.NONE, new NullProgressMonitor());
OutputStream stream = srcFileStore.openOutputStream(EFS.NONE, new NullProgressMonitor());
stream.write(new byte[] { 'f', 'o', 'o', '\n' });
stream.close();
srcFileStore.copy(dstFileStore, EFS.NONE, new NullProgressMonitor());
} catch (CoreException e) {
fail(e.getMessage());
} catch (IOException e) {
fail(e.getMessage());
}
IFileInfo srcInfo = srcFileStore.fetchInfo();
IFileInfo dstInfo = dstFileStore.fetchInfo();
assertTrue(dstInfo.exists());
assertTrue(srcInfo.getLength() == dstInfo.getLength());
try {
InputStream stream = dstFileStore.openInputStream(EFS.NONE, new NullProgressMonitor());
byte[] b = new byte[4];
stream.read(b);
stream.close();
assertTrue(b[0] == 'f');
assertTrue(b[1] == 'o');
assertTrue(b[2] == 'o');
assertTrue(b[3] == '\n');
} catch (CoreException e) {
fail(e.getMessage());
} catch (IOException e) {
fail(e.getMessage());
}
try {
srcFileStore.delete(EFS.NONE, new NullProgressMonitor());
dstFileStore.delete(EFS.NONE, new NullProgressMonitor());
} catch (CoreException e) {
fail(e.getMessage());
}
}
public void testWd() {
/*
* Test connection wd
@ -127,7 +76,8 @@ public class ConnectionTests extends TestCase {
/*
* Test process builder inherits wd from connection
*/
IRemoteProcessBuilder builder = fRemoteServices.getProcessBuilder(fRemoteConnection, "pwd"); //$NON-NLS-1$
IRemoteProcessBuilder builder = fRemoteConnection.getProcessBuilder("pwd"); //$NON-NLS-1$
assertNotNull(builder);
try {
IRemoteProcess proc = builder.start();
BufferedReader stdout = new BufferedReader(new InputStreamReader(proc.getInputStream()));
@ -141,8 +91,10 @@ public class ConnectionTests extends TestCase {
/*
* Test process builder wd
*/
final IRemoteFileManager fileManager = fRemoteServices.getFileManager(fRemoteConnection);
builder = fRemoteServices.getProcessBuilder(fRemoteConnection, "pwd"); //$NON-NLS-1$
final IRemoteFileManager fileManager = fRemoteConnection.getFileManager();
assertNotNull(fileManager);
builder = fRemoteConnection.getProcessBuilder("pwd"); //$NON-NLS-1$
assertNotNull(builder);
builder.directory(fileManager.getResource("/bin"));
try {
IRemoteProcess proc = builder.start();
@ -165,11 +117,11 @@ public class ConnectionTests extends TestCase {
fRemoteServices = RemoteServices.getRemoteServices("org.eclipse.remote.JSch"); //$NON-NLS-1$
assertNotNull(fRemoteServices);
IRemoteConnectionManager connMgr = fRemoteServices.getConnectionManager();
assertNotNull(connMgr);
fRemoteConnectionManager = fRemoteServices.getConnectionManager();
assertNotNull(fRemoteConnectionManager);
try {
fRemoteConnection = connMgr.newConnection("test_connection"); //$NON-NLS-1$
fRemoteConnection = fRemoteConnectionManager.newConnection("test_connection"); //$NON-NLS-1$
} catch (RemoteConnectionException e) {
fail(e.getMessage());
}
@ -194,9 +146,7 @@ public class ConnectionTests extends TestCase {
@Override
protected void tearDown() throws Exception {
fRemoteConnection.close();
IRemoteConnectionManager connMgr = fRemoteServices.getConnectionManager();
assertNotNull(connMgr);
connMgr.removeConnection(fRemoteConnection);
fRemoteConnectionManager.removeConnection(fRemoteConnection);
}
}

View file

@ -2,6 +2,7 @@ package org.eclipse.remote.core.tests;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
@ -11,9 +12,11 @@ import java.net.URI;
import junit.framework.TestCase;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionManager;
import org.eclipse.remote.core.IRemoteFileManager;
@ -23,85 +26,92 @@ import org.eclipse.remote.core.exception.RemoteConnectionException;
public class FileStoreTests extends TestCase {
private static final String CONNECTION_NAME = "test_connection";
private static final String USERNAME = "user";
private static final String PASSWORD = "password";
private static final String USERNAME = "test";
private static final String PASSWORD = "";
private static final String HOST = "localhost";
private static final String PATH1 = "/tmp/sftp_test";
private static final String PATH2 = PATH1 + "/.file1";
private static final String LOCAL_DIR = "/tmp/ptp_" + System.getProperty("user.name") + "/filestore_tests";
private static final String REMOTE_DIR = "/tmp/ptp_" + USERNAME + "/filestore_tests";
private static final String LOCAL_FILE = "local_file";
private static final String REMOTE_FILE = "remote_file";
private static final String TEST_STRING = "a string containing fairly *()(*&^$%## random text";
private IRemoteServices fRemoteServices;
private IRemoteConnection fRemoteConnection;
private IRemoteConnectionManager fRemoteConnectionManager;
private IRemoteFileManager fRemoteFileManager;
private IFileStore fRemoteDir;
private IFileStore fLocalDir;
public void testFileStore() {
URI path1Uri = fRemoteFileManager.toURI(PATH1);
URI path2Uri = fRemoteFileManager.toURI(PATH2);
assertNotNull(path1Uri);
assertNotNull(path2Uri);
IFileStore store1 = null;
IFileStore store2 = null;
try {
store1 = EFS.getStore(path1Uri);
store2 = EFS.getStore(path2Uri);
} catch (Exception e) {
fail(e.getLocalizedMessage());
}
public void testStreams() {
IFileStore remoteFileStore = fRemoteDir.getChild(REMOTE_FILE);
for (int i = 0; i < 5; i++) {
assertFalse(store1.fetchInfo().exists());
try {
store1.mkdir(EFS.NONE, null);
remoteFileStore.delete(EFS.NONE, null);
} catch (CoreException e) {
e.getLocalizedMessage();
fail(e.getMessage());
}
assertTrue(store1.fetchInfo().exists());
assertFalse(store2.fetchInfo().exists());
assertFalse(remoteFileStore.fetchInfo().exists());
try {
OutputStream stream = store2.openOutputStream(EFS.NONE, null);
OutputStream stream = remoteFileStore.openOutputStream(EFS.NONE, null);
assertNotNull(stream);
BufferedWriter buf = new BufferedWriter(new OutputStreamWriter(stream));
buf.write(TEST_STRING);
buf.close();
} catch (Exception e) {
e.getLocalizedMessage();
fail(e.getMessage());
}
assertTrue(store2.fetchInfo().exists());
assertTrue(remoteFileStore.fetchInfo().exists());
try {
InputStream stream = store2.openInputStream(EFS.NONE, null);
InputStream stream = remoteFileStore.openInputStream(EFS.NONE, null);
assertNotNull(stream);
BufferedReader buf = new BufferedReader(new InputStreamReader(stream));
String line = buf.readLine().trim();
assertTrue(line.equals(TEST_STRING));
buf.close();
} catch (Exception e) {
e.getLocalizedMessage();
fail(e.getMessage());
}
}
}
public void testCopy() {
final IFileStore localFileStore = fLocalDir.getChild(LOCAL_FILE);
final IFileStore remoteFileStore = fRemoteDir.getChild(REMOTE_FILE);
try {
store2.delete(EFS.NONE, null);
localFileStore.delete(EFS.NONE, new NullProgressMonitor());
remoteFileStore.delete(EFS.NONE, new NullProgressMonitor());
OutputStream stream = localFileStore.openOutputStream(EFS.NONE, new NullProgressMonitor());
stream.write(new byte[] { 'f', 'o', 'o', '\n' });
stream.close();
localFileStore.copy(remoteFileStore, EFS.NONE, new NullProgressMonitor());
} catch (CoreException e) {
e.getLocalizedMessage();
fail(e.getMessage());
} catch (IOException e) {
fail(e.getMessage());
}
assertFalse(store2.fetchInfo().exists());
IFileInfo srcInfo = localFileStore.fetchInfo();
IFileInfo dstInfo = remoteFileStore.fetchInfo();
assertTrue(dstInfo.exists());
assertTrue(srcInfo.getLength() == dstInfo.getLength());
try {
store1.delete(EFS.NONE, null);
InputStream stream = remoteFileStore.openInputStream(EFS.NONE, new NullProgressMonitor());
byte[] b = new byte[4];
stream.read(b);
stream.close();
assertTrue(b[0] == 'f');
assertTrue(b[1] == 'o');
assertTrue(b[2] == 'o');
assertTrue(b[3] == '\n');
} catch (CoreException e) {
e.getLocalizedMessage();
fail(e.getMessage());
} catch (IOException e) {
fail(e.getMessage());
}
assertFalse(store1.fetchInfo().exists());
}
}
/*
@ -114,13 +124,13 @@ public class FileStoreTests extends TestCase {
fRemoteServices = RemoteServices.getRemoteServices("org.eclipse.remote.JSch");
assertNotNull(fRemoteServices);
IRemoteConnectionManager connMgr = fRemoteServices.getConnectionManager();
assertNotNull(connMgr);
fRemoteConnectionManager = fRemoteServices.getConnectionManager();
assertNotNull(fRemoteConnectionManager);
try {
fRemoteConnection = connMgr.newConnection(CONNECTION_NAME);
fRemoteConnection = fRemoteConnectionManager.newConnection(CONNECTION_NAME);
} catch (RemoteConnectionException e) {
fail(e.getLocalizedMessage());
fail(e.getMessage());
}
assertNotNull(fRemoteConnection);
fRemoteConnection.setAddress(HOST);
@ -134,8 +144,27 @@ public class FileStoreTests extends TestCase {
}
assertTrue(fRemoteConnection.isOpen());
fRemoteFileManager = fRemoteServices.getFileManager(fRemoteConnection);
fRemoteFileManager = fRemoteConnection.getFileManager();
assertNotNull(fRemoteFileManager);
URI remoteDirUri = fRemoteFileManager.toURI(REMOTE_DIR);
URI localDirUri = fRemoteFileManager.toURI(LOCAL_DIR);
assertNotNull(remoteDirUri);
assertNotNull(localDirUri);
try {
fRemoteDir = EFS.getStore(fRemoteFileManager.toURI(REMOTE_DIR));
fLocalDir = EFS.getLocalFileSystem().getStore(new Path(LOCAL_DIR));
} catch (CoreException e) {
fail(e.getMessage());
}
try {
fRemoteDir.mkdir(EFS.NONE, null);
fLocalDir.mkdir(EFS.NONE, null);
} catch (CoreException e) {
fail(e.getMessage());
}
}
/*
@ -145,10 +174,10 @@ public class FileStoreTests extends TestCase {
*/
@Override
protected void tearDown() throws Exception {
fRemoteDir.delete(EFS.NONE, new NullProgressMonitor());
fLocalDir.delete(EFS.NONE, new NullProgressMonitor());
fRemoteConnection.close();
IRemoteConnectionManager connMgr = fRemoteServices.getConnectionManager();
assertNotNull(connMgr);
connMgr.removeConnection(fRemoteConnection);
fRemoteConnectionManager.removeConnection(fRemoteConnection);
}
}

View file

@ -19,8 +19,8 @@ import org.eclipse.remote.core.RemoteServices;
import org.eclipse.remote.core.exception.RemoteConnectionException;
public class ProcessTests extends TestCase {
private static final String USERNAME = "user"; //$NON-NLS-1$
private static final String PASSWORD = "password"; //$NON-NLS-1$
private static final String USERNAME = "test"; //$NON-NLS-1$
private static final String PASSWORD = ""; //$NON-NLS-1$
private static final String HOST = "localhost"; //$NON-NLS-1$
private static int NUM_THREADS = 5;
@ -35,7 +35,8 @@ public class ProcessTests extends TestCase {
Thread thread = new Thread("test thread " + t) {
@Override
public void run() {
IRemoteProcessBuilder builder = fRemoteServices.getProcessBuilder(fRemoteConnection, "perl", "-V:version"); //$NON-NLS-1$
IRemoteProcessBuilder builder = fRemoteConnection.getProcessBuilder("perl", "-V:version"); //$NON-NLS-1$
assertNotNull(builder);
builder.redirectErrorStream(true);
for (int i = 0; i < 10; i++) {
try {
@ -71,7 +72,8 @@ public class ProcessTests extends TestCase {
}
public void testEnv() {
IRemoteProcessBuilder builder = fRemoteServices.getProcessBuilder(fRemoteConnection, "printenv"); //$NON-NLS-1$
IRemoteProcessBuilder builder = fRemoteConnection.getProcessBuilder("printenv"); //$NON-NLS-1$
assertNotNull(builder);
builder.redirectErrorStream(true);
String path = builder.environment().get("PATH");
builder.environment().clear();

View file

@ -10,7 +10,9 @@
*******************************************************************************/
package org.eclipse.internal.remote.core.services.local;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IPath;
@ -22,6 +24,9 @@ import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionChangeEvent;
import org.eclipse.remote.core.IRemoteConnectionChangeListener;
import org.eclipse.remote.core.IRemoteConnectionManager;
import org.eclipse.remote.core.IRemoteFileManager;
import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.IRemoteProcessBuilder;
import org.eclipse.remote.core.IRemoteServices;
import org.eclipse.remote.core.IUserAuthenticator;
import org.eclipse.remote.core.exception.RemoteConnectionException;
@ -34,6 +39,7 @@ public class LocalConnection implements IRemoteConnection {
private boolean fConnected = true;
private IPath fWorkingDir = null;
private final IRemoteFileManager fFileMgr = new LocalFileManager();
private final IRemoteConnection fConnection = this;
private final IRemoteServices fRemoteServices;
private final ListenerList fListeners = new ListenerList();
@ -67,6 +73,28 @@ public class LocalConnection implements IRemoteConnection {
}
}
/**
* Notify all listeners when this connection's status changes.
*
* @param event
*/
private void fireConnectionChangeEvent(final int type) {
IRemoteConnectionChangeEvent event = new IRemoteConnectionChangeEvent() {
@Override
public IRemoteConnection getConnection() {
return fConnection;
}
@Override
public int getType() {
return type;
}
};
for (Object listener : fListeners.getListeners()) {
((IRemoteConnectionChangeListener) listener).connectionChanged(event);
}
}
/*
* (non-Javadoc)
*
@ -133,6 +161,16 @@ public class LocalConnection implements IRemoteConnection {
return new HashMap<String, String>();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteServices#getCommandShell(int)
*/
@Override
public IRemoteProcess getCommandShell(int flags) throws IOException {
throw new IOException("Not currently implemented"); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
@ -154,6 +192,16 @@ public class LocalConnection implements IRemoteConnection {
return System.getenv(name);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteServices#getFileManager(j)
*/
@Override
public IRemoteFileManager getFileManager() {
return fFileMgr;
}
/*
* (non-Javadoc)
*
@ -174,6 +222,26 @@ public class LocalConnection implements IRemoteConnection {
return 0;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteServices#getProcessBuilder(java.util.List)
*/
@Override
public IRemoteProcessBuilder getProcessBuilder(List<String> command) {
return new LocalProcessBuilder(command);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteServices#getProcessBuilder(java.lang.String[])
*/
@Override
public IRemoteProcessBuilder getProcessBuilder(String... command) {
return new LocalProcessBuilder(command);
}
/*
* (non-Javadoc)
*
@ -392,26 +460,4 @@ public class LocalConnection implements IRemoteConnection {
return false;
}
/**
* Notify all listeners when this connection's status changes.
*
* @param event
*/
private void fireConnectionChangeEvent(final int type) {
IRemoteConnectionChangeEvent event = new IRemoteConnectionChangeEvent() {
@Override
public IRemoteConnection getConnection() {
return fConnection;
}
@Override
public int getType() {
return type;
}
};
for (Object listener : fListeners.getListeners()) {
((IRemoteConnectionChangeListener) listener).connectionChanged(event);
}
}
}

View file

@ -20,47 +20,52 @@ import org.eclipse.core.runtime.Path;
import org.eclipse.remote.core.IRemoteFileManager;
public class LocalFileManager implements IRemoteFileManager {
private final LocalConnection fConnection;
public LocalFileManager(LocalConnection conn) {
fConnection = conn;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteFileManager#getDirectorySeparator()
*/
@Override
public String getDirectorySeparator() {
return System.getProperty("file.separator", "/"); //$NON-NLS-1$ //$NON-NLS-2$
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteFileManager#getResource(java.lang.String)
*/
public IFileStore getResource(String pathStr) {
IPath path = new Path(pathStr);
if (!path.isAbsolute()) {
path = new Path(fConnection.getWorkingDirectory()).append(path);
}
return EFS.getLocalFileSystem().getStore(path);
@Override
public IFileStore getResource(String path) {
return EFS.getLocalFileSystem().getStore(new Path(path));
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteFileManager#toPath(java.net.URI)
*/
@Override
public String toPath(URI uri) {
return URIUtil.toPath(uri).toString();
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteFileManager#toURI(org.eclipse.core.runtime.IPath)
*/
@Override
public URI toURI(IPath path) {
return URIUtil.toURI(path);
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteFileManager#toURI(java.lang.String)
*/
@Override
public URI toURI(String path) {
return URIUtil.toURI(path);
}

View file

@ -31,7 +31,6 @@ import org.eclipse.core.runtime.Platform;
import org.eclipse.internal.remote.core.RemoteCorePlugin;
import org.eclipse.remote.core.AbstractRemoteProcessBuilder;
import org.eclipse.remote.core.IProcessFactory;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteProcess;
public class LocalProcessBuilder extends AbstractRemoteProcessBuilder {
@ -41,14 +40,14 @@ public class LocalProcessBuilder extends AbstractRemoteProcessBuilder {
private final IProcessFactory fProcessFactory;
private final Map<String, String> fRemoteEnv = new HashMap<String, String>();
public LocalProcessBuilder(IRemoteConnection conn, List<String> command) {
super(conn, command);
public LocalProcessBuilder(List<String> command) {
super(command);
fRemoteEnv.putAll(System.getenv());
fProcessFactory = getProcessFactory();
}
public LocalProcessBuilder(IRemoteConnection conn, String... command) {
this(conn, Arrays.asList(command));
public LocalProcessBuilder(String... command) {
this(Arrays.asList(command));
}
/*
@ -60,9 +59,12 @@ public class LocalProcessBuilder extends AbstractRemoteProcessBuilder {
public IFileStore directory() {
IFileStore dir = super.directory();
if (dir == null) {
dir = EFS.getLocalFileSystem().getStore(new Path(connection().getWorkingDirectory()));
String userDir = System.getProperty("user.dir"); //$NON-NLS-1$
if (userDir != null) {
dir = EFS.getLocalFileSystem().getStore(new Path(userDir));
directory(dir);
}
}
return dir;
}

View file

@ -10,22 +10,14 @@
*******************************************************************************/
package org.eclipse.internal.remote.core.services.local;
import java.io.IOException;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionManager;
import org.eclipse.remote.core.IRemoteFileManager;
import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.IRemoteProcessBuilder;
import org.eclipse.remote.core.IRemoteServices;
import org.eclipse.remote.core.IRemoteServicesDescriptor;
public class LocalServices implements IRemoteServices {
public static final String LocalServicesId = "org.eclipse.remote.LocalServices"; //$NON-NLS-1$
private IRemoteFileManager fFileMgr = null;
private final IRemoteConnectionManager fConnMgr = new LocalConnectionManager(this);
private final IRemoteServicesDescriptor fDescriptor;
@ -45,16 +37,6 @@ public class LocalServices implements IRemoteServices {
return fDescriptor.canCreateConnections();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteServices#getCommandShell(org.eclipse.remote.core.IRemoteConnection, int)
*/
@Override
public IRemoteProcess getCommandShell(IRemoteConnection conn, int flags) throws IOException {
throw new IOException("Not currently implemented"); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
@ -67,24 +49,6 @@ public class LocalServices implements IRemoteServices {
return fConnMgr;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.remote.core.IRemoteServicesDescriptor#getFileManager(
* org.eclipse.remote.core.IRemoteConnection)
*/
@Override
public IRemoteFileManager getFileManager(IRemoteConnection conn) {
if (!(conn instanceof LocalConnection)) {
return null;
}
if (fFileMgr == null) {
fFileMgr = new LocalFileManager((LocalConnection) conn);
}
return fFileMgr;
}
/*
* (non-Javadoc)
*
@ -105,30 +69,6 @@ public class LocalServices implements IRemoteServices {
return fDescriptor.getName();
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.remote.core.IRemoteServicesDescriptor#getProcessBuilder
* (org.eclipse.remote.core.IRemoteConnection, java.util.List)
*/
@Override
public IRemoteProcessBuilder getProcessBuilder(IRemoteConnection conn, List<String> command) {
return new LocalProcessBuilder(conn, command);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.remote.core.IRemoteServicesDescriptor#getProcessBuilder
* (org.eclipse.remote.core.IRemoteConnection, java.lang.String[])
*/
@Override
public IRemoteProcessBuilder getProcessBuilder(IRemoteConnection conn, String... command) {
return new LocalProcessBuilder(conn, command);
}
/*
* (non-Javadoc)
*
@ -139,18 +79,6 @@ public class LocalServices implements IRemoteServices {
return fDescriptor.getScheme();
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.remote.core.IRemoteServicesDescriptor#getServicesExtension
* (org.eclipse.remote.core.IRemoteConnection, java.lang.Class)
*/
@SuppressWarnings({ "rawtypes" })
public Object getServicesExtension(IRemoteConnection conn, Class extension) {
return null;
}
/*
* (non-Javadoc)
*

View file

@ -25,17 +25,15 @@ import org.eclipse.core.filesystem.IFileStore;
*/
public abstract class AbstractRemoteProcessBuilder implements IRemoteProcessBuilder {
private List<String> fCommandArgs;
private IRemoteConnection fRemoteConnection;
private IFileStore fRemoteDir = null;
private boolean fRedirectErrorStream = false;
public AbstractRemoteProcessBuilder(IRemoteConnection conn, List<String> command) {
fRemoteConnection = conn;
public AbstractRemoteProcessBuilder(List<String> command) {
fCommandArgs = command;
}
public AbstractRemoteProcessBuilder(IRemoteConnection conn, String... command) {
this(conn, Arrays.asList(command));
public AbstractRemoteProcessBuilder(String... command) {
this(Arrays.asList(command));
}
/*
@ -73,29 +71,6 @@ public abstract class AbstractRemoteProcessBuilder implements IRemoteProcessBuil
return this;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteProcessBuilder#connection()
*/
@Override
public IRemoteConnection connection() {
return fRemoteConnection;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.remote.core.IRemoteProcessBuilder#connection(org.eclipse
* .ptp.remote.core.IRemoteConnection)
*/
@Override
public IRemoteProcessBuilder connection(IRemoteConnection conn) {
fRemoteConnection = conn;
return this;
}
/*
* (non-Javadoc)
*

View file

@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.remote.core;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
@ -126,6 +128,27 @@ public interface IRemoteConnection {
*/
public Map<String, String> getAttributes();
/**
* Get a remote process that runs a command shell on the remote system. The shell will be the user's default shell on the remote
* system. The flags may be used to modify behavior of the remote process. These flags may only be supported by specific types
* of remote service providers. Clients can use {@link IRemoteProcessBuilder#getSupportedFlags()} to find out the flags
* supported by the service provider.
*
* <pre>
* Current flags are:
* {@link IRemoteProcessBuilder#NONE} - disable any flags
* {@link IRemoteProcessBuilder#ALLOCATE_PTY} - allocate a pseudo-terminal for the process (RFC-4254 Sec. 6.2)
* {@link IRemoteProcessBuilder#FORWARD_X11} - enable X11 forwarding (RFC-4254 Sec. 6.3)
* </pre>
*
* @param flags
* bitwise-or of flags
* @return remote process object
* @throws IOException
* @since 7.0
*/
public IRemoteProcess getCommandShell(int flags) throws IOException;
/**
* Returns an unmodifiable string map view of the remote environment. The connection must be open prior to calling this method.
*
@ -143,6 +166,13 @@ public interface IRemoteConnection {
*/
public String getEnv(String name);
/**
* Get a file manager for managing remote files
*
* @return file manager or null if connection is not open
*/
public IRemoteFileManager getFileManager();
/**
* Get unique name for this connection.
*
@ -159,6 +189,20 @@ public interface IRemoteConnection {
*/
public int getPort();
/**
* Get a process builder for creating remote processes
*
* @return process builder or null if connection is not open
*/
public IRemoteProcessBuilder getProcessBuilder(List<String> command);
/**
* Get a process builder for creating remote processes
*
* @return process builder or null if connection is not open
*/
public IRemoteProcessBuilder getProcessBuilder(String... command);
/**
* Gets the remote system property indicated by the specified key. The connection must be open prior to calling this method.
*

View file

@ -64,20 +64,6 @@ public interface IRemoteProcessBuilder {
*/
public IRemoteProcessBuilder command(String... command);
/**
* Returns this process builder's connection.
*
* @return the connection used by this process builder
*/
public IRemoteConnection connection();
/**
* Sets this process builder's connection.
*
* @return This process builder
*/
public IRemoteProcessBuilder connection(IRemoteConnection conn);
/**
* Returns this process builder's working directory.
*

View file

@ -10,9 +10,6 @@
*******************************************************************************/
package org.eclipse.remote.core;
import java.io.IOException;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
/**
@ -27,56 +24,6 @@ public interface IRemoteServices extends IRemoteServicesDescriptor {
*/
public IRemoteConnectionManager getConnectionManager();
/**
* Get a file manager for managing remote files
*
* @param conn
* connection to use for managing files
* @return file manager or null if services are not initialized
*/
public IRemoteFileManager getFileManager(IRemoteConnection conn);
/**
* Get a process builder for creating remote processes
*
* @param conn
* connection to use for creating remote processes
* @return process builder or null if services are not initialized
*/
public IRemoteProcessBuilder getProcessBuilder(IRemoteConnection conn, List<String> command);
/**
* Get a process builder for creating remote processes
*
* @param conn
* connection to use for creating remote processes
* @return process builder or null if services are not initialized
*/
public IRemoteProcessBuilder getProcessBuilder(IRemoteConnection conn, String... command);
/**
* Get a remote process that runs a command shell on the remote system. The shell will be the user's default shell on the remote
* system. The flags may be used to modify behavior of the remote process. These flags may only be supported by specific types
* of remote service providers. Clients can use {@link IRemoteProcessBuilder#getSupportedFlags()} to find out the flags
* supported by the service provider.
*
* <pre>
* Current flags are:
* {@link IRemoteProcessBuilder#NONE} - disable any flags
* {@link IRemoteProcessBuilder#ALLOCATE_PTY} - allocate a pseudo-terminal for the process (RFC-4254 Sec. 6.2)
* {@link IRemoteProcessBuilder#FORWARD_X11} - enable X11 forwarding (RFC-4254 Sec. 6.3)
* </pre>
*
* @param conn
* connection used for creating the remote process
* @param flags
* bitwise-or of flags
* @return remote process object
* @throws IOException
* @since 7.0
*/
public IRemoteProcess getCommandShell(IRemoteConnection conn, int flags) throws IOException;
/**
* Initialize the remote service. Clients should not call this method (it is called internally.)
*

View file

@ -74,7 +74,7 @@ public class RemoteServicesUtils {
if (remoteConnectionManager != null) {
IRemoteConnection remoteConnection = remoteConnectionManager.getConnection(connectionName);
if (remoteConnection != null) {
IRemoteFileManager remoteFileManager = remoteServices.getFileManager(remoteConnection);
IRemoteFileManager remoteFileManager = remoteConnection.getFileManager();
if (remoteFileManager != null) {
return remoteFileManager.getResource(path);
}

View file

@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.internal.remote.jsch.core;
import java.io.IOException;
import java.net.PasswordAuthentication;
import java.util.ArrayList;
import java.util.Collections;
@ -28,6 +29,9 @@ import org.eclipse.jsch.core.IJSchService;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionChangeEvent;
import org.eclipse.remote.core.IRemoteConnectionChangeListener;
import org.eclipse.remote.core.IRemoteFileManager;
import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.IRemoteProcessBuilder;
import org.eclipse.remote.core.IRemoteServices;
import org.eclipse.remote.core.IUserAuthenticator;
import org.eclipse.remote.core.exception.AddressInUseException;
@ -55,13 +59,14 @@ public class JSchConnection implements IRemoteConnection {
private int fPort = DEFAULT_PORT;
private String fConnName;
private boolean fIsOpen;
private IUserAuthenticator fAuthenticator;
private final IJSchService fJSchService;
private final IRemoteServices fRemoteServices;
private final ListenerList fListeners = new ListenerList();
private final List<Session> fSessions = new ArrayList<Session>();
private ChannelSftp fSftpChannel;
public JSchConnection(String name, IRemoteServices services) {
fConnName = name;
fRemoteServices = services;
@ -78,6 +83,35 @@ public class JSchConnection implements IRemoteConnection {
fListeners.add(listener);
}
private boolean checkConfiguration(Session session, IProgressMonitor monitor) throws RemoteConnectionException {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
ChannelSftp sftp;
try {
/*
* First, check if sftp is supported at all. This is required for EFS, so throw exception if not supported.
*/
sftp = openSftpChannel(session);
} catch (RemoteConnectionException e) {
throw new RemoteConnectionException(Messages.JSchConnection_Remote_host_does_not_support_sftp);
}
/*
* While sftp channel is open, try opening an exec channel. If it doesn't succeed, then MaxSession is < 2 so we need at
* least one additional session.
*/
try {
loadEnv(subMon.newChild(10));
} catch (RemoteConnectionException e) {
if (e.getMessage().contains("channel is not opened")) { //$NON-NLS-1$
return false;
}
} finally {
if (sftp != null) {
sftp.disconnect();
}
}
return true;
}
/**
* @throws RemoteConnectionException
*/
@ -97,6 +131,9 @@ public class JSchConnection implements IRemoteConnection {
*/
public synchronized void close() {
if (isOpen()) {
if (fSftpChannel != null && fSftpChannel.isConnected()) {
fSftpChannel.disconnect();
}
for (Session session : fSessions) {
if (session.isConnected()) {
session.disconnect();
@ -246,6 +283,15 @@ public class JSchConnection implements IRemoteConnection {
return Collections.unmodifiableMap(fProperties);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteServices#getCommandShell(int)
*/
public IRemoteProcess getCommandShell(int flags) throws IOException {
throw new IOException("Not currently implemented"); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
@ -255,19 +301,6 @@ public class JSchConnection implements IRemoteConnection {
return Collections.unmodifiableMap(fEnv);
}
private void loadEnv(IProgressMonitor monitor) throws RemoteConnectionException {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
ExecCommand exec = new ExecCommand(this);
String env = exec.setCommand("printenv").getResult(subMon.newChild(10)).trim(); //$NON-NLS-1$
String[] vars = env.split("\n"); //$NON-NLS-1$
for (String var : vars) {
String[] kv = var.split("="); //$NON-NLS-1$
if (kv.length == 2) {
fEnv.put(kv[0], kv[1]);
}
}
}
/*
* (non-Javadoc)
*
@ -277,6 +310,31 @@ public class JSchConnection implements IRemoteConnection {
return getEnv().get(name);
}
/**
* Open an exec channel to the remote host.
*
* @return exec channel or null if the progress monitor was cancelled
*
* @throws RemoteConnectionException
* if a channel could not be opened
*/
public ChannelExec getExecChannel() throws RemoteConnectionException {
try {
return (ChannelExec) fSessions.get(0).openChannel("exec"); //$NON-NLS-1$
} catch (JSchException e) {
throw new RemoteConnectionException(e.getMessage());
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteServices#getFileManager()
*/
public IRemoteFileManager getFileManager() {
return new JSchFileManager(this);
}
/*
* (non-Javadoc)
*
@ -295,6 +353,121 @@ public class JSchConnection implements IRemoteConnection {
return fPort;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteServices#getProcessBuilder(java.util.List)
*/
public IRemoteProcessBuilder getProcessBuilder(List<String> command) {
return new JSchProcessBuilder(this, command);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteServices#getProcessBuilder(java.lang.String[])
*/
public IRemoteProcessBuilder getProcessBuilder(String... command) {
return new JSchProcessBuilder(this, command);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection#getProperty(java.lang.String )
*/
public String getProperty(String key) {
return fProperties.get(key);
}
/**
* Get the result of executing a pwd command.
*
* @return current working directory
*/
private String getPwd() {
return null; // TODO: implement
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection#getRemoteServices()
*/
public IRemoteServices getRemoteServices() {
return fRemoteServices;
}
/**
* Open an sftp channel to the remote host. Always use the second session if available.
*
* @return sftp channel or null if the progress monitor was cancelled
* @throws RemoteConnectionException
* if a channel could not be opened
*/
public ChannelSftp getSftpChannel() throws RemoteConnectionException {
if (fSftpChannel == null || fSftpChannel.isClosed()) {
Session session = fSessions.get(0);
if (fSessions.size() > 1) {
session = fSessions.get(1);
}
fSftpChannel = openSftpChannel(session);
if (fSftpChannel == null) {
throw new RemoteConnectionException(Messages.JSchConnection_Unable_to_open_sftp_channel);
}
}
return fSftpChannel;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection#getUsername()
*/
public String getUsername() {
return fUsername;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection#getWorkingDirectory()
*/
public String getWorkingDirectory() {
if (!isOpen()) {
return "/"; //$NON-NLS-1$
}
if (fWorkingDir == null) {
fWorkingDir = getPwd();
if (fWorkingDir == null) {
return "/"; //$NON-NLS-1$
}
}
return fWorkingDir;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection#isOpen()
*/
public boolean isOpen() {
return fIsOpen;
}
private void loadEnv(IProgressMonitor monitor) throws RemoteConnectionException {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
ExecCommand exec = new ExecCommand(this);
String env = exec.setCommand("printenv").getResult(subMon.newChild(10)).trim(); //$NON-NLS-1$
String[] vars = env.split("\n"); //$NON-NLS-1$
for (String var : vars) {
String[] kv = var.split("="); //$NON-NLS-1$
if (kv.length == 2) {
fEnv.put(kv[0], kv[1]);
}
}
}
/**
*
* Load the following hard-coded properties at runtime:
@ -390,78 +563,6 @@ public class JSchConnection implements IRemoteConnection {
fProperties.put(OS_ARCH_PROPERTY, osArch);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection#getProperty(java.lang.String )
*/
public String getProperty(String key) {
return fProperties.get(key);
}
/**
* Get the result of executing a pwd command.
*
* @return current working directory
*/
private String getPwd() {
return null; // TODO: implement
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection#getRemoteServices()
*/
public IRemoteServices getRemoteServices() {
return fRemoteServices;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection#getUsername()
*/
public String getUsername() {
return fUsername;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection#getWorkingDirectory()
*/
public String getWorkingDirectory() {
if (!isOpen()) {
return "/"; //$NON-NLS-1$
}
if (fWorkingDir == null) {
fWorkingDir = getPwd();
if (fWorkingDir == null) {
return "/"; //$NON-NLS-1$
}
}
return fWorkingDir;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection#isOpen()
*/
public boolean isOpen() {
return fIsOpen;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection#open()
*/
public void open(IProgressMonitor monitor) throws RemoteConnectionException {
open(null, monitor);
}
private Session newSession(final IUserAuthenticator authenticator, IProgressMonitor monitor) throws RemoteConnectionException {
SubMonitor progress = SubMonitor.convert(monitor, 10);
try {
@ -510,7 +611,6 @@ public class JSchConnection implements IRemoteConnection {
fJSchService.connect(session, 0, progress.newChild(10));
if (!progress.isCanceled()) {
fSessions.add(session);
fAuthenticator = authenticator;
return session;
}
return null;
@ -519,72 +619,13 @@ public class JSchConnection implements IRemoteConnection {
}
}
private ChannelSftp fSftpChannel;
private ChannelExec fExecChannel;
/**
* Open an sftp channel to the remote host. Always use the second session if available.
/*
* (non-Javadoc)
*
* @return sftp channel or null if the progress monitor was cancelled
* @throws RemoteConnectionException
* if a channel could not be opened
* @see org.eclipse.remote.core.IRemoteConnection#open()
*/
public ChannelSftp getSftpChannel() throws RemoteConnectionException {
Session session = fSessions.get(0);
if (fSessions.size() > 1) {
session = fSessions.get(1);
}
ChannelSftp channel = openSftpChannel(session);
if (channel == null) {
throw new RemoteConnectionException("Unable to open sftp channel: check sftp is enabled on remote host");
}
return channel;
}
private ChannelSftp openSftpChannel(Session session) throws RemoteConnectionException {
try {
ChannelSftp channel = (ChannelSftp) session.openChannel("sftp"); //$NON-NLS-1$
channel.connect();
return channel;
} catch (JSchException e) {
if (!e.getMessage().contains("channel is not opened")) { //$NON-NLS-1$
throw new RemoteConnectionException(e.getMessage());
}
}
return null;
}
private ChannelExec openExecChannel(Session[] sessions) throws RemoteConnectionException {
for (Session session : sessions) {
try {
ChannelExec channel = (ChannelExec) session.openChannel("exec"); //$NON-NLS-1$
if (!channel.isConnected()) {
channel.connect();
return channel;
}
} catch (JSchException e) {
if (!e.getMessage().contains("channel is not opened")) { //$NON-NLS-1$
throw new RemoteConnectionException(e.getMessage());
}
}
}
return null;
}
/**
* Open an exec channel to the remote host.
*
* @return exec channel or null if the progress monitor was cancelled
*
* @throws RemoteConnectionException
* if a channel could not be opened
*/
public ChannelExec getExecChannel() throws RemoteConnectionException {
try {
return (ChannelExec) fSessions.get(0).openChannel("exec"); //$NON-NLS-1$
} catch (JSchException e) {
throw new RemoteConnectionException(e.getMessage());
}
public void open(IProgressMonitor monitor) throws RemoteConnectionException {
open(null, monitor);
}
/*
@ -610,30 +651,15 @@ public class JSchConnection implements IRemoteConnection {
}
}
private boolean checkConfiguration(Session session, IProgressMonitor monitor) throws RemoteConnectionException {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
/*
* First, check if sftp is supported at all. This is required for EFS, so throw exception if not supported.
*/
ChannelSftp sftp = openSftpChannel(session);
if (sftp == null) {
throw new RemoteConnectionException(
"Remote host does not support sftp. Remote functionality requires sftp to be enabled");
}
/*
* While sftp channel is open, try opening an exec channel. If it doesn't succeed, then MaxSession is < 2 so we need at
* least one additional session.
*/
private ChannelSftp openSftpChannel(Session session) throws RemoteConnectionException {
try {
loadEnv(subMon.newChild(10));
} catch (RemoteConnectionException e) {
if (e.getMessage().contains("channel is not opened")) {
return false;
ChannelSftp channel = (ChannelSftp) session.openChannel("sftp"); //$NON-NLS-1$
channel.connect();
return channel;
} catch (JSchException e) {
throw new RemoteConnectionException(e.getMessage());
}
}
sftp.disconnect();
return true;
}
/*
* (non-Javadoc)

View file

@ -20,8 +20,8 @@ import org.eclipse.remote.core.IRemoteFileManager;
public class JSchFileManager implements IRemoteFileManager {
private final JSchConnection fConnection;
public JSchFileManager(JSchConnection conn) {
fConnection = conn;
public JSchFileManager(JSchConnection connection) {
fConnection = connection;
}
/*
@ -49,7 +49,7 @@ public class JSchFileManager implements IRemoteFileManager {
if (!path.isAbsolute()) {
path = new Path(fConnection.getWorkingDirectory()).append(path);
}
return new JschFileStore(fConnection, path.toString());
return new JschFileStore(JSchFileSystem.getURIFor(fConnection.getName(), path.toString()));
}
/*

View file

@ -25,20 +25,13 @@ package org.eclipse.internal.remote.jsch.core;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.provider.FileSystem;
import org.eclipse.core.runtime.IPath;
import org.eclipse.remote.core.exception.RemoteConnectionException;
import com.jcraft.jsch.ChannelSftp;
public class JSchFileSystem extends FileSystem {
private final Map<String, ChannelSftp> fChannels = new HashMap<String, ChannelSftp>();
/**
* Return the connection name encoded in the URI.
*
@ -132,21 +125,4 @@ public class JSchFileSystem extends FileSystem {
public IFileStore getStore(IPath path) {
return null;
}
/**
* Get an sftp channel for the connection being used for the file stores. We only want one channel per connection so that all
* file stores using that connection also use the same channel.
*
* @return sftp channel or null if monitor is cancelled
* @throws RemoteConnectionException
* if a channel can't be obtained
*/
public synchronized ChannelSftp getChannel(JSchConnection connection) throws RemoteConnectionException {
ChannelSftp channel = fChannels.get(connection.getName());
if (channel == null) {
channel = connection.getSftpChannel();
fChannels.put(connection.getName(), channel);
}
return channel;
}
}

View file

@ -25,6 +25,7 @@ import java.util.Set;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.internal.remote.jsch.core.messages.Messages;
import org.eclipse.remote.core.AbstractRemoteProcessBuilder;
import org.eclipse.remote.core.IRemoteFileManager;
import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.exception.RemoteConnectionException;
@ -33,19 +34,18 @@ import com.jcraft.jsch.JSchException;
public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
private final JSchConnection fConnection;
private final JSchFileManager fFileMgr;
private final Map<String, String> fRemoteEnv;
private Map<String, String> fNewRemoteEnv = null;
private final Map<String, String> fRemoteEnv = new HashMap<String, String>();
private final Set<Character> charSet = new HashSet<Character>();
private Map<String, String> fNewRemoteEnv = null;
/**
* @since 4.0
*/
public JSchProcessBuilder(JSchConnection conn, JSchFileManager fileMgr, List<String> command) {
super(conn, command);
fConnection = conn;
fFileMgr = fileMgr;
fRemoteEnv = new HashMap<String, String>(conn.getEnv());
public JSchProcessBuilder(JSchConnection connection, List<String> command) {
super(command);
fConnection = connection;
fRemoteEnv.putAll(fConnection.getEnv());
// Create set of characters not to escape
String trustedChars = null;
@ -60,8 +60,8 @@ public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
/**
* @since 4.0
*/
public JSchProcessBuilder(JSchConnection conn, JSchFileManager fileMgr, String... command) {
this(conn, fileMgr, Arrays.asList(command));
public JSchProcessBuilder(JSchConnection connection, String... command) {
this(connection, Arrays.asList(command));
}
/*
@ -72,8 +72,9 @@ public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
@Override
public IFileStore directory() {
IFileStore dir = super.directory();
if (dir == null) {
dir = fFileMgr.getResource(connection().getWorkingDirectory());
IRemoteFileManager fileMgr = fConnection.getFileManager();
if (dir == null && fileMgr != null) {
dir = fileMgr.getResource(fConnection.getWorkingDirectory());
directory(dir);
}
return dir;
@ -177,7 +178,6 @@ public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
ChannelExec exec = fConnection.getExecChannel();
String command = buildCommand(remoteCmd, env, clearEnv);
exec.setCommand(command);
System.out.println("running command: " + command); //$NON-NLS-1$
exec.setPty((flags & ALLOCATE_PTY) == ALLOCATE_PTY);
exec.setXForwarding((flags & FORWARD_X11) == FORWARD_X11);
exec.connect();

View file

@ -10,39 +10,20 @@
*******************************************************************************/
package org.eclipse.internal.remote.jsch.core;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.remote.core.AbstractRemoteServices;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionManager;
import org.eclipse.remote.core.IRemoteFileManager;
import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.IRemoteProcessBuilder;
import org.eclipse.remote.core.IRemoteServicesDescriptor;
public class JSchServices extends AbstractRemoteServices {
public static final String JSCH_ID = "org.eclipse.remote.JSch"; //$NON-NLS-1$
private final JSchConnectionManager connMgr = new JSchConnectionManager(this);
private final Map<String, JSchFileManager> fileMgrs = new HashMap<String, JSchFileManager>();
public JSchServices(IRemoteServicesDescriptor descriptor) {
super(descriptor);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteServices#getCommandShell(org.eclipse.remote.core.IRemoteConnection, int)
*/
public IRemoteProcess getCommandShell(IRemoteConnection conn, int flags) throws IOException {
throw new IOException("Not currently implemented"); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
@ -54,44 +35,6 @@ public class JSchServices extends AbstractRemoteServices {
return connMgr;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.remote.core.IRemoteServicesDescriptor#getFileManager(
* org.eclipse.remote.core.IRemoteConnection)
*/
public IRemoteFileManager getFileManager(IRemoteConnection conn) {
JSchFileManager fileMgr = fileMgrs.get(conn.getName());
if (fileMgr == null) {
fileMgr = new JSchFileManager((JSchConnection) conn);
fileMgrs.put(conn.getName(), fileMgr);
}
return fileMgr;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.remote.core.IRemoteServicesDescriptor#getProcessBuilder
* (org.eclipse.remote.core.IRemoteConnection, java.util.List)
*/
public IRemoteProcessBuilder getProcessBuilder(IRemoteConnection conn, List<String> command) {
return new JSchProcessBuilder((JSchConnection) conn, (JSchFileManager) getFileManager(conn), command);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.remote.core.IRemoteServicesDescriptor#getProcessBuilder
* (org.eclipse.remote.core.IRemoteConnection, java.lang.String[])
*/
public IRemoteProcessBuilder getProcessBuilder(IRemoteConnection conn, String... command) {
return new JSchProcessBuilder((JSchConnection) conn, (JSchFileManager) getFileManager(conn), command);
}
/*
* (non-Javadoc)
*

View file

@ -1,19 +0,0 @@
/*******************************************************************************
* Copyright (c) 2013 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:
* IBM Corporation - Initial API and implementation
*******************************************************************************/
package org.eclipse.internal.remote.jsch.core;
import com.jcraft.jsch.ChannelExec;
public class JSchUtils {
public static String execWithOutput(ChannelExec channel, String command) {
return null;
}
}

View file

@ -57,36 +57,38 @@ public class JschFileStore extends FileStore {
synchronized (instanceMap) {
JschFileStore store = instanceMap.get(uri.toString());
if (store == null) {
IRemoteServices services = RemoteServices.getRemoteServices(uri);
assert (services instanceof JSchServices);
if (services != null) {
IRemoteConnectionManager manager = services.getConnectionManager();
if (manager != null) {
IRemoteConnection connection = manager.getConnection(uri);
if (connection != null && connection instanceof JSchConnection) {
String path = uri.getPath();
store = new JschFileStore((JSchConnection) connection, path);
store = new JschFileStore(uri);
instanceMap.put(uri.toString(), store);
}
}
}
}
return store;
}
}
private final JSchConnection fConnection;
// private final JSchConnection fConnection;
private final IPath fRemotePath;
private final URI fURI;
public JschFileStore(JSchConnection conn, String path) {
fConnection = conn;
fRemotePath = new Path(path);
public JschFileStore(URI uri) {
fURI = uri;
fRemotePath = new Path(uri.getPath());
}
private void checkConnection() throws RemoteConnectionException {
if (!fConnection.isOpen()) {
private JSchConnection checkConnection() throws RemoteConnectionException {
IRemoteServices services = RemoteServices.getRemoteServices(fURI);
assert (services instanceof JSchServices);
if (services == null) {
throw new RemoteConnectionException(NLS.bind(Messages.JschFileStore_No_remote_services_found_for_URI, fURI));
}
IRemoteConnectionManager manager = services.getConnectionManager();
assert (manager != null);
IRemoteConnection connection = manager.getConnection(fURI);
if (connection == null || !(connection instanceof JSchConnection)) {
throw new RemoteConnectionException(NLS.bind(Messages.JschFileStore_Invalid_connection_for_URI, fURI));
}
if (!connection.isOpen()) {
throw new RemoteConnectionException(Messages.JschFileStore_Connection_is_not_open);
}
return (JSchConnection) connection;
}
/*
@ -97,9 +99,9 @@ public class JschFileStore extends FileStore {
*/
@Override
public IFileInfo[] childInfos(int options, IProgressMonitor monitor) throws CoreException {
checkConnection();
JSchConnection connection = checkConnection();
SubMonitor subMon = SubMonitor.convert(monitor, 10);
ChildInfosCommand command = new ChildInfosCommand(fConnection, fRemotePath);
ChildInfosCommand command = new ChildInfosCommand(connection, fRemotePath);
return command.getResult(subMon.newChild(10));
}
@ -128,11 +130,11 @@ public class JschFileStore extends FileStore {
*/
@Override
public void delete(int options, IProgressMonitor monitor) throws CoreException {
checkConnection();
JSchConnection connection = checkConnection();
SubMonitor subMon = SubMonitor.convert(monitor, 20);
IFileInfo info = fetchInfo(EFS.NONE, subMon.newChild(10));
if (!subMon.isCanceled() && info.exists()) {
DeleteCommand command = new DeleteCommand(fConnection, fRemotePath);
DeleteCommand command = new DeleteCommand(connection, fRemotePath);
command.getResult(subMon.newChild(10));
}
}
@ -145,9 +147,9 @@ public class JschFileStore extends FileStore {
*/
@Override
public IFileInfo fetchInfo(int options, IProgressMonitor monitor) throws CoreException {
checkConnection();
JSchConnection connection = checkConnection();
SubMonitor subMon = SubMonitor.convert(monitor, 10);
FetchInfoCommand command = new FetchInfoCommand(fConnection, fRemotePath);
FetchInfoCommand command = new FetchInfoCommand(connection, fRemotePath);
return command.getResult(subMon.newChild(10));
}
@ -159,7 +161,7 @@ public class JschFileStore extends FileStore {
*/
@Override
public IFileStore getChild(String name) {
URI uri = JSchFileSystem.getURIFor(fConnection.getName(), fRemotePath.append(name).toString());
URI uri = JSchFileSystem.getURIFor(JSchFileSystem.getConnectionNameFor(fURI), fRemotePath.append(name).toString());
return JschFileStore.getInstance(uri);
}
@ -201,7 +203,7 @@ public class JschFileStore extends FileStore {
if (fRemotePath.segmentCount() > 0) {
parentPath = fRemotePath.removeLastSegments(1).toString();
}
return JschFileStore.getInstance(JSchFileSystem.getURIFor(fConnection.getName(), parentPath));
return JschFileStore.getInstance(JSchFileSystem.getURIFor(JSchFileSystem.getConnectionNameFor(fURI), parentPath));
}
/*
@ -212,7 +214,7 @@ public class JschFileStore extends FileStore {
*/
@Override
public IFileStore mkdir(int options, IProgressMonitor monitor) throws CoreException {
checkConnection();
JSchConnection connection = checkConnection();
SubMonitor subMon = SubMonitor.convert(monitor, 20);
IFileInfo info = fetchInfo(EFS.NONE, subMon.newChild(10));
@ -227,7 +229,7 @@ public class JschFileStore extends FileStore {
}
}
MkdirCommand command = new MkdirCommand(fConnection, fRemotePath);
MkdirCommand command = new MkdirCommand(connection, fRemotePath);
command.getResult(subMon.newChild(10));
} else if (!info.isDirectory()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRONG_TYPE, NLS.bind(
@ -246,7 +248,7 @@ public class JschFileStore extends FileStore {
*/
@Override
public InputStream openInputStream(int options, IProgressMonitor monitor) throws CoreException {
checkConnection();
JSchConnection connection = checkConnection();
SubMonitor subMon = SubMonitor.convert(monitor, 30);
IFileInfo info = fetchInfo(EFS.NONE, subMon.newChild(10));
if (!subMon.isCanceled()) {
@ -258,7 +260,7 @@ public class JschFileStore extends FileStore {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRONG_TYPE, NLS.bind(
Messages.JschFileStore_Is_a_directory, fRemotePath.toString()), null));
}
GetInputStreamCommand command = new GetInputStreamCommand(fConnection, fRemotePath);
GetInputStreamCommand command = new GetInputStreamCommand(connection, fRemotePath);
return command.getResult(subMon.newChild(10));
}
return null;
@ -272,7 +274,7 @@ public class JschFileStore extends FileStore {
*/
@Override
public OutputStream openOutputStream(int options, IProgressMonitor monitor) throws CoreException {
checkConnection();
JSchConnection connection = checkConnection();
SubMonitor subMon = SubMonitor.convert(monitor, 30);
IFileInfo info = fetchInfo(EFS.NONE, subMon.newChild(10));
if (!subMon.isCanceled()) {
@ -280,7 +282,7 @@ public class JschFileStore extends FileStore {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRONG_TYPE, NLS.bind(
Messages.JschFileStore_Is_a_directory, fRemotePath.toString()), null));
}
GetOutputStreamCommand command = new GetOutputStreamCommand(fConnection, options, fRemotePath);
GetOutputStreamCommand command = new GetOutputStreamCommand(connection, options, fRemotePath);
return command.getResult(subMon.newChild(10));
}
return null;
@ -295,9 +297,9 @@ public class JschFileStore extends FileStore {
*/
@Override
public void putInfo(IFileInfo info, int options, IProgressMonitor monitor) throws CoreException {
checkConnection();
JSchConnection connection = checkConnection();
SubMonitor subMon = SubMonitor.convert(monitor, 10);
PutInfoCommand command = new PutInfoCommand(fConnection, info, options, fRemotePath);
PutInfoCommand command = new PutInfoCommand(connection, info, options, fRemotePath);
command.getResult(subMon.newChild(10));
}
@ -308,6 +310,6 @@ public class JschFileStore extends FileStore {
*/
@Override
public URI toURI() {
return JSchFileSystem.getURIFor(fConnection.getName(), fRemotePath.toString());
return fURI;
}
}

View file

@ -114,32 +114,19 @@ public abstract class AbstractRemoteCommand<T> {
}
private T1 waitCmdInThread(Future<T1> future) throws SftpException, RemoteConnectionException {
T1 ret = null;
boolean bInterrupted = Thread.interrupted();
while (!future.isDone()) {
while (!getProgressMonitor().isCanceled()) {
try {
if (getProgressMonitor().isCanceled()) {
future.cancel(true);
getChannel().quit();
throw new RemoteConnectionException(Messages.AbstractRemoteCommand_Operation_cancelled_by_user);
}
ret = future.get(100, TimeUnit.MILLISECONDS);
return future.get(100, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
bInterrupted = true;
} catch (TimeoutException e) {
// ignore
} catch (ExecutionException e) {
/*
* close sftp channel (gets
* automatically reopened) to make
* sure the channel is not in
* undefined state because of
* exception
*/
getChannel().quit();
if (e.getCause() instanceof SftpException) {
throw (SftpException) e.getCause();
}
getChannel().disconnect();
throw new RemoteConnectionException(e.getMessage());
}
getProgressMonitor().worked(1);
@ -147,7 +134,9 @@ public abstract class AbstractRemoteCommand<T> {
if (bInterrupted) {
Thread.currentThread().interrupt(); // set current thread flag
}
return ret;
future.cancel(true);
getChannel().disconnect();
throw new RemoteConnectionException(Messages.AbstractRemoteCommand_Operation_cancelled_by_user);
}
}

View file

@ -1,15 +1,14 @@
package org.eclipse.internal.remote.jsch.core.commands;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.internal.remote.jsch.core.JSchConnection;
import org.eclipse.internal.remote.jsch.core.messages.Messages;
import org.eclipse.remote.core.exception.RemoteConnectionException;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;
public class DeleteCommand extends AbstractRemoteCommand<Void> {
private final IPath fRemotePath;
@ -22,19 +21,62 @@ public class DeleteCommand extends AbstractRemoteCommand<Void> {
@Override
public Void getResult(IProgressMonitor monitor) throws RemoteConnectionException {
final SubMonitor subMon = SubMonitor.convert(monitor, 10);
SftpCallable<Void> c = new SftpCallable<Void>() {
@Override
public Void call() throws JSchException, SftpException {
getChannel().rm(fRemotePath.toString());
return null;
}
};
try {
subMon.subTask(Messages.DeleteCommand_Remove_file);
c.getResult(subMon.newChild(10));
} catch (SftpException e) {
throw new RemoteConnectionException(e.getMessage());
ExecCommand command = new ExecCommand(getConnection());
command.setCommand("/bin/rm -rf " + quote(fRemotePath.toString(), true)); //$NON-NLS-1$
String result = command.getResult(subMon.newChild(10));
if (!result.equals("")) { //$NON-NLS-1$
throw new RemoteConnectionException(result);
}
return null;
}
private String quote(String path, boolean full) {
StringBuffer buffer = new StringBuffer();
StringCharacterIterator iter = new StringCharacterIterator(path);
for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
switch (c) {
case '(':
case ')':
case '[':
case ']':
case '{':
case '}':
case '|':
case '\\':
case '*':
case '&':
case '^':
case '%':
case '$':
case '#':
case '@':
case '!':
case '~':
case '`':
case '\'':
case '"':
case ':':
case ';':
case '?':
case '<':
case '>':
case ',':
case '\n':
if (full) {
buffer.append('\\');
}
buffer.append(c);
continue;
case ' ':
buffer.append('\\');
buffer.append(c);
continue;
default:
buffer.append(c);
continue;
}
}
return buffer.toString();
}
}

View file

@ -5,6 +5,7 @@ import java.io.ByteArrayOutputStream;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.internal.remote.jsch.core.JSchConnection;
import org.eclipse.internal.remote.jsch.core.messages.Messages;
import org.eclipse.remote.core.exception.RemoteConnectionException;
import com.jcraft.jsch.JSchException;
@ -47,7 +48,7 @@ public class ExecCommand extends AbstractRemoteCommand<String> {
return stream.toString();
}
};
subMon.subTask("Exec command");
subMon.subTask(Messages.ExecCommand_Exec_command);
return c.getResult(subMon.newChild(10));
}
}

View file

@ -22,20 +22,16 @@ public class MkdirCommand extends AbstractRemoteCommand<Void> {
@Override
public Void getResult(IProgressMonitor monitor) throws RemoteConnectionException {
createDirectory(fRemotePath, monitor);
return null;
}
private void createDirectory(IPath path, IProgressMonitor monitor) throws RemoteConnectionException {
final SubMonitor subMon = SubMonitor.convert(monitor, 20);
/*
* Recursively create parent directories
*/
FetchInfoCommand command = new FetchInfoCommand(getConnection(), path.removeLastSegments(1));
FetchInfoCommand command = new FetchInfoCommand(getConnection(), fRemotePath.removeLastSegments(1));
IFileInfo info = command.getResult(subMon.newChild(10));
if (!info.exists()) {
createDirectory(path.removeLastSegments(1), subMon.newChild(10));
MkdirCommand mkdirCommand = new MkdirCommand(getConnection(), fRemotePath.removeLastSegments(1));
mkdirCommand.getResult(subMon.newChild(10));
}
/*
@ -54,5 +50,6 @@ public class MkdirCommand extends AbstractRemoteCommand<Void> {
} catch (SftpException e) {
throw new RemoteConnectionException(e.getMessage());
}
return null;
}
}

View file

@ -27,6 +27,8 @@ public class Messages extends NLS {
public static String AuthInfo_Authentication_message;
public static String ChildInfosCommand_Get_file_attributes;
public static String DeleteCommand_Remove_file;
public static String ExecCommand_Exec_command;
public static String FetchInfoCommand_Fetch_info;
public static String GetInputStreamCommand_Get_input_stream;
public static String JSchConnection_connectionNotOpen;
@ -34,6 +36,10 @@ public class Messages extends NLS {
public static String JSchConnection_remotePort;
public static String RemoteToolsConnection_open;
public static String JSchConnection_forwarding;
public static String JSchConnection_Remote_host_does_not_support_sftp;
public static String JSchConnection_Unable_to_open_sftp_channel;
public static String JSchConnection_username_must_be_set;
public static String JSchConnectionManager_connection_with_this_name_exists;
public static String JSchConnectionManager_cannotRemoveOpenConnection;
@ -43,7 +49,11 @@ public class Messages extends NLS {
public static String JschFileStore_Connection_is_not_open;
public static String JschFileStore_File_doesnt_exist;
public static String JschFileStore_Invalid_connection_for_URI;
public static String JschFileStore_Is_a_directory;
public static String JschFileStore_No_remote_services_found_for_URI;
public static String JschFileStore_The_file_of_name_already_exists;
public static String JschFileStore_The_parent_of_directory_does_not_exist;
public static String MkdirCommand_Create_directory;

View file

@ -14,6 +14,7 @@ AbstractRemoteCommand_Execution_exception=Execution exception
AuthInfo_Authentication_message=Authentication Message
ChildInfosCommand_Get_file_attributes=Get file attributes
DeleteCommand_Remove_file=Remove file
ExecCommand_Exec_command=Exec command
FetchInfoCommand_Fetch_info=Fetch info
GetInputStreamCommand_Get_input_stream=Get input stream
JSchConnection_connectionNotOpen=Connection is not open
@ -21,6 +22,8 @@ JSchConnection_remote_address_must_be_set=Remote address must be set before open
JSchConnection_remotePort=Could not allocate remote port
RemoteToolsConnection_open=Opening connection...
JSchConnection_forwarding=Setting up remote forwarding
JSchConnection_Remote_host_does_not_support_sftp=Remote host does not support sftp. Remote functionality requires sftp to be enabled
JSchConnection_Unable_to_open_sftp_channel=Unable to open sftp channel: check sftp is enabled on remote host
JSchConnection_username_must_be_set=Username must be set before opening connection
JSchConnectionManager_connection_with_this_name_exists=A connection with this name already exists
JSchConnectionManager_cannotRemoveOpenConnection=Cannot remove an open connection
@ -28,7 +31,9 @@ JSchConnectionManager_invalidConnectionType=Invalid connection type
JSchProcessBuilder_Connection_is_not_open=Connection is not open
JschFileStore_Connection_is_not_open=Connection is not open
JschFileStore_File_doesnt_exist=File {0} doesn't exist
JschFileStore_Invalid_connection_for_URI=Invalid connection for URI: "{0}"
JschFileStore_Is_a_directory={0} is a directory
JschFileStore_No_remote_services_found_for_URI=No remote services found for URI: "{0}"
JschFileStore_The_file_of_name_already_exists=A file of name {0} already exists
JschFileStore_The_parent_of_directory_does_not_exist=The parent of directory {0} does not exist
MkdirCommand_Create_directory=Create directory

View file

@ -90,7 +90,6 @@ public class RemoteResourceBrowser extends Dialog {
private String remotePaths[];
private String fInitialPath;
private IPath fRootPath;
private final IRemoteServices fServices;
private IRemoteFileManager fFileMgr;
private IRemoteConnection fConnection;
private final IRemoteUIConnectionManager fUIConnMgr;
@ -99,7 +98,6 @@ public class RemoteResourceBrowser extends Dialog {
public RemoteResourceBrowser(IRemoteServices services, IRemoteConnection conn, Shell parent, int flags) {
super(parent);
setShellStyle(SWT.RESIZE | getShellStyle());
fServices = services;
fConnection = conn;
this.optionFlags = flags;
if (conn == null) {
@ -127,7 +125,7 @@ public class RemoteResourceBrowser extends Dialog {
return false;
}
fFileMgr = fServices.getFileManager(conn);
fFileMgr = conn.getFileManager();
if (fFileMgr != null) {
/*
* Note: the call to findInitialPath must happen before the