INT-1591 FileListFilter is now parameterized. Existing implementations required refactoring to specify <File> for <F>.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user