polishing

This commit is contained in:
Mark Fisher
2011-10-19 14:01:03 -04:00
parent c1107a229e
commit 9df127e09d
3 changed files with 90 additions and 67 deletions

View File

@@ -61,12 +61,14 @@ public class FileTransferringMessageHandler extends AbstractMessageHandler {
private volatile String charset = "UTF-8";
private volatile String remoteFileSeparator = "/";
public FileTransferringMessageHandler(SessionFactory sessionFactory) {
Assert.notNull(sessionFactory, "sessionFactory must not be null");
this.sessionFactory = sessionFactory;
}
public void setAutoCreateDirectory(boolean autoCreateDirectory) {
this.autoCreateDirectory = autoCreateDirectory;
}
@@ -77,11 +79,12 @@ public class FileTransferringMessageHandler extends AbstractMessageHandler {
}
public void setRemoteDirectoryExpression(Expression remoteDirectoryExpression) {
Assert.notNull(remoteDirectoryExpression, "remoteDirectoryExpression must not be null");
this.directoryExpressionProcessor = new ExpressionEvaluatingMessageProcessor<String>(remoteDirectoryExpression, String.class);
}
protected String getTemporaryFileSuffix() {
return temporaryFileSuffix;
return this.temporaryFileSuffix;
}
public void setTemporaryDirectory(File temporaryDirectory) {
@@ -135,7 +138,7 @@ public class FileTransferringMessageHandler extends AbstractMessageHandler {
try {
file.delete();
}
catch (Throwable th) {
catch (Throwable t) {
// ignore
}
}
@@ -159,7 +162,7 @@ public class FileTransferringMessageHandler extends AbstractMessageHandler {
sendableFile = new File(this.temporaryDirectory, tempFileName); // will only create temp file for String/byte[]
byte[] bytes = null;
if (payload instanceof String) {
bytes = ((String) payload).getBytes(charset);
bytes = ((String) payload).getBytes(this.charset);
}
else {
bytes = (byte[]) payload;
@@ -168,7 +171,7 @@ public class FileTransferringMessageHandler extends AbstractMessageHandler {
}
else {
throw new IllegalArgumentException("Unsupported payload type. The only supported payloads are " +
"java.io.File, java.lang.String and byte[]");
"java.io.File, java.lang.String, and byte[]");
}
return sendableFile;
}
@@ -184,17 +187,15 @@ public class FileTransferringMessageHandler extends AbstractMessageHandler {
if (!StringUtils.hasText(remoteDirectory)) {
remoteDirectory = "";
}
else if (!remoteDirectory.endsWith(remoteFileSeparator)) {
remoteDirectory += remoteFileSeparator;
else if (!remoteDirectory.endsWith(this.remoteFileSeparator)) {
remoteDirectory += this.remoteFileSeparator;
}
String remoteFilePath = remoteDirectory + fileName;
// write remote file first with .writing extension
String tempFilePath = remoteFilePath + this.temporaryFileSuffix;
if (this.autoCreateDirectory){
if (this.autoCreateDirectory) {
session.mkdir(remoteDirectory);
}
try {
session.write(fileInputStream, tempFilePath);
// then rename it to its final name
@@ -207,4 +208,5 @@ public class FileTransferringMessageHandler extends AbstractMessageHandler {
fileInputStream.close();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.integration.file.remote.session.Session;
import org.springframework.util.Assert;
@@ -50,7 +51,7 @@ class FtpSession implements Session {
public boolean remove(String path) throws IOException {
Assert.hasText(path, "path must not be null");
boolean completed = this.client.deleteFile(path);
if (!completed){
if (!completed) {
throw new IOException("Failed to delete '" + path + "'. Server replied with: " + client.getReplyString());
}
return completed;
@@ -62,25 +63,28 @@ class FtpSession implements Session {
return this.client.listFiles(path);
}
public void read(String path, OutputStream fos) throws IOException{
public void read(String path, OutputStream fos) throws IOException {
Assert.hasText(path, "path must not be null");
Assert.notNull(fos, "outputStream must not be null");
boolean completed = this.client.retrieveFile(path, fos);
if (!completed){
throw new IOException("Failed to copy '" + path + "'. Server replied with: " + client.getReplyString());
if (!completed) {
throw new IOException("Failed to copy '" + path +
"'. Server replied with: " + this.client.getReplyString());
}
logger.info("File have been successfully transfered to: " + path);
}
public void write(InputStream inputStream, String path) throws IOException{
public void write(InputStream inputStream, String path) throws IOException {
Assert.notNull(inputStream, "inputStream must not be null");
Assert.hasText(path, "path must not be null");
boolean completed = client.storeFile(path, inputStream);
if (!completed){
boolean completed = this.client.storeFile(path, inputStream);
if (!completed) {
throw new IOException("Failed to write to '" + path
+ "'. Server replied with: " + client.getReplyString());
+ "'. Server replied with: " + this.client.getReplyString());
}
if (logger.isInfoEnabled()) {
logger.info("File has been successfully transfered to: " + path);
}
logger.info("File have been successfully transfered to: " + path);
}
public void close() {
@@ -96,21 +100,24 @@ class FtpSession implements Session {
public boolean isOpen() {
try {
client.noop();
} catch (Exception e) {
this.client.noop();
}
catch (Exception e) {
return false;
}
return true;
}
public void rename(String pathFrom, String pathTo) throws IOException{
client.deleteFile(pathTo);
boolean completed = client.rename(pathFrom, pathTo);
if (!completed){
this.client.deleteFile(pathTo);
boolean completed = this.client.rename(pathFrom, pathTo);
if (!completed) {
throw new IOException("Failed to rename '" + pathFrom +
"' to " + pathTo + "'. Server replied with: " + client.getReplyString());
"' to " + pathTo + "'. Server replied with: " + this.client.getReplyString());
}
if (logger.isInfoEnabled()) {
logger.info("File has been successfully renamed from: " + pathFrom + " to " + pathTo);
}
logger.info("File have been successfully renamed from: " + pathFrom + " to " + pathTo);
}
public void mkdir(String directory) throws IOException {
@@ -123,4 +130,5 @@ class FtpSession implements Session {
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,12 +46,13 @@ import com.jcraft.jsch.SftpException;
* @since 2.0
*/
class SftpSession implements Session {
private final Log logger = LogFactory.getLog(this.getClass());
private volatile ChannelSftp channel;
private final com.jcraft.jsch.Session jschSession;
private volatile ChannelSftp channel;
public SftpSession(com.jcraft.jsch.Session jschSession) {
Assert.notNull(jschSession, "jschSession must not be null");
@@ -59,7 +60,7 @@ class SftpSession implements Session {
}
public boolean remove(String path) throws IOException{
public boolean remove(String path) throws IOException {
Assert.state(this.channel != null, "session is not connected");
try {
this.channel.rm(path);
@@ -91,9 +92,8 @@ class SftpSession implements Session {
return new LsEntry[0];
}
public void read(String source, OutputStream os) throws IOException{
public void read(String source, OutputStream os) throws IOException {
Assert.state(this.channel != null, "session is not connected");
try {
InputStream is = this.channel.get(source);
FileCopyUtils.copy(is, os);
@@ -103,7 +103,7 @@ class SftpSession implements Session {
}
}
public void write(InputStream inputStream, String destination) throws IOException{
public void write(InputStream inputStream, String destination) throws IOException {
Assert.state(this.channel != null, "session is not connected");
try {
this.channel.put(inputStream, destination);
@@ -119,21 +119,6 @@ class SftpSession implements Session {
}
}
void connect() {
try {
if (!this.jschSession.isConnected()) {
this.jschSession.connect();
this.channel = (ChannelSftp) this.jschSession.openChannel("sftp");
}
if (this.channel != null && !this.channel.isConnected()) {
this.channel.connect();
}
}
catch (JSchException e) {
throw new IllegalStateException("failed to connect", e);
}
}
public boolean isOpen() {
return this.jschSession.isConnected();
}
@@ -149,7 +134,7 @@ class SftpSession implements Session {
}
try {
this.remove(pathTo);
if (logger.isDebugEnabled()){
if (logger.isDebugEnabled()) {
logger.debug("Delete file: " + pathTo + " succeeded. Will attempt rename again");
}
}
@@ -162,27 +147,53 @@ class SftpSession implements Session {
}
catch (SftpException sftpex2) {
throw new NestedIOException("failed to rename from " + pathFrom + " to " + pathTo, sftpex2);
}
}
}
if (logger.isDebugEnabled()){
if (logger.isDebugEnabled()) {
logger.debug("File: " + pathFrom + " was successfully renamed to " + pathTo);
}
}
}
public void mkdir(String remoteDirectory) throws IOException {
try {
this.mkdirRecursively(remoteDirectory, remoteDirectory);
} catch (SftpException e) {
}
catch (SftpException e) {
throw new NestedIOException("failed to create remote directory '" + remoteDirectory + "'.", e);
}
}
private void mkdirRecursively(String remoteDirectory, String originalRemoteDirectory) throws SftpException{
void connect() {
try {
if (!this.jschSession.isConnected()) {
this.jschSession.connect();
this.channel = (ChannelSftp) this.jschSession.openChannel("sftp");
}
if (this.channel != null && !this.channel.isConnected()) {
this.channel.connect();
}
}
catch (JSchException e) {
throw new IllegalStateException("failed to connect", e);
}
}
/**
* Since the underlying SFTP API does not give us a clean method to create directories recursively,
* we need to create them one at the time starting from the path that we know actually exists.
* To determine the existing path we need to iterate through each delimited segment starting from
* the full directory path moving backward until we find it. Once found we need to start creating
* individual directories for each segment; so in this method on the initial call the two parameters
* will be the same, but for each recursive call the 'currentPath' is the directory with one less
* segment from the previous 'currentPath'. For example, if you had '/foo/bar/baz', in the next
* iteration it would be '/foo/bar/', and then just '/foo' and so on.
*/
private void mkdirRecursively(String currentPath, String fullPath) throws SftpException {
String remoteFileSeparator = "/";
if (this.exists(remoteDirectory)){
String missingDirectoryPath = originalRemoteDirectory.substring(remoteDirectory.length());
if (this.exists(currentPath)) {
String missingDirectoryPath = fullPath.substring(currentPath.length());
String[] directories = StringUtils.tokenizeToStringArray(missingDirectoryPath, remoteFileSeparator);
String directory = remoteDirectory + remoteFileSeparator;
String directory = currentPath + remoteFileSeparator;
for (String directorySegment : directories) {
directory += directorySegment + remoteFileSeparator;
if (logger.isDebugEnabled()){
@@ -192,20 +203,21 @@ class SftpSession implements Session {
}
}
else {
if (logger.isDebugEnabled()){
logger.debug("Directory '" + remoteDirectory + "' does not exist. Will attempt to auto-create it");
if (logger.isDebugEnabled()) {
logger.debug("Directory '" + currentPath + "' does not exist. Will attempt to auto-create it");
}
int nextSeparatorIndex = remoteDirectory.lastIndexOf(remoteFileSeparator);
if (nextSeparatorIndex <= 0){
throw new MessagingException("Failed to auto-create directory '" + originalRemoteDirectory + "'");
int nextSeparatorIndex = currentPath.lastIndexOf(remoteFileSeparator);
if (nextSeparatorIndex <= 0) {
throw new MessagingException("Failed to auto-create directory '" + fullPath + "'");
}
else {
remoteDirectory = remoteDirectory.substring(0, nextSeparatorIndex);
this.mkdirRecursively(remoteDirectory, originalRemoteDirectory);
currentPath = currentPath.substring(0, nextSeparatorIndex);
this.mkdirRecursively(currentPath, fullPath);
}
}
}
private boolean exists(String path){
private boolean exists(String path) {
try {
this.channel.lstat(path);
return true;
@@ -215,4 +227,5 @@ class SftpSession implements Session {
}
return false;
}
}