com.adrninistrator.javacg2.parser.JarEntryPreHandle2Parser Maven / Gradle / Ivy
package com.adrninistrator.javacg2.parser;
import com.adrninistrator.javacg2.common.JavaCG2Constants;
import com.adrninistrator.javacg2.conf.JavaCG2ConfInfo;
import com.adrninistrator.javacg2.dto.classes.ClassExtendsInfo;
import com.adrninistrator.javacg2.dto.method.MethodArgReturnTypes;
import com.adrninistrator.javacg2.spring.UseSpringBeanByAnnotationHandler;
import com.adrninistrator.javacg2.util.JavaCG2ByteCodeUtil;
import com.adrninistrator.javacg2.util.JavaCG2ClassMethodUtil;
import net.lingala.zip4j.io.inputstream.ZipInputStream;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.commons.lang3.ArrayUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author adrninistrator
* @date 2022/9/14
* @description: 解析jar包中的文件,第二次预处理
*/
public class JarEntryPreHandle2Parser extends AbstractJarEntryParser {
private final Set classExtendsSet = new HashSet<>(JavaCG2Constants.SIZE_100);
private Map> classExtendsImplMethodWithArgTypesMap;
private Map> interfaceMethodWithArgTypesMap;
private Map classAndSuperMap;
private Map classExtendsInfoMap;
private Map> childrenClassMap;
private Set interfaceExtendsSet;
private Map> interfaceExtendsInfoMap;
private Map> childrenInterfaceMap;
private Set allClassNameSet;
private final UseSpringBeanByAnnotationHandler useSpringBeanByAnnotationHandler;
public JarEntryPreHandle2Parser(JavaCG2ConfInfo javaCG2ConfInfo, Map jarPathNumMap, UseSpringBeanByAnnotationHandler useSpringBeanByAnnotationHandler) {
super(javaCG2ConfInfo, jarPathNumMap);
this.useSpringBeanByAnnotationHandler = useSpringBeanByAnnotationHandler;
}
@Override
public void init() {
// 获取涉及继承的类
for (Map.Entry entry : classAndSuperMap.entrySet()) {
String superClassName = entry.getValue();
if (JavaCG2ClassMethodUtil.isClassInJdk(superClassName) && !allClassNameSet.contains(superClassName)) {
// 若父类是JDK中的类,且在指定的jar包中未找到,则不添加
continue;
}
String className = entry.getKey();
classExtendsSet.add(className);
classExtendsSet.add(superClassName);
}
}
@Override
protected boolean handleEntry(ZipInputStream zipInputStream, String jarEntryPath) throws IOException {
// 尝试处理jar包中的class文件
tryHandleClassEntry(zipInputStream, jarEntryPath);
// 以上方法返回值不处理
return true;
}
@Override
protected boolean handleClassEntry(JavaClass javaClass, String jarEntryPath) {
if (javaClass.isClass()) {
// 处理类
// 查找涉及继承的类的信息,需要提前执行,使后续处理方法调用时,classExtendsMethodInfoMap的数据是完整的
findClassExtendsInfo(javaClass);
if (javaCG2ConfInfo.isParseMethodCallTypeValue()) {
// 记录类中带有Spring相关注解的字段信息
useSpringBeanByAnnotationHandler.recordClassFieldsWithSpringAnnotation(javaClass);
}
return true;
}
// 处理接口
findInterfaceExtendsInfo(javaClass);
return true;
}
// 查找涉及继承的类的信息
private void findClassExtendsInfo(JavaClass javaClass) {
String className = javaClass.getClassName();
if (!classExtendsSet.contains(className) || classExtendsInfoMap.containsKey(className)) {
// 假如当前类不涉及继承,或当前类已处理过,则不处理
return;
}
String superClassName = javaClass.getSuperclassName();
List childrenClassList = childrenClassMap.computeIfAbsent(superClassName, k -> new ArrayList<>());
childrenClassList.add(className);
classExtendsInfoMap.put(className, new ClassExtendsInfo(javaClass.getAccessFlags(), superClassName));
// 记录类中可能涉及继承的方法
Method[] methods = javaClass.getMethods();
if (ArrayUtils.isNotEmpty(methods)) {
Map methodArgReturnTypesMap = JavaCG2ByteCodeUtil.genExtendsClassMethodWithArgTypes(javaClass.getMethods());
JavaCG2ClassMethodUtil.copyClassMethodMap(classExtendsImplMethodWithArgTypesMap, className, methodArgReturnTypesMap);
}
}
// 查找涉及继承的接口的信息
private void findInterfaceExtendsInfo(JavaClass interfaceClass) {
String interfaceName = interfaceClass.getClassName();
if (interfaceClass.isAnnotation() ||
!interfaceExtendsSet.contains(interfaceName) ||
interfaceExtendsInfoMap.containsKey(interfaceName)) {
// 假如接口为注解,或当前接口不涉及继承,或当前接口已处理过,则不处理
return;
}
String[] superInterfaceNames = interfaceClass.getInterfaceNames();
for (String superInterfaceName : superInterfaceNames) {
List childrenInterfaceList = childrenInterfaceMap.computeIfAbsent(superInterfaceName, k -> new ArrayList<>());
childrenInterfaceList.add(interfaceName);
}
// 记录当前接口的方法信息
Map methodAttributeMap = new HashMap<>();
for (Method method : interfaceClass.getMethods()) {
methodAttributeMap.put(new MethodArgReturnTypes(method.getName(), method.getArgumentTypes(), method.getReturnType()), method.getAccessFlags());
}
interfaceExtendsInfoMap.put(interfaceName, Arrays.asList(superInterfaceNames));
interfaceMethodWithArgTypesMap.put(interfaceName, methodAttributeMap);
}
//
public void setClassExtendsImplMethodWithArgTypesMap(Map> classExtendsImplMethodWithArgTypesMap) {
this.classExtendsImplMethodWithArgTypesMap = classExtendsImplMethodWithArgTypesMap;
}
public void setInterfaceMethodWithArgTypesMap(Map> interfaceMethodWithArgTypesMap) {
this.interfaceMethodWithArgTypesMap = interfaceMethodWithArgTypesMap;
}
public void setClassAndSuperMap(Map classAndSuperMap) {
this.classAndSuperMap = classAndSuperMap;
}
public void setClassExtendsInfoMap(Map classExtendsInfoMap) {
this.classExtendsInfoMap = classExtendsInfoMap;
}
public void setChildrenClassMap(Map> childrenClassMap) {
this.childrenClassMap = childrenClassMap;
}
public void setInterfaceExtendsSet(Set interfaceExtendsSet) {
this.interfaceExtendsSet = interfaceExtendsSet;
}
public void setInterfaceExtendsInfoMap(Map> interfaceExtendsInfoMap) {
this.interfaceExtendsInfoMap = interfaceExtendsInfoMap;
}
public void setChildrenInterfaceMap(Map> childrenInterfaceMap) {
this.childrenInterfaceMap = childrenInterfaceMap;
}
public void setAllClassNameSet(Set allClassNameSet) {
this.allClassNameSet = allClassNameSet;
}
}