/* * This file is part of the Wildfire Chat package. * (c) Heavyrain2012 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ package com.xiaoleilu.loServer.action; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class ClassUtil { /** * 获取同一路径下所有子类或接口实现类 * * @param cls * @return * @throws IOException * @throws ClassNotFoundException */ public static List> getAllAssignedClass(Class cls) throws IOException, ClassNotFoundException { List> classes = new ArrayList>(); for (Class c : getClasses(cls)) { if (cls.isAssignableFrom(c) && !cls.equals(c)) { classes.add(c); } } return classes; } /** * 取得当前类路径下的所有类 * * @param cls * @return * @throws IOException * @throws ClassNotFoundException */ public static List> getClasses(Class cls) throws IOException, ClassNotFoundException { String pk = cls.getPackage().getName(); // String path = pk.replace('.', '/'); // ClassLoader classloader = Thread.currentThread().getContextClassLoader(); // URL url = classloader.getResource(path); // String type = url.getProtocol(); // // System.out.println("the type is " + type); // System.out.println(url.getPath()); // // return getClasses(new File(url.getFile()), pk); List classNames = getClassName(pk, true); List> classes = new ArrayList<>(); for (String className : classNames) { if (className.endsWith(".class")) { className = className.substring(0, className.length() - 6); className = className.substring(className.lastIndexOf("/")+1, className.length()); } classes.add(Class.forName(className)); } return classes; } /** * 迭代查找类 * * @param dir * @param pk * @return * @throws ClassNotFoundException */ private static List> getClasses(File dir, String pk) throws ClassNotFoundException { System.out.println(dir.getAbsolutePath()); List> classes = new ArrayList>(); if (!dir.exists()) { return classes; } for (File f : dir.listFiles()) { if (f.isDirectory()) { classes.addAll(getClasses(f, pk + "." + f.getName())); } String name = f.getName(); if (name.endsWith(".class")) { classes.add(Class.forName(pk + "." + name.substring(0, name.length() - 6))); } } return classes; } /** * 获取某包下所有类 * @param packageName 包名 * @param childPackage 是否遍历子包 * @return 类的完整名称 */ public static List getClassName(String packageName, boolean childPackage) { List fileNames = null; ClassLoader loader = Thread.currentThread().getContextClassLoader(); String packagePath = packageName.replace(".", "/"); URL url = loader.getResource(packagePath); if (url != null) { String type = url.getProtocol(); if (type.equals("file")) { fileNames = getClassNameByFile(url.getPath(), null, childPackage); } else if (type.equals("jar")) { fileNames = getClassNameByJar(url.getPath(), childPackage); } } else { fileNames = getClassNameByJars(((URLClassLoader) loader).getURLs(), packagePath, childPackage); } return fileNames; } /** * 从项目文件获取某包下所有类 * @param filePath 文件路径 * @param className 类名集合 * @param childPackage 是否遍历子包 * @return 类的完整名称 */ private static List getClassNameByFile(String filePath, List className, boolean childPackage) { List myClassName = new ArrayList(); File file = new File(filePath); File[] childFiles = file.listFiles(); for (File childFile : childFiles) { if (childFile.isDirectory()) { if (childPackage) { myClassName.addAll(getClassNameByFile(childFile.getPath(), myClassName, childPackage)); } } else { String childFilePath = childFile.getPath(); if (childFilePath.endsWith(".class")) { if (childFilePath.indexOf("\\classes") >= 0 || childFilePath.indexOf("/classes") >= 0) { int start = childFilePath.indexOf("\\classes"); if (start == -1) { start = childFilePath.indexOf("/classes"); } childFilePath = childFilePath.substring(start + 9, childFilePath.lastIndexOf(".")); } childFilePath = childFilePath.replace("\\", "."); childFilePath = childFilePath.replace("/", "."); myClassName.add(childFilePath); } } } return myClassName; } /** * 从jar获取某包下所有类 * @param jarPath jar文件路径 * @param childPackage 是否遍历子包 * @return 类的完整名称 */ private static List getClassNameByJar(String jarPath, boolean childPackage) { List myClassName = new ArrayList(); String[] jarInfo = jarPath.split("!"); String jarFilePath = jarInfo[0].substring(jarInfo[0].indexOf("/")); String packagePath = jarInfo[1].substring(1); try { JarFile jarFile = new JarFile(jarFilePath); Enumeration entrys = jarFile.entries(); while (entrys.hasMoreElements()) { JarEntry jarEntry = entrys.nextElement(); String entryName = jarEntry.getName(); if (entryName.endsWith(".class")) { if (childPackage) { if (entryName.startsWith(packagePath)) { entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf(".")); myClassName.add(entryName); } } else { int index = entryName.lastIndexOf("/"); String myPackagePath; if (index != -1) { myPackagePath = entryName.substring(0, index); } else { myPackagePath = entryName; } if (myPackagePath.equals(packagePath)) { entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf(".")); myClassName.add(entryName); } } } } } catch (Exception e) { e.printStackTrace(); } return myClassName; } /** * 从所有jar中搜索该包,并获取该包下所有类 * @param urls URL集合 * @param packagePath 包路径 * @param childPackage 是否遍历子包 * @return 类的完整名称 */ private static List getClassNameByJars(URL[] urls, String packagePath, boolean childPackage) { List myClassName = new ArrayList(); if (urls != null) { for (int i = 0; i < urls.length; i++) { URL url = urls[i]; String urlPath = url.getPath(); // 不必搜索classes文件夹 if (urlPath.endsWith("classes/")) { continue; } String jarPath = urlPath + "!/" + packagePath; myClassName.addAll(getClassNameByJar(jarPath, childPackage)); } } return myClassName; } }