101 lines
4.0 KiB
Java
101 lines
4.0 KiB
Java
package com.aicheck.parser;
|
||
|
||
import com.github.javaparser.StaticJavaParser;
|
||
import com.github.javaparser.ast.CompilationUnit;
|
||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
||
import com.github.javaparser.ast.body.MethodDeclaration;
|
||
import com.github.javaparser.ast.body.TypeDeclaration;
|
||
import com.github.javaparser.ast.expr.MethodCallExpr;
|
||
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
|
||
|
||
import java.io.IOException;
|
||
import java.nio.charset.StandardCharsets;
|
||
import java.nio.file.Files;
|
||
import java.nio.file.Path;
|
||
import java.util.LinkedHashSet;
|
||
import java.util.Set;
|
||
import java.util.stream.Stream;
|
||
|
||
/**
|
||
* 扫描 Dto→Entity 转换关系:convert 方法返回值、BeanUtils.copyProperties 调用。
|
||
*/
|
||
public class ConversionParser {
|
||
|
||
/** 在类内查找 convert 方法,收集返回 Entity 的类型名 */
|
||
public Set<String> findConvertTargetsInClass(String source, String className) {
|
||
Set<String> entities = new LinkedHashSet<>();
|
||
if (source == null || source.isBlank()) {
|
||
return entities;
|
||
}
|
||
CompilationUnit cu = StaticJavaParser.parse(source);
|
||
for (TypeDeclaration<?> type : cu.getTypes()) {
|
||
if (type instanceof ClassOrInterfaceDeclaration) {
|
||
ClassOrInterfaceDeclaration classDecl = (ClassOrInterfaceDeclaration) type;
|
||
if (!classDecl.getNameAsString().equals(className)) {
|
||
continue;
|
||
}
|
||
for (MethodDeclaration method : classDecl.getMethods()) {
|
||
if (!"convert".equals(method.getNameAsString())) {
|
||
continue;
|
||
}
|
||
String returnType = TypeNameUtils.simpleName(TypeNameUtils.typeToString(method.getType()));
|
||
if (returnType.endsWith("Entity")) {
|
||
entities.add(returnType);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return entities;
|
||
}
|
||
|
||
/** 递归扫描目录,查找 BeanUtils.copyProperties(sourceClass, *Entity) */
|
||
public Set<String> findBeanUtilsTargets(Path rootDir, String sourceClassName) throws IOException {
|
||
Set<String> entities = new LinkedHashSet<>();
|
||
if (!Files.exists(rootDir)) {
|
||
return entities;
|
||
}
|
||
try (Stream<Path> paths = Files.walk(rootDir)) {
|
||
paths.filter(path -> path.toString().endsWith(".java")).forEach(path -> {
|
||
try {
|
||
String source = Files.readString(path, StandardCharsets.UTF_8);
|
||
entities.addAll(scanBeanUtilsInSource(source, sourceClassName));
|
||
} catch (IOException ignored) {
|
||
// 跳过
|
||
}
|
||
});
|
||
}
|
||
return entities;
|
||
}
|
||
|
||
/** 在单文件源码中扫描 BeanUtils.copyProperties 调用 */
|
||
private Set<String> scanBeanUtilsInSource(String source, String sourceClassName) {
|
||
Set<String> entities = new LinkedHashSet<>();
|
||
CompilationUnit cu = StaticJavaParser.parse(source);
|
||
cu.accept(new VoidVisitorAdapter<Void>() {
|
||
@Override
|
||
public void visit(MethodCallExpr call, Void arg) {
|
||
super.visit(call, arg);
|
||
if (!call.getNameAsString().equals("copyProperties")) {
|
||
return;
|
||
}
|
||
if (call.getScope().isEmpty()) {
|
||
return;
|
||
}
|
||
String scope = call.getScope().get().toString();
|
||
if (!scope.endsWith("BeanUtils")) {
|
||
return;
|
||
}
|
||
if (call.getArguments().size() < 2) {
|
||
return;
|
||
}
|
||
String firstArg = TypeNameUtils.simpleName(call.getArguments().get(0).toString());
|
||
String secondArg = TypeNameUtils.simpleName(call.getArguments().get(1).toString());
|
||
if (sourceClassName.equals(firstArg) && secondArg.endsWith("Entity")) {
|
||
entities.add(secondArg);
|
||
}
|
||
}
|
||
}, null);
|
||
return entities;
|
||
}
|
||
}
|