/** * Jeff Rupp * Master's Thesis * 2005 * * This is a utility class for discovering all the classes in a given * classpath resource which are instances of a given type, or if the * suffix of a file matches a given suffix. */ package jdr.utils; import java.io.*; import java.util.*; import java.util.zip.*; public class ClassPathHelper { private static final String filesep = System.getProperty("file.separator"); private static final String[] classPath = getClassPath(); public static final FileFilter classFilter = new FileFilter() { public boolean accept(File file) { return file.getName().endsWith(".class"); } }; /** Return the system class path as an array of strings. */ public static String[] getClassPath() { String classPath = System.getProperty("java.class.path"); return getClassPath(classPath); } /** Convert a class path to an array of strings. A class path is a list of path names separated by the character in the path.separator system property. */ public static String[] getClassPath(String path) { String pathsep = System.getProperty("path.separator"); StringTokenizer tok = new StringTokenizer(path,pathsep); String[] s = new String[tok.countTokens()]; for(int i = 0; tok.hasMoreTokens(); ++i) s[i] = tok.nextToken(); return s; } public static ArrayList getClassesOfType(String path, String pkg, Class cl) throws Exception { ArrayList result = new ArrayList(); // If the path is a zip or jar file, look inside for the // file String lPath = path.toLowerCase(); ArrayList files = null; files = getFiles(path, classFilter); for(Iterator it = files.iterator();it.hasNext();) { String className = ""; String res = ""; if(lPath.endsWith(".zip") || lPath.endsWith(".jar")) { ZipEntry ze = (ZipEntry)it.next(); className = ze.getName(); res = className.replace('/', '.'); } else { className = it.next().toString(); res = className.replace(File.separatorChar, '.'); } //System.out.println("classname: "+className); //System.out.println("resconv: "+res); int pkgIndex = res.indexOf(pkg); int clsIndex = res.lastIndexOf(".class"); //System.out.println(pkg+" Index: "+pkgIndex+" .class Index: "+clsIndex); if((pkgIndex >= 0) && (clsIndex > pkgIndex)) { res = res.substring(pkgIndex, clsIndex); //System.out.println("res: "+res); try { Class c = Class.forName(res); if(cl.isAssignableFrom(c)) { result.add(c.getName()); } c = null; } catch(NoClassDefFoundError err) { //System.out.println("Got err: " + err.getMessage()); } catch(Exception ex) { //System.out.println("Got: " + ex.getMessage()); } } } return result; } public static ArrayList getFiles(String path, FileFilter filter) { String lPath = path.toLowerCase(); if(lPath.endsWith(".zip") || lPath.endsWith(".jar")) { try { return getFilesInJar(path,filter); } catch(Exception ex) { return new ArrayList(); } } else { // Not a zip or jar file. Look for the resources in // a file/dir return getFilesInDir(path,filter); } } public static ArrayList getFilesInDir(String path, FileFilter filter) { ArrayList result = new ArrayList(); File f = new File(path); if(f.exists()) { if(f.isDirectory()) { String[] files = f.list(); for(int i = 0;i < files.length;i++) { result.addAll(getFilesInDir(f.getAbsolutePath()+File.separator+files[i], filter)); } } else { if(filter.accept(f)) { result.add(f); } } } return result; } /** Given a resource name and jar file name, open the jar file * and return a buffer containing the contents. Returns null * if the jar file could not be found or the resource could * not be found */ public static ArrayList getFilesInJar(String jarFile, FileFilter filter) throws Exception { ArrayList result = new ArrayList(); ZipFile zip = null; File f = new File(jarFile); // Make sure the file exists before opening it if(f.exists() && f.isFile()) { // Open the zip file zip = new ZipFile(f); } if(zip == null) return result; for(Enumeration en = zip.entries();en.hasMoreElements();) { ZipEntry ze = (ZipEntry)en.nextElement(); if(filter.accept(new File(ze.getName()))) { result.add(ze); } } return result; } }