INT-1591 FileListFilter is now parameterized. Existing implementations required refactoring to specify <File> for <F>.

This commit is contained in:
Mark Fisher
2010-11-08 17:31:32 -05:00
parent 59a15d6177
commit e4f6b33b7b
37 changed files with 603 additions and 442 deletions

View File

@@ -21,8 +21,8 @@ import java.util.Arrays;
import java.util.List;
import org.springframework.integration.MessagingException;
import org.springframework.integration.file.entries.AcceptOnceEntryFileListFilter;
import org.springframework.integration.file.entries.EntryListFilter;
import org.springframework.integration.file.filters.AcceptOnceFileListFilter;
import org.springframework.integration.file.filters.FileListFilter;
/**
* Default directory scanner and base class for other directory scanners.
@@ -33,12 +33,12 @@ import org.springframework.integration.file.entries.EntryListFilter;
*/
public class DefaultDirectoryScanner implements DirectoryScanner {
private volatile EntryListFilter<File> filter = new AcceptOnceEntryFileListFilter<File>();
private volatile FileListFilter<File> filter = new AcceptOnceFileListFilter<File>();
private volatile FileLocker locker;
public void setFilter(EntryListFilter<File> filter) {
public void setFilter(FileListFilter<File> filter) {
this.filter = filter;
}
@@ -66,7 +66,7 @@ public class DefaultDirectoryScanner implements DirectoryScanner {
throw new MessagingException("The path [" + directory
+ "] does not denote a properly accessible directory.");
}
return (this.filter != null) ? this.filter.filterEntries(files) : Arrays.asList(files);
return (this.filter != null) ? this.filter.filterFiles(files) : Arrays.asList(files);
}
/**

View File

@@ -16,11 +16,11 @@
package org.springframework.integration.file;
import org.springframework.integration.file.entries.EntryListFilter;
import java.io.File;
import java.util.List;
import org.springframework.integration.file.filters.FileListFilter;
/**
* Strategy for scanning directories. Implementations may select all children
* and grandchildren of the scanned directory in any order. This interface is
@@ -52,7 +52,7 @@ public interface DirectoryScanner {
* @param filter
* the custom filter to be used
*/
void setFilter(EntryListFilter<File> filter);
void setFilter(FileListFilter<File> filter);
/**
* Sets a custom locker to be used by this scanner. The locker will get a

View File

@@ -31,14 +31,14 @@ import org.springframework.integration.MessagingException;
import org.springframework.integration.aggregator.ResequencingMessageGroupProcessor;
import org.springframework.integration.context.IntegrationObjectSupport;
import org.springframework.integration.core.MessageSource;
import org.springframework.integration.file.entries.EntryListFilter;
import org.springframework.integration.file.filters.FileListFilter;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.util.Assert;
/**
* {@link MessageSource} that creates messages from a file system directory. To
* prevent messages for certain files, you may supply a
* {@link org.springframework.integration.file.entries.EntryListFilter}. By
* {@link org.springframework.integration.file.filters.FileListFilter}. By
* default, an
* {@link org.springframework.integration.file.entries.AcceptOnceEntryFileListFilter}
* is used. It ensures files are picked up only once from the directory.
@@ -174,22 +174,19 @@ public class FileReadingMessageSource extends IntegrationObjectSupport implement
}
/**
* Sets a
* {@link org.springframework.integration.file.entries.EntryListFilter}. By
* default a
* {@link org.springframework.integration.file.entries.AcceptOnceEntryFileListFilter}
* with no bounds is used. In most cases a customized
* {@link org.springframework.integration.file.entries.EntryListFilter} will
* Sets a {@link FileListFilter}. By default a
* {@link org.springframework.integration.file.filters.AbstractFileListFilter}
* with no bounds is used. In most cases a customized {@link FileListFilter} will
* be needed to deal with modification and duplication concerns. If multiple
* filters are required a
* {@link org.springframework.integration.file.entries.CompositeEntryListFilter}
* {@link org.springframework.integration.file.filters.CompositeFileListFilter}
* can be used to group them together.
* <p/>
* <b>The supplied filter must be thread safe.</b>.
*
* @param filter a filter
*/
public void setFilter(EntryListFilter<File> filter) {
public void setFilter(FileListFilter<File> filter) {
Assert.notNull(filter, "'filter' must not be null");
this.scanner.setFilter(filter);
}

View File

@@ -16,13 +16,12 @@
package org.springframework.integration.file;
import org.springframework.integration.file.entries.EntryListFilter;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import org.springframework.integration.file.filters.FileListFilter;
/**
* A custom scanner that only returns the first <code>maxNumberOfFiles</code>
* elements from a directory listing. This is useful to limit the number of File
@@ -38,7 +37,7 @@ public class HeadDirectoryScanner extends DefaultDirectoryScanner {
}
private static class HeadFilter implements EntryListFilter<File> {
private static class HeadFilter implements FileListFilter<File> {
private final int maxNumberOfFiles;
@@ -46,7 +45,7 @@ public class HeadDirectoryScanner extends DefaultDirectoryScanner {
this.maxNumberOfFiles = maxNumberOfFiles;
}
public List<File> filterEntries(File[] files) {
public List<File> filterFiles(File[] files) {
return Arrays.asList(files).subList(0, Math.min(files.length, maxNumberOfFiles));
}
}

View File

@@ -16,22 +16,25 @@
package org.springframework.integration.file.config;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.integration.file.entries.*;
import org.springframework.integration.file.filters.SimplePatternFileListFilter;
import java.io.File;
import java.util.Collection;
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;
/**
* @author Mark Fisher
* @since 1.0.3
*/
public class FileListFilterFactoryBean implements FactoryBean<EntryListFilter<File>> {
public class FileListFilterFactoryBean implements FactoryBean<FileListFilter<File>> {
private volatile EntryListFilter<File> fileListFilter;
private volatile FileListFilter<File> fileListFilter;
private volatile EntryListFilter<File> filterReference;
private volatile FileListFilter<File> filterReference;
private volatile String filenamePattern;
@@ -39,14 +42,14 @@ public class FileListFilterFactoryBean implements FactoryBean<EntryListFilter<Fi
private final Object monitor = new Object();
private volatile Collection<EntryListFilter<File>> filterReferences;
private volatile Collection<FileListFilter<File>> filterReferences;
public void setFilterReferences(Collection<EntryListFilter<File>> filterReferences) {
public void setFilterReferences(Collection<FileListFilter<File>> filterReferences) {
this.filterReferences = filterReferences;
}
public void setFilterReference(EntryListFilter<File> filterReference) {
public void setFilterReference(FileListFilter<File> filterReference) {
this.filterReference = filterReference;
}
@@ -58,7 +61,7 @@ public class FileListFilterFactoryBean implements FactoryBean<EntryListFilter<Fi
this.preventDuplicates = preventDuplicates;
}
public EntryListFilter<File> getObject() throws Exception {
public FileListFilter<File> getObject() throws Exception {
if (this.fileListFilter == null) {
synchronized (this.monitor) {
this.intializeFileListFilter();
@@ -68,7 +71,7 @@ public class FileListFilterFactoryBean implements FactoryBean<EntryListFilter<Fi
}
public Class<?> getObjectType() {
return (this.fileListFilter != null) ? this.fileListFilter.getClass() : EntryListFilter.class;
return (this.fileListFilter != null) ? this.fileListFilter.getClass() : FileListFilter.class;
}
public boolean isSingleton() {
@@ -79,7 +82,7 @@ public class FileListFilterFactoryBean implements FactoryBean<EntryListFilter<Fi
if (this.fileListFilter != null) {
return;
}
EntryListFilter<File> filter;
FileListFilter<File> filter;
if ((this.filterReference != null) && (this.filenamePattern != null)) {
throw new IllegalArgumentException("The 'filter' reference and "
+ "'filename-pattern' attributes are mutually exclusive.");
@@ -103,29 +106,29 @@ public class FileListFilterFactoryBean implements FactoryBean<EntryListFilter<Fi
}
}
else if (Boolean.FALSE.equals(this.preventDuplicates)) {
filter = new AcceptAllEntryListFilter<File>();
filter = new AcceptAllFileListFilter<File>();
}
else { // preventDuplicates is either TRUE or NULL
filter = new AcceptOnceEntryFileListFilter<File>();
filter = new AcceptOnceFileListFilter<File>();
}
// finally, it might be that they simply want a {@link CompositeEntryListFilter}
// finally, it might be that they simply want a {@link CompositeFileListFilter}
if ((this.filterReferences != null) && (this.filterReferences.size() > 0)) {
CompositeEntryListFilter<File> compositeFilter = new CompositeEntryListFilter<File>();
for (EntryListFilter<File> ff : filterReferences) {
CompositeFileListFilter<File> compositeFilter = new CompositeFileListFilter<File>();
for (FileListFilter<File> ff : filterReferences) {
compositeFilter.addFilter(ff);
}
filter = compositeFilter;
}
if (filter == null) {
filter = new CompositeEntryListFilter<File>();
filter = new CompositeFileListFilter<File>();
}
this.fileListFilter = filter;
}
private CompositeEntryListFilter<File> createCompositeWithAcceptOnceFilter(EntryListFilter<File> otherFilter) {
CompositeEntryListFilter<File> compositeFilter = new CompositeEntryListFilter<File>();
compositeFilter.addFilter(new AcceptOnceEntryFileListFilter<File>());
private CompositeFileListFilter<File> createCompositeWithAcceptOnceFilter(FileListFilter<File> otherFilter) {
CompositeFileListFilter<File> compositeFilter = new CompositeFileListFilter<File>();
compositeFilter.addFilter(new AcceptOnceFileListFilter<File>());
compositeFilter.addFilter(otherFilter);
return compositeFilter;
}

View File

@@ -16,19 +16,19 @@
package org.springframework.integration.file.config;
import java.io.File;
import java.util.Comparator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.integration.file.DirectoryScanner;
import org.springframework.integration.file.FileReadingMessageSource;
import org.springframework.integration.file.entries.CompositeEntryListFilter;
import org.springframework.integration.file.entries.EntryListFilter;
import org.springframework.integration.file.filters.CompositeFileListFilter;
import org.springframework.integration.file.filters.FileListFilter;
import org.springframework.integration.file.locking.AbstractFileLockerFilter;
import java.io.File;
import java.util.Comparator;
/**
* @author Mark Fisher
* @author Iwein Fuld
@@ -42,7 +42,7 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean<FileRead
private volatile File directory;
private volatile EntryListFilter<File> filter;
private volatile FileListFilter<File> filter;
private volatile AbstractFileLockerFilter locker;
@@ -71,7 +71,7 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean<FileRead
this.scanner = scanner;
}
public void setFilter(EntryListFilter<File> filter) {
public void setFilter(FileListFilter<File> filter) {
if (filter instanceof AbstractFileLockerFilter && (this.locker == null)) {
this.setLocker((AbstractFileLockerFilter) filter);
}
@@ -137,10 +137,10 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean<FileRead
this.source.setFilter(this.filter);
}
else {
CompositeEntryListFilter<File> fileCompositeEntryListFilter = new CompositeEntryListFilter<File>();
fileCompositeEntryListFilter.addFilter(this.filter);
fileCompositeEntryListFilter.addFilter(this.locker);
this.source.setFilter(fileCompositeEntryListFilter);
CompositeFileListFilter<File> compositeFileListFilter = new CompositeFileListFilter<File>();
compositeFileListFilter.addFilter(this.filter);
compositeFileListFilter.addFilter(this.locker);
this.source.setFilter(compositeFileListFilter);
this.source.setLocker(locker);
}
}

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.
@@ -16,7 +16,6 @@
package org.springframework.integration.file.filters;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -27,19 +26,16 @@ import java.util.List;
*
* @author Mark Fisher
* @author Iwein Fuld
*
* @deprecated Replaced by AbstractEntryListFilter in 2.0.0
*/
@Deprecated
public abstract class AbstractFileListFilter implements FileListFilter {
public abstract class AbstractFileListFilter<F> implements FileListFilter<F> {
/**
* {@inheritDoc}
*/
public final List<File> filterFiles(File[] files) {
List<File> accepted = new ArrayList<File>();
public final List<F> filterFiles(F[] files) {
List<F> accepted = new ArrayList<F>();
if (files != null) {
for (File file : files) {
for (F file : files) {
if (this.accept(file)) {
accepted.add(file);
}
@@ -51,6 +47,6 @@ public abstract class AbstractFileListFilter implements FileListFilter {
/**
* Subclasses must implement this method.
*/
protected abstract boolean accept(File file);
protected abstract boolean accept(F file);
}

View File

@@ -0,0 +1,35 @@
/*
* 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.filters;
/**
* Simple implementation of {@link FileListFilter} that always returns true.
* Suitable as a default.
*
* @author Iwein Fuld
* @author Josh Long
* @param <F>
*/
public class AcceptAllFileListFilter<F> extends AbstractFileListFilter<F> {
@Override
public boolean accept(F file) {
return true;
}
}

View File

@@ -13,14 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.file.filters;
import org.springframework.integration.file.entries.AcceptOnceEntryFileListFilter;
import org.springframework.util.Assert;
import java.io.File;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* {@link FileListFilter} that passes files only one time. This can
@@ -30,34 +27,46 @@ import java.util.List;
* This implementation is thread safe.
*
* @author Iwein Fuld
* @author Josh Long
* @since 1.0.0
*/
public class AcceptOnceFileListFilter extends AcceptOnceEntryFileListFilter<File> implements FileListFilter{
public class AcceptOnceFileListFilter<F> extends AbstractFileListFilter<F> {
/**
* Creates an AcceptOnceFileFilter that is based on a bounded queue. If the
* queue overflows, files that fall out will be passed through this filter
* again if passed to the {@link #filterFiles(File[])} method.
*
* @param maxCapacity the maximum number of Files to maintain in the 'seen'
* queue.
*/
public AcceptOnceFileListFilter(int maxCapacity) {
super(maxCapacity);
}
private final Queue<F> seen;
private final Object monitor = new Object();
/**
* Creates an AcceptOnceFileFilter based on an unbounded queue.
*/
public AcceptOnceFileListFilter() {
super();
}
/**
* Filter out all the files that this instance has seen before.
* Creates an AcceptOnceFileListFilter that is based on a bounded queue. If the queue overflows,
* files that fall out will be passed through this filter again if passed to the
* {@link #filterFiles(Object[])}
*
* @param maxCapacity the maximum number of Files to maintain in the 'seen' queue.
*/
public List<File> filterFiles(File[] files) {
Assert.notNull(files, "'files' must not be null.");
return this.filterEntries(files);
public AcceptOnceFileListFilter(int maxCapacity) {
this.seen = new LinkedBlockingQueue<F>(maxCapacity);
}
/**
* Creates an AcceptOnceFileListFilter based on an unbounded queue.
*/
public AcceptOnceFileListFilter() {
this.seen = new LinkedBlockingQueue<F>();
}
public boolean accept(F file) {
synchronized (this.monitor) {
if (this.seen.contains(file)) {
return false;
}
if (!this.seen.offer(file)) {
this.seen.poll();
this.seen.add(file);
}
return true;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 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,41 +13,82 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.file.filters;
import org.springframework.integration.file.entries.CompositeEntryListFilter;
import org.springframework.integration.file.entries.EntryListFilter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import java.io.File;
import java.io.FileFilter;
import java.util.*;
/**
* Composition that delegates to multiple {@link FileFilter}s. The composition is AND based, meaning that a file must
* pass through each filter's {@link #filterFiles(java.io.File[])} method in order to be accepted by the composite.
* Simple {@link FileListFilter} that predicates its matches against any of many
* configured {@link FileListFilter}.
*
* @author Iwein Fuld
* @author Mark Fisher
* @author Josh Long
* @param <F>
*/
public class CompositeFileListFilter extends CompositeEntryListFilter<File> implements FileListFilter{
public class CompositeFileListFilter<F> implements FileListFilter<F> {
public CompositeFileListFilter(EntryListFilter<File>... fileFilters) {
this(Arrays.asList(fileFilters));
}
private final Set<FileListFilter<F>> fileFilters;
public CompositeFileListFilter(Collection<? extends EntryListFilter<File>> fileFilters) {
super(fileFilters);
}
/**
* {@inheritDoc}
* <p/>
* This implementation delegates to a collection of filters and returns only files that pass all the filters.
*/
public List<File> filterFiles(File[] files) {
Assert.notNull(files, "'files' should not be null.");
return this.filterEntries(files);
}
public CompositeFileListFilter() {
this.fileFilters = new LinkedHashSet<FileListFilter<F>>();
}
public CompositeFileListFilter(Collection<? extends FileListFilter<F>> fileFilters) {
this.fileFilters = new LinkedHashSet<FileListFilter<F>>(fileFilters);
}
public CompositeFileListFilter<F> addFilter(FileListFilter<F> filter) {
return this.addFilters(Collections.singletonList(filter));
}
/**
* @param filters one or more new filters to add
* @return this CompositeFileFilter instance with the added filters
* @see #addFilters(Collection)
*/
public CompositeFileListFilter<F> addFilters(FileListFilter<F>... filters) {
return addFilters(Arrays.asList(filters));
}
/**
* Not thread safe. Only a single thread may add filters at a time.
* <p/>
* Add the new filters to this CompositeFileListFilter while maintaining the existing filters.
*
* @param filtersToAdd a list of filters to add
* @return this CompositeFileListFilter instance with the added filters
*/
public CompositeFileListFilter<F> addFilters(Collection<? extends FileListFilter<F>> filtersToAdd) {
for (FileListFilter<? extends F> elf : filtersToAdd) {
if (elf instanceof InitializingBean) {
try {
((InitializingBean) elf).afterPropertiesSet();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
this.fileFilters.addAll(filtersToAdd);
return this;
}
@SuppressWarnings("unchecked")
public List<F> filterFiles(F[] files) {
Assert.notNull(files, "'files' should not be null");
List<F> leftOver = Arrays.asList(files);
for (FileListFilter<F> fileFilter : this.fileFilters) {
F[] fileArray = (F[]) leftOver.toArray();
leftOver = fileFilter.filterFiles(fileArray);
}
return leftOver;
}
}

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.
@@ -16,25 +16,23 @@
package org.springframework.integration.file.filters;
import java.io.File;
import java.util.List;
/**
* Strategy interface for filtering a group of files.
* Strategy interface for filtering a group of files. This is a generic filter intended
* to work with either local files or references to remote files.
*
* @author Iwein Fuld
* @author Josh Long
*
* @since 1.0.0
*
* @see org.springframework.integration.file.entries.EntryListFilter
*
*/
public interface FileListFilter {
public interface FileListFilter<F> {
/**
* Filters out files and returns the files that are left in a list, or an
* empty list when a null is passed in.
*/
List<File> filterFiles(File[] files);
List<F> filterFiles(F[] files);
}

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.
@@ -16,40 +16,65 @@
package org.springframework.integration.file.filters;
import org.springframework.integration.file.entries.FileEntryNameExtractor;
import org.springframework.integration.file.entries.PatternMatchingEntryListFilter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.file.entries.EntryNameExtractor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.io.File;
import java.util.List;
import java.util.regex.Pattern;
/**
* An {@link org.springframework.integration.file.entries.EntryListFilter} implementation that matches a File against a {@link Pattern}.
* Filters a listing of files by qualifying their 'name' (as determined by {@link org.springframework.integration.file.entries.EntryNameExtractor})
* against a regular expression (an instance of {@link java.util.regex.Pattern})
*
* @author Iwein Fuld
* @author Mark Fisher
*
* @since 1.0.0
* @author Josh Long
* @param <F> the type of file entry
* @since 2.0
*/
public class PatternMatchingFileListFilter extends PatternMatchingEntryListFilter<File> implements FileListFilter{
public class PatternMatchingFileListFilter<F> extends AbstractFileListFilter<F> implements InitializingBean {
/**
* Create a file filter for the given pattern.
*/
public PatternMatchingFileListFilter(Pattern pattern) {
super(new FileEntryNameExtractor(), pattern);
private volatile EntryNameExtractor<F> entryNameExtractor;
private volatile Pattern pattern;
private volatile String patternExpression;
public PatternMatchingFileListFilter(EntryNameExtractor<F> entryNameExtractor, String pattern) {
this.entryNameExtractor = entryNameExtractor;
this.patternExpression = pattern;
}
public PatternMatchingFileListFilter(String pattern) {
super(new FileEntryNameExtractor(), pattern);
public PatternMatchingFileListFilter(EntryNameExtractor<F> entryNameExtractor, Pattern pattern) {
this.entryNameExtractor = entryNameExtractor;
this.pattern = pattern;
}
/**
* Filter out the files of which the name doesn't match the pattern of this filter
*/
public List<File> filterFiles(File[] files) {
Assert.notNull(files, "'files' must not be null.");
return this.filterEntries(files);
public void setEntryNameExtractor(EntryNameExtractor<F> entryNameExtractor) {
this.entryNameExtractor = entryNameExtractor;
}
public void setPattern(Pattern pattern) {
this.pattern = pattern;
}
public void setPatternExpression(String patternExpression) {
this.patternExpression = patternExpression;
}
public void afterPropertiesSet() throws Exception {
if (StringUtils.hasText(this.patternExpression) && (pattern == null)) {
this.pattern = Pattern.compile(this.patternExpression);
}
Assert.notNull(this.entryNameExtractor, "'entryNameExtractor' must not be null!");
Assert.notNull(this.pattern, "'pattern' must not be null!");
}
@Override
public boolean accept(F entry) {
return (entry != null) && this.pattern.matcher(this.entryNameExtractor.getName(entry)).matches();
}
}

View File

@@ -1,11 +1,24 @@
/*
* 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.filters;
import org.springframework.integration.file.entries.AbstractEntryListFilter;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.Assert;
import java.io.File;
import java.util.List;
import org.springframework.util.AntPathMatcher;
/**
* Filter that supports ant style path expressions, which are less powerful but more readable than regular expressions.
@@ -16,15 +29,18 @@ import java.util.List;
* @see org.springframework.integration.file.filters.PatternMatchingFileListFilter
* @since 2.0.0
*/
public class SimplePatternFileListFilter extends AbstractEntryListFilter<File> implements FileListFilter {
public class SimplePatternFileListFilter extends AbstractFileListFilter<File> {
private final AntPathMatcher matcher = new AntPathMatcher();
private final String path;
public SimplePatternFileListFilter(String path) {
this.path = path;
}
/**
* Accept the given file its name matches the pattern,
*/
@@ -33,8 +49,4 @@ public class SimplePatternFileListFilter extends AbstractEntryListFilter<File> i
return matcher.match(path, file.getName());
}
public List<File> filterFiles(File[] files) {
Assert.notNull("'files' must not be null.");
return this.filterEntries(files);
}
}

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.
@@ -16,11 +16,11 @@
package org.springframework.integration.file.locking;
import org.springframework.integration.file.FileLocker;
import org.springframework.integration.file.entries.AbstractEntryListFilter;
import java.io.File;
import org.springframework.integration.file.FileLocker;
import org.springframework.integration.file.filters.AbstractFileListFilter;
/**
* Convenience base class for implementing FileLockers that check a lock before accepting a file. This is needed
* when used in combination with a FileReadingMessageSource through a DirectoryScanner.
@@ -29,10 +29,11 @@ import java.io.File;
* @since 2.0
*
*/
public abstract class AbstractFileLockerFilter extends AbstractEntryListFilter<File> implements FileLocker {
public abstract class AbstractFileLockerFilter extends AbstractFileListFilter<File> implements FileLocker {
@Override
public boolean accept(File file) {
return this.isLockable(file);
}
}

View File

@@ -16,27 +16,27 @@
package org.springframework.integration.file.synchronization;
import java.util.concurrent.ScheduledFuture;
import org.springframework.core.io.Resource;
import org.springframework.integration.MessagingException;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.file.entries.AcceptAllEntryListFilter;
import org.springframework.integration.file.entries.EntryListFilter;
import org.springframework.integration.file.filters.AcceptAllFileListFilter;
import org.springframework.integration.file.filters.FileListFilter;
import org.springframework.scheduling.Trigger;
import org.springframework.util.Assert;
import java.util.concurrent.ScheduledFuture;
/**
* Base class charged with knowing how to connect to a remote file system,
* scan it for new files and then download the files.
* <p/>
* The implementation should run through any configured
* {@link org.springframework.integration.file.entries.EntryListFilter}s to
* ensure the entry is acceptable.
* {@link org.springframework.integration.file.filters.FileListFilter}s to
* ensure the file entry is acceptable.
*
* @author Josh Long
*/
public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends AbstractEndpoint {
public abstract class AbstractInboundRemoteFileSystemSychronizer<F> extends AbstractEndpoint {
/**
* Should we <emphasis>delete</emphasis> the <b>source</b> file? For an FTP
@@ -50,9 +50,9 @@ public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends Abst
protected volatile Resource localDirectory;
/**
* An {@link EntryListFilter} that runs against the <emphasis>remote</emphasis> file system view.
* An {@link FileListFilter} that runs against the <emphasis>remote</emphasis> file system view.
*/
protected volatile EntryListFilter<T> filter = new AcceptAllEntryListFilter<T>();
protected volatile FileListFilter<F> filter = new AcceptAllFileListFilter<F>();
/**
* The {@link ScheduledFuture} instance we get when we
@@ -63,10 +63,10 @@ public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends Abst
/**
* The {@link EntryAcknowledgmentStrategy} implementation.
*/
protected EntryAcknowledgmentStrategy<T> entryAcknowledgmentStrategy;
protected EntryAcknowledgmentStrategy<F> entryAcknowledgmentStrategy;
public void setEntryAcknowledgmentStrategy(EntryAcknowledgmentStrategy<T> entryAcknowledgmentStrategy) {
public void setEntryAcknowledgmentStrategy(EntryAcknowledgmentStrategy<F> entryAcknowledgmentStrategy) {
this.entryAcknowledgmentStrategy = entryAcknowledgmentStrategy;
}
@@ -78,7 +78,7 @@ public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends Abst
this.localDirectory = localDirectory;
}
public void setFilter(EntryListFilter<T> filter) {
public void setFilter(FileListFilter<F> filter) {
this.filter = filter;
}
@@ -90,16 +90,16 @@ public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends Abst
* be a 'live' stateful client (a connection?) that is inappropriate to cache as it has per-request state.
* @param t
* leverages strategy implementations to enable different
* behavior. It's a hook to the entry ({@link T}) after it's been
* behavior. It's a hook to the file entry ({@link F}) after it's been
* successfully downloaded. Conceptually, you might delete the
* remote one or rename it, etc.
* @throws Throwable
* escape hatch exception, let the adapter deal with it.
*/
protected void acknowledge(Object usefulContextOrClientData, T t) throws Throwable {
protected void acknowledge(Object usefulContextOrClientData, F file) throws Throwable {
Assert.notNull(this.entryAcknowledgmentStrategy != null,
"entryAcknowledgmentStrategy can't be null!");
this.entryAcknowledgmentStrategy.acknowledge(usefulContextOrClientData, t);
this.entryAcknowledgmentStrategy.acknowledge(usefulContextOrClientData, file);
}
/**
@@ -107,8 +107,8 @@ public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends Abst
*/
protected void doStart() {
if (this.entryAcknowledgmentStrategy == null) {
this.entryAcknowledgmentStrategy = new EntryAcknowledgmentStrategy<T>() {
public void acknowledge(Object o, T msg) {
this.entryAcknowledgmentStrategy = new EntryAcknowledgmentStrategy<F>() {
public void acknowledge(Object o, F msg) {
// no-op
}
};
@@ -167,9 +167,9 @@ public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends Abst
* into the pipeline and also some more advanced scenarios (i.e., 'move file
* to another folder on delete ', or 'rename on delete')
*
* @param <T> the entry type (file, sftp, ftp, ...)
* @param <F> the file entry type (file, sftp, ftp, ...)
*/
public static interface EntryAcknowledgmentStrategy<T> {
public static interface EntryAcknowledgmentStrategy<F> {
/**
* Semantics are simple. You get a pointer to the entry just processed
@@ -183,7 +183,7 @@ public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends Abst
* the data / file / entry you want to process -- specific to subclasses
* @throws Exception in case of an error while acknowledging
*/
void acknowledge(Object useful, T msg) throws Exception;
void acknowledge(Object useful, F msg) throws Exception;
}

View File

@@ -27,11 +27,11 @@ import org.springframework.integration.MessagingException;
import org.springframework.integration.core.MessageSource;
import org.springframework.integration.endpoint.MessageProducerSupport;
import org.springframework.integration.file.FileReadingMessageSource;
import org.springframework.integration.file.entries.AcceptOnceEntryFileListFilter;
import org.springframework.integration.file.entries.CompositeEntryListFilter;
import org.springframework.integration.file.entries.EntryListFilter;
import org.springframework.integration.file.entries.FileEntryNameExtractor;
import org.springframework.integration.file.entries.PatternMatchingEntryListFilter;
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.PatternMatchingFileListFilter;
/**
* Factors out the common logic between the FTP and SFTP adapters. Designed to
@@ -43,7 +43,7 @@ import org.springframework.integration.file.entries.PatternMatchingEntryListFilt
* <p/>
* The base class supports configuration of whether the remote file system and
* local file system's directories should be created on start (what 'creating a
* directory' means to the specific adapter is of course implementaton
* directory' means to the specific adapter is of course implementation
* specific).
* <p/>
* This class is to be used as a pair with an implementation of
@@ -53,7 +53,7 @@ import org.springframework.integration.file.entries.PatternMatchingEntryListFilt
*
* @author Josh Long
*/
public abstract class AbstractInboundRemoteFileSystemSynchronizingMessageSource<Y, T extends AbstractInboundRemoteFileSystemSychronizer<Y>>
public abstract class AbstractInboundRemoteFileSystemSynchronizingMessageSource<F, S extends AbstractInboundRemoteFileSystemSychronizer<F>>
extends MessageProducerSupport implements MessageSource<File> {
/**
@@ -70,7 +70,7 @@ public abstract class AbstractInboundRemoteFileSystemSynchronizingMessageSource<
* An implementation that will handle the chores of actually connecting to and synching up
* the remote file system with the local one, in an inbound direction.
*/
protected volatile T synchronizer;
protected volatile S synchronizer;
/**
* Directory to which things should be synched locally.
@@ -85,14 +85,14 @@ public abstract class AbstractInboundRemoteFileSystemSynchronizingMessageSource<
/**
* The predicate to use in scanning the remote File system for downloads.
*/
protected EntryListFilter<Y> remotePredicate;
protected FileListFilter<F> remotePredicate;
public void setAutoCreateDirectories(boolean autoCreateDirectories) {
this.autoCreateDirectories = autoCreateDirectories;
}
public void setSynchronizer(T synchronizer) {
public void setSynchronizer(S synchronizer) {
this.synchronizer = synchronizer;
}
@@ -100,7 +100,7 @@ public abstract class AbstractInboundRemoteFileSystemSynchronizingMessageSource<
this.localDirectory = localDirectory;
}
public void setRemotePredicate(EntryListFilter<Y> remotePredicate) {
public void setRemotePredicate(FileListFilter<F> remotePredicate) {
this.remotePredicate = remotePredicate;
}
@@ -154,12 +154,12 @@ public abstract class AbstractInboundRemoteFileSystemSynchronizingMessageSource<
}
@SuppressWarnings("unchecked")
private EntryListFilter<File> buildFilter() {
private FileListFilter<File> buildFilter() {
FileEntryNameExtractor fileEntryNameExtractor = new FileEntryNameExtractor();
Pattern completePattern = Pattern.compile("^.*(?<!" + INCOMPLETE_EXTENSION + ")$");
return new CompositeEntryListFilter<File>(Arrays.asList(
new AcceptOnceEntryFileListFilter<File>(),
new PatternMatchingEntryListFilter<File>(fileEntryNameExtractor, completePattern)));
return new CompositeFileListFilter<File>(Arrays.asList(
new AcceptOnceFileListFilter<File>(),
new PatternMatchingFileListFilter<File>(fileEntryNameExtractor, completePattern)));
}
}