/***************************************************************************** * Copyright (c) 2006, 2008 g-Eclipse Consortium * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Initial development of the original code was made for the * g-Eclipse project founded by European Union * project number: FP6-IST-034327 http://www.geclipse.eu/ * * Contributors: * Christof Klausecker GUP, JKU - initial API and implementation *****************************************************************************/ package eu.geclipse.efs.sftp.internal; import java.util.ArrayList; import java.util.HashMap; import java.util.Properties; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.jsch.core.IJSchService; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.HostKey; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import com.jcraft.jsch.UserInfo; import eu.geclipse.efs.sftp.Activator; import eu.geclipse.efs.sftp.IUserInfoProvider; /** * Manager for SFTP connections */ public class ConnectionManager { private static ConnectionManager instance = null; private final HashMap<ConnectionKey, ArrayList<Session>> sessions; private final HashMap<ConnectionKey, ArrayList<SFTPConnection>> connections; private ConnectionManager() { this.sessions = new HashMap<ConnectionKey, ArrayList<Session>>(); this.connections = new HashMap<ConnectionKey, ArrayList<SFTPConnection>>(); } /** * Returns the connection manager * * @return connection manager */ synchronized public static ConnectionManager getInstance() { if( instance == null ) { instance = new ConnectionManager(); } return instance; } /** * Acquire a {@link SFTPConnection} * * @param key * @return SFTPConnection * @throws CoreException */ synchronized public SFTPConnection acquireConnection( final ConnectionKey key ) throws CoreException { SFTPConnection result = null; ArrayList<Session> sessionsList = this.sessions.get( key ); ArrayList<SFTPConnection> connectionsList = this.connections.get( key ); if( sessionsList == null ) { sessionsList = new ArrayList<Session>(); this.sessions.put( key, sessionsList ); } if( connectionsList == null ) { connectionsList = new ArrayList<SFTPConnection>(); this.connections.put( key, connectionsList ); } for( SFTPConnection candidate : connectionsList ) { if( candidate != null && candidate.tryLock() == true ) { if( candidate.getChannel() == null || !candidate.getChannel().isConnected() || candidate.getChannel().isClosed() ) { connectionsList.remove( candidate ); } else { return candidate; } } } Session session = null; for( Session candidate : sessionsList ) { if( candidate.isConnected() ) { session = candidate; } else { sessionsList.remove( candidate ); } } // create session try { if( session == null ) { IJSchService service = Activator.getDefault().getJSchService(); session = service.createSession( key.getHost(), key.getPort(), key.getUsername() ); if( key.getPassword() != null ) { session.setPassword( key.getPassword() ); } Properties config = new Properties(); config.setProperty( "StrictHostKeyChecking", "ask" ); //$NON-NLS-1$ //$NON-NLS-2$ session.setConfig( config ); session.setUserInfo( getUserInfo( key ) ); session.connect(); sessionsList.add( session ); } // create channel ChannelSftp channel = ( ChannelSftp )session.openChannel( "sftp" ); //$NON-NLS-1$ channel.connect(); result = new SFTPConnection( channel ); result.lock(); } catch( JSchException jschException ) { throw new CoreException( new Status( IStatus.ERROR, Activator.PLUGIN_ID, jschException.getLocalizedMessage(), jschException ) ); } catch( NullPointerException nullPointerException ) { throw new CoreException( new Status( IStatus.ERROR, Activator.PLUGIN_ID, nullPointerException.getLocalizedMessage(), nullPointerException ) ); } connectionsList.add( result ); return result; } private UserInfo getUserInfo( final ConnectionKey key ) { UserInfo userInfo = null; IConfigurationElement[] configurationElements = Platform.getExtensionRegistry() .getConfigurationElementsFor( "eu.geclipse.efs.sftp.UserInfo" ); //$NON-NLS-1$ if( configurationElements.length > 0 ) { IUserInfoProvider provider; try { provider = ( IUserInfoProvider )configurationElements[ 0 ].createExecutableExtension( "class" ); //$NON-NLS-1$ userInfo = provider.getUserInfo( key.getUsername(), key.getHost(), key.getPassword(), null, key.getPort() ); } catch( CoreException e ) { e.printStackTrace(); } } if( userInfo == null ) { userInfo = new SSHUserInfo( key.getUsername(), key.getHost(), key.getPassword(), null, key.getPort() ); } return userInfo; } }