diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileInboundChannelAdapterParser.java b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileInboundChannelAdapterParser.java index 65e13c8311..37002df4da 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileInboundChannelAdapterParser.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileInboundChannelAdapterParser.java @@ -86,6 +86,7 @@ public class FileInboundChannelAdapterParser extends AbstractPollingInboundChann if (StringUtils.hasText(filter)) { factoryBeanBuilder.addPropertyReference("filterReference", filter); } + String filenamePattern = element.getAttribute("filename-pattern"); if (StringUtils.hasText(filenamePattern)) { if (StringUtils.hasText(filter)) { @@ -94,6 +95,15 @@ public class FileInboundChannelAdapterParser extends AbstractPollingInboundChann } factoryBeanBuilder.addPropertyValue("filenamePattern", filenamePattern); } + String filenameRegex = element.getAttribute("filename-regex"); + if (StringUtils.hasText(filenameRegex)) { + if (StringUtils.hasText(filter)) { + parserContext.getReaderContext().error( + "At most one of 'filter' and 'filename-regex' may be provided.", element); + } + factoryBeanBuilder.addPropertyValue("filenameRegex", filenameRegex); + } + IntegrationNamespaceUtils.setValueIfAttributeDefined(factoryBeanBuilder, element, "prevent-duplicates"); return BeanDefinitionReaderUtils.registerWithGeneratedName( factoryBeanBuilder.getBeanDefinition(), parserContext.getRegistry()); diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileListFilterFactoryBean.java b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileListFilterFactoryBean.java index 03d6a7751d..f0d9b6faa7 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileListFilterFactoryBean.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileListFilterFactoryBean.java @@ -17,14 +17,12 @@ package org.springframework.integration.file.config; import java.io.File; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import org.springframework.beans.factory.FactoryBean; -import org.springframework.integration.file.filters.AcceptAllFileListFilter; -import org.springframework.integration.file.filters.AcceptOnceFileListFilter; -import org.springframework.integration.file.filters.CompositeFileListFilter; -import org.springframework.integration.file.filters.FileListFilter; -import org.springframework.integration.file.filters.SimplePatternFileListFilter; +import org.springframework.integration.file.filters.*; /** * @author Mark Fisher @@ -38,6 +36,8 @@ public class FileListFilterFactoryBean implements FactoryBean filter; - if ((this.filterReference != null) && (this.filenamePattern != null)) { - throw new IllegalArgumentException("The 'filter' reference and " - + "'filename-pattern' attributes are mutually exclusive."); + if ((this.filterReference != null) && (this.filenamePattern != null || this.filenameRegex!=null)) { + throw new IllegalArgumentException("The 'filter' reference is mutually exclusive with " + + "'filename-pattern' and 'filename-regex' attributes."); } + //'filter' is set if (this.filterReference != null) { if (Boolean.TRUE.equals(this.preventDuplicates)) { filter = this.createCompositeWithAcceptOnceFilter(this.filterReference); @@ -96,15 +101,29 @@ public class FileListFilterFactoryBean implements FactoryBean> filtersNeeded = new ArrayList>(); + if (!Boolean.FALSE.equals(this.preventDuplicates)) { + //preventDuplicates is either null or true + filtersNeeded.add(new AcceptOnceFileListFilter()); } - else { // preventDuplicates is either TRUE or NULL - filter = this.createCompositeWithAcceptOnceFilter(patternFilter); + if (this.filenamePattern!=null){ + filtersNeeded.add(new SimplePatternFileListFilter(this.filenamePattern)); + } + if (this.filenameRegex!=null){ + filtersNeeded.add(new PatternMatchingFileListFilter(this.filenameRegex)); + } + if (filtersNeeded.size()==1){ + filter = filtersNeeded.get(0); + } + else { + filter = new CompositeFileListFilter(filtersNeeded); } } + + // no filters are provided else if (Boolean.FALSE.equals(this.preventDuplicates)) { filter = new AcceptAllFileListFilter(); } @@ -126,10 +145,12 @@ public class FileListFilterFactoryBean implements FactoryBean createCompositeWithAcceptOnceFilter(FileListFilter otherFilter) { + private CompositeFileListFilter createCompositeWithAcceptOnceFilter(FileListFilter... otherFilters) { CompositeFileListFilter compositeFilter = new CompositeFileListFilter(); compositeFilter.addFilter(new AcceptOnceFileListFilter()); - compositeFilter.addFilter(otherFilter); + for (FileListFilter otherFilter : otherFilters) { + compositeFilter.addFilter(otherFilter); + } return compositeFilter; } diff --git a/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-2.0.xsd b/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-2.0.xsd index f00a15167c..92927b03ba 100644 --- a/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-2.0.xsd +++ b/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-2.0.xsd @@ -61,7 +61,22 @@ - + + + + + + + + + + diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithRegexPatternParserTests-context.xml b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithRegexPatternParserTests-context.xml new file mode 100644 index 0000000000..36dab1d7be --- /dev/null +++ b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithRegexPatternParserTests-context.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithRegexPatternParserTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithRegexPatternParserTests.java new file mode 100644 index 0000000000..3c9825cf71 --- /dev/null +++ b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithRegexPatternParserTests.java @@ -0,0 +1,78 @@ +/* + * 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.file.config; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.DirectFieldAccessor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.ApplicationContext; +import org.springframework.integration.channel.AbstractMessageChannel; +import org.springframework.integration.endpoint.AbstractEndpoint; +import org.springframework.integration.file.FileReadingMessageSource; +import org.springframework.integration.file.filters.*; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.io.File; +import java.util.Set; +import java.util.regex.Pattern; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.*; + +/** + * + * @author Mark Fisher + * @author Iwein Fuld + * + * @see org.springframework.integration.file.config.FileInboundChannelAdapterWithPatternParserTests + */ +@ContextConfiguration +@RunWith(SpringJUnit4ClassRunner.class) +public class FileInboundChannelAdapterWithRegexPatternParserTests { + + @Autowired(required = true) + private ApplicationContext context; + + private DirectFieldAccessor accessor; + + @Autowired(required = true) + public void setSource(FileReadingMessageSource source) { + this.accessor = new DirectFieldAccessor(source); + } + + @Test + @SuppressWarnings("unchecked") + public void regexFilter() { + DirectFieldAccessor scannerAccessor = new DirectFieldAccessor(accessor.getPropertyValue("scanner")); + Object extractedFilter = scannerAccessor.getPropertyValue("filter"); + assertThat(extractedFilter, is(CompositeFileListFilter.class)); + Set> filters = (Set>) new DirectFieldAccessor( + extractedFilter).getPropertyValue("fileFilters"); + Pattern pattern = null; + for (FileListFilter filter : filters) { + if (filter instanceof PatternMatchingFileListFilter) { + pattern = (Pattern) new DirectFieldAccessor(filter).getPropertyValue("pattern"); + } + } + assertNotNull("expected SimplePatternFileListFilterTest", pattern); + assertEquals("^.*\\.txt$", pattern.pattern()); + } + +}