cleaning up file adapter support, removing deprecated FileListFilter* hierarchy

This commit is contained in:
Josh Long
2010-08-21 02:21:14 +00:00
parent 48d7279dd8
commit c67ee979cd
13 changed files with 53 additions and 327 deletions

View File

@@ -7,6 +7,7 @@ import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.file.entries.*;
import java.io.File;
import java.util.Arrays;
import java.util.regex.Pattern;
@@ -76,7 +77,9 @@ public abstract class AbstractInboundRemoteFileSystemSynchronizingMessageSource<
private EntryListFilter<File> buildFilter() {
FileEntryNamer fileEntryNamer = new FileEntryNamer();
Pattern completePattern = Pattern.compile("^.*(?<!" + INCOMPLETE_EXTENSION + ")$");
return new CompositeEntryListFilter<File>(new AcceptOnceEntryFileListFilter<File>(), new PatternMatchingEntryListFilter<File>(fileEntryNamer, completePattern));
return new CompositeEntryListFilter<File>(
Arrays.asList(
new AcceptOnceEntryFileListFilter<File>(), new PatternMatchingEntryListFilter<File>(fileEntryNamer, completePattern)));
}
@Override

View File

@@ -77,7 +77,7 @@ public class FileListFilterFactoryBean implements FactoryBean<EntryListFilter<Fi
return;
}
EntryListFilter<File> flf=null;
EntryListFilter<File> flf ;
if ((this.filterReference != null) && (this.filenamePattern != null)) {
throw new IllegalArgumentException("The 'filter' reference and " + "'filename-pattern' attributes are mutually exclusive.");
@@ -99,12 +99,12 @@ public class FileListFilterFactoryBean implements FactoryBean<EntryListFilter<Fi
}
} else if (Boolean.FALSE.equals(this.preventDuplicates)) {
flf = new AcceptAllEntryListFilter<File>();
} else { // preventDuplicates is either TRUE or NULL
} else { // preventDuplicates is either TRUE or NULL
flf = new AcceptOnceEntryFileListFilter<File>();
}
// finally, it might be that they simply want a {@link CompositeEntryListFilter}
if ((this.filterReferences != null) && (this.filterReferences.size() > 0) ) {
if ((this.filterReferences != null) && (this.filterReferences.size() > 0)) {
CompositeEntryListFilter<File> flfc = new CompositeEntryListFilter<File>();
for (EntryListFilter<File> ff : filterReferences)
@@ -112,14 +112,17 @@ public class FileListFilterFactoryBean implements FactoryBean<EntryListFilter<Fi
flf = flfc;
}
if( flf== null)flf =new CompositeEntryListFilter<File>();
if (flf == null) {
flf = new CompositeEntryListFilter<File>();
}
this.fileListFilter = flf;
}
private CompositeEntryListFilter<File> createCompositeWithAcceptOnceFilter(EntryListFilter<File> otherFilter) {
CompositeEntryListFilter<File> compositeFilter = new CompositeEntryListFilter<File>();
compositeFilter.addFilter(new AcceptOnceEntryFileListFilter<File>() );
compositeFilter.addFilter(new AcceptOnceEntryFileListFilter<File>());
compositeFilter.addFilter(otherFilter);
return compositeFilter;

View File

@@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.file.config;
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;
@@ -26,64 +27,65 @@ import org.springframework.integration.file.entries.EntryListFilter;
import org.springframework.integration.file.locking.AbstractFileLockerFilter;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
/**
* @author Mark Fisher
* @author Iwein Fuld
* @since 1.0.3
*/
public class FileReadingMessageSourceFactoryBean implements FactoryBean<FileReadingMessageSource> {
private static Log logger = LogFactory.getLog(FileReadingMessageSourceFactoryBean.class);
private volatile FileReadingMessageSource source;
private volatile File directory;
private volatile EntryListFilter<File> filter;
private volatile AbstractFileLockerFilter locker;
private volatile Comparator<File> comparator;
private volatile DirectoryScanner scanner;
private volatile Boolean scanEachPoll;
private volatile Boolean autoCreateDirectory;
private volatile Integer queueSize;
private final Object initializationMonitor = new Object();
@SuppressWarnings("unused")
public void setDirectory(File directory) {
this.directory = directory;
}
@SuppressWarnings("unused")
public void setComparator(Comparator<File> comparator) {
this.comparator = comparator;
}
@SuppressWarnings("unused")
public void setScanner(DirectoryScanner scanner) {
this.scanner = scanner;
}
@SuppressWarnings("unused")
public void setFilter(EntryListFilter<File> filter) {
if (filter instanceof AbstractFileLockerFilter && this.locker == null) {
if (filter instanceof AbstractFileLockerFilter && (this.locker == null)) {
this.setLocker((AbstractFileLockerFilter) filter);
}
this.filter = filter;
}
@SuppressWarnings("unused")
public void setScanEachPoll(Boolean scanEachPoll) {
this.scanEachPoll = scanEachPoll;
}
@SuppressWarnings("unused")
public void setAutoCreateDirectory(Boolean autoCreateDirectory) {
this.autoCreateDirectory = autoCreateDirectory;
}
@SuppressWarnings("unused")
public void setQueueSize(Integer queueSize) {
this.queueSize = queueSize;
}
@@ -96,6 +98,7 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean<FileRead
if (this.source == null) {
initSource();
}
return this.source;
}
@@ -112,37 +115,50 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean<FileRead
if (this.source != null) {
return;
}
boolean comparatorSet = this.comparator != null;
boolean queueSizeSet = this.queueSize != null;
if (comparatorSet) {
if(queueSizeSet){
if (queueSizeSet) {
logger.warn("'comparator' and 'queueSize' are mutually exclusive. Ignoring 'queueSize'");
}
this.source = new FileReadingMessageSource(this.comparator);
} else if ( queueSizeSet) {
} else if (queueSizeSet) {
this.source = new FileReadingMessageSource(queueSize);
}
else {
} else {
this.source = new FileReadingMessageSource();
}
this.source.setDirectory(this.directory);
if (this.scanner != null) {
this.source.setScanner(this.scanner);
}
if (this.filter != null) {
if (this.locker == null) {
this.source.setFilter(this.filter);
} else {
this.source.setFilter(new CompositeEntryListFilter<File>(this.filter, this.locker));
CompositeEntryListFilter<File> fileCompositeEntryListFilter = new CompositeEntryListFilter<File>();
for (EntryListFilter<File> filter : Arrays.asList(this.filter, this.locker))
fileCompositeEntryListFilter.addFilter(filter);
this.source.setFilter(fileCompositeEntryListFilter);
this.source.setLocker(locker);
}
}
if (this.scanEachPoll != null) {
this.source.setScanEachPoll(this.scanEachPoll);
}
if (this.autoCreateDirectory != null) {
this.source.setAutoCreateDirectory(this.autoCreateDirectory);
}
this.source.afterPropertiesSet();
}
}

View File

@@ -16,7 +16,6 @@
package org.springframework.integration.file.entries;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import java.util.*;
@@ -25,8 +24,8 @@ import java.util.*;
public class CompositeEntryListFilter<T> implements EntryListFilter<T> {
private final Set<EntryListFilter<T>> fileFilters;
public CompositeEntryListFilter(EntryListFilter<T>... fileFilters) {
this.fileFilters = new LinkedHashSet<EntryListFilter<T>>(Arrays.asList(fileFilters));
public CompositeEntryListFilter() {
this.fileFilters = new LinkedHashSet<EntryListFilter<T>>();
}
public CompositeEntryListFilter(Collection<?extends EntryListFilter<T>> fileFilters) {

View File

@@ -16,7 +16,7 @@
package org.springframework.integration.file.entries;
/**
* Responsible for coercing a String identification out of the {@link T} entry.
* Responsible for coercing a String identification out of the T entry.
* @param <T> the type of entry (there's an implementation for FTP, SFTP, and plain-old java.io.Files)
*
* @author Josh Long

View File

@@ -1,54 +0,0 @@
/*
* 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.filters;
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
* @author Iwein Fuld
*/
@Deprecated
public abstract class AbstractFileListFilter implements FileListFilter {
/**
* {@inheritDoc}
*/
public final List<File> filterFiles(File[] files) {
List<File> accepted = new ArrayList<File>();
if (files != null) {
for (File file : files) {
if (this.accept(file)) {
accepted.add(file);
}
}
}
return accepted;
}
/**
* Subclasses must implement this method.
*/
protected abstract boolean accept(File file);
}

View File

@@ -1,71 +0,0 @@
/*
* 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 java.io.File;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* {@link FileListFilter} that passes files only one time. This can
* conveniently be used to prevent duplication of files, as is done in
* {@link org.springframework.integration.file.FileReadingMessageSource}.
* <p/>
* This implementation is thread safe.
*
* @author Iwein Fuld
* @since 1.0.0
*/
@Deprecated
public class AcceptOnceFileListFilter extends AbstractFileListFilter {
private final Queue<File> seen;
private final Object monitor = new Object();
/**
* 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) {
this.seen = new LinkedBlockingQueue<File>(maxCapacity);
}
/**
* Creates an AcceptOnceFileFilter based on an unbounded queue.
*/
public AcceptOnceFileListFilter() {
this.seen = new LinkedBlockingQueue<File>();
}
protected boolean accept(File pathname) {
synchronized (this.monitor) {
if (seen.contains(pathname)) {
return false;
}
if (!seen.offer(pathname)) {
seen.poll();
seen.add(pathname);
}
return true;
}
}
}

View File

@@ -1,82 +0,0 @@
/*
* Copyright 2002-2009 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.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.
*
* @author Iwein Fuld
* @author Mark Fisher
*/
@Deprecated
public class CompositeFileListFilter implements FileListFilter {
private final Set<FileListFilter> fileFilters;
public CompositeFileListFilter(FileListFilter... fileFilters) {
this.fileFilters = new LinkedHashSet<FileListFilter>(Arrays.asList(fileFilters));
}
public CompositeFileListFilter(Collection<FileListFilter> fileFilters) {
this.fileFilters = new LinkedHashSet<FileListFilter>(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");
List<File> leftOver = Arrays.asList(files);
for (FileListFilter fileFilter : this.fileFilters) {
leftOver = fileFilter.filterFiles(leftOver.toArray(new File[]{}));
}
return leftOver;
}
/**
* @param filters one or more new filters to add
* @return this CompositeFileFilter instance with the added filters
*/
/* public CompositeFileListFilter addFilter(FileListFilter... 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 CompositeFileFilter while maintaining the existing filters.
*
* @param filtersToAdd a list of filters to add
* @return this CompositeFileFilter instance with the added filters
*/
/* public CompositeFileListFilter addFilters(Collection<FileListFilter> filtersToAdd) {
this.fileFilters.addAll(filtersToAdd);
return this;
}*/
}

View File

@@ -1,36 +0,0 @@
/*
* 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.filters;
import java.io.File;
import java.util.List;
/**
* Strategy interface for filtering a group of files.
*
* @author Iwein Fuld
*/
@Deprecated
public interface FileListFilter {
/**
* 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);
}

View File

@@ -1,49 +0,0 @@
/*
* 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.filters;
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
*/
@Deprecated
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();
}
}

View File

@@ -20,11 +20,7 @@ import java.util.concurrent.LinkedBlockingQueue;
* or Java 7's NIO.2 WaterService or other third party implementations.
* <p/>
* In the meantime, this provides us with a base class for building event driven file adapters quickly. The two cases I see are:
* <p/>
* <ol>
* <li></li>
* <li></li>
* </ol>
*
*
* @author Josh Long
*/

View File

@@ -44,7 +44,8 @@ public class CompositeFileListFilterTests {
@Test
public void forwardedToFilters() throws Exception {
CompositeEntryListFilter<File> compositeFileFilter = new CompositeEntryListFilter<File>(fileFilterMock1, fileFilterMock2);
CompositeEntryListFilter<File> compositeFileFilter = new CompositeEntryListFilter<File>();
compositeFileFilter .addFilter(fileFilterMock1);compositeFileFilter.addFilter( fileFilterMock2);
List<File> returnedFiles = Arrays.asList( fileMock);
when(fileFilterMock1.filterEntries(isA(File[].class))).thenReturn(returnedFiles);
when(fileFilterMock2.filterEntries(isA(File[].class))).thenReturn(returnedFiles);

View File

@@ -72,7 +72,7 @@ public class PatternMatchingFileListFilterTests {
}
@Test
@Test @SuppressWarnings("unchecked")
public void patternEditorInContext() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"patternMatchingFileListFilterTests.xml", this.getClass());