INT-1641, INT-1614 added support for 'filename-regex' for the FTP and SFTP inbound channel adapters

This commit is contained in:
Mark Fisher
2010-11-22 01:21:07 -05:00
parent bcc919fed7
commit 7ec046ad3f
8 changed files with 60 additions and 27 deletions

View File

@@ -19,7 +19,6 @@ package org.springframework.integration.file.config;
import org.w3c.dom.Element;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser;
@@ -27,7 +26,7 @@ import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.util.StringUtils;
/**
* Parser for 'sftp:inbound-channel-adapter'
* Abstract base class for parsing remote file inbound channel adapters.
*
* @author Oleg Zhurakousky
* @author Mark Fisher
@@ -36,7 +35,7 @@ import org.springframework.util.StringUtils;
public abstract class AbstractRemoteFileInboundChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser {
@Override
protected BeanMetadataElement parseSource(Element element, ParserContext parserContext) {
protected final BeanMetadataElement parseSource(Element element, ParserContext parserContext) {
// build the SessionFactory
BeanDefinitionBuilder sessionFactoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(
"org.springframework.integration.file.remote.session.CachingSessionFactory");
@@ -48,27 +47,7 @@ public abstract class AbstractRemoteFileInboundChannelAdapterParser extends Abst
synchronizerBuilder.addConstructorArgValue(sessionFactoryBuilder.getBeanDefinition());
IntegrationNamespaceUtils.setValueIfAttributeDefined(synchronizerBuilder, element, "remote-directory");
IntegrationNamespaceUtils.setValueIfAttributeDefined(synchronizerBuilder, element, "delete-remote-files");
// configure the FileListFilter if relevant attributes are present
String fileNamePattern = element.getAttribute("filename-pattern");
String filter = element.getAttribute("filter");
boolean hasFileNamePattern = StringUtils.hasText(fileNamePattern);
boolean hasFilter = StringUtils.hasText(filter);
if (hasFileNamePattern || hasFilter) {
if (!(hasFileNamePattern ^ hasFilter)) {
throw new BeanDefinitionStoreException("at most one of 'filename-pattern' or 'filter' " +
"is allowed on remote file inbound adapter");
}
}
if (hasFileNamePattern) {
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.genericBeanDefinition(
this.getSimplePatternFileListFilterClassname());
filterBuilder.addConstructorArgValue(fileNamePattern);
synchronizerBuilder.addPropertyValue("filter", filterBuilder.getBeanDefinition());
}
else if (hasFilter) {
synchronizerBuilder.addPropertyReference("filter", filter);
}
this.configureFilter(synchronizerBuilder, element, parserContext);
// build the MessageSource
BeanDefinitionBuilder messageSourceBuilder = BeanDefinitionBuilder.genericBeanDefinition(this.getMessageSourceClassname());
@@ -78,10 +57,52 @@ public abstract class AbstractRemoteFileInboundChannelAdapterParser extends Abst
return messageSourceBuilder.getBeanDefinition();
}
private void configureFilter(BeanDefinitionBuilder synchronizerBuilder, Element element, ParserContext parserContext) {
String filter = element.getAttribute("filter");
String fileNamePattern = element.getAttribute("filename-pattern");
String fileNameRegex = element.getAttribute("filename-regex");
boolean hasFilter = StringUtils.hasText(filter);
boolean hasFileNamePattern = StringUtils.hasText(fileNamePattern);
boolean hasFileNameRegex = StringUtils.hasText(fileNameRegex);
if (hasFilter || hasFileNamePattern || hasFileNameRegex) {
int count = 0;
if (hasFilter) {
count++;
}
if (hasFileNamePattern) {
count++;
}
if (hasFileNameRegex) {
count++;
}
if (count != 1) {
parserContext.getReaderContext().error("at most one of 'filename-pattern', " +
"'filename-regex', or 'filter' is allowed on remote file inbound adapter", element);
}
if (hasFilter) {
synchronizerBuilder.addPropertyReference("filter", filter);
}
else if (hasFileNamePattern) {
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.genericBeanDefinition(
this.getSimplePatternFileListFilterClassname());
filterBuilder.addConstructorArgValue(fileNamePattern);
synchronizerBuilder.addPropertyValue("filter", filterBuilder.getBeanDefinition());
}
else if (hasFileNameRegex) {
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.genericBeanDefinition(
this.getRegexPatternFileListFilterClassname());
filterBuilder.addConstructorArgValue(fileNameRegex);
synchronizerBuilder.addPropertyValue("filter", filterBuilder.getBeanDefinition());
}
}
}
protected abstract String getMessageSourceClassname();
protected abstract String getInboundFileSynchronizerClassname();
protected abstract String getSimplePatternFileListFilterClassname();
protected abstract String getRegexPatternFileListFilterClassname();
}

View File

@@ -42,4 +42,9 @@ public class FtpInboundChannelAdapterParser extends AbstractRemoteFileInboundCha
return BASE_PACKAGE + ".filters.FtpSimplePatternFileListFilter";
}
@Override
protected String getRegexPatternFileListFilterClassname() {
return BASE_PACKAGE + ".filters.FtpRegexPatternFileListFilter";
}
}

View File

@@ -55,6 +55,7 @@
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="filename-pattern" type="xsd:string"/>
<xsd:attribute name="filename-regex" type="xsd:string"/>
<xsd:attribute name="filter" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>

View File

@@ -16,7 +16,7 @@
charset="UTF-8"
auto-create-local-directory="true"
delete-remote-files="true"
filename-pattern=".?txt"
filename-pattern="*.txt"
local-directory="."
remote-directory="foo/bar">
<int:poller fixed-rate="1000"/>

View File

@@ -35,7 +35,7 @@
charset="UTF-8"
auto-create-local-directory="true"
delete-remote-files="true"
filename-pattern=".?txt"
filename-regex="[0-9]+\.txt"
local-directory="."
remote-directory="foo/bar">
<int:poller fixed-rate="1000"/>

View File

@@ -44,4 +44,9 @@ public class SftpInboundChannelAdapterParser extends AbstractRemoteFileInboundCh
return BASE_PACKAGE + ".filters.SftpSimplePatternFileListFilter";
}
@Override
protected String getRegexPatternFileListFilterClassname() {
return BASE_PACKAGE + ".filters.SftpRegexPatternFileListFilter";
}
}

View File

@@ -107,6 +107,7 @@
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="filename-pattern" type="xsd:string"/>
<xsd:attribute name="filename-regex" type="xsd:string"/>
<xsd:attribute name="remote-directory" type="xsd:string" use="required"/>
<xsd:attribute name="local-directory" type="xsd:string" use="required"/>
<xsd:attribute name="auto-create-local-directory" type="xsd:boolean"/>

View File

@@ -38,7 +38,7 @@
<sftp:inbound-channel-adapter id="sftpAdapterAutoCreate"
session-factory="sftpSessionFactory"
channel="requestChannel"
filename-pattern="foo.txt"
filename-regex="f[o]+\.txt"
remote-directory="/foo"
local-directory="file:local-test-dir"
auto-create-local-directory="false"