
fi.evolver.utils.ftp.SftpConnection Maven / Gradle / Ivy
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