From f1389f23a49745fb2bb3b026162e094b7e38d5a3 Mon Sep 17 00:00:00 2001 From: Josh Greatrex Date: Thu, 8 May 2014 16:14:44 +0100 Subject: [PATCH] Updates to #download() methods on Connection Changed to accept two strings instead of FtpFile. Turned out to be pointless and also stopped users from downloading an already known file. --- build.gradle | 9 ++- src/main/java/jftp/connection/Connection.java | 73 +------------------ .../java/jftp/connection/FtpConnection.java | 21 +++--- .../java/jftp/connection/SftpConnection.java | 6 +- .../jftp/connection/FtpConnectionTest.java | 43 +++++------ .../jftp/connection/SftpConnectionTest.java | 14 ++-- 6 files changed, 47 insertions(+), 119 deletions(-) diff --git a/build.gradle b/build.gradle index 1aceb9f..fc0c9a8 100644 --- a/build.gradle +++ b/build.gradle @@ -3,11 +3,12 @@ apply plugin: 'eclipse' apply plugin: 'application' group 'jftp' -version '0.1-alpha' +version '0.2-alpha' repositories { mavenCentral() } dependencies { + compile 'com.jcraft:jsch:0.1.50' compile 'joda-time:joda-time:2.3' compile 'commons-net:commons-net:3.3' @@ -26,5 +27,9 @@ task jarWithDependencies(type: Jar, dependsOn: 'build') { from files(sourceSets.main.output.classesDir) from files(sourceSets.main.output.resourcesDir) - from {configurations.compile.collect {zipTree(it)}} + from { + configurations.compile.collect { + zipTree(it) + } + } } \ No newline at end of file diff --git a/src/main/java/jftp/connection/Connection.java b/src/main/java/jftp/connection/Connection.java index 82970c4..6462d7a 100644 --- a/src/main/java/jftp/connection/Connection.java +++ b/src/main/java/jftp/connection/Connection.java @@ -7,80 +7,15 @@ public interface Connection { - /** - * Equivalent of a standard 'cd' on a directory. This will set the current working directory - * on the active connection to the given file path. - * - * @param - * directory - The directory to change to. Equivalent of a 'cd' command. - * - * @throws - * FtpException - */ void changeDirectory(String directory) throws FtpException; - - /** - * Reads out the current directory on the server. - * - * @return Absolute path purporting to the current working directory. - */ + String printWorkingDirectory() throws FtpException; - /** - * Lists all files and directories under the current working directory. - * - * @return - * A list of FtpFiles detailing what is in the current working directory. - * - * @throws - * FtpException - */ List listFiles() throws FtpException; - - /** - * Lists all files in the given path. This will accept either relative or absolute paths. - * - * E.g. If currently in /foo - listFiles('bar') will list files in /foo/bar. - * E.g. If currently in /foo - listFiles('/bar') will list files in /bar. - * - * @param - * path - * - * @return - * A list of FtpFiles within relative path. - * - * @throws - * FtpException - */ + List listFiles(String path) throws FtpException; - /** - * Downloads the given file to the given local directory. - * - * @param - * file file/directory to download - * - * @param - * localDirectory Local directory to download item to. This should NOT include the file name as this method - * will handle the creation of the file for the physical download. - * - * @throws - * FtpException - */ - void download(FtpFile file, String localDirectory) throws FtpException; - - /** - * Uploads the given file/directory to the given local directory. - * - * @param - * localFilePath Local file/directory to upload. - * - * @param - * remoteDirectory This is the remote directory that the local file will be uploaded to. The path supplied must be - * a valid directory (not including file name). - * - * @throws - * FtpException - */ + void download(String remoteFilePath, String localDirectory) throws FtpException; + void upload(String localFilePath, String remoteDirectory) throws FtpException; } diff --git a/src/main/java/jftp/connection/FtpConnection.java b/src/main/java/jftp/connection/FtpConnection.java index 7490d3a..aafb404 100644 --- a/src/main/java/jftp/connection/FtpConnection.java +++ b/src/main/java/jftp/connection/FtpConnection.java @@ -97,15 +97,15 @@ public List listFiles(String remotePath) throws FtpException { } @Override - public void download(FtpFile file, String localDirectory) throws FtpException { + public void download(String remoteFilePath, String localDirectory) throws FtpException { - String localDestination = String.format("%s%s%s", localDirectory, FILE_SEPARATOR, file.getName()); + String localDestination = determinePath(remoteFilePath, localDirectory); try { OutputStream outputStream = fileStreamFactory.createOutputStream(localDestination); - boolean hasDownloaded = client.retrieveFile(file.getFullPath(), outputStream); + boolean hasDownloaded = client.retrieveFile(remoteFilePath, outputStream); outputStream.close(); @@ -117,7 +117,7 @@ public void download(FtpFile file, String localDirectory) throws FtpException { } catch (IOException e) { - throw new FtpException(String.format(FILE_DOWNLOAD_FAILURE_MESSAGE, file.getName()), e); + throw new FtpException(String.format(FILE_DOWNLOAD_FAILURE_MESSAGE, remoteFilePath), e); } } @@ -128,7 +128,7 @@ public void upload(String localFilePath, String remoteDirectory) throws FtpExcep InputStream localFileInputStream = fileStreamFactory.createInputStream(localFilePath); - boolean hasUploaded = client.storeFile(determineRemotePath(localFilePath, remoteDirectory), localFileInputStream); + boolean hasUploaded = client.storeFile(determinePath(localFilePath, remoteDirectory), localFileInputStream); localFileInputStream.close(); @@ -141,17 +141,16 @@ public void upload(String localFilePath, String remoteDirectory) throws FtpExcep throw new FtpException("Upload may not have completed.", e); } - } - private String determineRemotePath(String localFilePath, String remoteDirectory) { + private String determinePath(String sourcePathWithName, String targetPathWithoutName) { - Path remotePath = Paths.get(remoteDirectory); + Path targetPath = Paths.get(targetPathWithoutName); - String safeRemotePath = remotePath.toString(); - String fileName = Paths.get(localFilePath).getFileName().toString(); + String safePath = targetPath.toString(); + String fileName = Paths.get(sourcePathWithName).getFileName().toString(); - return safeRemotePath + remotePath.getFileSystem().getSeparator() + fileName; + return safePath + targetPath.getFileSystem().getSeparator() + fileName; } private void ensureFileHasSuccessfullyUploaded(boolean hasUploaded) { diff --git a/src/main/java/jftp/connection/SftpConnection.java b/src/main/java/jftp/connection/SftpConnection.java index 3e38240..014a58c 100644 --- a/src/main/java/jftp/connection/SftpConnection.java +++ b/src/main/java/jftp/connection/SftpConnection.java @@ -95,15 +95,15 @@ public List listFiles(String remotePath) throws FtpException { } @Override - public void download(FtpFile file, String localDirectory) throws FtpException { + public void download(String remoteFilePath, String localDirectory) throws FtpException { try { - channel.get(file.getName(), localDirectory); + channel.get(remoteFilePath, localDirectory); } catch (SftpException e) { - throw new FtpException("Unable to download file " + file.getName(), e); + throw new FtpException("Unable to download file " + remoteFilePath, e); } } diff --git a/src/test/java/jftp/connection/FtpConnectionTest.java b/src/test/java/jftp/connection/FtpConnectionTest.java index fb5d46c..d897862 100644 --- a/src/test/java/jftp/connection/FtpConnectionTest.java +++ b/src/test/java/jftp/connection/FtpConnectionTest.java @@ -23,7 +23,6 @@ import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; -import org.joda.time.DateTime; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -36,9 +35,7 @@ public class FtpConnectionTest { private static final String LOCAL_DIRECTORY = "."; - private static final String TEST_DOWNLOAD_FILE = "jUnit_Mock_File.txt"; private static final String DIRECTORY_PATH = "this/is/a/directory"; - private static final String FILE_SEPARATOR = System.getProperty("file.separator"); @InjectMocks private FtpConnection ftpConnection; @@ -172,16 +169,21 @@ public void whenListingFilesAndGivingRelativePathThenThatPathShouldBeUsedAlongsi verify(mockFtpClient).listFiles(DIRECTORY_PATH + "/relativePath"); } + + @Test + public void downloadMethodShouldCreateLocalFileStreamFromCorrectPathBasedOnRemoteFileName() throws FileNotFoundException { + + ftpConnection.download("path/to/remote.file", LOCAL_DIRECTORY); + + verify(mockFileStreamFactory).createOutputStream(LOCAL_DIRECTORY + "/remote.file"); + } @Test public void downloadMethodShouldCallOnFtpClientRetrieveFilesMethodWithRemoteFilename() throws IOException { - FtpFile file = new FtpFile(TEST_DOWNLOAD_FILE, 1000, "/full/path/to/FileToDownload.txt", new DateTime().getMillis(), - false); + ftpConnection.download("path/to/remote.file", LOCAL_DIRECTORY); - ftpConnection.download(file, LOCAL_DIRECTORY); - - verify(mockFtpClient).retrieveFile(file.getFullPath(), mockFileOutputStream); + verify(mockFtpClient).retrieveFile("path/to/remote.file", mockFileOutputStream); } @Test @@ -189,14 +191,11 @@ public void downloadMethodShouldThrowExceptionIfUnableToOpenStreamToLocalFile() expectedException.expect(FtpException.class); expectedException - .expectMessage(is(equalTo("Unable to write to local directory ." + FILE_SEPARATOR + TEST_DOWNLOAD_FILE))); - - FtpFile file = new FtpFile(TEST_DOWNLOAD_FILE, 1000, "/full/path/to/FileToDownload.txt", new DateTime().getMillis(), - false); + .expectMessage(is(equalTo("Unable to write to local directory " + LOCAL_DIRECTORY + "/remote.file"))); - when(mockFtpClient.retrieveFile(file.getFullPath(), mockFileOutputStream)).thenThrow(new FileNotFoundException()); + when(mockFtpClient.retrieveFile("path/to/remote.file", mockFileOutputStream)).thenThrow(new FileNotFoundException()); - ftpConnection.download(file, LOCAL_DIRECTORY); + ftpConnection.download("path/to/remote.file", LOCAL_DIRECTORY); } @Test @@ -204,14 +203,11 @@ public void shouldDownloadFailForAnyReasonWhileInProgressThenCatchIOExceptionAnd throws IOException { expectedException.expect(FtpException.class); - expectedException.expectMessage(is(equalTo("Unable to download file " + TEST_DOWNLOAD_FILE))); + expectedException.expectMessage(is(equalTo("Unable to download file path/to/remote.file"))); - FtpFile file = new FtpFile(TEST_DOWNLOAD_FILE, 1000, "/full/path/to/FileToDownload.txt", new DateTime().getMillis(), - false); + when(mockFtpClient.retrieveFile("path/to/remote.file", mockFileOutputStream)).thenThrow(new IOException()); - when(mockFtpClient.retrieveFile(file.getFullPath(), mockFileOutputStream)).thenThrow(new IOException()); - - ftpConnection.download(file, LOCAL_DIRECTORY); + ftpConnection.download("path/to/remote.file", LOCAL_DIRECTORY); } @Test @@ -220,12 +216,9 @@ public void ifRetrieveFileMethodInClientReturnsFalseThenThrowDownloadFailedExcep expectedException.expect(FtpException.class); expectedException.expectMessage(is(equalTo("Server returned failure while downloading."))); - FtpFile file = new FtpFile(TEST_DOWNLOAD_FILE, 1000, "/full/path/to/FileToDownload.txt", new DateTime().getMillis(), - false); - - when(mockFtpClient.retrieveFile(file.getFullPath(), mockFileOutputStream)).thenReturn(false); + when(mockFtpClient.retrieveFile("path/to/remote.file", mockFileOutputStream)).thenReturn(false); - ftpConnection.download(file, LOCAL_DIRECTORY); + ftpConnection.download("path/to/remote.file", LOCAL_DIRECTORY); } @Test diff --git a/src/test/java/jftp/connection/SftpConnectionTest.java b/src/test/java/jftp/connection/SftpConnectionTest.java index b8fc7f8..094f1d7 100644 --- a/src/test/java/jftp/connection/SftpConnectionTest.java +++ b/src/test/java/jftp/connection/SftpConnectionTest.java @@ -178,24 +178,20 @@ public void returnedFtpFilesShouldHaveCorrectModifiedDateTimesAgainstThem() { @Test public void downloadMethodShouldCallChannelGetMethodWithFtpFileNameAndDirectory() throws SftpException { - FtpFile file = new FtpFile("File Name.txt", 1000, "/remote/server/dir/File Name.txt", 123456789, false); + sftpConnection.download("path/to/file.txt", "some/directory"); - sftpConnection.download(file, "some/directory"); - - verify(mockChannel).get("File Name.txt", "some/directory"); + verify(mockChannel).get("path/to/file.txt", "some/directory"); } @Test public void downloadMethodShouldThrowDownloadFailedExceptionWhenChannelThrowsSftpConnection() throws SftpException { expectedException.expect(FtpException.class); - expectedException.expectMessage(is(equalTo("Unable to download file File Name.txt"))); - - doThrow(new SftpException(999, "")).when(mockChannel).get(anyString(), anyString()); + expectedException.expectMessage(is(equalTo("Unable to download file path/to/file.txt"))); - FtpFile file = new FtpFile("File Name.txt", 1000, "remote/server/dir/File Name.txt", 123456789, false); + doThrow(new SftpException(999, "")).when(mockChannel).get("path/to/file.txt", "some/directory"); - sftpConnection.download(file, "some/directory"); + sftpConnection.download("path/to/file.txt", "some/directory"); } @Test