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