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 [EMAIL PROTECTED] 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 + * [EMAIL PROTECTED] #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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 - * [EMAIL PROTECTED] #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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]