如何比较同一个项目中不同版本的区别

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 如何比较同一个项目中不同版本的区别

在项目研发的过程中,我们往往会同时写多个版本的情况,而如果我们在低版本bug的同时新版本可能也存在这个bug,那么,一般解决方案有两个,要么是将最新的代码实时与新版本同步,要么是在新版本要上线的时候对新老版本的bug进行对比。理论上讲,第一种方案相对来说,出错的概率要小一些。所以下面我来介绍一下对于第二种方案的思路。

主体思路

首先,我们要知道,比较两个项目的异同一般是指的对两个版本的异同点进行比较,两个完全不同的项目是没有必要比较异同的。那么比较这个系统的两个不同版本主要关心的点有哪些呢?

1、新版本相对于旧版本少的文件:这很有可能是旧版本为了满足一定的需求而创建的,而这个需求在新版本中也有。
2、相同代码文件中代码的不同之处。

新版本相较于旧版本多出来的文件我们是不需要考虑的。

针对上面两个关注点,可以采取以下两种方案

GIT比较法

git 追踪到文件,就可以很好的满足到上面提到的两种情况。
假设我们的两个版本为1.0和2.0,首先,创建一个1.0项目的副本目录(包含git文件夹),同时也创建一个2.0项目的副本目录(包含git文件夹),然后将1.0副本代码替换为2.0副本代码,然后利用可视化提交界面,一个个的进行区别查看,然后根据现有的逻辑进行补充。
逻辑如图所示:
在这里插入图片描述

当我们使用Git进行异同点检查的时候,可能遇到的指令有 git revert(撤销历史提交),因为对于1.0的git来说,1,.0中新增的文件,对于2.0的代码进行检查显示的就是该文件被删除了,所以我们需要对删除的文件的删除行为进行撤销。

查看思路:

1、unknown的东西就不管,因为这是最新版多的东西
2、miss的东西可能是缺少的,也可能是修改的,所以这里不能盲目git revert。
3、modifined是变化的,如果是变少了:本质上就是1.0修复时加上去的,所以要考虑加到2.0中

注意事项:

1、确保两个版本的代码都是最新的(1.0和2.0)
2、一定不要点确认提交,毕竟我们只是使用git的比较机制
3、看准比较的究竟那边是本地当前的和以前的,这里我推荐使用可视化工具
4、修改的过程中可能会有改错的情况,所以在改完之后要启动所有项目试一下。

Java静态代码分析法

该方法目前只做到了能比较两个java项目的相似度,目前对自动化变更代码尚有技术的不可预知性。

分析Java代码

首先,定义出一个Java代码的项目结构对应的简单对象。

给出Java项目结构所需简单对象

pom

public class Pom {
   
   
    public String schemaLocation; // http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd
    public String modelVersion; // 4.0.0
    public String groupId; // org.ccs.nss
    public String artifactId; // nss-boot-parent
    public String version; // 1.0
    public String packaging; // pom
    public PomParent parent; // {groupId=org.springframework.boot, artifactId=spring-boot-starter-parent, version=2.3.3.RELEASE, relativePath=}
    public PomRepositories repositories; // {repository=[{id=central, name=aliyun Repository, url=https://maven.aliyun.com/repository/central, snapshots={enabled=false}}, {id=jeecg, name=jeecg Repository, url=http://maven.jeecg.org/nexus/content/repositories/jeecg, snapshots={enabled=false}}]}
    public PomPluginrepositories pluginRepositories; // {pluginRepository=[{id=central, url=https://maven.aliyun.com/repository/central}, {id=jeecg, url=http://maven.jeecg.org/nexus/content/repositories/jeecg}]}
    public PomModules modules; // {module=[base-common, module-system]}
    public PomProperties properties; // {log4j2.version=2.17.1, maven-jar-plugin.version=3.1.1, nss.common.version=1.0, java.version=1.8, project.reporting.outputEncoding=UTF-8, project.build.sourceEncoding=UTF-8, mybatis-plus.version=3.1.2, druid.version=1.1.17, jwt.version=0.9.1, commons.version=2.6, aliyun-java-sdk-core.version=3.2.3, aliyun-java-sdk-dysmsapi.version=1.0.0}
    public PomDependencies dependencies; // {dependency=[{groupId=org.springframework.boot, artifactId=spring-boot-starter-web}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-mail}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-test, scope=test}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-aop}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-actuator}, {groupId=org.apache.cxf, artifactId=cxf-spring-boot-starter-jaxws, version=3.2.4}, {groupId=commons-io, artifactId=commons-io, version=${commons.version}}, {groupId=commons-lang, artifactId=commons-lang, version=${commons.version}}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-freemarker}, {groupId=org.projectlombok, artifactId=lombok}, {groupId=com.baomidou, artifactId=mybatis-plus-boot-starter, version=${mybatis-plus.version}}, {groupId=com.alibaba, artifactId=druid-spring-boot-starter, version=${druid.version}}, {groupId=com.baomidou, artifactId=dynamic-datasource-spring-boot-starter, version=2.5.4}, {groupId=com.alibaba, artifactId=fastjson, version=1.2.73}, {groupId=mysql, artifactId=mysql-connector-java, version=5.1.47, scope=runtime}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-quartz}, {groupId=com.auth0, artifactId=java-jwt, version=3.7.0}, {groupId=org.apache.shiro, artifactId=shiro-spring-boot-starter, version=1.6.0}, {groupId=io.springfox, artifactId=springfox-swagger2, version=2.9.2}, {groupId=io.springfox, artifactId=springfox-swagger-ui, version=2.9.2}, {groupId=com.github.xiaoymin, artifactId=swagger-bootstrap-ui, version=1.9.3}, {groupId=io.springfox, artifactId=springfox-bean-validators, version=2.9.2}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-data-redis}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-data-ldap}, {groupId=org.apache.commons, artifactId=commons-pool2}, {groupId=com.github.tobato, artifactId=fastdfs-client, version=1.26.7}, {groupId=org.jeecgframework.boot, artifactId=codegenerate, version=1.0.5}, {groupId=org.jeecgframework, artifactId=autopoi-web, version=1.1.1, exclusions={exclusion={groupId=commons-codec, artifactId=commons-codec}}}, {groupId=cn.hutool, artifactId=hutool-all, version=4.5.11}, {groupId=com.thoughtworks.xstream, artifactId=xstream, version=1.3.1}, {groupId=com.aliyun, artifactId=aliyun-java-sdk-dysmsapi, version=${aliyun-java-sdk-dysmsapi.version}}, {groupId=com.aliyun, artifactId=aliyun-java-sdk-core, version=${aliyun-java-sdk-core.version}}, {groupId=com.github.penggle, artifactId=kaptcha, version=2.3.2}, {groupId=com.itextpdf, artifactId=itextpdf, version=5.5.13}, {groupId=org.bouncycastle, artifactId=bcprov-jdk15on, version=1.49}, {groupId=com.itextpdf, artifactId=itext-asian, version=5.2.0}, {groupId=commons-net, artifactId=commons-net, version=3.6}, {groupId=com.jcraft, artifactId=jsch, version=0.1.55}]}
    public PomDependencymanagement dependencyManagement; // {dependencies={dependency={groupId=org.ccs.nss, artifactId=base-common, version=${nss.common.version}}}}
    public PomBuild build; // {plugins={plugin=[{groupId=org.apache.maven.plugins, artifactId=maven-compiler-plugin, configuration={source=1.8, target=1.8, encoding=UTF-8}}, {groupId=org.apache.maven.plugins, artifactId=maven-surefire-plugin, configuration={skipTests=true}}, {groupId=org.apache.maven.plugins, artifactId=maven-resources-plugin, configuration={nonFilteredFileExtensions={nonFilteredFileExtension=[woff, woff2, eot, ttf, svg, xlsx, xls]}}}]}, resources={resource=[{directory=src/main/resources, filtering=true}, {directory=src/main/java, includes={include=[**/*.xml, **/*.json, **/*.ftl]}}]}}
}
public class PomParent {
    public String groupId; // org.springframework.boot
    public String artifactId; // spring-boot-starter-parent
    public String version; // 2.3.3.RELEASE
    public String relativePath; // 
}
public class PomRepositories {
    public List<PomRepositoriesRepository> repository; // [{id=central, name=aliyun Repository, url=https://maven.aliyun.com/repository/central, snapshots={enabled=false}}, {id=jeecg, name=jeecg Repository, url=http://maven.jeecg.org/nexus/content/repositories/jeecg, snapshots={enabled=false}}]
}
public class PomPluginrepositories {
    public List<PomPluginrepositoriesPluginrepository> pluginRepository; // [{id=central, url=https://maven.aliyun.com/repository/central}, {id=jeecg, url=http://maven.jeecg.org/nexus/content/repositories/jeecg}]
}
public class PomModules {
    public List<String> module; // [base-common, module-system]
}
public class PomProperties {
    public String log4j2Version; // 2.17.1
    public String mavenJarPluginVersion; // 3.1.1
    public String nssCommonVersion; // 1.0
    public String javaVersion; // 1.8
    public String projectReportingOutputEncoding; // UTF-8
    public String projectBuildSourceEncoding; // UTF-8
    public String mybatisPlusVersion; // 3.1.2
    public String druidVersion; // 1.1.17
    public String jwtVersion; // 0.9.1
    public String commonsVersion; // 2.6
    public String aliyunJavaSdkCoreVersion; // 3.2.3
    public String aliyunJavaSdkDysmsapiVersion; // 1.0.0
}
public class PomDependencies {
    public List<PomDependenciesDependency> dependency; // [{groupId=org.springframework.boot, artifactId=spring-boot-starter-web}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-mail}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-test, scope=test}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-aop}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-actuator}, {groupId=org.apache.cxf, artifactId=cxf-spring-boot-starter-jaxws, version=3.2.4}, {groupId=commons-io, artifactId=commons-io, version=${commons.version}}, {groupId=commons-lang, artifactId=commons-lang, version=${commons.version}}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-freemarker}, {groupId=org.projectlombok, artifactId=lombok}, {groupId=com.baomidou, artifactId=mybatis-plus-boot-starter, version=${mybatis-plus.version}}, {groupId=com.alibaba, artifactId=druid-spring-boot-starter, version=${druid.version}}, {groupId=com.baomidou, artifactId=dynamic-datasource-spring-boot-starter, version=2.5.4}, {groupId=com.alibaba, artifactId=fastjson, version=1.2.73}, {groupId=mysql, artifactId=mysql-connector-java, version=5.1.47, scope=runtime}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-quartz}, {groupId=com.auth0, artifactId=java-jwt, version=3.7.0}, {groupId=org.apache.shiro, artifactId=shiro-spring-boot-starter, version=1.6.0}, {groupId=io.springfox, artifactId=springfox-swagger2, version=2.9.2}, {groupId=io.springfox, artifactId=springfox-swagger-ui, version=2.9.2}, {groupId=com.github.xiaoymin, artifactId=swagger-bootstrap-ui, version=1.9.3}, {groupId=io.springfox, artifactId=springfox-bean-validators, version=2.9.2}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-data-redis}, {groupId=org.springframework.boot, artifactId=spring-boot-starter-data-ldap}, {groupId=org.apache.commons, artifactId=commons-pool2}, {groupId=com.github.tobato, artifactId=fastdfs-client, version=1.26.7}, {groupId=org.jeecgframework.boot, artifactId=codegenerate, version=1.0.5}, {groupId=org.jeecgframework, artifactId=autopoi-web, version=1.1.1, exclusions={exclusion={groupId=commons-codec, artifactId=commons-codec}}}, {groupId=cn.hutool, artifactId=hutool-all, version=4.5.11}, {groupId=com.thoughtworks.xstream, artifactId=xstream, version=1.3.1}, {groupId=com.aliyun, artifactId=aliyun-java-sdk-dysmsapi, version=${aliyun-java-sdk-dysmsapi.version}}, {groupId=com.aliyun, artifactId=aliyun-java-sdk-core, version=${aliyun-java-sdk-core.version}}, {groupId=com.github.penggle, artifactId=kaptcha, version=2.3.2}, {groupId=com.itextpdf, artifactId=itextpdf, version=5.5.13}, {groupId=org.bouncycastle, artifactId=bcprov-jdk15on, version=1.49}, {groupId=com.itextpdf, artifactId=itext-asian, version=5.2.0}, {groupId=commons-net, artifactId=commons-net, version=3.6}, {groupId=com.jcraft, artifactId=jsch, version=0.1.55}]
}
public class PomDependencymanagement {
    public PomDependencymanagementDependencies dependencies; // {dependency={groupId=org.ccs.nss, artifactId=base-common, version=${nss.common.version}}}
}
public class PomBuild {
    public PomBuildPlugins plugins; // {plugin=[{groupId=org.apache.maven.plugins, artifactId=maven-compiler-plugin, configuration={source=1.8, target=1.8, encoding=UTF-8}}, {groupId=org.apache.maven.plugins, artifactId=maven-surefire-plugin, configuration={skipTests=true}}, {groupId=org.apache.maven.plugins, artifactId=maven-resources-plugin, configuration={nonFilteredFileExtensions={nonFilteredFileExtension=[woff, woff2, eot, ttf, svg, xlsx, xls]}}}]}
    public PomBuildResources resources; // {resource=[{directory=src/main/resources, filtering=true}, {directory=src/main/java, includes={include=[**/*.xml, **/*.json, **/*.ftl]}}]}
}
... ...

javacontroller

public class JavaController {
   
   
    private String absolutePath;
    private String name;
    private List<String> methodZhuShi;
    private List<String> allZhuShi;
    private List<JavaHttpApi> apis;

    public JavaController() {
   
   
        this.methodZhuShi = new ArrayList<>();
        this.allZhuShi = new ArrayList<>();
        this.apis = new ArrayList<>();
    }

    public List<JavaHttpApi> getApis() {
   
   
        return apis;
    }

    public void setApis(List<JavaHttpApi> apis) {
   
   
        this.apis = apis;
    }

    public List<String> getAllZhuShi() {
   
   
        return allZhuShi;
    }

    public void setAllZhuShi(List<String> allZhuShi) {
   
   
        this.allZhuShi = allZhuShi;
    }

    public List<String> getMethodZhuShi() {
   
   
        return methodZhuShi;
    }

    public void setMethodZhuShi(List<String> methodZhuShi) {
   
   
        this.methodZhuShi = methodZhuShi;
    }

    public String getAbsolutePath() {
   
   
        return absolutePath;
    }

    public void setAbsolutePath(String absolutePath) {
   
   
        this.absolutePath = absolutePath;
    }

    public String getName() {
   
   
        return name;
    }

    public void setName(String name) {
   
   
        this.name = name;
    }
}

javahttpApi

public class JavaHttpApi {
   
   
    private String belongController;
    private String method;
    private String url;
    private String paramStr;
    private String name;
    private Map<String,Object> paramJsons;

    public Map<String, Object> getParamJsons() {
   
   
        return paramJsons;
    }

    public void setParamJsons(Map<String, Object> paramJsons) {
   
   
        this.paramJsons = paramJsons;
    }

    public String getName() {
   
   
        return name;
    }

    public void setName(String name) {
   
   
        this.name = name;
    }

    public String getBelongController() {
   
   
        return belongController;
    }

    public void setBelongController(String belongController) {
   
   
        this.belongController = belongController;
    }

    public String getMethod() {
   
   
        return method;
    }

    public void setMethod(String method) {
   
   
        this.method = method;
    }

    public String getUrl() {
   
   
        return url;
    }

    public void setUrl(String url) {
   
   
        this.url = url;
    }

    public String getParamStr() {
   
   
        return paramStr;
    }

    public void setParamStr(String paramStr) {
   
   
        this.paramStr = paramStr;
    }
}

javaClass

public class JavaClass {
   
   
    private String absolutePath;
    private String name;
    private List<String> allZhuShi = new ArrayList<>();
    private Set<String> allAnaotion = new HashSet<>();
    private Map<String,Object> fields = new HashMap<>();

    public Map<String, Object> getFields() {
   
   
        return fields;
    }

    public void setFields(Map<String, Object> fields) {
   
   
        this.fields = fields;
    }

    public Set<String> getAllAnaotion() {
   
   
        return allAnaotion;
    }

    public void setAllAnaotion(Set<String> allAnaotion) {
   
   
        this.allAnaotion = allAnaotion;
    }

    public String getAbsolutePath() {
   
   
        return absolutePath;
    }

    public void setAbsolutePath(String absolutePath) {
   
   
        this.absolutePath = absolutePath;
    }

    public String getName() {
   
   
        return name;
    }

    public void setName(String name) {
   
   
        this.name = name;
    }

    public List<String> getAllZhuShi() {
   
   
        return allZhuShi;
    }

    public void setAllZhuShi(List<String> allZhuShi) {
   
   
        this.allZhuShi = allZhuShi;
    }
}
将pom文件反序列化为对象
public static List<Pom> getPomContent(String folder, String ignores) {
   
   
        FolderUtils.Dir dir = FolderUtils.getFolder(folder, ignores);
        List<String> pomPaths = FolderUtils.getAbsolutePathOfDirNameByCondition(dir, "pom.xml");
        List<Pom> poms = new ArrayList<>();
        for (String pomPath : pomPaths) {
   
   
            String content = FileUtils.getFileContent(pomPath, false);
            ObjectMapper xmlMapper = new XmlMapper();
            try {
   
   
                Pom pom = PomExchange.exchangePom(xmlMapper.readValue(content, Map.class));
                poms.add(pom);
            } catch (JsonProcessingException e) {
   
   
                e.printStackTrace();
            }
        }
        return poms;
    }

下面是exchange方法

import cn.chaojilaji.auto.zlang.codereview.javahandler.pomHandler.data.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PomExchange {
   
   
    public static Pom exchangePom(Map<String, Object> tmp) {
   
   
        Pom tmpDto = new Pom();
        tmpDto.schemaLocation = (String) tmp.getOrDefault("schemaLocation", "");
        tmpDto.modelVersion = (String) tmp.getOrDefault("modelVersion", "");
        tmpDto.groupId = (String) tmp.getOrDefault("groupId", "");
        tmpDto.artifactId = (String) tmp.getOrDefault("artifactId", "");
        tmpDto.version = (String) tmp.getOrDefault("version", "");
        tmpDto.packaging = (String) tmp.getOrDefault("packaging", "");
        tmpDto.parent = exchangePomParent((Map<String, Object>) tmp.getOrDefault("parent", new HashMap<>()));
        tmpDto.repositories = exchangePomRepositories((Map<String, Object>) tmp.getOrDefault("repositories", new HashMap<>()));
        tmpDto.pluginRepositories = exchangePomPluginrepositories((Map<String, Object>) tmp.getOrDefault("pluginRepositories", new HashMap<>()));
        tmpDto.modules = exchangePomModules((Map<String, Object>) tmp.getOrDefault("modules", new HashMap<>()));
        tmpDto.properties = exchangePomProperties((Map<String, Object>) tmp.getOrDefault("properties", new HashMap<>()));
        tmpDto.dependencies = exchangePomDependencies((Map<String, Object>) tmp.getOrDefault("dependencies", new HashMap<>()));
        tmpDto.dependencyManagement = exchangePomDependencyManagement((Map<String, Object>) tmp.getOrDefault("dependencyManagement", new HashMap<>()));
        tmpDto.build = exchangePomBuild((Map<String, Object>) tmp.getOrDefault("build", new HashMap<>()));
        return tmpDto;
    }

    public static PomParent exchangePomParent(Map<String, Object> tmp) {
   
   
        PomParent tmpDto = new PomParent();
        tmpDto.groupId = (String) tmp.getOrDefault("groupId", "");
        tmpDto.artifactId = (String) tmp.getOrDefault("artifactId", "");
        tmpDto.version = (String) tmp.getOrDefault("version", "");
        tmpDto.relativePath = (String) tmp.getOrDefault("relativePath", "");
        return tmpDto;
    }

    public static PomRepositories exchangePomRepositories(Map<String, Object> tmp) {
   
   
        PomRepositories tmpDto = new PomRepositories();
        try {
   
   
            tmpDto.repository = new ArrayList<>();
            List<Map<String, Object>> tmpRepository = (List<Map<String, Object>>) tmp.getOrDefault("repository", new ArrayList<>());
            for (Map<String, Object> a : tmpRepository) {
   
   
                tmpDto.repository.add(exchangePomRepositoriesRepository(a));
            }
        } catch (Exception e) {
   
   
        }

        return tmpDto;
    }

    public static PomRepositoriesRepository exchangePomRepositoriesRepository(Map<String, Object> tmp) {
   
   
        PomRepositoriesRepository tmpDto = new PomRepositoriesRepository();
        tmpDto.snapshots = exchangePomRepositoriesRepositorySnapshots((Map<String, Object>) tmp.getOrDefault("snapshots", new HashMap<>()));
        tmpDto.name = (String) tmp.getOrDefault("name", "");
        tmpDto.id = (String) tmp.getOrDefault("id", "");
        tmpDto.url = (String) tmp.getOrDefault("url", "");
        return tmpDto;
    }

    public static PomRepositoriesRepositorySnapshots exchangePomRepositoriesRepositorySnapshots(Map<String, Object> tmp) {
   
   
        PomRepositoriesRepositorySnapshots tmpDto = new PomRepositoriesRepositorySnapshots();
        tmpDto.enabled = (String) tmp.getOrDefault("enabled", "");
        return tmpDto;
    }

    public static PomPluginrepositories exchangePomPluginrepositories(Map<String, Object> tmp) {
   
   
        PomPluginrepositories tmpDto = new PomPluginrepositories();
        try {
   
   
            tmpDto.pluginRepository = new ArrayList<>();
            List<Map<String, Object>> tmpPluginRepository = (List<Map<String, Object>>) tmp.getOrDefault("pluginRepository", new ArrayList<>());
            for (Map<String, Object> a : tmpPluginRepository) {
   
   
                tmpDto.pluginRepository.add(exchangePomPluginrepositoriesPluginrepository(a));
            }
        } catch (Exception e) {
   
   
        }

        return tmpDto;
    }

    public static PomPluginrepositoriesPluginrepository exchangePomPluginrepositoriesPluginrepository(Map<String, Object> tmp) {
   
   
        PomPluginrepositoriesPluginrepository tmpDto = new PomPluginrepositoriesPluginrepository();
        tmpDto.id = (String) tmp.getOrDefault("id", "");
        tmpDto.url = (String) tmp.getOrDefault("url", "");
        return tmpDto;
    }

    public static PomModules exchangePomModules(Map<String, Object> tmp) {
   
   
        PomModules tmpDto = new PomModules();
        tmpDto.module = (List<String>) tmp.getOrDefault("module", new ArrayList<>());
        return tmpDto;
    }

    public static PomProperties exchangePomProperties(Map<String, Object> tmp) {
   
   
        PomProperties tmpDto = new PomProperties();
        tmpDto.log4j2Version = (String) tmp.getOrDefault("log4j2.version", "");
        tmpDto.mavenJarPluginVersion = (String) tmp.getOrDefault("maven-jar-plugin.version", "");
        tmpDto.nssCommonVersion = (String) tmp.getOrDefault("nss.common.version", "");
        tmpDto.javaVersion= (String) tmp.getOrDefault("java.version", "");
        tmpDto.projectReportingOutputEncoding = (String) tmp.getOrDefault("project.reporting.outputEncoding", "");
        tmpDto.projectBuildSourceEncoding = (String) tmp.getOrDefault("project.build.sourceEncoding", "");
        tmpDto.mybatisPlusVersion = (String) tmp.getOrDefault("mybatis-plus.version", "");
        tmpDto.druidVersion = (String) tmp.getOrDefault("druid.version", "");
        tmpDto.jwtVersion = (String) tmp.getOrDefault("jwt.version", "");
        tmpDto.commonsVersion = (String) tmp.getOrDefault("commons.version", "");
        tmpDto.aliyunJavaSdkCoreVersion = (String) tmp.getOrDefault("aliyun-java-sdk-core.version", "");
        tmpDto.aliyunJavaSdkDysmsapiVersion = (String) tmp.getOrDefault("aliyun-java-sdk-dysmsapi.version", "");
        return tmpDto;
    }

    public static PomDependencies exchangePomDependencies(Map<String, Object> tmp) {
   
   
        PomDependencies tmpDto = new PomDependencies();
        try {
   
   
            tmpDto.dependency = new ArrayList<>();
            List<Map<String, Object>> tmpDependency = (List<Map<String, Object>>) tmp.getOrDefault("dependency", new ArrayList<>());
            for (Map<String, Object> a : tmpDependency) {
   
   
                tmpDto.dependency.add(exchangePomDependenciesDependency(a));
            }
        } catch (Exception e) {
   
   
        }

        return tmpDto;
    }

    public static PomDependenciesDependency exchangePomDependenciesDependency(Map<String, Object> tmp) {
   
   
        PomDependenciesDependency tmpDto = new PomDependenciesDependency();
        tmpDto.groupId = (String) tmp.getOrDefault("groupId", "");
        tmpDto.scope = (String) tmp.getOrDefault("scope", "");
        tmpDto.artifactId = (String) tmp.getOrDefault("artifactId", "");
        tmpDto.exclusions = exchangePomDependenciesDependencyExclusions((Map<String, Object>) tmp.getOrDefault("exclusions", new HashMap<>()));
        tmpDto.version = (String) tmp.getOrDefault("version", "");
        return tmpDto;
    }

    public static PomDependenciesDependencyExclusions exchangePomDependenciesDependencyExclusions(Map<String, Object> tmp) {
   
   
        PomDependenciesDependencyExclusions tmpDto = new PomDependenciesDependencyExclusions();
        tmpDto.exclusion = exchangePomDependenciesDependencyExclusionsExclusion((Map<String, Object>) tmp.getOrDefault("exclusion", new HashMap<>()));
        return tmpDto;
    }

    public static PomDependenciesDependencyExclusionsExclusion exchangePomDependenciesDependencyExclusionsExclusion(Map<String, Object> tmp) {
   
   
        PomDependenciesDependencyExclusionsExclusion tmpDto = new PomDependenciesDependencyExclusionsExclusion();
        tmpDto.groupId = (String) tmp.getOrDefault("groupId", "");
        tmpDto.artifactId = (String) tmp.getOrDefault("artifactId", "");
        return tmpDto;
    }

    public static PomDependencymanagement exchangePomDependencyManagement(Map<String, Object> tmp) {
   
   
        PomDependencymanagement tmpDto = new PomDependencymanagement();
        tmpDto.dependencies = exchangePomDependencymanagementDependencies((Map<String, Object>) tmp.getOrDefault("dependencies", new HashMap<>()));
        return tmpDto;
    }

    public static PomDependencymanagementDependencies exchangePomDependencymanagementDependencies(Map<String, Object> tmp) {
   
   
        PomDependencymanagementDependencies tmpDto = new PomDependencymanagementDependencies();
        try {
   
   
            tmpDto.dependency = exchangePomDependencymanagementDependenciesDependency((Map<String, Object>) tmp.getOrDefault("dependency", new HashMap<>()));
        }catch (Exception e){
   
   
            e.printStackTrace();
        }
        return tmpDto;
    }

    public static PomDependencymanagementDependenciesDependency exchangePomDependencymanagementDependenciesDependency(Map<String, Object> tmp) {
   
   
        PomDependencymanagementDependenciesDependency tmpDto = new PomDependencymanagementDependenciesDependency();
        tmpDto.groupId = (String) tmp.getOrDefault("groupId", "");
        tmpDto.artifactId = (String) tmp.getOrDefault("artifactId", "");
        tmpDto.version = (String) tmp.getOrDefault("version", "");
        return tmpDto;
    }

    public static PomBuild exchangePomBuild(Map<String, Object> tmp) {
   
   
        PomBuild tmpDto = new PomBuild();
        tmpDto.plugins = exchangePomBuildPlugins((Map<String, Object>) tmp.getOrDefault("plugins", new HashMap<>()));
        tmpDto.resources = exchangePomBuildResources((Map<String, Object>) tmp.getOrDefault("resources", new HashMap<>()));
        return tmpDto;
    }

    public static PomBuildPlugins exchangePomBuildPlugins(Map<String, Object> tmp) {
   
   
        PomBuildPlugins tmpDto = new PomBuildPlugins();
        try {
   
   
            tmpDto.plugin = new ArrayList<>();
            List<Map<String, Object>> tmpPlugin = (List<Map<String, Object>>) tmp.getOrDefault("plugin", new ArrayList<>());
            for (Map<String, Object> a : tmpPlugin) {
   
   
                tmpDto.plugin.add(exchangePomBuildPluginsPlugin(a));
            }
        } catch (Exception e) {
   
   
        }

        return tmpDto;
    }

    public static PomBuildPluginsPlugin exchangePomBuildPluginsPlugin(Map<String, Object> tmp) {
   
   
        PomBuildPluginsPlugin tmpDto = new PomBuildPluginsPlugin();
        tmpDto.configuration = exchangePomBuildPluginsPluginConfiguration((Map<String, Object>) tmp.getOrDefault("configuration", new HashMap<>()));
        tmpDto.groupId = (String) tmp.getOrDefault("groupId", "");
        tmpDto.artifactId = (String) tmp.getOrDefault("artifactId", "");
        return tmpDto;
    }

    public static PomBuildPluginsPluginConfiguration exchangePomBuildPluginsPluginConfiguration(Map<String, Object> tmp) {
   
   
        PomBuildPluginsPluginConfiguration tmpDto = new PomBuildPluginsPluginConfiguration();
        tmpDto.source = (String) tmp.getOrDefault("source", "");
        tmpDto.target = (String) tmp.getOrDefault("target", "");
        tmpDto.encoding = (String) tmp.getOrDefault("encoding", "");
        return tmpDto;
    }

    public static PomBuildResources exchangePomBuildResources(Map<String, Object> tmp) {
   
   
        PomBuildResources tmpDto = new PomBuildResources();
        try {
   
   
            tmpDto.resource = new ArrayList<>();
            List<Map<String, Object>> tmpResource = (List<Map<String, Object>>) tmp.getOrDefault("resource", new ArrayList<>());
            for (Map<String, Object> a : tmpResource) {
   
   
                tmpDto.resource.add(exchangePomBuildResourcesResource(a));
            }
        } catch (Exception e) {
   
   
        }

        return tmpDto;
    }

    public static PomBuildResourcesResource exchangePomBuildResourcesResource(Map<String, Object> tmp) {
   
   
        PomBuildResourcesResource tmpDto = new PomBuildResourcesResource();
        tmpDto.includes = exchangePomBuildResourcesResourceIncludes((Map<String, Object>) tmp.getOrDefault("includes", new HashMap<>()));
        tmpDto.directory = (String) tmp.getOrDefault("directory", "");
        tmpDto.filtering = (String) tmp.getOrDefault("filtering", "");
        return tmpDto;
    }

    public static PomBuildResourcesResourceIncludes exchangePomBuildResourcesResourceIncludes(Map<String, Object> tmp) {
   
   
        PomBuildResourcesResourceIncludes tmpDto = new PomBuildResourcesResourceIncludes();
        tmpDto.include = (List<String>) tmp.getOrDefault("include", new ArrayList<>());
        return tmpDto;
    }
}
解析所有的Controller
public static List<JavaController> getAllController(String folder, String ignores) {
   
   
        FolderUtils.Dir dir = FolderUtils.getFolder(folder, ignores);
        List<String> controllerPaths = FolderUtils.getAbsolutePathOfDirContentByCondition(dir, "@Controller");
        controllerPaths.addAll(FolderUtils.getAbsolutePathOfDirContentByCondition(dir, "@RestController"));
        Collections.sort(controllerPaths);
        List<JavaController> ans = new ArrayList<>();
        Pattern pattern = Pattern.compile(PatternEnum.CLASS_TITLE.getRegexp());
        Pattern zhuShiPattern = Pattern.compile(PatternEnum.CONTROLLER_FUNC_ZHUSHI.getRegexp());
        Set<String> controllerSet = new HashSet<>();
        for (String path : controllerPaths) {
   
   
            String content = FileUtils.getFileContent(path, false);
            // TODO: 2022/5/18 寻找controller的类标头
            Matcher matcher = pattern.matcher(content);
            if (matcher.find()) {
   
   
                String xx = matcher.group("name").trim();
                if (controllerSet.contains(xx)) {
   
   
                    continue;
                }
                controllerSet.add(xx);
                JavaController controller = new JavaController();
                controller.setAbsolutePath(path);
                controller.setName(xx);
                // TODO: 2022/5/18 寻找各个方法
                StringBuilder tmpContent = new StringBuilder();
                tmpContent.append(content);
                List<String> x = getAllResultByRegexp(tmpContent.toString(), zhuShiPattern);
                controller.getMethodZhuShi().addAll(x);
                controller.getAllZhuShi().addAll(getAllResultByRegexp(tmpContent.toString(), Pattern.compile(PatternEnum.ZHUSHI_YANZHENG.getRegexp())));
                controller.getAllZhuShi().addAll(getAllResultByRegexp(tmpContent.toString(), Pattern.compile(PatternEnum.ZHUSHI_2.getRegexp())));
                ans.add(controller);
            }
        }
        return ans;
    }
获取所有的类
public static List<JavaClass> getAllClass(String folder, String ignores) {
   
   
        FolderUtils.Dir dir = FolderUtils.getFolder(folder, ignores);
        List<String> classPaths = FolderUtils.getAbsolutePathOfDirNameByCondition(dir, ".java");
        Pattern pattern = Pattern.compile(PatternEnum.CLASS_TITLE.getRegexp());
        Set<String> controllerSet = new HashSet<>();
        List<JavaClass> ans = new ArrayList<>();
        for (String path : classPaths) {
   
   
            String content = FileUtils.getFileContent(path, false);
            // TODO: 2022/5/18 寻找controller的类标头
            Matcher matcher = pattern.matcher(content);
            if (matcher.find()) {
   
   
                String xx = matcher.group("name").trim();
                if (controllerSet.contains(xx)) {
   
   
                    continue;
                }
                controllerSet.add(xx);
                JavaClass controller = new JavaClass();
                controller.setAbsolutePath(path);
                controller.setName(xx);
                // TODO: 2022/5/18 寻找各个方法
                StringBuilder tmpContent = new StringBuilder();
                tmpContent.append(content);
                controller.getAllAnaotion().addAll(getAllResultByRegexp(tmpContent.toString(), Pattern.compile(PatternEnum.ANA.getRegexp())));
                controller.getAllZhuShi().addAll(getAllResultByRegexp(tmpContent.toString(), Pattern.compile(PatternEnum.ZHUSHI_YANZHENG.getRegexp())));
                controller.getAllZhuShi().addAll(getAllResultByRegexp(tmpContent.toString(), Pattern.compile(PatternEnum.ZHUSHI_2.getRegexp())));
                ans.add(controller);
            }
        }
        return ans;
    }

比对两个项目

在完成对Java项目进行反序列化之后,我们对两个不同的项目进行比较

public static Double rejectProjects(JavaProject source, JavaProject target, String ignores) {
   
   
        System.out.println("-----生成分析结果--------");
//        Double zhuShi = rejectAllZhuShi(source, target);
//        Double classNum = rejectAllClass(source, target);
//        Double utils = rejectAllUtils(source, target);
        Map<String, JavaClass> sourceName2Class = new HashMap<>();
        List<JavaClass> sourceClasses = source.getClasses();
        for (JavaClass javaClass : sourceClasses) {
   
   
            sourceName2Class.put(javaClass.getName(), javaClass);
        }
        Double total = 0.0;
        int cnt = 0;
        for (JavaClass javaClass : target.getClasses()) {
   
   
            if (sourceName2Class.containsKey(javaClass.getName())) {
   
   
                cnt++;
                System.out.println("开始分析 " + javaClass.getName());
                String sourceClassBody = FileUtils.getFileContent(sourceName2Class.get(javaClass.getName()).getAbsolutePath(), false);
                for (String zhuShi1 : sourceName2Class.get(javaClass.getName()).getAllZhuShi()) {
   
   
                    sourceClassBody = sourceClassBody.replace(zhuShi1, "");
                }
                String targetClassBody = FileUtils.getFileContent(javaClass.getAbsolutePath(), false);
                for (String zhuShi2 : javaClass.getAllZhuShi()) {
   
   
                    targetClassBody = targetClassBody.replace(zhuShi2, "");
                }
                total += classSimilarity(sourceClassBody, targetClassBody, new HashSet<>(Arrays.asList(ignores.split(","))));
            }
        }

        return total / cnt;
    }

public static Map<String, Integer> splitStr(String classBody, Set<String> ignores) {
   
   
        String[] a = classBody.replaceAll(",|\\.| |\n|;|\\{|}|\\(|\\)|\\[|]|\"|==|=|<|>|:|/|\\\\|\\?|!", "----").toLowerCase().split("----");
        Map<String, Integer> ans = new HashMap<>();
        for (String aa : a) {
   
   
            if (ignores.contains(aa)) continue;
//            aa = aa.replaceAll("[\\\\u4e00-\\\\u9fa5]+","");
            if (StringUtils.hasText(aa)) {
   
   
                if (!ans.containsKey(aa)) {
   
   
                    ans.put(aa, 0);
                }
                ans.put(aa, ans.get(aa) + 1);
            }
        }
        return ans;
    }

    public static Double classSimilarity(String classA, String classB, Set<String> ignores) {
   
   
        if (classA.equals(classB)) {
   
   
            System.out.println("两边代码一模一样");
            return 1.0;
        }
        Map<String, Integer> a = splitStr(classA, ignores);
        Map<String, Integer> b = splitStr(classB, ignores);
        Set<String> xxx = new HashSet<>(a.keySet());
        xxx.addAll(b.keySet());
        if (a.size() == b.size()) {
   
   
            System.out.print("两边代码关键词数量相同,");
        } else {
   
   
            System.out.print("两边代码关键词数量不同,分别为 原始:" + a.size() + ",新的:" + b.size() + " ");
        }
        int cnt = 0;
        Set<String> numberNt = new HashSet<>();
        Set<String> strNt = new HashSet<>();
        for (String xxxx : xxx) {
   
   
            if (a.containsKey(xxxx) && b.containsKey(xxxx)) {
   
   
                if (a.get(xxxx).equals(b.get(xxxx))) {
   
   
                    cnt++;
                } else {
   
   
                    numberNt.add(xxxx);
                }
            } else {
   
   
                if (a.containsKey(xxxx) && !b.containsKey(xxxx)) {
   
   
                    strNt.add("减少了 " + xxxx);
                } else {
   
   
                    strNt.add("增加了 " + xxxx);
                }
            }
        }
        System.out.println("其中关键字数量相同的有 " + cnt + "个,占总个数的" + (2 * cnt * 1.0) / (a.size() + b.size()));
        System.out.println("数量不同的为 " + Json.toJson(numberNt));
        System.out.println("关键词不同的为 " + Json.toJson(strNt));
        System.out.println();
        return (2 * cnt * 1.0) / (a.size() + b.size());
    }

这个方案我曾经拿来比对开源项目与面试者提供的项目的区别,以查看面试者究竟是何水平。
image.png
最终会得到相似度
image.png
现贴上完整代码

import cn.chaojilaji.auto.zlang.codereview.javahandler.JavaClass;
import cn.chaojilaji.auto.zlang.codereview.javahandler.JavaProject;
import cn.chaojilaji.auto.zlang.codereview.javahandler.PatternEnum;
import cn.chaojilaji.auto.zlang.codereview.javahandler.controllerHandler.JavaController;
import cn.chaojilaji.auto.zlang.codereview.javahandler.controllerHandler.JavaHttpApi;
import cn.chaojilaji.auto.zlang.codereview.javahandler.pomHandler.PomExchange;
import cn.chaojilaji.auto.zlang.codereview.javahandler.pomHandler.data.Pom;
import cn.chaojilaji.auto.zlang.file.FileUtils;
import cn.chaojilaji.auto.zlang.file.FolderUtils;
import cn.chaojilaji.auto.zlang.generate.DuiJieUtils;
import cn.chaojilaji.auto.zlang.generate.GenerateDto;
import cn.chaojilaji.auto.zlang.generate.GenerateFile;
import cn.chaojilaji.auto.zlang.json.Json;
import cn.chaojilaji.auto.zlang.string.StringFormatUtils;
import cn.chaojilaji.auto.zlang.yaml.YamlUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.omg.Messaging.SYNC_WITH_TRANSPORT;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class JavaProjectCodeReview {
   
   


    /**
     * 该函数为准备阶段函数
     *
     * @param file
     */
    public static void getPomStruct(String file) {
   
   
        String xmlStr = FileUtils.getFileContent(file, false);
        ObjectMapper xmlMapper = new XmlMapper();
        Map y = null;
        try {
   
   
            y = xmlMapper.readValue(xmlStr, Map.class);
            String json = Json.toJson(y);
            List<GenerateDto> generateDtos = DuiJieUtils.recursionJson(json, "Pom");
            GenerateFile.createExchange(generateDtos, "src/main/java/cn/chaojilaji/auto/zlang/codereview/javahandler/pomHandler", "Pom");
            for (GenerateDto dto : generateDtos) {
   
   
                GenerateFile.createDto(dto, "src/main/java/cn/chaojilaji/auto/zlang/codereview/javahandler/pomHandler/data");
            }
        } catch (Exception e) {
   
   
            e.printStackTrace();
        }
    }


    public static List<Pom> getPomContent(String folder, String ignores) {
   
   
        FolderUtils.Dir dir = FolderUtils.getFolder(folder, ignores);
        List<String> pomPaths = FolderUtils.getAbsolutePathOfDirNameByCondition(dir, "pom.xml");
        List<Pom> poms = new ArrayList<>();
        for (String pomPath : pomPaths) {
   
   
            String content = FileUtils.getFileContent(pomPath, false);
            ObjectMapper xmlMapper = new XmlMapper();
            try {
   
   
                Pom pom = PomExchange.exchangePom(xmlMapper.readValue(content, Map.class));
                poms.add(pom);
            } catch (JsonProcessingException e) {
   
   
                e.printStackTrace();
            }
        }
        return poms;
    }

    public static void getPropertyContent(String folder, String ignores, JavaProject project) {
   
   
        FolderUtils.Dir dir = FolderUtils.getFolder(folder, ignores);
        List<String> properties = FolderUtils.getAbsolutePathOfDirNameByCondition(dir, ".yml");
        properties.addAll(FolderUtils.getAbsolutePathOfDirNameByCondition(dir, ".property"));
        for (String path : properties) {
   
   
            if (path.endsWith(".yml")) {
   
   
                Map<String, Object> xx = YamlUtils.loadFromFile2Map(path);
                if (Objects.isNull(xx)) continue;
                for (Map.Entry<String, Object> xxx : xx.entrySet()) {
   
   
                    String xxxx = xxx.getKey().replace("_", "").toLowerCase() + " : "
                            + xxx.getValue().toString().replace("_", "").toLowerCase();
                    if (xxxx.contains("url")
                            || xxxx.contains("password")
                            || xxxx.contains("pwd")
//                            || xxxx.contains("path")
                            || xxxx.contains("username")
                            || xxxx.contains("http")) {
   
   
                        project.getSensitiveProperties().add(xxxx);
                    }
                    project.getAllProperties().add(xxxx);
                }
            } else {
   
   
                List<String> content = FileUtils.getListKeyWithOneLine(path, false);
                for (String x : content) {
   
   
                    String xxxx = x.replaceAll("_", "").toLowerCase();
                    if (xxxx.contains("url")
                            || xxxx.contains("password")
                            || xxxx.contains("pwd")
//                            || xxxx.contains("path")
                            || xxxx.contains("username")
                            || xxxx.contains("http")) {
   
   
                        project.getSensitiveProperties().add(xxxx);
                    }
                    project.getAllProperties().add(xxxx);
                }
            }
        }
    }

    public static List<String> getAllResultByRegexp(String content, Pattern pattern) {
   
   
        Matcher matcher = pattern.matcher(content);
        List<String> ans = new ArrayList<>();
        while (matcher.find()) {
   
   
            String x = matcher.group();
            ans.add(x);
//            System.out.println(x);
//            System.out.println("begin = " + matcher.start() + ", end = " + matcher.end());
        }
        return ans;

    }

    public static List<JavaClass> getAllClass(String folder, String ignores) {
   
   
        FolderUtils.Dir dir = FolderUtils.getFolder(folder, ignores);
        List<String> classPaths = FolderUtils.getAbsolutePathOfDirNameByCondition(dir, ".java");
        Pattern pattern = Pattern.compile(PatternEnum.CLASS_TITLE.getRegexp());
        Set<String> controllerSet = new HashSet<>();
        List<JavaClass> ans = new ArrayList<>();
        for (String path : classPaths) {
   
   
            String content = FileUtils.getFileContent(path, false);
            // TODO: 2022/5/18 寻找controller的类标头
            Matcher matcher = pattern.matcher(content);
            if (matcher.find()) {
   
   
                String xx = matcher.group("name").trim();
                if (controllerSet.contains(xx)) {
   
   
                    continue;
                }
                controllerSet.add(xx);
                JavaClass controller = new JavaClass();
                controller.setAbsolutePath(path);
                controller.setName(xx);
                // TODO: 2022/5/18 寻找各个方法
                StringBuilder tmpContent = new StringBuilder();
                tmpContent.append(content);
                controller.getAllAnaotion().addAll(getAllResultByRegexp(tmpContent.toString(), Pattern.compile(PatternEnum.ANA.getRegexp())));
                controller.getAllZhuShi().addAll(getAllResultByRegexp(tmpContent.toString(), Pattern.compile(PatternEnum.ZHUSHI_YANZHENG.getRegexp())));
                controller.getAllZhuShi().addAll(getAllResultByRegexp(tmpContent.toString(), Pattern.compile(PatternEnum.ZHUSHI_2.getRegexp())));
                ans.add(controller);
            }
        }
        return ans;
    }

    public static List<JavaController> getAllController(String folder, String ignores) {
   
   
        FolderUtils.Dir dir = FolderUtils.getFolder(folder, ignores);
        List<String> controllerPaths = FolderUtils.getAbsolutePathOfDirContentByCondition(dir, "@Controller");
        controllerPaths.addAll(FolderUtils.getAbsolutePathOfDirContentByCondition(dir, "@RestController"));
        Collections.sort(controllerPaths);
        List<JavaController> ans = new ArrayList<>();
        Pattern pattern = Pattern.compile(PatternEnum.CLASS_TITLE.getRegexp());
        Pattern zhuShiPattern = Pattern.compile(PatternEnum.CONTROLLER_FUNC_ZHUSHI.getRegexp());
        Set<String> controllerSet = new HashSet<>();
        for (String path : controllerPaths) {
   
   
            String content = FileUtils.getFileContent(path, false);
            // TODO: 2022/5/18 寻找controller的类标头
            Matcher matcher = pattern.matcher(content);
            if (matcher.find()) {
   
   
                String xx = matcher.group("name").trim();
                if (controllerSet.contains(xx)) {
   
   
                    continue;
                }
                controllerSet.add(xx);
                JavaController controller = new JavaController();
                controller.setAbsolutePath(path);
                controller.setName(xx);
                // TODO: 2022/5/18 寻找各个方法
                StringBuilder tmpContent = new StringBuilder();
                tmpContent.append(content);
                List<String> x = getAllResultByRegexp(tmpContent.toString(), zhuShiPattern);
                controller.getMethodZhuShi().addAll(x);
                controller.getAllZhuShi().addAll(getAllResultByRegexp(tmpContent.toString(), Pattern.compile(PatternEnum.ZHUSHI_YANZHENG.getRegexp())));
                controller.getAllZhuShi().addAll(getAllResultByRegexp(tmpContent.toString(), Pattern.compile(PatternEnum.ZHUSHI_2.getRegexp())));
                ans.add(controller);
            }
        }
        return ans;
    }

    public static void categoryClass(JavaProject project) {
   
   
        List<JavaClass> javaClasses = project.getClasses();
        for (JavaClass javaClass : javaClasses) {
   
   
            String x = javaClass.getName().toLowerCase();
            x = x.toLowerCase().trim();
            if (x.endsWith("pojo") || x.endsWith("query") || x.endsWith("bo")
                    || x.endsWith("ao") || x.endsWith("dto") || x.endsWith("vo")
                    || x.endsWith("entity")) {
   
   
                if (x.split(" ").length == 1) {
   
   
                    project.getPojo().add(javaClass);
                    if (x.endsWith("query")) {
   
   
                        project.getQuery().add(javaClass);
                    }
                    if (x.endsWith("vo")) {
   
   
                        project.getVo().add(javaClass);
                    }
                    if (x.endsWith("dto")) {
   
   
                        project.getDto().add(javaClass);
                    }
                }
            }
            if (x.contains("service") || x.contains("server") || x.contains("task")) {
   
   
                project.getServices().add(javaClass);
            }
            if (x.contains("repository") || x.contains("dao") || x.contains("mapper")) {
   
   
                project.getRepository().add(javaClass);
            }
            if (x.contains("util")) {
   
   
                project.getUtils().add(javaClass);
            }
        }
    }

    public static void getAllZhuShi(JavaProject project) {
   
   
        List<JavaClass> classes = project.getClasses();
        for (JavaClass javaClass : classes) {
   
   
            if (Objects.nonNull(javaClass.getAllZhuShi())) {
   
   
                project.getAllZhuShi().addAll(javaClass.getAllZhuShi());
            }
        }
    }

    public static JavaClass getJavaClassByName(String name, JavaProject javaProject) {
   
   
        for (JavaClass javaClass : javaProject.getClasses()) {
   
   
            if (javaClass.getName().equalsIgnoreCase(name)) {
   
   
                return javaClass;
            }
        }
        return null;
    }

    public static void handleFields(JavaClass javaClass) {
   
   
        String path = javaClass.getAbsolutePath();
        String content = FileUtils.getFileContent(path, false);
        Pattern pattern1 = Pattern.compile("((public|private|protect) )(?<type>[<>a-zA-Z0-9]+) (?<name>[a-zA-Z0-9]+);");
        Matcher matcher = pattern1.matcher(content);
        while (matcher.find()) {
   
   
            String type = matcher.group("type");
            String name = matcher.group("name");
            if (type.equalsIgnoreCase(javaClass.getName())) {
   
   
                continue;
            }
            javaClass.getFields().put(StringFormatUtils.camel(name), type);
        }
    }

    public static Map<String, Object> getApisParams(String params, JavaProject javaProject) {
   
   
        Matcher requestBodyMatcher = PatternEnum.PARAMS_REQUEST_BODY.getPattern().matcher(params);
        Matcher queryObjectMatcher = PatternEnum.PARAMS_QUERY.getPattern().matcher(params);
        Matcher pathMatcher = PatternEnum.PARAMS_PATH.getPattern().matcher(params);
        Matcher paramMatcher = PatternEnum.PARAMS_REQUEST_PARAM.getPattern().matcher(params);
        Matcher param2Matcher = PatternEnum.PARAMS_REQUEST_PARAM2.getPattern().matcher(params);
        Matcher fileMatcher = PatternEnum.PARAMS_MULTIPARTFILE.getPattern().matcher(params);
        Map<String, Object> ans = new HashMap<>();
        while (requestBodyMatcher.find()) {
   
   
            String className = requestBodyMatcher.group("type");
            if (StringUtils.hasText(className)) {
   
   
                JavaClass javaClass = getJavaClassByName(className, javaProject);
                if (Objects.nonNull(javaClass)) {
   
   
                    ans.put(javaClass.getName(), javaClass.getFields());
                } else {
   
   
                    ans.put(className, "项目中不存在");
                }
            }
        }
        while (queryObjectMatcher.find()) {
   
   
            String className = queryObjectMatcher.group("queryObject");
            if (StringUtils.hasText(className)) {
   
   
                JavaClass javaClass = getJavaClassByName(className, javaProject);
                if (Objects.nonNull(javaClass)) {
   
   
                    ans.put(javaClass.getName(), javaClass.getFields());
                } else {
   
   
                    ans.put(className, "项目中不存在");
                }
            }
        }
        while (pathMatcher.find()) {
   
   
            String innerName = pathMatcher.group("innerName");
            String type = pathMatcher.group("type");
            if (StringUtils.hasText(innerName))
            ans.put(StringFormatUtils.camel(innerName), type);
        }
        while (paramMatcher.find()) {
   
   
            String innerName = paramMatcher.group("innerName");
            String type = paramMatcher.group("type");
            String nullable = paramMatcher.group("nullable");
            String outerName = paramMatcher.group("outerName");
            String value = type;
            String key = outerName;
            if (StringUtils.hasText(nullable)){
   
   
                value = value + " or nullable";
            }
            if (StringUtils.hasText(innerName)){
   
   
                key = innerName;
            }
            if (StringUtils.hasText(key))
            ans.put(StringFormatUtils.camel(key),value);
        }
        while (param2Matcher.find()) {
   
   
            String innerName = param2Matcher.group("innerName");
            String type = param2Matcher.group("type");
            String nullable = param2Matcher.group("nullable");
            String outerName = param2Matcher.group("outerName");
            String value = type;
            String key = outerName;
            if (StringUtils.hasText(nullable)){
   
   
                value = value + " or nullable";
            }
            if (StringUtils.hasText(innerName)){
   
   
                key = innerName;
            }
            if (StringUtils.hasText(key))
                ans.put(StringFormatUtils.camel(key),value);
        }
        while (fileMatcher.find()){
   
   
            String name = fileMatcher.group("name");
            if (StringUtils.hasText(name))
            ans.put(StringFormatUtils.camel(name),"file");
        }
        return ans;
    }

    public static void getControllerHttpMethod(JavaProject project) {
   
   
        Pattern pattern = Pattern.compile(PatternEnum.CONTROLLER_2_API.getRegexp());
        List<JavaController> controllers = project.getPublicControllers();
        for (JavaController controller : controllers) {
   
   
            String content = FileUtils.getFileContent(controller.getAbsolutePath(), false);
            Matcher matcher = pattern.matcher(content);
            while (matcher.find()) {
   
   
                String method = matcher.group("method");
                String path = matcher.group("path");
                String name = matcher.group("name");
                String params = matcher.group("params");
                String responseBodyOrNot = matcher.group("jsonOrNot");
                if (method.toLowerCase().equals("request")) {
   
   
                    method = matcher.group(4);
                }
                JavaHttpApi api = new JavaHttpApi();
                api.setBelongController(controller.getName());
                api.setMethod(Objects.isNull(method) ? "controller上的或未定义" : method);
                api.setUrl(path);
                api.setParamStr(params);
                api.setParamJsons(getApisParams(params,project));
                api.setName(name);
                controller.getApis().add(api);
            }
        }
    }


    public static JavaProject reviewJavaProject(String folder, String ignores) {
   
   
        JavaProject project = new JavaProject();
        project.setName(folder.replaceAll("/", "").replace("\\", "").toLowerCase());
        project.setPath(folder);
        project.getPoms().addAll(getPomContent(folder, ignores));
        project.getPublicControllers().addAll(getAllController(folder, ignores));
        getPropertyContent(folder, ignores, project);
        project.getClasses().addAll(getAllClass(folder, ignores));
        for (JavaClass javaClass : project.getClasses()) {
   
   
            project.getAllAnoations().addAll(javaClass.getAllAnaotion());
            handleFields(javaClass);
        }
        categoryClass(project);
        getAllZhuShi(project);
        getControllerHttpMethod(project);
        System.out.println(project.getPublicControllers().size());
        return project;
    }

    public static Double rejectAllZhuShi(JavaProject source, JavaProject target) {
   
   
        System.out.println("-----生成分析结果--------");
        Set<String> x = new HashSet<>(source.getAllZhuShi());
        x.retainAll(target.getAllZhuShi());
        int n = target.getAllZhuShi().size();
        int cnt = 0;
        for (int i = 0; i < n; i++) {
   
   
            if (x.contains(target.getAllZhuShi().get(i))) {
   
   
                cnt++;
            }
        }
        Map<String, Object> params = new HashMap<>();
        params.put("old_size", source.getAllZhuShi().size());
        params.put("new_size", target.getAllZhuShi().size());
        params.put("new_in_old_size", cnt);

        System.out.println(StringFormatUtils.formatByName("原始的注释条数为 {old_size}条,新的注释条数为{new_size}条,其中相同的注释有 {new_in_old_size} 条", params));
        return (2 * cnt) / (source.getAllZhuShi().size() + target.getAllZhuShi().size()) * 1.0;
    }

    public static Double rejectAllClass(JavaProject source, JavaProject target) {
   
   
        List<JavaClass> javaClasses = source.getClasses();
        Set<String> x = new HashSet<>(javaClasses.stream().map(JavaClass::getName).collect(Collectors.toSet()));
        x.retainAll(target.getClasses().stream().map(JavaClass::getName).collect(Collectors.toSet()));
        Map<String, Object> params = new HashMap<>();
        params.put("old_size", source.getClasses().size());
        params.put("new_size", target.getClasses().size());
        params.put("new_in_old_size", x.size());

        System.out.println(StringFormatUtils.formatByName("原始的类的个数为 {old_size}条,新的类的个数为{new_size}条,其中相同的类的个数有 {new_in_old_size} 条", params));
        return (2 * x.size()) / (source.getAllZhuShi().size() + target.getAllZhuShi().size()) * 1.0;
    }

    public static Double rejectAllUtils(JavaProject source, JavaProject target) {
   
   
        List<JavaClass> javaClasses = source.getUtils();
        Set<String> x = new HashSet<>(javaClasses.stream().map(JavaClass::getName).collect(Collectors.toSet()));
        x.retainAll(target.getUtils().stream().map(JavaClass::getName).collect(Collectors.toSet()));
        Map<String, Object> params = new HashMap<>();
        params.put("old_size", source.getUtils().size());
        params.put("new_size", target.getUtils().size());
        params.put("new_in_old_size", x.size());

        System.out.println(StringFormatUtils.formatByName("原始的工具类的个数为 {old_size}条,新的工具类的个数为{new_size}条,其中相同的工具类的个数有 {new_in_old_size} 条", params));
        return (2 * x.size()) / (source.getAllZhuShi().size() + target.getAllZhuShi().size()) * 1.0;
    }

    public static Map<String, Integer> splitStr(String classBody, Set<String> ignores) {
   
   
        String[] a = classBody.replaceAll(",|\\.| |\n|;|\\{|}|\\(|\\)|\\[|]|\"|==|=|<|>|:|/|\\\\|\\?|!", "----").toLowerCase().split("----");
        Map<String, Integer> ans = new HashMap<>();
        for (String aa : a) {
   
   
            if (ignores.contains(aa)) continue;
//            aa = aa.replaceAll("[\\\\u4e00-\\\\u9fa5]+","");
            if (StringUtils.hasText(aa)) {
   
   
                if (!ans.containsKey(aa)) {
   
   
                    ans.put(aa, 0);
                }
                ans.put(aa, ans.get(aa) + 1);
            }
        }
        return ans;
    }

    public static Double classSimilarity(String classA, String classB, Set<String> ignores) {
   
   
        if (classA.equals(classB)) {
   
   
            System.out.println("两边代码一模一样");
            return 1.0;
        }
        Map<String, Integer> a = splitStr(classA, ignores);
        Map<String, Integer> b = splitStr(classB, ignores);
        Set<String> xxx = new HashSet<>(a.keySet());
        xxx.addAll(b.keySet());
        if (a.size() == b.size()) {
   
   
            System.out.print("两边代码关键词数量相同,");
        } else {
   
   
            System.out.print("两边代码关键词数量不同,分别为 原始:" + a.size() + ",新的:" + b.size() + " ");
        }
        int cnt = 0;
        Set<String> numberNt = new HashSet<>();
        Set<String> strNt = new HashSet<>();
        for (String xxxx : xxx) {
   
   
            if (a.containsKey(xxxx) && b.containsKey(xxxx)) {
   
   
                if (a.get(xxxx).equals(b.get(xxxx))) {
   
   
                    cnt++;
                } else {
   
   
                    numberNt.add(xxxx);
                }
            } else {
   
   
                if (a.containsKey(xxxx) && !b.containsKey(xxxx)) {
   
   
                    strNt.add("减少了 " + xxxx);
                } else {
   
   
                    strNt.add("增加了 " + xxxx);
                }
            }
        }
        System.out.println("其中关键字数量相同的有 " + cnt + "个,占总个数的" + (2 * cnt * 1.0) / (a.size() + b.size()));
        System.out.println("数量不同的为 " + Json.toJson(numberNt));
        System.out.println("关键词不同的为 " + Json.toJson(strNt));
        System.out.println();
        return (2 * cnt * 1.0) / (a.size() + b.size());
    }


    public static Double rejectProjects(JavaProject source, JavaProject target, String ignores) {
   
   
        System.out.println("-----生成分析结果--------");
//        Double zhuShi = rejectAllZhuShi(source, target);
//        Double classNum = rejectAllClass(source, target);
//        Double utils = rejectAllUtils(source, target);
        Map<String, JavaClass> sourceName2Class = new HashMap<>();
        List<JavaClass> sourceClasses = source.getClasses();
        for (JavaClass javaClass : sourceClasses) {
   
   
            sourceName2Class.put(javaClass.getName(), javaClass);
        }
        Double total = 0.0;
        int cnt = 0;
        for (JavaClass javaClass : target.getClasses()) {
   
   
            if (sourceName2Class.containsKey(javaClass.getName())) {
   
   
                cnt++;
                System.out.println("开始分析 " + javaClass.getName());
                String sourceClassBody = FileUtils.getFileContent(sourceName2Class.get(javaClass.getName()).getAbsolutePath(), false);
                for (String zhuShi1 : sourceName2Class.get(javaClass.getName()).getAllZhuShi()) {
   
   
                    sourceClassBody = sourceClassBody.replace(zhuShi1, "");
                }
                String targetClassBody = FileUtils.getFileContent(javaClass.getAbsolutePath(), false);
                for (String zhuShi2 : javaClass.getAllZhuShi()) {
   
   
                    targetClassBody = targetClassBody.replace(zhuShi2, "");
                }
                total += classSimilarity(sourceClassBody, targetClassBody, new HashSet<>(Arrays.asList(ignores.split(","))));
            }
        }

        return total / cnt;
    }

    public static void main(String[] args) {
   
   
        String ignores2 = "goose,reggie,glj,itheima,*,**";
        JavaProject source = reviewJavaProject("D:\\个人\\面试的\\1 瑞吉外卖项目\\1 瑞吉外卖项目\\代码\\day06\\reggie_take_out\\reggie_take_out", "target,.mvn,.idea,.git");
        JavaProject source1 = reviewJavaProject("D:\\个人\\面试的\\5 瑞吉外卖项目优化篇\\5 瑞吉外卖项目优化篇\\代码\\day03\\reggie_take_out\\reggie_take_out", "target,.mvn,.idea,.git");
        Double y = rejectProjects(source, source1, ignores2);
        System.out.println(y);
    }



}
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7月前
|
存储 Perl
创建并发布自己的公有库和如何把私有库的文件分多层目录存储
创建并发布自己的公有库和如何把私有库的文件分多层目录存储
25 0
|
7月前
|
Java Maven
依赖版本与环境冲突问题
切换依赖版本需要刷新maven文件夹 !
71 0
|
存储 机器人 应用服务中间件
|
Java API Maven
springboot 如何查看版本号之间的相互依赖:(二)
springboot 如何查看版本号之间的相互依赖:(二)
134 0
|
Java Maven
springboot 如何查看版本号之间的相互依赖:(一)
springboot 如何查看版本号之间的相互依赖:(一)
359 0
|
JavaScript 开发者
Vite 在运行过程中是如何发现新增依赖的?
Vite 在运行过程中是如何发现新增依赖的?
237 0
|
iOS开发 Perl
iOS 同一个工程创建不同的多版本切换应用
iOS 同一个工程创建不同的多版本切换应用
iOS 同一个工程创建不同的多版本切换应用
|
算法 数据库
分布式学习十三:实现全局唯一id命名
分布式学习十三:实现全局唯一id命名
152 0
分布式学习十三:实现全局唯一id命名
|
Linux
单一版本
单一版本
103 0
|
云安全 JSON 安全
在 Python 中为无服务器应用设计安全租户隔离
软件即服务(SaaS)已经成为当今一种非常普遍的软件交付方式。虽然这方便了用户访问,而且消除了用户的运营开销,但这也改变了以前的模式,将实现 SLA 以及现代云原生组织所期望的所有安全和数据隐私要求的责任交给了软件供应商。这也是采用多租户等资源和成本效益架构模式背后的驱动力。
167 0
在 Python 中为无服务器应用设计安全租户隔离