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

svn commit: r424673 - in /jakarta/commons/proper/io/trunk/src: java/org/apache/commons/io/FileFinder.java test/org/apache/commons/io/FileFinderTestCase.java

Author: niallp
Date: Sat Jul 22 21:46:48 2006
New Revision: 424673

URL: http://svn.apache.org/viewvc?rev=424673&view=rev
Log:
IO-86 - Add FileFinder back into Commons IO

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

Added: 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=424673&view=auto
==============================================================================
--- 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/FileFinder.java Sat Jul 22 21:46:48 2006
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2005-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.List;
+import java.util.ArrayList;
+
+/**
+ * <p>Navigate/search through a File Hierarchy.</p>
+ *
+ * <p>FileFinder can be used as it is to provide a list
+ * of the files and directories in a file hierarchy,
+ * starting from a specified point.</p>
+ * 
+ * <p>It can be used in conjunction with a <code>FileFilter</code>
+ * to selectively filter the results produced. Commons IO
+ * provides a number of useful
+ * {@link org.apache.commons.io.filefilter.IOFileFilter} implementations
+ * which can be used in conjunction with this class.</p>
+ * 
+ * <p>FileFinder can also be extended to provide custom implementations
+ * that process the file hierarchy further (see example file cleaner below).</p>
+ *
+ * <h4>Example 1 - List all files and directories</h4>
+ * <p>Example, showing how to list all files and directories
+ * starting from the current directory:</p>
+ *
+ * <pre>
+ * List files = FileFinder.ALL_FILES.find();
+ * for (int i = 0; i < files.size(); i++) {
+ *     File file = (File)files.get(i);
+ *     System.out.println(file.getName());
+ * }
+ * </pre>
+ *
+ * <h4>Example 2 - Filtered list of files and directories</h4>
+ * <p>Example, showing how to list all directories and
+ * files ending in ".java" starting in a directory called
+ * "src":</p>
+ *
+ * <pre>
+ * IOFileFilter dirFilter  = DirectoryFileFilter.INSTANCE;
+ * IOFileFilter fileFilter = new SuffixFileFilter(".java");
+ * IOFileFilter filter     = new OrFileFilter(directories, txtFiles);
+ * 
+ * FileFinder finder = new FileFinder(filter);
+ * 
+ * List files = finder.find(new File("src"));
+ * for (int i = 0; i < files.size(); i++) {
+ *     File file = (File)files.get(i);
+ *     System.out.println(file.getName());
+ * }
+ * </pre>
+ *
+ * <h4>Example 3 - Custom Implementation</h4>
+ * <p>Example, showing how to create an implementation that
+ * deletes files and directories and returns a list of
+ * what has been deleted.</p>
+ *
+ * <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 {
+
+    /** 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() {
+    }
+
+    /**
+     * <p>Construct an instance with a filter.</p>
+     *
+     * @param filter Filter to limit the navigation/results
+     */
+    public FileFinder(FileFilter filter) {
+        this(filter, -1);
+    }
+
+    /**
+     * <p>Construct an instance limiting the <i>depth</i>
+     * navigated to.</p>
+     * 
+     * @param depthLimit Controls how <i>deep</i> the hierarchy is
+     *  navigated to (less than 0 means unlimited)
+     */
+    public FileFinder(int depthLimit) {
+        this(null, depthLimit);
+    }
+
+    /**
+     * <p>Construct an instance with a filter and limit
+     * the <i>depth</i> navigated to.</p>
+     *
+     * @param filter Filter to limit the navigation/results
+     * @param depthLimit Controls how <i>deep</i> the hierarchy is
+     *  navigated to (less than 0 means unlimited)
+     */
+    public FileFinder(FileFilter filter, int depthLimit) {
+        this.filter = filter;
+        this.depthLimit = depthLimit;
+    }
+
+    /**
+     * <p>Walk the file hierarchy starting from the current
+     * directory.</p>
+     *
+     * @return The collection of files found.
+     */
+    public List find() {
+        return find(new File("."));
+    }
+
+    /**
+     * <p>Walk the file hierarchy starting from the specified
+     * directory.</p>
+     *
+     * @param startDirectory The directory to start from
+     * @return The collection of files found.
+     */
+    public List find(File startDirectory) {
+        if (startDirectory == null || !startDirectory.exists()) {
+            String message = "Directory does not exist: " + startDirectory;
+            throw new IllegalArgumentException(message);
+        }
+        if (!startDirectory.isDirectory()) {
+            String message = "Not a directory: " + startDirectory;
+            throw new IllegalArgumentException(message);
+        }
+        List results = new ArrayList();
+        handleDirectory(startDirectory, 0, results);
+        return results;
+    }
+
+    /**
+     * <p>Process a directory.</p>
+     *
+     * @param directory The directory to process
+     * @param depth The directory level (starting directory = 0)
+     * @param results The collection of files found.
+     */
+    private void handleDirectory(File directory, int depth, List results) {
+        handleDirectoryStart(directory, depth, results);
+        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()) {
+                        handleDirectory(files[i], childDepth, results);
+                    } else {
+                        handleFile(files[i], childDepth, results);
+                    }
+                }
+            }
+        }
+        handleDirectoryEnd(directory, depth, results);
+    }
+
+    /**
+     * <p>Initial directory processing.</p>
+     *
+     * <p>This implementation adds the directory to the
+     * results collection.</p>
+     *
+     * @param directory The directory being processed
+     * @param depth The directory level (starting directory = 0)
+     * @param results The collection of files found.
+     */
+    protected void handleDirectoryStart(File directory, int depth, List results) {
+        results.add(directory);
+    }
+
+    /**
+     * <p>Final directory processing.</p>
+     * 
+     * <p>This implementation does nothing.</p>
+     *
+     * @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) {
+    }
+
+
+    /**
+     * <p>File processing.</p>
+     * 
+     * <p>This implementation adds the file to the results
+     * collection.</p>
+     *
+     * @param file The file being processed
+     * @param depth The directory level (starting directory = 0)
+     * @param results The collection of files found.
+     */
+    protected void handleFile(File file, int depth, List results) {
+        results.add(file);
+    }
+
+    /**
+     * <p>Handle directories which are restricted.</p>
+     * 
+     * @param directory Restricted directory
+     */
+    protected void handleRestricted(File directory) {
+    }
+}
\ No newline at end of file

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

Propchange: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileFinder.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileFinderTestCase.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileFinderTestCase.java?rev=424673&view=auto
==============================================================================
--- jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileFinderTestCase.java (added)
+++ jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileFinderTestCase.java Sat Jul 22 21:46:48 2006
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2005-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.util.List;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.apache.commons.io.filefilter.IOFileFilter;
+import org.apache.commons.io.filefilter.NameFileFilter;
+import org.apache.commons.io.filefilter.OrFileFilter;
+
+public class FileFinderTestCase extends TestCase {
+
+    // Directories
+    private static final File javaDir      = new File("src/java");
+    private static final File orgDir       = new File(javaDir, "org");
+    private static final File apacheDir    = new File(orgDir, "apache");
+    private static final File commonsDir   = new File(apacheDir, "commons");
+    private static final File ioDir        = new File(commonsDir, "io");
+    private static final File outputDir    = new File(ioDir, "output");
+    private static final File[] dirs       = new File[] {orgDir, apacheDir, commonsDir, ioDir, outputDir};
+
+    // Files
+    private static final File copyUtils     = new File(ioDir, "CopyUtils.java");
+    private static final File ioUtils       = new File(ioDir, "IOUtils.java");
+    private static final File proxyWriter   = new File(outputDir, "ProxyWriter.java");
+    private static final File nullStream    = new File(outputDir, "NullOutputStream.java");
+    private static final File[] ioFiles     = new File[] {copyUtils, ioUtils};
+    private static final File[] outputFiles = new File[] {proxyWriter, nullStream};
+    
+    // Filters
+    private static final IOFileFilter dirsFilter        = createNameFilter(dirs);
+    private static final IOFileFilter iofilesFilter     = createNameFilter(ioFiles);
+    private static final IOFileFilter outputFilesFilter = createNameFilter(outputFiles);
+    private static final IOFileFilter ioDirAndFilesFilter = new OrFileFilter(dirsFilter, iofilesFilter);
+    private static final IOFileFilter dirsAndFilesFilter = new OrFileFilter(ioDirAndFilesFilter, outputFilesFilter);
+
+    // Filter to exclude SVN files
+    private static final IOFileFilter NOT_SVN = FileFilterUtils.makeSVNAware(null);
+
+    public static Test suite() {
+        return new TestSuite(FileFinderTestCase.class);
+    }
+
+    /** Construct the TestCase using the name */
+    public FileFinderTestCase(String name) {
+        super(name);
+    }
+
+    /** Set Up */
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    /** Tear Down */
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    //-----------------------------------------------------------------------
+
+    /**
+     * Test Filtering
+     */
+    public void testFilter() {
+        List results = new FileFinder(dirsAndFilesFilter).find(javaDir);
+        assertEquals("Result Size", (1 + dirs.length + ioFiles.length + outputFiles.length), results.size());
+        assertTrue("Start Dir", results.contains(javaDir));
+        checkContainsFiles("Dir", dirs, results);
+        checkContainsFiles("IO File", ioFiles, results);
+        checkContainsFiles("Output File", outputFiles, results);
+    }
+
+    /**
+     * Test Filtering and limit to depth 0
+     */
+    public void testFilterAndLimitA() {
+        List results = new FileFinder(NOT_SVN, 0).find(javaDir);
+        assertEquals("[A] Result Size", 1, results.size());
+        assertTrue("[A] Start Dir",   results.contains(javaDir));
+    }
+
+    /**
+     * Test Filtering and limit to depth 1
+     */
+    public void testFilterAndLimitB() {
+        List results = new FileFinder(NOT_SVN, 1).find(javaDir);
+        assertEquals("[B] Result Size", 2, results.size());
+        assertTrue("[B] Start Dir",   results.contains(javaDir));
+        assertTrue("[B] Org Dir",     results.contains(orgDir));
+    }
+
+    /**
+     * Test Filtering and limit to depth 3
+     */
+    public void testFilterAndLimitC() {
+        List results = new FileFinder(NOT_SVN, 3).find(javaDir);
+        assertEquals("[A] Result Size", 4, results.size());
+        assertTrue("[A] Start Dir",   results.contains(javaDir));
+        assertTrue("[A] Org Dir",     results.contains(orgDir));
+        assertTrue("[A] Apache Dir",  results.contains(apacheDir));
+        assertTrue("[A] Commons Dir", results.contains(commonsDir));
+    }
+
+    /**
+     * Test Filtering and limit to depth 5
+     */
+    public void testFilterAndLimitD() {
+        List results = new FileFinder(dirsAndFilesFilter, 5).find(javaDir);
+        assertEquals("[D] Result Size", (1 + dirs.length + ioFiles.length), results.size());
+        assertTrue("[D] Start Dir", results.contains(javaDir));
+        checkContainsFiles("[D] Dir", dirs, results);
+        checkContainsFiles("[D] File", ioFiles, results);
+    }
+
+    /**
+     * Test Limiting to current directory
+     */
+    public void testLimitToCurrent() {
+        List results = new FileFinder(0).find();
+        assertEquals("Result Size", 1, results.size());
+        assertTrue("Current Dir", results.contains(new File(".")));
+    }
+
+    /**
+     * test an invalid start directory
+     */
+    public void testMissingStartDirectory() {
+        try {
+            FileFinder.ALL_FILES.find(new File("invalid-dir"));
+            fail("Invalid start directory didn't throw Exception");
+        } catch (IllegalArgumentException ignore) {
+            // expected result
+        }
+        try {
+            FileFinder.ALL_FILES.find(null);
+            fail("Null start directory didn't throw Exception");
+        } catch (IllegalArgumentException ignore) {
+            // expected result
+        }
+    }
+
+    /**
+     * Check the files in the array are in the results list.
+     */
+    private void checkContainsFiles(String prefix, File[] files, List results) {
+        for (int i = 0; i < files.length; i++) {
+            assertTrue(prefix + "["+i+"] " + files[i], results.contains(files[i]));
+        }
+    }
+
+    /**
+     * Create an name filter containg the names of the files
+     * in the array.
+     */
+    private static IOFileFilter createNameFilter(File[] files) {
+        String[] names = new String[files.length];
+        for (int i = 0; i < files.length; i++) {
+            names[i] = files[i].getName();
+        }
+        return new NameFileFilter(names);
+    }
+
+}

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

Propchange: jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileFinderTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL



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