Added PatternMatchingFileListFilter and namespace support for the "filename-pattern" attribute. AbstractFilePayloadTransformer now sets the "filename" Message header. Renamed the filters to include FileListFilter (rather than just FileFilter) to avoid confusion with the FileFilter interface.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A convenience base class for any {@link FileListFilter} whose criteria can
|
||||
* be evaluated against each File in isolation. If the entire List of files is
|
||||
* required for evaluation, implement the FileListFilter interface directly.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public abstract class AbstractFileListFilter implements FileListFilter {
|
||||
|
||||
/**
|
||||
* Returns the list of files that are accepted by this filter.
|
||||
*/
|
||||
public final List<File> filterFiles(File[] files) {
|
||||
List<File> accepted = new ArrayList<File>();
|
||||
for (File file : files) {
|
||||
if (this.accept(file)) {
|
||||
accepted.add(file);
|
||||
}
|
||||
}
|
||||
return accepted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement this method.
|
||||
*/
|
||||
protected abstract boolean accept(File file);
|
||||
|
||||
}
|
||||
@@ -17,8 +17,6 @@
|
||||
package org.springframework.integration.file;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
@@ -28,9 +26,8 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||
* {@link PollableFileSource}.
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
*
|
||||
*/
|
||||
public class AcceptOnceFileFilter implements FileListFilter {
|
||||
public class AcceptOnceFileListFilter extends AbstractFileListFilter {
|
||||
|
||||
private final Queue<File> seen;
|
||||
|
||||
@@ -45,34 +42,20 @@ public class AcceptOnceFileFilter implements FileListFilter {
|
||||
* @param maxCapacity the maximum number of Files to maintain in the 'seen'
|
||||
* queue.
|
||||
*/
|
||||
public AcceptOnceFileFilter(int maxCapacity) {
|
||||
public AcceptOnceFileListFilter(int maxCapacity) {
|
||||
this.seen = new LinkedBlockingQueue<File>(maxCapacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an AcceptOnceFileFilter based on an unbounded queue.
|
||||
*/
|
||||
public AcceptOnceFileFilter() {
|
||||
public AcceptOnceFileListFilter() {
|
||||
this.seen = new LinkedBlockingQueue<File>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the list of files that have not already been filtered by this
|
||||
* instance.
|
||||
*/
|
||||
public List<File> filterFiles(File[] files) {
|
||||
List<File> accepted = new ArrayList<File>();
|
||||
for (File file : files) {
|
||||
if (accept(file)) {
|
||||
accepted.add(file);
|
||||
}
|
||||
}
|
||||
return accepted;
|
||||
}
|
||||
|
||||
private boolean accept(File pathname) {
|
||||
synchronized (monitor) {
|
||||
protected boolean accept(File pathname) {
|
||||
synchronized (this.monitor) {
|
||||
if (seen.contains(pathname)) {
|
||||
return false;
|
||||
}
|
||||
@@ -26,23 +26,25 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* Composition that delegates to multiple {@link FileFilter}s. The composition
|
||||
* is AND based, meaning that all filters must {@link #filterFiles(File)} in
|
||||
* order for a file to be accepted by the composite.
|
||||
* is AND based, meaning that a file must pass through each filter's
|
||||
* {@link #filterFiles(File)} method in order to be accepted by the composite.
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
*/
|
||||
public class CompositeFileFilter implements FileListFilter {
|
||||
public class CompositeFileListFilter implements FileListFilter {
|
||||
|
||||
private final Set<FileListFilter> fileFilters;
|
||||
|
||||
public CompositeFileFilter(FileListFilter... fileFilters) {
|
||||
|
||||
public CompositeFileListFilter(FileListFilter... fileFilters) {
|
||||
this.fileFilters = new HashSet<FileListFilter>(Arrays.asList(fileFilters));
|
||||
}
|
||||
|
||||
public CompositeFileFilter(Collection<FileListFilter> fileFilters) {
|
||||
public CompositeFileListFilter(Collection<FileListFilter> fileFilters) {
|
||||
this.fileFilters = new HashSet<FileListFilter>(fileFilters);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -59,7 +61,7 @@ public class CompositeFileFilter implements FileListFilter {
|
||||
* @param filters one or more new filters to be used
|
||||
* @return a new CompositeFileFilter with the additional filters
|
||||
*/
|
||||
public CompositeFileFilter addFilter(FileListFilter... filters) {
|
||||
public CompositeFileListFilter addFilter(FileListFilter... filters) {
|
||||
return addFilters(Arrays.asList(filters));
|
||||
}
|
||||
|
||||
@@ -70,9 +72,10 @@ public class CompositeFileFilter implements FileListFilter {
|
||||
* @param filtersToAdd
|
||||
* @return a new CompositeFileFilter with the added filters
|
||||
*/
|
||||
public CompositeFileFilter addFilters(Collection<FileListFilter> filtersToAdd) {
|
||||
public CompositeFileListFilter addFilters(Collection<FileListFilter> filtersToAdd) {
|
||||
HashSet<FileListFilter> newFilterSet = new HashSet<FileListFilter>(filtersToAdd);
|
||||
newFilterSet.addAll(fileFilters);
|
||||
return new CompositeFileFilter(newFilterSet);
|
||||
return new CompositeFileListFilter(newFilterSet);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,29 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Strategy interface for filtering a group of files.
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
*/
|
||||
public interface FileListFilter {
|
||||
|
||||
List<File> filterFiles(File[] files);
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A {@link FileListFilter} implementation that matches against a {@link Pattern}.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class PatternMatchingFileListFilter extends AbstractFileListFilter {
|
||||
|
||||
private final Pattern pattern;
|
||||
|
||||
|
||||
/**
|
||||
* Create a filter for the given pattern.
|
||||
*/
|
||||
public PatternMatchingFileListFilter(Pattern pattern) {
|
||||
Assert.notNull(pattern, "pattern must not be null");
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
|
||||
protected boolean accept(File file) {
|
||||
return (file != null)
|
||||
&& this.pattern.matcher(file.getName()).matches();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.file;
|
||||
|
||||
import java.io.File;
|
||||
@@ -26,6 +27,7 @@ import java.util.concurrent.PriorityBlockingQueue;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.message.Message;
|
||||
@@ -36,16 +38,17 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* PollableSource that creates messages from a file system directory. To prevent
|
||||
* messages from showing up on the source you can supply a FileFilter to it. By
|
||||
* default an {@link AcceptOnceFileFilter} is used that ensures files are picked
|
||||
* messages for certain files, you may supply a {@link FileListFilter}. By
|
||||
* default, an {@link AcceptOnceFileListFilter} is used. It ensures files are picked
|
||||
* up only once from the directory.
|
||||
*
|
||||
* A common problem with reading files is that files are picked up that are not
|
||||
* ready. The default {@link AcceptOnceFileFilter} does not prevent this. In
|
||||
* most cases this can be prevented by renaming the files as soon as they are
|
||||
* ready. A FileFilter that accepts only files that are ready, composed with the
|
||||
* default {@link AcceptOnceFileFilter} would allow for this.
|
||||
* @see CompositeFileFilter for a way to do this.
|
||||
* <p>
|
||||
* A common problem with reading files is that a file may be detected before it
|
||||
* is ready. The default {@link AcceptOnceFileListFilter} does not prevent this. In
|
||||
* most cases, this can be prevented if the file-writing process renames each
|
||||
* file as soon as it is ready for reading. A pattern-matching filter that
|
||||
* accepts only files that are ready (e.g. based on a known suffix), composed
|
||||
* with the default {@link AcceptOnceFileListFilter} would allow for this.
|
||||
* See {@ link CompositeFileFilter} for a way to do this.
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
*/
|
||||
@@ -57,7 +60,8 @@ public class PollableFileSource implements PollableSource<File>, MessageDelivery
|
||||
|
||||
private final Queue<File> toBeReceived = new PriorityBlockingQueue<File>();
|
||||
|
||||
private volatile FileListFilter filter = new AcceptOnceFileFilter();
|
||||
private volatile FileListFilter filter = new AcceptOnceFileListFilter();
|
||||
|
||||
|
||||
public void setInputDirectory(Resource inputDirectory) {
|
||||
Assert.notNull(inputDirectory, "inputDirectory cannot be null");
|
||||
@@ -73,10 +77,10 @@ public class PollableFileSource implements PollableSource<File>, MessageDelivery
|
||||
|
||||
/**
|
||||
* Sets a {@link FileFilter} on the {@link PollableSource}. By default a
|
||||
* {@link AcceptOnceFileFilter} with no bounds is used. In most cases a
|
||||
* {@link AcceptOnceFileListFilter} with no bounds is used. In most cases a
|
||||
* customized {@link FileFilter} will be needed to deal with modification
|
||||
* and duplication concerns. If multiple filters are required a
|
||||
* {@link CompositeFileFilter} can be used to group them together <p/>
|
||||
* {@link CompositeFileListFilter} can be used to group them together <p/>
|
||||
* <b>Note that the supplied filter must be thread safe</b>.
|
||||
*/
|
||||
public void setFilter(FileListFilter filter) {
|
||||
|
||||
@@ -16,12 +16,18 @@
|
||||
|
||||
package org.springframework.integration.file.config;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.ConfigurationException;
|
||||
import org.springframework.integration.config.AbstractPollingInboundChannelAdapterParser;
|
||||
import org.springframework.integration.file.AcceptOnceFileListFilter;
|
||||
import org.springframework.integration.file.CompositeFileListFilter;
|
||||
import org.springframework.integration.file.PatternMatchingFileListFilter;
|
||||
import org.springframework.integration.file.PollableFileSource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -29,6 +35,7 @@ import org.springframework.util.StringUtils;
|
||||
* Parser for the <inbound-channel-adapter> element of the 'file' namespace.
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class FileInboundChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser {
|
||||
|
||||
@@ -43,6 +50,17 @@ public class FileInboundChannelAdapterParser extends AbstractPollingInboundChann
|
||||
if (StringUtils.hasText(filter)){
|
||||
builder.addPropertyReference("filter", filter);
|
||||
}
|
||||
String filenamePattern = element.getAttribute("filename-pattern");
|
||||
if (StringUtils.hasText(filenamePattern)) {
|
||||
if (StringUtils.hasText(filter)) {
|
||||
throw new ConfigurationException("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);
|
||||
}
|
||||
return BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), parserContext.getRegistry());
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<xsd:attribute name="directory" type="xsd:string"/>
|
||||
<xsd:attribute name="channel" type="xsd:string"/>
|
||||
<xsd:attribute name="filter" type="xsd:string"/>
|
||||
<xsd:attribute name="filename-pattern" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
||||
@@ -18,8 +18,13 @@ package org.springframework.integration.file.transformer;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessagingException;
|
||||
import org.springframework.integration.transformer.AbstractPayloadTransformer;
|
||||
import org.springframework.integration.transformer.Transformer;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -27,32 +32,41 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public abstract class AbstractFilePayloadTransformer<T> extends AbstractPayloadTransformer<File, T> {
|
||||
public abstract class AbstractFilePayloadTransformer<T> implements Transformer {
|
||||
|
||||
private volatile boolean deleteFile;
|
||||
private final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
private volatile boolean deleteFileAfterTransformation;
|
||||
|
||||
|
||||
/**
|
||||
* Specify whether to delete the File after transformation.
|
||||
*/
|
||||
public void setDeleteFile(boolean deleteFile) {
|
||||
this.deleteFile = deleteFile;
|
||||
public void setDeleteFileAfterTransformation(boolean deleteFileAfterTransformation) {
|
||||
this.deleteFileAfterTransformation = deleteFileAfterTransformation;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final T transformPayload(File file) throws Exception {
|
||||
Assert.notNull(file, "File must not be null");
|
||||
if (!file.exists()) {
|
||||
throw new MessagingException("File '" + file + "' no longer exists.");
|
||||
}
|
||||
if (!file.canRead()) {
|
||||
throw new MessagingException("Unable to read File '" + file + "'");
|
||||
}
|
||||
T result = transformFile(file);
|
||||
if (this.deleteFile) {
|
||||
file.delete();
|
||||
}
|
||||
return result;
|
||||
public final Message<?> transform(Message<?> message) {
|
||||
try {
|
||||
Assert.notNull(message, "Message must not be null");
|
||||
Object payload = message.getPayload();
|
||||
Assert.notNull(payload, "Mesasge payload must not be null");
|
||||
Assert.isInstanceOf(File.class, payload, "Message payload must be of type [java.io.File]");
|
||||
File file = (File) payload;
|
||||
T result = this.transformFile(file);
|
||||
Message<?> transformedMessage = MessageBuilder.withPayload(result)
|
||||
.copyHeaders(message.getHeaders())
|
||||
.setHeaderIfAbsent("filename", file.getName())
|
||||
.build();
|
||||
if (this.deleteFileAfterTransformation) {
|
||||
if (!file.delete() && this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("failed to delete File '" + file + "'");
|
||||
}
|
||||
}
|
||||
return transformedMessage;
|
||||
} catch (Exception e) {
|
||||
throw new MessagingException(message, "failed to transform File Message", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.junit.Test;
|
||||
/**
|
||||
* @author Iwein Fuld
|
||||
*/
|
||||
public class CompositeFileFilterTest {
|
||||
public class CompositeFileListFilterTests {
|
||||
|
||||
private FileListFilter fileFilterMock1 = createMock(FileListFilter.class);
|
||||
|
||||
@@ -45,7 +45,7 @@ public class CompositeFileFilterTest {
|
||||
|
||||
@Test
|
||||
public void forwardedToFilters() throws Exception {
|
||||
CompositeFileFilter compositeFileFilter = new CompositeFileFilter(fileFilterMock1, fileFilterMock2);
|
||||
CompositeFileListFilter compositeFileFilter = new CompositeFileListFilter(fileFilterMock1, fileFilterMock2);
|
||||
List<File> returnedFiles = Arrays.asList(new File[] { fileMock });
|
||||
expect(fileFilterMock1.filterFiles(isA(File[].class))).andReturn(returnedFiles).times(1);
|
||||
expect(fileFilterMock2.filterFiles(isA(File[].class))).andReturn(returnedFiles).times(1);
|
||||
@@ -56,7 +56,7 @@ public class CompositeFileFilterTest {
|
||||
|
||||
@Test
|
||||
public void forwardedToAddedFilters() throws Exception {
|
||||
CompositeFileFilter compositeFileFilter = new CompositeFileFilter().addFilter(fileFilterMock1, fileFilterMock2);
|
||||
CompositeFileListFilter compositeFileFilter = new CompositeFileListFilter().addFilter(fileFilterMock1, fileFilterMock2);
|
||||
List<File> returnedFiles = Arrays.asList(new File[] { fileMock });
|
||||
expect(fileFilterMock1.filterFiles(isA(File[].class))).andReturn(returnedFiles).times(1);
|
||||
expect(fileFilterMock2.filterFiles(isA(File[].class))).andReturn(returnedFiles).times(1);
|
||||
@@ -67,7 +67,7 @@ public class CompositeFileFilterTest {
|
||||
|
||||
@Test
|
||||
public void negative() throws Exception {
|
||||
CompositeFileFilter compositeFileFilter = new CompositeFileFilter(fileFilterMock1, fileFilterMock2);
|
||||
CompositeFileListFilter compositeFileFilter = new CompositeFileListFilter(fileFilterMock1, fileFilterMock2);
|
||||
expect(fileFilterMock2.filterFiles(isA(File[].class))).andReturn(new ArrayList<File>()).times(1);
|
||||
expect(fileFilterMock1.filterFiles(isA(File[].class))).andReturn(new ArrayList<File>()).times(1);
|
||||
replay(fileFilterMock1, fileFilterMock2);
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class PatternMatchingFileListFilterTests {
|
||||
|
||||
@Test
|
||||
public void matchSingleFile() {
|
||||
File[] files = new File[] { new File("/some/path/test.txt") };
|
||||
Pattern pattern = Pattern.compile("[a-z]+\\.txt");
|
||||
PatternMatchingFileListFilter filter = new PatternMatchingFileListFilter(pattern);
|
||||
List<File> accepted = filter.filterFiles(files);
|
||||
assertEquals(1, accepted.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noMatchWithSingleFile() {
|
||||
File[] files = new File[] { new File("/some/path/Test.txt") };
|
||||
Pattern pattern = Pattern.compile("[a-z]+\\.txt");
|
||||
PatternMatchingFileListFilter filter = new PatternMatchingFileListFilter(pattern);
|
||||
List<File> accepted = filter.filterFiles(files);
|
||||
assertEquals(0, accepted.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchSubset() {
|
||||
File[] files = new File[] {
|
||||
new File("/some/path/foo.txt"),
|
||||
new File("/some/path/foo.not"),
|
||||
new File("/some/path/bar.txt"),
|
||||
new File("/some/path/bar.not")
|
||||
};
|
||||
Pattern pattern = Pattern.compile("[a-z]+\\.txt");
|
||||
PatternMatchingFileListFilter filter = new PatternMatchingFileListFilter(pattern);
|
||||
List<File> accepted = filter.filterFiles(files);
|
||||
assertEquals(2, accepted.size());
|
||||
assertTrue(accepted.contains(new File("/some/path/foo.txt")));
|
||||
assertTrue(accepted.contains(new File("/some/path/bar.txt")));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void nullPattern() {
|
||||
new PatternMatchingFileListFilter(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patternEditorInContext() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"patternMatchingFileListFilterTests.xml", this.getClass());
|
||||
FileListFilter filter = (FileListFilter) context.getBean("filter");
|
||||
File[] files = new File[] { new File("/some/path/foo.txt") };
|
||||
List<File> accepted = filter.filterFiles(files);
|
||||
assertEquals(1, accepted.size());
|
||||
}
|
||||
|
||||
@Test(expected = BeanCreationException.class)
|
||||
public void invalidPatternSyntax() throws Throwable {
|
||||
new ClassPathXmlApplicationContext("invalidPatternMatchingFileListFilterTests.xml", this.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
<!-- under test -->
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<!-- under test -->
|
||||
<bean id="pollableFileSource" class="org.springframework.integration.file.PollableFileSource"
|
||||
p:inputDirectory="file:${java.io.tmpdir}/PollableFileSourceIntegrationTests"
|
||||
p:filter-ref="compositeFilter" />
|
||||
<!-- customized filter -->
|
||||
<bean id="compositeFilter"
|
||||
class="org.springframework.integration.file.CompositeFileFilter">
|
||||
p:filter-ref="compositeFilter"/>
|
||||
|
||||
<!-- customized filter -->
|
||||
<bean id="compositeFilter" class="org.springframework.integration.file.CompositeFileListFilter">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.springframework.integration.file.AcceptOnceFileFilter" />
|
||||
<bean class="org.springframework.integration.file.TestFileFilter" />
|
||||
<bean class="org.springframework.integration.file.AcceptOnceFileListFilter" />
|
||||
<bean class="org.springframework.integration.file.TestFileListFilter" />
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
<bean
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
|
||||
|
||||
</beans>
|
||||
@@ -23,7 +23,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author Iwein Fuld
|
||||
*/
|
||||
public class TestFileFilter implements FileListFilter {
|
||||
public class TestFileListFilter implements FileListFilter {
|
||||
|
||||
public List<File> filterFiles(File[] files) {
|
||||
return Arrays.asList(files);
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration/file"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
@@ -8,14 +9,16 @@
|
||||
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
|
||||
http://www.springframework.org/schema/integration/file
|
||||
http://www.springframework.org/schema/integration/file/spring-integration-file-1.0.xsd">
|
||||
|
||||
<inbound-channel-adapter id="inputDirPoller"
|
||||
directory="file:${java.io.tmpdir}" filter="filter" />
|
||||
<beans:bean id="filter"
|
||||
class="org.springframework.integration.file.CompositeFileFilter">
|
||||
|
||||
<beans:bean id="filter" class="org.springframework.integration.file.CompositeFileListFilter">
|
||||
<beans:constructor-arg>
|
||||
<beans:list></beans:list>
|
||||
</beans:constructor-arg>
|
||||
</beans:bean>
|
||||
<beans:bean
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
|
||||
|
||||
<beans:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
|
||||
|
||||
</beans:beans>
|
||||
@@ -27,7 +27,7 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.channel.MessageChannel;
|
||||
import org.springframework.integration.file.CompositeFileFilter;
|
||||
import org.springframework.integration.file.CompositeFileListFilter;
|
||||
import org.springframework.integration.file.PollableFileSource;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@@ -63,7 +63,7 @@ public class FileInboundChannelAdapterParserTests {
|
||||
|
||||
@Test
|
||||
public void filter() throws Exception {
|
||||
assertTrue("'filter' should be set", accessor.getPropertyValue("filter") instanceof CompositeFileFilter);
|
||||
assertTrue("'filter' should be set", accessor.getPropertyValue("filter") instanceof CompositeFileListFilter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
||||
|
||||
<bean id="filter" class="org.springframework.integration.file.PatternMatchingFileListFilter">
|
||||
<constructor-arg value="[fo+\.[tx]{3}"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
||||
|
||||
<bean id="filter" class="org.springframework.integration.file.PatternMatchingFileListFilter">
|
||||
<constructor-arg value="fo+\.[tx]{3}"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user