Recursively search a directory tree
/* * Copyright 2007 Google Inc. * * 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. */ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; /** * Recursively search a directory tree, for each File found in it, call * FileFinderListener.proceedFile. A filter can be set prior calling this * method. * * @author ycoppel@google.com (Yohann Coppel) * */ public class FileLister { /** * Base directory to explore. */ private File classPath; /** * File listener for callbacks. */ private FileListerListener listener; /** * @param classPath * path to the classFile (usually top level package as com in * com.google.common) */ public FileLister(File classPath, FileListerListener depmk) { this.classPath = classPath; this.listener = depmk; } /** * begin the search of class files in the classPath given to the constructor. */ public void start() { listener.startProcessing(); for (File f : classPath.listFiles()) { dfsFileSearch(f); } listener.endOfProcessing(); } /** * operate a recursive depth first search in the directory. If file is a * directory, recursively search into for files. For each file found, check if * it passes the filter of DepMaker, and if yes, call proceedFile with the * file. * * @param file * File where to start the dfsFileSearch */ private void dfsFileSearch(File file) { boolean dirMatches = listener.directoryFilter(file.getPath()); if (file.isDirectory()) { // call callback for entering the directory only if the directory matches if (dirMatches) { listener.enterDirectory(file.getPath().replaceFirst(classPath.getPath(), "")); } // look inside of the directory anyway (maybe sub directories matches... for (File f : file.listFiles()) { dfsFileSearch(f); } // get out of the directory, callback. if (dirMatches) { listener.outDirectory(file.getPath().replaceFirst(classPath.getPath(), "")); } } else { // dir.isFile() == true if (listener.fileFilter(file.getPath()) && dirMatches) { try { listener.proceedFile(new FileInputStream(file), file.getPath().replaceFirst( classPath.getPath(), "")); } catch (FileNotFoundException e) { // should not happen, cause we just seen it on the hard drive... // but who knows... e.printStackTrace(); } } } } } /* * Copyright 2007 Google Inc. * * 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. */ /** * Listener for callbacks when directories and files are found when exploring a * directory, or a jar file for example. * * @author ycoppel@google.com (Yohann Coppel) * */ interface FileListerListener { /** * Filter to apply to (normal - i.e not a directory) files found in the * directory. May be a simple filename check as "end with .class" * * @param name * filename * @return true if the filename pass the filter, and that proceedFile should * be called on this file later * */ public boolean fileFilter(String name); /** * Filter to apply to directories. If this methods return false, * subdirectories should not be traversed. May be a simple directory path * check as "start with 'directoryfilter'" * * @param name * filename to check * @return true if the directory can contain interresting files. */ public boolean directoryFilter(String name); /** * method called when a file passing the fileFilter test is found. * * @param f * file found. */ public void proceedFile(InputStream f, String name); /** * called when entering in the given directory * * @param directoryPath */ public void enterDirectory(String directoryPath); /** * called when we step out from the given directory * * @param directoryPath */ public void outDirectory(String directoryPath); /** * callback called at the begining of the processing */ public void startProcessing(); /** * callback called at the end of the processing */ public void endOfProcessing(); }