INT-4149: Improve (S)FTP Recursive MGET

JIRA: https://jira.spring.io/browse/INT-4149

Add an option to always pass directories while recursing.

* Fix typos in docs
* Revert `SyslogReceivingChannelAdapterTests` `Thread.sleep()` fixes
This commit is contained in:
Gary Russell
2016-10-28 13:56:43 -04:00
committed by Artem Bilan
parent 67d6cd0c89
commit a43299213e
18 changed files with 207 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 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.
@@ -32,6 +32,7 @@ import org.springframework.integration.file.filters.SimplePatternFileListFilter;
/**
* @author Mark Fisher
* @author Gunnar Hillert
* @author Gary Russell
* @since 1.0.3
*/
public class FileListFilterFactoryBean implements FactoryBean<FileListFilter<File>> {
@@ -48,6 +49,8 @@ public class FileListFilterFactoryBean implements FactoryBean<FileListFilter<Fil
private volatile Boolean preventDuplicates;
private volatile Boolean alwaysAcceptDirectories;
private final Object monitor = new Object();
public void setFilter(FileListFilter<File> filter) {
@@ -76,6 +79,18 @@ public class FileListFilterFactoryBean implements FactoryBean<FileListFilter<Fil
this.preventDuplicates = preventDuplicates;
}
/**
* Set to true to indicate that the pattern should not be applied to directories.
* Used for recursive scans for file patterns, for example in gateway recursive
* mget operations. Only applies when a pattern or regex is provided.
* @param alwaysAcceptDirectories true to always pass directories.
* @since 5.0
*/
public void setAlwaysAcceptDirectories(Boolean alwaysAcceptDirectories) {
this.alwaysAcceptDirectories = alwaysAcceptDirectories;
}
@Override
public FileListFilter<File> getObject() throws Exception {
if (this.result == null) {
synchronized (this.monitor) {
@@ -85,10 +100,12 @@ public class FileListFilterFactoryBean implements FactoryBean<FileListFilter<Fil
return this.result;
}
@Override
public Class<?> getObjectType() {
return (this.result != null) ? this.result.getClass() : FileListFilter.class;
}
@Override
public boolean isSingleton() {
return true;
}
@@ -132,10 +149,18 @@ public class FileListFilterFactoryBean implements FactoryBean<FileListFilter<Fil
filtersNeeded.add(new AcceptOnceFileListFilter<File>());
}
if (this.filenamePattern != null) {
filtersNeeded.add(new SimplePatternFileListFilter(this.filenamePattern));
SimplePatternFileListFilter patternFilter = new SimplePatternFileListFilter(this.filenamePattern);
if (this.alwaysAcceptDirectories != null) {
patternFilter.setAlwaysAcceptDirectories(this.alwaysAcceptDirectories);
}
filtersNeeded.add(patternFilter);
}
if (this.filenameRegex != null) {
filtersNeeded.add(new RegexPatternFileListFilter(this.filenameRegex));
RegexPatternFileListFilter regexFilter = new RegexPatternFileListFilter(this.filenameRegex);
if (this.alwaysAcceptDirectories != null) {
regexFilter.setAlwaysAcceptDirectories(this.alwaysAcceptDirectories);
}
filtersNeeded.add(regexFilter);
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2016 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;
/**
* A file list filter that can be configured to always accept (pass) directories.
* This permits, for example, pattern matching on just files when using recursion
* to examine a directory tree.
*
* @author Gary Russell
* @since 5.0
*
*/
public abstract class AbstractDirectoryAwareFileListFilter<F> extends AbstractFileListFilter<F> {
private boolean alwaysAcceptDirectories;
/**
* Set to true so that filters that support this feature can unconditionally pass
* directories; default false.
* @param alwaysAcceptDirectories true to always pass directories.
*/
public void setAlwaysAcceptDirectories(boolean alwaysAcceptDirectories) {
this.alwaysAcceptDirectories = alwaysAcceptDirectories;
}
protected boolean alwaysAccept(F file) {
return file != null && this.alwaysAcceptDirectories && isDirectory(file);
}
/**
* Subclasses must implement this method to indicate whether the file
* is a directory or not.
* @param file the file.
* @return true if it's a directory.
*/
protected abstract boolean isDirectory(F file);
}

View File

@@ -30,7 +30,8 @@ import org.springframework.util.Assert;
* @param <F> the type of file entry
* @since 2.0
*/
public abstract class AbstractRegexPatternFileListFilter<F> extends AbstractFileListFilter<F> implements InitializingBean {
public abstract class AbstractRegexPatternFileListFilter<F> extends AbstractDirectoryAwareFileListFilter<F>
implements InitializingBean {
private volatile Pattern pattern;
@@ -59,7 +60,7 @@ public abstract class AbstractRegexPatternFileListFilter<F> extends AbstractFile
@Override
public boolean accept(F file) {
return (file != null) && this.pattern.matcher(this.getFilename(file)).matches();
return alwaysAccept(file) || (file != null && this.pattern.matcher(getFilename(file)).matches());
}
/**

View File

@@ -29,7 +29,7 @@ import org.springframework.util.AntPathMatcher;
* @see org.springframework.integration.file.filters.AbstractRegexPatternFileListFilter
* @since 2.0
*/
public abstract class AbstractSimplePatternFileListFilter<F> extends AbstractFileListFilter<F> {
public abstract class AbstractSimplePatternFileListFilter<F> extends AbstractDirectoryAwareFileListFilter<F> {
private final AntPathMatcher matcher = new AntPathMatcher();
@@ -46,7 +46,7 @@ public abstract class AbstractSimplePatternFileListFilter<F> extends AbstractFil
*/
@Override
public final boolean accept(F file) {
return this.matcher.match(this.path, this.getFilename(file));
return alwaysAccept(file) || (file != null && this.matcher.match(this.path, this.getFilename(file)));
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2016 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.
@@ -23,6 +23,7 @@ import java.util.regex.Pattern;
* Implementation of AbstractRegexPatternMatchingFileListFilter for java.io.File instances.
*
* @author Mark Fisher
* @author Gary Russell
*/
public class RegexPatternFileListFilter extends AbstractRegexPatternFileListFilter<File> {
@@ -40,4 +41,9 @@ public class RegexPatternFileListFilter extends AbstractRegexPatternFileListFilt
return (file != null) ? file.getName() : null;
}
@Override
protected boolean isDirectory(File file) {
return file.isDirectory();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2016 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.
@@ -23,6 +23,7 @@ import java.io.File;
* This filter only filters on the name of the file, the rest of the path is ignored.
*
* @author Mark Fisher
* @author Gary Russell
* @since 2.0
*/
public class SimplePatternFileListFilter extends AbstractSimplePatternFileListFilter<File> {
@@ -37,4 +38,10 @@ public class SimplePatternFileListFilter extends AbstractSimplePatternFileListFi
return file.getName();
}
@Override
protected boolean isDirectory(File file) {
return file.isDirectory();
}
}