From dbdbb88247f45950809874ef72b806f906061a37 Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Sun, 21 Nov 2010 17:29:51 -0500 Subject: [PATCH] INT-1614 moved file copy code up to base class, subclasses now only implement isFile and getFilename methods --- .../AbstractInboundFileSynchronizer.java | 61 +++++++++++++++++- .../inbound/FtpInboundFileSynchronizer.java | 56 ++-------------- .../integration/ftp/session/FtpSession.java | 30 ++------- .../FtpSendingMessageHandlerTest.java | 7 +- .../inbound/SftpInboundFileSynchronizer.java | 64 ++----------------- 5 files changed, 81 insertions(+), 137 deletions(-) diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/remote/synchronizer/AbstractInboundFileSynchronizer.java b/spring-integration-file/src/main/java/org/springframework/integration/file/remote/synchronizer/AbstractInboundFileSynchronizer.java index 1252bafd7f..1229f9c096 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/remote/synchronizer/AbstractInboundFileSynchronizer.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/remote/synchronizer/AbstractInboundFileSynchronizer.java @@ -17,7 +17,9 @@ package org.springframework.integration.file.remote.synchronizer; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -31,6 +33,7 @@ import org.springframework.integration.file.filters.FileListFilter; 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.FileCopyUtils; import org.springframework.util.ObjectUtils; /** @@ -135,6 +138,62 @@ public abstract class AbstractInboundFileSynchronizer implements InboundFileS } } - protected abstract boolean copyFileToLocalDirectory(String remoteDirectoryPath, F file, File localDirectory, Session session) throws IOException; + private void copyFileToLocalDirectory(String remoteDirectoryPath, F remoteFile, File localDirectory, Session session) throws IOException { + String remoteFileName = this.getFilename(remoteFile); + String remoteFilePath = remoteDirectoryPath + File.separator + remoteFileName; + if (!this.isFile(remoteFile)) { + if (logger.isDebugEnabled()) { + logger.debug("cannot copy, not a file: " + remoteFilePath); + } + return; + } + File localFile = new File(localDirectory, remoteFileName); + if (!localFile.exists()) { + String tempFileName = localFile.getAbsolutePath() + AbstractInboundFileSynchronizingMessageSource.INCOMPLETE_EXTENSION; + File tempFile = new File(tempFileName); + InputStream inputStream = null; + FileOutputStream fileOutputStream = new FileOutputStream(tempFile); + try { + inputStream = session.get(remoteFilePath); + if (inputStream != null) { + FileCopyUtils.copy(inputStream, fileOutputStream); + } + } + catch (Exception e) { + if (e instanceof RuntimeException){ + throw (RuntimeException) e; + } + else { + throw new MessagingException("Failure occurred while copying from remote to local directory", e); + } + } + finally { + try { + if (inputStream != null) { + inputStream.close(); + } + } + catch (Exception ignored1) { + } + try { + fileOutputStream.close(); + } + catch (Exception ignored2) { + } + } + if (tempFile.renameTo(localFile)) { + if (this.shouldDeleteSourceFile) { + session.rm(remoteFilePath); + if (logger.isDebugEnabled()) { + logger.debug("deleted " + remoteFilePath); + } + } + } + } + } + + protected abstract boolean isFile(F file); + + protected abstract String getFilename(F file); } 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 80ca841fa9..45d7e2bfd0 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 @@ -16,19 +16,11 @@ package org.springframework.integration.ftp.inbound; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; - import org.apache.commons.net.ftp.FTPFile; -import org.springframework.integration.MessagingException; import org.springframework.integration.file.remote.session.Session; import org.springframework.integration.file.remote.session.SessionFactory; import org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer; -import org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource; -import org.springframework.util.FileCopyUtils; /** * An FTP-adapter implementation of {@link org.springframework.integration.file.synchronization.AbstractInboundRemoteFileSystemSychronizer} @@ -47,51 +39,13 @@ public class FtpInboundFileSynchronizer extends AbstractInboundFileSynchronizer< @Override - protected boolean copyFileToLocalDirectory(String remoteDirectoryPath, FTPFile ftpFile, File localDirectory, Session session) throws IOException { - if (!ftpFile.isFile()) { - return false; - } - String remoteFileName = ftpFile.getName(); - String localFileName = localDirectory.getPath() + "/" + remoteFileName; - File localFile = new File(localFileName); - if (!localFile.exists()) { - String tempFileName = localFileName + AbstractInboundFileSynchronizingMessageSource.INCOMPLETE_EXTENSION; - File file = new File(tempFileName); - FileOutputStream fileOutputStream = new FileOutputStream(file); - try { - InputStream inputStream = session.get(remoteFileName); - if (inputStream == null) { - return false; - } - FileCopyUtils.copy(inputStream, fileOutputStream); - if (this.shouldDeleteSourceFile) { - this.deleteRemoteFile(session, ftpFile); - } - } - catch (Exception e) { - if (e instanceof RuntimeException){ - throw (RuntimeException) e; - } - else { - throw new MessagingException("Failed to copy file", e); - } - } - finally { - fileOutputStream.close(); - } - file.renameTo(localFile); - return true; - } - return false; + protected boolean isFile(FTPFile file) { + return file.isFile(); } - // TODO: make this an abstract method in the base class once the code that calls this is refactored upward - private void deleteRemoteFile(Session session, FTPFile ftpFile) { - if ((ftpFile != null) && session.rm(ftpFile.getName())) { - if (logger.isDebugEnabled()) { - logger.debug("deleted " + ftpFile.getName()); - } - } + @Override + protected String getFilename(FTPFile file) { + return file.getName(); } } diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/FtpSession.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/FtpSession.java index 5e58ac0bf9..591cbd4b69 100644 --- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/FtpSession.java +++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/session/FtpSession.java @@ -16,7 +16,6 @@ package org.springframework.integration.ftp.session; -import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -27,7 +26,6 @@ import org.apache.commons.net.ftp.FTPFile; import org.springframework.integration.file.remote.session.Session; import org.springframework.util.Assert; -import org.springframework.util.StringUtils; /** * @author Mark Fisher @@ -72,9 +70,9 @@ public class FtpSession implements Session { } } - public InputStream get(String source) { + public InputStream get(String path) { try { - InputStream inputStream = this.client.retrieveFileStream(source); + InputStream inputStream = this.client.retrieveFileStream(path); this.client.completePendingCommand(); return inputStream; } @@ -86,31 +84,15 @@ public class FtpSession implements Session { } } - public void put(InputStream inputStream, String destination) { - String originalWorkDir = null; + public void put(InputStream inputStream, String path) { + Assert.notNull(inputStream, "inputStream must not be null"); + Assert.notNull(path, "path must not be null"); try { - String fileName = StringUtils.getFilename(destination); - int startOfFileName = destination.lastIndexOf(File.separatorChar); - - if (startOfFileName > 0) { - originalWorkDir = client.printWorkingDirectory(); - String pathname = destination.substring(0, startOfFileName); - client.changeWorkingDirectory(pathname); - } - this.client.storeFile(fileName, inputStream); + this.client.storeFile(path, inputStream); } catch (IOException e) { throw new IllegalStateException("failed to copy file", e); } - finally { - if (originalWorkDir != null){ - try { - this.client.changeWorkingDirectory(originalWorkDir); - } catch (IOException ioex) { - throw new IllegalStateException("failed to change working directories ", ioex); - } - } - } } public void close() { 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 efae3a7858..99d16e9373 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 @@ -127,12 +127,10 @@ public class FtpSendingMessageHandlerTest { when(ftpClient.changeWorkingDirectory(Mockito.anyString())).thenReturn(true); when(ftpClient.printWorkingDirectory()).thenReturn("remote-target-dir"); when(ftpClient.storeFile(Mockito.anyString(), Mockito.any(InputStream.class))).thenAnswer(new Answer() { - public Boolean answer(InvocationOnMock invocation) - throws Throwable { + public Boolean answer(InvocationOnMock invocation) throws Throwable { String fileName = (String) invocation.getArguments()[0]; InputStream fis = (InputStream) invocation.getArguments()[1]; - String workingDirectory = ftpClient.printWorkingDirectory(); - FileCopyUtils.copy(fis, new FileOutputStream(workingDirectory + File.separator + fileName)); + FileCopyUtils.copy(fis, new FileOutputStream(fileName)); return true; } }); @@ -142,4 +140,5 @@ public class FtpSendingMessageHandlerTest { } } } + } 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 9ba5d3f3a5..f6202115eb 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 @@ -16,19 +16,10 @@ package org.springframework.integration.sftp.inbound; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.springframework.integration.MessagingException; -import org.springframework.integration.file.remote.session.Session; import org.springframework.integration.file.remote.session.SessionFactory; import org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer; -import org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource; -import org.springframework.util.FileCopyUtils; -import com.jcraft.jsch.ChannelSftp; +import com.jcraft.jsch.ChannelSftp.LsEntry; /** * Handles the synchronization between a remote SFTP directory and a local mount. @@ -38,7 +29,7 @@ import com.jcraft.jsch.ChannelSftp; * @author Mark Fisher * @since 2.0 */ -public class SftpInboundFileSynchronizer extends AbstractInboundFileSynchronizer { +public class SftpInboundFileSynchronizer extends AbstractInboundFileSynchronizer { public SftpInboundFileSynchronizer(SessionFactory sessionFactory) { super(sessionFactory); @@ -46,54 +37,13 @@ public class SftpInboundFileSynchronizer extends AbstractInboundFileSynchronizer @Override - protected boolean copyFileToLocalDirectory(String remoteDirectoryPath, ChannelSftp.LsEntry entry, File localDirectory, Session session) throws IOException { - if (entry == null || entry.getAttrs() == null || entry.getAttrs().isDir() || entry.getAttrs().isLink()) { - return false; - } - File localFile = new File(localDirectory, entry.getFilename()); - if (!localFile.exists()) { - InputStream in = null; - FileOutputStream fileOutputStream = null; - try { - File tmpLocalTarget = new File(localFile.getAbsolutePath() + - AbstractInboundFileSynchronizingMessageSource.INCOMPLETE_EXTENSION); - fileOutputStream = new FileOutputStream(tmpLocalTarget); - String remoteFqPath = remoteDirectoryPath + File.separator + entry.getFilename(); - in = session.get(remoteFqPath); - try { - FileCopyUtils.copy(in, fileOutputStream); - } - finally { - in.close(); - fileOutputStream.close(); - } - if (tmpLocalTarget.renameTo(localFile)) { - if (this.shouldDeleteSourceFile) { - this.deleteRemoteFile(remoteDirectoryPath, session, entry); - } - } - return true; - } - catch (Exception e) { - if (e instanceof RuntimeException){ - throw (RuntimeException) e; - } - else { - throw new MessagingException("Failure occurred while copying from remote to local directory", e); - } - } - } - else { - return true; - } + protected boolean isFile(LsEntry file) { + return (file != null && file.getAttrs() != null && !file.getAttrs().isDir() && !file.getAttrs().isLink()); } - private void deleteRemoteFile(String remotePath, Session session, ChannelSftp.LsEntry msg) { - String remoteFqPath = remotePath + "/" + msg.getFilename(); - session.rm(remoteFqPath); - if (logger.isDebugEnabled()) { - logger.debug("deleted " + msg.getFilename()); - } + @Override + protected String getFilename(LsEntry file) { + return file.getFilename(); } }