package jef.tools;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import jef.tools.reflect.ClassLoaderUtil;
import jef.tools.resource.IResource;
/**
* 扫描指定包(包括jar)下的class文件 <br>
*
* @author jiyi
*/
public class ClassScanner {
/**
* 是否排除内部类
*/
private boolean excludeInnerClass = true;
/**
* class path根路径,如果不指定那么就在所有ClassPath下寻找
*
* @return
*/
private URL rootClasspath;
public boolean isExcludeInnerClass() {
return excludeInnerClass;
}
public ClassScanner excludeInnerClass(boolean excludeInnerClass) {
this.excludeInnerClass = excludeInnerClass;
return this;
}
public ClassScanner rootClasspath(URL rootClasspath) {
this.rootClasspath = rootClasspath;
return this;
}
/**
* 扫描包
*
* @param basePackage
* 基础包
* @param recursive
* 是否递归搜索子包
* @return Set
*/
public IResource[] scan(String... packages) {
URLClassLoader cl = rootClasspath == null ? null : new URLClassLoader(new URL[] { rootClasspath });
if(packages.length==0){
packages=new String[]{""};
}
List<IResource> result = new ArrayList<IResource>();
for (String packageName : packages) {
if(packageName==null){
continue;
}
String keystr;
if(StringUtils.isBlank(packageName)){
keystr="classpath*:"+ "**/*.class";
return ResourceUtils.findResources(cl,keystr);
}
keystr="classpath*:"+ packageName.replace('.', '/') + "/*.class";
IResource[] res = ResourceUtils.findResources(cl,keystr);
if(packages.length==1){
return res;
}
result.addAll(Arrays.asList(res));
}
return result.toArray(new IResource[result.size()]);
}
/**
* 用相同类的一个已经加载的类来设置要搜索的classpath
*
* @param rootCls
*/
public void setRootBySameUrlClass(Class<?> rootCls) {
if (rootCls == null)
return;
this.rootClasspath = ClassLoaderUtil.getCodeSource(rootCls);
if (rootClasspath == null)
rootClasspath = rootCls.getResource("/");
}
public static IResource[] listClassNameInPackage(Class<?> rootCls, String[] pkgNames, boolean includeInner) {
ClassScanner cs = new ClassScanner().excludeInnerClass(!includeInner);
cs.setRootBySameUrlClass(rootCls);
return cs.scan(pkgNames);
}
public static IResource[] listClassNameInPackage(File root, String[] pkgNames, boolean includeInner) {
ClassScanner cs=new ClassScanner().excludeInnerClass(!includeInner);
try {
cs.rootClasspath(root.toURI().toURL());
} catch (MalformedURLException e) {
throw new RuntimeException(e.getMessage());
}
return cs.scan(pkgNames);
}
}