Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.adrninistrator.javacg.handler.ExtendsImplHandler Maven / Gradle / Ivy
package com.adrninistrator.javacg.handler;
import com.adrninistrator.javacg.common.JavaCGConstants;
import com.adrninistrator.javacg.common.enums.JavaCGCallTypeEnum;
import com.adrninistrator.javacg.comparator.MethodArgReturnTypesComparator;
import com.adrninistrator.javacg.conf.JavaCGConfInfo;
import com.adrninistrator.javacg.dto.access_flag.JavaCGAccessFlags;
import com.adrninistrator.javacg.dto.call.MethodCall;
import com.adrninistrator.javacg.dto.classes.ClassExtendsMethodInfo;
import com.adrninistrator.javacg.dto.classes.ClassImplementsMethodInfo;
import com.adrninistrator.javacg.dto.classes.Node4ClassExtendsMethod;
import com.adrninistrator.javacg.dto.counter.JavaCGCounter;
import com.adrninistrator.javacg.dto.interfaces.InterfaceExtendsMethodInfo;
import com.adrninistrator.javacg.dto.jar.ClassAndJarNum;
import com.adrninistrator.javacg.dto.method.MethodArgReturnTypes;
import com.adrninistrator.javacg.dto.stack.ListAsStack;
import com.adrninistrator.javacg.util.JavaCGByteCodeUtil;
import com.adrninistrator.javacg.util.JavaCGFileUtil;
import com.adrninistrator.javacg.util.JavaCGLogUtil;
import com.adrninistrator.javacg.util.JavaCGUtil;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author adrninistrator
* @date 2022/11/13
* @description: 继承及实现相关的方法处理类
*/
public class ExtendsImplHandler {
private JavaCGConfInfo javaCGConfInfo;
private JavaCGCounter callIdCounter;
private Map> interfaceMethodWithArgsMap;
private Map> childrenClassMap;
private Map interfaceExtendsMethodInfoMap;
private Map> childrenInterfaceMap;
private Map classImplementsMethodInfoMap;
private Map classExtendsMethodInfoMap;
private ClassAndJarNum classAndJarNum;
public void handle(Writer methodCallWriter) throws IOException {
// 将父接口中的方法添加到子接口中
addSuperInterfaceMethod4ChildrenInterface(methodCallWriter);
// 将接口中的抽象方法添加到抽象父类中
addInterfaceMethod4SuperAbstractClass();
// 记录父类调用子类方法,及子类调用父类方法
recordClassExtendsMethod(methodCallWriter);
// 记录接口调用实现类方法
recordInterfaceCallClassMethod(methodCallWriter);
}
// 将父接口中的方法添加到子接口中
private void addSuperInterfaceMethod4ChildrenInterface(Writer methodCallWriter) throws IOException {
// 查找顶层父接口
Set topSuperInterfaceSet = new HashSet<>();
for (Map.Entry entry : interfaceExtendsMethodInfoMap.entrySet()) {
InterfaceExtendsMethodInfo interfaceExtendsMethodInfo = entry.getValue();
for (String superInterface : interfaceExtendsMethodInfo.getSuperInterfaceList()) {
InterfaceExtendsMethodInfo superInterfaceExtendsMethodInfo = interfaceExtendsMethodInfoMap.get(superInterface);
if (superInterfaceExtendsMethodInfo == null || superInterfaceExtendsMethodInfo.getSuperInterfaceList().isEmpty()) {
// 父接口在接口涉及继承的信息Map中不存在记录,或父接口列表为空,说明当前为顶层父接口
if (!topSuperInterfaceSet.add(superInterface)) {
continue;
}
if (JavaCGLogUtil.isDebugPrintFlag()) {
JavaCGLogUtil.debugPrint("处理一个顶层父接口: " + superInterface);
}
}
}
}
List topSuperInterfaceSetList = new ArrayList<>(topSuperInterfaceSet);
// 对顶层父接口类名排序
Collections.sort(topSuperInterfaceSetList);
for (String topSuperInterface : topSuperInterfaceSetList) {
// 遍历顶层父接口并处理
handleOneSuperInterface(topSuperInterface, methodCallWriter);
}
}
// 处理一个父接口
private void handleOneSuperInterface(String superInterface, Writer methodCallWriter) throws IOException {
List childrenInterfaceList = childrenInterfaceMap.get(superInterface);
if (childrenInterfaceList == null) {
return;
}
for (String childrenInterface : childrenInterfaceList) {
// 处理父接口及一个子接口
handleSuperAndChildInterface(superInterface, childrenInterface, methodCallWriter);
// 继续处理子接口
handleOneSuperInterface(childrenInterface, methodCallWriter);
}
}
// 处理父接口及一个子接口
private void handleSuperAndChildInterface(String superInterface, String childInterface, Writer methodCallWriter) throws IOException {
InterfaceExtendsMethodInfo superInterfaceExtendsMethodInfo = interfaceExtendsMethodInfoMap.get(superInterface);
if (superInterfaceExtendsMethodInfo == null) {
// 父接口在接口涉及继承的信息Map中不存在记录时,不处理
return;
}
InterfaceExtendsMethodInfo childInterfaceExtendsMethodInfo = interfaceExtendsMethodInfoMap.get(childInterface);
List superInterfaceMethodAndArgsList = superInterfaceExtendsMethodInfo.getMethodAndArgsList();
// 对父接口中的方法进行排序
superInterfaceMethodAndArgsList.sort(MethodArgReturnTypesComparator.getInstance());
// 遍历父接口中的方法
for (MethodArgReturnTypes superMethodAndArgs : superInterfaceMethodAndArgsList) {
List childInterfaceMethodAndArgsList = childInterfaceExtendsMethodInfo.getMethodAndArgsList();
if (childInterfaceMethodAndArgsList.contains(superMethodAndArgs)) {
// 子接口中已包含父接口,跳过
continue;
}
// 在子接口中添加父接口的方法(涉及继承的接口相关结构)
childInterfaceMethodAndArgsList.add(superMethodAndArgs);
// 在子接口中添加父接口的方法(所有接口都需要记录的结构)
List childInterfaceMethodAndArgsListAll = interfaceMethodWithArgsMap.computeIfAbsent(childInterface, k -> new ArrayList<>());
childInterfaceMethodAndArgsListAll.add(superMethodAndArgs);
// 添加子接口调用父接口方法
addExtraMethodCall(methodCallWriter, childInterface, superMethodAndArgs.getMethodName(), superMethodAndArgs.getMethodArgTypes(),
superMethodAndArgs.getMethodReturnType(), JavaCGCallTypeEnum.CTE_CHILD_CALL_SUPER_INTERFACE, superInterface, superMethodAndArgs.getMethodName(),
superMethodAndArgs.getMethodArgTypes(), superMethodAndArgs.getMethodReturnType()
);
}
}
// 将接口中的抽象方法加到抽象父类中
private void addInterfaceMethod4SuperAbstractClass() {
for (Map.Entry> childrenClassEntry : childrenClassMap.entrySet()) {
String superClassName = childrenClassEntry.getKey();
ClassExtendsMethodInfo classExtendsMethodInfo = classExtendsMethodInfoMap.get(superClassName);
if (classExtendsMethodInfo == null || !JavaCGByteCodeUtil.isAbstractFlag(classExtendsMethodInfo.getAccessFlags())) {
/*
为空的情况,对应其他jar包中的Class可以找到,但是找不到它们的方法,是正常的,不处理
若不是抽象类则不处理
*/
continue;
}
ClassImplementsMethodInfo classImplementsMethodInfo = classImplementsMethodInfoMap.get(superClassName);
if (classImplementsMethodInfo == null) {
continue;
}
Map methodWithArgsMap = classExtendsMethodInfo.getMethodWithArgsMap();
int accessFlags = 0;
accessFlags = JavaCGByteCodeUtil.setAbstractFlag(accessFlags, true);
accessFlags = JavaCGByteCodeUtil.setPublicFlag(accessFlags, true);
accessFlags = JavaCGByteCodeUtil.setProtectedFlag(accessFlags, false);
// 将接口中的抽象方法加到抽象父类中
for (String interfaceName : classImplementsMethodInfo.getInterfaceNameList()) {
List interfaceMethodWithArgsList = interfaceMethodWithArgsMap.get(interfaceName);
if (interfaceMethodWithArgsList == null) {
continue;
}
for (MethodArgReturnTypes interfaceMethodWithArgs : interfaceMethodWithArgsList) {
// 添加时不覆盖现有的值
methodWithArgsMap.putIfAbsent(interfaceMethodWithArgs, accessFlags);
}
}
}
}
// 记录父类调用子类方法,及子类调用父类方法
private void recordClassExtendsMethod(Writer methodCallWriter) throws IOException {
Set topSuperClassNameSet = new HashSet<>();
// 得到最顶层父类名称
for (Map.Entry classExtendsMethodInfoEntry : classExtendsMethodInfoMap.entrySet()) {
String className = classExtendsMethodInfoEntry.getKey();
ClassExtendsMethodInfo classExtendsMethodInfo = classExtendsMethodInfoEntry.getValue();
String superClassName = classExtendsMethodInfo.getSuperClassName();
if (JavaCGUtil.isClassInJdk(superClassName)) {
topSuperClassNameSet.add(className);
}
}
List topSuperClassNameList = new ArrayList<>(topSuperClassNameSet);
// 对顶层父类类名排序
Collections.sort(topSuperClassNameList);
for (String topSuperClassName : topSuperClassNameList) {
// 处理一个顶层父类
handleOneTopSuperClass(topSuperClassName, methodCallWriter);
}
}
// 处理一个顶层父类
private void handleOneTopSuperClass(String topSuperClassName, Writer methodCallWriter) throws IOException {
if (JavaCGLogUtil.isDebugPrintFlag()) {
JavaCGLogUtil.debugPrint("处理一个顶层父类: " + topSuperClassName);
}
ListAsStack nodeStack = new ListAsStack<>();
// 初始化节点列表
Node4ClassExtendsMethod topNode = new Node4ClassExtendsMethod(topSuperClassName, JavaCGConstants.EXTENDS_NODE_INDEX_INIT);
nodeStack.push(topNode);
// 开始循环
while (true) {
Node4ClassExtendsMethod currentNode = nodeStack.peek();
List childrenClassList = childrenClassMap.get(currentNode.getSuperClassName());
if (childrenClassList == null) {
System.err.println("### 未找到顶层父类的子类: " + currentNode.getSuperClassName());
return;
}
// 对子类类名排序
Collections.sort(childrenClassList);
int currentChildClassIndex = currentNode.getChildClassIndex() + 1;
if (currentChildClassIndex >= childrenClassList.size()) {
if (nodeStack.atBottom()) {
return;
}
// 删除栈顶元素
nodeStack.removeTop();
continue;
}
// 处理当前的子类
String childClassName = childrenClassList.get(currentChildClassIndex);
// 处理父类和子类的方法调用
handleSuperAndChildClass(currentNode.getSuperClassName(), childClassName, methodCallWriter);
// 处理下一个子类
currentNode.setChildClassIndex(currentChildClassIndex);
List nextChildClassList = childrenClassMap.get(childClassName);
if (nextChildClassList == null) {
// 当前的子类下没有子类
continue;
}
// 当前的子类下有子类
// 入栈
Node4ClassExtendsMethod nextNode = new Node4ClassExtendsMethod(childClassName, JavaCGConstants.EXTENDS_NODE_INDEX_INIT);
nodeStack.push(nextNode);
}
}
// 处理父类和子类的方法调用
private void handleSuperAndChildClass(String superClassName, String childClassName, Writer methodCallWriter) throws IOException {
ClassExtendsMethodInfo superClassMethodInfo = classExtendsMethodInfoMap.get(superClassName);
if (superClassMethodInfo == null) {
System.err.println("### 未找到父类信息: " + superClassName);
return;
}
ClassExtendsMethodInfo childClassMethodInfo = classExtendsMethodInfoMap.get(childClassName);
if (childClassMethodInfo == null) {
System.err.println("### 未找到子类信息: " + childClassName);
return;
}
Map superMethodWithArgsMap = superClassMethodInfo.getMethodWithArgsMap();
Map childMethodWithArgsMap = childClassMethodInfo.getMethodWithArgsMap();
List superMethodAndArgsList = new ArrayList<>(superMethodWithArgsMap.keySet());
// 对父类方法进行排序
superMethodAndArgsList.sort(MethodArgReturnTypesComparator.getInstance());
// 遍历父类方法
for (MethodArgReturnTypes superMethodWithArgs : superMethodAndArgsList) {
Integer superMethodAccessFlags = superMethodWithArgsMap.get(superMethodWithArgs);
if (JavaCGByteCodeUtil.isAbstractFlag(superMethodAccessFlags)) {
// 处理父类抽象方法
// 添加时不覆盖现有的值
childMethodWithArgsMap.putIfAbsent(superMethodWithArgs, superMethodAccessFlags);
// 添加父类调用子类的方法调用
addExtraMethodCall(methodCallWriter, superClassName, superMethodWithArgs.getMethodName(), superMethodWithArgs.getMethodArgTypes(),
superMethodWithArgs.getMethodReturnType(), JavaCGCallTypeEnum.CTE_SUPER_CALL_CHILD, childClassName, superMethodWithArgs.getMethodName(),
superMethodWithArgs.getMethodArgTypes(), superMethodWithArgs.getMethodReturnType());
continue;
}
if (JavaCGByteCodeUtil.isPublicFlag(superMethodAccessFlags)
|| JavaCGByteCodeUtil.isProtectedMethod(superMethodAccessFlags)
|| (!JavaCGByteCodeUtil.isPrivateMethod(superMethodAccessFlags)
&& JavaCGUtil.checkSamePackage(superClassName, childClassName))
) {
/*
对于父类中满足以下条件的非抽象方法进行处理:
public
或protected
或非public非protected非private且父类与子类在同一个包
*/
if (childMethodWithArgsMap.get(superMethodWithArgs) != null) {
// 若当前方法已经处理过则跳过
continue;
}
childMethodWithArgsMap.put(superMethodWithArgs, superMethodAccessFlags);
// 添加子类调用父类方法
addExtraMethodCall(methodCallWriter, childClassName, superMethodWithArgs.getMethodName(), superMethodWithArgs.getMethodArgTypes(),
superMethodWithArgs.getMethodReturnType(), JavaCGCallTypeEnum.CTE_CHILD_CALL_SUPER, superClassName, superMethodWithArgs.getMethodName(),
superMethodWithArgs.getMethodArgTypes(), superMethodWithArgs.getMethodReturnType());
}
}
}
// 记录接口调用实现类方法
private void recordInterfaceCallClassMethod(Writer methodCallWriter) throws IOException {
if (classImplementsMethodInfoMap.isEmpty() || interfaceMethodWithArgsMap.isEmpty()) {
return;
}
List classNameList = new ArrayList<>(classImplementsMethodInfoMap.keySet());
// 对类名进行排序
Collections.sort(classNameList);
// 对类名进行遍历
for (String className : classNameList) {
ClassImplementsMethodInfo classImplementsMethodInfo = classImplementsMethodInfoMap.get(className);
List interfaceNameList = classImplementsMethodInfo.getInterfaceNameList();
// 对实现的接口进行排序
Collections.sort(interfaceNameList);
// 找到在接口和实现类中都存在的方法
for (String interfaceName : interfaceNameList) {
List interfaceMethodWithArgsList = interfaceMethodWithArgsMap.get(interfaceName);
if (JavaCGUtil.isCollectionEmpty(interfaceMethodWithArgsList)) {
continue;
}
List methodWithArgsList = classImplementsMethodInfo.getMethodWithArgsList();
// 在处理接口调用实现类方法时,将父类中定义的可能涉及实现的方法添加到当前类的方法中
addSuperMethod2ImplClass(methodWithArgsList, className);
// 对方法进行排序
methodWithArgsList.sort(MethodArgReturnTypesComparator.getInstance());
// 对方法进行遍历
for (MethodArgReturnTypes methodWithArgs : methodWithArgsList) {
if (!interfaceMethodWithArgsList.contains(methodWithArgs)) {
// 接口中不包含的方法,跳过
continue;
}
// 添加接口调用实现类方法
addExtraMethodCall(methodCallWriter, interfaceName, methodWithArgs.getMethodName(), methodWithArgs.getMethodArgTypes(), methodWithArgs.getMethodReturnType(),
JavaCGCallTypeEnum.CTE_INTERFACE_CALL_IMPL_CLASS, className, methodWithArgs.getMethodName(), methodWithArgs.getMethodArgTypes(),
methodWithArgs.getMethodReturnType());
}
}
}
}
/**
* 在处理接口调用实现类方法时,将父类中定义的可能涉及实现的方法添加到当前类的方法中
*
* @param methodWithArgsList 当前类中定义的方法
* @param className
*/
private void addSuperMethod2ImplClass(List methodWithArgsList, String className) {
// 获取当前处理的实现类涉及继承的信息
ClassExtendsMethodInfo classExtendsMethodInfo = classExtendsMethodInfoMap.get(className);
if (classExtendsMethodInfo == null) {
return;
}
// 获取当前处理的实现类中的方法信息
Map methodWithArgsMap = classExtendsMethodInfo.getMethodWithArgsMap();
if (methodWithArgsMap == null) {
return;
}
for (Map.Entry entry : methodWithArgsMap.entrySet()) {
MethodArgReturnTypes methodAndArgs = entry.getKey();
if (methodWithArgsList.contains(methodAndArgs)) {
// 已包含的方法,跳过
continue;
}
String methodName = methodAndArgs.getMethodName();
JavaCGAccessFlags methodAccessFlags = new JavaCGAccessFlags(entry.getValue());
if (JavaCGByteCodeUtil.checkImplMethod(methodName, methodAccessFlags)) {
// 将父类中定义的,可能涉及实现的方法添加到当前类的方法中
methodWithArgsList.add(methodAndArgs);
}
}
}
// 添加额外的方法调用关系
private void addExtraMethodCall(Writer methodCallWriter,
String callerClassName,
String callerMethodName,
String callerMethodArgs,
String callerMethodReturnType,
JavaCGCallTypeEnum methodCallType,
String calleeClassName,
String calleeMethodName,
String calleeMethodArgs,
String calleeMethodReturnType) throws IOException {
if (JavaCGUtil.checkSkipClass(callerClassName, javaCGConfInfo.getNeedHandlePackageSet()) ||
JavaCGUtil.checkSkipClass(calleeClassName, javaCGConfInfo.getNeedHandlePackageSet())) {
return;
}
String callerClassJarNum = classAndJarNum.getJarNum(callerClassName);
String calleeClassJarNum = classAndJarNum.getJarNum(calleeClassName);
MethodCall methodCall = new MethodCall(
callIdCounter.addAndGet(),
callerClassName,
callerMethodName,
callerMethodArgs,
callerMethodReturnType,
methodCallType,
calleeClassName,
calleeMethodName,
calleeMethodArgs,
JavaCGConstants.DEFAULT_LINE_NUMBER,
null,
calleeMethodReturnType,
null
);
JavaCGFileUtil.write2FileWithTab(methodCallWriter, methodCall.genCallContent(callerClassJarNum, calleeClassJarNum));
}
//
public void setJavaCGConfInfo(JavaCGConfInfo javaCGConfInfo) {
this.javaCGConfInfo = javaCGConfInfo;
}
public void setCallIdCounter(JavaCGCounter callIdCounter) {
this.callIdCounter = callIdCounter;
}
public void setInterfaceMethodWithArgsMap(Map> interfaceMethodWithArgsMap) {
this.interfaceMethodWithArgsMap = interfaceMethodWithArgsMap;
}
public void setChildrenClassMap(Map> childrenClassMap) {
this.childrenClassMap = childrenClassMap;
}
public void setInterfaceExtendsMethodInfoMap(Map interfaceExtendsMethodInfoMap) {
this.interfaceExtendsMethodInfoMap = interfaceExtendsMethodInfoMap;
}
public void setChildrenInterfaceMap(Map> childrenInterfaceMap) {
this.childrenInterfaceMap = childrenInterfaceMap;
}
public void setClassImplementsMethodInfoMap(Map classImplementsMethodInfoMap) {
this.classImplementsMethodInfoMap = classImplementsMethodInfoMap;
}
public void setClassExtendsMethodInfoMap(Map classExtendsMethodInfoMap) {
this.classExtendsMethodInfoMap = classExtendsMethodInfoMap;
}
public void setClassAndJarNum(ClassAndJarNum classAndJarNum) {
this.classAndJarNum = classAndJarNum;
}
}