📄 classdiscovery.java
字号:
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* * ClassDiscovery.java * Copyright (C) 2005 University of Waikato, Hamilton, New Zealand * */package weka.core;import java.io.File;import java.lang.reflect.Modifier;import java.net.URL;import java.util.Collections;import java.util.Comparator;import java.util.Enumeration;import java.util.HashSet;import java.util.Hashtable;import java.util.StringTokenizer;import java.util.Vector;import java.util.jar.JarEntry;import java.util.jar.JarFile;/** * This class is used for discovering classes that implement a certain * interface or a derived from a certain class. * * @author FracPete (fracpete at waikato dot ac dot nz) * @version $Revision: 1.6 $ * @see StringCompare */public class ClassDiscovery { /** whether to output some debug information. */ public final static boolean VERBOSE = false; /** for caching queries (classname+packagename <-> Vector with classnames). */ protected static Hashtable<String,Vector> m_Cache; /** notify if VERBOSE is still on */ static { if (VERBOSE) System.err.println(ClassDiscovery.class.getName() + ": VERBOSE ON"); } /** * Checks whether the "otherclass" is a subclass of the given "superclass". * * @param superclass the superclass to check against * @param otherclass this class is checked whether it is a subclass * of the the superclass * @return TRUE if "otherclass" is a true subclass */ public static boolean isSubclass(String superclass, String otherclass) { try { return isSubclass(Class.forName(superclass), Class.forName(otherclass)); } catch (Exception e) { return false; } } /** * Checks whether the "otherclass" is a subclass of the given "superclass". * * @param superclass the superclass to check against * @param otherclass this class is checked whether it is a subclass * of the the superclass * @return TRUE if "otherclass" is a true subclass */ public static boolean isSubclass(Class superclass, Class otherclass) { Class currentclass; boolean result; result = false; currentclass = otherclass; do { result = currentclass.equals(superclass); // topmost class reached? if (currentclass.equals(Object.class)) break; if (!result) currentclass = currentclass.getSuperclass(); } while (!result); return result; } /** * Checks whether the given class implements the given interface. * * @param intf the interface to look for in the given class * @param cls the class to check for the interface * @return TRUE if the class contains the interface */ public static boolean hasInterface(String intf, String cls) { try { return hasInterface(Class.forName(intf), Class.forName(cls)); } catch (Exception e) { return false; } } /** * Checks whether the given class implements the given interface. * * @param intf the interface to look for in the given class * @param cls the class to check for the interface * @return TRUE if the class contains the interface */ public static boolean hasInterface(Class intf, Class cls) { Class[] intfs; int i; boolean result; Class currentclass; result = false; currentclass = cls; do { // check all the interfaces, this class implements intfs = currentclass.getInterfaces(); for (i = 0; i < intfs.length; i++) { if (intfs[i].equals(intf)) { result = true; break; } } // get parent class if (!result) { currentclass = currentclass.getSuperclass(); // topmost class reached or no superclass? if ( (currentclass == null) || (currentclass.equals(Object.class)) ) break; } } while (!result); return result; } /** * If the given package can be found in this part of the classpath then * an URL object is returned, otherwise <code>null</code>. * * @param classpathPart the part of the classpath to look for the package * @param pkgname the package to look for * @return if found, the url as string, otherwise null */ protected static URL getURL(String classpathPart, String pkgname) { String urlStr; URL result; File classpathFile; File file; JarFile jarfile; Enumeration enm; String pkgnameTmp; result = null; urlStr = null; try { classpathFile = new File(classpathPart); // directory or jar? if (classpathFile.isDirectory()) { // does the package exist in this directory? file = new File(classpathPart + pkgname); if (file.exists()) urlStr = "file:" + classpathPart + pkgname; } else { // is package actually included in jar? jarfile = new JarFile(classpathPart); enm = jarfile.entries(); pkgnameTmp = pkgname.substring(1); // remove the leading "/" while (enm.hasMoreElements()) { if (enm.nextElement().toString().startsWith(pkgnameTmp)) { urlStr = "jar:file:" + classpathPart + "!" + pkgname; break; } } } } catch (Exception e) { // ignore } // try to generate URL from url string if (urlStr != null) { try { result = new URL(urlStr); } catch (Exception e) { System.err.println( "Trying to create URL from '" + urlStr + "' generates this exception:\n" + e); result = null; } } return result; } /** * Checks the given packages for classes that inherited from the given class, * in case it's a class, or implement this class, in case it's an interface. * * @param classname the class/interface to look for * @param pkgnames the packages to search in * @return a list with all the found classnames */ public static Vector find(String classname, String[] pkgnames) { Vector result; Class cls; result = new Vector(); try { cls = Class.forName(classname); result = find(cls, pkgnames); } catch (Exception e) { e.printStackTrace(); } return result; } /** * Checks the given package for classes that inherited from the given class, * in case it's a class, or implement this class, in case it's an interface. * * @param classname the class/interface to look for * @param pkgname the package to search in * @return a list with all the found classnames */ public static Vector find(String classname, String pkgname) { Vector result; Class cls; result = new Vector(); try { cls = Class.forName(classname); result = find(cls, pkgname); } catch (Exception e) { e.printStackTrace(); } return result; } /** * Checks the given packages for classes that inherited from the given class, * in case it's a class, or implement this class, in case it's an interface. * * @param cls the class/interface to look for * @param pkgnames the packages to search in * @return a list with all the found classnames */ public static Vector find(Class cls, String[] pkgnames) { Vector result; int i; result = new Vector(); for (i = 0; i < pkgnames.length; i++) result.addAll(find(cls, pkgnames[i])); // sort result Collections.sort(result, new StringCompare()); return result; } /** * Checks the given package for classes that inherited from the given class, * in case it's a class, or implement this class, in case it's an interface. * * @param cls the class/interface to look for * @param pkgname the package to search in * @return a list with all the found classnames */ public static Vector find(Class cls, String pkgname) { Vector result; StringTokenizer tok; String part; String pkgpath; File dir; File[] files; URL url; int i; Class clsNew; String classname; JarFile jar; JarEntry entry; Enumeration enm; // already cached? result = getCache(cls, pkgname); if (result == null) { result = new Vector(); if (VERBOSE) System.out.println( "Searching for '" + cls.getName() + "' in '" + pkgname + "':"); // turn package into path pkgpath = pkgname.replaceAll("\\.", "/"); // 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); // does package exist in this part of the classpath? url = getURL(part, "/" + pkgpath); if (VERBOSE) { if (url == null) System.out.println(" " + pkgpath + " NOT FOUND"); else System.out.println(" " + pkgpath + " FOUND"); } if (url == null) continue; // find classes dir = new File(part + "/" + pkgpath); if (dir.exists()) { files = dir.listFiles(); for (i = 0; i < files.length; i++) { // only class files if ( (!files[i].isFile()) || (!files[i].getName().endsWith(".class")) ) continue; try { classname = pkgname + "." + files[i].getName().replaceAll(".*/", "") .replaceAll("\\.class", ""); result.add(classname); } catch (Exception e) { e.printStackTrace(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -