package org.test4j.tools.commons; import java.io.File; import java.io.IOException; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import java.util.StringTokenizer; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; import org.test4j.module.Test4JException; /** * * @author darui.wudr * */ @SuppressWarnings({ "rawtypes" }) public class ClazzFinder { /** * 判断应用程序是否运行在IDE容器里 * * @param clazPath * @return */ protected static boolean isAppRunningInIde(String clazPath) { boolean in_ide = false; StringTokenizer tokenizer = new StringTokenizer(clazPath, File.pathSeparator); while (tokenizer.hasMoreTokens()) { String entry = (String) tokenizer.nextToken(); if (entry.endsWith(".jar") == false) { in_ide = true; break; } } return in_ide; } /** * 判断App是否是已jar方式运行的 * * @param clazPath * @return */ protected static boolean isAppRunningInJar(String clazPath) { boolean result = false; StringTokenizer tokenizer = new StringTokenizer(clazPath, File.pathSeparator); if (tokenizer.countTokens() == 1 && clazPath.endsWith(".jar")) { result = true; } return result; } /** * * @param clazPath * @param packPath * @return * @throws IOException */ protected static List<String> findClazzInIdeApp(String clazPath, String packPath) throws IOException { List<String> clazzes = new LinkedList<String>(); StringTokenizer tokenizer = new StringTokenizer(clazPath, File.pathSeparator); while (tokenizer.hasMoreTokens()) { String entry = tokenizer.nextToken(); if (entry.endsWith(".jar")) { clazzes.addAll(findClazzInJarFile(new JarFile(entry), packPath)); } else { clazzes.addAll(findClazzInIdeTarget(entry, packPath)); } } return clazzes; } /** * 获得所有jar包中package下面所有的class * * @param clazPath * @param packPath * @return * @throws IOException */ protected static List<String> findClazzInJarApp(String jarName, String packPath) throws IOException { List<String> clazzes = new LinkedList<String>(); JarFile jarFile = new JarFile(jarName); clazzes.addAll(findClazzInJarFile(jarFile, packPath)); Manifest manifest = jarFile.getManifest(); if (manifest == null) { return clazzes; } String jarClassPath = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH); StringTokenizer tokenizer = new StringTokenizer(jarClassPath, " "); while (tokenizer.hasMoreTokens()) { String jarFileName = (String) tokenizer.nextToken(); clazzes.addAll(findClazzInJarFile(new JarFile(jarFileName), packPath)); } return clazzes; } /** * 在IDE的编译路径中获取packPath下所有的class * * @param target * @param pathPath * @return */ protected static List<String> findClazzInIdeTarget(String target, String packPath) { List<String> clazzes = new LinkedList<String>(); String dir = target + File.separator + packPath.replace('.', File.separatorChar); File directory = new File(dir); String[] classnames = directory.list(); if (classnames == null) { return clazzes; } for (String clazname : classnames) { if (clazname.endsWith(".class") == false) { continue; } String claz = packPath + "." + clazname.substring(0, clazname.indexOf('.')); clazzes.add(claz); } return clazzes; } /** * 获得jar文件中package下面所有的class * * @param aJarFile * @param aPackage * @return */ private static List<String> findClazzInJarFile(JarFile aJarFile, String packPath) { List<String> clazzes = new LinkedList<String>(); Enumeration<JarEntry> jarEntries = aJarFile.entries(); String pack = ClazzFinder.pathReplace(packPath); while (jarEntries.hasMoreElements()) { String clazName = jarEntries.nextElement().getName(); int index = clazName.lastIndexOf(".class"); if (index == -1 || index != clazName.length() - 6) { continue; } clazName = ClazzFinder.pathReplace(clazName.substring(0, index)); index = clazName.lastIndexOf("."); String packName = ""; if (index != -1) { packName = clazName.substring(0, index); } if (packName.equals(pack)) { clazzes.add(clazName); } } return clazzes; } /** * 替换路径中所有的/\为. * * @param path * @return */ protected static String pathReplace(String path) { return path.replace('/', '.').replace('\\', '.'); } /** * 获得packPath路径下所有的class * * @param packPath * @return */ public static final String SUN_BOOT_PATH = "sun.boot.class.path"; public static final String JAVA_EXT_DIRS = "java.ext.dirs"; public static final String JAVA_CLASS_PATH = "java.class.path"; public static List<String> findClazz(String packPath) { String classPath = System.getProperty(JAVA_CLASS_PATH); boolean runInIDE = ClazzFinder.isAppRunningInIde(classPath); try { List<String> clazzes = null; if (runInIDE) { clazzes = ClazzFinder.findClazzInIdeApp(classPath, packPath); } else { clazzes = ClazzFinder.findClazzInJarApp(classPath, packPath); } return clazzes; } catch (Throwable e) { String error = String.format("RunInIDE : %s , classpath : %s", String.valueOf(runInIDE), classPath); throw new Test4JException(error, e); } } /** * 获得的与claz的package相同的所有class * * @param claz * @return */ public static List<String> findClazz(Class claz) { String pack = ""; Package _package = claz.getPackage(); if (_package != null) { pack = _package.getName(); } return ClazzFinder.findClazz(pack); } /** * 获得class的package路径 * * @param claz * @return */ public static String finePackageDir(Class claz) { String pack = ""; Package _package = claz.getPackage(); if (_package != null) { pack = _package.getName(); } return pack.replaceAll("\\.", "/"); } }