Author: scolebourne
Date: Sat Oct 14 07:26:28 2006
New Revision: 463942
URL: http://svn.apache.org/viewvc?view=rev&rev=463942
Log:
Add constructor to take directory and file filters separately
Modified:
jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/DirectoryWalker.java
jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/DirectoryWalkerTestCase.java
Modified:
jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/DirectoryWalker.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/DirectoryWalker.java?view=diff&rev=463942&r1=463941&r2=463942
==============================================================================
---
jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/DirectoryWalker.java
(original)
+++
jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/DirectoryWalker.java
Sat Oct 14 07:26:28 2006
@@ -21,6 +21,10 @@
import java.io.IOException;
import java.util.Collection;
+import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.apache.commons.io.filefilter.IOFileFilter;
+import org.apache.commons.io.filefilter.TrueFileFilter;
+
/**
* Abstract class that walks through a directory hierarchy and provides
* subclasses with convenient hooks to add specific behaviour.
@@ -80,14 +84,28 @@
* <a name="filter"></a>
* <h3>2. Filter Example</h3>
*
- * If you wanted all directories which are not hidden
- * and files which end in ".txt" - you could build a composite filter
- * using the filter implementations in the Commons IO
- * <a href="filefilter/package-summary.html">filefilter</a> package
- * in the following way:
- *
+ * Choosing which directories and files to process can be a key aspect
+ * of using this class. This information can be setup in three ways,
+ * via three different constructors.
+ * <p>
+ * The first option is to visit all directories and files.
+ * This is achieved via the no-args constructor.
+ * <p>
+ * The second constructor option is to supply a single [EMAIL PROTECTED]
FileFilter}
+ * that describes the files and directories to visit. Care must be taken
+ * with this option as the same filter is used for both directories
+ * and files.
+ * <p>
+ * For example, if you wanted all directories which are not hidden
+ * and files which end in ".txt":
* <pre>
- *
+ * public class FooDirectoryWalker extends DirectoryWalker {
+ * public FooDirectoryWalker(FileFilter filter) {
+ * super(filter, -1);
+ * }
+ * }
+ *
+ * // Build up the filters and create the walker
* // Create a filter for Non-hidden directories
* IOFileFilter fooDirFilter =
* FileFilterUtils.andFileFilter(FileFilterUtils.directoryFileFilter,
@@ -103,9 +121,32 @@
* FileFilterUtils.orFileFilter(fooDirFilter, fooFileFilter);
*
* // Use the filter to construct a DirectoryWalker implementation
- * FooDirectoryWalker walker = new FooDirectoryWalker(fooFilter, -1);
- *
+ * FooDirectoryWalker walker = new FooDirectoryWalker(fooFilter);
* </pre>
+ * <p>
+ * The third constructor option is to specify separate filters, one for
+ * directories and one for files. These are combined internally to form
+ * the correct <code>FileFilter</code>, something which is very easy to
+ * get wrong when attempted manually, particularly when trying to
+ * express constructs like 'any file in directories named docs'.
+ * <p>
+ * For example, if you wanted all directories which are not hidden
+ * and files which end in ".txt":
+ * <pre>
+ * public class FooDirectoryWalker extends DirectoryWalker {
+ * public FooDirectoryWalker(IOFileFilter dirFilter, IOFileFilter
fileFilter) {
+ * super(dirFilter, fileFilter, -1);
+ * }
+ * }
+ *
+ * // Use the filters to construct the walker
+ * FooDirectoryWalker walker = new FooDirectoryWalker(
+ * HiddenFileFilter.VISIBLE,
+ * FileFilterUtils.suffixFileFilter(".txt"),
+ * );
+ * <pre>
+ * This is much simpler than the previous example, and is why it is the
preferred
+ * option for filtering.
*
* <a name="cancel"></a>
* <h3>3. Cancellation</h3>
@@ -145,8 +186,8 @@
*
* This example provides a <code>cancel()</code> method for external processes
to
* indcate that processing must stop. Calling this method sets a
- * <a
href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#36930">
- * volatile</a> flag to (hopefully) ensure it will work properly in
+ * <a
href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#36930">volatile</a>
+ * flag to (hopefully) ensure it will work properly in
* a multi-threaded environment. In this implementation the flag is checked in
two
* of the lifecycle methods using a convenience
<code>checkIfCancelled()</code> method
* which throws a [EMAIL PROTECTED] CancelException} if cancellation has been
requested.
@@ -237,13 +278,45 @@
/**
* Construct an instance with a filter and limit the <i>depth</i>
navigated to.
+ * <p>
+ * The filter controls which files and directories will be navigated to as
+ * part of the walk. The [EMAIL PROTECTED] FileFilterUtils} class is
useful for combining
+ * various filters together. A <code>null</code> filter means that no
+ * filtering should occur and all files and directories will be visited.
*
- * @param filter the filter to limit the navigation/results, may be null
+ * @param filter the filter to apply, null means visit all files
* @param depthLimit controls how <i>deep</i> the hierarchy is
* navigated to (less than 0 means unlimited)
*/
protected DirectoryWalker(FileFilter filter, int depthLimit) {
this.filter = filter;
+ this.depthLimit = depthLimit;
+ }
+
+ /**
+ * Construct an instance with a directory and a file filter and an optional
+ * limit on the <i>depth</i> navigated to.
+ * <p>
+ * The filters control which files and directories will be navigated to as
part
+ * of the walk. This constructor uses [EMAIL PROTECTED]
FileFilterUtils#makeDirectoryOnly()}
+ * and [EMAIL PROTECTED] FileFilterUtils#makeFileOnly()} internally to
combine the filters.
+ * A <code>null</code> filter means that no filtering should occur.
+ *
+ * @param directoryFilter the filter to apply to directories, null means
visit all directories
+ * @param fileFilter the filter to apply to files, null means visit all
files
+ * @param depthLimit controls how <i>deep</i> the hierarchy is
+ * navigated to (less than 0 means unlimited)
+ */
+ protected DirectoryWalker(IOFileFilter directoryFilter, IOFileFilter
fileFilter, int depthLimit) {
+ if (directoryFilter == null && fileFilter == null) {
+ this.filter = null;
+ } else {
+ directoryFilter = (directoryFilter != null ? directoryFilter :
TrueFileFilter.TRUE);
+ fileFilter = (fileFilter != null ? fileFilter :
TrueFileFilter.TRUE);
+ directoryFilter =
FileFilterUtils.makeDirectoryOnly(directoryFilter);
+ fileFilter = FileFilterUtils.makeFileOnly(fileFilter);
+ this.filter = FileFilterUtils.orFileFilter(directoryFilter,
fileFilter);
+ }
this.depthLimit = depthLimit;
}
Modified:
jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/DirectoryWalkerTestCase.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/DirectoryWalkerTestCase.java?view=diff&rev=463942&r1=463941&r2=463942
==============================================================================
---
jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/DirectoryWalkerTestCase.java
(original)
+++
jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/DirectoryWalkerTestCase.java
Sat Oct 14 07:26:28 2006
@@ -19,6 +19,7 @@
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
+import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
@@ -146,6 +147,50 @@
}
/**
+ * Test separate dir and file filters
+ */
+ public void testFilterDirAndFile1() {
+ List results = new TestFileFinder(dirsFilter, iofilesFilter,
-1).find(javaDir);
+ assertEquals("[DirAndFile1] Result Size", (1 + dirs.length +
ioFiles.length), results.size());
+ assertTrue("[DirAndFile1] Start Dir", results.contains(javaDir));
+ checkContainsFiles("[DirAndFile1] Dir", dirs, results);
+ checkContainsFiles("[DirAndFile1] File", ioFiles, results);
+ }
+
+ /**
+ * Test separate dir and file filters
+ */
+ public void testFilterDirAndFile2() {
+ List results = new TestFileFinder((IOFileFilter) null, (IOFileFilter)
null, -1).find(javaDir);
+ assertTrue("[DirAndFile2] Result Size", results.size() > (1 +
dirs.length + ioFiles.length));
+ assertTrue("[DirAndFile2] Start Dir", results.contains(javaDir));
+ checkContainsFiles("[DirAndFile2] Dir", dirs, results);
+ checkContainsFiles("[DirAndFile2] File", ioFiles, results);
+ }
+
+ /**
+ * Test separate dir and file filters
+ */
+ public void testFilterDirAndFile3() {
+ List results = new TestFileFinder(dirsFilter, (IOFileFilter) null,
-1).find(javaDir);
+ List resultDirs = directoriesOnly(results);
+ assertEquals("[DirAndFile3] Result Size", (1 + dirs.length),
resultDirs.size());
+ assertTrue("[DirAndFile3] Start Dir", results.contains(javaDir));
+ checkContainsFiles("[DirAndFile3] Dir", dirs, resultDirs);
+ }
+
+ /**
+ * Test separate dir and file filters
+ */
+ public void testFilterDirAndFile4() {
+ List results = new TestFileFinder((IOFileFilter) null, iofilesFilter,
-1).find(javaDir);
+ List resultFiles = filesOnly(results);
+ assertEquals("[DirAndFile4] Result Size", ioFiles.length,
resultFiles.size());
+ assertTrue("[DirAndFile4] Start Dir", results.contains(javaDir));
+ checkContainsFiles("[DirAndFile4] File", ioFiles, resultFiles);
+ }
+
+ /**
* Test Limiting to current directory
*/
public void testLimitToCurrent() {
@@ -195,6 +240,34 @@
}
/**
+ * Extract the directories.
+ */
+ private List directoriesOnly(Collection results) {
+ List list = new ArrayList(results.size());
+ for (Iterator it = results.iterator(); it.hasNext(); ) {
+ File file = (File) it.next();
+ if (file.isDirectory()) {
+ list.add(file);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Extract the files.
+ */
+ private List filesOnly(Collection results) {
+ List list = new ArrayList(results.size());
+ for (Iterator it = results.iterator(); it.hasNext(); ) {
+ File file = (File) it.next();
+ if (file.isFile()) {
+ list.add(file);
+ }
+ }
+ return list;
+ }
+
+ /**
* Create an name filter containg the names of the files
* in the array.
*/
@@ -257,6 +330,10 @@
protected TestFileFinder(FileFilter filter, int depthLimit) {
super(filter, depthLimit);
+ }
+
+ protected TestFileFinder(IOFileFilter dirFilter, IOFileFilter
fileFilter, int depthLimit) {
+ super(dirFilter, fileFilter, depthLimit);
}
/** find files. */
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]