主要思路:
1.从gitlab上下载contract源码,使用org.eclipse.jgit
2.mvn编译并把生成的jar和依赖的jar拷贝到指定目录下,使用org.apache.maven.shared maven-invoker
3.扫描源码列出所有以I开头,以.java结尾的文件绝对路径getCanonicalPath()
4.根据第三步的文件绝对路径,切割转换出className,package+文件名
5.Class获取Method,解析每个method,java基本类型需要转换为class类的名称
MethodEntity.java
public class MethodEntity {
// 接口类名,例如:IZZHaHaService
private String interfaceClassName;
// 接口类名,包含package信息,例如:com.bj58.zhuanzhuan.IZZHaHaService
private String interfaceClassFullName;
private String methodName;
// 入参类型的完整名称,按照入参顺序排列,例如:java.util.List<com.bj58.zhuanzhuan.entity.ViViEntity>
private List<String> paramterTypeCanonicalNames;
// 入参类型名称,按照入参顺序排列,例如:List
private List<String> paramterTypeNames;
/**
* 根据函数名和入参的类型及名称,判断当前实例是否是要找的
*
* @param methodName
* 不为空
* @param paramNames
* 参数类型列表
* @param interfaceName
* 接口类名,传null不做比对
* @return True or False
*/
public Boolean isSeached(String methodName, List<String> paramNames, String interfaceName) {
if (interfaceName != null) {
if (!interfaceName.equals(this.interfaceClassName)) {
return Boolean.FALSE;
}
}
if (methodName == null) {
return Boolean.FALSE;
}
if (paramNames == null && getParamterTypeNames() == null) {
return Boolean.TRUE;
}
if ((paramNames == null && getParamterTypeNames() != null)
|| paramNames != null && getParamterTypeNames() == null
|| paramNames.size() != getParamterTypeNames().size()) {
return Boolean.FALSE;
}
if (methodName.equals(getMethodName())) {
return paramNames.equals(getParamterTypeNames());
} else {
return Boolean.FALSE;
}
}
public String getInterfaceClassFullName() {
return interfaceClassFullName;
}
public void setInterfaceClassFullName(String interfaceClassFullName) {
this.interfaceClassFullName = interfaceClassFullName;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public List<String> getParamterTypeCanonicalNames() {
return paramterTypeCanonicalNames;
}
public void setParamterTypeCanonicalNames(List<String> paramterTypeCanonicalNames) {
this.paramterTypeCanonicalNames = paramterTypeCanonicalNames;
}
public List<String> getParamterTypeNames() {
return paramterTypeNames;
}
public void setParamterTypeNames(List<String> paramterTypeNames) {
this.paramterTypeNames = paramterTypeNames;
}
public String getInterfaceClassName() {
return interfaceClassName;
}
public void setInterfaceClassName(String interfaceClassName) {
this.interfaceClassName = interfaceClassName;
}
}
扫包,获取所有的可调用方法
// java基本数据类型和对应的类
private static Map<String, String> basicDataTypeReference = new HashMap<String, String>() {
private static final long serialVersionUID = 4477784757087366211L;
{
// 九种基本类型
// java.lang.Boolean
// java.lang.Character
// java.lang.Byte
// java.lang.Short
// java.lang.Integer
// java.lang.Long
// java.lang.Float
// java.lang.Double
// java.lang.Void
put("boolean", "java.lang.Boolean");
put("char", "java.lang.Character");
put("byte", "java.lang.Byte");
put("short", "java.lang.Short");
put("int", "java.lang.Integer");
put("long", "java.lang.Long");
put("float", "java.lang.Float");
put("double", "java.lang.Double");
}
};
/**
* 扫码contract目录下的所有接口文件
*
* @param serviceName
* 服务名,例如zzpost
* @throws Exception
*/
public void scanContractFiles(String serviceName) throws Exception {
// 拿到所有以.java结尾的文件
Collection<File> sourceFiles = FileUtils.listFiles(file, new WildcardFileFilter("I*.java"),TrueFileFilter.INSTANCE);
for (File f : sourceFiles) {
String canonicalPath = f.getCanonicalPath();
String fileName = f.getName();
// D:\aaa\com\bj58\zhuanzhuan\IHaHaService.java
// 以com开始不要最后的.java com.bj58.zhuanzhuan.IHaHaService
String clazzPath = canonicalPath.substring(canonicalPath.indexOf("com"), canonicalPath.length() - 5)
.replace("\\", ".").replace("/", ".");
Class<?> clazz = Class.forName(clazzPath, true, loader);
for (Method m : clazz.getMethods()) {
MethodEntity entity = new MethodEntity();
List<String> paramTypeCanonicalNames = new ArrayList<>();
List<String> paramTypeNames = new ArrayList<>();
// 5 为".java"的长度
entity.setInterfaceClassName(fileName.substring(0, fileName.length() - 5));
entity.setInterfaceClassFullName(clazzPath);
entity.setMethodName(m.getName());
for (Parameter p : m.getParameters()) {
String paramSimpleName = p.getType().getSimpleName();
// List,抹掉具体类型
paramTypeNames.add(basicDataType2ClassType(paramSimpleName, true));
String paramClassName = p.getParameterizedType().getTypeName();
// java.util.List<java.lang.Long>,参数类型的完整名称
paramTypeCanonicalNames.add(basicDataType2ClassType(paramClassName, false));
}
entity.setParamterTypeCanonicalNames(paramTypeCanonicalNames);
entity.setParamterTypeNames(paramTypeNames);
methodEntities.add(entity);
String json = JSON.toJSONString(entity);
System.out.println(json);
}
}
}
/**
* 基本数据类型替换为基本类型对应的class类
*
* @param type
* 需要转换的类型
* @param isSimpleName
* 是否为类名简写
* @return String
*/
private String basicDataType2ClassType(String type, Boolean isSimpleName) {
String res = "";
if (basicDataTypeReference.containsKey(type)) {
res = basicDataTypeReference.get(type);
if (isSimpleName) {
res = res.substring(res.lastIndexOf(".") + 1);
}
return res;
} else {
return type;
}
}
console输出如下:
{"interfaceClassFullName":"com.bj58.zhuanzhuan.IAaaaService","interfaceClassName":"IAaaaService","methodName":"getInfo","paramterTypeCanonicalNames":["java.lang.String","java.util.List<java.lang.Long>"],"paramterTypeNames":["String","List"]}
{"interfaceClassFullName":"com.bj58.zhuanzhuan.IBiuBiuService","interfaceClassName":"IBiuBiuService","methodName":"getUser","paramterTypeCanonicalNames":["java.lang.String","java.lang.String","java.lang.String","java.lang.Integer","java.lang.Integer"],"paramterTypeNames":["String","String","String","Integer","Integer"]}