📄 classdiscovery.java
字号:
} } else { try { jar = new JarFile(part); enm = jar.entries(); while (enm.hasMoreElements()) { entry = (JarEntry) enm.nextElement(); // only class files if ( (entry.isDirectory()) || (!entry.getName().endsWith(".class")) ) continue; classname = entry.getName().replaceAll("\\.class", ""); // only classes in the particular package if (!classname.startsWith(pkgpath)) continue; // no sub-package if (classname.substring(pkgpath.length() + 1).indexOf("/") > -1) continue; result.add(classname.replaceAll("/", ".")); } } catch (Exception e) { e.printStackTrace(); } } } // check classes i = 0; while (i < result.size()) { try { clsNew = Class.forName((String) result.get(i)); // no abstract classes if (Modifier.isAbstract(clsNew.getModifiers())) result.remove(i); // must implement interface else if ( (cls.isInterface()) && (!hasInterface(cls, clsNew)) ) result.remove(i); // must be derived from class else if ( (!cls.isInterface()) && (!isSubclass(cls, clsNew)) ) result.remove(i); else i++; } catch (Exception e) { System.err.println("Checking class: " + result.get(i)); e.printStackTrace(); } } // sort result Collections.sort(result, new StringCompare()); // add to cache addCache(cls, pkgname, result); } return result; } /** * adds all the sub-directories recursively to the list. * * @param prefix the path prefix * @param dir the directory to look in for sub-dirs * @param list the current list of sub-dirs * @return the new list of sub-dirs */ protected static HashSet getSubDirectories(String prefix, File dir, HashSet list) { File[] files; int i; String newPrefix; // add directory to the list if (prefix == null) newPrefix = ""; else if (prefix.length() == 0) newPrefix = dir.getName(); else newPrefix = prefix + "." + dir.getName(); if (newPrefix.length() != 0) list.add(newPrefix); // search for sub-directories files = dir.listFiles(); if (files != null) { for (i = 0; i < files.length; i++) { if (files[i].isDirectory()) list = getSubDirectories(newPrefix, files[i], list); } } return list; } /** * Lists all packages it can find in the classpath. * * @return a list with all the found packages */ public static Vector findPackages() { Vector result; StringTokenizer tok; String part; File file; JarFile jar; JarEntry entry; Enumeration enm; HashSet set; result = new Vector(); set = new HashSet(); // check all parts of the classpath, to include additional classes from // "parallel" directories/jars, not just the first occurence tok = new StringTokenizer( System.getProperty("java.class.path"), System.getProperty("path.separator")); while (tok.hasMoreTokens()) { part = tok.nextToken(); if (VERBOSE) System.out.println("Classpath-part: " + part); // find classes file = new File(part); if (file.isDirectory()) { set = getSubDirectories(null, file, set); } else if (file.exists()) { try { jar = new JarFile(part); enm = jar.entries(); while (enm.hasMoreElements()) { entry = (JarEntry) enm.nextElement(); // only directories if (entry.isDirectory()) set.add(entry.getName().replaceAll("/", ".").replaceAll("\\.$", "")); } } catch (Exception e) { e.printStackTrace(); } } } // sort result set.remove("META-INF"); result.addAll(set); Collections.sort(result, new StringCompare()); return result; } /** * initializes the cache for the classnames. */ protected static void initCache() { if (m_Cache == null) m_Cache = new Hashtable<String,Vector>(); } /** * adds the list of classnames to the cache. * * @param cls the class to cache the classnames for * @param pkgname the package name the classes were found in * @param classnames the list of classnames to cache */ protected static void addCache(Class cls, String pkgname, Vector classnames) { initCache(); m_Cache.put(cls.getName() + "-" + pkgname, classnames); } /** * returns the list of classnames associated with this class and package, if * available, otherwise null. * * @param cls the class to get the classnames for * @param pkgname the package name for the classes * @return the classnames if found, otherwise null */ protected static Vector getCache(Class cls, String pkgname) { initCache(); return m_Cache.get(cls.getName() + "-" + pkgname); } /** * clears the cache for class/classnames relation. */ public static void clearCache() { initCache(); m_Cache.clear(); } /** * Possible calls: * <ul> * <li> * weka.core.ClassDiscovery <packages><br/> * Prints all the packages in the current classpath * </li> * <li> * weka.core.ClassDiscovery <classname> <packagename(s)><br/> * Prints the classes it found. * </li> * </ul> * * @param args the commandline arguments */ public static void main(String[] args) { Vector list; Vector packages; int i; StringTokenizer tok; if ((args.length == 1) && (args[0].equals("packages"))) { list = findPackages(); for (i = 0; i < list.size(); i++) System.out.println(list.get(i)); } else if (args.length == 2) { // packages packages = new Vector(); tok = new StringTokenizer(args[1], ","); while (tok.hasMoreTokens()) packages.add(tok.nextToken()); // search list = ClassDiscovery.find( args[0], (String[]) packages.toArray(new String[packages.size()])); // print result, if any System.out.println( "Searching for '" + args[0] + "' in '" + args[1] + "':\n" + " " + list.size() + " found."); for (i = 0; i < list.size(); i++) System.out.println(" " + (i+1) + ". " + list.get(i)); } else { System.out.println("\nUsage:"); System.out.println( ClassDiscovery.class.getName() + " packages"); System.out.println("\tlists all packages in the classpath"); System.out.println( ClassDiscovery.class.getName() + " <classname> <packagename(s)>"); System.out.println("\tlists classes derived from/implementing 'classname' that"); System.out.println("\tcan be found in 'packagename(s)' (comma-separated list"); System.out.println(); System.exit(1); } } /** * compares two strings. The following order is used:<br/> * <ul> * <li>case insensitive</li> * <li>german umlauts (ä , ö etc.) or other non-ASCII letters * are treated as special chars</li> * <li>special chars < numbers < letters</li> * </ul> */ public static class StringCompare implements Comparator { /** * appends blanks to the string if its shorter than <code>len</code>. * * @param s the string to pad * @param len the minimum length for the string to have * @return the padded string */ private String fillUp(String s, int len) { while (s.length() < len) s += " "; return s; } /** * returns the group of the character: 0=special char, 1=number, 2=letter. * * @param c the character to check * @return the group */ private int charGroup(char c) { int result; result = 0; if ( (c >= 'a') && (c <= 'z') ) result = 2; else if ( (c >= '0') && (c <= '9') ) result = 1; return result; } /** * Compares its two arguments for order. * * @param o1 the first object * @param o2 the second object * @return -1 if o1<o2, 0 if o1=o2 and 1 if o1&;gt;o2 */ public int compare(Object o1, Object o2) { String s1; String s2; int i; int result; int v1; int v2; result = 0; // they're equal // get lower case string s1 = o1.toString().toLowerCase(); s2 = o2.toString().toLowerCase(); // same length s1 = fillUp(s1, s2.length()); s2 = fillUp(s2, s1.length()); for (i = 0; i < s1.length(); i++) { // same char? if (s1.charAt(i) == s2.charAt(i)) { result = 0; } else { v1 = charGroup(s1.charAt(i)); v2 = charGroup(s2.charAt(i)); // different type (special, number, letter)? if (v1 != v2) { if (v1 < v2) result = -1; else result = 1; } else { if (s1.charAt(i) < s2.charAt(i)) result = -1; else result = 1; } break; } } return result; } /** * Indicates whether some other object is "equal to" this Comparator. * * @param obj the object to compare with this Comparator * @return true if the object is a StringCompare object as well */ public boolean equals(Object obj) { return (obj instanceof StringCompare); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -