You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2006/07/23 16:57:18 UTC

svn commit: r424750 - in /jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io: DirectoryWalker.java FileFinder.java

Author: scolebourne
Date: Sun Jul 23 07:57:17 2006
New Revision: 424750

URL: http://svn.apache.org/viewvc?rev=424750&view=rev
Log:
Create DirectoryWalker by extracting from FileFinder

Added:
    jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/DirectoryWalker.java   (with props)
Modified:
    jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileFinder.java

Added: 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?rev=424750&view=auto
==============================================================================
--- jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/DirectoryWalker.java (added)
+++ jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/DirectoryWalker.java Sun Jul 23 07:57:17 2006
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * 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.apache.commons.io;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.filefilter.IOFileFilter;
+
+/**
+ * Abstract class that walks through a directory hierarchy and provides
+ * subclasses with convenient hooks to add specific behaviour.
+ * <p>
+ * This class operates with a {@link IOFileFilter file filter} and maximum
+ * depth to limit the files and direcories visited. Commons IO supplies many
+ * common filter implementations in the <code>filefilter</code> package.
+ * <p>
+ * This class is extended within Commons IO to provide a file finder facility.
+ * However there are many other possible extensions. For example, to delete all
+ * files and '.svn' directories, and return a list of deleted files:
+ * <pre>
+ *  public class FileCleaner extends DirectoryWalker {
+ *
+ *    public List clean(File startDirectory) {
+ *      return walk(startDirectory);
+ *    }
+ *
+ *    protected boolean handleDirectoryStart(File directory, int depth, List results) {
+ *      // skip contents of svn directories
+ *      return !".svn".equals(directory.getName());
+ *    }
+ *
+ *    protected void handleDirectoryEnd(File directory, int depth, List results) {
+ *      // delete svn directories
+ *      if (".svn".equals(directory.getName())) {
+ *        directory.delete();
+ *      }
+ *    }
+ *
+ *    protected void handleFile(File file, int depth, List results) {
+ *      // delete file and add to list of deleted
+ *      file.delete();
+ *      results.add(file);
+ *    }
+ *  }
+ * </pre>
+ *
+ * @since Commons IO 1.3
+ * @version $Revision: 424748 $
+ */
+public abstract class DirectoryWalker {
+
+    /**
+     * The file filter to use to filter files and directories.
+     */
+    private final FileFilter filter;
+    /**
+     * The limit on the directory depth to walk.
+     */
+    private final int depthLimit;
+
+    /**
+     * Construct an instance with a filter and limit the <i>depth</i> navigated to.
+     *
+     * @param filter  the filter to limit the navigation/results, may be null
+     * @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;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Internal method that walks the directory hierarchy.
+     * <p>
+     * Most users of this class do not need to call this method. This method will
+     * be called automatically by another (public) method on the specific subclass.
+     * <p>
+     * Writers of subclasses should call this method to start the directory walk.
+     * Once called, this method will emit events as it walks the hierarchy.
+     * The event methods have the prefix <code>handle</code>.
+     *
+     * @param startDirectory  the directory to start from
+     * @return the collection of result objects, typically File objects
+     */
+    protected List walk(File startDirectory) {
+        List results = new ArrayList();
+        handleStart(startDirectory, results);
+        walk(startDirectory, 0, results);
+        handleEnd(results);
+        return results;
+    }
+
+    /**
+     * Main recursive method to examine the directory hierarchy.
+     *
+     * @param directory  the directory to examine
+     * @param depth  the directory level (starting directory = 0)
+     * @return the collection of result objects
+     */
+    private void walk(File directory, int depth, List results) {
+        boolean process = handleDirectoryStart(directory, depth, results);
+        if (process) {
+            int childDepth = depth + 1;
+            if (depthLimit < 0 || childDepth <= depthLimit) {
+                File[] files = (filter == null ? directory.listFiles() : directory.listFiles(filter));
+                if (files == null) {
+                    handleRestricted(directory);
+                } else {
+                    for (int i = 0; i < files.length; i++) {
+                        if (files[i].isDirectory()) {
+                            walk(files[i], childDepth, results);
+                        } else {
+                            handleFile(files[i], childDepth, results);
+                        }
+                    }
+                }
+            }
+        }
+        handleDirectoryEnd(directory, depth, results);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Overridable callback method invoked at the start of processing.
+     * <p>
+     * This implementation does nothing.
+     *
+     * @param startDirectory  the directory to start from
+     * @param results  the collection of result objects, may be updated
+     */
+    protected void handleStart(File startDirectory, List results) {
+        // do nothing - overridable by subclass
+    }
+
+    /**
+     * Overridable callback method invoked at the start of processing each directory.
+     * <p>
+     * This method returns a boolean to indicate if the directory should be examined
+     * or not. If you return false, the next event received will be the
+     * {@link #handleDirectoryEnd} for that directory. Note that this functionality
+     * is in addition to the filtering by file filter.
+     * <p>
+     * This implementation does nothing and returns true.
+     *
+     * @param directory  the current directory being processed
+     * @param depth  the current directory level (starting directory = 0)
+     * @param results  the collection of result objects, may be updated
+     * @return true to process this directory, false to skip this directory
+     */
+    protected boolean handleDirectoryStart(File directory, int depth, List results) {
+        // do nothing - overridable by subclass
+        return true;
+    }
+
+    /**
+     * Overridable callback method invoked for each (non-directory) file.
+     * <p>
+     * This implementation does nothing.
+     *
+     * @param file  the current file being processed
+     * @param depth  the current directory level (starting directory = 0)
+     * @param results  the collection of result objects, may be updated
+     */
+    protected void handleFile(File file, int depth, List results) {
+        // do nothing - overridable by subclass
+    }
+
+    /**
+     * Overridable callback method invoked for each restricted directory.
+     *
+     * @param directory  the restricted directory
+     */
+    protected void handleRestricted(File directory) {
+        // do nothing - overridable by subclass
+    }
+
+    /**
+     * Overridable callback method invoked at the end of processing each directory.
+     * <p>
+     * This implementation does nothing.
+     *
+     * @param directory The directory being processed
+     * @param depth The directory level (starting directory = 0)
+     * @param results The collection of files found.
+     */
+    protected void handleDirectoryEnd(File directory, int depth, List results) {
+        // do nothing - overridable by subclass
+    }
+
+    /**
+     * Overridable callback method invoked at the end of processing.
+     * <p>
+     * This implementation does nothing.
+     *
+     * @param results  the collection of result objects, may be updated
+     */
+    protected void handleEnd(List results) {
+        // do nothing - overridable by subclass
+    }
+
+}

Propchange: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/DirectoryWalker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/DirectoryWalker.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision

Modified: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileFinder.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileFinder.java?rev=424750&r1=424749&r2=424750&view=diff
==============================================================================
--- jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileFinder.java (original)
+++ jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileFinder.java Sun Jul 23 07:57:17 2006
@@ -18,14 +18,12 @@
 import java.io.File;
 import java.io.FileFilter;
 import java.util.List;
-import java.util.ArrayList;
 
 import org.apache.commons.io.filefilter.FileFilterUtils;
 import org.apache.commons.io.filefilter.IOFileFilter;
 
 /**
- * Finds files in a directory hierarchy, with the potential for subclasses
- * to add additiional behaviour.
+ * Finds files in a directory hierarchy applying a file filter.
  * <p>
  * FileFinder can be used without changes to provide a list of the files
  * and directories in a file hierarchy starting from a specified point.
@@ -34,8 +32,11 @@
  * <p>
  * Commons IO supplies many common filter implementations in the
  * <code>filefilter</code> package, see {@link FileFilterUtils}.
- * You can also create your own custom implementation, such as in the
- * file cleaner example below.
+ * <p>
+ * In addition to using FileFinder directly, you can create more advanced
+ * subclasses. FileFinder is a subclass of {@link DirectoryWalker} which
+ * provides a structured approach to walking the directory structure of
+ * a filing system. See that class for more details.
  *
  * <h4>Example 1 - List all files and directories</h4>
  * Example, showing how to list all files and directories starting from
@@ -65,46 +66,19 @@
  * }
  * </pre>
  *
- * <h4>Example 3 - Custom Implementation</h4>
- * Example, showing how to create an implementation that deletes files
- * and directories and returns a list of what has been deleted.
- *
- * <pre>
- *  public class FileDelete extends FileFinder {
- *
- *    public FileDelete() {
- *    }
- *
- *    protected void handleDirectoryStart(File directory, int depth, List results) {
- *    }
- *
- *    protected void handleDirectoryEnd(File directory, int depth, List results) {
- *      directory.delete();
- *      results.add(directory);
- *    }
- *
- *    protected void handleFile(File file, int depth, List results) {
- *      file.delete();
- *      results.add(file);
- *    }
- *  }
- * </pre>
- *
  * @since Commons IO 1.3
  * @version $Revision$
  */
-public class FileFinder {
+public class FileFinder extends DirectoryWalker {
 
     /** Singleton instance that finds all files */
     public static final FileFinder ALL_FILES = new FileFinder();
 
-    private FileFilter filter;
-    private int depthLimit = -1;
-
     /**
      * Restrictive consructor - use <code>ALL_FILES</code> singleton instance.
      */
     protected FileFinder() {
+        super(null, -1);
     }
 
     /**
@@ -113,7 +87,7 @@
      * @param filter  the filter to limit the navigation/results
      */
     public FileFinder(FileFilter filter) {
-        this(filter, -1);
+        super(filter, -1);
     }
 
     /**
@@ -123,7 +97,7 @@
      *  navigated to (less than 0 means unlimited)
      */
     public FileFinder(int depthLimit) {
-        this(null, depthLimit);
+        super(null, depthLimit);
     }
 
     /**
@@ -134,8 +108,7 @@
      *  navigated to (less than 0 means unlimited)
      */
     public FileFinder(FileFilter filter, int depthLimit) {
-        this.filter = filter;
-        this.depthLimit = depthLimit;
+        super(filter, depthLimit);
     }
 
     //-----------------------------------------------------------------------
@@ -167,75 +140,12 @@
             String message = "Not a directory: " + startDirectory;
             throw new IllegalArgumentException(message);
         }
-        return examine(startDirectory);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Examines the directory hierarchy.
-     *
-     * @param startDirectory  the directory to start from
-     * @return the collection of result objects
-     */
-    private List examine(File startDirectory) {
-        List results = new ArrayList();
-        handleStart(startDirectory, results);
-        examine(startDirectory, 0, results);
-        handleEnd(results);
-        return results;
-    }
-
-    /**
-     * Main recursive method to examine the directory hierarchy.
-     *
-     * @param directory  the directory to examine
-     * @param depth  the directory level (starting directory = 0)
-     * @return the collection of result objects
-     */
-    private void examine(File directory, int depth, List results) {
-        boolean process = handleDirectoryStart(directory, depth, results);
-        if (process) {
-            int childDepth = depth + 1;
-            if (depthLimit < 0 || childDepth <= depthLimit) {
-                File[] files = (filter == null ? directory.listFiles() : directory.listFiles(filter));
-                if (files == null) {
-                    handleRestricted(directory);
-                } else {
-                    for (int i = 0; i < files.length; i++) {
-                        if (files[i].isDirectory()) {
-                            examine(files[i], childDepth, results);
-                        } else {
-                            handleFile(files[i], childDepth, results);
-                        }
-                    }
-                }
-            }
-        }
-        handleDirectoryEnd(directory, depth, results);
+        return walk(startDirectory);
     }
 
     //-----------------------------------------------------------------------
     /**
-     * Overridable callback method invoked at the start of processing.
-     * <p>
-     * This implementation does nohting.
-     *
-     * @param startDirectory  the directory to start from
-     * @param results  the collection of result objects, may be updated
-     */
-    protected void handleStart(File startDirectory, List results) {
-        // do nothing - overridable by subclass
-    }
-
-    /**
-     * Overridable callback method invoked at the start of processing each directory.
-     * <p>
-     * This method returns a boolean to indicate if the directory should be examined
-     * or not. If you return false, the next event received will be the
-     * {@link #handleDirectoryEnd} for that directory. Note that this functionality
-     * is in addition to the filtering by file filter.
-     * <p>
-     * This implementation adds the directory to the results collection.
+     * Handles a directory start by adding the File to the result set.
      *
      * @param directory  the current directory being processed
      * @param depth  the current directory level (starting directory = 0)
@@ -248,9 +158,7 @@
     }
 
     /**
-     * Overridable callback method invoked for each (non-directory) file.
-     * <p>
-     * This implementation adds the file to the results collection.
+     * Handles a file by adding the File to the result set.
      *
      * @param file  the current file being processed
      * @param depth  the current directory level (starting directory = 0)
@@ -258,39 +166,6 @@
      */
     protected void handleFile(File file, int depth, List results) {
         results.add(file);
-    }
-
-    /**
-     * Overridable callback method invoked for each restricted directory.
-     *
-     * @param directory  the restricted directory
-     */
-    protected void handleRestricted(File directory) {
-        // do nothing - overridable by subclass
-    }
-
-    /**
-     * Overridable callback method invoked at the end of processing each directory.
-     * <p>
-     * This implementation does nothing.
-     *
-     * @param directory The directory being processed
-     * @param depth The directory level (starting directory = 0)
-     * @param results The collection of files found.
-     */
-    protected void handleDirectoryEnd(File directory, int depth, List results) {
-        // do nothing - overridable by subclass
-    }
-
-    /**
-     * Overridable callback method invoked at the end of processing.
-     * <p>
-     * This implementation does nothing.
-     *
-     * @param results  the collection of result objects, may be updated
-     */
-    protected void handleEnd(List results) {
-        // do nothing - overridable by subclass
     }
 
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org