INT-1562 formatting

This commit is contained in:
Mark Fisher
2010-10-27 17:22:33 -04:00
parent 892a6f9f42
commit 20e3f924fa
26 changed files with 643 additions and 589 deletions

View File

@@ -1,40 +1,65 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import java.io.IOException;
import java.net.SocketException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.integration.MessagingException;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.net.SocketException;
/**
*
* base class for the other {@link org.springframework.integration.ftp.FtpClientFactory} implementations.
* Most of this came out of the {@link DefaultFtpClientFactory} and was refactored into a base class
*
* @author Iwein Fuld
*
* @param <T>
*/
abstract public class AbstractFtpClientFactory<T extends FTPClient> implements FtpClientFactory<T> {
private static final Log logger = LogFactory.getLog(FtpClientFactory.class);
private static final String DEFAULT_REMOTE_WORKING_DIRECTORY = "/";
protected FTPClientConfig config;
protected String username;
protected String host;
protected String password;
protected int port = FTP.DEFAULT_PORT;
protected String remoteWorkingDirectory = DEFAULT_REMOTE_WORKING_DIRECTORY;
protected int clientMode = FTPClient.ACTIVE_LOCAL_DATA_CONNECTION_MODE;
protected int fileType = FTP.BINARY_FILE_TYPE;
public void setFileType(int fileType) {
this.fileType = fileType;
}
@@ -70,9 +95,9 @@ abstract public class AbstractFtpClientFactory<T extends FTPClient> implements F
}
/**
* Set client mode for example
* <code>FTPClient.ACTIVE_LOCAL_CONNECTION_MODE</code> (default) Only local
* modes are supported.
* Set client mode, for example
* <code>FTPClient.ACTIVE_LOCAL_CONNECTION_MODE</code> (default)
* Only local modes are supported.
*/
public void setClientMode(int clientMode) {
this.clientMode = clientMode;
@@ -118,7 +143,6 @@ abstract public class AbstractFtpClientFactory<T extends FTPClient> implements F
}
setClientMode(client);
client.setFileType(this.fileType);
if (logger.isDebugEnabled()) {
@@ -135,7 +159,6 @@ abstract public class AbstractFtpClientFactory<T extends FTPClient> implements F
logger.debug("working directory is: " +
client.printWorkingDirectory());
}
return client;
}
@@ -146,16 +169,13 @@ abstract public class AbstractFtpClientFactory<T extends FTPClient> implements F
switch (clientMode) {
case FTPClient.ACTIVE_LOCAL_DATA_CONNECTION_MODE:
client.enterLocalActiveMode();
break;
case FTPClient.PASSIVE_LOCAL_DATA_CONNECTION_MODE:
client.enterLocalPassiveMode();
break;
default:
break;
}
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import org.springframework.util.StringUtils;
@@ -5,91 +21,78 @@ import org.springframework.util.StringUtils;
import javax.net.ssl.KeyManager;
import javax.net.ssl.TrustManager;
/**
* Factors out the client factory creaton
* Factors out the client factory creation.
*
* @author Josh Long
*/
public class ClientFactorySupport {
public static DefaultFtpsClientFactory ftpsClientFactory(String host,
int port, String remoteDir, String user, String pw, int fileType,
public static DefaultFtpsClientFactory ftpsClientFactory(String host, int port, String remoteWorkingDirectory, String user, String password, int fileType,
int clientMode, String prot, String protocol, String authValue,
Boolean implicit, TrustManager trustManager, KeyManager keyManager,
Boolean sessionCreation, Boolean useClientMode,
Boolean wantsClientAuth, Boolean needClientAuth, String[] cipherSuites) {
DefaultFtpsClientFactory defaultFtpClientFactory = new DefaultFtpsClientFactory();
defaultFtpClientFactory.setHost(host);
defaultFtpClientFactory.setPassword(pw);
defaultFtpClientFactory.setPort((port));
defaultFtpClientFactory.setRemoteWorkingDirectory(remoteDir);
defaultFtpClientFactory.setPassword(password);
defaultFtpClientFactory.setPort(port);
defaultFtpClientFactory.setRemoteWorkingDirectory(remoteWorkingDirectory);
defaultFtpClientFactory.setUsername(user);
defaultFtpClientFactory.setFileType(fileType);
defaultFtpClientFactory.setClientMode(clientMode);
if (cipherSuites != null) {
defaultFtpClientFactory.setCipherSuites(cipherSuites);
}
if (StringUtils.hasText(prot)) {
defaultFtpClientFactory.setProt(prot);
}
if (StringUtils.hasText(protocol)) {
defaultFtpClientFactory.setProtocol(protocol);
}
if (StringUtils.hasText(authValue)) {
defaultFtpClientFactory.setAuthValue(authValue);
}
if (null != implicit) {
defaultFtpClientFactory.setImplicit(implicit);
}
if (trustManager != null) {
defaultFtpClientFactory.setTrustManager(trustManager);
}
if (keyManager != null) {
defaultFtpClientFactory.setKeyManager(keyManager);
}
if (needClientAuth != null) {
defaultFtpClientFactory.setNeedClientAuth(needClientAuth);
}
if (wantsClientAuth != null) {
defaultFtpClientFactory.setWantsClientAuth(wantsClientAuth);
}
if (sessionCreation != null) {
defaultFtpClientFactory.setSessionCreation(sessionCreation);
}
if (useClientMode != null) {
defaultFtpClientFactory.setUseClientMode(useClientMode);
}
return defaultFtpClientFactory;
}
public static DefaultFtpClientFactory ftpClientFactory(String host,
int port,
String remoteDir,
String remoteWorkingDirectory,
String user,
String pw,
String password,
int clientMode,
int fileType) {
DefaultFtpClientFactory defaultFtpClientFactory = new DefaultFtpClientFactory();
defaultFtpClientFactory.setHost(host);
defaultFtpClientFactory.setPassword(pw);
defaultFtpClientFactory.setPassword(password);
defaultFtpClientFactory.setPort(port);
defaultFtpClientFactory.setRemoteWorkingDirectory(remoteDir);
defaultFtpClientFactory.setRemoteWorkingDirectory(remoteWorkingDirectory);
defaultFtpClientFactory.setUsername(user);
defaultFtpClientFactory.setClientMode(clientMode);
defaultFtpClientFactory.setFileType(fileType);
return defaultFtpClientFactory;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2010 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.
@@ -13,20 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import org.apache.commons.net.ftp.FTPClient;
/**
* Default implementation of FtpClientFactory.
*
* @author iwein
* @author Iwein Fuld
* @author Josh Long
*/
public class DefaultFtpClientFactory extends AbstractFtpClientFactory<FTPClient> {
@Override
protected FTPClient createSingleInstanceOfClient() {
return new FTPClient();
}
}

View File

@@ -1,22 +1,31 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPSClient;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.net.SocketException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.TrustManager;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;
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.DefaultFtpClientFactory}
@@ -25,19 +34,32 @@ import java.util.Properties;
* @author Iwein Fuld
*/
public class DefaultFtpsClientFactory extends AbstractFtpClientFactory<FTPSClient> {
private Boolean useClientMode;
private Boolean sessionCreation;
private String authValue;
private TrustManager trustManager;
private String[] cipherSuites;
private String[] protocols;
private KeyManager keyManager;
private Boolean needClientAuth;
private Boolean wantsClientAuth;
private boolean implicit = false;
private String prot = "P";
private String protocol;
public void setProtocol(String protocol) {
this.protocol = protocol;
}
@@ -82,9 +104,12 @@ public class DefaultFtpsClientFactory extends AbstractFtpClientFactory<FTPSClien
this.prot = prot;
}
public void setImplicit(boolean implicit) {
this.implicit = implicit;
}
@Override
protected void onAfterConnect(FTPSClient ftpsClient)
throws IOException {
protected void onAfterConnect(FTPSClient ftpsClient) throws IOException {
ftpsClient.execPBSZ(0);
ftpsClient.execPROT(this.prot);
}
@@ -92,64 +117,50 @@ public class DefaultFtpsClientFactory extends AbstractFtpClientFactory<FTPSClien
@Override
public FTPSClient getClient() throws SocketException, IOException {
FTPSClient ftpsClient = super.getClient();
if (StringUtils.hasText(this.authValue)) {
ftpsClient.setAuthValue(authValue);
}
if (this.trustManager != null) {
ftpsClient.setTrustManager(this.trustManager);
}
if (this.cipherSuites != null) {
ftpsClient.setEnabledCipherSuites(this.cipherSuites);
}
if (this.protocols != null) {
ftpsClient.setEnabledProtocols(this.protocols);
}
if (this.sessionCreation != null) {
ftpsClient.setEnabledSessionCreation(this.sessionCreation);
}
if (this.useClientMode != null) {
ftpsClient.setUseClientMode(this.useClientMode);
}
if (this.sessionCreation != null) {
ftpsClient.setEnabledSessionCreation(this.sessionCreation);
}
if (this.keyManager != null) {
ftpsClient.setKeyManager(keyManager);
}
if (this.needClientAuth != null) {
ftpsClient.setNeedClientAuth(this.needClientAuth);
}
if (this.wantsClientAuth != null) {
ftpsClient.setWantClientAuth(this.wantsClientAuth);
}
return ftpsClient;
}
public void setImplicit(boolean implicit) {
this.implicit = implicit;
}
@Override
protected FTPSClient createSingleInstanceOfClient() {
try {
if (StringUtils.hasText(this.protocol)) {
return new FTPSClient(this.protocol, this.implicit);
}
return new FTPSClient(this.implicit);
} catch (NoSuchAlgorithmException e) {
}
catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2010 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.
@@ -13,22 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import org.apache.commons.net.ftp.FTPClient;
import java.io.IOException;
/**
* Factory for {@link FTPClient}.
*
* @author Iwein Fuld
*/
public interface FtpClientFactory<T extends FTPClient> {
/**
* @return Fully configured and connected FTPClient. Never <code>null</code>.
* @throws IOException thrown when a networking IO subsystem error occurs
*/
T getClient() throws IOException;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2010 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.
@@ -13,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import org.apache.commons.net.ftp.FTPClient;
/**
* A pool of {@link FTPClient} instances. The pool can be used to control the
* number of open FTP connections and reuse these connections efficiently.
@@ -25,6 +25,7 @@ import org.apache.commons.net.ftp.FTPClient;
* @author Iwein Fuld
*/
public interface FtpClientPool extends FtpClientFactory {
/**
* Releases the client back to the pool. When calling this method the caller
* is no longer responsible for the connection. The pool is free to do with
@@ -43,4 +44,5 @@ public interface FtpClientPool extends FtpClientFactory {
* <code>null</code>.
*/
void releaseClient(FTPClient client);
}

View File

@@ -1,16 +1,33 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.integration.file.entries.EntryNamer;
/**
* A {@link org.springframework.integration.file.entries.EntryNamer} for {@link org.apache.commons.net.ftp.FTPFile} objects
*
* @author Josh Long
*/
public class FtpFileEntryNamer implements EntryNamer<FTPFile> {
public String nameOf(FTPFile entry) {
return entry.getName();
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import org.apache.commons.net.ftp.FTPClient;
@@ -17,24 +33,22 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
/**
* An FTP-adapter implementation of {@link org.springframework.integration.file.AbstractInboundRemoteFileSystemSychronizer}
*
* @author Iwein Fuld
* @author Josh Long
*/
public class FtpInboundRemoteFileSystemSynchronizer
extends AbstractInboundRemoteFileSystemSychronizer<FTPFile> {
protected FtpClientPool clientPool;
public class FtpInboundRemoteFileSystemSynchronizer extends AbstractInboundRemoteFileSystemSychronizer<FTPFile> {
private volatile Trigger trigger = new PeriodicTrigger(10 * 1000);
protected volatile FtpClientPool clientPool;
@Override
protected void onInit() throws Exception {
Assert.notNull(this.clientPool, "clientPool can't be null");
if (this.shouldDeleteSourceFile) {
this.entryAcknowledgmentStrategy = new DeletionEntryAcknowledgmentStrategy();
}
protected Trigger getTrigger() {
return this.trigger;
}
/**
@@ -46,37 +60,40 @@ public class FtpInboundRemoteFileSystemSynchronizer
this.clientPool = clientPool;
}
protected boolean copyFileToLocalDirectory(FTPClient client,
FTPFile ftpFile, Resource localDirectory)
throws IOException, FileNotFoundException {
String remoteFileName = ftpFile.getName();
String localFileName = localDirectory.getFile().getPath() + "/" +
remoteFileName;
File localFile = new File(localFileName);
@Override
protected void onInit() throws Exception {
Assert.notNull(this.clientPool, "clientPool must not be null");
if (this.shouldDeleteSourceFile) {
this.entryAcknowledgmentStrategy = new DeletionEntryAcknowledgmentStrategy();
}
}
private boolean copyFileToLocalDirectory(FTPClient client, FTPFile ftpFile, Resource localDirectory)
throws IOException, FileNotFoundException {
String remoteFileName = ftpFile.getName();
String localFileName = localDirectory.getFile().getPath() + "/" + remoteFileName;
File localFile = new File(localFileName);
if (!localFile.exists()) {
String tempFileName = localFileName +
AbstractInboundRemoteFileSystemSynchronizingMessageSource.INCOMPLETE_EXTENSION;
File file = new File(tempFileName);
FileOutputStream fos = new FileOutputStream(file);
try {
client.retrieveFile(remoteFileName, fos);
// Perhaps we have some dispatch of hte source file to do?
// Perhaps we have some dispatch of the source file to do?
acknowledge(client, ftpFile);
} catch (Throwable th) {
}
catch (Throwable th) {
throw new RuntimeException(th);
} finally {
}
finally {
fos.close();
}
file.renameTo(localFile);
return true;
} else {
return false;
}
return false;
}
@Override
@@ -86,44 +103,38 @@ public class FtpInboundRemoteFileSystemSynchronizer
Assert.state(client != null,
FtpClientPool.class.getSimpleName() +
" returned a 'null' client. " +
"This most likely a bug in the pool implementation.");
"This is most likely a bug in the pool implementation.");
Collection<FTPFile> fileList = this.filter.filterEntries(client.listFiles());
try {
for (FTPFile ftpFile : fileList) {
if ((ftpFile != null) && ftpFile.isFile()) {
copyFileToLocalDirectory(client, ftpFile,
this.localDirectory);
copyFileToLocalDirectory(client, ftpFile, this.localDirectory);
}
}
} finally {
}
finally {
this.clientPool.releaseClient(client);
}
} catch (IOException e) {
throw new MessagingException("Problem occurred while synchronizing remote to local directory",
e);
}
catch (IOException e) {
throw new MessagingException("Problem occurred while synchronizing remote to local directory", e);
}
}
@Override
protected Trigger getTrigger() {
return new PeriodicTrigger(10 * 1000);
}
/**
* An ackowledgment strategy that deletes
* An acknowledgment strategy that deletes the file.
*/
class DeletionEntryAcknowledgmentStrategy implements AbstractInboundRemoteFileSystemSychronizer.EntryAcknowledgmentStrategy<FTPFile> {
public void acknowledge(Object useful, FTPFile msg)
throws Exception {
FTPClient ftpClient = (FTPClient) useful;
private class DeletionEntryAcknowledgmentStrategy implements AbstractInboundRemoteFileSystemSychronizer.EntryAcknowledgmentStrategy<FTPFile> {
if ((msg != null) && ftpClient.deleteFile(msg.getName())) {
public void acknowledge(Object useful, FTPFile fptFile) throws Exception {
FTPClient ftpClient = (FTPClient) useful;
if ((fptFile != null) && ftpClient.deleteFile(fptFile.getName())) {
if (logger.isDebugEnabled()) {
logger.debug("deleted " + msg.getName());
logger.debug("deleted " + fptFile.getName());
}
}
}
}
}

View File

@@ -1,23 +1,51 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.integration.file.AbstractInboundRemoteFileSystemSynchronizingMessageSource;
/**
* a {@link org.springframework.integration.core.MessageSource} implementation for FTP
* A {@link org.springframework.integration.core.MessageSource} implementation for FTP.
*
* @author Iwein Fuld
* @author Josh Long
*/
public class FtpInboundRemoteFileSystemSynchronizingMessageSource
extends AbstractInboundRemoteFileSystemSynchronizingMessageSource<FTPFile, FtpInboundRemoteFileSystemSynchronizer> {
private volatile FtpClientPool clientPool;
public void setClientPool(FtpClientPool clientPool) {
this.clientPool = clientPool;
}
public String getComponentType() {
return "ftp:inbound-channel-adapter";
}
@Override
protected void onInit() {
super.onInit();
this.synchronizer.setClientPool(this.clientPool);
}
@Override
protected void doStart() {
this.synchronizer.start();
@@ -28,13 +56,4 @@ public class FtpInboundRemoteFileSystemSynchronizingMessageSource
this.synchronizer.stop();
}
@Override
protected void onInit() {
super.onInit();
this.synchronizer.setClientPool(this.clientPool);
}
public String getComponentType() {
return "ftp:inbound-channel-adapter";
}
}

View File

@@ -1,9 +1,28 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import java.io.File;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
@@ -14,9 +33,6 @@ import org.springframework.integration.file.entries.EntryListFilter;
import org.springframework.integration.file.entries.PatternMatchingEntryListFilter;
import org.springframework.util.StringUtils;
import java.io.File;
/**
* Factory to make building the namespace easier
*
@@ -24,35 +40,91 @@ import java.io.File;
* @author Josh Long
*/
public class FtpRemoteFileSystemSynchronizingMessageSourceFactoryBean
extends AbstractFactoryBean<FtpInboundRemoteFileSystemSynchronizingMessageSource>
implements ResourceLoaderAware {
extends AbstractFactoryBean<FtpInboundRemoteFileSystemSynchronizingMessageSource> implements ResourceLoaderAware {
protected volatile String port;
protected volatile String autoCreateDirectories;
protected volatile String filenamePattern;
protected volatile String username;
protected volatile String password;
protected volatile String host;
protected volatile String remoteDirectory;
protected volatile String localWorkingDirectory;
protected volatile ResourceLoader resourceLoader;
protected volatile Resource localDirectoryResource;
protected volatile EntryListFilter<FTPFile> filter;
protected volatile int clientMode = FTPClient.ACTIVE_LOCAL_DATA_CONNECTION_MODE;
protected volatile int fileType = FTP.BINARY_FILE_TYPE;
private volatile String autoDeleteRemoteFilesOnSync;
protected String defaultFtpInboundFolderName = "ftpInbound";
@SuppressWarnings("unused")
public void setFileType(int fileType) {
this.fileType = fileType;
}
@SuppressWarnings("unused")
public void setAutoDeleteRemoteFilesOnSync(
String autoDeleteRemoteFilesOnSync) {
public void setAutoDeleteRemoteFilesOnSync(String autoDeleteRemoteFilesOnSync) {
this.autoDeleteRemoteFilesOnSync = autoDeleteRemoteFilesOnSync;
}
public void setPort(String port) {
this.port = port;
}
public void setAutoCreateDirectories(String autoCreateDirectories) {
this.autoCreateDirectories = autoCreateDirectories;
}
public void setFilenamePattern(String filenamePattern) {
this.filenamePattern = filenamePattern;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setHost(String host) {
this.host = host;
}
public void setRemoteDirectory(String remoteDirectory) {
this.remoteDirectory = remoteDirectory;
}
public void setLocalWorkingDirectory(String localWorkingDirectory) {
this.localWorkingDirectory = localWorkingDirectory;
}
public void setFilter(EntryListFilter<FTPFile> filter) {
this.filter = filter;
}
public void setClientMode(int clientMode) {
this.clientMode = clientMode;
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Override
public Class<?> getObjectType() {
return FtpInboundRemoteFileSystemSynchronizingMessageSource.class;
@@ -61,122 +133,52 @@ public class FtpRemoteFileSystemSynchronizingMessageSourceFactoryBean
private Resource fromText(String path) {
ResourceEditor resourceEditor = new ResourceEditor(this.resourceLoader);
resourceEditor.setAsText(path);
return (Resource) resourceEditor.getValue();
}
protected AbstractFtpClientFactory defaultClientFactory()
throws Exception {
protected AbstractFtpClientFactory<?> defaultClientFactory() throws Exception {
return ClientFactorySupport.ftpClientFactory(this.host,
Integer.parseInt(this.port), this.remoteDirectory, this.username,
this.password, this.clientMode, this.fileType);
}
@Override
protected FtpInboundRemoteFileSystemSynchronizingMessageSource createInstance()
throws Exception {
protected FtpInboundRemoteFileSystemSynchronizingMessageSource createInstance() throws Exception {
boolean autoCreatDirs = Boolean.parseBoolean(this.autoCreateDirectories);
boolean ackRemoteDir = Boolean.parseBoolean(this.autoDeleteRemoteFilesOnSync);
FtpInboundRemoteFileSystemSynchronizingMessageSource ftpRemoteFileSystemSynchronizingMessageSource =
new FtpInboundRemoteFileSystemSynchronizingMessageSource();
ftpRemoteFileSystemSynchronizingMessageSource.setAutoCreateDirectories(autoCreatDirs);
if (!StringUtils.hasText(this.localWorkingDirectory)) {
File tmp = new File(SystemUtils.getJavaIoTmpDir(), defaultFtpInboundFolderName);
this.localWorkingDirectory = "file://" + tmp.getAbsolutePath();
}
this.localDirectoryResource = this.fromText(this.localWorkingDirectory);
FtpFileEntryNamer ftpFileEntryNamer = new FtpFileEntryNamer();
CompositeEntryListFilter<FTPFile> compositeFtpFileListFilter = new CompositeEntryListFilter<FTPFile>();
if (StringUtils.hasText(this.filenamePattern)) {
PatternMatchingEntryListFilter<FTPFile> ftpFilePatternMatchingEntryListFilter =
new PatternMatchingEntryListFilter<FTPFile>(ftpFileEntryNamer, filenamePattern);
compositeFtpFileListFilter.addFilter(ftpFilePatternMatchingEntryListFilter);
}
if (this.filter != null) {
compositeFtpFileListFilter.addFilter(this.filter);
}
QueuedFtpClientPool queuedFtpClientPool = new QueuedFtpClientPool(15,
defaultClientFactory());
QueuedFtpClientPool queuedFtpClientPool = new QueuedFtpClientPool(15, defaultClientFactory());
FtpInboundRemoteFileSystemSynchronizer ftpRemoteFileSystemSynchronizer = new FtpInboundRemoteFileSystemSynchronizer();
ftpRemoteFileSystemSynchronizer.setClientPool(queuedFtpClientPool);
ftpRemoteFileSystemSynchronizer.setLocalDirectory(this.localDirectoryResource);
ftpRemoteFileSystemSynchronizer.setShouldDeleteSourceFile(ackRemoteDir);
ftpRemoteFileSystemSynchronizer.setFilter(compositeFtpFileListFilter);
ftpRemoteFileSystemSynchronizingMessageSource.setRemotePredicate(compositeFtpFileListFilter);
ftpRemoteFileSystemSynchronizingMessageSource.setSynchronizer(ftpRemoteFileSystemSynchronizer);
ftpRemoteFileSystemSynchronizingMessageSource.setClientPool(queuedFtpClientPool);
ftpRemoteFileSystemSynchronizingMessageSource.setLocalDirectory(this.localDirectoryResource);
ftpRemoteFileSystemSynchronizingMessageSource.setBeanFactory(this.getBeanFactory());
ftpRemoteFileSystemSynchronizingMessageSource.setAutoStartup(true);
ftpRemoteFileSystemSynchronizingMessageSource.afterPropertiesSet();
ftpRemoteFileSystemSynchronizingMessageSource.start();
return ftpRemoteFileSystemSynchronizingMessageSource;
}
@SuppressWarnings("unused")
public void setPort(String port) {
this.port = port;
}
@SuppressWarnings("unused")
public void setAutoCreateDirectories(String autoCreateDirectories) {
this.autoCreateDirectories = autoCreateDirectories;
}
@SuppressWarnings("unused")
public void setFilenamePattern(String filenamePattern) {
this.filenamePattern = filenamePattern;
}
@SuppressWarnings("unused")
public void setUsername(String username) {
this.username = username;
}
@SuppressWarnings("unused")
public void setPassword(String password) {
this.password = password;
}
@SuppressWarnings("unused")
public void setHost(String host) {
this.host = host;
}
@SuppressWarnings("unused")
public void setRemoteDirectory(String remoteDirectory) {
this.remoteDirectory = remoteDirectory;
}
@SuppressWarnings("unused")
public void setLocalWorkingDirectory(String localWorkingDirectory) {
this.localWorkingDirectory = localWorkingDirectory;
}
@SuppressWarnings("unused")
public void setFilter(EntryListFilter<FTPFile> filter) {
this.filter = filter;
}
@SuppressWarnings("unused")
public void setClientMode(int clientMode) {
this.clientMode = clientMode;
}
@SuppressWarnings("unused")
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}

View File

@@ -85,14 +85,12 @@ public class FtpSendingMessageHandler extends AbstractMessageHandler{
}
protected void onInit() throws Exception {
Assert.notNull(ftpClientPool, "'ftpClientPool' must not be null");
Assert.notNull(temporaryBufferFolder,
Assert.notNull(this.ftpClientPool, "'ftpClientPool' must not be null");
Assert.notNull(this.temporaryBufferFolder,
"'temporaryBufferFolder' must not be null");
temporaryBufferFolderFile = this.temporaryBufferFolder.getFile();
this.temporaryBufferFolderFile = this.temporaryBufferFolder.getFile();
}
/* Ugh this needs to be put in a convenient place accessible for all the file:, sftp:, and ftp:* adapters */
private File handleFileMessage(File sourceFile, File tempFile, File resultFile) throws IOException {
if (sourceFile.renameTo(resultFile)) {
return resultFile;
@@ -108,8 +106,7 @@ public class FtpSendingMessageHandler extends AbstractMessageHandler{
return resultFile;
}
private File handleStringMessage(String content, File tempFile,
File resultFile, String charset) throws IOException {
private File handleStringMessage(String content, File tempFile, File resultFile, String charset) throws IOException {
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(tempFile), charset);
FileCopyUtils.copy(content, writer);
tempFile.renameTo(resultFile);
@@ -162,25 +159,21 @@ public class FtpSendingMessageHandler extends AbstractMessageHandler{
Assert.notNull(message, "'message' must not be null");
Object payload = message.getPayload();
Assert.notNull(payload, "Message payload must not be null");
File file = this.redeemForStorableFile(message);
if ((file != null) && file.exists()) {
FTPClient client = null;
boolean sentSuccesfully;
try {
client = getFtpClient();
sentSuccesfully = sendFile(file, client);
} catch (FileNotFoundException e) {
}
catch (FileNotFoundException e) {
throw new MessageDeliveryException(message,
"File [" + file +
"] not found in local working directory; it was moved or deleted unexpectedly",
e);
"File [" + file + "] not found in local working directory; it was moved or deleted unexpectedly", e);
}
catch (IOException e) {
throw new MessageDeliveryException(message,
"Error transferring file [" + file +
"] from local working directory to remote FTP directory", e);
"Error transferring file [" + file + "] from local working directory to remote FTP directory", e);
}
catch (Exception e) {
throw new MessageDeliveryException(message,
@@ -190,8 +183,9 @@ public class FtpSendingMessageHandler extends AbstractMessageHandler{
if (file.exists()) {
try {
file.delete();
} catch (Throwable th) {
/// noop
}
catch (Throwable th) {
// ignore
}
}
if (client != null) {
@@ -199,8 +193,7 @@ public class FtpSendingMessageHandler extends AbstractMessageHandler{
}
}
if (!sentSuccesfully) {
throw new MessageDeliveryException(message,
"Failed to store file '" + file + "'");
throw new MessageDeliveryException(message, "Failed to store file '" + file + "'");
}
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import org.springframework.beans.BeansException;
@@ -10,100 +26,106 @@ import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
import org.springframework.integration.file.FileNameGenerator;
/**
* A factory bean implementation that handles constructing an outbound FTP adapter.
*
* A factory bean implementation that handles constructing an outbound FTP
* adapter.
*
* @author Iwein Fuld
* @author Josh Long
*/
public class FtpSendingMessageHandlerFactoryBean extends AbstractFactoryBean<FtpSendingMessageHandler>
implements ResourceLoaderAware, ApplicationContextAware {
protected int port;
protected String username;
protected String password;
protected String host;
protected String remoteDirectory;
private String charset;
protected int clientMode;
private int fileType;
implements ResourceLoaderAware, ApplicationContextAware {
protected int port;
protected String username;
protected String password;
protected String host;
protected String remoteDirectory;
private String charset;
protected int clientMode;
private int fileType;
private ResourceLoader resourceLoader;
private FileNameGenerator fileNameGenerator;
private ApplicationContext applicationContext;
public void setCharset(String charset) {
this.charset = charset;
}
public void setFileNameGenerator(FileNameGenerator fileNameGenerator) {
public void setCharset(String charset) {
this.charset = charset;
}
public void setFileNameGenerator(FileNameGenerator fileNameGenerator) {
this.fileNameGenerator = fileNameGenerator;
}
public void setFileType(int fileType) {
this.fileType = fileType;
}
public void setFileType(int fileType) {
this.fileType = fileType;
}
public void setClientMode(int clientMode) {
this.clientMode = clientMode;
}
public void setClientMode(int clientMode) {
this.clientMode = clientMode;
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public void setPort(int port) {
this.port = port;
}
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public Class<?extends FtpSendingMessageHandler> getObjectType() {
return FtpSendingMessageHandler.class;
}
public void setPassword(String password) {
this.password = password;
}
protected AbstractFtpClientFactory clientFactory() {
return ClientFactorySupport.ftpClientFactory(this.host, this.port,
this.remoteDirectory, this.username, this.password,
this.clientMode, this.fileType);
}
public void setHost(String host) {
this.host = host;
}
@Override
protected FtpSendingMessageHandler createInstance()
throws Exception {
// the dependencies for the outbound-adapter are much simpler
// they only require an instance of the pool
AbstractFtpClientFactory defaultFtpClientFactory = clientFactory();
public void setRemoteDirectory(String remoteDirectory) {
this.remoteDirectory = remoteDirectory;
}
QueuedFtpClientPool queuedFtpClientPool = new QueuedFtpClientPool(15,
defaultFtpClientFactory);
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
FtpSendingMessageHandler ftpSendingMessageHandler = new FtpSendingMessageHandler(queuedFtpClientPool);
ftpSendingMessageHandler.setFileNameGenerator(this.fileNameGenerator);
if (this.charset != null) {
ftpSendingMessageHandler.setCharset(this.charset);
}
ftpSendingMessageHandler.afterPropertiesSet();
return ftpSendingMessageHandler;
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void setPort(int port) {
this.port = port;
}
@Override
public Class<? extends FtpSendingMessageHandler> getObjectType() {
return FtpSendingMessageHandler.class;
}
public void setUsername(String username) {
this.username = username;
}
protected AbstractFtpClientFactory<?> clientFactory() {
return ClientFactorySupport.ftpClientFactory(this.host, this.port,
this.remoteDirectory, this.username, this.password,
this.clientMode, this.fileType);
}
public void setPassword(String password) {
this.password = password;
}
@Override
protected FtpSendingMessageHandler createInstance() throws Exception {
AbstractFtpClientFactory<?> defaultFtpClientFactory = clientFactory();
QueuedFtpClientPool queuedFtpClientPool = new QueuedFtpClientPool(15, defaultFtpClientFactory);
FtpSendingMessageHandler ftpSendingMessageHandler = new FtpSendingMessageHandler(
queuedFtpClientPool);
ftpSendingMessageHandler.setFileNameGenerator(this.fileNameGenerator);
if (this.charset != null) {
ftpSendingMessageHandler.setCharset(this.charset);
}
ftpSendingMessageHandler.afterPropertiesSet();
return ftpSendingMessageHandler;
}
public void setHost(String host) {
this.host = host;
}
public void setRemoteDirectory(String remoteDirectory) {
this.remoteDirectory = remoteDirectory;
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import org.apache.commons.net.ftp.FTPClient;
@@ -5,14 +21,13 @@ import org.apache.commons.net.ftp.FTPClient;
import javax.net.ssl.KeyManager;
import javax.net.ssl.TrustManager;
/**
* Factory to make building the namespace easier
* Factory to make building the namespace easier.
*
* @author Josh Long
*/
public class FtpsRemoteFileSystemSynchronizingMessageSourceFactoryBean
extends FtpRemoteFileSystemSynchronizingMessageSourceFactoryBean {
public class FtpsRemoteFileSystemSynchronizingMessageSourceFactoryBean extends FtpRemoteFileSystemSynchronizingMessageSourceFactoryBean {
/**
* Sets whether the connection is implicit. Local testing reveals this to be a good choice.
*/
@@ -27,20 +42,30 @@ public class FtpsRemoteFileSystemSynchronizingMessageSourceFactoryBean
* "P"
*/
protected volatile String prot;
private KeyManager keyManager;
private TrustManager trustManager;
protected volatile String authValue;
private Boolean sessionCreation;
private Boolean useClientMode;
private Boolean needClientAuth;
private Boolean wantsClientAuth;
private String[] cipherSuites;
public FtpsRemoteFileSystemSynchronizingMessageSourceFactoryBean() {
this.defaultFtpInboundFolderName = "ftpsInbound";
this.clientMode = FTPClient.PASSIVE_LOCAL_DATA_CONNECTION_MODE;
}
public void setKeyManager(KeyManager keyManager) {
this.keyManager = keyManager;
}
@@ -81,8 +106,11 @@ public class FtpsRemoteFileSystemSynchronizingMessageSourceFactoryBean
this.wantsClientAuth = wantsClientAuth;
}
protected AbstractFtpClientFactory defaultClientFactory()
throws Exception {
public void setCipherSuites(String[] cipherSuites) {
this.cipherSuites = cipherSuites;
}
protected AbstractFtpClientFactory<?> defaultClientFactory() throws Exception {
DefaultFtpsClientFactory factory = ClientFactorySupport.ftpsClientFactory(this.host,
Integer.parseInt(this.port), this.remoteDirectory,
this.username, this.password, this.fileType, this.clientMode,
@@ -94,7 +122,4 @@ public class FtpsRemoteFileSystemSynchronizingMessageSourceFactoryBean
return factory;
}
public void setCipherSuites(String[] cipherSuites) {
this.cipherSuites = cipherSuites;
}
}

View File

@@ -1,16 +1,30 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import javax.net.ssl.KeyManager;
import javax.net.ssl.TrustManager;
/**
* Sends files to a remote FTPS file system. Based heavily on {@link org.springframework.integration.ftp.FtpSendingMessageHandler}
*
* @author Josh Long
* @author Iwein Fuld
*/
public class FtpsSendingMessageHandlerFactoryBean extends FtpSendingMessageHandlerFactoryBean {
/**
@@ -27,16 +41,26 @@ public class FtpsSendingMessageHandlerFactoryBean extends FtpSendingMessageHandl
* "P"
*/
protected volatile String prot;
private KeyManager keyManager;
private TrustManager trustManager;
protected volatile String authValue;
private Boolean sessionCreation;
private Boolean useClientMode;
private Boolean needClientAuth;
private Boolean wantsClientAuth;
private String[] cipherSuites;
private int fileType;
public void setImplicit(Boolean implicit) {
this.implicit = implicit;
}
@@ -86,7 +110,7 @@ public class FtpsSendingMessageHandlerFactoryBean extends FtpSendingMessageHandl
}
@Override
protected AbstractFtpClientFactory clientFactory() {
protected AbstractFtpClientFactory<?> clientFactory() {
DefaultFtpsClientFactory factory = ClientFactorySupport.ftpsClientFactory(this.host,
(this.port), this.remoteDirectory, this.username,
this.password, this.fileType, this.clientMode, this.prot,
@@ -94,7 +118,7 @@ public class FtpsSendingMessageHandlerFactoryBean extends FtpSendingMessageHandl
this.trustManager, this.keyManager, this.sessionCreation,
this.useClientMode, this.wantsClientAuth, this.needClientAuth,
this.cipherSuites);
return factory;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2010 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp;
import org.apache.commons.logging.Log;
@@ -25,7 +26,6 @@ import java.net.SocketException;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
/**
* FtpClientPool implementation based on a Queue. This implementation has a
* default pool size of 5, but this is configurable with a constructor argument.
@@ -36,22 +36,28 @@ import java.util.concurrent.ArrayBlockingQueue;
* @author Iwein Fuld
*/
public class QueuedFtpClientPool implements FtpClientPool {
private static final Log log = LogFactory.getLog(QueuedFtpClientPool.class);
private static final int DEFAULT_POOL_SIZE = 5;
private final Queue<FTPClient> pool;
private final FtpClientFactory factory;
public QueuedFtpClientPool(FtpClientFactory factory) {
private static final Log logger = LogFactory.getLog(QueuedFtpClientPool.class);
private static final int DEFAULT_POOL_SIZE = 5;
private final Queue<FTPClient> pool;
private final FtpClientFactory<?> factory;
public QueuedFtpClientPool(FtpClientFactory<?> factory) {
this(DEFAULT_POOL_SIZE, factory);
}
/**
* @param maxPoolSize the maximum size of the pool
*/
public QueuedFtpClientPool(int maxPoolSize, FtpClientFactory factory) {
Assert.notNull(factory);
public QueuedFtpClientPool(int maxPoolSize, FtpClientFactory<?> factory) {
Assert.notNull(factory, "factory must not be null");
this.factory = factory;
pool = new ArrayBlockingQueue<FTPClient>(maxPoolSize);
this.pool = new ArrayBlockingQueue<FTPClient>(maxPoolSize);
}
/**
@@ -65,12 +71,10 @@ public class QueuedFtpClientPool implements FtpClientPool {
* reason large pools are not recommended in poor networking conditions.
*/
public FTPClient getClient() throws SocketException, IOException {
FTPClient client = pool.poll();
FTPClient client = this.pool.poll();
if (client == null) {
client = factory.getClient();
client = this.factory.getClient();
}
return prepareClient(client);
}
@@ -88,8 +92,7 @@ public class QueuedFtpClientPool implements FtpClientPool {
* @throws SocketException
* @throws IOException
*/
protected FTPClient prepareClient(FTPClient client)
throws SocketException, IOException {
protected FTPClient prepareClient(FTPClient client) throws SocketException, IOException {
return isClientAlive(client) ? client : getClient();
}
@@ -98,20 +101,26 @@ public class QueuedFtpClientPool implements FtpClientPool {
if (client.sendNoOp()) {
return true;
}
} catch (IOException e) {
log.warn("Client [" + client + "] discarded: ", e);
}
catch (IOException e) {
if (logger.isWarnEnabled()) {
logger.warn("Client [" + client + "] discarded: ", e);
}
}
return false;
}
public void releaseClient(FTPClient client) {
if ((client != null) && !pool.offer(client)) {
if ((client != null) && !this.pool.offer(client)) {
try {
client.disconnect();
} catch (IOException e) {
log.warn("Error disconnecting ftpclient", e);
}
catch (IOException e) {
if (logger.isWarnEnabled()) {
logger.warn("Error disconnecting ftpclient", e);
}
}
}
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp.config;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
@@ -8,25 +24,21 @@ import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.ftp.FtpSendingMessageHandlerFactoryBean;
import org.w3c.dom.Element;
/**
* Logic for parsing the ftp:outbound-channel-adapter
*
* @author Josh Long
*/
public class FtpMessageSendingConsumerBeanDefinitionParser
extends AbstractOutboundChannelAdapterParser {
public class FtpMessageSendingConsumerBeanDefinitionParser extends AbstractOutboundChannelAdapterParser {
@Override
protected AbstractBeanDefinition parseConsumer(Element element,
ParserContext parserContext) {
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
FtpSendingMessageHandlerFactoryBean.class.getName());
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder,element,"charset");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder,element,"filename-generator", "fileNameGenerator");
FtpNamespaceParserSupport.configureCoreFtpClient(builder, element,
parserContext);
FtpNamespaceParserSupport.configureCoreFtpClient(builder, element, parserContext);
return builder.getBeanDefinition();
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp.config;
import java.util.Arrays;
@@ -34,8 +50,8 @@ public class FtpMessageSourceBeanDefinitionParser extends AbstractPollingInbound
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, a);
}
FtpNamespaceParserSupport.configureCoreFtpClient(builder, element, parserContext);
String beanName = BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(),
parserContext.getRegistry());
String beanName = BeanDefinitionReaderUtils.registerWithGeneratedName(
builder.getBeanDefinition(), parserContext.getRegistry());
return new RuntimeBeanReference(beanName);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors
* Copyright 2002-2010 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.
@@ -13,15 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp.config;
import org.apache.commons.net.ftp.FTP;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHandler;
import java.util.HashMap;
import java.util.Map;
/**
* Provides namespace support for using FTP
* <p/>
@@ -29,9 +29,10 @@ import java.util.Map;
*
* @author Josh Long
*/
@SuppressWarnings("unused")
public class FtpNamespaceHandler extends NamespaceHandlerSupport {
public class FtpNamespaceHandler extends AbstractIntegrationNamespaceHandler {
static public Map<String, Integer> FILE_TYPES = new HashMap<String, Integer>();
static public Map<String, Integer> CLIENT_MODES = new HashMap<String, Integer>();
static {
@@ -47,10 +48,10 @@ public class FtpNamespaceHandler extends NamespaceHandlerSupport {
CLIENT_MODES.put("passive-remote-data-connection-mode", 3);
}
public void init() {
registerBeanDefinitionParser("inbound-channel-adapter",
new FtpMessageSourceBeanDefinitionParser());
registerBeanDefinitionParser("outbound-channel-adapter",
new FtpMessageSendingConsumerBeanDefinitionParser());
registerBeanDefinitionParser("inbound-channel-adapter", new FtpMessageSourceBeanDefinitionParser());
registerBeanDefinitionParser("outbound-channel-adapter", new FtpMessageSendingConsumerBeanDefinitionParser());
}
}

View File

@@ -1,42 +1,52 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.w3c.dom.Element;
/**
* A lot of parsers need to support the same set of core attributes, so I'm hiding that logic here
* General support for parsers in the FTP namespace.
*
* @author Josh Long
*/
public class FtpNamespaceParserSupport {
/**
* lots of values are supported across all adapters, let this code handle it initially
*
* Handles values that are supported across all adapters.
* @param builder a builder
* @param element an element
* @param parserContext a parser context
*/
public static void configureCoreFtpClient(BeanDefinitionBuilder builder,
Element element, ParserContext parserContext) {
for (String p : "auto-create-directories,username,port,password,host,remote-directory".split(
",")) {
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder,
element, p);
public static void configureCoreFtpClient(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) {
for (String p : "auto-create-directories,username,port,password,host,remote-directory".split(",")) {
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, p);
}
if (element.hasAttribute("file-type")) {
int fileType = FtpNamespaceHandler.FILE_TYPES.get(element.getAttribute(
"file-type"));
int fileType = FtpNamespaceHandler.FILE_TYPES.get(element.getAttribute("file-type"));
builder.addPropertyValue("fileType", fileType);
}
if (element.hasAttribute("client-mode")) {
int clientMode = FtpNamespaceHandler.CLIENT_MODES.get(element.getAttribute(
"client-mode"));
int clientMode = FtpNamespaceHandler.CLIENT_MODES.get(element.getAttribute("client-mode"));
builder.addPropertyValue("clientMode", clientMode);
}
}
}

View File

@@ -1,32 +1,44 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.ftp.FtpsSendingMessageHandlerFactoryBean;
import org.w3c.dom.Element;
/**
* Logic for parsing the ftp:outbound-channel-adapter
* Parser for the FTPS outbound-channel-adapter
*
* @author Josh Long
*/
public class FtpsMessageSendingConsumerBeanDefinitionParser extends AbstractOutboundChannelAdapterParser {
@Override
protected AbstractBeanDefinition parseConsumer(Element element,
ParserContext parserContext) {
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
FtpsSendingMessageHandlerFactoryBean.class.getName());
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder,element,"charset");
FtpNamespaceParserSupport.configureCoreFtpClient(builder, element,
parserContext);
FtpNamespaceParserSupport.configureCoreFtpClient(builder, element, parserContext);
return builder.getBeanDefinition();
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2002-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp.config;
import java.util.Arrays;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010 the original author or authors
* Copyright 2002-2010 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.
@@ -13,25 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.ftp.config;
/**
* Provides namespace support for using FTP
* Provides namespace support for using FTP.
* <p/>
* This is *heavily* influenced by the good work done by Iwein before.
*
* @author Josh Long
*/
@SuppressWarnings("unused")
public class FtpsNamespaceHandler extends FtpNamespaceHandler {
@Override
public void init() {
this.registerBeanDefinitionParser("inbound-channel-adapter",
new FtpsMessageSourceBeanDefinitionParser());
// todo test this
this.registerBeanDefinitionParser("outbound-channel-adapter",
new FtpsMessageSendingConsumerBeanDefinitionParser());
this.registerBeanDefinitionParser("inbound-channel-adapter", new FtpsMessageSourceBeanDefinitionParser());
this.registerBeanDefinitionParser("outbound-channel-adapter", new FtpsMessageSendingConsumerBeanDefinitionParser());
}
}

View File

@@ -1,117 +0,0 @@
package org.springframework.integration.ftp.impl;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
import org.springframework.core.io.ResourceLoader;
import org.springframework.integration.file.entries.CompositeEntryListFilter;
import org.springframework.integration.file.entries.EntryListFilter;
import org.springframework.integration.file.entries.PatternMatchingEntryListFilter;
import org.springframework.integration.ftp.*;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.IOException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.TrustManager;
/**
* Factory to make building the namespace easier
*
* @author Iwein Fuld
* @author Josh Long
*/
public class FtpsRemoteFileSystemSynchronizingMessageSourceFactoryBean extends FtpRemoteFileSystemSynchronizingMessageSourceFactoryBean {
/**
* Sets whether the connection is implicit. Local testing reveals this to be a good choice.
*/
protected volatile Boolean implicit = Boolean.FALSE;
/**
* "TLS" or "SSL"
*/
protected volatile String protocol;
/**
* "P"
*/
protected volatile String prot;
private KeyManager keyManager;
private TrustManager trustManager;
protected volatile String authValue;
private Boolean sessionCreation;
private Boolean useClientMode;
private Boolean needClientAuth;
private Boolean wantsClientAuth;
private String[] cipherSuites;
public FtpsRemoteFileSystemSynchronizingMessageSourceFactoryBean() {
this.defaultFtpInboundFolderName = "ftpsInbound";
this.clientMode = FTPClient.PASSIVE_LOCAL_DATA_CONNECTION_MODE;
}
public void setKeyManager(KeyManager keyManager) {
this.keyManager = keyManager;
}
public void setTrustManager(TrustManager trustManager) {
this.trustManager = trustManager;
}
public void setImplicit(Boolean implicit) {
this.implicit = implicit;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public void setProt(String prot) {
this.prot = prot;
}
public void setAuthValue(String authValue) {
this.authValue = authValue;
}
public void setSessionCreation(Boolean sessionCreation) {
this.sessionCreation = sessionCreation;
}
public void setUseClientMode(Boolean useClientMode) {
this.useClientMode = useClientMode;
}
public void setNeedClientAuth(Boolean needClientAuth) {
this.needClientAuth = needClientAuth;
}
public void setWantsClientAuth(Boolean wantsClientAuth) {
this.wantsClientAuth = wantsClientAuth;
}
protected AbstractFtpClientFactory defaultClientFactory()
throws Exception {
DefaultFtpsClientFactory factory = ClientFactorySupport.ftpsClientFactory(this.host, Integer.parseInt(this.port), this.remoteDirectory, this.username, this.password, this.fileType,
this.clientMode, this.prot, this.protocol, this.authValue, this.implicit, this.trustManager, this.keyManager, this.sessionCreation, this.useClientMode, this.wantsClientAuth,
this.needClientAuth, this.cipherSuites);
return factory;
}
public void setCipherSuites(String[] cipherSuites) {
this.cipherSuites = cipherSuites;
}
}

View File

@@ -29,13 +29,10 @@
<xsd:import namespace="http://www.springframework.org/schema/integration"
schemaLocation="http://www.springframework.org/schema/integration/spring-integration-2.0.xsd"/>
<xsd:element name="outbound-channel-adapter">
<xsd:annotation>
<xsd:documentation><![CDATA[
Builds an outbound-channel-adapter that writes files to a remote FTP endpoint.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
@@ -49,7 +46,6 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="username" type="xsd:string" use="required"/>
<xsd:attribute name="remote-directory" type="xsd:string" use="required"/>
<xsd:attribute name="host" type="xsd:string" use="required"/>
@@ -59,7 +55,7 @@
<xsd:attribute name="filename-generator" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Allows you to specify a reference to
Allows you to specify a reference to
[org.springframework.integration.file.FileNameGenerator] implementation.
</xsd:documentation>
<xsd:appinfo>
@@ -71,10 +67,9 @@
</xsd:attribute>
<xsd:attribute use="optional" name="client-mode" default="active-local-data-connection-mode">
<xsd:annotation>
<xsd:documentation><![CDATA[
the FTP Client-Mode.
/***
<xsd:documentation><![CDATA[the FTP Client-Mode
/***
* A constant indicating the FTP session is expecting all transfers
* to occur between the client (local) and server and that the server
* should connect to the client's data port to initiate a data transfer.
@@ -107,8 +102,6 @@
* transfer.
***/
PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
@@ -120,13 +113,10 @@
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute use="optional" name="file-type" default="binary-file-type">
<xsd:attribute name="file-type" default="binary-file-type" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Binary, ASCII, or EBDIC. Binary's a good default
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
@@ -137,17 +127,13 @@
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="inbound-channel-adapter">
<xsd:annotation>
<xsd:documentation><![CDATA[
Builds an inbound-channel-adapter that synchronizes a local directory with the contents of a remote FTP endpoint.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
@@ -164,12 +150,10 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute use="optional" name="file-type" default="binary-file-type">
<xsd:attribute name="file-type" default="binary-file-type" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Binary, ASCII, or EBDIC. Binary's a good default
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
@@ -190,24 +174,19 @@
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="filename-pattern" type="xsd:string"/>
<xsd:attribute name="local-working-directory" type="xsd:string"/>
<xsd:attribute name="auto-create-directories" type="xsd:boolean"/>
<xsd:attribute name="auto-delete-remote-files-on-sync" type="xsd:boolean"/>
<xsd:attribute name="username" type="xsd:string" use="required"/>
<xsd:attribute name="remote-directory" type="xsd:string" use="required"/>
<xsd:attribute name="host" type="xsd:string" use="required"/>
<xsd:attribute name="password" type="xsd:string"/>
<xsd:attribute name="port" type="xsd:int" default="22"/>
<xsd:attribute use="optional" name="client-mode" default="active-local-data-connection-mode">
<xsd:attribute name="client-mode" default="active-local-data-connection-mode" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
the FTP Client-Mode.
/***
<xsd:documentation><![CDATA[the FTP Client-Mode
/***
* A constant indicating the FTP session is expecting all transfers
* to occur between the client (local) and server and that the server
* should connect to the client's data port to initiate a data transfer.
@@ -240,8 +219,6 @@
* transfer.
***/
PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
@@ -250,13 +227,10 @@
<xsd:enumeration value="active-remote-data-connection-mode"/>
<xsd:enumeration value="passive-local-data-connection-mode"/>
<xsd:enumeration value="passive-remote-data-connection-mode"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@@ -29,13 +29,10 @@
<xsd:import namespace="http://www.springframework.org/schema/integration"
schemaLocation="http://www.springframework.org/schema/integration/spring-integration-2.0.xsd"/>
<xsd:element name="outbound-channel-adapter">
<xsd:annotation>
<xsd:documentation><![CDATA[
Builds an outbound-channel-adapter that writes files to a remote FTPS endpoint.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
@@ -49,8 +46,6 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="username" type="xsd:string" use="required"/>
<xsd:attribute name="remote-directory" type="xsd:string" use="required"/>
<xsd:attribute name="host" type="xsd:string" use="required"/>
@@ -70,10 +65,10 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute use="optional" name="client-mode" default="active-local-data-connection-mode">
<xsd:attribute name="client-mode" default="active-local-data-connection-mode" use="optional" >
<xsd:annotation>
<xsd:documentation><![CDATA[
the FTP Client-Mode.
the FTP Client-Mode
/***
* A constant indicating the FTP session is expecting all transfers
@@ -109,7 +104,6 @@
***/
PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
@@ -121,14 +115,11 @@
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute use="optional" name="file-type" default="binary-file-type">
<xsd:attribute name="file-type" default="binary-file-type" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Binary, ASCII, or EBDIC. Binary's a good default
]]></xsd:documentation>
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:NMTOKEN">
@@ -138,26 +129,19 @@
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="inbound-channel-adapter">
<xsd:annotation>
<xsd:documentation><![CDATA[
Builds an inbound-channel-adapter that synchronizes a local directory with the contents of a remote FTP endpoint.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="channel" use="required" type="xsd:string">
<xsd:annotation>
@@ -171,10 +155,8 @@
<xsd:attribute use="optional" name="file-type" default="binary-file-type">
<xsd:annotation>
<xsd:documentation><![CDATA[
Binary, ASCII, or EBDIC. Binary's a good default
]]></xsd:documentation>
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:NMTOKEN">
@@ -194,13 +176,9 @@
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="filename-pattern" type="xsd:string"/>
<xsd:attribute name="local-working-directory" type="xsd:string"/>
<xsd:attribute name="auto-create-directories" type="xsd:boolean"/>
<xsd:attribute name="auto-delete-remote-files-on-sync" type="xsd:boolean"/>
<xsd:attribute name="username" type="xsd:string" use="required"/>
<xsd:attribute name="remote-directory" type="xsd:string" use="required"/>
<xsd:attribute name="host" type="xsd:string" use="required"/>
@@ -244,8 +222,6 @@
* transfer.
***/
PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
@@ -254,7 +230,6 @@
<xsd:enumeration value="active-remote-data-connection-mode"/>
<xsd:enumeration value="passive-local-data-connection-mode"/>
<xsd:enumeration value="passive-remote-data-connection-mode"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
@@ -262,5 +237,4 @@
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@@ -4,8 +4,5 @@ log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
log4j.category.org.springframework=WARN
# log4j.category.org.springframework.integration=DEBUG
# log4j.category.org.springframework.integration.jdbc=DEBUG
log4j.category.org.springframework.ftp=DEBUG