|
Finally, for the sake of completeness, Listing 13-5 shows the source for the class path search routines used by ClassPathTool. It is highly recursive, and on systems with symbolic links (such as most UNIX systems), you may want to either change the default maximum search depth or be sure to set the recursion (-r) to a non-negative number. Listing 13-5. Searching for Classespackage com.cascadetg.ch13; import java.io.File; import java.util.*; import java.util.zip.*; import org.apache.commons.lang.SystemUtils; public class ClassPathTool { // Utility values, initialized once static Properties systemProps = System.getProperties(); // Class configuration boolean verbose = false; boolean useJavaClassPath = true; boolean useBootClassPath = true; String userDefinedClassPath; String searchClass = "java.lang.String"; // Reporting statistics int filesChecked = 0; int directoriesChecked = 0; long timeElapsed = 0; // The maximum recursion depth to check, or -1 for infinite int maxSearchDepth = -1; // Used during search, the directory version (e.g. // \java\lang\String.class private String directorySearch; // Used during search, the ZIP entry version (e.g. // /java/lang/String.class private String zipEntrySearch; public List getPaths() { String[] paths = new String[3]; if (useJavaClassPath) paths[0] = System.getProperty("java.class.path"); if (useBootClassPath) paths[1] = System .getProperty("sun.boot.class.path"); paths[2] = userDefinedClassPath; java.util.List results = new LinkedList(); for (int i = 0; i < 3; i++) { if (paths[i] != null) { StringTokenizer myJavaClassPathTokenizer = new StringTokenizer( paths[i], SystemUtils.PATH_SEPARATOR, false); while (myJavaClassPathTokenizer .hasMoreElements()) results.add(myJavaClassPathTokenizer .nextElement()); } } return results; } public void findItem(Map foundEntries, String directory, int depth) { boolean pathIsZip = false; if (directory.endsWith(".jar")) pathIsZip = true; if (directory.endsWith(".zip")) pathIsZip = true; File myFile = new File(directory); if (myFile.isDirectory()) { directoriesChecked++; File checkLoc = new File(myFile.getPath() + SystemUtils.FILE_SEPARATOR + directorySearch); if (checkLoc.exists()) { foundEntries.put(checkLoc.getAbsolutePath(), new java.util.Date(checkLoc .lastModified()) .toLocaleString()); } if (maxSearchDepth != 0) { File[] items = myFile.listFiles(); for (int i = 0; i < items.length; i++) { boolean keepRecursing = true; if (maxSearchDepth != -1) if (depth > maxSearchDepth) keepRecursing = false; if (keepRecursing) { findItem(foundEntries, items[i] .getAbsolutePath(), (depth + 1)); } } } } if (pathIsZip) { ZipFile myZip = null; try { if (myFile.exists()) { filesChecked++; myZip = new ZipFile(myFile, ZipFile.OPEN_READ); ZipEntry myEntry = myZip .getEntry(zipEntrySearch); if (myEntry != null) { foundEntries.put(myZip.getName(), new java.util.Date(myFile .lastModified()) .toLocaleString()); } } } catch (Exception e) { System.err.print("While opening file: " + directory + " "); if (verbose) { e.printStackTrace(); } else { System.err.println(e.getMessage()); } } finally { try { if (myZip != null) myZip.close(); } catch (Exception e) { // Silent failure. } } } } /** Performs the search based on the current settings. */ public java.util.Map getEntries() { long startTime = System.currentTimeMillis(); HashMap foundEntries = new HashMap(); Iterator paths = getPaths().iterator(); directorySearch = searchClass.replace('.', SystemUtils.FILE_SEPARATOR.charAt(0)); directorySearch = directorySearch + ".class"; zipEntrySearch = searchClass.replace('.', '/'); zipEntrySearch = zipEntrySearch + ".class"; while (paths.hasNext()) { String current = (String) paths.next(); if (verbose) System.out .println("Base search: " + current); findItem(foundEntries, current, 0); } timeElapsed = System.currentTimeMillis() - startTime; return foundEntries; } public void listProp() { Iterator myPropKeys = systemProps.keySet().iterator(); while (myPropKeys.hasNext()) { String key = myPropKeys.next().toString(); System.out.print(key); System.out.print(":"); System.out.println(systemProps.getProperty(key)); } } public static void main(String[] argv) { ClassPathTool cp = new ClassPathTool(); String input = "org.hsqldb.Database"; cp.setUserDefinedClassPath("C:\\devenv\\"); cp.setVerbose(false); cp.setMaxSearchDepth(4); Map foundEntries = cp.getEntries(); System.out.println("Files checked: " + cp.filesChecked); System.out.println("Directories checked: " + cp.directoriesChecked); System.out.println("Elapsed time: " + cp.getTimeElapsed() / 1000 + "." + cp.getTimeElapsed() % 1000 + " sec"); if (foundEntries.size() > 0) { System.out.println("Found in:"); Iterator found = foundEntries.keySet().iterator(); while (found.hasNext()) { Object foundFile = found.next(); System.out.print(foundFile.toString()); System.out.print(" ["); System.out.print(foundEntries.get(foundFile)); System.out.println("]"); } } else { System.out.println("Unable to find entry."); } } public boolean isVerbose() { return verbose; } public void setVerbose(boolean verbose) { this.verbose = verbose; } public String getUserDefinedClassPath() { return userDefinedClassPath; } public void setUserDefinedClassPath(String userDefinedClassPath) { this.userDefinedClassPath = userDefinedClassPath; } public String getSearchClass() { return searchClass; } public void setSearchClass(String searchClass) { this.searchClass = searchClass; } public boolean isUseBootClassPath() { return useBootClassPath; } public void setUseBootClassPath(boolean useBootClassPath) { this.useBootClassPath = useBootClassPath; } public boolean isUseJavaClassPath() { return useJavaClassPath; } public void setUseJavaClassPath(boolean useJavaClassPath) { this.useJavaClassPath = useJavaClassPath; } public int getDirectoriesChecked() { return directoriesChecked; } public int getFilesChecked() { return filesChecked; } public int getMaxSearchDepth() { return maxSearchDepth; } public void setMaxSearchDepth(int maxSearchDepth) { this.maxSearchDepth = maxSearchDepth; } public long getTimeElapsed() { return timeElapsed; } } |
|