001: /*
002: * ====================================================================
003: * JAFFA - Java Application Framework For All
004: *
005: * Copyright (C) 2002 JAFFA Development Group
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * Redistribution and use of this software and associated documentation ("Software"),
022: * with or without modification, are permitted provided that the following conditions are met:
023: * 1. Redistributions of source code must retain copyright statements and notices.
024: * Redistributions must also contain a copy of this document.
025: * 2. Redistributions in binary form must reproduce the above copyright notice,
026: * this list of conditions and the following disclaimer in the documentation
027: * and/or other materials provided with the distribution.
028: * 3. The name "JAFFA" must not be used to endorse or promote products derived from
029: * this Software without prior written permission. For written permission,
030: * please contact mail to: jaffagroup@yahoo.com.
031: * 4. Products derived from this Software may not be called "JAFFA" nor may "JAFFA"
032: * appear in their names without prior written permission.
033: * 5. Due credit should be given to the JAFFA Project (http://jaffa.sourceforge.net).
034: *
035: * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: */
049:
050: /*
051: * FindFiles.java
052: *
053: * Created on October 29, 2001, 2:16 PM
054: */
055:
056: package org.jaffa.util;
057:
058: import java.util.ArrayList;
059: import java.util.List;
060: import java.util.Iterator;
061: import java.util.StringTokenizer;
062: import java.io.File;
063: import java.io.FilenameFilter;
064:
065: /**This class is used to locate files with the specified set of root search directories. <p>
066: * The root directorities and all of its sub folders will be searched for the specified file.<p>
067: * This has been optimized not to search the same directories if the several root paths intersect.<p>
068: * <p>
069: * It currently does not support wildcard charaters in the filename parameter.<p>
070: * <p>
071: * <B>Example</B>
072: * <pre>
073: * FindFiles x = new FindFiles( System.getProperty("java.class.path") , "ComponentDefinition.xml");
074: * List files = x.getList();
075: * if(files == null)
076: * System.out.println("No Files Found");
077: * else {
078: * for(Iterator it = files.iterator(); it.hasNext();) {
079: * File file = (File) it.next();
080: * System.out.println( file.getPath() );
081: * }
082: * System.out.println(files.size() + " File(s) Found");
083: * }
084: * </pre>
085: *
086: * @author PaulE
087: * @version 1.0
088: */
089: public class FindFiles {
090:
091: private ArrayList m_filesFound = null;
092: private String m_filter = null;
093: private String m_pathList = null;
094:
095: /** Keep a list of the directories bein searched. Only search again if an entry is not in here...*/
096: private static final boolean DIR_CACHING = true;
097: private ArrayList m_dirCache = new ArrayList();
098:
099: /** Create a file search object specifying the search root directories and the filename to seach for. <p>
100: * Note: the file name is case sensitive and does not support wild card characters.<p>
101: * @param pathList A semicolon seperated list of root directories top be searched
102: * @param filename The name of the file to search for
103: */
104: public FindFiles(String pathList, String filename) {
105: m_filter = filename;
106: m_pathList = pathList;
107: }
108:
109: /** Resursivly search the speecified pathList for any file with the specified name
110: * @return A List of Files (<CODE>java.io.File</CODE> Objects) that matched the search criteria in the constructor
111: */
112: public List getList() {
113: if (m_filesFound == null) {
114: m_filesFound = new ArrayList();
115: findFiles();
116: }
117: return m_filesFound;
118: }
119:
120: /* Look for the files in question */
121: private void findFiles() {
122:
123: // Create the filter to use when searching for files
124: // This could be enhanced to use a wildcard filter object if needed!!!!
125: FilenameFilter filter = new DirFilter();
126:
127: // Tokenize the list of directories and loop through each one.
128: StringTokenizer st = new StringTokenizer(m_pathList,
129: File.pathSeparator);
130: while (st.hasMoreTokens()) {
131: String path = st.nextToken();
132: File f = new File(path);
133: // Only process this entry if it's a directory
134: if (f.isDirectory()) {
135:
136: // Get all sub-directories under this root.
137: DirList structure = new DirList(path);
138:
139: // For each sub directory, search it for any of the required file names
140: for (Iterator it = structure.getList().iterator(); it
141: .hasNext();) {
142: File dir = (File) it.next();
143: File[] list = dir.listFiles(filter);
144:
145: // For any matching files, add it to the search results (assming it not in there already!)
146: for (int i = 0; i < list.length; i++)
147: if (!m_filesFound.contains(list[i]))
148: m_filesFound.add(list[i]);
149: }
150: }
151: }
152: }
153:
154: /** Inner class used to filter the search results */
155: private class DirFilter implements FilenameFilter {
156: /** Tests if a specified file should be included in a file list.
157: *
158: * @param dir the directory in which the file was found
159: * @param name the name of the file
160: * @return <CODE>true</CODE> if and only if the name should be included in the file list; <CODE>false</CODE> otherwise
161: */
162: public boolean accept(File dir, String name) {
163: //System.out.println("Checking : " + name);
164: return m_filter.equalsIgnoreCase(name);
165: }
166: }
167:
168: /** Inner Class Created For Traversing a Directory Structure */
169: private class DirList {
170: ArrayList m_files = null;
171: String m_root;
172:
173: /** Create the tree specifying the starting point */
174: DirList(String file) {
175: m_root = file;
176: }
177:
178: /** Recursive function to go down the tree */
179: private void buildTree(File start) {
180: if (start == null || !start.isDirectory())
181: return;
182:
183: // Check the caching before continuing...
184: if (DIR_CACHING == true) {
185: if (m_dirCache.contains(start))
186: return;
187: else
188: m_dirCache.add(start);
189: }
190: m_files.add(start);
191: File[] contents = start.listFiles();
192: for (int i = 0; i < contents.length; i++) {
193: if (contents[i].isDirectory())
194: buildTree(contents[i]);
195: }
196: }
197:
198: /* Get the directory list */
199: List getList() {
200: if (m_files == null) {
201: m_files = new ArrayList();
202: buildTree(new File(m_root));
203: }
204: return m_files;
205: }
206: }
207: }
|