com.github.yoojia.next.utils.ClassFinder Maven / Gradle / Ivy
package com.github.yoojia.next.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
/**
* @author YOOJIA.CHEN ([email protected])
*/
public final class ClassFinder {
private final Logger mLogger = LoggerFactory.getLogger(ClassFinder.class);
private final ArrayList mClasses = new ArrayList<>();
public enum ConsumeResult {
CONSUMED, SKIP
}
public interface Visitor {
ConsumeResult visit(String className) throws Exception;
}
public interface PrepareHandler {
void prepare(String root, T module, Class> hostType, Method method);
}
public void start(){
mClasses.clear();
final long scanTime = System.nanoTime();
final URL url = this.getClass().getResource("/");
// 1. 当前项目下的类文件
try {
final Path base = Paths.get(url.toURI());
mLogger.debug("Searching path: {}", base);
final FileVisitor visitor = new SimpleFileVisitor() {
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attr) throws IOException {
final Path clazz = base.relativize(path);
final String name = clazz.toString();
if (name.endsWith(".class")){
mClasses.add(resolveName(name));
}
return FileVisitResult.CONTINUE;
}
};
Files.walkFileTree(base, visitor);
} catch (Exception e) {
throw new RuntimeException(e);
}
// 2. TODO 扫描 Jar 文件内的 class 文件
TimeAnalysis.log(scanTime, "Scan classes:" + mClasses.size());
}
public void walkClasses(Visitor visitor){
if(mClasses == null) {
throw new IllegalStateException("Cannot walk classes after scanner closed!");
}
final int max = mClasses.size() - 1;
final List deleteRef = new ArrayList<>();
try{
for (int i = 0;i <= max; ++i){
final String item = mClasses.get(i);
if (ConsumeResult.CONSUMED.equals(visitor.visit(item))){
deleteRef.add(item);
}
}
}catch (Throwable e){
throw new RuntimeException(e);
}
mClasses.removeAll(deleteRef);
}
public void clean(){
mClasses.clear();
}
private static String resolveName(String name){
// Not String.replace, String.replace/replaceAll use regex objects
// Here use a simple way: fast and low memory
final List segments = URIs.fastParse(name, File.separator.charAt(0), false);
final StringBuilder ret = new StringBuilder();
for (String seg : segments) {
if(seg.contains(".class")){
ret.append(seg.substring(0, seg.length() - 6)/* 6: .class */);
}else{
ret.append(seg).append('.');
}
}
return ret.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy