package org.directwebremoting.impl; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URL; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; public class ClasspathScanner { private String pkg; private boolean recur = false; protected String getPackage() { return pkg; } public ClasspathScanner(String pkg, boolean subpackages) { recur = subpackages; sanitizePackage(pkg); } public ClasspathScanner(String pkg) { sanitizePackage(pkg); } private void sanitizePackage(String pkgName) { if ((pkgName == null) || (pkgName.trim().length() == 0)) throw new IllegalArgumentException("Base package cannot be null"); pkg = pkgName.replace('.', '/'); if (pkg.endsWith("*")) pkg = pkg.substring(0, pkg.length() - 1); if (pkg.endsWith("/")) pkg = pkg.substring(0, pkg.length() - 1); } protected ClassLoader getClassLoader() { return Thread.currentThread().getContextClassLoader(); } protected boolean isJARPath(String path) { return (path.indexOf("!") > 0) & (path.indexOf(".jar") > 0); } protected void add(Set<String> classes, String className) { if ((className.startsWith(pkg)) && (className.endsWith(".class"))) { boolean add = recur ? true : className.substring(pkg.length() + 1).indexOf("/") < 0; if (add) classes.add(className.substring(0, className.length() - 6).replace('/', '.')); } } protected Set<String> getClassesFromJAR(String path) throws IOException { Set<String> classes = new HashSet<String>(); String jarPath = path.substring(0, path.indexOf("!")).substring(path.indexOf(":") + 1); JarInputStream jarFile = new JarInputStream(new FileInputStream(jarPath)); JarEntry jarEntry; do { jarEntry = jarFile.getNextJarEntry(); if (jarEntry != null) add(classes, jarEntry.getName()); } while (jarEntry != null); return classes; } protected Set<String> getClassesFromDirectory(String path) { Set<String> classes = new HashSet<String>(); File directory = new File(path); if (directory.exists()) { for (String file : directory.list()) { File f = new File(directory, file); if (f.isFile()) add(classes, path.substring(path.indexOf(pkg)) + file); else if (recur) classes.addAll(getClassesFromDirectory(path + file + "/")); } } return classes; } protected String sanitizeURLForWindows(String path) { String tmp = path; if(tmp.indexOf("%20") > 0) tmp = tmp.replaceAll("%20", " "); // Encodes if ((tmp.indexOf(":") >= 0) && (tmp.startsWith("/"))) tmp = tmp.substring(1); // Removes leading / in URLs like /c:/... return tmp; } protected String sanitizeURL(String path) { return sanitizeURLForWindows(path); } public Set<String> getClasses() throws IOException { Set<String> classes = new HashSet<String>(); Enumeration<URL> resources = getClassLoader().getResources(pkg + "/"); if (resources != null) { while (resources.hasMoreElements()) { String path = sanitizeURL(resources.nextElement().getFile()); if ((path != null) && (path.trim().length() > 0)) classes.addAll( isJARPath(path) ? getClassesFromJAR(path) : getClassesFromDirectory(path) ); } } return classes; } }