diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/config/FtpInboundChannelAdapterParser.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/config/FtpInboundChannelAdapterParser.java index 0e29f546bb..ac300ce95f 100644 --- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/config/FtpInboundChannelAdapterParser.java +++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/config/FtpInboundChannelAdapterParser.java @@ -19,6 +19,8 @@ package org.springframework.integration.ftp.config; import org.springframework.integration.file.config.AbstractRemoteFileInboundChannelAdapterParser; /** + * Parser for the FTP 'inbound-channel-adapter' element. + * * @author Mark Fisher * @since 2.0 */ diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/filters/FtpRegexPatternFileListFilter.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/filters/FtpRegexPatternFileListFilter.java index fc377f2efa..0ada50d8a2 100644 --- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/filters/FtpRegexPatternFileListFilter.java +++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/filters/FtpRegexPatternFileListFilter.java @@ -23,6 +23,8 @@ import org.apache.commons.net.ftp.FTPFile; import org.springframework.integration.file.filters.AbstractRegexPatternFileListFilter; /** + * Implementation of {@link AbstractRegexPatternFileListFilter} for FTP. + * * @author Mark Fisher * @since 2.0 */ diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/filters/FtpSimplePatternFileListFilter.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/filters/FtpSimplePatternFileListFilter.java index d42e6701c2..2aad1f1dab 100644 --- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/filters/FtpSimplePatternFileListFilter.java +++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/filters/FtpSimplePatternFileListFilter.java @@ -21,6 +21,8 @@ import org.apache.commons.net.ftp.FTPFile; import org.springframework.integration.file.filters.AbstractSimplePatternFileListFilter; /** + * Implementation of {@link AbstractSimplePatternFileListFilter} for FTP. + * * @author Mark Fisher * @since 2.0 */ diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/inbound/FtpInboundFileSynchronizer.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/inbound/FtpInboundFileSynchronizer.java index 45d7e2bfd0..17d004ffcc 100644 --- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/inbound/FtpInboundFileSynchronizer.java +++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/inbound/FtpInboundFileSynchronizer.java @@ -23,10 +23,12 @@ import org.springframework.integration.file.remote.session.SessionFactory; import org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer; /** - * An FTP-adapter implementation of {@link org.springframework.integration.file.synchronization.AbstractInboundRemoteFileSystemSychronizer} + * An implementation of {@link AbstractInboundFileSynchronizer} for FTP. * * @author Iwein Fuld * @author Josh Long + * @author Mark Fisher + * @since 2.0 */ public class FtpInboundFileSynchronizer extends AbstractInboundFileSynchronizer { @@ -40,12 +42,12 @@ public class FtpInboundFileSynchronizer extends AbstractInboundFileSynchronizer< @Override protected boolean isFile(FTPFile file) { - return file.isFile(); + return file != null && file.isFile(); } @Override protected String getFilename(FTPFile file) { - return file.getName(); + return (file != null ? file.getName() : null); } } diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/inbound/FtpInboundFileSynchronizingMessageSource.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/inbound/FtpInboundFileSynchronizingMessageSource.java index e7a99fa6a8..40a72ea4c9 100644 --- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/inbound/FtpInboundFileSynchronizingMessageSource.java +++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/inbound/FtpInboundFileSynchronizingMessageSource.java @@ -26,11 +26,12 @@ import org.springframework.integration.file.remote.synchronizer.AbstractInboundF * * @author Iwein Fuld * @author Josh Long + * @author Mark Fisher * @since 2.0 */ public class FtpInboundFileSynchronizingMessageSource extends AbstractInboundFileSynchronizingMessageSource { - public FtpInboundFileSynchronizingMessageSource( AbstractInboundFileSynchronizer synchronizer) { + public FtpInboundFileSynchronizingMessageSource(AbstractInboundFileSynchronizer synchronizer) { super(synchronizer); } diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/AbstractFtpSessionFactory.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/AbstractFtpSessionFactory.java index a95a1156fb..d54a974cfd 100644 --- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/AbstractFtpSessionFactory.java +++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/AbstractFtpSessionFactory.java @@ -30,12 +30,13 @@ import org.springframework.integration.MessagingException; import org.springframework.integration.file.remote.session.Session; import org.springframework.integration.file.remote.session.SessionFactory; import org.springframework.util.Assert; -import org.springframework.util.StringUtils; /** * Base class for FTP SessionFactory implementations. * * @author Iwein Fuld + * @author Mark Fisher + * @since 2.0 */ public abstract class AbstractFtpSessionFactory implements SessionFactory { @@ -56,8 +57,6 @@ public abstract class AbstractFtpSessionFactory implements protected String remoteWorkingDirectory = DEFAULT_REMOTE_WORKING_DIRECTORY; - - protected int clientMode = FTPClient.ACTIVE_LOCAL_DATA_CONNECTION_MODE; protected int fileType = FTP.BINARY_FILE_TYPE; @@ -127,20 +126,6 @@ public abstract class AbstractFtpSessionFactory implements this.clientMode = clientMode; } - protected abstract T createSingleInstanceOfClient(); - - /** - * this is a hook to setup the state of the {@link org.apache.commons.net.ftp.FTPClient} impl *after* the - * implementation's {@link org.apache.commons.net.ftp.FTPClient#connect(String)} method's been called but before any - * action's been taken. - * - * @param t the ftp client instance on which to act - * @throws IOException if anything should go wrong - */ - protected void onAfterConnect(T t) throws IOException { - // NOOP - } - public Session getSession() { try { T client = this.createClient(); @@ -154,47 +139,39 @@ public abstract class AbstractFtpSessionFactory implements } } - T createClient() throws SocketException, IOException { - T client = createSingleInstanceOfClient(); - client.configure(config); - - if (!StringUtils.hasText(username)) { - throw new MessagingException("username is required"); - } - - client.connect(host); - onAfterConnect(client); - + private T createClient() throws SocketException, IOException { + T client = this.createClientInstance(); + Assert.notNull(client, "client must not be null"); + client.configure(this.config); + Assert.hasText(this.username, "username is required"); + client.connect(this.host); + this.afterConnect(client); if (!FTPReply.isPositiveCompletion(client.getReplyCode())) { - throw new MessagingException("Connecting to server [" + host + ":" + - port + "] failed, please check the connection"); + throw new MessagingException("Connecting to server [" + + this.host + ":" + this.port + "] failed. Please check the connection."); } - if (logger.isDebugEnabled()) { - logger.debug("Connected to server [" + host + ":" + port + "]"); + logger.debug("Connected to server [" + this.host + ":" + this.port + "]"); } - if (!client.login(username, password)) { throw new MessagingException( "Login failed. Please check the username and password."); } - this.updateClientMode(client); client.setFileType(this.fileType); - if (logger.isDebugEnabled()) { logger.debug("login successful"); } - - if (!remoteWorkingDirectory.equals(client.printWorkingDirectory()) && - !client.changeWorkingDirectory(remoteWorkingDirectory)) { + if (!this.remoteWorkingDirectory.equals(client.printWorkingDirectory()) && + !client.changeWorkingDirectory(this.remoteWorkingDirectory)) { throw new MessagingException("Could not change directory to '" + remoteWorkingDirectory + "'. Please check the path."); } - if (logger.isDebugEnabled()) { - logger.debug("working directory is: " + - client.printWorkingDirectory()); + logger.debug("working directory is: " + client.printWorkingDirectory()); + } + if (client != null) { + this.postProcessClient(client); } return client; } @@ -203,7 +180,7 @@ public abstract class AbstractFtpSessionFactory implements * Sets the mode of the connection. Only local modes are supported. */ private void updateClientMode(FTPClient client) { - switch (clientMode) { + switch (this.clientMode) { case FTPClient.ACTIVE_LOCAL_DATA_CONNECTION_MODE: client.enterLocalActiveMode(); break; @@ -215,4 +192,22 @@ public abstract class AbstractFtpSessionFactory implements } } + protected abstract T createClientInstance(); + + /** + * this is a hook to setup the state of the {@link org.apache.commons.net.ftp.FTPClient} impl *after* the + * implementation's {@link org.apache.commons.net.ftp.FTPClient#connect(String)} method's been called but before any + * action's been taken. + * + * @param t the ftp client instance on which to act + * @throws IOException if anything should go wrong + */ + protected void afterConnect(T t) throws IOException { + // NOOP + } + + protected void postProcessClient(T t) throws IOException { + // NOOP + } + } diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/DefaultFtpSessionFactory.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/DefaultFtpSessionFactory.java index 4a94717ca9..42231a40e8 100644 --- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/DefaultFtpSessionFactory.java +++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/DefaultFtpSessionFactory.java @@ -18,17 +18,17 @@ package org.springframework.integration.ftp.session; import org.apache.commons.net.ftp.FTPClient; - /** - * Default implementation of FtpClientFactory. + * Default implementation of FTP SessionFactory. * * @author Iwein Fuld * @author Josh Long + * @since 2.0 */ public class DefaultFtpSessionFactory extends AbstractFtpSessionFactory { @Override - protected FTPClient createSingleInstanceOfClient() { + protected FTPClient createClientInstance() { return new FTPClient(); } diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/DefaultFtpsSessionFactory.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/DefaultFtpsSessionFactory.java index f3ebc92fd9..044433fab3 100644 --- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/DefaultFtpsSessionFactory.java +++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/DefaultFtpsSessionFactory.java @@ -27,10 +27,12 @@ import org.apache.commons.net.ftp.FTPSClient; import org.springframework.util.StringUtils; /** - * provides a working FTPS implementation. Based heavily on {@link org.springframework.integration.ftp.session.DefaultFtpSessionFactory} + * SessionFactory for FTPS. * * @author Josh Long * @author Iwein Fuld + * @author Mark Fisher + * @since 2.0 */ public class DefaultFtpsSessionFactory extends AbstractFtpSessionFactory { @@ -108,14 +110,26 @@ public class DefaultFtpsSessionFactory extends AbstractFtpSessionFactory { @Override - protected FTPClient createSingleInstanceOfClient() { + protected FTPClient createClientInstance() { try { when(ftpClient.getReplyCode()).thenReturn(250); when(ftpClient.login("kermit", "frog")).thenReturn(true); diff --git a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/outbound/FtpSendingMessageHandlerTest.java b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/outbound/FtpSendingMessageHandlerTest.java index 4a80b529be..b5324844d8 100644 --- a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/outbound/FtpSendingMessageHandlerTest.java +++ b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/outbound/FtpSendingMessageHandlerTest.java @@ -114,11 +114,12 @@ public class FtpSendingMessageHandlerTest { handler.handleMessage(new GenericMessage(new File("template.mf"))); assertTrue(file.exists()); } - - + + public static class TestFtpSessionFactory extends AbstractFtpSessionFactory { + @Override - protected FTPClient createSingleInstanceOfClient() { + protected FTPClient createClientInstance() { try { when(ftpClient.getReplyCode()).thenReturn(250); when(ftpClient.login("kermit", "frog")).thenReturn(true); diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/inbound/SftpInboundFileSynchronizer.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/inbound/SftpInboundFileSynchronizer.java index 25f2e1e4e9..38656d3617 100644 --- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/inbound/SftpInboundFileSynchronizer.java +++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/inbound/SftpInboundFileSynchronizer.java @@ -29,7 +29,7 @@ import com.jcraft.jsch.ChannelSftp.LsEntry; * @author Mark Fisher * @since 2.0 */ -class SftpInboundFileSynchronizer extends AbstractInboundFileSynchronizer { +public class SftpInboundFileSynchronizer extends AbstractInboundFileSynchronizer { public SftpInboundFileSynchronizer(SessionFactory sessionFactory) { super(sessionFactory); @@ -43,7 +43,7 @@ class SftpInboundFileSynchronizer extends AbstractInboundFileSynchronizer