Class Helper updated. It can search for classes correctly.

This commit is contained in:
Zhen Tang 2013-06-06 17:31:58 +08:00
parent b28129ab97
commit 413441a26a
2 changed files with 116 additions and 108 deletions

View File

@ -1,9 +1,9 @@
package haflow.utility; package haflow.utility;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
@ -14,117 +14,26 @@ import org.springframework.stereotype.Component;
@Component @Component
public class ClassHelper { public class ClassHelper {
private List<String> getClassNameByFile(String packageName,
String filePath, List<String> className,
boolean searchInChildPackage) throws Exception {
List<String> classNames = new ArrayList<String>();
String decodedFilePath = URLDecoder.decode(filePath, "utf-8");
File file = new File(decodedFilePath);
File[] classFiles = file.listFiles();
for (File classFile : classFiles) {
if (classFile.isDirectory()) {
if (searchInChildPackage) {
classNames.addAll(getClassNameByFile(packageName,
classFile.getPath(), classNames,
searchInChildPackage));
}
} else {
String classFilePath = classFile.getPath();
if (classFilePath.endsWith(".class")) {
classFilePath = classFilePath.replace("\\", ".");
classFilePath = classFilePath.replace("/", ".");
classFilePath = classFilePath.substring(
classFilePath.indexOf("classes") + 8,
classFilePath.lastIndexOf("."));
classNames.add(classFilePath);
}
}
}
return classNames;
}
private List<String> getClassNameByJar(String jarPath,
boolean searchInChildPackage) throws Exception {
List<String> classNames = new ArrayList<String>();
String[] jarInfo = jarPath.split("!");
String jarFilePath = jarInfo[0].substring(jarInfo[0].indexOf("/"));
String decodedJarFilePath = URLDecoder.decode(jarFilePath, "utf-8");
String packagePath = jarInfo[1].substring(1);
JarFile jarFile = new JarFile(decodedJarFilePath);
Enumeration<JarEntry> entrys = jarFile.entries();
while (entrys.hasMoreElements()) {
JarEntry jarEntry = entrys.nextElement();
String entryName = jarEntry.getName();
if (entryName.endsWith(".class")) {
if (searchInChildPackage) {
if (entryName.startsWith(packagePath)) {
entryName = entryName.replace("/", ".").substring(0,
entryName.lastIndexOf("."));
classNames.add(entryName);
}
} else {
int index = entryName.lastIndexOf("/");
String entryPath;
if (index != -1) {
entryPath = entryName.substring(0, index);
} else {
entryPath = entryName;
}
if (entryPath.equals(packagePath)) {
entryName = entryName.replace("/", ".").substring(0,
entryName.lastIndexOf("."));
classNames.add(entryName);
}
}
}
}
jarFile.close();
return classNames;
}
private List<String> getClassNameByJars(URL[] jarFiles, String packagePath,
boolean searchInChildPackage) throws Exception {
List<String> classNames = new ArrayList<String>();
if (jarFiles != null) {
for (int i = 0; i < jarFiles.length; i++) {
URL jarFileUrl = jarFiles[i];
String jarFilePath = jarFileUrl.getPath();
if (jarFilePath.endsWith("classes/")) {
continue;
}
String jarPath = jarFilePath + "!/" + packagePath;
classNames.addAll(this.getClassNameByJar(jarPath,
searchInChildPackage));
}
}
return classNames;
}
public List<String> getClassNames(String packageName, public List<String> getClassNames(String packageName,
boolean searchInchildPackage) { boolean searchInChildPackage) {
try { try {
List<String> classNames = null; List<String> classNames = new ArrayList<String>();
ClassLoader classLoader = Thread.currentThread() URLClassLoader classLoader = (URLClassLoader) Thread
.getContextClassLoader(); .currentThread().getContextClassLoader();
String packagePath = packageName.replace(".", "/"); URL[] urls = classLoader.getURLs();
URL packageUrl = classLoader.getResource(packagePath); for (URL url : urls) {
if (packageUrl != null) { if (url.getProtocol().equals("file")) {
String protocol = packageUrl.getProtocol(); File file = new File(url.getFile());
if (protocol.equals("file")) { String root = file.getPath();
classNames = this.getClassNameByFile(packageName, if (file.isDirectory()) {
packageUrl.getPath(), null, searchInchildPackage); classNames.addAll(this.getClassNamesFromDirectory(root,
} else if (protocol.equals("jar")) { packageName, searchInChildPackage, file, true));
classNames = this.getClassNameByJar(packageUrl.getPath(), } else if (file.getName().endsWith(".jar")) {
searchInchildPackage); classNames.addAll(this.getClassNameFromJar(packageName,
} else { searchInChildPackage, file));
classNames = null; }
} }
} else {
classNames = this.getClassNameByJars(
((URLClassLoader) classLoader).getURLs(), packagePath,
searchInchildPackage);
} }
return classNames; return classNames;
} catch (Exception e) { } catch (Exception e) {
@ -133,4 +42,83 @@ public class ClassHelper {
} }
} }
private List<String> getClassNamesFromDirectory(String root,
String packageName, boolean searchInChildPackage, File directory,
boolean continueSearch) {
List<String> classNames = new ArrayList<String>();
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
if (searchInChildPackage || continueSearch) {
boolean needToContinue = continueSearch;
if (file.getPath().endsWith(packageName.replace(".", "/"))) {
needToContinue = needToContinue & false;
}
classNames.addAll(this.getClassNamesFromDirectory(root,
packageName, searchInChildPackage, file,
needToContinue));
}
} else {
if (file.getPath().endsWith(".class")) {
String classFileName = file.getPath().replace(root + "/",
"");
if (classFileName.startsWith(packageName.replace(".", "/"))) {
String className = classFileName.substring(0,
classFileName.length() - ".class".length())
.replace("/", ".");
classNames.add(className);
}
}
}
}
return classNames;
}
private List<String> getClassNameFromJar(String packageName,
boolean searchInChildPackage, File file) {
List<String> classNames = new ArrayList<String>();
JarFile jarFile = null;
try {
jarFile = new JarFile(file);
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String entryName = jarEntry.getName();
if (entryName.endsWith(".class")) {
String packagePath = packageName.replace(".", "/") + "/";
if (searchInChildPackage) {
if (entryName.startsWith(packagePath)) {
entryName = entryName.replace("/", ".").substring(
0, entryName.lastIndexOf("."));
classNames.add(entryName);
}
} else {
int index = entryName.lastIndexOf("/");
String entryPath;
if (index != -1) {
entryPath = entryName.substring(0, index);
} else {
entryPath = entryName;
}
if (entryPath.equals(packagePath)) {
entryName = entryName.replace("/", ".").substring(
0, entryName.lastIndexOf("."));
classNames.add(entryName);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (jarFile != null) {
try {
jarFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return classNames;
}
} }

View File

@ -0,0 +1,20 @@
package haflow.test;
import haflow.utility.ClassHelper;
import org.junit.Test;
import java.util.List;
public class ClassHelperTest {
@Test
public void test() {
ClassHelper classHelper = new ClassHelper();
List<String> classes = classHelper.getClassNames("haflow.module", true);
if (classes != null) {
for (String c : classes) {
System.out.println(c);
}
}
}
}