From aa9f4e192fb74d44da300708f1f7b7c221b5919c Mon Sep 17 00:00:00 2001 From: Cyril Ledru Date: Wed, 16 Mar 2011 16:15:21 +0800 Subject: [PATCH] Remove inheritance coupling between SCP*Clients Use delegation to SCPEngine instead of inheritance. Remove methods using String path for source file. --- .../sshj/xfer/scp/SCPDownloadClient.java | 68 +++++++++------- .../net/schmizz/sshj/xfer/scp/SCPEngine.java | 29 ++----- .../sshj/xfer/scp/SCPFileTransfer.java | 3 +- .../sshj/xfer/scp/SCPUploadClient.java | 81 ++++++++----------- 4 files changed, 80 insertions(+), 101 deletions(-) diff --git a/src/main/java/net/schmizz/sshj/xfer/scp/SCPDownloadClient.java b/src/main/java/net/schmizz/sshj/xfer/scp/SCPDownloadClient.java index 434f5b48..8b1f9b99 100644 --- a/src/main/java/net/schmizz/sshj/xfer/scp/SCPDownloadClient.java +++ b/src/main/java/net/schmizz/sshj/xfer/scp/SCPDownloadClient.java @@ -15,37 +15,44 @@ */ package net.schmizz.sshj.xfer.scp; -import net.schmizz.sshj.common.IOUtils; -import net.schmizz.sshj.common.SSHException; -import net.schmizz.sshj.connection.channel.direct.SessionFactory; -import net.schmizz.sshj.xfer.FileTransferUtil; -import net.schmizz.sshj.xfer.ModeSetter; -import net.schmizz.sshj.xfer.TransferListener; - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.LinkedList; import java.util.List; +import net.schmizz.sshj.common.IOUtils; +import net.schmizz.sshj.common.SSHException; +import net.schmizz.sshj.connection.channel.direct.SessionFactory; +import net.schmizz.sshj.xfer.FileTransferUtil; +import net.schmizz.sshj.xfer.ModeSetter; +import net.schmizz.sshj.xfer.TransferListener; +import net.schmizz.sshj.xfer.scp.SCPEngine.Arg; + /** Support for uploading files over a connected link using SCP. */ -public final class SCPDownloadClient - extends SCPEngine { +public final class SCPDownloadClient { private final ModeSetter modeSetter; private boolean recursive = true; + private SCPEngine engine; + SCPDownloadClient(SessionFactory host, TransferListener listener, ModeSetter modeSetter) { - super(host, listener); + engine = new SCPEngine(host, listener); this.modeSetter = modeSetter; } /** Download a file from {@code sourcePath} on the connected host to {@code targetPath} locally. */ - @Override public synchronized int copy(String sourcePath, String targetPath) throws IOException { - return super.copy(sourcePath, targetPath); + engine.cleanSlate(); + try { + startCopy(sourcePath, targetPath); + } finally { + engine.exit(); + } + return engine.exitStatus; } public boolean getRecursive() { @@ -56,17 +63,16 @@ public final class SCPDownloadClient this.recursive = recursive; } - @Override void startCopy(String sourcePath, String targetPath) throws IOException { init(sourcePath); - signal("Start status OK"); + engine.signal("Start status OK"); - String msg = readMessage(true); + String msg = engine.readMessage(true); do process(null, msg, new File(targetPath)); - while ((msg = readMessage(false)) != null); + while ((msg = engine.readMessage(false)) != null); } private void init(String source) @@ -78,7 +84,7 @@ public final class SCPDownloadClient args.add(Arg.RECURSIVE); if (modeSetter.preservesTimes()) args.add(Arg.PRESERVE_TIMES); - execSCPWith(args, source); + engine.execSCPWith(args, source); } private long parseLong(String longString, String valType) @@ -107,8 +113,8 @@ public final class SCPDownloadClient switch (msg.charAt(0)) { case 'T': - signal("ACK: T"); - process(msg, readMessage(true), f); + engine.signal("ACK: T"); + process(msg, engine.readMessage(true), f); break; case 'C': @@ -128,7 +134,7 @@ public final class SCPDownloadClient default: String err = "Unrecognized message: `" + msg + "`"; - sendMessage((char) 2 + err); + engine.sendMessage((char) 2 + err); throw new SCPException(err); } @@ -142,16 +148,16 @@ public final class SCPDownloadClient final String dirname = dMsgParts[2]; if (length != 0) throw new IOException("Remote SCP command sent strange directory length: " + length); - listener.startedDir(dirname); + engine.listener.startedDir(dirname); { f = FileTransferUtil.getTargetDirectory(f, dirname); - signal("ACK: D"); + engine.signal("ACK: D"); do { - } while (!process(null, readMessage(), f)); + } while (!process(null, engine.readMessage(), f)); setAttributes(f, parsePermissions(dMsgParts[0]), tMsg); - signal("ACK: E"); + engine.signal("ACK: E"); } - listener.finishedDir(); + engine.listener.finishedDir(); } private void processFile(String cMsg, String tMsg, File f) @@ -159,21 +165,21 @@ public final class SCPDownloadClient final String[] cMsgParts = tokenize(cMsg, 3); // C final long length = parseLong(cMsgParts[1], "length"); final String filename = cMsgParts[2]; - listener.startedFile(filename, length); + engine.listener.startedFile(filename, length); { f = FileTransferUtil.getTargetFile(f, filename); - signal("Remote can start transfer"); + engine.signal("Remote can start transfer"); final FileOutputStream fos = new FileOutputStream(f); try { - transfer(scp.getInputStream(), fos, scp.getLocalMaxPacketSize(), length); + engine.transfer(engine.scp.getInputStream(), fos, engine.scp.getLocalMaxPacketSize(), length); } finally { IOUtils.closeQuietly(fos); } - check("Remote agrees transfer done"); + engine.check("Remote agrees transfer done"); setAttributes(f, parsePermissions(cMsgParts[0]), tMsg); - signal("Transfer done"); + engine.signal("Transfer done"); } - listener.finishedFile(); + engine.listener.finishedFile(); } private void setAttributes(File f, int perms, String tMsg) diff --git a/src/main/java/net/schmizz/sshj/xfer/scp/SCPEngine.java b/src/main/java/net/schmizz/sshj/xfer/scp/SCPEngine.java index 8930ceda..de798f79 100644 --- a/src/main/java/net/schmizz/sshj/xfer/scp/SCPEngine.java +++ b/src/main/java/net/schmizz/sshj/xfer/scp/SCPEngine.java @@ -15,23 +15,22 @@ */ package net.schmizz.sshj.xfer.scp; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; + import net.schmizz.sshj.common.IOUtils; import net.schmizz.sshj.common.SSHException; import net.schmizz.sshj.connection.channel.direct.Session.Command; import net.schmizz.sshj.connection.channel.direct.SessionFactory; import net.schmizz.sshj.xfer.TransferListener; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; - /** @see SCP Protocol */ -abstract class SCPEngine { +class SCPEngine { static enum Arg { SOURCE('f'), @@ -70,17 +69,6 @@ abstract class SCPEngine { this.listener = listener; } - public int copy(String sourcePath, String targetPath) - throws IOException { - cleanSlate(); - try { - startCopy(sourcePath, targetPath); - } finally { - exit(); - } - return exitStatus; - } - public int getExitStatus() { return exitStatus; } @@ -173,9 +161,6 @@ abstract class SCPEngine { scp.getOutputStream().flush(); } - abstract void startCopy(String sourcePath, String targetPath) - throws IOException; - void transfer(InputStream in, OutputStream out, int bufSize, long len) throws IOException { final byte[] buf = new byte[bufSize]; diff --git a/src/main/java/net/schmizz/sshj/xfer/scp/SCPFileTransfer.java b/src/main/java/net/schmizz/sshj/xfer/scp/SCPFileTransfer.java index b7d95cb9..7329989f 100644 --- a/src/main/java/net/schmizz/sshj/xfer/scp/SCPFileTransfer.java +++ b/src/main/java/net/schmizz/sshj/xfer/scp/SCPFileTransfer.java @@ -19,6 +19,7 @@ import java.io.IOException; import net.schmizz.sshj.connection.channel.direct.SessionFactory; import net.schmizz.sshj.xfer.AbstractFileTransfer; +import net.schmizz.sshj.xfer.FileSystemFile; import net.schmizz.sshj.xfer.FileTransfer; import net.schmizz.sshj.xfer.LocalFile; @@ -49,7 +50,7 @@ public class SCPFileTransfer @Override public void upload(String localPath, String remotePath) throws IOException { - newSCPUploadClient().copy(localPath, remotePath); + newSCPUploadClient().copy(new FileSystemFile(localPath), remotePath); } public void upload(LocalFile localFile, String remotePath) diff --git a/src/main/java/net/schmizz/sshj/xfer/scp/SCPUploadClient.java b/src/main/java/net/schmizz/sshj/xfer/scp/SCPUploadClient.java index cd5cdce9..a3a89809 100644 --- a/src/main/java/net/schmizz/sshj/xfer/scp/SCPUploadClient.java +++ b/src/main/java/net/schmizz/sshj/xfer/scp/SCPUploadClient.java @@ -29,55 +29,42 @@ import net.schmizz.sshj.connection.channel.direct.SessionFactory; import net.schmizz.sshj.xfer.LocalFile; import net.schmizz.sshj.xfer.ModeGetter; import net.schmizz.sshj.xfer.TransferListener; +import net.schmizz.sshj.xfer.scp.SCPEngine.Arg; /** Support for uploading files over a connected link using SCP. */ -public final class SCPUploadClient - extends SCPEngine { +public final class SCPUploadClient { private final ModeGetter modeGetter; private FileFilter fileFilter; - SCPUploadClient(SessionFactory host, TransferListener listener, ModeGetter modeGetter) { - super(host, listener); - this.modeGetter = modeGetter; - } + private SCPEngine engine; - /** Upload a file from {@code sourcePath} locally to {@code targetPath} on the remote host. */ - @Override - public synchronized int copy(String sourcePath, String targetPath) - throws IOException { - return super.copy(sourcePath, targetPath); + SCPUploadClient(SessionFactory host, TransferListener listener, ModeGetter modeGetter) { + engine = new SCPEngine(host, listener); + this.modeGetter = modeGetter; } /** Upload a local file from {@code localFile} to {@code targetPath} on the remote host. */ public synchronized int copy(LocalFile sourceFile, String remotePath) throws IOException { - cleanSlate(); + engine.cleanSlate(); try { startCopy(sourceFile, remotePath); } finally { - exit(); + engine.exit(); } - return exitStatus; + return engine.exitStatus; } public void setFileFilter(FileFilter fileFilter) { this.fileFilter = fileFilter; } - @Override - protected synchronized void startCopy(String sourcePath, String targetPath) - throws IOException { - init(targetPath); - check("Start status OK"); - process(new File(sourcePath)); - } - - protected synchronized void startCopy(LocalFile sourceFile, String targetPath) + private synchronized void startCopy(LocalFile sourceFile, String targetPath) throws IOException { init(targetPath); - check("Start status OK"); + engine.check("Start status OK"); process(sourceFile); } @@ -96,19 +83,19 @@ public final class SCPUploadClient args.add(Arg.RECURSIVE); if (modeGetter.preservesTimes()) args.add(Arg.PRESERVE_TIMES); - execSCPWith(args, target); + engine.execSCPWith(args, target); } private void process(File f) throws IOException { if (f.isDirectory()) { - listener.startedDir(f.getName()); + engine.listener.startedDir(f.getName()); sendDirectory(f); - listener.finishedDir(); + engine.listener.finishedDir(); } else if (f.isFile()) { - listener.startedFile(f.getName(), f.length()); + engine.listener.startedFile(f.getName(), f.length()); sendFile(f); - listener.finishedFile(); + engine.listener.finishedFile(); } else throw new IOException(f + " is not a regular file or directory"); } @@ -116,13 +103,13 @@ public final class SCPUploadClient private void process(LocalFile f) throws IOException { if (f.isDirectory()) { - listener.startedDir(f.getName()); + engine.listener.startedDir(f.getName()); sendDirectory(f); - listener.finishedDir(); + engine.listener.finishedDir(); } else if (f.isFile()) { - listener.startedFile(f.getName(), f.length()); + engine.listener.startedFile(f.getName(), f.length()); sendFile(f); - listener.finishedFile(); + engine.listener.finishedFile(); } else throw new IOException(f + " is not a regular file or directory"); } @@ -130,19 +117,19 @@ public final class SCPUploadClient private void sendDirectory(File f) throws IOException { preserveTimeIfPossible(f); - sendMessage("D0" + getPermString(f) + " 0 " + f.getName()); + engine.sendMessage("D0" + getPermString(f) + " 0 " + f.getName()); for (File child : getChildren(f)) process(child); - sendMessage("E"); + engine.sendMessage("E"); } private void sendDirectory(LocalFile f) throws IOException { preserveTimeIfPossible(f); - sendMessage("D0" + getPermString(f) + " 0 " + f.getName()); + engine.sendMessage("D0" + getPermString(f) + " 0 " + f.getName()); for (LocalFile child : f.getChildren()) process(child); - sendMessage("E"); + engine.sendMessage("E"); } private void sendFile(File f) @@ -150,10 +137,10 @@ public final class SCPUploadClient preserveTimeIfPossible(f); final InputStream src = new FileInputStream(f); try { - sendMessage("C0" + getPermString(f) + " " + f.length() + " " + f.getName()); - transfer(src, scp.getOutputStream(), scp.getRemoteMaxPacketSize(), f.length()); - signal("Transfer done"); - check("Remote agrees transfer done"); + engine.sendMessage("C0" + getPermString(f) + " " + f.length() + " " + f.getName()); + engine.transfer(src, engine.scp.getOutputStream(), engine.scp.getRemoteMaxPacketSize(), f.length()); + engine.signal("Transfer done"); + engine.check("Remote agrees transfer done"); } finally { IOUtils.closeQuietly(src); } @@ -164,10 +151,10 @@ public final class SCPUploadClient preserveTimeIfPossible(f); final InputStream src = f.stream(); try { - sendMessage("C0" + getPermString(f) + " " + f.length() + " " + f.getName()); - transfer(src, scp.getOutputStream(), scp.getRemoteMaxPacketSize(), f.length()); - signal("Transfer done"); - check("Remote agrees transfer done"); + engine.sendMessage("C0" + getPermString(f) + " " + f.length() + " " + f.getName()); + engine.transfer(src, engine.scp.getOutputStream(), engine.scp.getRemoteMaxPacketSize(), f.length()); + engine.signal("Transfer done"); + engine.check("Remote agrees transfer done"); } finally { IOUtils.closeQuietly(src); } @@ -176,13 +163,13 @@ public final class SCPUploadClient private void preserveTimeIfPossible(File f) throws IOException { if (modeGetter.preservesTimes()) - sendMessage("T" + modeGetter.getLastModifiedTime(f) + " 0 " + modeGetter.getLastAccessTime(f) + " 0"); + engine.sendMessage("T" + modeGetter.getLastModifiedTime(f) + " 0 " + modeGetter.getLastAccessTime(f) + " 0"); } private void preserveTimeIfPossible(LocalFile f) throws IOException { if (modeGetter.preservesTimes()) - sendMessage("T" + modeGetter.getLastModifiedTime(f) + " 0 " + modeGetter.getLastAccessTime(f) + " 0"); + engine.sendMessage("T" + modeGetter.getLastModifiedTime(f) + " 0 " + modeGetter.getLastAccessTime(f) + " 0"); } private String getPermString(File f)