在项目研发的过程中,我们往往会同时写多个版本的情况,而如果我们在低版本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());
}
这个方案我曾经拿来比对开源项目与面试者提供的项目的区别,以查看面试者究竟是何水平。
最终会得到相似度
现贴上完整代码
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);
}
}