All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fi.evolver.utils.ftp.SftpConnection Maven / Gradle / Ivy

There is a newer version: 3.5.0
Show newest version
package fi.evolver.utils.ftp;

import java.io.InputStream;
import java.net.URI;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

import fi.evolver.utils.CommunicationException;
import fi.evolver.utils.UriUtils;

public class SftpConnection extends RemoteConnection {
	private Session session;
	private ChannelSftp channel;


	private SftpConnection() { }


	public static SftpConnection connect(URI uri, int connectTimeoutMs, int readTimeoutMs, List identityFiles) throws CommunicationException {
		if (uri == null)
			throw new NullPointerException("Connection URI can not be null");
		if (!"sftp".equals(uri.getScheme()))
			throw new CommunicationException("The %s protocol is not supported", uri.getScheme());

		SftpConnection connection = new SftpConnection();
		connection.initConnection(uri, connectTimeoutMs, readTimeoutMs, identityFiles);
		return connection;
	}


	@Override
	public List list(Pattern filter) throws CommunicationException {
		try {
			@SuppressWarnings("unchecked")
			List entries = new ArrayList<>(channel.ls("."));

			List results = new ArrayList<>();
			for (ChannelSftp.LsEntry entry: entries) {
				if (filter != null) {
					Matcher m = filter.matcher(entry.getFilename());
					if (!m.matches())
						continue;
				}

				LocalDateTime modified = new Timestamp(entry.getAttrs().getMTime() * 1000L).toLocalDateTime();
				results.add(new RemoteFile(entry.getFilename(), entry.getAttrs().getSize(), modified, entry.getAttrs().isDir()));
			}

			return results;
		}
		catch (SftpException e) {
			throw new CommunicationException(e, "Listing files failed");
		}
	}


	@Override
	public InputStream download(String remote) throws CommunicationException {
		try {
			return channel.get(remote);
		}
		catch (SftpException e) {
			throw new CommunicationException(e, "Initiating download of %s failed", remote);
		}
	}


	@Override
	public void rename(String from, String to) throws CommunicationException {
		try {
			channel.rename(from, to);
		}
		catch (SftpException e) {
			throw new CommunicationException(e, "Renaming %s to %s failed", from, to);
		}
	}


	@Override
	public void upload(String remote, InputStream local) throws CommunicationException {
		try {
			channel.put(local, remote);
		}
		catch (SftpException e) {
			throw new CommunicationException(e, "Uploading file to %s failed", remote);
		}
	}


	@Override
	public String pwd() throws CommunicationException {
		try {
			String dir = channel.pwd();
			if (dir == null)
				throw new CommunicationException("Checking current directory failed");
			return dir;
		}
		catch (SftpException e) {
			throw new CommunicationException(e, "Checking current directory failed");
		}
	}


	@Override
	public void cd(String directory) throws CommunicationException {
		try {
			channel.cd(directory);
		}
		catch (SftpException e) {
			throw new CommunicationException(e, "Changing directory to %s failed", directory);
		}
	}


	@Override
	public void rm(String remote) throws CommunicationException {
		try {
			channel.rm(remote);
		}
		catch (SftpException e) {
			throw new CommunicationException(e, "Deleting file %s failed", remote);
		}
	}


	@Override
	public void rmdir(String remote) throws CommunicationException {
		try {
			channel.rmdir(remote);
		}
		catch (SftpException e) {
			throw new CommunicationException(e, "Deleting file %s failed", remote);
		}
	}


	@Override
	public void mkdir(String remote) throws CommunicationException {
		try {
			channel.mkdir(remote);
		}
		catch (SftpException e) {
			throw new CommunicationException(e, "Creating directory %s failed", remote);
		}
	}


	@Override
	public void close() throws CommunicationException {
		if (!channel.isClosed()) {
			channel.exit();
			session.disconnect();
		}
	}


	private void initConnection(URI uri, int connectTimeoutMs, int readTimeoutMs, List identityFiles) throws CommunicationException {
		try {
			this.session = startSftpSession(uri, connectTimeoutMs, readTimeoutMs, identityFiles);
			this.channel = (ChannelSftp)session.openChannel("sftp");
			this.channel.connect(connectTimeoutMs);
		}
		catch (JSchException e) {
			throw new CommunicationException(e, "SFTP connection to %s failed", uri.getHost());
		}
	}


	private static Session startSftpSession(URI uri, int connectTimeoutMs, int readTimeoutMs, List identityFiles) throws JSchException {
		JSch jsch = new JSch();
		for (String identityFile: identityFiles)
			jsch.addIdentity(identityFile);
		int port = uri.getPort() == -1 ? 22 : uri.getPort();
		Session session = jsch.getSession(UriUtils.getUserName(uri), uri.getHost(), port);
		String password = UriUtils.getPassword(uri);
		if (password != null)
			session.setPassword(password);

		session.setConfig("compression.s2c", "[email protected],zlib,none");
		session.setConfig("compression.c2s", "[email protected],zlib,none");
		session.setConfig("compression_level", "9");

		session.setConfig("StrictHostKeyChecking", "no");

		session.connect(connectTimeoutMs);
		session.setTimeout(readTimeoutMs);
		return session;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy