diff --git a/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileInboundChannelAdapterParser.java b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileInboundChannelAdapterParser.java
index 0f2426bb73..25a604da17 100644
--- a/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileInboundChannelAdapterParser.java
+++ b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileInboundChannelAdapterParser.java
@@ -16,19 +16,15 @@
package org.springframework.integration.file.config;
-import java.util.regex.Pattern;
-
import org.w3c.dom.Element;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
+import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser;
-import org.springframework.integration.file.AcceptOnceFileListFilter;
-import org.springframework.integration.file.CompositeFileListFilter;
-import org.springframework.integration.file.PatternMatchingFileListFilter;
-import org.springframework.integration.file.FileReadingMessageSource;
-import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -39,9 +35,14 @@ import org.springframework.util.StringUtils;
*/
public class FileInboundChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser {
+ private static final String PACKAGE_NAME = "org.springframework.integration.file";
+
+
@Override
+ @SuppressWarnings("unchecked")
protected String parseSource(Element element, ParserContext parserContext) {
- BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(FileReadingMessageSource.class);
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
+ PACKAGE_NAME + ".FileReadingMessageSource");
String directory = element.getAttribute("directory");
if (StringUtils.hasText(directory)) {
builder.addPropertyValue("inputDirectory", directory);
@@ -52,15 +53,30 @@ public class FileInboundChannelAdapterParser extends AbstractPollingInboundChann
}
String filenamePattern = element.getAttribute("filename-pattern");
if (StringUtils.hasText(filenamePattern)) {
- Assert.isTrue(!StringUtils.hasText(filter),
- "at most one of 'filter' and 'filename-pattern' may be provided");
- AcceptOnceFileListFilter acceptOnceFilter = new AcceptOnceFileListFilter();
- Pattern pattern = Pattern.compile(filenamePattern);
- PatternMatchingFileListFilter patternFilter = new PatternMatchingFileListFilter(pattern);
- CompositeFileListFilter compositeFilter = new CompositeFileListFilter(acceptOnceFilter, patternFilter);
- builder.addPropertyValue("filter", compositeFilter);
+ if (StringUtils.hasText(filter)) {
+ parserContext.getReaderContext().error(
+ "At most one of 'filter' and 'filename-pattern' may be provided.", element);
+ }
+ String acceptOnceFilterBeanName = this.parseFilter("AcceptOnceFileListFilter", null, parserContext);
+ String patternFilterBeanName = this.parseFilter("PatternMatchingFileListFilter", filenamePattern, parserContext);
+ ManagedList filters = new ManagedList();
+ filters.add(new RuntimeBeanReference(acceptOnceFilterBeanName));
+ filters.add(new RuntimeBeanReference(patternFilterBeanName));
+ String compositeFilterBeanName = this.parseFilter("CompositeFileListFilter", filters, parserContext);
+ builder.addPropertyReference("filter", compositeFilterBeanName);
}
return BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), parserContext.getRegistry());
}
+ private String parseFilter(String shortClassName, Object constructorArgValue, ParserContext parserContext) {
+ BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.genericBeanDefinition(
+ PACKAGE_NAME + "." + shortClassName);
+ filterBuilder.getBeanDefinition().setRole(BeanDefinition.ROLE_SUPPORT);
+ if (constructorArgValue != null) {
+ filterBuilder.addConstructorArgValue(constructorArgValue);
+ }
+ return BeanDefinitionReaderUtils.registerWithGeneratedName(
+ filterBuilder.getBeanDefinition(), parserContext.getRegistry());
+ }
+
}
diff --git a/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileOutboundChannelAdapterParser.java b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileOutboundChannelAdapterParser.java
index b5d6078bb1..851f40be00 100644
--- a/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileOutboundChannelAdapterParser.java
+++ b/org.springframework.integration.file/src/main/java/org/springframework/integration/file/config/FileOutboundChannelAdapterParser.java
@@ -22,8 +22,6 @@ 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.file.FileWritingMessageHandler;
-import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -36,8 +34,11 @@ public class FileOutboundChannelAdapterParser extends AbstractOutboundChannelAda
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
String directory = element.getAttribute("directory");
- Assert.hasText(directory, "directory is required");
- BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(FileWritingMessageHandler.class);
+ if (!StringUtils.hasText(directory)) {
+ parserContext.getReaderContext().error("directory is required", element);
+ }
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
+ "org.springframework.integration.file.FileWritingMessageHandler");
builder.addConstructorArgValue(directory);
String fileNameGenerator = element.getAttribute("filename-generator");
if (StringUtils.hasText(fileNameGenerator)) {
diff --git a/org.springframework.integration.file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPatternParserTests-context.xml b/org.springframework.integration.file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPatternParserTests-context.xml
new file mode 100644
index 0000000000..ef96569e0a
--- /dev/null
+++ b/org.springframework.integration.file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPatternParserTests-context.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/org.springframework.integration.file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPatternParserTests.java b/org.springframework.integration.file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPatternParserTests.java
new file mode 100644
index 0000000000..e61c420afc
--- /dev/null
+++ b/org.springframework.integration.file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPatternParserTests.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2002-2008 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.DirectFieldAccessor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.channel.SubscribableChannel;
+import org.springframework.integration.endpoint.AbstractEndpoint;
+import org.springframework.integration.file.AcceptOnceFileListFilter;
+import org.springframework.integration.file.CompositeFileListFilter;
+import org.springframework.integration.file.FileListFilter;
+import org.springframework.integration.file.FileReadingMessageSource;
+import org.springframework.integration.file.PatternMatchingFileListFilter;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Mark Fisher
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class FileInboundChannelAdapterWithPatternParserTests {
+
+ @Autowired(required=true)
+ private SubscribableChannel channel;
+
+ @Autowired(required=true)
+ private AbstractEndpoint endpoint;
+
+ private DirectFieldAccessor accessor;
+
+
+ @Autowired(required=true)
+ public void setSource(FileReadingMessageSource source) {
+ this.accessor = new DirectFieldAccessor(source);
+ }
+
+ @Test
+ public void channelName() {
+ assertEquals("adapterWithPattern", channel.getName());
+ }
+
+ @Test
+ public void autoStartupDisabled() {
+ assertFalse(this.endpoint.isRunning());
+ Boolean autoStartupValue = (Boolean) new DirectFieldAccessor(endpoint).getPropertyValue("autoStartup");
+ assertFalse(autoStartupValue);
+ }
+
+ @Test
+ public void inputDirectory() {
+ assertEquals(System.getProperty("java.io.tmpdir"), ((File) accessor.getPropertyValue("inputDirectory")).getPath());
+ }
+
+ @Test
+ public void compositeFilterType() {
+ assertTrue(accessor.getPropertyValue("filter") instanceof CompositeFileListFilter);
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void compositeFilterSetSize() {
+ Set filters = (Set) new DirectFieldAccessor(
+ accessor.getPropertyValue("filter")).getPropertyValue("fileFilters");
+ assertEquals(2, filters.size());
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void acceptOnceFilter() {
+ Set filters = (Set) new DirectFieldAccessor(
+ accessor.getPropertyValue("filter")).getPropertyValue("fileFilters");
+ boolean hasAcceptOnceFilter = false;
+ for (FileListFilter filter : filters) {
+ if (filter instanceof AcceptOnceFileListFilter) {
+ hasAcceptOnceFilter = true;
+ }
+ }
+ assertTrue("expected AcceptOnceFileListFilter", hasAcceptOnceFilter);
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void patternFilter() {
+ Set filters = (Set) new DirectFieldAccessor(
+ accessor.getPropertyValue("filter")).getPropertyValue("fileFilters");
+ Pattern pattern = null;
+ for (FileListFilter filter : filters) {
+ if (filter instanceof PatternMatchingFileListFilter) {
+ pattern = (Pattern) new DirectFieldAccessor(filter).getPropertyValue("pattern");
+ }
+ }
+ assertNotNull("expected PatternMatchingFileListFilter", pattern);
+ assertEquals(".*\\.txt", pattern.toString());
+ assertFalse(pattern.matcher("foo").matches());
+ assertTrue(pattern.matcher("foo.txt").matches());
+ }
+
+}