INT-1614 moved file copy code up to base class, subclasses now only implement isFile and getFilename methods

This commit is contained in:
Mark Fisher
2010-11-21 17:29:51 -05:00
parent a62dece984
commit dbdbb88247
5 changed files with 81 additions and 137 deletions

View File

@@ -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<F> 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);
}

View File

@@ -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();
}
}

View File

@@ -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() {

View File

@@ -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<Boolean>() {
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 {
}
}
}
}

View File

@@ -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<ChannelSftp.LsEntry> {
public class SftpInboundFileSynchronizer extends AbstractInboundFileSynchronizer<LsEntry> {
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();
}
}