Author: chatellier Date: 2009-10-28 15:41:46 +0000 (Wed, 28 Oct 2009) New Revision: 2709 Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHUtils.java Log: Add sftp utilities methods. Modified: isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHUtils.java =================================================================== --- isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHUtils.java 2009-10-28 13:31:45 UTC (rev 2708) +++ isis-fish/trunk/src/main/java/fr/ifremer/isisfish/util/ssh/SSHUtils.java 2009-10-28 15:41:46 UTC (rev 2709) @@ -29,14 +29,19 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Writer; +import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; +import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; +import com.jcraft.jsch.SftpATTRS; +import com.jcraft.jsch.SftpException; +import com.jcraft.jsch.SftpProgressMonitor; /** * SSH utils class. @@ -44,9 +49,9 @@ * All this code has be taken from ant optionnal ssh task. * * Use full for: + * - exec command * - scpTo command * - scpFrom command - * - exec command * * @author chatellier * @version $Revision$ @@ -61,7 +66,7 @@ protected static final byte LINE_FEED = 0x0a; protected static final int BUFFER_SIZE = 1024; - private static final int HUNDRED_KILOBYTES = 102400; + protected static final int HUNDRED_KILOBYTES = 102400; /** Utility class */ protected SSHUtils() { @@ -467,4 +472,202 @@ fis.close(); } } + + /** + * Progress monitor (sftp). + */ + protected static class ProgressMonitor implements SftpProgressMonitor { + private long initFileSize = 0; + private long totalLength = 0; + private int percentTransmitted = 0; + + public void init(int op, String src, String dest, long max) { + initFileSize = max; + totalLength = 0; + percentTransmitted = 0; + } + + public boolean count(long len) { + totalLength += len; + percentTransmitted = trackProgress(initFileSize, + totalLength, + percentTransmitted); + return true; + } + + public void end() { + + } + + public long getTotalLength() { + return totalLength; + } + } + + /** + * Open sftp channel. + * + * @param session + * @return + * @throws JSchException + */ + protected static ChannelSftp openSftpChannel(Session session) throws JSchException { + ChannelSftp channel = (ChannelSftp) session.openChannel("sftp"); + return channel; + } + + /** + * Perform sftp file transfert. + * + * @param session + * @param localFile + * @param remotePath + * + * @throws SSHException on i/o errors + */ + public static void sftpFrom(Session session, File localFile, String remotePath) throws SSHException { + ChannelSftp channel = null; + try { + channel = openSftpChannel(session); + channel.connect(); + try { + SftpATTRS attrs = channel.stat(remotePath); + if (attrs.isDir() && !remotePath.endsWith("/")) { + remotePath = remotePath + "/"; + } + } catch (SftpException ee) { + // Ignored + } + getDir(channel, remotePath, localFile); + } catch (SftpException e) { + throw new SSHException(e); + } catch (JSchException e) { + throw new SSHException(e); + } catch (IOException e) { + throw new SSHException(e); + } finally { + if (channel != null) { + channel.disconnect(); + } + } + } + + protected static void getDir(ChannelSftp channel, + String remoteFile, + File localFile) throws IOException, SftpException { + String pwd = remoteFile; + if (remoteFile.lastIndexOf('/') != -1) { + if (remoteFile.length() > 1) { + pwd = remoteFile.substring(0, remoteFile.lastIndexOf('/')); + } + } + channel.cd(pwd); + if (!localFile.exists()) { + localFile.mkdirs(); + } + Vector files = channel.ls(remoteFile); + for (int i = 0; i < files.size(); i++) { + ChannelSftp.LsEntry le = (ChannelSftp.LsEntry) files.elementAt(i); + String name = le.getFilename(); + if (le.getAttrs().isDir()) { + if (name.equals(".") || name.equals("..")) { + continue; + } + getDir(channel, + channel.pwd() + "/" + name + "/", + new File(localFile, le.getFilename())); + } else { + getFile(channel, le, localFile); + } + } + channel.cd(".."); + } + + protected static void getFile(ChannelSftp channel, + ChannelSftp.LsEntry le, + File localFile) throws IOException, SftpException { + String remoteFile = le.getFilename(); + if (!localFile.exists()) { + String path = localFile.getAbsolutePath(); + int i = 0; + if ((i = path.lastIndexOf(File.pathSeparator)) != -1) { + if (path.length() > File.pathSeparator.length()) { + new File(path.substring(0, i)).mkdirs(); + } + } + } + + if (localFile.isDirectory()) { + localFile = new File(localFile, remoteFile); + } + + long totalLength = le.getAttrs().getSize(); + + SftpProgressMonitor monitor = null; + boolean trackProgress = totalLength > HUNDRED_KILOBYTES; + if (trackProgress) { + monitor = new ProgressMonitor(); + } + channel.get(remoteFile, localFile.getAbsolutePath(), monitor); + } + + /** + * Perform sftp file transfert. + * + * @param session + * @param localFile + * @param remoteFilePath + * + * @throws SSHException on i/o errors + */ + public static void sftpTo(Session session, File localFile, + String remoteFilePath) throws SSHException { + try { + doSingleSftpransfer(session, localFile, remoteFilePath); + } catch (IOException e) { + throw new SSHException(e); + } catch (JSchException e) { + throw new SSHException(e); + } + } + + // sftp + protected static void doSingleSftpransfer(Session session, File localFile, + String remoteFilePath) throws IOException, JSchException { + ChannelSftp channel = openSftpChannel(session); + try { + channel.connect(); + try { + sendFileToRemote(channel, localFile, remoteFilePath); + } catch (SftpException e) { + throw new JSchException(e.toString()); + } + } finally { + if (channel != null) { + channel.disconnect(); + } + } + } + + // sftp + protected static void sendFileToRemote(ChannelSftp channel, + File localFile, + String remotePath) + throws IOException, SftpException { + long filesize = localFile.length(); + + if (remotePath == null) { + remotePath = localFile.getName(); + } + + // only track progress for files larger than 100kb in verbose mode + boolean trackProgress = filesize > HUNDRED_KILOBYTES; + + SftpProgressMonitor monitor = null; + if (trackProgress) { + monitor = new ProgressMonitor(); + } + + channel.put(localFile.getAbsolutePath(), remotePath, monitor); + } }
participants (1)
-
chatellierï¼ users.labs.libre-entreprise.org