diff --git a/bundles/org.eclipse.remote.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.remote.core/META-INF/MANIFEST.MF index 0dacec9ee70..91963849960 100644 --- a/bundles/org.eclipse.remote.core/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.remote.core/META-INF/MANIFEST.MF @@ -14,7 +14,6 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.11.0", Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.remote.core, org.eclipse.remote.core.exception, - org.eclipse.remote.core.launch, org.eclipse.remote.internal.core;x-friends:="org.eclipse.remote.ui,org.eclipse.remote.jsch.core", org.eclipse.remote.internal.core.preferences;x-friends:="org.eclipse.remote.ui" Bundle-Localization: plugin diff --git a/bundles/org.eclipse.remote.core/plugin.xml b/bundles/org.eclipse.remote.core/plugin.xml index 9753107b402..85324367874 100644 --- a/bundles/org.eclipse.remote.core/plugin.xml +++ b/bundles/org.eclipse.remote.core/plugin.xml @@ -8,7 +8,9 @@ diff --git a/bundles/org.eclipse.remote.core/schema/remoteServices.exsd b/bundles/org.eclipse.remote.core/schema/remoteServices.exsd index a8e42467cb8..3a37704fb35 100644 --- a/bundles/org.eclipse.remote.core/schema/remoteServices.exsd +++ b/bundles/org.eclipse.remote.core/schema/remoteServices.exsd @@ -84,10 +84,24 @@ - + - The capabilities of this connection. This an integer created by ORing the applicable capabilities as listed in IRemoteServices. + Can you add connections using the API. Default is true. + + + + + + + Can a connection be changed using the API. Default is true. + + + + + + + Can a connection be removed using the API. diff --git a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/core/IRemoteConnectionType.java b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/core/IRemoteConnectionType.java index 19196f0fe0a..02d155a1c72 100644 --- a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/core/IRemoteConnectionType.java +++ b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/core/IRemoteConnectionType.java @@ -38,13 +38,6 @@ public interface IRemoteConnectionType { } } - // Capabilities - static final int CAPABILITY_ADD_CONNECTIONS = 0x01; - static final int CAPABILITY_EDIT_CONNECTIONS = 0x02; - static final int CAPABILITY_REMOVE_CONNECTIONS = 0x04; - static final int CAPABILITY_SUPPORTS_TCP_PORT_FORWARDING = 0x08; - static final int CAPABILITY_SUPPORTS_X11_FORWARDING = 0x10; - /** * Get the remote services manager. This is a convenient way to get back * to the root. @@ -75,11 +68,25 @@ public interface IRemoteConnectionType { String getScheme(); /** - * Gets the capabilities of the remote service. + * Can you add new connections of this type using the API. * - * @return bit-wise or of capability flag constants + * @return can add */ - int getCapabilities(); + boolean canAdd(); + + /** + * Can you edit connections of this type, i.e. create working copies. + * + * @return can edit + */ + boolean canEdit(); + + /** + * Can you remove connections of this type using the API. + * + * @return can remove + */ + boolean canRemove(); /** * Get the service for this remote services implementation that implements the given interface. @@ -101,6 +108,13 @@ public interface IRemoteConnectionType { */ boolean hasService(Class service); + /** + * Return the list of connection type services supported by this type. + * + * @return connection type services + */ + List getServices(); + /** * Do connections created by this connection type support the given service. * @@ -110,6 +124,13 @@ public interface IRemoteConnectionType { */ boolean hasConnectionService(Class service); + /** + * Return the list of connection services supported by connections of this type. + * + * @return connection services + */ + List getConnectionServices(); + /** * Do processes created by this connection type support the given service. * @@ -119,6 +140,13 @@ public interface IRemoteConnectionType { */ boolean hasProcessService(Class service); + /** + * Return the list of process services supported by connections of this type. + * + * @return process services + */ + List getProcessServices(); + /** * Gets the remote connection corresponding to the supplied name. * diff --git a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/core/launch/IRemoteLaunchConfigService.java b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/core/launch/IRemoteLaunchConfigService.java deleted file mode 100644 index db4592a3223..00000000000 --- a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/core/launch/IRemoteLaunchConfigService.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 QNX Software Systems 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: - * QNX - initial API and implementation - *******************************************************************************/ -package org.eclipse.remote.core.launch; - -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.ILaunchConfigurationType; -import org.eclipse.remote.core.IRemoteConnection; - -/** - * Manages and persists the mapping between launch configurations and - * remote connections that they run on. Each launch configuration has an - * active remote connection. - * - * @since 2.0 - */ -public interface IRemoteLaunchConfigService { - - /** - * Sets the active remote connection for the given launch configuration. - * - * @param launchConfig launch configuration - * @param connection active remote connection - */ - void setActiveConnection(ILaunchConfiguration launchConfig, IRemoteConnection connection); - - /** - * Gets the active remote connection for the given launch configuration - * @param launchConfig launch configuration - * @return active remote connection - */ - IRemoteConnection getActiveConnection(ILaunchConfiguration launchConfig); - - /** - * For a given launch configuration type, get the remote connection that was last - * used by a launch configuration of that type. - * - * This is used for new launch configurations with the assumption that the user - * will want to use the same remote connection. - * - * @param launchConfigType launch configuration type - * @return last active remote configuration - */ - IRemoteConnection getLastActiveConnection(ILaunchConfigurationType launchConfigType); - -} 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 8a84bdc4e28..548f8fd818d 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 @@ -39,7 +39,7 @@ public class RemoteConnection implements IRemoteConnection { private final RemoteConnectionType connectionType; private String name; - private final Map servicesMap = new HashMap<>(); + private final Map, Service> servicesMap = new HashMap<>(); private final ListenerList fListeners = new ListenerList(); @@ -69,15 +69,15 @@ public class RemoteConnection implements IRemoteConnection { @Override public T getService(Class service) { String serviceName = service.getName(); - Object obj = servicesMap.get(serviceName); + T obj = (T) servicesMap.get(serviceName); if (obj == null) { obj = connectionType.getConnectionService(this, service); if (obj != null) { - servicesMap.put(serviceName, obj); + servicesMap.put(service, obj); } } - return (T) obj; + return obj; } /* 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 d5db29d23ba..c7cde9b83e2 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 @@ -39,10 +39,14 @@ public class RemoteConnectionType implements IRemoteConnectionType { private final String id; private final String name; private final String scheme; - private final int capabilities; + private final boolean canAdd; + private final boolean canEdit; + private final boolean canRemove; - private final Map serviceMap = new HashMap<>(); + private final Map, Object> serviceMap = new HashMap<>(); private final Map serviceDefinitionMap = new HashMap<>(); + private final Map connectionServiceDefinitionMap = new HashMap<>(); + private final Map processServiceDefinitionMap = new HashMap<>(); private final Map connections = new HashMap<>(); @@ -52,22 +56,23 @@ public class RemoteConnectionType implements IRemoteConnectionType { name = ce.getAttribute("name"); //$NON-NLS-1$ scheme = ce.getAttribute("scheme"); //$NON-NLS-1$ - String caps = ce.getAttribute("capabilities"); //$NON-NLS-1$ - if (caps != null) { - capabilities = Integer.parseInt(caps); - } else { - capabilities = 0; - } - + // capabilities, default is true for all of these + String canAddStr = ce.getAttribute("canAdd"); //$NON-NLS-1$ + canAdd = canAddStr != null ? Boolean.parseBoolean(canAddStr) : true; + + String canEditStr = ce.getAttribute("canEdit"); //$NON-NLS-1$ + canEdit = canEditStr != null ? Boolean.parseBoolean(canEditStr) : true; + + String canRemoveStr = ce.getAttribute("canRemove"); //$NON-NLS-1$ + canRemove = canRemoveStr != null ? Boolean.parseBoolean(canRemoveStr) : true; + // load up existing connections - synchronized (connections) { - try { - for (String connectionName : getPreferenceNode().childrenNames()) { - connections.put(connectionName, new RemoteConnection(this, connectionName)); - } - } catch (BackingStoreException e) { - RemoteCorePlugin.log(e); + try { + for (String connectionName : getPreferenceNode().childrenNames()) { + connections.put(connectionName, new RemoteConnection(this, connectionName)); } + } catch (BackingStoreException e) { + RemoteCorePlugin.log(e); } } @@ -119,14 +124,19 @@ public class RemoteConnectionType implements IRemoteConnectionType { return scheme; } - /* - * (non-Javadoc) - * - * @see org.eclipse.remote.core.IRemoteConnectionType#getCapabilities() - */ @Override - public int getCapabilities() { - return capabilities; + public boolean canAdd() { + return canAdd; + } + + @Override + public boolean canEdit() { + return canEdit; + } + + @Override + public boolean canRemove() { + return canRemove; } /* @@ -136,18 +146,16 @@ public class RemoteConnectionType implements IRemoteConnectionType { */ @Override public T getService(Class service) { - String serviceName = service.getName(); @SuppressWarnings("unchecked") - T obj = (T) serviceMap.get(serviceName); + T obj = (T) serviceMap.get(service); if (obj == null) { - IConfigurationElement ce = serviceDefinitionMap.get(serviceName); + IConfigurationElement ce = serviceDefinitionMap.get(service.getName()); if (ce != null) { try { Service.Factory factory = (Service.Factory) ce.createExecutableExtension("factory"); //$NON-NLS-1$ if (factory != null) { obj = factory.getService(this, service); - serviceMap.put(serviceName, obj); - serviceDefinitionMap.remove(serviceName); + serviceMap.put(service, obj); } } catch (CoreException e) { RemoteCorePlugin.log(e.getStatus()); @@ -157,6 +165,11 @@ public class RemoteConnectionType implements IRemoteConnectionType { return obj; } + @Override + public List getServices() { + return new ArrayList<>(serviceDefinitionMap.keySet()); + } + /* * (non-Javadoc) * @@ -164,8 +177,7 @@ public class RemoteConnectionType implements IRemoteConnectionType { */ @Override public boolean hasService(Class service) { - String serviceName = service.getName(); - return serviceMap.get(serviceName) != null || serviceDefinitionMap.get(service) != null; + return serviceDefinitionMap.get(service.getName()) != null; } /** @@ -179,9 +191,7 @@ public class RemoteConnectionType implements IRemoteConnectionType { * @throws CoreException */ public T getConnectionService(IRemoteConnection connection, Class service) { - // Both top level and connection services are stored in the serviceDefinitionMap. - // In theory the two sets of interfaces can't collide. - IConfigurationElement ce = serviceDefinitionMap.get(service.getName()); + IConfigurationElement ce = connectionServiceDefinitionMap.get(service.getName()); if (ce != null) { try { IRemoteConnection.Service.Factory factory = (IRemoteConnection.Service.Factory) ce @@ -197,6 +207,11 @@ public class RemoteConnectionType implements IRemoteConnectionType { return null; } + @Override + public List getConnectionServices() { + return new ArrayList<>(connectionServiceDefinitionMap.keySet()); + } + /* * (non-Javadoc) * @@ -204,7 +219,7 @@ public class RemoteConnectionType implements IRemoteConnectionType { */ @Override public boolean hasConnectionService(Class service) { - return serviceDefinitionMap.get(service.getName()) != null; + return connectionServiceDefinitionMap.get(service.getName()) != null; } /** @@ -218,9 +233,7 @@ public class RemoteConnectionType implements IRemoteConnectionType { * @throws CoreException */ public T getProcessService(IRemoteProcess process, Class service) { - // Both top level and connection services are stored in the serviceDefinitionMap. - // In theory the two sets of interfaces can't collide. - IConfigurationElement ce = serviceDefinitionMap.get(service.getName()); + IConfigurationElement ce = processServiceDefinitionMap.get(service.getName()); if (ce != null) { try { IRemoteProcess.Service.Factory factory = (IRemoteProcess.Service.Factory) ce.createExecutableExtension("factory"); //$NON-NLS-1$ @@ -235,6 +248,11 @@ public class RemoteConnectionType implements IRemoteConnectionType { return null; } + @Override + public List getProcessServices() { + return new ArrayList<>(processServiceDefinitionMap.keySet()); + } + /* * (non-Javadoc) * @@ -242,7 +260,7 @@ public class RemoteConnectionType implements IRemoteConnectionType { */ @Override public boolean hasProcessService(Class service) { - return serviceDefinitionMap.get(service.getName()) != null; + return processServiceDefinitionMap.get(service.getName()) != null; } /** @@ -253,8 +271,19 @@ public class RemoteConnectionType implements IRemoteConnectionType { * the extension element defining the service */ public void addService(IConfigurationElement ce) { - String service = ce.getAttribute("service"); //$NON-NLS-1$ - serviceDefinitionMap.put(service, ce); + String serviceName = ce.getAttribute("service"); //$NON-NLS-1$ + String name = ce.getName(); + switch (name) { + case "connectionTypeService": //$NON-NLS-1$ + serviceDefinitionMap.put(serviceName, ce); + break; + case "connectionService": //$NON-NLS-1$ + connectionServiceDefinitionMap.put(serviceName, ce); + break; + case "processService": //$NON-NLS-1$ + processServiceDefinitionMap.put(serviceName, ce); + break; + } } /** @@ -298,13 +327,13 @@ public class RemoteConnectionType implements IRemoteConnectionType { if (connection != null) { return connection; } - + // If it's a file: scheme we must be the local connection type, just return our // hopefully one connection, the Local connection. if (uri.getScheme().equals("file") && !connections.isEmpty()) { //$NON-NLS-1$ return connections.values().iterator().next(); } - + return null; } } diff --git a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteCorePlugin.java b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteCorePlugin.java index bc564fabee1..4272f87e817 100644 --- a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteCorePlugin.java +++ b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteCorePlugin.java @@ -18,8 +18,6 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Status; import org.eclipse.remote.core.IRemoteServicesManager; -import org.eclipse.remote.core.launch.IRemoteLaunchConfigService; -import org.eclipse.remote.internal.core.launch.RemoteLaunchConfigService; import org.eclipse.remote.internal.core.preferences.Preferences; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; @@ -110,7 +108,6 @@ public class RemoteCorePlugin extends Plugin { super.start(context); plugin = this; context.registerService(IRemoteServicesManager.class, new RemoteServicesManager(), null); - context.registerService(IRemoteLaunchConfigService.class, new RemoteLaunchConfigService(), null); RemoteDebugOptions.configure(context); ResourcesPlugin.getWorkspace().addSaveParticipant(getUniqueIdentifier(), new ISaveParticipant() { @Override diff --git a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteProcess.java b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteProcess.java index d5ecde6c746..67c7da41a61 100644 --- a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteProcess.java +++ b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteProcess.java @@ -24,7 +24,7 @@ import org.eclipse.remote.core.IRemoteProcessControlService; * Standard root class for remote processes. */ public class RemoteProcess extends Process implements IRemoteProcess { - private final Map servicesMap = new HashMap<>(); + private final Map, Service> servicesMap = new HashMap<>(); private final IRemoteConnection connection; private final IRemoteProcessBuilder builder; @@ -111,16 +111,15 @@ public class RemoteProcess extends Process implements IRemoteProcess { @SuppressWarnings("unchecked") @Override public T getService(Class service) { - String serviceName = service.getName(); - Object obj = servicesMap.get(serviceName); + T obj = (T) servicesMap.get(service); if (obj == null) { obj = getConnectionType().getProcessService(this, service); if (obj != null) { - servicesMap.put(serviceName, obj); + servicesMap.put(service, obj); } } - return (T) obj; + return obj; } /** diff --git a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteServicesManager.java b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteServicesManager.java index 678f23c194c..0211841492f 100644 --- a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteServicesManager.java +++ b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/RemoteServicesManager.java @@ -218,7 +218,6 @@ public class RemoteServicesManager implements IRemoteServicesManager { */ @Override public List getAllRemoteConnections() { - // TODO do this without getting the connection managers and force loading the plugins List connections = new ArrayList<>(); for (IRemoteConnectionType connType : getAllConnectionTypes()) { connections.addAll(connType.getConnections()); diff --git a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/launch/RemoteLaunchConfigService.java b/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/launch/RemoteLaunchConfigService.java deleted file mode 100644 index 5b2ce2316a2..00000000000 --- a/bundles/org.eclipse.remote.core/src/org/eclipse/remote/internal/core/launch/RemoteLaunchConfigService.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.eclipse.remote.internal.core.launch; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.preferences.InstanceScope; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.ILaunchConfigurationType; -import org.eclipse.remote.core.IRemoteConnection; -import org.eclipse.remote.core.IRemoteConnectionType; -import org.eclipse.remote.core.IRemoteServicesManager; -import org.eclipse.remote.core.launch.IRemoteLaunchConfigService; -import org.eclipse.remote.internal.core.RemoteCorePlugin; -import org.osgi.service.prefs.Preferences; - -public class RemoteLaunchConfigService implements IRemoteLaunchConfigService { - - private static final String REMOTE_LAUNCH_CONFIG = "remoteLaunchConfig"; //$NON-NLS-1$ - private static final String REMOTE_LAUNCH_TYPE = "remoteLaunchType"; //$NON-NLS-1$ - - private Preferences getPreferences(String node) { - return InstanceScope.INSTANCE.getNode(RemoteCorePlugin.getUniqueIdentifier()).node(node); - } - - private IRemoteConnection getRemoteConnection(String remoteId) { - if (remoteId == null) { - return null; - } - - String[] ids = remoteId.split(":"); //$NON-NLS-1$ - if (ids.length < 2) { - return null; - } - - IRemoteServicesManager manager = RemoteCorePlugin.getService(IRemoteServicesManager.class); - IRemoteConnectionType connectionType = manager.getConnectionType(ids[0]); - if (connectionType == null) { - return null; - } - - return connectionType.getConnection(ids[1]); - } - - @Override - public void setActiveConnection(ILaunchConfiguration launchConfig, IRemoteConnection connection) { - String remoteId = connection.getConnectionType().getId() + ":" + connection.getName(); //$NON-NLS-1$ - getPreferences(REMOTE_LAUNCH_CONFIG).put(launchConfig.getName(), remoteId); - try { - getPreferences(REMOTE_LAUNCH_TYPE).put(launchConfig.getType().getIdentifier(), remoteId); - } catch (CoreException e) { - RemoteCorePlugin.log(e.getStatus()); - } - } - - @Override - public IRemoteConnection getActiveConnection(ILaunchConfiguration launchConfig) { - String remoteId = getPreferences(REMOTE_LAUNCH_CONFIG).get(launchConfig.getName(), null); - return getRemoteConnection(remoteId); - } - - @Override - public IRemoteConnection getLastActiveConnection(ILaunchConfigurationType launchConfigType) { - String remoteId = getPreferences(REMOTE_LAUNCH_TYPE).get(launchConfigType.getIdentifier(), null); - return getRemoteConnection(remoteId); - } - -} diff --git a/bundles/org.eclipse.remote.jsch.core/plugin.xml b/bundles/org.eclipse.remote.jsch.core/plugin.xml index 154b3aec627..b3d72c998f0 100644 --- a/bundles/org.eclipse.remote.jsch.core/plugin.xml +++ b/bundles/org.eclipse.remote.jsch.core/plugin.xml @@ -4,7 +4,6 @@ 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 170dd748d2c..8f4210e71ef 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 @@ -24,6 +24,7 @@ import org.eclipse.core.runtime.SubMonitor; import org.eclipse.jsch.core.IJSchService; import org.eclipse.osgi.util.NLS; import org.eclipse.remote.core.IRemoteConnection; +import org.eclipse.remote.core.IRemoteConnectionChangeListener; import org.eclipse.remote.core.IRemoteConnectionControlService; import org.eclipse.remote.core.IRemoteConnectionHostService; import org.eclipse.remote.core.IRemoteConnectionPropertyService; @@ -52,7 +53,7 @@ import com.jcraft.jsch.UserInfo; * @since 5.0 */ public class JSchConnection implements IRemoteConnectionControlService, IRemoteConnectionPropertyService, - IRemotePortForwardingService, IRemoteProcessService, IRemoteConnectionHostService { + IRemotePortForwardingService, IRemoteProcessService, IRemoteConnectionHostService, IRemoteConnectionChangeListener { // Connection Type ID public static final String JSCH_ID = "org.eclipse.remote.JSch"; //$NON-NLS-1$ @@ -255,9 +256,21 @@ public class JSchConnection implements IRemoteConnectionControlService, IRemoteC private ChannelSftp fSftpChannel; private boolean isFullySetup; // including sftp channel and environment + private static final Map connectionMap = new HashMap<>(); + public JSchConnection(IRemoteConnection connection) { fRemoteConnection = connection; fJSchService = Activator.getDefault().getService(); + connection.addConnectionChangeListener(this); + } + + @Override + public void connectionChanged(RemoteConnectionChangeEvent event) { + if (event.getType() == RemoteConnectionChangeEvent.CONNECTION_REMOVED) { + synchronized (connectionMap) { + connectionMap.remove(event.getConnection()); + } + } } /* @@ -286,7 +299,14 @@ public class JSchConnection implements IRemoteConnectionControlService, IRemoteC // As a side effect, it makes this class a service too which can be used // by the this plug-in if (JSchConnection.class.equals(service)) { - return (T) new JSchConnection(connection); + synchronized (connectionMap) { + JSchConnection jschConnection = connectionMap.get(connection); + if (jschConnection == null) { + jschConnection = new JSchConnection(connection); + connectionMap.put(connection, jschConnection); + } + return (T) jschConnection; + } } else if (IRemoteConnectionControlService.class.equals(service) || IRemoteConnectionPropertyService.class.equals(service) || IRemotePortForwardingService.class.equals(service) || IRemoteProcessService.class.equals(service) || IRemoteConnectionHostService.class.equals(service)) { @@ -338,13 +358,7 @@ public class JSchConnection implements IRemoteConnectionControlService, IRemoteC } } - /* - * (non-Javadoc) - * - * @see org.eclipse.remote.core.IRemoteConnectionControlService#close() - */ - @Override - public synchronized void close() { + private synchronized void cleanup() { if (fSftpChannel != null) { if (fSftpChannel.isConnected()) { fSftpChannel.disconnect(); @@ -357,6 +371,16 @@ public class JSchConnection implements IRemoteConnectionControlService, IRemoteC } } fSessions.clear(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.remote.core.IRemoteConnectionControlService#close() + */ + @Override + public synchronized void close() { + cleanup(); fRemoteConnection.fireConnectionChangeEvent(RemoteConnectionChangeEvent.CONNECTION_CLOSED); } @@ -714,7 +738,7 @@ public class JSchConnection implements IRemoteConnectionControlService, IRemoteC } } if (!hasOpenSession) { - close(); // Cleanup if session is closed + cleanup(); // Cleanup if session is closed } return hasOpenSession; } diff --git a/bundles/org.eclipse.remote.jsch.ui/icons/ssh.png b/bundles/org.eclipse.remote.jsch.ui/icons/ssh.png new file mode 100644 index 00000000000..8cbd0a13ba8 Binary files /dev/null and b/bundles/org.eclipse.remote.jsch.ui/icons/ssh.png differ diff --git a/bundles/org.eclipse.remote.jsch.ui/src/org/eclipse/remote/internal/jsch/ui/Activator.java b/bundles/org.eclipse.remote.jsch.ui/src/org/eclipse/remote/internal/jsch/ui/Activator.java index 080fe5c6e4f..d07e0ea5f75 100644 --- a/bundles/org.eclipse.remote.jsch.ui/src/org/eclipse/remote/internal/jsch/ui/Activator.java +++ b/bundles/org.eclipse.remote.jsch.ui/src/org/eclipse/remote/internal/jsch/ui/Activator.java @@ -1,20 +1,23 @@ package org.eclipse.remote.internal.jsch.ui; import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Status; import org.eclipse.jsch.core.IJSchService; +import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; /** * The activator class controls the plug-in life cycle */ -public class Activator extends Plugin { +public class Activator extends AbstractUIPlugin { // The plug-in ID private static final String PLUGIN_ID = "org.eclipse.remote.jsch.ui"; //$NON-NLS-1$ + // Image Keys + public static final String IMG_CONNECTION_TYPE = PLUGIN_ID + ".connectionType"; //$NON-NLS-1$ + // The shared instance private static Activator plugin; @@ -107,6 +110,7 @@ public class Activator extends Plugin { plugin = this; ServiceReference reference = context.getServiceReference(IJSchService.class); fJSchService = context.getService(reference); + getImageRegistry().put(IMG_CONNECTION_TYPE, imageDescriptorFromPlugin(PLUGIN_ID, "/icons/ssh.png")); //$NON-NLS-1$ } /* diff --git a/bundles/org.eclipse.remote.jsch.ui/src/org/eclipse/remote/internal/jsch/ui/JSchUIConnectionService.java b/bundles/org.eclipse.remote.jsch.ui/src/org/eclipse/remote/internal/jsch/ui/JSchUIConnectionService.java index f0e6bfd1064..3801ee2ecd1 100644 --- a/bundles/org.eclipse.remote.jsch.ui/src/org/eclipse/remote/internal/jsch/ui/JSchUIConnectionService.java +++ b/bundles/org.eclipse.remote.jsch.ui/src/org/eclipse/remote/internal/jsch/ui/JSchUIConnectionService.java @@ -19,18 +19,20 @@ import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.remote.core.IRemoteConnection; import org.eclipse.remote.core.IRemoteConnectionType; import org.eclipse.remote.core.IRemoteConnectionType.Service; import org.eclipse.remote.core.exception.RemoteConnectionException; import org.eclipse.remote.internal.jsch.ui.messages.Messages; import org.eclipse.remote.internal.jsch.ui.wizards.JSchConnectionWizard; -import org.eclipse.remote.ui.AbstractRemoteUIConnectionManager; +import org.eclipse.remote.ui.AbstractRemoteUIConnectionService; import org.eclipse.remote.ui.IRemoteUIConnectionService; import org.eclipse.remote.ui.IRemoteUIConnectionWizard; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Shell; -public class JSchUIConnectionService extends AbstractRemoteUIConnectionManager { +public class JSchUIConnectionService extends AbstractRemoteUIConnectionService { private final IRemoteConnectionType fConnectionType; @@ -53,7 +55,7 @@ public class JSchUIConnectionService extends AbstractRemoteUIConnectionManager { public IRemoteConnectionType getConnectionType() { return fConnectionType; } - + @Override public IRemoteUIConnectionWizard getConnectionWizard(Shell shell) { return new JSchConnectionWizard(shell, fConnectionType); @@ -92,4 +94,15 @@ public class JSchUIConnectionService extends AbstractRemoteUIConnectionManager { } } } + + @Override + public ILabelProvider getLabelProvider() { + return new DefaultLabelProvider() { + @Override + public Image getImage(Object element) { + return Activator.getDefault().getImageRegistry().get(Activator.IMG_CONNECTION_TYPE); + } + }; + } + } diff --git a/bundles/org.eclipse.remote.serial.core/plugin.xml b/bundles/org.eclipse.remote.serial.core/plugin.xml index c36d8be75ac..2f226dccdd5 100644 --- a/bundles/org.eclipse.remote.serial.core/plugin.xml +++ b/bundles/org.eclipse.remote.serial.core/plugin.xml @@ -4,7 +4,6 @@ diff --git a/bundles/org.eclipse.remote.serial.ui/icons/serial.png b/bundles/org.eclipse.remote.serial.ui/icons/serial.png new file mode 100644 index 00000000000..55927362f66 Binary files /dev/null and b/bundles/org.eclipse.remote.serial.ui/icons/serial.png differ diff --git a/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/Activator.java b/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/Activator.java index 68443c48293..f22863d95bd 100644 --- a/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/Activator.java +++ b/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/Activator.java @@ -25,13 +25,16 @@ public class Activator extends AbstractUIPlugin { // The plug-in ID public static final String PLUGIN_ID = "org.eclipse.remote.serial.ui"; //$NON-NLS-1$ + // Image keys + public static final String IMG_CONNECTION_TYPE = PLUGIN_ID + ".connectionType"; //$NON-NLS-1$ + // The shared instance private static Activator plugin; - public void start(BundleContext context) throws Exception { super.start(context); plugin = this; + getImageRegistry().put(IMG_CONNECTION_TYPE, imageDescriptorFromPlugin(PLUGIN_ID, "/icons/serial.png")); //$NON-NLS-1$ } public void stop(BundleContext context) throws Exception { diff --git a/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/SerialPortConnectionsUI.java b/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/SerialPortConnectionsUI.java index 45917c43b3a..0ce8185afb4 100644 --- a/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/SerialPortConnectionsUI.java +++ b/bundles/org.eclipse.remote.serial.ui/src/org/eclipse/remote/serial/internal/ui/SerialPortConnectionsUI.java @@ -15,15 +15,18 @@ import java.lang.reflect.InvocationTargetException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.remote.core.IRemoteConnection; import org.eclipse.remote.core.IRemoteConnectionType; import org.eclipse.remote.core.IRemoteConnectionType.Service; import org.eclipse.remote.core.exception.RemoteConnectionException; +import org.eclipse.remote.ui.AbstractRemoteUIConnectionService; import org.eclipse.remote.ui.IRemoteUIConnectionService; import org.eclipse.remote.ui.IRemoteUIConnectionWizard; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Shell; -public class SerialPortConnectionsUI implements IRemoteUIConnectionService { +public class SerialPortConnectionsUI extends AbstractRemoteUIConnectionService { private final IRemoteConnectionType connectionType; @@ -70,4 +73,14 @@ public class SerialPortConnectionsUI implements IRemoteUIConnectionService { } } + @Override + public ILabelProvider getLabelProvider() { + return new DefaultLabelProvider() { + @Override + public Image getImage(Object element) { + return Activator.getDefault().getImageRegistry().get(Activator.IMG_CONNECTION_TYPE); + } + }; + } + } diff --git a/bundles/org.eclipse.remote.ui/icons/connection.gif b/bundles/org.eclipse.remote.ui/icons/connection.gif new file mode 100644 index 00000000000..870934b6934 Binary files /dev/null and b/bundles/org.eclipse.remote.ui/icons/connection.gif differ diff --git a/bundles/org.eclipse.remote.ui/icons/console.png b/bundles/org.eclipse.remote.ui/icons/console.png new file mode 100644 index 00000000000..ca77aee5bca Binary files /dev/null and b/bundles/org.eclipse.remote.ui/icons/console.png differ diff --git a/bundles/org.eclipse.remote.ui/plugin.properties b/bundles/org.eclipse.remote.ui/plugin.properties index 6d387c5c375..46646a72eea 100644 --- a/bundles/org.eclipse.remote.ui/plugin.properties +++ b/bundles/org.eclipse.remote.ui/plugin.properties @@ -17,3 +17,5 @@ ConnectionsContent.name=Connections NewConnectionCommand.name=New Connection DeleteConnectionCommand.name=Delete Connection ConnectionProperties.name=Connection +OpenConnectionCommand.name=Open Connection +CloseConnectionCommand.name=Close Connection diff --git a/bundles/org.eclipse.remote.ui/plugin.xml b/bundles/org.eclipse.remote.ui/plugin.xml index 59a38f886c1..a94f2713300 100644 --- a/bundles/org.eclipse.remote.ui/plugin.xml +++ b/bundles/org.eclipse.remote.ui/plugin.xml @@ -36,6 +36,11 @@ factory="org.eclipse.remote.internal.ui.services.local.LocalUIFileService$Factory" service="org.eclipse.remote.ui.IRemoteUIFileService"> + + @@ -46,6 +51,7 @@ @@ -57,7 +63,7 @@ activeByDefault="true" contentProvider="org.eclipse.remote.internal.ui.views.RemoteConnectionsContentProvider" id="org.eclipse.remote.ui.navigatorContent.connections" - labelProvider="org.eclipse.remote.internal.ui.views.RemoteConnectionsLabelProvider" + labelProvider="org.eclipse.remote.ui.RemoteConnectionsLabelProvider" name="%ConnectionsContent.name"> + + + + @@ -128,7 +144,7 @@ class="org.eclipse.remote.internal.ui.ServicePropertyTester" id="org.eclipse.remote.ui.propertyTester.hasService" namespace="org.eclipse.remote.ui" - properties="hasConnectionTypeService,hasConnectionService,canDelete" + properties="hasConnectionTypeService,hasConnectionService,canDelete,canOpen,canClose" type="org.eclipse.remote.core.IRemoteConnection"> @@ -147,6 +163,38 @@ + + + + + + + + + + + + + + + + + + + + T getService(IRemoteConnectionType connectionType, Class service) { + if (IRemoteUIConnectionService.class.equals(service)) { + return (T) new LocalUIConnectionService(connectionType); + } + return null; + } + } + + @Override + public IRemoteConnectionType getConnectionType() { + return connectionType; + } + +} diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/CloseConnectionHandler.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/CloseConnectionHandler.java new file mode 100644 index 00000000000..cd62f1c6133 --- /dev/null +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/CloseConnectionHandler.java @@ -0,0 +1,61 @@ +package org.eclipse.remote.internal.ui.views; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.remote.core.IRemoteConnection; +import org.eclipse.remote.core.IRemoteConnectionControlService; +import org.eclipse.remote.internal.ui.RemoteUIPlugin; +import org.eclipse.ui.handlers.HandlerUtil; + +public class CloseConnectionHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().getSelection(); + if (selection != null && selection instanceof IStructuredSelection) { + // Get the manageable connections from the selection + final List connections = new ArrayList(); + @SuppressWarnings("unchecked") + Iterator i = ((IStructuredSelection) selection).iterator(); + while (i.hasNext()) { + Object obj = i.next(); + if (obj instanceof IRemoteConnection) { + IRemoteConnection connection = (IRemoteConnection) obj; + connections.add(connection); + } + } + + new Job(Messages.CloseConnectionHandler_0) { + protected IStatus run(IProgressMonitor monitor) { + List status = new ArrayList<>(); + for (IRemoteConnection connection : connections) { + IRemoteConnectionControlService controlService = connection.getService(IRemoteConnectionControlService.class); + if (controlService != null) { + controlService.close(); + } + } + + if (status.isEmpty()) { + return Status.OK_STATUS; + } else { + return new MultiStatus(RemoteUIPlugin.PLUGIN_ID, 1, status.toArray(new IStatus[status.size()]), Messages.CloseConnectionHandler_1, null); + } + } + }.schedule(); + } + return Status.OK_STATUS; + } + +} diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/DeleteRemoteConnectionHandler.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/DeleteRemoteConnectionHandler.java index c679c4250fa..8597faade6b 100644 --- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/DeleteRemoteConnectionHandler.java +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/DeleteRemoteConnectionHandler.java @@ -43,7 +43,7 @@ public class DeleteRemoteConnectionHandler extends AbstractHandler { if (obj instanceof IRemoteConnection) { IRemoteConnection connection = (IRemoteConnection) obj; IRemoteConnectionType connectionType = connection.getConnectionType(); - if ((connectionType.getCapabilities() & IRemoteConnectionType.CAPABILITY_REMOVE_CONNECTIONS) != 0) { + if (connectionType.canRemove()) { connections.add(connection); } } diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/Messages.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/Messages.java index bc140ebd628..ed6e6f2f125 100644 --- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/Messages.java +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/Messages.java @@ -4,8 +4,12 @@ import org.eclipse.osgi.util.NLS; public class Messages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.remote.internal.ui.views.messages"; //$NON-NLS-1$ + public static String CloseConnectionHandler_0; + public static String CloseConnectionHandler_1; public static String DeleteRemoteConnectionHandler_ConfirmDeleteMessage; public static String DeleteRemoteConnectionHandler_DeleteConnectionTitle; + public static String OpenConnectionHandler_0; + public static String OpenConnectionHandler_1; static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/NewRemoteConnectionTypePage.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/NewRemoteConnectionTypePage.java index 6763909213c..b1d562f442d 100644 --- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/NewRemoteConnectionTypePage.java +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/NewRemoteConnectionTypePage.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2015 QNX Software Systems 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: + * QNX Software Systems - initial API and implementation + *******************************************************************************/ package org.eclipse.remote.internal.ui.views; import org.eclipse.jface.wizard.IWizardPage; @@ -9,6 +19,7 @@ import org.eclipse.remote.internal.ui.RemoteUIPlugin; import org.eclipse.remote.ui.IRemoteUIConnectionService; import org.eclipse.remote.ui.IRemoteUIConnectionWizard; import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; @@ -46,25 +57,25 @@ public class NewRemoteConnectionTypePage extends WizardPage { IRemoteServicesManager remoteManager = RemoteUIPlugin.getService(IRemoteServicesManager.class); for (IRemoteConnectionType connectionType : remoteManager.getAllConnectionTypes()) { - if ((connectionType.getCapabilities() & IRemoteConnectionType.CAPABILITY_ADD_CONNECTIONS) == 0) + if (!connectionType.canAdd()) continue; - IRemoteUIConnectionService connManager = connectionType.getService(IRemoteUIConnectionService.class); - if (connManager == null) + IRemoteUIConnectionService connService = connectionType.getService(IRemoteUIConnectionService.class); + if (connService == null) continue; - IRemoteUIConnectionWizard wizard = connManager.getConnectionWizard(parent.getShell()); + IRemoteUIConnectionWizard wizard = connService.getConnectionWizard(parent.getShell()); if (wizard == null) continue; TableItem item = new TableItem(table, SWT.NONE); item.setText(connectionType.getName()); item.setData(wizard); - // TODO connection type icons somehow -// Image icon = ui.getIcon(); -// if (icon != null) { -// item.setImage(icon); -// } + + Image icon = connService.getLabelProvider().getImage(connectionType); + if (icon != null) { + item.setImage(icon); + } // TODO select the last selected entry table.select(0); diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/OpenConnectionHandler.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/OpenConnectionHandler.java new file mode 100644 index 00000000000..7d56e0b2534 --- /dev/null +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/OpenConnectionHandler.java @@ -0,0 +1,66 @@ +package org.eclipse.remote.internal.ui.views; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.remote.core.IRemoteConnection; +import org.eclipse.remote.core.IRemoteConnectionControlService; +import org.eclipse.remote.core.exception.RemoteConnectionException; +import org.eclipse.remote.internal.ui.RemoteUIPlugin; +import org.eclipse.ui.handlers.HandlerUtil; + +public class OpenConnectionHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().getSelection(); + if (selection != null && selection instanceof IStructuredSelection) { + // Get the manageable connections from the selection + final List connections = new ArrayList(); + @SuppressWarnings("unchecked") + Iterator i = ((IStructuredSelection) selection).iterator(); + while (i.hasNext()) { + Object obj = i.next(); + if (obj instanceof IRemoteConnection) { + IRemoteConnection connection = (IRemoteConnection) obj; + connections.add(connection); + } + } + + new Job(Messages.OpenConnectionHandler_0) { + protected IStatus run(IProgressMonitor monitor) { + List status = new ArrayList<>(); + for (IRemoteConnection connection : connections) { + IRemoteConnectionControlService controlService = connection.getService(IRemoteConnectionControlService.class); + if (controlService != null) { + try { + controlService.open(monitor); + } catch (RemoteConnectionException e) { + status.add(e.getStatus()); + } + } + } + + if (status.isEmpty()) { + return Status.OK_STATUS; + } else { + return new MultiStatus(RemoteUIPlugin.PLUGIN_ID, 1, status.toArray(new IStatus[status.size()]), Messages.OpenConnectionHandler_1, null); + } + } + }.schedule(); + } + return Status.OK_STATUS; + } + +} diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/RemoteConnectionsLabelProvider.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/RemoteConnectionsLabelProvider.java deleted file mode 100644 index 9009d2ea9c0..00000000000 --- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/RemoteConnectionsLabelProvider.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.eclipse.remote.internal.ui.views; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.remote.core.IRemoteConnection; -import org.eclipse.swt.graphics.Image; - - -public class RemoteConnectionsLabelProvider extends LabelProvider { - - @Override - public String getText(Object element) { - if (element instanceof IRemoteConnection) { - return ((IRemoteConnection) element).getName(); - } else { - return super.getText(element); - } - } - - @Override - public Image getImage(Object element) { - // TODO Need a method to get icons for the UI connection managers. - return super.getImage(element); - } - -} diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/messages.properties b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/messages.properties index ee73ad7de56..bfcf04c098f 100644 --- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/messages.properties +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/internal/ui/views/messages.properties @@ -1,2 +1,6 @@ +CloseConnectionHandler_0=Closing connections +CloseConnectionHandler_1=Error closing connections DeleteRemoteConnectionHandler_ConfirmDeleteMessage=Delete connection DeleteRemoteConnectionHandler_DeleteConnectionTitle=Delete Connection +OpenConnectionHandler_0=Openning connections +OpenConnectionHandler_1=Error openning connections diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/AbstractRemoteUIConnectionManager.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/AbstractRemoteUIConnectionService.java similarity index 70% rename from bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/AbstractRemoteUIConnectionManager.java rename to bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/AbstractRemoteUIConnectionService.java index 3b0f05c27d7..aaac6148a9e 100644 --- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/AbstractRemoteUIConnectionManager.java +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/AbstractRemoteUIConnectionService.java @@ -19,20 +19,28 @@ import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.remote.core.IRemoteConnection; +import org.eclipse.remote.core.IRemoteConnectionType; import org.eclipse.remote.core.exception.RemoteConnectionException; +import org.eclipse.remote.internal.ui.RemoteUIImages; import org.eclipse.remote.internal.ui.RemoteUIPlugin; import org.eclipse.remote.internal.ui.messages.Messages; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Shell; /** * Abstract base class for providing UI connection manager services. + * @since 2.0 */ -public abstract class AbstractRemoteUIConnectionManager implements IRemoteUIConnectionService { +public abstract class AbstractRemoteUIConnectionService implements IRemoteUIConnectionService { + @Override public void openConnectionWithProgress(final Shell shell, IRunnableContext context, final IRemoteConnection connection) { if (!connection.isOpen()) { IRunnableWithProgress op = new IRunnableWithProgress() { + @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { connection.open(monitor); @@ -62,4 +70,30 @@ public abstract class AbstractRemoteUIConnectionManager implements IRemoteUIConn } } + protected static class DefaultLabelProvider extends LabelProvider { + @Override + public String getText(Object element) { + if (element instanceof IRemoteConnection) { + return ((IRemoteConnection) element).getName(); + } else if (element instanceof IRemoteConnectionType) { + return ((IRemoteConnectionType) element).getName(); + } else { + return super.getText(element); + } + } + + @Override + public Image getImage(Object element) { + if (element instanceof IRemoteConnection || element instanceof IRemoteConnectionType) { + return RemoteUIImages.get(RemoteUIImages.IMG_DEFAULT_TYPE); + } + return super.getImage(element); + } + } + + @Override + public ILabelProvider getLabelProvider() { + return new DefaultLabelProvider(); + } + } diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/IRemoteUIConnectionService.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/IRemoteUIConnectionService.java index 5828164570e..11c794dee7d 100644 --- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/IRemoteUIConnectionService.java +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/IRemoteUIConnectionService.java @@ -11,6 +11,7 @@ package org.eclipse.remote.ui; import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.remote.core.IRemoteConnection; import org.eclipse.remote.core.IRemoteConnectionType; import org.eclipse.swt.widgets.Shell; @@ -21,6 +22,12 @@ import org.eclipse.swt.widgets.Shell; * @since 2.0 */ public interface IRemoteUIConnectionService extends IRemoteConnectionType.Service { + + /** + * ID for the command to start the new connection wizard. + */ + public static final String NEW_CONNECTION_COMMAND = "org.eclipse.remote.ui.command.newConnection"; //$NON-NLS-1$ + /** * Create a wizard for adding or editing connections. The implementation can choose to do this in any way, but typically will * use a dialog or wizard. @@ -42,7 +49,15 @@ public interface IRemoteUIConnectionService extends IRemoteConnectionType.Servic * runnable context for displaying progress indicator. Can be null. * @param connection * connection to open - * @since 5.0 */ public void openConnectionWithProgress(Shell shell, IRunnableContext context, IRemoteConnection connection); + + /** + * Return the label provider that provides the text and base image for the connection type + * and connections of that type. + * + * @return label provider + */ + public ILabelProvider getLabelProvider(); + } diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/RemoteConnectionsLabelProvider.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/RemoteConnectionsLabelProvider.java new file mode 100644 index 00000000000..c86cf66100d --- /dev/null +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/RemoteConnectionsLabelProvider.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2015 QNX Software Systems 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: + * QNX Software Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.remote.ui; + +import org.eclipse.jface.resource.CompositeImageDescriptor; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.remote.core.IRemoteConnection; +import org.eclipse.remote.core.IRemoteConnectionType; +import org.eclipse.remote.internal.ui.RemoteUIPlugin; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +/** + * A label provider to show the test and base image for remote connections. + * It calls out to the connection type services to get the text and images for + * the types of the connections. + * + * @since 2.0 + */ +public class RemoteConnectionsLabelProvider extends LabelProvider { + + @Override + public String getText(Object element) { + if (element instanceof IRemoteConnection) { + IRemoteConnectionType type = ((IRemoteConnection) element).getConnectionType(); + IRemoteUIConnectionService uiService = type.getService(IRemoteUIConnectionService.class); + if (uiService != null) { + return uiService.getLabelProvider().getText(element); + } else { + return ((IRemoteConnection) element).getName(); + } + } else { + return super.getText(element); + } + } + + @Override + public Image getImage(Object element) { + if (element instanceof IRemoteConnection) { + IRemoteConnection connection = (IRemoteConnection) element; + IRemoteConnectionType type = connection.getConnectionType(); + IRemoteUIConnectionService uiService = type.getService(IRemoteUIConnectionService.class); + if (uiService != null) { + final Image baseImage = uiService.getLabelProvider().getImage(element); + if (connection.isOpen()) { + return baseImage; + } else { + String closedId = "closed." + type.getId(); //$NON-NLS-1$ + Image closedImage = RemoteUIPlugin.getDefault().getImageRegistry().get(closedId); + if (closedImage == null) { + final Image errorImage = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_DEC_FIELD_ERROR); + ImageDescriptor desc = new CompositeImageDescriptor() { + @Override + protected Point getSize() { + Rectangle bounds = baseImage.getBounds(); + return new Point(bounds.width, bounds.height); + } + + @Override + protected void drawCompositeImage(int width, int height) { + drawImage(baseImage.getImageData(), 0, 0); + int y = baseImage.getBounds().height - errorImage.getBounds().height; + drawImage(errorImage.getImageData(), 0, y); + } + }; + closedImage = desc.createImage(); + RemoteUIPlugin.getDefault().getImageRegistry().put(closedId, closedImage); + } + return closedImage; + } + } + } + return super.getImage(element); + } + +} diff --git a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteConnectionWidget.java b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteConnectionWidget.java index 62fda4b432f..ec7e8e77d68 100644 --- a/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteConnectionWidget.java +++ b/bundles/org.eclipse.remote.ui/src/org/eclipse/remote/ui/widgets/RemoteConnectionWidget.java @@ -521,7 +521,7 @@ public class RemoteConnectionWidget extends Composite { * Enable 'new' button if new connections are supported */ fNewConnectionButton - .setEnabled((selectedConnectionType.getCapabilities() & IRemoteConnectionType.CAPABILITY_ADD_CONNECTIONS) != 0); + .setEnabled(selectedConnectionType.canAdd()); } } finally { fWidgetListener.setEnabled(enabled); @@ -652,12 +652,12 @@ public class RemoteConnectionWidget extends Composite { } fConnectionCombo.setEnabled(fEnabled && isRemote); fNewConnectionButton.setEnabled(fEnabled && isRemote - && (fDefaultConnectionType.getCapabilities() & IRemoteConnectionType.CAPABILITY_ADD_CONNECTIONS) != 0); + && fDefaultConnectionType.canAdd()); } else { IRemoteConnectionType services = getSelectedConnectionType(); fConnectionCombo.setEnabled(fEnabled && services != null); fNewConnectionButton.setEnabled(fEnabled && services != null - && (services.getCapabilities() & IRemoteConnectionType.CAPABILITY_ADD_CONNECTIONS) != 0); + && services.canAdd()); fConnectionTypeCombo.setEnabled(fEnabled); } }