14fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy/* 24fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Licensed to the Apache Software Foundation (ASF) under one or more 34fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * contributor license agreements. See the NOTICE file distributed with 44fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * this work for additional information regarding copyright ownership. 54fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The ASF licenses this file to You under the Apache License, Version 2.0 64fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * (the "License"); you may not use this file except in compliance with 74fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * the License. You may obtain a copy of the License at 84fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 94fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * http://www.apache.org/licenses/LICENSE-2.0 104fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 114fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Unless required by applicable law or agreed to in writing, software 124fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * distributed under the License is distributed on an "AS IS" BASIS, 134fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 144fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * See the License for the specific language governing permissions and 154fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * limitations under the License. 164fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 174fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedypackage org.apache.commons.io; 184fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 194fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedyimport java.io.File; 204fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedyimport java.io.FileFilter; 214fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedyimport java.io.IOException; 224fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedyimport java.util.Collection; 234fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 244fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedyimport org.apache.commons.io.filefilter.FileFilterUtils; 254fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedyimport org.apache.commons.io.filefilter.IOFileFilter; 264fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedyimport org.apache.commons.io.filefilter.TrueFileFilter; 274fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 284fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy/** 294fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Abstract class that walks through a directory hierarchy and provides 304fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * subclasses with convenient hooks to add specific behaviour. 314fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 324fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This class operates with a {@link FileFilter} and maximum depth to 334fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * limit the files and direcories visited. 344fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Commons IO supplies many common filter implementations in the 354fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <a href="filefilter/package-summary.html"> filefilter</a> package. 364fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 374fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The following sections describe: 384fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <ul> 394fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <li><a href="#example">1. Example Implementation</a> - example 404fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <code>FileCleaner</code> implementation.</li> 414fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <li><a href="#filter">2. Filter Example</a> - using 424fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * {@link FileFilter}(s) with <code>DirectoryWalker</code>.</li> 434fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <li><a href="#cancel">3. Cancellation</a> - how to implement cancellation 444fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * behaviour.</li> 454fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * </ul> 464fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 474fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <a name="example"></a> 484fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <h3>1. Example Implementation</h3> 494fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 504fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * There are many possible extensions, for example, to delete all 514fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * files and '.svn' directories, and return a list of deleted files: 524fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <pre> 534fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * public class FileCleaner extends DirectoryWalker { 544fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 554fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * public FileCleaner() { 564fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * super(); 574fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 584fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 594fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * public List clean(File startDirectory) { 604fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * List results = new ArrayList(); 614fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * walk(startDirectory, results); 624fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * return results; 634fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 644fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 654fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * protected boolean handleDirectory(File directory, int depth, Collection results) { 664fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // delete svn directories and then skip 674fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * if (".svn".equals(directory.getName())) { 684fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * directory.delete(); 694fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * return false; 704fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } else { 714fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * return true; 724fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 734fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 744fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 754fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 764fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * protected void handleFile(File file, int depth, Collection results) { 774fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // delete file and add to list of deleted 784fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * file.delete(); 794fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * results.add(file); 804fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 814fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 824fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * </pre> 834fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 844fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <a name="filter"></a> 854fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <h3>2. Filter Example</h3> 864fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 874fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Choosing which directories and files to process can be a key aspect 884fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * of using this class. This information can be setup in three ways, 894fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * via three different constructors. 904fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 914fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The first option is to visit all directories and files. 924fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This is achieved via the no-args constructor. 934fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 944fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The second constructor option is to supply a single {@link FileFilter} 954fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * that describes the files and directories to visit. Care must be taken 964fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * with this option as the same filter is used for both directories 974fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * and files. 984fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 994fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * For example, if you wanted all directories which are not hidden 1004fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * and files which end in ".txt": 1014fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <pre> 1024fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * public class FooDirectoryWalker extends DirectoryWalker { 1034fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * public FooDirectoryWalker(FileFilter filter) { 1044fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * super(filter, -1); 1054fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 1064fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 1074fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1084fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // Build up the filters and create the walker 1094fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // Create a filter for Non-hidden directories 1104fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * IOFileFilter fooDirFilter = 1114fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * FileFilterUtils.andFileFilter(FileFilterUtils.directoryFileFilter, 1124fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * HiddenFileFilter.VISIBLE); 1134fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1144fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // Create a filter for Files ending in ".txt" 1154fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * IOFileFilter fooFileFilter = 1164fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * FileFilterUtils.andFileFilter(FileFilterUtils.fileFileFilter, 1174fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * FileFilterUtils.suffixFileFilter(".txt")); 1184fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1194fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // Combine the directory and file filters using an OR condition 1204fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * java.io.FileFilter fooFilter = 1214fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * FileFilterUtils.orFileFilter(fooDirFilter, fooFileFilter); 1224fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1234fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // Use the filter to construct a DirectoryWalker implementation 1244fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * FooDirectoryWalker walker = new FooDirectoryWalker(fooFilter); 1254fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * </pre> 1264fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 1274fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The third constructor option is to specify separate filters, one for 1284fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * directories and one for files. These are combined internally to form 1294fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * the correct <code>FileFilter</code>, something which is very easy to 1304fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * get wrong when attempted manually, particularly when trying to 1314fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * express constructs like 'any file in directories named docs'. 1324fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 1334fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * For example, if you wanted all directories which are not hidden 1344fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * and files which end in ".txt": 1354fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <pre> 1364fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * public class FooDirectoryWalker extends DirectoryWalker { 1374fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * public FooDirectoryWalker(IOFileFilter dirFilter, IOFileFilter fileFilter) { 1384fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * super(dirFilter, fileFilter, -1); 1394fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 1404fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 1414fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1424fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // Use the filters to construct the walker 1434fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * FooDirectoryWalker walker = new FooDirectoryWalker( 1444fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * HiddenFileFilter.VISIBLE, 1454fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * FileFilterUtils.suffixFileFilter(".txt"), 1464fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * ); 1474fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * </pre> 1484fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This is much simpler than the previous example, and is why it is the preferred 1494fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * option for filtering. 1504fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1514fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <a name="cancel"></a> 1524fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <h3>3. Cancellation</h3> 1534fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1544fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The DirectoryWalker contains some of the logic required for cancel processing. 1554fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Subclasses must complete the implementation. 1564fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 1574fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * What <code>DirectoryWalker</code> does provide for cancellation is: 1584fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <ul> 1594fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <li>{@link CancelException} which can be thrown in any of the 1604fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <i>lifecycle</i> methods to stop processing.</li> 1614fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <li>The <code>walk()</code> method traps thrown {@link CancelException} 1624fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * and calls the <code>handleCancelled()</code> method, providing 1634fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * a place for custom cancel processing.</li> 1644fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * </ul> 1654fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 1664fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Implementations need to provide: 1674fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <ul> 1684fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <li>The decision logic on whether to cancel processing or not.</li> 1694fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <li>Constructing and throwing a {@link CancelException}.</li> 1704fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <li>Custom cancel processing in the <code>handleCancelled()</code> method. 1714fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * </ul> 1724fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 1734fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Two possible scenarios are envisaged for cancellation: 1744fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <ul> 1754fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <li><a href="#external">3.1 External / Mult-threaded</a> - cancellation being 1764fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * decided/initiated by an external process.</li> 1774fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <li><a href="#internal">3.2 Internal</a> - cancellation being decided/initiated 1784fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * from within a DirectoryWalker implementation.</li> 1794fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * </ul> 1804fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 1814fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The following sections provide example implementations for these two different 1824fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * scenarios. 1834fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1844fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <a name="external"></a> 1854fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <h4>3.1 External / Multi-threaded</h4> 1864fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1874fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This example provides a public <code>cancel()</code> method that can be 1884fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * called by another thread to stop the processing. A typical example use-case 1894fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * would be a cancel button on a GUI. Calling this method sets a 1904fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <a href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#36930"> 1914fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * volatile</a> flag to ensure it will work properly in a multi-threaded environment. 1924fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The flag is returned by the <code>handleIsCancelled()</code> method, which 1934fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * will cause the walk to stop immediately. The <code>handleCancelled()</code> 1944fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * method will be the next, and last, callback method received once cancellation 1954fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * has occurred. 1964fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 1974fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <pre> 1984fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * public class FooDirectoryWalker extends DirectoryWalker { 1994fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2004fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * private volatile boolean cancelled = false; 2014fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2024fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * public void cancel() { 2034fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * cancelled = true; 2044fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 2054fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2064fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * private void handleIsCancelled(File file, int depth, Collection results) { 2074fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * return cancelled; 2084fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 2094fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2104fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * protected void handleCancelled(File startDirectory, Collection results, CancelException cancel) { 2114fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // implement processing required when a cancellation occurs 2124fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 2134fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 2144fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * </pre> 2154fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2164fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <a name="internal"></a> 2174fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <h4>3.2 Internal</h4> 2184fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2194fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This shows an example of how internal cancellation processing could be implemented. 2204fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <b>Note</b> the decision logic and throwing a {@link CancelException} could be implemented 2214fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * in any of the <i>lifecycle</i> methods. 2224fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2234fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <pre> 2244fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * public class BarDirectoryWalker extends DirectoryWalker { 2254fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2264fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * protected boolean handleDirectory(File directory, int depth, Collection results) throws IOException { 2274fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // cancel if hidden directory 2284fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * if (directory.isHidden()) { 2294fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * throw new CancelException(file, depth); 2304fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 2314fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * return true; 2324fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 2334fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2344fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * protected void handleFile(File file, int depth, Collection results) throws IOException { 2354fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // cancel if read-only file 2364fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * if (!file.canWrite()) { 2374fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * throw new CancelException(file, depth); 2384fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 2394fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * results.add(file); 2404fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 2414fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2424fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * protected void handleCancelled(File startDirectory, Collection results, CancelException cancel) { 2434fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // implement processing required when a cancellation occurs 2444fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 2454fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 2464fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * </pre> 2474fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2484fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @since Commons IO 1.3 2494fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @version $Revision: 424748 $ 2504fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 2514fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedypublic abstract class DirectoryWalker { 2524fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 2534fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 2544fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The file filter to use to filter files and directories. 2554fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 2564fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy private final FileFilter filter; 2574fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 2584fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The limit on the directory depth to walk. 2594fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 2604fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy private final int depthLimit; 2614fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 2624fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 2634fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Construct an instance with no filtering and unlimited <i>depth</i>. 2644fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 2654fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected DirectoryWalker() { 2664fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy this(null, -1); 2674fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 2684fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 2694fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 2704fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Construct an instance with a filter and limit the <i>depth</i> navigated to. 2714fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 2724fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The filter controls which files and directories will be navigated to as 2734fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * part of the walk. The {@link FileFilterUtils} class is useful for combining 2744fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * various filters together. A <code>null</code> filter means that no 2754fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * filtering should occur and all files and directories will be visited. 2764fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2774fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param filter the filter to apply, null means visit all files 2784fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param depthLimit controls how <i>deep</i> the hierarchy is 2794fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * navigated to (less than 0 means unlimited) 2804fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 2814fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected DirectoryWalker(FileFilter filter, int depthLimit) { 2824fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy this.filter = filter; 2834fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy this.depthLimit = depthLimit; 2844fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 2854fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 2864fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 2874fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Construct an instance with a directory and a file filter and an optional 2884fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * limit on the <i>depth</i> navigated to. 2894fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 2904fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The filters control which files and directories will be navigated to as part 2914fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * of the walk. This constructor uses {@link FileFilterUtils#makeDirectoryOnly(IOFileFilter)} 2924fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * and {@link FileFilterUtils#makeFileOnly(IOFileFilter)} internally to combine the filters. 2934fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * A <code>null</code> filter means that no filtering should occur. 2944fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 2954fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param directoryFilter the filter to apply to directories, null means visit all directories 2964fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param fileFilter the filter to apply to files, null means visit all files 2974fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param depthLimit controls how <i>deep</i> the hierarchy is 2984fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * navigated to (less than 0 means unlimited) 2994fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 3004fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected DirectoryWalker(IOFileFilter directoryFilter, IOFileFilter fileFilter, int depthLimit) { 3014fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy if (directoryFilter == null && fileFilter == null) { 3024fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy this.filter = null; 3034fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } else { 3044fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy directoryFilter = (directoryFilter != null ? directoryFilter : TrueFileFilter.TRUE); 3054fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy fileFilter = (fileFilter != null ? fileFilter : TrueFileFilter.TRUE); 3064fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy directoryFilter = FileFilterUtils.makeDirectoryOnly(directoryFilter); 3074fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy fileFilter = FileFilterUtils.makeFileOnly(fileFilter); 3084fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy this.filter = FileFilterUtils.orFileFilter(directoryFilter, fileFilter); 3094fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3104fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy this.depthLimit = depthLimit; 3114fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3124fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 3134fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy //----------------------------------------------------------------------- 3144fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 3154fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Internal method that walks the directory hierarchy in a depth-first manner. 3164fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 3174fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Users of this class do not need to call this method. This method will 3184fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * be called automatically by another (public) method on the specific subclass. 3194fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 3204fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Writers of subclasses should call this method to start the directory walk. 3214fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Once called, this method will emit events as it walks the hierarchy. 3224fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The event methods have the prefix <code>handle</code>. 3234fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 3244fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param startDirectory the directory to start from, not null 3254fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param results the collection of result objects, may be updated 3264fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws NullPointerException if the start directory is null 3274fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if an I/O Error occurs 3284fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 3294fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected final void walk(File startDirectory, Collection results) throws IOException { 3304fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy if (startDirectory == null) { 3314fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy throw new NullPointerException("Start Directory is null"); 3324fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3334fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy try { 3344fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy handleStart(startDirectory, results); 3354fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy walk(startDirectory, 0, results); 3364fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy handleEnd(results); 3374fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } catch(CancelException cancel) { 3384fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy handleCancelled(startDirectory, results, cancel); 3394fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3404fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3414fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 3424fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 3434fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Main recursive method to examine the directory hierarchy. 3444fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 3454fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param directory the directory to examine, not null 3464fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param depth the directory level (starting directory = 0) 3474fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param results the collection of result objects, may be updated 3484fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if an I/O Error occurs 3494fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 3504fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy private void walk(File directory, int depth, Collection results) throws IOException { 3514fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy checkIfCancelled(directory, depth, results); 3524fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy if (handleDirectory(directory, depth, results)) { 3534fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy handleDirectoryStart(directory, depth, results); 3544fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy int childDepth = depth + 1; 3554fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy if (depthLimit < 0 || childDepth <= depthLimit) { 3564fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy checkIfCancelled(directory, depth, results); 3574fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy File[] childFiles = (filter == null ? directory.listFiles() : directory.listFiles(filter)); 3584fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy if (childFiles == null) { 3594fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy handleRestricted(directory, childDepth, results); 3604fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } else { 3614fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy for (int i = 0; i < childFiles.length; i++) { 3624fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy File childFile = childFiles[i]; 3634fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy if (childFile.isDirectory()) { 3644fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy walk(childFile, childDepth, results); 3654fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } else { 3664fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy checkIfCancelled(childFile, childDepth, results); 3674fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy handleFile(childFile, childDepth, results); 3684fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy checkIfCancelled(childFile, childDepth, results); 3694fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3704fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3714fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3724fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3734fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy handleDirectoryEnd(directory, depth, results); 3744fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3754fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy checkIfCancelled(directory, depth, results); 3764fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3774fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 3784fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy //----------------------------------------------------------------------- 3794fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 3804fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Checks whether the walk has been cancelled by calling {@link #handleIsCancelled}, 3814fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * throwing a <code>CancelException</code> if it has. 3824fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 3834fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Writers of subclasses should not normally call this method as it is called 3844fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * automatically by the walk of the tree. However, sometimes a single method, 3854fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * typically {@link #handleFile}, may take a long time to run. In that case, 3864fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * you may wish to check for cancellation by calling this method. 3874fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 3884fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param file the current file being processed 3894fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param depth the current file level (starting directory = 0) 3904fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param results the collection of result objects, may be updated 3914fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if an I/O Error occurs 3924fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 3934fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected final void checkIfCancelled(File file, int depth, Collection results) throws IOException { 3944fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy if (handleIsCancelled(file, depth, results)) { 3954fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy throw new CancelException(file, depth); 3964fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3974fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 3984fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 3994fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 4004fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Overridable callback method invoked to determine if the entire walk 4014fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * operation should be immediately cancelled. 4024fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 4034fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This method should be implemented by those subclasses that want to 4044fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * provide a public <code>cancel()</code> method available from another 4054fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * thread. The design pattern for the subclass should be as follows: 4064fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <pre> 4074fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * public class FooDirectoryWalker extends DirectoryWalker { 4084fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * private volatile boolean cancelled = false; 4094fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 4104fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * public void cancel() { 4114fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * cancelled = true; 4124fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 4134fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * private void handleIsCancelled(File file, int depth, Collection results) { 4144fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * return cancelled; 4154fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 4164fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * protected void handleCancelled(File startDirectory, 4174fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Collection results, CancelException cancel) { 4184fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * // implement processing required when a cancellation occurs 4194fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 4204fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * } 4214fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * </pre> 4224fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 4234fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * If this method returns true, then the directory walk is immediately 4244fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * cancelled. The next callback method will be {@link #handleCancelled}. 4254fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 4264fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This implementation returns false. 4274fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 4284fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param file the file or directory being processed 4294fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param depth the current directory level (starting directory = 0) 4304fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param results the collection of result objects, may be updated 4314fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @return true if the walk has been cancelled 4324fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if an I/O Error occurs 4334fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 4344fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected boolean handleIsCancelled( 4354fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy File file, int depth, Collection results) throws IOException { 4364fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy // do nothing - overridable by subclass 4374fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy return false; // not cancelled 4384fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 4394fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 4404fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 4414fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Overridable callback method invoked when the operation is cancelled. 4424fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * The file being processed when the cancellation occurred can be 4434fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * obtained from the exception. 4444fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 4454fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This implementation just re-throws the {@link CancelException}. 4464fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 4474fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param startDirectory the directory that the walk started from 4484fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param results the collection of result objects, may be updated 4494fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param cancel the exception throw to cancel further processing 4504fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * containing details at the point of cancellation. 4514fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if an I/O Error occurs 4524fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 4534fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected void handleCancelled(File startDirectory, Collection results, 4544fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy CancelException cancel) throws IOException { 4554fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy // re-throw exception - overridable by subclass 4564fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy throw cancel; 4574fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 4584fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 4594fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy //----------------------------------------------------------------------- 4604fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 4614fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Overridable callback method invoked at the start of processing. 4624fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 4634fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This implementation does nothing. 4644fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 4654fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param startDirectory the directory to start from 4664fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param results the collection of result objects, may be updated 4674fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if an I/O Error occurs 4684fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 4694fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected void handleStart(File startDirectory, Collection results) throws IOException { 4704fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy // do nothing - overridable by subclass 4714fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 4724fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 4734fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 4744fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Overridable callback method invoked to determine if a directory should be processed. 4754fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 4764fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This method returns a boolean to indicate if the directory should be examined or not. 4774fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * If you return false, the entire directory and any subdirectories will be skipped. 4784fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Note that this functionality is in addition to the filtering by file filter. 4794fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 4804fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This implementation does nothing and returns true. 4814fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 4824fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param directory the current directory being processed 4834fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param depth the current directory level (starting directory = 0) 4844fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param results the collection of result objects, may be updated 4854fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @return true to process this directory, false to skip this directory 4864fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if an I/O Error occurs 4874fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 4884fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected boolean handleDirectory(File directory, int depth, Collection results) throws IOException { 4894fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy // do nothing - overridable by subclass 4904fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy return true; // process directory 4914fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 4924fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 4934fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 4944fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Overridable callback method invoked at the start of processing each directory. 4954fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 4964fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This implementation does nothing. 4974fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 4984fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param directory the current directory being processed 4994fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param depth the current directory level (starting directory = 0) 5004fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param results the collection of result objects, may be updated 5014fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if an I/O Error occurs 5024fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 5034fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected void handleDirectoryStart(File directory, int depth, Collection results) throws IOException { 5044fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy // do nothing - overridable by subclass 5054fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 5064fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 5074fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 5084fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Overridable callback method invoked for each (non-directory) file. 5094fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 5104fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This implementation does nothing. 5114fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 5124fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param file the current file being processed 5134fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param depth the current directory level (starting directory = 0) 5144fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param results the collection of result objects, may be updated 5154fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if an I/O Error occurs 5164fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 5174fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected void handleFile(File file, int depth, Collection results) throws IOException { 5184fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy // do nothing - overridable by subclass 5194fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 5204fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 5214fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 5224fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Overridable callback method invoked for each restricted directory. 5234fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 5244fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This implementation does nothing. 5254fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 5264fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param directory the restricted directory 5274fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param depth the current directory level (starting directory = 0) 5284fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param results the collection of result objects, may be updated 5294fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if an I/O Error occurs 5304fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 5314fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected void handleRestricted(File directory, int depth, Collection results) throws IOException { 5324fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy // do nothing - overridable by subclass 5334fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 5344fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 5354fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 5364fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Overridable callback method invoked at the end of processing each directory. 5374fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 5384fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This implementation does nothing. 5394fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 5404fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param directory the directory being processed 5414fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param depth the current directory level (starting directory = 0) 5424fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param results the collection of result objects, may be updated 5434fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if an I/O Error occurs 5444fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 5454fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected void handleDirectoryEnd(File directory, int depth, Collection results) throws IOException { 5464fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy // do nothing - overridable by subclass 5474fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 5484fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 5494fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 5504fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Overridable callback method invoked at the end of processing. 5514fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * <p> 5524fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * This implementation does nothing. 5534fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 5544fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param results the collection of result objects, may be updated 5554fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @throws IOException if an I/O Error occurs 5564fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 5574fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy protected void handleEnd(Collection results) throws IOException { 5584fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy // do nothing - overridable by subclass 5594fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 5604fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 5614fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy //----------------------------------------------------------------------- 5624fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 5634fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * CancelException is thrown in DirectoryWalker to cancel the current 5644fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * processing. 5654fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 5664fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy public static class CancelException extends IOException { 5674fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 5684fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** Serialization id. */ 5694fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy private static final long serialVersionUID = 1347339620135041008L; 5704fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 5714fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** The file being processed when the exception was thrown. */ 5724fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy private File file; 5734fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** The file depth when the exception was thrown. */ 5744fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy private int depth = -1; 5754fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 5764fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 5774fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Constructs a <code>CancelException</code> with 5784fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * the file and depth when cancellation occurred. 5794fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 5804fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param file the file when the operation was cancelled, may be null 5814fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param depth the depth when the operation was cancelled, may be null 5824fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 5834fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy public CancelException(File file, int depth) { 5844fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy this("Operation Cancelled", file, depth); 5854fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 5864fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 5874fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 5884fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Constructs a <code>CancelException</code> with 5894fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * an appropriate message and the file and depth when 5904fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * cancellation occurred. 5914fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 5924fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param message the detail message 5934fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param file the file when the operation was cancelled 5944fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @param depth the depth when the operation was cancelled 5954fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 5964fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy public CancelException(String message, File file, int depth) { 5974fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy super(message); 5984fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy this.file = file; 5994fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy this.depth = depth; 6004fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 6014fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 6024fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 6034fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Return the file when the operation was cancelled. 6044fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 6054fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @return the file when the operation was cancelled 6064fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 6074fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy public File getFile() { 6084fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy return file; 6094fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 6104fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy 6114fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy /** 6124fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * Return the depth when the operation was cancelled. 6134fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * 6144fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy * @return the depth when the operation was cancelled 6154fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy */ 6164fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy public int getDepth() { 6174fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy return depth; 6184fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 6194fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy } 6204fa0a3295bcacbdcd6a9e7709cf17aa5adb90356Scott Kennedy} 621