001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.io;
018:
019: import java.io.File;
020: import java.io.FileFilter;
021: import java.io.IOException;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.ArrayList;
025: import java.util.Collection;
026:
027: import junit.framework.Assert;
028: import junit.framework.Test;
029: import junit.framework.TestCase;
030: import junit.framework.TestSuite;
031:
032: import org.apache.commons.io.filefilter.FileFilterUtils;
033: import org.apache.commons.io.filefilter.IOFileFilter;
034: import org.apache.commons.io.filefilter.NameFileFilter;
035: import org.apache.commons.io.filefilter.OrFileFilter;
036:
037: /**
038: * This is used to test DirectoryWalker for correctness.
039: *
040: * @version $Id: DirectoryWalkerTestCase.java 481847 2006-12-03 18:05:37Z scolebourne $
041: * @see DirectoryWalker
042: *
043: */
044: public class DirectoryWalkerTestCase extends TestCase {
045:
046: // Directories
047: private static final File current = new File(".");
048: private static final File javaDir = new File("src/java");
049: private static final File orgDir = new File(javaDir, "org");
050: private static final File apacheDir = new File(orgDir, "apache");
051: private static final File commonsDir = new File(apacheDir,
052: "commons");
053: private static final File ioDir = new File(commonsDir, "io");
054: private static final File outputDir = new File(ioDir, "output");
055: private static final File[] dirs = new File[] { orgDir, apacheDir,
056: commonsDir, ioDir, outputDir };
057:
058: // Files
059: private static final File copyUtils = new File(ioDir,
060: "CopyUtils.java");
061: private static final File ioUtils = new File(ioDir, "IOUtils.java");
062: private static final File proxyWriter = new File(outputDir,
063: "ProxyWriter.java");
064: private static final File nullStream = new File(outputDir,
065: "NullOutputStream.java");
066: private static final File[] ioFiles = new File[] { copyUtils,
067: ioUtils };
068: private static final File[] outputFiles = new File[] { proxyWriter,
069: nullStream };
070:
071: // Filters
072: private static final IOFileFilter dirsFilter = createNameFilter(dirs);
073: private static final IOFileFilter iofilesFilter = createNameFilter(ioFiles);
074: private static final IOFileFilter outputFilesFilter = createNameFilter(outputFiles);
075: private static final IOFileFilter ioDirAndFilesFilter = new OrFileFilter(
076: dirsFilter, iofilesFilter);
077: private static final IOFileFilter dirsAndFilesFilter = new OrFileFilter(
078: ioDirAndFilesFilter, outputFilesFilter);
079:
080: // Filter to exclude SVN files
081: private static final IOFileFilter NOT_SVN = FileFilterUtils
082: .makeSVNAware(null);
083:
084: public static Test suite() {
085: return new TestSuite(DirectoryWalkerTestCase.class);
086: }
087:
088: /** Construct the TestCase using the name */
089: public DirectoryWalkerTestCase(String name) {
090: super (name);
091: }
092:
093: /** Set Up */
094: protected void setUp() throws Exception {
095: super .setUp();
096: }
097:
098: /** Tear Down */
099: protected void tearDown() throws Exception {
100: super .tearDown();
101: }
102:
103: //-----------------------------------------------------------------------
104:
105: /**
106: * Test Filtering
107: */
108: public void testFilter() {
109: List results = new TestFileFinder(dirsAndFilesFilter, -1)
110: .find(javaDir);
111: assertEquals(
112: "Result Size",
113: (1 + dirs.length + ioFiles.length + outputFiles.length),
114: results.size());
115: assertTrue("Start Dir", results.contains(javaDir));
116: checkContainsFiles("Dir", dirs, results);
117: checkContainsFiles("IO File", ioFiles, results);
118: checkContainsFiles("Output File", outputFiles, results);
119: }
120:
121: /**
122: * Test Filtering and limit to depth 0
123: */
124: public void testFilterAndLimitA() {
125: List results = new TestFileFinder(NOT_SVN, 0).find(javaDir);
126: assertEquals("[A] Result Size", 1, results.size());
127: assertTrue("[A] Start Dir", results.contains(javaDir));
128: }
129:
130: /**
131: * Test Filtering and limit to depth 1
132: */
133: public void testFilterAndLimitB() {
134: List results = new TestFileFinder(NOT_SVN, 1).find(javaDir);
135: assertEquals("[B] Result Size", 2, results.size());
136: assertTrue("[B] Start Dir", results.contains(javaDir));
137: assertTrue("[B] Org Dir", results.contains(orgDir));
138: }
139:
140: /**
141: * Test Filtering and limit to depth 3
142: */
143: public void testFilterAndLimitC() {
144: List results = new TestFileFinder(NOT_SVN, 3).find(javaDir);
145: assertEquals("[C] Result Size", 4, results.size());
146: assertTrue("[C] Start Dir", results.contains(javaDir));
147: assertTrue("[C] Org Dir", results.contains(orgDir));
148: assertTrue("[C] Apache Dir", results.contains(apacheDir));
149: assertTrue("[C] Commons Dir", results.contains(commonsDir));
150: }
151:
152: /**
153: * Test Filtering and limit to depth 5
154: */
155: public void testFilterAndLimitD() {
156: List results = new TestFileFinder(dirsAndFilesFilter, 5)
157: .find(javaDir);
158: assertEquals("[D] Result Size",
159: (1 + dirs.length + ioFiles.length), results.size());
160: assertTrue("[D] Start Dir", results.contains(javaDir));
161: checkContainsFiles("[D] Dir", dirs, results);
162: checkContainsFiles("[D] File", ioFiles, results);
163: }
164:
165: /**
166: * Test separate dir and file filters
167: */
168: public void testFilterDirAndFile1() {
169: List results = new TestFileFinder(dirsFilter, iofilesFilter, -1)
170: .find(javaDir);
171: assertEquals("[DirAndFile1] Result Size",
172: (1 + dirs.length + ioFiles.length), results.size());
173: assertTrue("[DirAndFile1] Start Dir", results.contains(javaDir));
174: checkContainsFiles("[DirAndFile1] Dir", dirs, results);
175: checkContainsFiles("[DirAndFile1] File", ioFiles, results);
176: }
177:
178: /**
179: * Test separate dir and file filters
180: */
181: public void testFilterDirAndFile2() {
182: List results = new TestFileFinder((IOFileFilter) null,
183: (IOFileFilter) null, -1).find(javaDir);
184: assertTrue("[DirAndFile2] Result Size",
185: results.size() > (1 + dirs.length + ioFiles.length));
186: assertTrue("[DirAndFile2] Start Dir", results.contains(javaDir));
187: checkContainsFiles("[DirAndFile2] Dir", dirs, results);
188: checkContainsFiles("[DirAndFile2] File", ioFiles, results);
189: }
190:
191: /**
192: * Test separate dir and file filters
193: */
194: public void testFilterDirAndFile3() {
195: List results = new TestFileFinder(dirsFilter,
196: (IOFileFilter) null, -1).find(javaDir);
197: List resultDirs = directoriesOnly(results);
198: assertEquals("[DirAndFile3] Result Size", (1 + dirs.length),
199: resultDirs.size());
200: assertTrue("[DirAndFile3] Start Dir", results.contains(javaDir));
201: checkContainsFiles("[DirAndFile3] Dir", dirs, resultDirs);
202: }
203:
204: /**
205: * Test separate dir and file filters
206: */
207: public void testFilterDirAndFile4() {
208: List results = new TestFileFinder((IOFileFilter) null,
209: iofilesFilter, -1).find(javaDir);
210: List resultFiles = filesOnly(results);
211: assertEquals("[DirAndFile4] Result Size", ioFiles.length,
212: resultFiles.size());
213: assertTrue("[DirAndFile4] Start Dir", results.contains(javaDir));
214: checkContainsFiles("[DirAndFile4] File", ioFiles, resultFiles);
215: }
216:
217: /**
218: * Test Limiting to current directory
219: */
220: public void testLimitToCurrent() {
221: List results = new TestFileFinder(null, 0).find(current);
222: assertEquals("Result Size", 1, results.size());
223: assertTrue("Current Dir", results.contains(new File(".")));
224: }
225:
226: /**
227: * test an invalid start directory
228: */
229: public void testMissingStartDirectory() {
230:
231: // TODO is this what we want with invalid directory?
232: File invalidDir = new File("invalid-dir");
233: List results = new TestFileFinder(null, -1).find(invalidDir);
234: assertEquals("Result Size", 1, results.size());
235: assertTrue("Current Dir", results.contains(invalidDir));
236:
237: try {
238: new TestFileFinder(null, -1).find(null);
239: fail("Null start directory didn't throw Exception");
240: } catch (NullPointerException ignore) {
241: // expected result
242: }
243: }
244:
245: /**
246: * test an invalid start directory
247: */
248: public void testHandleStartDirectoryFalse() {
249:
250: List results = new TestFalseFileFinder(null, -1).find(current);
251: assertEquals("Result Size", 0, results.size());
252:
253: }
254:
255: // ------------ Convenience Test Methods ------------------------------------
256:
257: /**
258: * Check the files in the array are in the results list.
259: */
260: private void checkContainsFiles(String prefix, File[] files,
261: Collection results) {
262: for (int i = 0; i < files.length; i++) {
263: assertTrue(prefix + "[" + i + "] " + files[i], results
264: .contains(files[i]));
265: }
266: }
267:
268: /**
269: * Extract the directories.
270: */
271: private List directoriesOnly(Collection results) {
272: List list = new ArrayList(results.size());
273: for (Iterator it = results.iterator(); it.hasNext();) {
274: File file = (File) it.next();
275: if (file.isDirectory()) {
276: list.add(file);
277: }
278: }
279: return list;
280: }
281:
282: /**
283: * Extract the files.
284: */
285: private List filesOnly(Collection results) {
286: List list = new ArrayList(results.size());
287: for (Iterator it = results.iterator(); it.hasNext();) {
288: File file = (File) it.next();
289: if (file.isFile()) {
290: list.add(file);
291: }
292: }
293: return list;
294: }
295:
296: /**
297: * Create an name filter containg the names of the files
298: * in the array.
299: */
300: private static IOFileFilter createNameFilter(File[] files) {
301: String[] names = new String[files.length];
302: for (int i = 0; i < files.length; i++) {
303: names[i] = files[i].getName();
304: }
305: return new NameFileFilter(names);
306: }
307:
308: /**
309: * Test Cancel
310: */
311: public void testCancel() {
312: String cancelName = null;
313:
314: // Cancel on a file
315: try {
316: cancelName = "DirectoryWalker.java";
317: new TestCancelWalker(cancelName, false).find(javaDir);
318: fail("CancelException not thrown for '" + cancelName + "'");
319: } catch (DirectoryWalker.CancelException cancel) {
320: assertEquals("File: " + cancelName, cancelName, cancel
321: .getFile().getName());
322: assertEquals("Depth: " + cancelName, 5, cancel.getDepth());
323: } catch (IOException ex) {
324: fail("IOException: " + cancelName + " " + ex);
325: }
326:
327: // Cancel on a directory
328: try {
329: cancelName = "commons";
330: new TestCancelWalker(cancelName, false).find(javaDir);
331: fail("CancelException not thrown for '" + cancelName + "'");
332: } catch (DirectoryWalker.CancelException cancel) {
333: assertEquals("File: " + cancelName, cancelName, cancel
334: .getFile().getName());
335: assertEquals("Depth: " + cancelName, 3, cancel.getDepth());
336: } catch (IOException ex) {
337: fail("IOException: " + cancelName + " " + ex);
338: }
339:
340: // Suppress CancelException (use same file name as preceeding test)
341: try {
342: List results = new TestCancelWalker(cancelName, true)
343: .find(javaDir);
344: File lastFile = (File) results.get(results.size() - 1);
345: assertEquals("Suppress: " + cancelName, cancelName,
346: lastFile.getName());
347: } catch (IOException ex) {
348: fail("Suppress threw " + ex);
349: }
350:
351: }
352:
353: /**
354: * Test Cancel
355: */
356: public void testMultiThreadCancel() {
357: String cancelName = null;
358: TestMultiThreadCancelWalker walker = null;
359: // Cancel on a file
360: try {
361: cancelName = "DirectoryWalker.java";
362: walker = new TestMultiThreadCancelWalker(cancelName, false);
363: walker.find(javaDir);
364: fail("CancelException not thrown for '" + cancelName + "'");
365: } catch (DirectoryWalker.CancelException cancel) {
366: File last = (File) walker.results
367: .get(walker.results.size() - 1);
368: assertEquals(cancelName, last.getName());
369: assertEquals("Depth: " + cancelName, 5, cancel.getDepth());
370: } catch (IOException ex) {
371: fail("IOException: " + cancelName + " " + ex);
372: }
373:
374: // Cancel on a directory
375: try {
376: cancelName = "commons";
377: walker = new TestMultiThreadCancelWalker(cancelName, false);
378: walker.find(javaDir);
379: fail("CancelException not thrown for '" + cancelName + "'");
380: } catch (DirectoryWalker.CancelException cancel) {
381: assertEquals("File: " + cancelName, cancelName, cancel
382: .getFile().getName());
383: assertEquals("Depth: " + cancelName, 3, cancel.getDepth());
384: } catch (IOException ex) {
385: fail("IOException: " + cancelName + " " + ex);
386: }
387:
388: // Suppress CancelException (use same file name as preceeding test)
389: try {
390: walker = new TestMultiThreadCancelWalker(cancelName, true);
391: List results = walker.find(javaDir);
392: File lastFile = (File) results.get(results.size() - 1);
393: assertEquals("Suppress: " + cancelName, cancelName,
394: lastFile.getName());
395: } catch (IOException ex) {
396: fail("Suppress threw " + ex);
397: }
398:
399: }
400:
401: // ------------ Test DirectoryWalker implementation --------------------------
402:
403: /**
404: * Test DirectoryWalker implementation that finds files in a directory hierarchy
405: * applying a file filter.
406: */
407: private static class TestFileFinder extends DirectoryWalker {
408:
409: protected TestFileFinder(FileFilter filter, int depthLimit) {
410: super (filter, depthLimit);
411: }
412:
413: protected TestFileFinder(IOFileFilter dirFilter,
414: IOFileFilter fileFilter, int depthLimit) {
415: super (dirFilter, fileFilter, depthLimit);
416: }
417:
418: /** find files. */
419: protected List find(File startDirectory) {
420: List results = new ArrayList();
421: try {
422: walk(startDirectory, results);
423: } catch (IOException ex) {
424: Assert.fail(ex.toString());
425: }
426: return results;
427: }
428:
429: /** Handles a directory end by adding the File to the result set. */
430: protected void handleDirectoryEnd(File directory, int depth,
431: Collection results) {
432: results.add(directory);
433: }
434:
435: /** Handles a file by adding the File to the result set. */
436: protected void handleFile(File file, int depth,
437: Collection results) {
438: results.add(file);
439: }
440: }
441:
442: // ------------ Test DirectoryWalker implementation --------------------------
443:
444: /**
445: * Test DirectoryWalker implementation that always returns false
446: * from handleDirectoryStart()
447: */
448: private static class TestFalseFileFinder extends TestFileFinder {
449:
450: protected TestFalseFileFinder(FileFilter filter, int depthLimit) {
451: super (filter, depthLimit);
452: }
453:
454: /** Always returns false. */
455: protected boolean handleDirectory(File directory, int depth,
456: Collection results) {
457: return false;
458: }
459: }
460:
461: // ------------ Test DirectoryWalker implementation --------------------------
462:
463: /**
464: * Test DirectoryWalker implementation that finds files in a directory hierarchy
465: * applying a file filter.
466: */
467: static class TestCancelWalker extends DirectoryWalker {
468: private String cancelFileName;
469: private boolean suppressCancel;
470:
471: TestCancelWalker(String cancelFileName, boolean suppressCancel) {
472: super ();
473: this .cancelFileName = cancelFileName;
474: this .suppressCancel = suppressCancel;
475: }
476:
477: /** find files. */
478: protected List find(File startDirectory) throws IOException {
479: List results = new ArrayList();
480: walk(startDirectory, results);
481: return results;
482: }
483:
484: /** Handles a directory end by adding the File to the result set. */
485: protected void handleDirectoryEnd(File directory, int depth,
486: Collection results) throws IOException {
487: results.add(directory);
488: if (cancelFileName.equals(directory.getName())) {
489: throw new CancelException(directory, depth);
490: }
491: }
492:
493: /** Handles a file by adding the File to the result set. */
494: protected void handleFile(File file, int depth,
495: Collection results) throws IOException {
496: results.add(file);
497: if (cancelFileName.equals(file.getName())) {
498: throw new CancelException(file, depth);
499: }
500: }
501:
502: /** Handles Cancel. */
503: protected void handleCancelled(File startDirectory,
504: Collection results, CancelException cancel)
505: throws IOException {
506: if (!suppressCancel) {
507: super .handleCancelled(startDirectory, results, cancel);
508: }
509: }
510: }
511:
512: /**
513: * Test DirectoryWalker implementation that finds files in a directory hierarchy
514: * applying a file filter.
515: */
516: static class TestMultiThreadCancelWalker extends DirectoryWalker {
517: private String cancelFileName;
518: private boolean suppressCancel;
519: private boolean cancelled;
520: public List results;
521:
522: TestMultiThreadCancelWalker(String cancelFileName,
523: boolean suppressCancel) {
524: super ();
525: this .cancelFileName = cancelFileName;
526: this .suppressCancel = suppressCancel;
527: }
528:
529: /** find files. */
530: protected List find(File startDirectory) throws IOException {
531: results = new ArrayList();
532: walk(startDirectory, results);
533: return results;
534: }
535:
536: /** Handles a directory end by adding the File to the result set. */
537: protected void handleDirectoryEnd(File directory, int depth,
538: Collection results) throws IOException {
539: results.add(directory);
540: assertEquals(false, cancelled);
541: if (cancelFileName.equals(directory.getName())) {
542: cancelled = true;
543: }
544: }
545:
546: /** Handles a file by adding the File to the result set. */
547: protected void handleFile(File file, int depth,
548: Collection results) throws IOException {
549: results.add(file);
550: assertEquals(false, cancelled);
551: if (cancelFileName.equals(file.getName())) {
552: cancelled = true;
553: }
554: }
555:
556: /** Handles Cancelled. */
557: protected boolean handleIsCancelled(File file, int depth,
558: Collection results) throws IOException {
559: return cancelled;
560: }
561:
562: /** Handles Cancel. */
563: protected void handleCancelled(File startDirectory,
564: Collection results, CancelException cancel)
565: throws IOException {
566: if (!suppressCancel) {
567: super.handleCancelled(startDirectory, results, cancel);
568: }
569: }
570: }
571:
572: }
|