获取项目中调用的其他接口列表

package springcloud_producer_8001;


import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.file.FileAlreadyExistsException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;



public class AppTest   {
    
    /** 用来保存引入的类全限定名 */
    private Set<String> classResult = new HashSet<String>();
    /** 用来保存引用的类的方法,包括普通方法和静态方法名 */
    private Set<String> methodResult = new HashSet<String>();
    /**
     *     我们要找的目标包
     * */
    private List<String> searchPackages;
    
    
    /**
     *     构造函数
     *     @param searchPackages 我们要找的目标包
     * */
    public AppTest(List<String> searchPackages) {
        if(searchPackages == null || searchPackages.isEmpty()) {
            throw new IllegalArgumentException("searchPackages不能为空");
        }
        this.searchPackages = searchPackages;
    }


    
    /**
     *     获取目标文件中引用的指定包内的类和使用的方法
     *     @param f 目标文件,如果是文件夹,则会递归处理
     * @throws Exception 
     * */
    public void parseAllUsedImportClassAndMethods(String path) throws Exception {
        File file = new File(path);
        // 获取类和方法
        this.getAllUsedImportClassAndMethods(file);
        // 获取方法的参数类型
        this.getMethodParams();
    }
    
    
    
    
    /**
     *     递归获取java文件内容
     * */
    private void getAllUsedImportClassAndMethods(File f) throws Exception {
        if(f.isDirectory()) {
            // 如果是目录,那就递归获取java文件
            File[] listFiles = f.listFiles();
            for(File file :listFiles) {
                this.getAllUsedImportClassAndMethods(file);
            }
        }else {
            // 如果是.java结尾的文件就读取
            if(f.getName().endsWith(".java")) {
                this.getFileText(f);
            }
        }
    }
    
    /**
     *     读取文件内容
     * */
    private void getFileText(File file) throws Exception{
        FileReader reader = new FileReader(file);
        char[] buf = new char[1024];
        StringBuilder sb = new StringBuilder();
        while(reader.read(buf ) != -1) {
            sb.append(buf);
        }
        // 获取引入的类
        Set<String> importClass = this.getImport(sb.toString());
        // 获取引入的方法
        this.getMethods(sb.toString(), importClass);
        reader.close();
    }
    
    /**
     *     获取import的类
     * */
    private Set<String> getImport(String fileText)  {
        StringBuilder sb = new StringBuilder();
        sb.append("import +?(");
        for(String packageStr :this.searchPackages) {
            sb.append(packageStr).append(".*?").append("|");
        }
        if(sb.charAt(sb.length() - 1) == '|') {
            sb.deleteCharAt(sb.length() - 1);
        }
        sb.append(") *;");
        Pattern p = Pattern.compile(sb.toString());
        Matcher m = p.matcher(fileText);
        Set<String> thisResult = new HashSet<String>();
        while(m.find()) {
            for(int i = 1; i <= m.groupCount(); i++) {
                String group = m.group(i);
                classResult.add(group);
                thisResult.add(group);
            }
        }
        return thisResult;
    }
    
    /**
     *     获取调用的方法
     * */
    private void getMethods(String fileText,Set<String> importClass)  {
        // 普通方法
        for(String clasz: importClass) {
            String simpleClass = clasz.substring(clasz.lastIndexOf(".")+1);
            Pattern p = Pattern.compile("private +"+simpleClass+" +(.*?);");
            Matcher m = p.matcher(fileText);
            if(m.find()) {
                String fieldName = m.group(1);
                Pattern p2 = Pattern.compile(fieldName+"\\.([a-zA-Z]+?)\\(.*?\\)");
                Matcher m2 = p2.matcher(fileText);
                while(m2.find()) {
                    for(int i = 1; i <= m2.groupCount(); i++) {
                        String group = m2.group(i);
                        methodResult.add(clasz + "." + group);
                    }
                }
            }
        }
        // 静态方法
        for(String clasz: importClass) {
            String simpleClass = clasz.substring(clasz.lastIndexOf(".")+1);
            Pattern p2 = Pattern.compile(simpleClass+"\\.([a-zA-Z]+?)\\(.*?\\)");
            Matcher m2 = p2.matcher(fileText);
            while(m2.find()) {
                for(int i = 1; i <= m2.groupCount(); i++) {
                    String group = m2.group(i);
                    methodResult.add(clasz + "." + group);
                }
            }
        }
    }
    
    
    /**
     *     获取类方法的参数类型
     * */
    @SuppressWarnings("rawtypes")
    private void getMethodParams() {
        this.methodResult = this.methodResult.stream().sorted().map((methodStr)->{
            // 获取方法的参数
            StringBuilder sb = new StringBuilder(methodStr);
            sb.append("(");
            int pointLastIndex = methodStr.lastIndexOf(".");
            String methodName = methodStr.substring(pointLastIndex+1);
            String className = methodStr.substring(0,pointLastIndex);
            try {
                Class<?> clasz = Class.forName(className);
                Method[] declaredMethods = clasz.getDeclaredMethods();
                for(Method method: declaredMethods) {
                    if(method.getName().equals(methodName)) {
                        Class<?>[] parameterTypes = method.getParameterTypes();
                        for(Class p: parameterTypes) {
                            sb.append(p.getSimpleName()).append(" ,");
                        }
                        break;
                    }
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                return methodStr;
            }
            if(sb.charAt(sb.length()-1) == ',') {
                sb.deleteCharAt(sb.length()-1);
            }
            sb.append(")");
            return sb.toString();
        }).collect(Collectors.toSet());
    }
    
    /**
     *     导出
     *     @throws Exception 
     * */
    public void export(String path) throws Exception {
        File file = new File(path);
        if(file.exists()) {
            throw new FileAlreadyExistsException(path);
        }
        // 创建父目录
        file.getParentFile().mkdirs();
        FileWriter fw = new FileWriter(file);
        
        fw.write("引用的类如下:\n");
        for(String clasz: this.classResult) {
            fw.write(clasz);
            fw.write("\n");
        }
        
        fw.write("\n使用的引用类的方法如下:\n");
        for(String method: this.methodResult) {
            fw.write(method);
            fw.write("\n");
        }
        fw.flush();
        fw.close();
    }
    
    /**
     *     导出
     *     @throws Exception 
     * */
    public void export(OutputStream out) throws Exception {
        
        out.write("引用的类如下:\n".getBytes(Charset.forName("utf-8")));
        for(String clasz: this.classResult) {
            out.write(clasz.getBytes(Charset.forName("utf-8")));
            out.write("\n".getBytes(Charset.forName("utf-8")));
        }
        
        out.write("\n使用的引用类的方法如下:\n".getBytes(Charset.forName("utf-8")));
        for(String method: this.methodResult) {
            out.write(method.getBytes(Charset.forName("utf-8")));
            out.write("\n".getBytes(Charset.forName("utf-8")));
        }
        out.flush();
        out.close();
    }
    
    
    /**
     *     测试
     * */
    public static void main(String[] args) throws Exception {
        AppTest test = new AppTest(Arrays.asList("springcloud_producer.service"));
        test.parseAllUsedImportClassAndMethods("D:\\workspace\\java_web\\springcloud-parent\\springcloud_producer\\src\\main\\java\\springcloud_producer");
        test.export(System.out);
        test.export("C:\\Users\\HongCheng\\Desktop\\2.txt");
    }
}

posted @   要买CT5的小曹  阅读(8)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示