From b9bfeab706d30d0cc234b2b6f95da0236bcad5dc Mon Sep 17 00:00:00 2001 From: Greg Watson Date: Thu, 22 Oct 2015 09:34:01 -0400 Subject: [PATCH 1/8] Bug 480259 - Up button converts path to local file system Change-Id: Ic6288d779ca79a83c71a1a54fe40e7e4570dd14a Signed-off-by: Greg Watson --- .../eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java index e4cbc359a84..d10cd2f66c5 100644 --- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java @@ -279,7 +279,7 @@ public class RemoteResourceBrowserWidget extends Composite { @Override public void widgetSelected(SelectionEvent e) { if (!fRootPath.isRoot()) { - setRoot(fRootPath.removeLastSegments(1).toOSString()); + setRoot(fRootPath.removeLastSegments(1).toString()); } } }); From 839a9b61c300cd829c8a93884b170058603b2062 Mon Sep 17 00:00:00 2001 From: Greg Watson Date: Thu, 22 Oct 2015 09:35:19 -0400 Subject: [PATCH 2/8] Bug 480314 - RemoteResourceBrowserWidget should have traverse listener Change-Id: I2750979e94e08f9a7b844ef01fd232cf6945fafe Signed-off-by: Greg Watson --- .../remote/ui/widgets/RemoteResourceBrowserWidget.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java index d10cd2f66c5..5564ecebc64 100644 --- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteResourceBrowserWidget.java @@ -61,6 +61,8 @@ import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; @@ -254,6 +256,14 @@ public class RemoteResourceBrowserWidget extends Composite { label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); fRemotePathText = new Text(textComp, SWT.BORDER | SWT.SINGLE); + fRemotePathText.addTraverseListener(new TraverseListener() { + @Override + public void keyTraversed(TraverseEvent e) { + if (e.detail == SWT.TRAVERSE_RETURN) { + e.doit = false; + } + } + }); fRemotePathText.addSelectionListener(new SelectionAdapter() { @Override public void widgetDefaultSelected(SelectionEvent e) { From 881ca83b431f3625c9aa510eec49e86ae57f5ee1 Mon Sep 17 00:00:00 2001 From: Greg Watson Date: Mon, 11 Jan 2016 09:00:19 -0500 Subject: [PATCH 3/8] Bug 485549 - prevent ArrayIndexOutOfBoundsException if no services are installed. Change-Id: I96249643103ea9427b1c5d165d8854e50984f614 Signed-off-by: Greg Watson --- .../preferences/ConnectionsPreferencePage.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/preferences/ConnectionsPreferencePage.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/preferences/ConnectionsPreferencePage.java index 8cb7e0d10f3..fe7369b1575 100644 --- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/preferences/ConnectionsPreferencePage.java +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/preferences/ConnectionsPreferencePage.java @@ -386,16 +386,18 @@ public class ConnectionsPreferencePage extends PreferencePage implements IWorkbe fCloseButton.addSelectionListener(fEventHandler); fCloseButton.setEnabled(false); - String id = Preferences.getString(IRemotePreferenceConstants.PREF_CONNECTION_TYPE_ID); - if ("".equals(id)) { //$NON-NLS-1$ - id = fServiceIDs[0]; - } - for (int i = 0; i < fServiceIDs.length; i++) { - if (id.equals(fServiceIDs[i])) { - fServicesCombo.select(i); + if (fServiceIDs.length > 0) { + String id = Preferences.getString(IRemotePreferenceConstants.PREF_CONNECTION_TYPE_ID); + if ("".equals(id)) { //$NON-NLS-1$ + id = fServiceIDs[0]; } + for (int i = 0; i < fServiceIDs.length; i++) { + if (id.equals(fServiceIDs[i])) { + fServicesCombo.select(i); + } + } + selectServices(id); } - selectServices(id); return preferencePane; } From 775acd6898a1eaa955aecaca35f57a9c082b0d6f Mon Sep 17 00:00:00 2001 From: Greg Watson Date: Wed, 13 Jan 2016 14:57:44 -0500 Subject: [PATCH 4/8] Bug 485789 - Add connection canceled message. Change-Id: Ia0a6de9f40749269649e42beb77a374277721c8b Signed-off-by: Greg Watson --- .../org/eclipse/remote/internal/jsch/core/JSchConnection.java | 3 +++ .../eclipse/remote/internal/jsch/core/messages/Messages.java | 2 ++ .../remote/internal/jsch/core/messages/messages.properties | 1 + 3 files changed, 6 insertions(+) diff --git a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchConnection.java b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchConnection.java index dee054e6300..c9e2dc11e21 100644 --- a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchConnection.java +++ b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchConnection.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.jsch.core.IJSchService; import org.eclipse.osgi.util.NLS; @@ -924,6 +925,8 @@ public class JSchConnection implements IRemoteConnectionControlService, IRemoteC return session; } return null; + } catch (OperationCanceledException e) { + throw new RemoteConnectionException(Messages.JSchConnection_0); } catch (JSchException e) { throw new RemoteConnectionException(e.getMessage()); } diff --git a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/Messages.java b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/Messages.java index 221a3e8664e..fd288be2981 100755 --- a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/Messages.java +++ b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/Messages.java @@ -26,6 +26,8 @@ public class Messages extends NLS { public static String GetInputStreamCommand_Receiving; public static String GetOutputStreamCommand_Sending; + public static String JSchConnection_0; + public static String JSchConnection_Connection_was_cancelled; public static String JSchConnection_connectionNotOpen; public static String JSchConnection_Executing_command; diff --git a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/messages.properties b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/messages.properties index b9152f94c3c..41b4506556a 100755 --- a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/messages.properties +++ b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/messages/messages.properties @@ -16,6 +16,7 @@ AuthInfo_Authentication_message=Authentication Message ExecCommand_Exec_command=Executing command "{0}" GetInputStreamCommand_Receiving=Receiving {0}: GetOutputStreamCommand_Sending=Sending {0}: +JSchConnection_0=Connection canceled by user JSchConnection_Connection_was_cancelled=Connection was cancelled JSchConnection_connectionNotOpen=Connection is not open JSchConnection_Executing_command=Executing command "{0}" From e7e4989522aa23b986f27df8271cb8ed26d715db Mon Sep 17 00:00:00 2001 From: Greg Watson Date: Thu, 14 Jan 2016 09:48:26 -0500 Subject: [PATCH 5/8] Updated version to 2.0.2 --- bundles/org.eclipse.remote.console/pom.xml | 2 +- bundles/org.eclipse.remote.core/pom.xml | 2 +- bundles/org.eclipse.remote.jsch.core/pom.xml | 2 +- bundles/org.eclipse.remote.jsch.ui/pom.xml | 2 +- bundles/org.eclipse.remote.serial.core/pom.xml | 2 +- bundles/org.eclipse.remote.serial.ui/pom.xml | 2 +- bundles/org.eclipse.remote.ui/pom.xml | 2 +- features/org.eclipse.remote-feature/feature.xml | 2 +- features/org.eclipse.remote-feature/pom.xml | 4 ++-- features/org.eclipse.remote.console-feature/feature.xml | 2 +- features/org.eclipse.remote.console-feature/pom.xml | 4 ++-- features/org.eclipse.remote.serial-feature/feature.xml | 2 +- features/org.eclipse.remote.serial-feature/pom.xml | 4 ++-- releng/org.eclipse.remote.build/pom.xml | 2 +- releng/org.eclipse.remote.repo/pom.xml | 4 ++-- 15 files changed, 19 insertions(+), 19 deletions(-) diff --git a/bundles/org.eclipse.remote.console/pom.xml b/bundles/org.eclipse.remote.console/pom.xml index 921424bb4b9..68b1b006563 100644 --- a/bundles/org.eclipse.remote.console/pom.xml +++ b/bundles/org.eclipse.remote.console/pom.xml @@ -6,7 +6,7 @@ org.eclipse.remote remote-parent - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT ../../releng/org.eclipse.remote.build/pom.xml diff --git a/bundles/org.eclipse.remote.core/pom.xml b/bundles/org.eclipse.remote.core/pom.xml index 542bfe6e278..fd41dbbc047 100644 --- a/bundles/org.eclipse.remote.core/pom.xml +++ b/bundles/org.eclipse.remote.core/pom.xml @@ -6,7 +6,7 @@ org.eclipse.remote remote-parent - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT ../../releng/org.eclipse.remote.build/pom.xml diff --git a/bundles/org.eclipse.remote.jsch.core/pom.xml b/bundles/org.eclipse.remote.jsch.core/pom.xml index a72412ad86e..13dba0b313b 100644 --- a/bundles/org.eclipse.remote.jsch.core/pom.xml +++ b/bundles/org.eclipse.remote.jsch.core/pom.xml @@ -6,7 +6,7 @@ org.eclipse.remote remote-parent - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT ../../releng/org.eclipse.remote.build/pom.xml diff --git a/bundles/org.eclipse.remote.jsch.ui/pom.xml b/bundles/org.eclipse.remote.jsch.ui/pom.xml index 8809e9f42ac..ba869d051fd 100644 --- a/bundles/org.eclipse.remote.jsch.ui/pom.xml +++ b/bundles/org.eclipse.remote.jsch.ui/pom.xml @@ -6,7 +6,7 @@ org.eclipse.remote remote-parent - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT ../../releng/org.eclipse.remote.build/pom.xml diff --git a/bundles/org.eclipse.remote.serial.core/pom.xml b/bundles/org.eclipse.remote.serial.core/pom.xml index 2dd520e9461..0bd2d60d0f8 100644 --- a/bundles/org.eclipse.remote.serial.core/pom.xml +++ b/bundles/org.eclipse.remote.serial.core/pom.xml @@ -6,7 +6,7 @@ org.eclipse.remote remote-parent - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT ../../releng/org.eclipse.remote.build/pom.xml diff --git a/bundles/org.eclipse.remote.serial.ui/pom.xml b/bundles/org.eclipse.remote.serial.ui/pom.xml index 56660ac6ea2..02a3c02ea56 100644 --- a/bundles/org.eclipse.remote.serial.ui/pom.xml +++ b/bundles/org.eclipse.remote.serial.ui/pom.xml @@ -6,7 +6,7 @@ org.eclipse.remote remote-parent - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT ../../releng/org.eclipse.remote.build/pom.xml diff --git a/bundles/org.eclipse.remote.ui/pom.xml b/bundles/org.eclipse.remote.ui/pom.xml index 851df2fb7b1..e1b823928d3 100644 --- a/bundles/org.eclipse.remote.ui/pom.xml +++ b/bundles/org.eclipse.remote.ui/pom.xml @@ -6,7 +6,7 @@ org.eclipse.remote remote-parent - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT ../../releng/org.eclipse.remote.build/pom.xml diff --git a/features/org.eclipse.remote-feature/feature.xml b/features/org.eclipse.remote-feature/feature.xml index 7deb6810a3a..bd2932c3d49 100644 --- a/features/org.eclipse.remote-feature/feature.xml +++ b/features/org.eclipse.remote-feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/features/org.eclipse.remote-feature/pom.xml b/features/org.eclipse.remote-feature/pom.xml index 9e06b29339e..2bfe5559d79 100644 --- a/features/org.eclipse.remote-feature/pom.xml +++ b/features/org.eclipse.remote-feature/pom.xml @@ -6,7 +6,7 @@ org.eclipse.remote remote-parent - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT ../../releng/org.eclipse.remote.build/pom.xml @@ -43,6 +43,6 @@ org.eclipse.remote - 2.0.1-SNAPSHOT + 2.0.2-SNAPSHOT eclipse-feature diff --git a/features/org.eclipse.remote.console-feature/feature.xml b/features/org.eclipse.remote.console-feature/feature.xml index 226d9e1f06e..14ed3912518 100644 --- a/features/org.eclipse.remote.console-feature/feature.xml +++ b/features/org.eclipse.remote.console-feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/features/org.eclipse.remote.console-feature/pom.xml b/features/org.eclipse.remote.console-feature/pom.xml index d6624198cb7..df3490c9d6b 100644 --- a/features/org.eclipse.remote.console-feature/pom.xml +++ b/features/org.eclipse.remote.console-feature/pom.xml @@ -6,13 +6,13 @@ org.eclipse.remote remote-parent - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT ../../releng/org.eclipse.remote.build/pom.xml org.eclipse.remote.features org.eclipse.remote.console - 2.0.1-SNAPSHOT + 2.0.2-SNAPSHOT eclipse-feature diff --git a/features/org.eclipse.remote.serial-feature/feature.xml b/features/org.eclipse.remote.serial-feature/feature.xml index 060d88d722c..d58a58197c0 100644 --- a/features/org.eclipse.remote.serial-feature/feature.xml +++ b/features/org.eclipse.remote.serial-feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/features/org.eclipse.remote.serial-feature/pom.xml b/features/org.eclipse.remote.serial-feature/pom.xml index fd97c11ffde..024c56c96df 100644 --- a/features/org.eclipse.remote.serial-feature/pom.xml +++ b/features/org.eclipse.remote.serial-feature/pom.xml @@ -6,13 +6,13 @@ org.eclipse.remote remote-parent - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT ../../releng/org.eclipse.remote.build/pom.xml org.eclipse.remote.features org.eclipse.remote.serial - 2.0.1-SNAPSHOT + 2.0.2-SNAPSHOT eclipse-feature diff --git a/releng/org.eclipse.remote.build/pom.xml b/releng/org.eclipse.remote.build/pom.xml index caddb2ad516..f281fac7983 100644 --- a/releng/org.eclipse.remote.build/pom.xml +++ b/releng/org.eclipse.remote.build/pom.xml @@ -10,7 +10,7 @@ org.eclipse.remote remote-parent - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT pom Remote Parent diff --git a/releng/org.eclipse.remote.repo/pom.xml b/releng/org.eclipse.remote.repo/pom.xml index 90ded07163c..a26712c3ca5 100644 --- a/releng/org.eclipse.remote.repo/pom.xml +++ b/releng/org.eclipse.remote.repo/pom.xml @@ -7,11 +7,11 @@ org.eclipse.remote remote-parent - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT ../../releng/org.eclipse.remote.build/pom.xml - 1.1.1-SNAPSHOT + 2.0.2-SNAPSHOT org.eclipse.remote.repo eclipse-repository From 1eb9e0a68335d804fcb74b9fa8b82c18e676eb2b Mon Sep 17 00:00:00 2001 From: Greg Watson Date: Thu, 14 Jan 2016 09:51:08 -0500 Subject: [PATCH 6/8] Update release and tycho versions --- releng/org.eclipse.remote.build/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/releng/org.eclipse.remote.build/pom.xml b/releng/org.eclipse.remote.build/pom.xml index f281fac7983..5910b6df4a4 100644 --- a/releng/org.eclipse.remote.build/pom.xml +++ b/releng/org.eclipse.remote.build/pom.xml @@ -15,9 +15,9 @@ Remote Parent - 2.0.1 + 2.0.2 luna - 0.20.0 + 0.24.0 ${tycho-version} scm:git:git://git.eclipse.org/gitroot/ptp/org.eclipse.remote.git 4.5milestones From b1e764a1638aeb382ff89726bee203e1fe6311d5 Mon Sep 17 00:00:00 2001 From: Greg Watson Date: Wed, 20 Jan 2016 17:28:24 -0500 Subject: [PATCH 7/8] Bug 479433 - Add better support for multiple input streams. Change-Id: I6234928c5ef6129cda3b77fd7e6467c0e817d7b4 Signed-off-by: Greg Watson --- .../internal/jsch/core/JSchConnection.java | 52 ++++--- .../core/commands/AbstractRemoteCommand.java | 4 +- .../core/commands/GetInputStreamCommand.java | 133 ++++++++++++++++-- .../remote/jsch/tests/FileStoreTests.java | 67 ++++++++- 4 files changed, 225 insertions(+), 31 deletions(-) diff --git a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchConnection.java b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchConnection.java index c9e2dc11e21..3ea70d3391e 100644 --- a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchConnection.java +++ b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/JSchConnection.java @@ -257,7 +257,7 @@ public class JSchConnection implements IRemoteConnectionControlService, IRemoteC private final Map fProperties = new HashMap(); private final List fSessions = new ArrayList(); - private ChannelSftp fSftpChannel; + private ChannelSftp fSftpCommandChannel; private boolean isFullySetup; // including sftp channel and environment private static final Map connectionMap = new HashMap<>(); @@ -363,11 +363,11 @@ public class JSchConnection implements IRemoteConnectionControlService, IRemoteC } private synchronized void cleanup() { - if (fSftpChannel != null) { - if (fSftpChannel.isConnected()) { - fSftpChannel.disconnect(); + if (fSftpCommandChannel != null) { + if (fSftpCommandChannel.isConnected()) { + fSftpCommandChannel.disconnect(); } - fSftpChannel = null; + fSftpCommandChannel = null; } for (Session session : fSessions) { if (session.isConnected()) { @@ -677,24 +677,40 @@ public class JSchConnection implements IRemoteConnectionControlService, IRemoteC } /** - * Open an sftp channel to the remote host. Always use the second session if available. + * Open an sftp command channel to the remote host. This channel is for commands that do not require any + * state being preserved and should not be closed. Long running commands (such as get/put) should use a separate channel + * obtained via {#link #newSftpChannel()}. + * + * Always use the second session if available. * - * @return sftp channel or null if the progress monitor was cancelled + * @return sftp channel * @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); - } + public ChannelSftp getSftpCommandChannel() throws RemoteConnectionException { + if (fSftpCommandChannel == null || fSftpCommandChannel.isClosed()) { + fSftpCommandChannel = newSftpChannel(); } - return fSftpChannel; + return fSftpCommandChannel; + } + + /** + * Open a channel for long running commands. This channel should be closed when the command is completed. + * + * @return sftp channel + * @throws RemoteConnectionException + * if a channel could not be opened + */ + public ChannelSftp newSftpChannel() 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(Messages.JSchConnection_Unable_to_open_sftp_channel); + } + return channel; } public Channel getStreamForwarder(String host, int port) throws RemoteConnectionException { diff --git a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/commands/AbstractRemoteCommand.java b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/commands/AbstractRemoteCommand.java index 3d49cba56e0..8649e9a62d0 100755 --- a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/commands/AbstractRemoteCommand.java +++ b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/commands/AbstractRemoteCommand.java @@ -188,7 +188,7 @@ public abstract class AbstractRemoteCommand { private ChannelSftp fSftpChannel; private Future asyncCmdInThread() throws RemoteConnectionException { - setChannel(fConnection.getSftpChannel()); + setChannel(fConnection.getSftpCommandChannel()); return fPool.submit(this); } @@ -244,7 +244,6 @@ public abstract class AbstractRemoteCommand { if (e.getCause() instanceof SftpException) { throw (SftpException) e.getCause(); } - getChannel().disconnect(); throw new RemoteConnectionException(e.getMessage()); } getProgressMonitor().worked(1); @@ -253,7 +252,6 @@ public abstract class AbstractRemoteCommand { Thread.currentThread().interrupt(); // set current thread flag } future.cancel(true); - getChannel().disconnect(); throw new RemoteConnectionException(Messages.AbstractRemoteCommand_Operation_cancelled_by_user); } } diff --git a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/commands/GetInputStreamCommand.java b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/commands/GetInputStreamCommand.java index 9c3743d3afa..aa552348c26 100644 --- a/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/commands/GetInputStreamCommand.java +++ b/bundles/org.eclipse.remote.jsch.core/src/org/eclipse/remote/internal/jsch/core/commands/GetInputStreamCommand.java @@ -11,12 +11,24 @@ import org.eclipse.remote.core.exception.RemoteConnectionException; import org.eclipse.remote.internal.jsch.core.JSchConnection; import org.eclipse.remote.internal.jsch.core.messages.Messages; +import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.SftpException; +/** + * The JSch implementation does not support multiple streams open on a single channel, so we must create a new channel for each + * subsequent stream. This has the problem that there are usually only a limited number of channels that can be opened + * simultaneously, so it is possible that this call will fail unless the open streams are closed first. + * + * This code will use the initial (command) channel first, or if that is already being used, will open a new stream. It must be + * careful not to close the command stream as other threads may still be using it. + */ public class GetInputStreamCommand extends AbstractRemoteCommand { private final IPath fRemotePath; + private static ChannelSftp commandChannel; + private ChannelSftp thisChannel; + public GetInputStreamCommand(JSchConnection connection, IPath path) { super(connection); fRemotePath = path; @@ -25,19 +37,124 @@ public class GetInputStreamCommand extends AbstractRemoteCommand { @Override public InputStream getResult(IProgressMonitor monitor) throws RemoteConnectionException { final SubMonitor subMon = SubMonitor.convert(monitor, 10); - SftpCallable c = new SftpCallable() { + + final SftpCallable c = new SftpCallable() { + private ChannelSftp newChannel() throws IOException { + synchronized (GetInputStreamCommand.class) { + if (commandChannel != null) { + try { + thisChannel = getConnection().newSftpChannel(); + return thisChannel; + } catch (RemoteConnectionException e) { + throw new IOException(e.getMessage()); + } + } + thisChannel = commandChannel = getChannel(); + return commandChannel; + } + } + @Override public InputStream call() throws JSchException, SftpException, IOException { - try { - return getConnection().getSftpChannel().get(fRemotePath.toString(), - new CommandProgressMonitor(NLS.bind(Messages.GetInputStreamCommand_Receiving, fRemotePath.toString()), getProgressMonitor())); - } catch (RemoteConnectionException e) { - throw new IOException(e.getMessage()); - } + return newChannel().get(fRemotePath.toString(), new CommandProgressMonitor( + NLS.bind(Messages.GetInputStreamCommand_Receiving, fRemotePath.toString()), getProgressMonitor())); } }; try { - return c.getResult(subMon.newChild(10)); + final InputStream stream = c.getResult(subMon.newChild(10)); + return new InputStream() { + @Override + public int read() throws IOException { + return stream.read(); + } + + /* + * (non-Javadoc) + * + * @see java.io.InputStream#close() + */ + @Override + public void close() throws IOException { + stream.close(); + synchronized (GetInputStreamCommand.class) { + if (thisChannel != commandChannel) { + thisChannel.disconnect(); + } else { + commandChannel = null; + } + } + } + + /* + * (non-Javadoc) + * + * @see java.io.InputStream#read(byte[]) + */ + @Override + public int read(byte[] b) throws IOException { + return stream.read(b); + } + + /* + * (non-Javadoc) + * + * @see java.io.InputStream#read(byte[], int, int) + */ + @Override + public int read(byte[] b, int off, int len) throws IOException { + return stream.read(b, off, len); + } + + /* + * (non-Javadoc) + * + * @see java.io.InputStream#skip(long) + */ + @Override + public long skip(long n) throws IOException { + return stream.skip(n); + } + + /* + * (non-Javadoc) + * + * @see java.io.InputStream#available() + */ + @Override + public int available() throws IOException { + return stream.available(); + } + + /* + * (non-Javadoc) + * + * @see java.io.InputStream#mark(int) + */ + @Override + public synchronized void mark(int readlimit) { + stream.mark(readlimit); + } + + /* + * (non-Javadoc) + * + * @see java.io.InputStream#reset() + */ + @Override + public synchronized void reset() throws IOException { + stream.reset(); + } + + /* + * (non-Javadoc) + * + * @see java.io.InputStream#markSupported() + */ + @Override + public boolean markSupported() { + return stream.markSupported(); + } + }; } catch (SftpException e) { throw new RemoteConnectionException(e.getMessage()); } diff --git a/tests/org.eclipse.remote.jsch.tests/src/org/eclipse/remote/jsch/tests/FileStoreTests.java b/tests/org.eclipse.remote.jsch.tests/src/org/eclipse/remote/jsch/tests/FileStoreTests.java index 8c1e3ed2504..62d0ddac2f4 100644 --- a/tests/org.eclipse.remote.jsch.tests/src/org/eclipse/remote/jsch/tests/FileStoreTests.java +++ b/tests/org.eclipse.remote.jsch.tests/src/org/eclipse/remote/jsch/tests/FileStoreTests.java @@ -9,8 +9,6 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; 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; @@ -24,6 +22,8 @@ import org.eclipse.remote.core.IRemoteFileService; import org.eclipse.remote.core.IRemoteServicesManager; import org.eclipse.remote.internal.jsch.core.JSchConnection; +import junit.framework.TestCase; + public class FileStoreTests extends TestCase { private static final String CONNECTION_NAME = "test_connection"; private static final String USERNAME = "test"; @@ -33,7 +33,9 @@ public class FileStoreTests extends TestCase { 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 REMOTE_FILE2 = "remote_file2"; private static final String TEST_STRING = "a string containing fairly *()(*&^$%## random text"; + private static final String TEST_STRING2 = "a different string containing fairly *()(*&^$%## random text"; private IRemoteConnectionType fConnectionType; private IRemoteConnection fRemoteConnection; @@ -82,6 +84,67 @@ public class FileStoreTests extends TestCase { } } + public void testMultiStreams() { + IFileStore remoteFileStore = fRemoteDir.getChild(REMOTE_FILE); + IFileStore remoteFileStore2 = fRemoteDir.getChild(REMOTE_FILE2); + + try { + createFile(remoteFileStore, TEST_STRING); + createFile(remoteFileStore2, TEST_STRING2); + } catch (Exception e) { + fail(e.getMessage()); + } + + assertTrue(remoteFileStore.fetchInfo().exists()); + assertTrue(remoteFileStore2.fetchInfo().exists()); + + /* + * Check how many streams we can open + */ + InputStream streams[] = new InputStream[100]; + int streamCount = 0; + + for (; streamCount < streams.length; streamCount++) { + try { + streams[streamCount] = remoteFileStore.openInputStream(EFS.NONE, null); + } catch (Exception e) { + if (!e.getMessage().endsWith("channel is not opened.")) { + fail(e.getMessage()); + } + break; + } + } + + for (int i = 0; i < streamCount; i++) { + try { + streams[i].close(); + } catch (IOException e) { + // No need to deal with this + } + } + + for (int i = 0; i < streamCount / 2; i++) { + try { + 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)); + + InputStream stream2 = remoteFileStore2.openInputStream(EFS.NONE, null); + assertNotNull(stream2); + BufferedReader buf2 = new BufferedReader(new InputStreamReader(stream2)); + String line2 = buf2.readLine().trim(); + assertTrue(line2.equals(TEST_STRING2)); + + stream.close(); + stream2.close(); + } catch (Exception e) { + fail(e.getMessage()); + } + } + } + public void testCopy() { final IFileStore localFileStore = fLocalDir.getChild(LOCAL_FILE); final IFileStore remoteFileStore = fRemoteDir.getChild(REMOTE_FILE); From 8ae9754935d940ee610497a2f61277c83086aa87 Mon Sep 17 00:00:00 2001 From: Greg Watson Date: Wed, 9 Mar 2016 15:09:25 -0500 Subject: [PATCH 8/8] Bug 486593 - fix encoding of connection names Change-Id: I97d77a8a3e8fcfa348fd50486eebeeecb2c24878 Signed-off-by: Greg Watson --- .../eclipse/remote/internal/core/RemoteConnection.java | 4 ++-- .../remote/internal/core/RemoteConnectionType.java | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteConnection.java b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteConnection.java index 7b447540540..3812e1895a5 100644 --- a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteConnection.java +++ b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteConnection.java @@ -114,14 +114,14 @@ public class RemoteConnection implements IRemoteConnection { throw new ConnectionExistsException(newName); } - Preferences newPrefs = connectionType.getPreferenceNode().node(newName); + Preferences newPrefs = connectionType.getPreferenceNode().node(URLEncoder.encode(newName, "UTF-8")); Preferences oldPrefs = getPreferences(); for (String key : oldPrefs.keys()) { newPrefs.put(key, oldPrefs.get(key, null)); } oldPrefs.removeNode(); - } catch (BackingStoreException e) { + } catch (BackingStoreException | UnsupportedEncodingException e) { RemoteCorePlugin.log(e); } diff --git a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteConnectionType.java b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteConnectionType.java index c7cde9b83e2..94f44aa3b03 100644 --- a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteConnectionType.java +++ b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteConnectionType.java @@ -10,7 +10,10 @@ *******************************************************************************/ package org.eclipse.remote.internal.core; +import java.io.UnsupportedEncodingException; import java.net.URI; +import java.net.URLDecoder; +import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -68,10 +71,11 @@ public class RemoteConnectionType implements IRemoteConnectionType { // load up existing connections try { - for (String connectionName : getPreferenceNode().childrenNames()) { + for (String nodeName : getPreferenceNode().childrenNames()) { + String connectionName = URLDecoder.decode(nodeName, "UTF-8"); connections.put(connectionName, new RemoteConnection(this, connectionName)); } - } catch (BackingStoreException e) { + } catch (BackingStoreException | UnsupportedEncodingException e) { RemoteCorePlugin.log(e); } }