修复反射无法获取getParent方法,导致生成的key不正确问题

This commit is contained in:
makejava 2022-07-06 11:24:03 +08:00
parent efcf66bdab
commit b42113f3a2
2 changed files with 72 additions and 3 deletions

View File

@ -3,14 +3,18 @@ package com.sjhy.plugin.dto;
import com.intellij.database.model.DasNamespace;
import com.intellij.database.psi.DbElement;
import com.intellij.database.psi.DbTable;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiClass;
import com.sjhy.plugin.dict.GlobalDict;
import com.sjhy.plugin.entity.TableInfo;
import com.sjhy.plugin.tool.ReflectionUtils;
import lombok.Data;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
/**
* 表格信息设置传输对象
@ -24,7 +28,7 @@ public class TableInfoSettingsDTO {
private Map<String, TableInfoDTO> tableInfoMap;
public TableInfoSettingsDTO() {
this.tableInfoMap = new HashMap<>(16);
this.tableInfoMap = new TreeMap<>();
}
private String generateKey(DbTable dbTable) {
@ -39,9 +43,12 @@ public class TableInfoSettingsDTO {
}
builder.insert(0, name);
try {
Method method = element.getClass().getDeclaredMethod("getParent");
Method method = ReflectionUtils.getDeclaredMethod(element.getClass(), "getParent");
if (method == null) {
break;
}
element = (DbElement) method.invoke(element);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
} catch (IllegalAccessException | InvocationTargetException e) {
break;
}
// 未必所有的数据库都是存在三层例如MySQL就只有两层如果上次层不是Namespace则不再继续获取
@ -101,6 +108,7 @@ public class TableInfoSettingsDTO {
} else if (tableInfo.getPsiClassObj() != null) {
key = generateKey((PsiClass) tableInfo.getPsiClassObj());
} else {
Messages.showInfoMessage(tableInfo.getName() + "表配置信息保存失败", GlobalDict.TITLE_INFO);
return;
}
this.tableInfoMap.put(key, TableInfoDTO.valueOf(tableInfo));

View File

@ -1,7 +1,13 @@
package com.sjhy.plugin.tool;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* 反射工具
@ -25,4 +31,59 @@ public class ReflectionUtils {
}
}
public static Method getDeclaredMethod(Class<?> clazz, String name, Class<?>... parameterTypes) {
Class<?> searchType = clazz;
while (searchType != null) {
Method[] methods = (searchType.isInterface() ? searchType.getMethods() : getDeclaredMethods(searchType));
for (Method method : methods) {
if (!Objects.equals(name, method.getName())) {
continue;
}
if (parameterTypes == null || Arrays.equals(parameterTypes, method.getParameterTypes())) {
return method;
}
}
searchType = searchType.getSuperclass();
}
return null;
}
private static Method[] getDeclaredMethods(Class<?> clazz) {
Method[] result;
try {
Method[] declaredMethods = clazz.getDeclaredMethods();
List<Method> defaultMethods = findConcreteMethodsOnInterfaces(clazz);
if (defaultMethods != null) {
result = new Method[declaredMethods.length + defaultMethods.size()];
System.arraycopy(declaredMethods, 0, result, 0, declaredMethods.length);
int index = declaredMethods.length;
for (Method defaultMethod : defaultMethods) {
result[index] = defaultMethod;
index++;
}
} else {
result = declaredMethods;
}
} catch (Throwable ex) {
throw new IllegalStateException("Failed to introspect Class [" + clazz.getName() +
"] from ClassLoader [" + clazz.getClassLoader() + "]", ex);
}
return result;
}
private static List<Method> findConcreteMethodsOnInterfaces(Class<?> clazz) {
List<Method> result = null;
for (Class<?> ifc : clazz.getInterfaces()) {
for (Method ifcMethod : ifc.getMethods()) {
if (!Modifier.isAbstract(ifcMethod.getModifiers())) {
if (result == null) {
result = new ArrayList<>();
}
result.add(ifcMethod);
}
}
}
return result;
}
}