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]

Reply via email to