INT-947: prework moving filtering, scanning, locking into scanner. This opens the door for simplification, particularly around locking.

This commit is contained in:
Iwein Fuld
2010-02-12 15:07:33 +00:00
parent 8ae281bc7b
commit fec08008ea
12 changed files with 341 additions and 165 deletions

View File

@@ -0,0 +1,78 @@
/*
* 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;
import org.springframework.integration.core.MessagingException;
import org.springframework.integration.file.locking.FileLocker;
import java.io.File;
import java.util.List;
/**
* Default directory scanner and base class for other directory scanners. It takes care of the default interrelations
* between filtering, scanning and locking.
*
* @author Iwein Fuld
* @since 2.0
*/
public class DefaultDirectoryScanner implements DirectoryScanner {
private FileListFilter filter = new AcceptOnceFileListFilter();
private FileLocker locker;
public final List<File> listFiles(File directory) throws IllegalArgumentException {
File[] files = listEligibleFiles(directory);
if (files == null) {
throw new MessagingException("The path [" + directory
+ "] does not denote a properly accessible directory.");
}
return this.filter.filterFiles(files);
}
/**
* Subclasses may refine the listing strategy by overriding this method. The files returned here are passed onto the
* filter.
*
* @param directory root directory to use for listing
* @return the files this scanner should consider
*/
protected File[] listEligibleFiles(File directory) {
return directory.listFiles();
}
/**
* {@inheritDoc}
*/
public final void setFilter(FileListFilter filter) {
this.filter = filter;
}
/**
* {@inheritDoc}
* <p/>
* This class takes the minimal implementation and merely delegates to the locker if set.
*/
public final boolean tryClaim(File file) {
return locker != null ? locker.lock(file) : true;
}
/**
* {@inheritDoc}
*/
public final void setLocker(FileLocker locker) {
this.locker = locker;
}
}

View File

@@ -16,24 +16,57 @@
package org.springframework.integration.file;
import org.springframework.integration.file.locking.FileLocker;
import java.io.File;
import java.util.List;
/**
* Strategy for scanning directories. Implementations may select all children and grandchildren of the scanned directory
* in any order. This interface is intended to enable the selection and ordering of files in a directory like
* RecursiveDirectoryScanner. If the only requirement is to ignore certain files a FileListFilter implementation should
* suffice.
* in any order. This interface is intended to enable the customization of selection, locking and ordering of files in a
* directory like RecursiveDirectoryScanner. If the only requirement is to ignore certain files a FileListFilter
* implementation should suffice.
*
* @author Iwein Fuld
*
*
* @author Iwein Fuld
*/
public interface DirectoryScanner {
/**
* Scans the directory according to the strategy particular to this implementation and returns the selected files
* as a File array.
* Scans the directory according to the strategy particular to this implementation and returns the selected files as
* a File array. This method may never return files that are rejected by the filter.
*
* @param directory the directory to scan for files
* @return a list of files representing the content of the directory
*/
File[] listFiles(File directory) throws IllegalArgumentException;
List<File> listFiles(File directory) throws IllegalArgumentException;
/**
* Sets a custom filter to be used by this scanner. The filter will get a chance to reject files before the scanner
* presents them through its listFiles method. A scanner may use additional filtering that is out of the control of
* the provided filter.
*
* @param filter the custom filter to be used
*/
void setFilter(FileListFilter filter);
/**
* Claim the file to process. It is up to the implementation to decide what additional safe guards are required to
* attain a claim to the file. But if a locker is set implementations MUST invoke its <code>lock</code> method and
* MUST return <code>false<code> if the locker did not grant the lock.
*
* @param file file to be claimed
* @return true if the claim was granted false otherwise
*/
boolean tryClaim(File file);
/**
* Sets a custom locker to be used by this scanner. The locker will get a chance to lock files and reject claims on
* files that are already locked.
*
* @param locker the custom locker to be used
*/
void setLocker(FileLocker locker);
}

View File

@@ -67,7 +67,7 @@ public class FileReadingMessageSource implements MessageSource<File>,
private volatile File directory;
private volatile DirectoryScanner scanner = new ToplevelDirectoryScanner();
private volatile DirectoryScanner scanner = new DefaultDirectoryScanner();
private volatile boolean autoCreateDirectory = true;
@@ -78,10 +78,6 @@ public class FileReadingMessageSource implements MessageSource<File>,
*/
private final Queue<File> toBeReceived;
private volatile FileListFilter filter = new AcceptOnceFileListFilter();
private volatile FileLocker locker = new NoopFileLocker();
private boolean scanEachPoll = false;
/**
@@ -141,10 +137,7 @@ public class FileReadingMessageSource implements MessageSource<File>,
*/
public void setFilter(FileListFilter filter) {
Assert.notNull(filter, "'filter' must not be null");
this.filter = filter;
if (filter instanceof FileLocker && locker instanceof NoopFileLocker) {
this.locker = (FileLocker) filter;
}
this.scanner.setFilter(filter);
}
/**
@@ -158,7 +151,7 @@ public class FileReadingMessageSource implements MessageSource<File>,
*/
public void setLocker(FileLocker locker) {
Assert.notNull(locker, "'fileLocker' must not be null.");
this.locker = locker;
this.scanner.setLocker(locker);
}
/**
@@ -199,7 +192,7 @@ public class FileReadingMessageSource implements MessageSource<File>,
File file = toBeReceived.poll();
// file == null means the queue was empty
// we can't rely on isEmpty for concurrency reasons
while (file != null && !locker.lock(file)) {
while (file != null && !scanner.tryClaim(file)) {
file = toBeReceived.poll();
}
if (file != null) {
@@ -212,12 +205,7 @@ public class FileReadingMessageSource implements MessageSource<File>,
}
private void scanInputDirectory() {
File[] fileArray = scanner.listFiles(directory);
if (fileArray == null) {
throw new MessagingException("The path [" + this.directory
+ "] does not denote a properly accessible directory.");
}
List<File> filteredFiles = this.filter.filterFiles(fileArray);
List<File> filteredFiles = scanner.listFiles(directory);
Set<File> freshFiles = new HashSet<File>(filteredFiles);
if (!freshFiles.isEmpty()) {
toBeReceived.addAll(freshFiles);
@@ -261,10 +249,4 @@ public class FileReadingMessageSource implements MessageSource<File>,
// noop
}
}
private static class ToplevelDirectoryScanner implements DirectoryScanner {
public File[] listFiles(File directory) throws IllegalArgumentException {
return directory.listFiles();
}
}
}

View File

@@ -7,18 +7,18 @@ import java.util.List;
/**
* DirectoryScanner that lists all files inside a directory and subdirectories, without limit. This scanner should not
* be used with directories that contain a vast number of files, as all the file names will be read into memory and the
* scanning will be done recursively.
*
* be used with directories that contain a vast number of files or on deep trees, as all the file names will be read
* into memory and the scanning will be done recursively.
*
* @author Iwein Fuld
*/
public class RecursiveLeafOnlyDirectoryScanner implements DirectoryScanner {
public File[] listFiles(File directory) throws IllegalArgumentException {
public class RecursiveLeafOnlyDirectoryScanner extends DefaultDirectoryScanner {
protected File[] listEligibleFiles(File directory) throws IllegalArgumentException {
File[] rootFiles = directory.listFiles();
List<File> files = new ArrayList<File>(rootFiles.length);
for (File rootFile : rootFiles) {
if (rootFile.isDirectory()){
files.addAll(Arrays.asList(listFiles(rootFile)));
if (rootFile.isDirectory()) {
files.addAll(Arrays.asList(listEligibleFiles(rootFile)));
} else {
files.add(rootFile);
}

View File

@@ -64,6 +64,9 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean {
}
public void setFilter(FileListFilter filter) {
if (filter instanceof AbstractLockingFilter && this.locker == null) {
this.setLocker((AbstractLockingFilter) filter);
}
this.filter = filter;
}
@@ -102,6 +105,9 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean {
this.source = (this.comparator != null) ?
new FileReadingMessageSource(this.comparator) : 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);
@@ -116,9 +122,6 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean {
if (this.autoCreateDirectory != null) {
this.source.setAutoCreateDirectory(this.autoCreateDirectory);
}
if (this.scanner != null) {
this.source.setScanner(this.scanner);
}
this.source.afterPropertiesSet();
}
}

View File

@@ -21,8 +21,8 @@ import org.springframework.integration.file.AbstractFileListFilter;
import java.io.File;
/**
* Convenience base class for implementing FileLockers that acquires a lock upon accepting a file. This is required
* when used in combination with a FileReadingMessageSource.
* Convenience base class for implementing FileLockers that acquire a lock upon accepting a file. This is needed
* when used in combination with a FileReadingMessageSource through a DirectoryScanner.
*
* @author Iwein Fuld
* @since 2.0

View File

@@ -23,6 +23,9 @@ import java.io.File;
* single time. Implementations are free to implement any relation between
* locking and unlocking. This means that there are no safety guarantees in the
* contract, defining these guarantees is up to the implementation.
*
* If a filter that respects locks is required extend
* {@link org.springframework.integration.file.locking.AbstractLockingFilter} instead.
*
* @author Iwein Fuld
* @since 2.0
@@ -32,12 +35,16 @@ public interface FileLocker {
/**
* Tries to lock the given file and returns <code>true</code> if it was
* successful, <code>false</code> otherwise.
*/
*
* @param fileToLock the file that should be locked according to this locker
*/
boolean lock(File fileToLock);
/**
* Unlocks the given file.
*/
*
* @param fileToUnlock the file that should be unlocked according to this locker
*/
void unlock(File fileToUnlock);
}

View File

@@ -0,0 +1,66 @@
/*
* 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;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import java.util.List;
import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.*;
import static org.hamcrest.CoreMatchers.*;
/**
* @author Iwein Fuld
*/
public class RecursiveLeafOnlyDirectoryScannerTest {
private File folderThatShouldBeIgnored;
private File subFolderThatShouldBeIgnored;
private File topLevelFile;
private File subLevelFile;
private File subSubLevelFile;
@Rule
public TemporaryFolder recursivePath = new TemporaryFolder() {
@Override
public void create() throws IOException {
super.create();
folderThatShouldBeIgnored = this.newFolder("shouldBeIgnored");
subFolderThatShouldBeIgnored = new File(folderThatShouldBeIgnored, "shouldBeIgnored");
subFolderThatShouldBeIgnored.mkdir();
topLevelFile = this.newFile("file1");
subLevelFile = new File(folderThatShouldBeIgnored, "file2");
subLevelFile.createNewFile();
subSubLevelFile = new File(subFolderThatShouldBeIgnored, "file2");
subSubLevelFile.createNewFile();
}
};
@Test
public void shouldReturnAllFiles() {
List<File> files = new RecursiveLeafOnlyDirectoryScanner().listFiles(recursivePath.getRoot());
assertThat(files.size(), is(3));
assertThat(files, hasItem(topLevelFile));
assertThat(files, hasItem(subLevelFile));
assertThat(files, hasItem(subSubLevelFile));
}
}

View File

@@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.file.CompositeFileListFilter;
import org.springframework.integration.file.DefaultDirectoryScanner;
import org.springframework.integration.file.FileReadingMessageSource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -72,8 +73,11 @@ public class FileInboundChannelAdapterParserTests {
@Test
public void filter() throws Exception {
assertTrue("'filter' should be set", accessor.getPropertyValue("filter") instanceof CompositeFileListFilter);
DefaultDirectoryScanner scanner = (DefaultDirectoryScanner) accessor.getPropertyValue("scanner");
DirectFieldAccessor scannerAccessor = new DirectFieldAccessor(scanner);
assertTrue("'filter' should be set", scannerAccessor.getPropertyValue("filter") instanceof CompositeFileListFilter);
}
@Test
public void comparator() throws Exception {

View File

@@ -36,6 +36,7 @@ import static org.junit.Assert.*;
/**
* @author Mark Fisher
* @author Iwein Fuld
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@@ -77,22 +78,27 @@ public class FileInboundChannelAdapterWithPatternParserTests {
@Test
public void compositeFilterType() {
assertTrue(accessor.getPropertyValue("filter") instanceof CompositeFileListFilter);
DirectFieldAccessor scannerAccessor = new DirectFieldAccessor(accessor.getPropertyValue("scanner"));
assertTrue(scannerAccessor.getPropertyValue("filter") instanceof CompositeFileListFilter);
}
@Test
@SuppressWarnings("unchecked")
public void compositeFilterSetSize() {
DirectFieldAccessor scannerAccessor = new DirectFieldAccessor(accessor.getPropertyValue("scanner"));
Set<FileListFilter> filters = (Set<FileListFilter>) new DirectFieldAccessor(
accessor.getPropertyValue("filter")).getPropertyValue("fileFilters");
scannerAccessor.getPropertyValue("filter")).getPropertyValue("fileFilters");
assertEquals(2, filters.size());
}
@Test
@SuppressWarnings("unchecked")
public void acceptOnceFilter() {
DirectFieldAccessor scannerAccessor = new DirectFieldAccessor(accessor.getPropertyValue("scanner"));
Set<FileListFilter> filters = (Set<FileListFilter>) new DirectFieldAccessor(
accessor.getPropertyValue("filter")).getPropertyValue("fileFilters");
scannerAccessor.getPropertyValue("filter")).getPropertyValue("fileFilters");
boolean hasAcceptOnceFilter = false;
for (FileListFilter filter : filters) {
if (filter instanceof AcceptOnceFileListFilter) {
@@ -105,8 +111,10 @@ public class FileInboundChannelAdapterWithPatternParserTests {
@Test
@SuppressWarnings("unchecked")
public void patternFilter() {
DirectFieldAccessor scannerAccessor = new DirectFieldAccessor(accessor.getPropertyValue("scanner"));
Set<FileListFilter> filters = (Set<FileListFilter>) new DirectFieldAccessor(
accessor.getPropertyValue("filter")).getPropertyValue("fileFilters");
scannerAccessor.getPropertyValue("filter")).getPropertyValue("fileFilters");
Pattern pattern = null;
for (FileListFilter filter : filters) {
if (filter instanceof PatternMatchingFileListFilter) {

View File

@@ -16,31 +16,22 @@
package org.springframework.integration.file.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.file.*;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.io.File;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.file.AcceptOnceFileListFilter;
import org.springframework.integration.file.CompositeFileListFilter;
import org.springframework.integration.file.FileListFilter;
import org.springframework.integration.file.PatternMatchingFileListFilter;
import org.springframework.integration.file.TestFileListFilter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;
/**
* @author Mark Fisher
@@ -49,107 +40,109 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
public class FileInboundChannelAdapterWithPreventDuplicatesFlagTests {
@Autowired
private ApplicationContext context;
@Autowired
private ApplicationContext context;
@Autowired
@Qualifier("testFilter")
private TestFileListFilter testFilter;
@Autowired
@Qualifier("testFilter")
private TestFileListFilter testFilter;
@Test
public void filterAndNull() {
FileListFilter filter = this.extractFilter("filterAndNull");
assertFalse(filter instanceof CompositeFileListFilter);
assertSame(testFilter, filter);
}
@Test
public void filterAndNull() {
FileListFilter filter = this.extractFilter("filterAndNull");
assertFalse(filter instanceof CompositeFileListFilter);
assertSame(testFilter, filter);
}
@Test
@SuppressWarnings("unchecked")
public void filterAndTrue() {
FileListFilter filter = this.extractFilter("filterAndTrue");
assertTrue(filter instanceof CompositeFileListFilter);
Collection filters = (Collection) new DirectFieldAccessor(filter).getPropertyValue("fileFilters");
assertTrue(filters.iterator().next() instanceof AcceptOnceFileListFilter);
assertTrue(filters.contains(testFilter));
}
@Test
@SuppressWarnings("unchecked")
public void filterAndTrue() {
FileListFilter filter = this.extractFilter("filterAndTrue");
assertTrue(filter instanceof CompositeFileListFilter);
Collection filters = (Collection) new DirectFieldAccessor(filter).getPropertyValue("fileFilters");
assertTrue(filters.iterator().next() instanceof AcceptOnceFileListFilter);
assertTrue(filters.contains(testFilter));
}
@Test
public void filterAndFalse() throws Exception {
FileListFilter filter = this.extractFilter("filterAndFalse");
assertFalse(filter instanceof CompositeFileListFilter);
assertSame(testFilter, filter);
}
@Test
public void filterAndFalse() throws Exception {
FileListFilter filter = this.extractFilter("filterAndFalse");
assertFalse(filter instanceof CompositeFileListFilter);
assertSame(testFilter, filter);
}
@Test
@SuppressWarnings("unchecked")
public void patternAndNull() throws Exception {
FileListFilter filter = this.extractFilter("patternAndNull");
assertTrue(filter instanceof CompositeFileListFilter);
Collection filters = (Collection) new DirectFieldAccessor(filter).getPropertyValue("fileFilters");
Iterator<FileListFilter> iterator = filters.iterator();
assertTrue(iterator.next() instanceof AcceptOnceFileListFilter);
assertTrue(iterator.next() instanceof PatternMatchingFileListFilter);
}
@Test
@SuppressWarnings("unchecked")
public void patternAndNull() throws Exception {
FileListFilter filter = this.extractFilter("patternAndNull");
assertTrue(filter instanceof CompositeFileListFilter);
Collection filters = (Collection) new DirectFieldAccessor(filter).getPropertyValue("fileFilters");
Iterator<FileListFilter> iterator = filters.iterator();
assertTrue(iterator.next() instanceof AcceptOnceFileListFilter);
assertTrue(iterator.next() instanceof PatternMatchingFileListFilter);
}
@Test
@SuppressWarnings("unchecked")
public void patternAndTrue() throws Exception {
FileListFilter filter = this.extractFilter("patternAndTrue");
assertTrue(filter instanceof CompositeFileListFilter);
Collection filters = (Collection) new DirectFieldAccessor(filter).getPropertyValue("fileFilters");
Iterator<FileListFilter> iterator = filters.iterator();
assertTrue(iterator.next() instanceof AcceptOnceFileListFilter);
assertTrue(iterator.next() instanceof PatternMatchingFileListFilter);
}
@Test
@SuppressWarnings("unchecked")
public void patternAndTrue() throws Exception {
FileListFilter filter = this.extractFilter("patternAndTrue");
assertTrue(filter instanceof CompositeFileListFilter);
Collection filters = (Collection) new DirectFieldAccessor(filter).getPropertyValue("fileFilters");
Iterator<FileListFilter> iterator = filters.iterator();
assertTrue(iterator.next() instanceof AcceptOnceFileListFilter);
assertTrue(iterator.next() instanceof PatternMatchingFileListFilter);
}
@Test
public void patternAndFalse() throws Exception {
FileListFilter filter = this.extractFilter("patternAndFalse");
assertFalse(filter instanceof CompositeFileListFilter);
assertTrue(filter instanceof PatternMatchingFileListFilter);
}
@Test
public void patternAndFalse() throws Exception {
FileListFilter filter = this.extractFilter("patternAndFalse");
assertFalse(filter instanceof CompositeFileListFilter);
assertTrue(filter instanceof PatternMatchingFileListFilter);
}
@Test
public void defaultAndNull() throws Exception {
FileListFilter filter = this.extractFilter("defaultAndNull");
assertNotNull(filter);
assertFalse(filter instanceof CompositeFileListFilter);
assertTrue(filter instanceof AcceptOnceFileListFilter);
File testFile = new File("test");
File[] files = new File[] { testFile, testFile, testFile };
List<File> result = filter.filterFiles(files);
assertEquals(1, result.size());
}
@Test
public void defaultAndNull() throws Exception {
FileListFilter filter = this.extractFilter("defaultAndNull");
assertNotNull(filter);
assertFalse(filter instanceof CompositeFileListFilter);
assertTrue(filter instanceof AcceptOnceFileListFilter);
File testFile = new File("test");
File[] files = new File[]{testFile, testFile, testFile};
List<File> result = filter.filterFiles(files);
assertEquals(1, result.size());
}
@Test
public void defaultAndTrue() throws Exception {
FileListFilter filter = this.extractFilter("defaultAndTrue");
assertFalse(filter instanceof CompositeFileListFilter);
assertTrue(filter instanceof AcceptOnceFileListFilter);
File testFile = new File("test");
File[] files = new File[] { testFile, testFile, testFile };
List<File> result = filter.filterFiles(files);
assertEquals(1, result.size());
}
@Test
public void defaultAndTrue() throws Exception {
FileListFilter filter = this.extractFilter("defaultAndTrue");
assertFalse(filter instanceof CompositeFileListFilter);
assertTrue(filter instanceof AcceptOnceFileListFilter);
File testFile = new File("test");
File[] files = new File[]{testFile, testFile, testFile};
List<File> result = filter.filterFiles(files);
assertEquals(1, result.size());
}
@Test
public void defaultAndFalse() throws Exception {
FileListFilter filter = this.extractFilter("defaultAndFalse");
assertNotNull(filter);
assertFalse(filter instanceof CompositeFileListFilter);
assertFalse(filter instanceof AcceptOnceFileListFilter);
File testFile = new File("test");
File[] files = new File[] { testFile, testFile, testFile };
List<File> result = filter.filterFiles(files);
assertEquals(3, result.size());
}
@Test
public void defaultAndFalse() throws Exception {
FileListFilter filter = this.extractFilter("defaultAndFalse");
assertNotNull(filter);
assertFalse(filter instanceof CompositeFileListFilter);
assertFalse(filter instanceof AcceptOnceFileListFilter);
File testFile = new File("test");
File[] files = new File[]{testFile, testFile, testFile};
List<File> result = filter.filterFiles(files);
assertEquals(3, result.size());
}
private FileListFilter extractFilter(String beanName) {
return (FileListFilter) new DirectFieldAccessor(
new DirectFieldAccessor(context.getBean(beanName)).getPropertyValue("source"))
.getPropertyValue("filter");
}
private FileListFilter extractFilter(String beanName) {
return (FileListFilter) new DirectFieldAccessor(
new DirectFieldAccessor(
new DirectFieldAccessor(context.getBean(beanName))
.getPropertyValue("source"))
.getPropertyValue("scanner"))
.getPropertyValue("filter");
}
}

View File

@@ -63,16 +63,18 @@ public class FileLockingNamespaceTests {
@Test
public void shouldSetCustomLockerProperly() {
DirectFieldAccessor accessor = new DirectFieldAccessor(customLockingSource);
assertThat(accessor.getPropertyValue("locker"), is(StubLocker.class));
assertThat(accessor.getPropertyValue("filter"), is(CompositeFileListFilter.class));
assertThat(extractFromScanner("locker", customLockingSource), is(StubLocker.class));
assertThat(extractFromScanner("filter", customLockingSource), is(CompositeFileListFilter.class));
}
private Object extractFromScanner(String propertyName, FileReadingMessageSource source) {
return new DirectFieldAccessor( new DirectFieldAccessor(source).getPropertyValue("scanner") ).getPropertyValue(propertyName);
}
@Test
public void shouldSetNioLockerProperly() {
DirectFieldAccessor accessor = new DirectFieldAccessor(nioLockingSource);
assertThat(accessor.getPropertyValue("locker"), is(NioFileLocker.class));
assertThat(accessor.getPropertyValue("filter"), is(CompositeFileListFilter.class));
assertThat(extractFromScanner("locker", nioLockingSource), is(NioFileLocker.class));
assertThat(extractFromScanner("filter", nioLockingSource), is(CompositeFileListFilter.class));
}
public static class StubLocker extends AbstractLockingFilter {