INT-1614 moved file copy code up to base class, subclasses now only implement isFile and getFilename methods
This commit is contained in:
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user