栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java小工具:通过方法体内变更代码向上找方法调用链【完善中】

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java小工具:通过方法体内变更代码向上找方法调用链【完善中】

package com.test.springboot.springboot_first.sec;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import ch.qos.logback.core.net.SyslogOutputStream;

public class GetApiTest implements GetUrl {
    List list = new ArrayList();
    List list_filter = new ArrayList();
    List list_matched = new ArrayList();
    Integer ct = 0;
    String pth = "";

    @Override
    public void getUrl() {

    }

    
    public void getJavas(File dir) {
        File[] files = dir.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                getJavas(file);
            } else {
                if ((file + "").contains(".java")) {
                    list.add(file + "");
                }
            }
        }
    }

    
    
    public List getList(File dir) {
        getJavas(dir);
        return list;
    }

    
    
    
    

    public String txt2String(String path) {
        String fileContent = "";
        try {
            final File f = new File(path);
            if (f.isFile() && f.exists()) {
                final InputStreamReader read = new InputStreamReader(new FileInputStream(f), "utf-8");
                final BufferedReader reader = new BufferedReader(read);
                String line;
                while ((line = reader.readLine()) != null) {
                    fileContent += line;
                }
                read.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileContent;
    }

    
    public List getKeyWordMatchJavs(String kd) {
        if (!kd.contains("|")) {
            kd = kd + "|";
        }
        String[] st = kd.split("\|");
        for (String pa : list) {
            String mm = txt2String(pa);
            if (st.length == 1 && mm.contains(st[0].toString())) {
                // System.out.println(pa);
                list_filter.add(pa);
            }

        }
        return list_filter;

    }

    
    
    
    public List getKeyWordMatchJavs2(String kd, List lig) {
        if (!kd.contains("|")) {
            kd = kd + "|";
        }
        String[] st = kd.split("\|");
        for (String pa : list) {
            String mm = txt2String(pa);
            if (st.length == 1 && mm.contains(st[0].toString())) {
                lig.add(pa);
            }

        }
        return lig;

    }

    
    public List delLastElem(List lt) {
        List ltr = new ArrayList();
        for (int i = 0; i < lt.size() - 1; i++) {
            ltr.add(lt.get(i));
        }
        return ltr;
    }

    
    public List transFormA2L(String[] sg) {
        List li = new ArrayList();
        for (String s : sg) {
            li.add(s);
        }
        return li;
    }

    
    public String mergeList2String(List lsg, String sep) {
        String ms = "";
        for (String s : lsg) {
            ms = ms + s + sep;
        }

        return ms.substring(0, ms.length() - 1);
    }

    

    public List getIndexOf(String inputStr, String pattern, Integer total, Integer delta) {
        Matcher matcher = Pattern.compile(pattern).matcher(inputStr);
        if (matcher.find()) {
            list_matched.add((matcher.start() + delta) + "|" + (matcher.end() + delta));
            ct = matcher.end() + delta;
            if (ct < total) {
                inputStr = inputStr.substring(ct - delta, total - delta);
                getIndexOf(inputStr, pattern, total, (matcher.end() + delta));
            }
        }
        return list_matched;
    }

    

    public String remAllCtrls(String mstr) {
        return mstr.replaceAll("t", " ").replace("n", " ").replaceAll("r", " ").replaceAll(" +", " ").trim();
    }

    
    public List getNearestPs(List mt, List source) {
        HashMap hp = new HashMap<>();
        for (String s : mt) {
            Integer container = 1000000000;
            for (String t : source) {
                Integer dt = Integer.parseInt(s.split("\|")[0]) - Integer.parseInt(t.split("\|")[0]);
                if (dt > 0 && dt < container) {
                    container = dt;
                }

            }
            hp.put(s, "" + container);
        }
        Iterator> nt = hp.entrySet().iterator();
        List st = new ArrayList();
        while (nt.hasNext()) {
            Map.Entry entry = nt.next();
            st.add(entry.getKey() + "=" + entry.getValue());
        }
        return st;
    }

    
    public static String watchMathedParts(String ct, List lt) {

        return null;
    }

    
    public String getClassName(String pth) {
        return pth.split("\\")[pth.split("\\").length - 1].split("\.")[0];
    }

    
    public void handleMap(HashMap> kk, String pa) {
        HashMap> hp = new HashMap>();
        for (String key : kk.keySet()) {
            List list4 = new ArrayList();
            for (String s : kk.get(key)) {
                String cts = new GetApiTest().remAllCtrls(new GetApiTest().txt2String(s));
                String pdns = "(new){0,}[\s]{0,}" + key.split("\|")[3]
                        + "[\s]{0,}((\()[\s]{0,}[^)]{0,}[\s]{0,}(\))[\s]{0,}){0,1}.[\s]{0,}"
                        + key.split("\|")[0] + "[\s]{0,}(\()[\s]{0,}[^)]{0,}[\s]{0,}(\))";
                System.out.println("mmmm"+pdns);
                Integer totals = cts.length();
                List strss = new GetApiTest().getIndexOf(cts, pdns, cts.length(), 0);
                List strss_ft = new ArrayList();
                for (String ss : strss) {
                    String rString = cts.substring(Integer.parseInt(ss.split("\|")[0]),
                            Integer.parseInt(ss.split("\|")[1]));
                    String tpString = key.split("\|")[1];
                    if (Pattern.compile("\s{0,}(\()\s{0,}(\))\s{0,}").matcher(tpString).find() == true
                            && Pattern.compile("\s{0,}(\()\s{0,}(\))\s{0,}").matcher(rString).find() == true) {
                        strss_ft.add(ss);

                    }
                    if (tpString.split(",").length == rString.split(",").length
                            && Pattern.compile("\s{0,}(\()\s{0,}(\))\s{0,}").matcher(tpString).find() == false
                            && Pattern.compile("\s{0,}(\()\s{0,}(\))\s{0,}").matcher(rString).find() == false) {
                        strss_ft.add(ss);
                    }
                    String tps_match = "new[\s]{0,}" + key.split("\|")[3]
                            + "[\s]{0,}((\()[\s]{0,}[^)]{0,}[\s]{0,}(\))[\s]{0,}){0,1}.[\s]{0,}"
                            + key.split("\|")[0] + "[\s]{0,}(\()[\s]{0,}[^)]{0,}[\s]{0,}(\))";
                    Matcher tps = Pattern.compile(tps_match).matcher(rString);

                    if (tps.find() == true) {
//                        System.out.println("new: "+cts);
                        String after_p = tps.group().split("\." + key.split("\|")[0])[1];

                        if (Pattern.compile("\s{0,}(\()\s{0,}(\))\s{0,}").matcher(tpString).find() == true
                                && Pattern.compile("\s{0,}(\()\s{0,}(\))\s{0,}").matcher(after_p).find() == true) {
                            strss_ft.add(ss);

                        }
                        if (tpString.split(",").length == after_p.split(",").length

                                && Pattern.compile("\s{0,}(\()\s{0,}(\))\s{0,}").matcher(tpString).find() == false
                                && Pattern.compile("\s{0,}(\()\s{0,}(\))\s{0,}").matcher(after_p)
                                        .find() == false) {
                            strss_ft.add(ss);
                        }
                    }
                    if(cts.contains("test_8888")){
                    System.out.println("rstring is: "+rString);
                    System.out.println("ppp: "+"ma(\.)"+ key.split("\|")[0]+ "[\s]{0,}(\()[\s]{0,}[^)]{0,}[\s]{0,}(\))");}
                    if(Pattern.compile("ma(\.)"+ key.split("\|")[0]+ "[\s]{0,}(\()[\s]{0,}[^)]{0,}[\s]{0,}(\))").matcher(rString).find()){
                        System.out.println("mmm: "+cts);
                        System.out.println("zhengzebiaodashi: "+"(\.)"+ key.split("\|")[0]+ "[\s]{0,}(\()[\s]{0,}[^)]{0,}[\s]{0,}(\))");
//                        System.out.println("matched: "+Pattern.compile("(\.)"+ key.split("\|")[0]+ "[\s]{0,}(\()[\s]{0,}[^)]{0,}[\s]{0,}(\))").matcher(rString).group());
                        strss_ft.add(ss);
                    }

                }
                List pss = new GetApiTest().getIndexOf(cts,
                        "[\s]{0,}(\()[\s\S]*?(\))[\s]{0,}(\{)[\s\S]*?(\})", cts.length(), 0);
                List lgg = new GetApiTest().getNearestPs(strss_ft, pss);
                if (strss_ft.size() != 0) {

                    List list = listAddDetail(s, lgg, remAllCtrls(txt2String(s)));
                    String pString = (String) list.get(0);

                    List lgs = (List) list.get(1);
                    System.out.println(
                            "迭代搜索的方法是【" + key.split("\|")[0] + key.split("\|")[1] + "】 查找到调用他的父方法是:【" + lgs + "】");
                    handleMap(trans2Map(lgs, pString, pa), pa);
                } else {
                }
            }
        }

    }

    
    public List listAddDetail(String pString, List lg, String ct) {
        List ls = new ArrayList();
        Integer total = ct.length();// 获取处理后的java文本总字节
        // 根据pString(java文件绝对路径)获取package路径,格式为xx.yy.zz
        List ii = transFormA2L(pString.split("\\src\\main\\java\\")[1].split("\\"));
        String mString = mergeList2String(delLastElem(ii), ".");
        List lgs = new ArrayList<>();
        // 根据返回的list作差结果lg,进行深加工,尾部追加对应的方法名称、入参、所在package路径、是否static方法(yes or
        // no)、类名称
        for (int i = 0; i < lg.size(); i++) {
            String[] k11 = lg.get(i).split("\=");
            Integer p11 = Integer.parseInt(k11[0].split("\|")[0]);
            Integer p21 = Integer.parseInt(k11[1]);
            String[] ss = ct.substring(0, p11 - p21).split("\s");
            lgs.add("" + lg.get(i) + "|" + ss[ss.length - 1] + "|"
                    + ct.substring(p11 - p21, total).split("\{")[0].trim() + "|" + mString + "|" + "no" + "|"
                    + new GetApiTest().getClassName(pString));// 考虑java名和类名不一样的情况?
        }
        ls.add(pString);
        ls.add(lgs);
        return ls;

    }

    
    public List getJsAccord2Part(String pa, String pdn) {

        List list = getList(new File(pa));// 过滤出工程下所有java文件
        List list2 = getKeyWordMatchJavs(pdn);// 搜索含有代码块的java文件,放到list中,代码片段不能跨方法。
        String pString = list2.get(0);// 默认修改的只有一个java文件,获取下角标为0的值

        String ct = remAllCtrls(txt2String(pString));// 对目标java文件进行合同空白符成一个空格以及去除末尾空格预处理,方便后续查找方法体
        pdn = remAllCtrls(pdn);// 对变更的打代码片段也进行合并空白符处理

        List strs = new GetApiTest().getIndexOf(ct, pdn, ct.length(), 0);// 获取匹配keyword的所在的起点和终点位置以及delta偏移量,返回list
        // 宽松匹配java类中的所有方法体,返回list
        List ps = new GetApiTest().getIndexOf(ct, "[\s]{0,}(\()[\s\S]*?(\))[\s]{0,}(\{)[\s\S]*?(\})",
                ct.length(), 0);
        // 根据方法体位置list和搜索代码块位置list作差,返回搜索代码块所在的方法体
        List lg = getNearestPs(strs, ps);
        return listAddDetail(pString, lg, ct);

    }

    
    public HashMap> trans2Map(List lgs, String pString, String pa) {
        // 获取工程下所有的java文件
        GetApiTest m2 = new GetApiTest();
        HashMap> kk = new HashMap>();
        List ll = m2.getList(new File(pa));
        for (int i = 0; i < lgs.size(); i++) {
            String pack_name = lgs.get(i).split("\|")[lgs.get(i).split("\|").length - 3];
            String class_name = lgs.get(i).split("\|")[lgs.get(i).split("\|").length - 1];
            String method_name = lgs.get(i).split("\|")[2];
            String method_types = lgs.get(i).split("\|")[3];
            // 遍历深加工后的lg,根据package路径去全局搜索含有该package路径的java文件,收集可能调用该方法的java文件
            List list3 = m2.getKeyWordMatchJavs2(pack_name, new ArrayList<>());
            boolean bn = list3.remove(pString); // 除去含有该pacakg路径的本身的一个类
            kk.put(method_name + "|" + method_types + "|" + pack_name + "|" + class_name, list3);// 使用map将数据存储起来,key=方法名|入参|pckage路径|类名,value=含有该package可能调用该方法的java绝对路径(除掉自身)
        }
        return kk;

    }

    public static void main(String[] args) {
        // SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd
        // HH:mm:ss");//设置日期格式
        // System.out.println(df.format(new Date()));// new Date()为获取当前系统时间
        String pa = "C:\Users\Administrator\Desktop\test\springboot-first";
        String pdn = "maxida";
        GetApiTest gTest = new GetApiTest();
        List ls = gTest.getJsAccord2Part(pa, pdn);
        String pString = (String) ls.get(0);
        System.out.println("项目工程根路径为:" + pa);
        System.out.println("变更代码片段" + pdn + "所在的java文件为: " + pString);
        List lgs = (List) ls.get(1);
        HashMap> kk = gTest.trans2Map(lgs, pString, pa);
        System.out.println("根据变更代码片段 【" + pdn + "】找到的所在的java文件【" + pString + "】所在的方法为" + kk);
        gTest.handleMap(kk, pa);
        // System.out.println(df.format(new Date()));// new Date()为获取当前系统时间
    }

}
 

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号