From 82bc3475ae391bbb14d8d5037904d9205572c272 Mon Sep 17 00:00:00 2001 From: rayduan Date: Mon, 11 Jan 2021 12:42:39 +0800 Subject: [PATCH 01/33] =?UTF-8?q?[add]=E8=AE=A1=E7=AE=97=E5=B7=AE=E5=BC=82?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 8 + README.md | 157 +++++ application/pom.xml | 99 +++ .../com/dr/code/diff/CodeDiffApplication.java | 26 + .../dr/code/diff/config/ExecutorConfig.java | 44 ++ .../com/dr/code/diff/config/GitConfig.java | 250 +++++++ .../diff/controller/CodeDiffController.java | 55 ++ .../com/dr/code/diff/dto/ClassInfoResult.java | 58 ++ .../dr/code/diff/dto/DiffMethodParams.java | 37 ++ .../dr/code/diff/dto/MethodInfoResult.java | 25 + .../dr/code/diff/service/CodeDiffService.java | 29 + .../service/impl/CodeDiffServiceImpl.java | 34 + .../dr/code/diff/util/MethodParserUtils.java | 74 +++ .../code/diff/vo/param/CodeDiffParamVO.java | 36 + .../code/diff/vo/result/CodeDiffResultVO.java | 39 ++ .../diff/vo/result/MethodInfoResultVO.java | 35 + .../src/main/resources/application.yml | 47 ++ application/src/main/resources/log4j2.yml | 88 +++ .../dr/code/diff/CodeDiffApplicationTest.java | 23 + .../dr/code/diff/config/GitConfigTest.java | 39 ++ .../code/diff/util/MethodParserUtilsTest.java | 24 + common/pom.xml | 66 ++ .../dr/common/annotation/IdempotentCheck.java | 18 + .../com/dr/common/aop/IdempotentAspect.java | 111 ++++ .../dr/common/config/BaseConfiguration.java | 83 +++ .../com/dr/common/constant/AuthConstant.java | 42 ++ .../java/com/dr/common/constant/Constant.java | 166 +++++ .../com/dr/common/enums/AdminTypeEnum.java | 54 ++ .../dr/common/enums/PermissionTypeEnum.java | 67 ++ .../com/dr/common/errorcode/BaseCode.java | 102 +++ .../java/com/dr/common/errorcode/BizCode.java | 71 ++ .../java/com/dr/common/errorcode/Code.java | 9 + .../dr/common/exception/BaseException.java | 48 ++ .../com/dr/common/exception/BizException.java | 25 + .../dr/common/httpclient/HttpClientUtil.java | 131 ++++ .../common/httpclient/HttpRequestResult.java | 24 + .../java/com/dr/common/log/LoggerUtil.java | 85 +++ .../java/com/dr/common/page/PageParam.java | 29 + .../java/com/dr/common/page/PageResult.java | 52 ++ .../com/dr/common/response/ApiResponse.java | 72 ++ .../com/dr/common/utils/auth/MD5Util.java | 49 ++ .../dr/common/utils/captcha/CaptchaUtil.java | 116 ++++ .../com/dr/common/utils/date/DateUtil.java | 622 ++++++++++++++++++ .../dr/common/utils/date/JDKDateTimeUtil.java | 103 +++ .../com/dr/common/utils/date/JDKDateUtil.java | 309 +++++++++ .../com/dr/common/utils/excel/ExcelUtil.java | 221 +++++++ .../com/dr/common/utils/file/FileUtil.java | 39 ++ .../com/dr/common/utils/list/ListUtils.java | 20 + .../common/utils/mapper/OrikaMapperUtils.java | 113 ++++ .../dr/common/utils/security/AESUtils.java | 86 +++ .../com/dr/common/utils/security/Md5Util.java | 54 ++ .../dr/common/utils/security/SaltUtil.java | 30 + .../utils/spring/SpringBeanRegisterUtils.java | 81 +++ .../common/utils/spring/SpringCtxUtils.java | 102 +++ .../dr/common/utils/string/PhoneUtils.java | 54 ++ .../dr/common/utils/string/ScmStringUtil.java | 23 + pom.xml | 168 +++++ 57 files changed, 4672 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 application/pom.xml create mode 100644 application/src/main/java/com/dr/code/diff/CodeDiffApplication.java create mode 100644 application/src/main/java/com/dr/code/diff/config/ExecutorConfig.java create mode 100644 application/src/main/java/com/dr/code/diff/config/GitConfig.java create mode 100644 application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java create mode 100644 application/src/main/java/com/dr/code/diff/dto/ClassInfoResult.java create mode 100644 application/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java create mode 100644 application/src/main/java/com/dr/code/diff/dto/MethodInfoResult.java create mode 100644 application/src/main/java/com/dr/code/diff/service/CodeDiffService.java create mode 100644 application/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java create mode 100644 application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java create mode 100644 application/src/main/java/com/dr/code/diff/vo/param/CodeDiffParamVO.java create mode 100644 application/src/main/java/com/dr/code/diff/vo/result/CodeDiffResultVO.java create mode 100644 application/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java create mode 100644 application/src/main/resources/application.yml create mode 100644 application/src/main/resources/log4j2.yml create mode 100644 application/src/test/java/com/dr/code/diff/CodeDiffApplicationTest.java create mode 100644 application/src/test/java/com/dr/code/diff/config/GitConfigTest.java create mode 100644 application/src/test/java/com/dr/code/diff/util/MethodParserUtilsTest.java create mode 100644 common/pom.xml create mode 100644 common/src/main/java/com/dr/common/annotation/IdempotentCheck.java create mode 100644 common/src/main/java/com/dr/common/aop/IdempotentAspect.java create mode 100644 common/src/main/java/com/dr/common/config/BaseConfiguration.java create mode 100644 common/src/main/java/com/dr/common/constant/AuthConstant.java create mode 100644 common/src/main/java/com/dr/common/constant/Constant.java create mode 100644 common/src/main/java/com/dr/common/enums/AdminTypeEnum.java create mode 100644 common/src/main/java/com/dr/common/enums/PermissionTypeEnum.java create mode 100644 common/src/main/java/com/dr/common/errorcode/BaseCode.java create mode 100644 common/src/main/java/com/dr/common/errorcode/BizCode.java create mode 100644 common/src/main/java/com/dr/common/errorcode/Code.java create mode 100644 common/src/main/java/com/dr/common/exception/BaseException.java create mode 100644 common/src/main/java/com/dr/common/exception/BizException.java create mode 100644 common/src/main/java/com/dr/common/httpclient/HttpClientUtil.java create mode 100644 common/src/main/java/com/dr/common/httpclient/HttpRequestResult.java create mode 100644 common/src/main/java/com/dr/common/log/LoggerUtil.java create mode 100644 common/src/main/java/com/dr/common/page/PageParam.java create mode 100644 common/src/main/java/com/dr/common/page/PageResult.java create mode 100644 common/src/main/java/com/dr/common/response/ApiResponse.java create mode 100644 common/src/main/java/com/dr/common/utils/auth/MD5Util.java create mode 100644 common/src/main/java/com/dr/common/utils/captcha/CaptchaUtil.java create mode 100644 common/src/main/java/com/dr/common/utils/date/DateUtil.java create mode 100644 common/src/main/java/com/dr/common/utils/date/JDKDateTimeUtil.java create mode 100644 common/src/main/java/com/dr/common/utils/date/JDKDateUtil.java create mode 100644 common/src/main/java/com/dr/common/utils/excel/ExcelUtil.java create mode 100644 common/src/main/java/com/dr/common/utils/file/FileUtil.java create mode 100644 common/src/main/java/com/dr/common/utils/list/ListUtils.java create mode 100644 common/src/main/java/com/dr/common/utils/mapper/OrikaMapperUtils.java create mode 100644 common/src/main/java/com/dr/common/utils/security/AESUtils.java create mode 100644 common/src/main/java/com/dr/common/utils/security/Md5Util.java create mode 100644 common/src/main/java/com/dr/common/utils/security/SaltUtil.java create mode 100644 common/src/main/java/com/dr/common/utils/spring/SpringBeanRegisterUtils.java create mode 100644 common/src/main/java/com/dr/common/utils/spring/SpringCtxUtils.java create mode 100644 common/src/main/java/com/dr/common/utils/string/PhoneUtils.java create mode 100644 common/src/main/java/com/dr/common/utils/string/ScmStringUtil.java create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..69db9df --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/.idea/ +/common/.mvn/wrapper/ +/common/.gitignore +/common/mvnw +/common/mvnw.cmd +/application/application.iml +/code-diff-parent.iml +/common/common.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..5401ad9 --- /dev/null +++ b/README.md @@ -0,0 +1,157 @@ +# code-diff +基於git的差异代码获取 + + +### 简介 ++ 本项目主要是用于基于jacoco的增量代码统计,增量代码的统计核心问题是如何获得增量代码,网络上关于增量代码的获取相关资料比较少,而且代码注释也没有,阅读起来相对困难,我这边参考了几个项目后根据实际需求,进行了整理,整个项目工程,只有application的部分代码为核心代码,其他都是辅助 + + +### 使用方法 +#### 1、修改application.yml + git: + userName: rayduan #git账号 + password: FDsfret334 #git密码 +#### 2、运行项目,访问http://127.0.0.1:8085/doc.html + 2.1 输入git地址,填写差异分支的旧版本,新版本,执行,就可以获取差异信息 + 2.2 { + "code": 10000, + "msg": "业务处理成功", + "data": [ + { + "classFile": "collector/src/main/java/com/geely/collector/CollectorApplication.java", + "methodInfos": [ + { + "md5": "13E2BFB69F7D987A6DB4272400C94E9B", + "methodName": "main", + "parameters": "[String[] args]" + } + ], + "type": "MODIFY" + }, + { + "classFile": "collector/src/main/java/com/geely/collector/bean/CodeQuality.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "collector/src/main/java/com/geely/collector/dao/basic/CodeQualityMapper.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "collector/src/main/java/com/geely/collector/dao/extension/CodeQualityExtensionMapper.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "collector/src/main/java/com/geely/collector/mvc/APIResponse.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "collector/src/main/java/com/geely/collector/mvc/BusinessException.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "collector/src/main/java/com/geely/collector/task/TestTask.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/gitlab/config/GitlabAPIConfig.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/gitlab/dto/CommitDetail.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/gitlab/dto/GitLabStats.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/gitlab/service/GitlabService.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/gitlab/service/impl/GitlabServiceImpl.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/Test.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/client/BaseHttpClient.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/client/MeasureClient.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/client/ProjectClient.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/client/authentication/PreemptiveAuth.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/config/SonarConnectionConf.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/dto/BaseModel.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/dto/MeasuresBean.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/dto/MeasuresResultDto.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/service/MeasureService.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/service/impl/MeasureServiceImpl.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/util/HttpResponseValidator.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/util/HttpResponseWrapper.java", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "third-sdk/src/main/java/com/geely/sonar/util/SonarContant.java", + "methodInfos": null, + "type": "ADD" + } + ] + } diff --git a/application/pom.xml b/application/pom.xml new file mode 100644 index 0000000..45efe3f --- /dev/null +++ b/application/pom.xml @@ -0,0 +1,99 @@ + + + + code-diff-parent + com.dr + 1.0.0-SNAPSHOT + + 4.0.0 + + application + + + + org.springframework.boot + spring-boot-starter-web + + + com.dr + common + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + org.springframework.boot + spring-boot-starter-logging + + + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + com.spring4all + swagger-spring-boot-starter + + + com.github.xiaoymin + swagger-bootstrap-ui + + + org.projectlombok + lombok + + + + org.springframework.boot + spring-boot-starter-test + test + + + + cn.afterturn + easypoi-spring-boot-starter + + + + + org.eclipse.jgit + org.eclipse.jgit + + + + + com.github.javaparser + javaparser-core + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + \ No newline at end of file diff --git a/application/src/main/java/com/dr/code/diff/CodeDiffApplication.java b/application/src/main/java/com/dr/code/diff/CodeDiffApplication.java new file mode 100644 index 0000000..40459bc --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/CodeDiffApplication.java @@ -0,0 +1,26 @@ +package com.dr.code.diff; + +import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI; +import com.spring4all.swagger.EnableSwagger2Doc; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +/** +* @date:2020/3/13 +* @className:JenkinsApplication +* @author: duanrui +* @description: jenkins服务 +* +*/ +@SpringBootApplication +@EnableSwagger2Doc +@EnableSwaggerBootstrapUI +@ComponentScan(value = "com.dr.**") +public class CodeDiffApplication { + + public static void main(String[] args) { + SpringApplication.run(CodeDiffApplication.class, args); + } + +} diff --git a/application/src/main/java/com/dr/code/diff/config/ExecutorConfig.java b/application/src/main/java/com/dr/code/diff/config/ExecutorConfig.java new file mode 100644 index 0000000..014d070 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/config/ExecutorConfig.java @@ -0,0 +1,44 @@ +package com.dr.code.diff.config; + + +import com.dr.common.log.LoggerUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * @author rui.duan + * @version 1.0 + * @className ExecutorConfig + * @description 线程池配置 + * @date 2019/9/4 4:58 下午 + */ +@Configuration +@Slf4j +public class ExecutorConfig { + + + @Bean("asyncExecutor") + public Executor asyncServiceExecutor() { + LoggerUtil.info(log, "初始化线程池"); + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //配置核心线程数 + executor.setCorePoolSize(10); + //配置最大线程数 + executor.setMaxPoolSize(22); + //配置队列大小 + executor.setQueueCapacity(10000); + //配置线程池中的线程的名称前缀 + executor.setThreadNamePrefix("thread-"); + // rejection-policy:当pool已经达到max size的时候,如何处理新任务 + // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //执行初始化 + executor.initialize(); + return executor; + } +} diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java new file mode 100644 index 0000000..11d9154 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -0,0 +1,250 @@ +package com.dr.code.diff.config; + +import com.dr.code.diff.dto.ClassInfoResult; +import com.dr.code.diff.dto.DiffMethodParams; +import com.dr.code.diff.dto.MethodInfoResult; +import com.dr.code.diff.util.MethodParserUtils; +import com.dr.common.log.LoggerUtil; +import com.dr.common.utils.file.FileUtil; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.diff.DiffEntry; +import org.eclipse.jgit.lib.ObjectReader; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.eclipse.jgit.treewalk.AbstractTreeIterator; +import org.eclipse.jgit.treewalk.CanonicalTreeParser; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.stream.Collectors; + +/** + * @author rui.duan + * @version 1.0 + * @className ShiroConfig + * @description git配置类 + * @date 2019/11/19 2:30 下午 + */ +@Configuration +@Slf4j +public class GitConfig { + + /** + * git账号 + */ + @Value(value = "${git.userName}") + private String gitUserName; + /** + * git密码 + */ + @Value(value = "${git.password}") + private String gitPassWord; + + /** + * git下载代码到本地的根目录 + */ + @Value(value = "${git.local.base.dir}") + private String localBaseRepoDir; + + + @Resource(name = "asyncExecutor") + private Executor executor; + + /** + * 克隆代码到本地 + * + * @param gitUrl + * @param codePath + * @param commitId + * @return + * @throws GitAPIException + * @throws IOException + */ + public Git cloneRepository(String gitUrl, String codePath, String commitId) { + Git git = null; + try { + if (!checkGitWorkSpace(gitUrl, codePath)) { + LoggerUtil.info(log, "本地代码不存在,clone", gitUrl, codePath); + git = Git.cloneRepository() + .setURI(gitUrl) + .setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)) + .setDirectory(new File(codePath)) + .setBranch(commitId) + .call(); + } else { + LoggerUtil.info(log, "本地代码存在,直接使用", gitUrl, codePath); + git = Git.open(new File(codePath)); + } + // 切换到指定commitId + git.checkout().setName(commitId).call(); + } catch (IOException | GitAPIException e) { + e.printStackTrace(); + } + return git; + } + + /** + * 判断工作目录是否存在 + * + * @param codePath + * @return + */ + public Boolean checkGitWorkSpace(String gitUrl, String codePath) throws IOException { + Boolean isExist = Boolean.FALSE; + File RepoGitDir = new File(codePath + "/.git"); + if (!RepoGitDir.exists()) { + return false; + } + Git git = Git.open(new File(codePath)); + if (null == git) { + return isExist; + } + Repository repository = git.getRepository(); + //解析本地代码,获取远程uri,是否是我们需要的git远程仓库 + String repoUrl = repository.getConfig().getString("remote", "origin", "url"); + if (gitUrl.equals(repoUrl)) { + isExist = Boolean.TRUE; + } else { + LoggerUtil.info(log, "本地存在其他仓的代码,先删除"); + FileUtil.removeDir(new File(codePath)); + } + return isExist; + } + + /** + * 获取差异方法 + * + * @param diffMethodParams + * @return + */ + public List diffMethods(DiffMethodParams diffMethodParams) { + try { + //原有代码git对象 + Git baseGit = cloneRepository(diffMethodParams.getGitUrl(), localBaseRepoDir + diffMethodParams.getBaseVersion(), diffMethodParams.getBaseVersion()); + //现有代码git对象 + Git nowGit = cloneRepository(diffMethodParams.getGitUrl(), localBaseRepoDir + diffMethodParams.getNowVersion(), diffMethodParams.getNowVersion()); + AbstractTreeIterator baseTree = prepareTreeParser(baseGit.getRepository(), diffMethodParams.getBaseVersion()); + AbstractTreeIterator nowTree = prepareTreeParser(nowGit.getRepository(), diffMethodParams.getNowVersion()); + //获取两个版本之间的差异代码 + List diff = nowGit.diff().setOldTree(baseTree).setNewTree(nowTree).setShowNameAndStatusOnly(true).call(); + //过滤出有效的差异代码 + Collection validDiffList = diff.stream() + //只计算java文件 + .filter(e -> e.getNewPath().endsWith(".java")) + //排除测试文件 + .filter(e -> e.getNewPath().contains("src/main/java")) + //只计算新增和变更文件 + .filter(e -> DiffEntry.ChangeType.ADD.equals(e.getChangeType()) || DiffEntry.ChangeType.MODIFY.equals(e.getChangeType())) + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(validDiffList)) { + return null; + } + /** + * 获取原类的方法 + */ + List> priceFuture = validDiffList.stream().map(item -> getClassMethods(getClassFile(baseGit, item.getNewPath()), getClassFile(nowGit, item.getNewPath()), item)).collect(Collectors.toList()); + return priceFuture.stream().map(CompletableFuture::join).filter(Objects::nonNull).collect(Collectors.toList()); + } catch (GitAPIException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 获取class文件的地址 + * + * @param git + * @param classPackage + * @return + */ + private String getClassFile(Git git, String classPackage) { + StringBuilder builder = new StringBuilder(git.getRepository().getDirectory().getParent()); + return builder.append("/") + .append(classPackage).toString(); + } + + /** + * 获取类的增量方法 + * + * @param oldClassFile 旧类的本地地址 + * @param mewClassFile 新类的本地地址 + * @param diffEntry 差异类 + * @return + */ + private CompletableFuture getClassMethods(String oldClassFile, String mewClassFile, DiffEntry diffEntry) { + //多线程获取差异方法 + return CompletableFuture.supplyAsync(() -> { + //新增类直接标记,不用计算方法 + if (DiffEntry.ChangeType.ADD.equals(diffEntry.getChangeType())) { + return ClassInfoResult.builder() + .classFile(diffEntry.getNewPath()) + .type(DiffEntry.ChangeType.ADD.name()) + .build(); + } + List diffMethods; + //获取新类的所有方法 + List newMethodInfoResults = MethodParserUtils.parseMethods(mewClassFile); + //如果新类为空,没必要比较 + if (CollectionUtils.isEmpty(newMethodInfoResults)) { + return null; + } + //获取旧类的所有方法 + List oldMethodInfoResults = MethodParserUtils.parseMethods(oldClassFile); + //如果旧类为空,新类的方法所有为增量 + if (CollectionUtils.isEmpty(oldMethodInfoResults)) { + diffMethods = newMethodInfoResults; + } else { //否则,计算增量方法 + List md5s = oldMethodInfoResults.stream().map(MethodInfoResult::getMd5).collect(Collectors.toList()); + diffMethods = newMethodInfoResults.stream().filter(m -> !md5s.contains(m.getMd5())).collect(Collectors.toList()); + } + //没有增量方法,过滤掉 + if (CollectionUtils.isEmpty(diffMethods)) { + return null; + } + ClassInfoResult result = ClassInfoResult.builder() + .classFile(diffEntry.getNewPath()) + .methodInfos(diffMethods) + .type(DiffEntry.ChangeType.MODIFY.name()) + .build(); + return result; + }, executor); + } + + + /** + * 将代码转成树状 + * + * @param repository + * @param branchName + * @return + */ + public static AbstractTreeIterator prepareTreeParser(Repository repository, String branchName) { + try { + RevWalk walk = new RevWalk(repository); + RevTree tree; + tree = walk.parseTree(repository.resolve(branchName)); + CanonicalTreeParser TreeParser = new CanonicalTreeParser(); + try (ObjectReader reader = repository.newObjectReader()) { + TreeParser.reset(reader, tree.getId()); + } + walk.dispose(); + return TreeParser; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java new file mode 100644 index 0000000..f0e1eb0 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java @@ -0,0 +1,55 @@ +package com.dr.code.diff.controller; + +import com.dr.code.diff.dto.ClassInfoResult; +import com.dr.code.diff.dto.DiffMethodParams; +import com.dr.code.diff.service.CodeDiffService; +import com.dr.code.diff.vo.result.CodeDiffResultVO; +import com.dr.common.response.ApiResponse; +import com.dr.common.utils.mapper.OrikaMapperUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * @author rui.duan + * @version 1.0 + * @className UserController + * @description 用户管理 + * @date 2019/11/20 6:25 下午 + */ +@RestController +@Api(value = "/api/code/diff", tags = "差异代码模块") +@RequestMapping("/api/code/diff") +public class CodeDiffController { + + @Autowired + private CodeDiffService codeDiffService; + + @ApiOperation("获取差异代码") + @RequestMapping(value = "/list", method = RequestMethod.GET) + public ApiResponse> getList( + @ApiParam(required = true, name = "gitUrl", value = "git远程仓库地址") + @RequestParam(value = "gitUrl") String gitUrl, + @ApiParam(required = true, name = "baseVersion", value = "git原始分支或tag") + @RequestParam(value = "baseVersion") String baseVersion, + @ApiParam(required = true, name = "nowVersion", value = "git现分支或tag") + @RequestParam(value = "nowVersion") String nowVersion) { + DiffMethodParams diffMethodParams = DiffMethodParams.builder() + .gitUrl(gitUrl) + .baseVersion(baseVersion) + .nowVersion(nowVersion) + .build(); + List diffCodeList = codeDiffService.getDiffCode(diffMethodParams); + List codeDiffResultVOS = OrikaMapperUtils.mapList(diffCodeList, ClassInfoResult.class, CodeDiffResultVO.class); + return new ApiResponse>().success(codeDiffResultVOS); + } + + +} diff --git a/application/src/main/java/com/dr/code/diff/dto/ClassInfoResult.java b/application/src/main/java/com/dr/code/diff/dto/ClassInfoResult.java new file mode 100644 index 0000000..e22cb4f --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/dto/ClassInfoResult.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2009, 2019 Mountainminds GmbH & Co. KG and Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package com.dr.code.diff.dto; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * @author dr + */ +@Builder +@Data +public class ClassInfoResult { + /** + * java文件 + */ + private String classFile; + /** + * 类名 + */ + private String className; + /** + * 包名 + */ + private String packages; + + /** + * 类中的方法 + */ + private List methodInfos; + + /** + * 新增的行数 + */ + private List addLines; + + /** + * 删除的行数 + */ + private List delLines; + + /** + * 修改类型 + */ + private String type; + +} diff --git a/application/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java b/application/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java new file mode 100644 index 0000000..591dc3b --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java @@ -0,0 +1,37 @@ +package com.dr.code.diff.dto; + +import lombok.Builder; +import lombok.Data; + +/** + * @ProjectName: base-service + * @Package: com.dr.jenkins.jenkins.dto + * @Description: 差异代码参数 + * @Author: duanrui + * @CreateDate: 2020/6/20 21:41 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2020 + */ +@Data +@Builder +public class DiffMethodParams { + + + /** + * git 远程仓库地址 + */ + private String gitUrl; + + /** + * git原始分支或tag + */ + private String baseVersion; + + /** + * git现分支或tag + */ + private String nowVersion; + + +} diff --git a/application/src/main/java/com/dr/code/diff/dto/MethodInfoResult.java b/application/src/main/java/com/dr/code/diff/dto/MethodInfoResult.java new file mode 100644 index 0000000..d6af651 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/dto/MethodInfoResult.java @@ -0,0 +1,25 @@ +package com.dr.code.diff.dto; + +import lombok.Builder; +import lombok.Data; + +/** + * @author dr + */ +@Builder +@Data +public class MethodInfoResult { + /** + * 方法的md5 + */ + public String md5; + /** + * 方法名 + */ + public String methodName; + /** + * 方法参数 + */ + public String parameters; + +} diff --git a/application/src/main/java/com/dr/code/diff/service/CodeDiffService.java b/application/src/main/java/com/dr/code/diff/service/CodeDiffService.java new file mode 100644 index 0000000..7d2a4d0 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/service/CodeDiffService.java @@ -0,0 +1,29 @@ +package com.dr.code.diff.service; + +import com.dr.code.diff.dto.ClassInfoResult; +import com.dr.code.diff.dto.DiffMethodParams; + +import java.util.List; + +/** + * @ProjectName: base-service + * @Package: com.dr.jenkins.jenkins.service + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2020/6/20 21:39 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2020 + */ +public interface CodeDiffService { + + + /** + * @date:2021/1/9 + * @className:CodeDiffService + * @author:Administrator + * @description: 获取差异代码 + */ + List getDiffCode(DiffMethodParams diffMethodParams); + +} diff --git a/application/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java b/application/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java new file mode 100644 index 0000000..a49ad11 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java @@ -0,0 +1,34 @@ +package com.dr.code.diff.service.impl; + +import com.dr.code.diff.config.GitConfig; +import com.dr.code.diff.dto.ClassInfoResult; +import com.dr.code.diff.dto.DiffMethodParams; +import com.dr.code.diff.service.CodeDiffService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ProjectName: base-service + * @Package: com.dr.jenkins.jenkins.service.impl + * @Description: 获取差异代码 + * @Author: duanrui + * @CreateDate: 2020/6/20 21:39 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2020 + */ +@Service +@Slf4j +public class CodeDiffServiceImpl implements CodeDiffService { + + @Autowired + private GitConfig gitConfig; + + @Override + public List getDiffCode(DiffMethodParams diffMethodParams) { + return gitConfig.diffMethods(diffMethodParams); + } +} diff --git a/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java new file mode 100644 index 0000000..a6f707a --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java @@ -0,0 +1,74 @@ +package com.dr.code.diff.util; + +import com.dr.code.diff.dto.MethodInfoResult; +import com.dr.common.utils.security.Md5Util; +import com.github.javaparser.StaticJavaParser; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.visitor.VoidVisitorAdapter; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.List; + +/** + * @ProjectName: base-service + * @Package: com.dr.codediff.util + * @Description: 解析获取类的方法 + * @Author: duanrui + * @CreateDate: 2021/1/8 21:06 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2021 + */ +public class MethodParserUtils { + + + /** + * 解析类获取类的所有方法 + * + * @param classFile + * @return + */ + public static List parseMethods(String classFile) { + try { + List list = new ArrayList<>(); + FileInputStream in = new FileInputStream(classFile); + CompilationUnit cu = StaticJavaParser.parse(in); + //由于jacoco不会统计结构覆盖率,没比较计算接口的方法,此处排除接口类 + final List types = cu.getTypes(); + boolean isInterface = types.stream().filter(t -> t instanceof ClassOrInterfaceDeclaration).anyMatch(t -> ((ClassOrInterfaceDeclaration) t).isInterface()); + if (isInterface) { + return list; + } + cu.accept(new MethodVisitor(), list); + return list; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + /** + * javaparser工具类核心方法,主要通过这个类便利class文件的方法,此方法主要是获取出代码的所有方法,然后再去对比方法是否存在差异 + */ + private static class MethodVisitor extends VoidVisitorAdapter> { + @Override + public void visit(MethodDeclaration n, List list) { + //删除注释 + n.removeComment(); + //计算方法体的hash值,疑问,空格,特殊转义字符会影响结果,导致相同匹配为差异 + String md5 = Md5Util.encode(n.toString()); + MethodInfoResult result = MethodInfoResult.builder() + .md5(md5) + .methodName(n.getNameAsString()) + .parameters(n.getParameters().toString()) + .build(); + list.add(result); + super.visit(n, list); + } + + } +} diff --git a/application/src/main/java/com/dr/code/diff/vo/param/CodeDiffParamVO.java b/application/src/main/java/com/dr/code/diff/vo/param/CodeDiffParamVO.java new file mode 100644 index 0000000..8cba231 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vo/param/CodeDiffParamVO.java @@ -0,0 +1,36 @@ +package com.dr.code.diff.vo.param; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @date:2021/1/9 + * @className:CodeDiffParamVO + * @author:Administrator + * @description: 增量代码请求参数 + */ +@Data +@ApiModel("增量代码获取参数") +public class CodeDiffParamVO { + + /** + * git 远程仓库地址 + */ + @ApiModelProperty(name = "name", value = "git远程仓库地址", dataType = "String", example = "https://github.com/rayduan/code-diff.git") + private String gitUrl; + + /** + * git原始分支或tag + */ + @ApiModelProperty(name = "name", value = " git原始分支或tag", dataType = "String", example = "master") + private String baseVersion; + + /** + * git现分支或tag + */ + @ApiModelProperty(name = "name", value = " git现分支或tag", dataType = "String", example = "develop") + private String nowVersion; + + +} diff --git a/application/src/main/java/com/dr/code/diff/vo/result/CodeDiffResultVO.java b/application/src/main/java/com/dr/code/diff/vo/result/CodeDiffResultVO.java new file mode 100644 index 0000000..f1672b0 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vo/result/CodeDiffResultVO.java @@ -0,0 +1,39 @@ +package com.dr.code.diff.vo.result; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @date:2021/1/9 + * @className:CodeDiffResultVO + * @author:Administrator + * @description: 差异代码结果集 + */ +@Data +@ApiModel("差异代码结果集") +public class CodeDiffResultVO { + + + /** + * java文件 + */ + @ApiModelProperty(name = "classFile", value = "java文件", dataType = "String", example = "com/dr/code/diff/controller/A.java") + private String classFile; + + /** + * 类中的方法 + */ + @ApiModelProperty(name = "methodInfos", value = "类中的方法") + private List methodInfos; + + + /** + * 修改类型 + */ + @ApiModelProperty(name = "type", value = "修改类型", dataType = "String", example = "ADD") + private String type; + +} diff --git a/application/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java b/application/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java new file mode 100644 index 0000000..dc6bc99 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java @@ -0,0 +1,35 @@ +package com.dr.code.diff.vo.result; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @date:2021/1/9 + * @className:MethodInfoResultVO + * @author:Administrator + * @description: 方法对象 + */ +@Data +@ApiModel("方法对象") +public class MethodInfoResultVO { + + + /** + * 方法的md5 + */ + @ApiModelProperty(name = "md5", value = "方法的md5", dataType = "string", example = "13E2BFB69F7D987A6DB4272400C94E9B") + public String md5; + /** + * 方法名 + */ + @ApiModelProperty(name = "methodName", value = "方法名", dataType = "string", example = "getAll") + public String methodName; + /** + * 方法参数 + */ + @ApiModelProperty(name = "parameters", value = "parameters", dataType = "string") + public String parameters; + + +} diff --git a/application/src/main/resources/application.yml b/application/src/main/resources/application.yml new file mode 100644 index 0000000..035a745 --- /dev/null +++ b/application/src/main/resources/application.yml @@ -0,0 +1,47 @@ +spring: + profiles: + #激活开发环境 + active: dev + messages: + basename: i18n/Messages,i18n/Pages + # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 + + main: + allow-bean-definition-overriding: true + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 +logging: + config: classpath:log4j2.yml +swagger: + enabled: true + base-package: com.dr.code.diff.controller +##日志配置 +#logging: +# config: classpath:log4j2.yml +#shiro: +# loginUrl: /view/sys/user/login +# successUrl: /view/sys/index +# unauthorizedUrl: /view/sys/unauthorized +# sessionManager: +# sessionIdUrlRewritingEnabled: false +git: + userName: rayduan + password: FDsfret334 + local: + base: + dir: D:\git-test\ +server: + port: 8085 + servlet: + session: + timeout: 3600 +#jenkins: +# url: http://192.168.80.128:8081 +# userName: admin +# password: 1 +--- +server: + port: 8084 +spring: + profiles: test diff --git a/application/src/main/resources/log4j2.yml b/application/src/main/resources/log4j2.yml new file mode 100644 index 0000000..2c04d1b --- /dev/null +++ b/application/src/main/resources/log4j2.yml @@ -0,0 +1,88 @@ + # 共有8个级别,按照从低到高为:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF。 +Configuration: + status: warn + monitorInterval: 30 + + Properties: # 定义全局变量 + Property: # 缺省配置(用于开发环境)。其他环境需要在VM参数中指定,如下: + #测试:-Dlog.level.console=warn -Dlog.level.xjj=trace + #生产:-Dlog.level.console=warn -Dlog.level.xjj=info + - name: log.level.console + value: debug + - name: log.sql.level + value: trace + - name: log.path + value: D://logs + Appenders: + Console: #输出到控制台 + name: CONSOLE + target: SYSTEM_OUT + ThresholdFilter: + level: ${sys:log.level.console} # “sys:”表示:如果VM参数中没指定这个变量值,则使用本文件中定义的缺省全局变量值 + onMatch: ACCEPT + onMismatch: DENY + PatternLayout: + pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n" + RollingFile: # 输出到文件,超过128MB归档 + - name: info + ignoreExceptions: false + fileName: ${log.path}/${date:yyyy-MM}/${date:yyyy-MM-dd}/info.log + filePattern: "${log.path}/${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz" + ThresholdFilter: + level: info + onMatch: ACCEPT + onMismatch: DENY + PatternLayout: + pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n" + Policies: + SizeBasedTriggeringPolicy: + size: "128 MB" + DefaultRolloverStrategy: + max: 1000 + - name: debug + ignoreExceptions: false + fileName: ${log.path}/${date:yyyy-MM}/${date:yyyy-MM-dd}/debug.log + filePattern: "${log.path}/$${date:yyyy-MM}/debug-%d{yyyy-MM-dd}-%i.log.gz" + ThresholdFilter: + level: debug + onMatch: ACCEPT + onMismatch: DENY + PatternLayout: + pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n" + Policies: + SizeBasedTriggeringPolicy: + size: "128 MB" + DefaultRolloverStrategy: + max: 1000 + - name: error + ignoreExceptions: false + fileName: ${log.path}/${date:yyyy-MM}/${date:yyyy-MM-dd}/error.log + filePattern: "${log.path}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz" + ThresholdFilter: + level: error + onMatch: ACCEPT + onMismatch: DENY + PatternLayout: + pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n" + Policies: + SizeBasedTriggeringPolicy: + size: "128 MB" + DefaultRolloverStrategy: + max: 1000 + Loggers: + Root: + level: info + AppenderRef: + - ref: CONSOLE + - ref: info + - ref: debug + - ref: error +# Logger: # 为com.xjj包配置特殊的Log级别,方便调试 +# - name: cnki.bdms.module.search.dal +# additivity: true +# level: ${sys:log.sql.level} +# AppenderRef: +# - ref: info +# - ref: debug +# - ref: error +# - ref: CONSOLE \ No newline at end of file diff --git a/application/src/test/java/com/dr/code/diff/CodeDiffApplicationTest.java b/application/src/test/java/com/dr/code/diff/CodeDiffApplicationTest.java new file mode 100644 index 0000000..a386c37 --- /dev/null +++ b/application/src/test/java/com/dr/code/diff/CodeDiffApplicationTest.java @@ -0,0 +1,23 @@ +package com.dr.code.diff; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +/** + * @ProjectName: base-service + * @Package: com.dr.codediff + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/1/7 19:55 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2021 + */ +@SpringBootTest(classes = CodeDiffApplication.class) +public class CodeDiffApplicationTest { + @Test + void contextLoads() { + } + + +} \ No newline at end of file diff --git a/application/src/test/java/com/dr/code/diff/config/GitConfigTest.java b/application/src/test/java/com/dr/code/diff/config/GitConfigTest.java new file mode 100644 index 0000000..92ab2f2 --- /dev/null +++ b/application/src/test/java/com/dr/code/diff/config/GitConfigTest.java @@ -0,0 +1,39 @@ +package com.dr.code.diff.config; + +import com.dr.code.diff.CodeDiffApplicationTest; +import com.dr.code.diff.dto.DiffMethodParams; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @ProjectName: base-service + * @Package: com.dr.codediff.config + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/1/7 19:56 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2021 + */ +class GitConfigTest extends CodeDiffApplicationTest { + + @Autowired + private GitConfig gitConfig; + + @Test + void cloneRepository() { + String localRepo = "D:\\git-test\\base-service"; + String gitUrl = "http://192.168.75.128/rayduan/base-service.git"; + gitConfig.cloneRepository(gitUrl, localRepo, "2ea401406d775005245faa0a57d6e08db348433f"); + } + + @Test + void diffMethods() { + DiffMethodParams diff = DiffMethodParams.builder() + .baseVersion("dac68b2f3976509b4204a66df8f5e71dffe023b7") + .nowVersion("74c026849763f1f9f0dfc967949d0b581959c2ea") + .gitUrl("https://github.com/rayduan/devops-data.git") + .build(); + gitConfig.diffMethods(diff); + } +} \ No newline at end of file diff --git a/application/src/test/java/com/dr/code/diff/util/MethodParserUtilsTest.java b/application/src/test/java/com/dr/code/diff/util/MethodParserUtilsTest.java new file mode 100644 index 0000000..4cf40f4 --- /dev/null +++ b/application/src/test/java/com/dr/code/diff/util/MethodParserUtilsTest.java @@ -0,0 +1,24 @@ +package com.dr.code.diff.util; + +import com.dr.code.diff.CodeDiffApplicationTest; +import org.junit.jupiter.api.Test; + +/** + * @ProjectName: base-service + * @Package: com.dr.codediff.util + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/1/8 21:11 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2021 + */ +class MethodParserUtilsTest extends CodeDiffApplicationTest { + + @Test + void parseMethods() { + MethodParserUtils methodParserUtils = new MethodParserUtils(); + methodParserUtils.parseMethods("D:\\git-test\\43c9a993fbbb35bbe3221dfc20cf07fedb0bb3a2\\collector\\src\\main\\java\\com\\geely\\collector\\mvc\\APIResponse.java"); +// methodParser.parseMethods("D:\\git-test\\43c9a993fbbb35bbe3221dfc20cf07fedb0bb3a2\\third-sdk\\src\\main\\java\\com\\geely\\gitlab\\service\\GitlabService.java"); + } +} \ No newline at end of file diff --git a/common/pom.xml b/common/pom.xml new file mode 100644 index 0000000..4fc70b6 --- /dev/null +++ b/common/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + com.dr + code-diff-parent + 1.0.0-SNAPSHOT + + common + 1.0.0-SNAPSHOT + common + Demo project for Spring Boot + + + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.apache.httpcomponents + httpclient + + + org.springframework.boot + spring-boot-starter-aop + + + ma.glasnost.orika + orika-core + + + cn.afterturn + easypoi-spring-boot-starter + + + org.projectlombok + lombok + + + com.alibaba + fastjson + + + com.github.whvcse + easy-captcha + + + + com.google.guava + guava + + + org.aspectj + aspectjweaver + + + + + + diff --git a/common/src/main/java/com/dr/common/annotation/IdempotentCheck.java b/common/src/main/java/com/dr/common/annotation/IdempotentCheck.java new file mode 100644 index 0000000..50c9f16 --- /dev/null +++ b/common/src/main/java/com/dr/common/annotation/IdempotentCheck.java @@ -0,0 +1,18 @@ +package com.dr.common.annotation; + + +import java.lang.annotation.*; + +/** + * @author rui.duan + */ +@Target({ ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface IdempotentCheck { + /** + * 需要等待的时间,单位s + * @return int + */ + int expireTime() default 3; +} diff --git a/common/src/main/java/com/dr/common/aop/IdempotentAspect.java b/common/src/main/java/com/dr/common/aop/IdempotentAspect.java new file mode 100644 index 0000000..cb31910 --- /dev/null +++ b/common/src/main/java/com/dr/common/aop/IdempotentAspect.java @@ -0,0 +1,111 @@ +package com.dr.common.aop; + + +import com.dr.common.annotation.IdempotentCheck; +import javassist.*; +import javassist.bytecode.CodeAttribute; +import javassist.bytecode.LocalVariableAttribute; +import javassist.bytecode.MethodInfo; +import org.apache.commons.lang3.ArrayUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +/** + * @author rui.duan + * @version 1.0 + * @className IdempotentAspect + * @description 幂等校验切面 + * @date 2019-06-10 19:23 + */ +@Aspect +@Component +public class IdempotentAspect { + + +// private IUcsCache ucsCache; + + @Pointcut("@annotation(com.dr.common.annotation.IdempotentCheck)") + public void idempotentCheck() {} + + @Before("idempotentCheck()") + public void doBefore(JoinPoint joinPoint) { + //拿到注解类的类名 + String targetName = joinPoint.getTarget().getClass().getName(); + //拿到注解类的方法名 + String methodName = joinPoint.getSignature().getName(); + //拿到注解类的参数 + Object[] arguments = joinPoint.getArgs(); + Class targetClass = null; + String args =""; + try { + targetClass = Class.forName(targetName); + Method[] methods = targetClass.getMethods(); + for (Method method : methods) { + if (method.getName().equals(methodName)) { + Class[] clazzs = method.getParameterTypes(); + if (clazzs.length == arguments.length) { + if(null != arguments && arguments.length >0){ + args = ArrayUtils.toString(arguments, "-"); + } + int expireTime = method.getAnnotation(IdempotentCheck.class).expireTime(); + //拼接key,同一类的同一方法的相同参数3秒内不能重复调用 + StringBuilder key = new StringBuilder(targetName) + .append(methodName) + .append(args); +// if(ucsCache.containsKey(key.toString())){ +// throw new ScmBizException(BaseCode.NOT_REPEAT_COMMIT); +// }else{ +// //接口加锁 +// ucsCache.set(key.toString(), AuthUtil.getUserInfo().getToken(),expireTime); +// } + + } + } + } + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + /** + * 通过反射机制 获取被切参数名以及参数值 + * + * @param cls + * @param clazzName + * @param methodName + * @param args + * @return + * @throws NotFoundException + */ + private Map getFieldsName(Class cls, String clazzName, String methodName, Object[] args) throws NotFoundException { + Map map = new HashMap(); + + ClassPool pool = ClassPool.getDefault(); + ClassClassPath classPath = new ClassClassPath(cls); + pool.insertClassPath(classPath); + + CtClass cc = pool.get(clazzName); + CtMethod cm = cc.getDeclaredMethod(methodName); + MethodInfo methodInfo = cm.getMethodInfo(); + CodeAttribute codeAttribute = methodInfo.getCodeAttribute(); + LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag); + if (attr == null) { + // exception + } + // String[] paramNames = new String[cm.getParameterTypes().length]; + int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1; + for (int i = 0; i < cm.getParameterTypes().length; i++) { + //paramNames即参数名 + map.put(attr.variableName(i + pos), args[i]); + } + return map; + } + +} diff --git a/common/src/main/java/com/dr/common/config/BaseConfiguration.java b/common/src/main/java/com/dr/common/config/BaseConfiguration.java new file mode 100644 index 0000000..14640bb --- /dev/null +++ b/common/src/main/java/com/dr/common/config/BaseConfiguration.java @@ -0,0 +1,83 @@ +package com.dr.common.config; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author rui.duan + * @version 1.0 + * @className ScmConfiguration + * @description 系统配置文件 + * @date 2019-07-09 11:18 + */ + +@Data +@Component +@ConfigurationProperties("base.custom") +public class BaseConfiguration { + + /** + * 白名单 + */ + private List whiteList; +// + /** + * 默认密码 + */ + private String defaultPassword; + + /** + * 登录url + */ + private String loginUrl; + + /** + * 登录成功后页面url + */ + private String successUrl; + + /** + * 没有权限的url + */ + private String unauthorizedUrl; +// +// /** +// * 是否开启swagger +// */ +// @Value(value = "${scm.swagger.enabled:true}") +// private Boolean swaggerEnabled; +// +// +// @Value(value = "${bsht.warehouse.url}") +// protected String warehouseUrl; +// +// @Value(value = "${bsht.warehouse.partner.id}") +// protected String partnerID; +// +// @Value(value ="${bsht.warehouse.partner.key}") +// protected String partnerKey; +// +// @Value(value ="${bsht.warehouse.customer.code}") +// protected String customerCode; +// +// @Value("${cloud.warehouse.test.list:DEV,TEST}") +// private String cloudWarehouseTestList; +// +// @Value(value ="${sg.console.gateway.url}") +// private String gateway; +// +// @Value(value = "${scm.mock.enabled:false}") +// private Boolean mockEnabled; +// +// @Value(value = "${scm.job.bets.username:jmywsx001}") +// private String betsUserName; +// +// @Value(value = "${scm.job.bets.password:JMYW1234}") +// private String betsPassword; + + +} diff --git a/common/src/main/java/com/dr/common/constant/AuthConstant.java b/common/src/main/java/com/dr/common/constant/AuthConstant.java new file mode 100644 index 0000000..e09fec7 --- /dev/null +++ b/common/src/main/java/com/dr/common/constant/AuthConstant.java @@ -0,0 +1,42 @@ +package com.dr.common.constant; + +/** + * @author ylw + * @description + * @date 2019/5/2716:08 + */ +public class AuthConstant { + public static final String ADMIN_TOKEN = "token"; + + public static final String REQ_USER_KEY = "req_admin_user"; + + public static final String USER_AGENT = "User-Agent"; + + public static final String OPEN_DATA = "bizData"; + + public static final String OPEN_CHANNEL_CODE = "channelCode"; + + public static final String OPEN_SIGN = "sign"; + + public static final String OPEN_TOEKN = "token"; + + public static final String AES_UTF8 = "UTF-8"; + + public static final int OPEN_TOKEN_VALIDITY_SECONDS = 60 * 60 * 2*1000; + + public static final int LOGIN_PASSWORD_ENCRYPTION_TIMES = 2; + + public static final int ADMIN_USER_ID = 0; + + public static final String ADMIN_USER_ACCOUNT = "admin"; + + public static final String ADMIN_USER_PASSWORD= "admin321"; + + public static final String ADMIN_USER_NAME = "系统管理员"; + + public static final Integer ADMIN_USER_STATUS = 1; + + public static final String USER_PASSWORD_SALT = "3b21wifi"; + + public static final String USER_PASSWORD_VALIDATE_RULES ="[0-9A-Za-z]{6,20}"; +} diff --git a/common/src/main/java/com/dr/common/constant/Constant.java b/common/src/main/java/com/dr/common/constant/Constant.java new file mode 100644 index 0000000..c38388c --- /dev/null +++ b/common/src/main/java/com/dr/common/constant/Constant.java @@ -0,0 +1,166 @@ +package com.dr.common.constant; + +/** + * @author rui.duan + * @version 1.0 + * @className Constant + * @description 常量数据 + * @date 2019-05-23 13:23 + */ +public class Constant { + /** + * 最大导入数量 + */ + public final static int LIMIT_IMPORT_COUNT = 10000; + + /** + * 最大导出条数 + */ + public final static int LIMIT_EXPORT_COUNT = 10000; + + /** + * 云秀供应商商品ID + */ + public final static String GOODS_SKU_CODE_PREIX = "YXSK"; + + /** + * 云秀供应商编号 + */ + public final static String SUPPLIER_CODE_PREIX = "YXGYS"; + + /** + * 仓库编号 + */ + public final static String WAREHOUSE_CODE_PREIX = "YXCK"; + + /** + * 销售渠道编号 + */ + public final static String CHANNEL_CODE_PREIX = "XSQD"; + + /** + * 云秀物流公司编号 + */ + public final static String LOGISTIC_COMPANY_CODE_PREIX = "YXWL"; + + /** + * 包材编号 + */ + public final static String MATERIAL_CODE_PREIX = "YXBC"; + + /** + * 业务线编号 + */ + public final static String LOB_CODE_PREIX = "YWX"; + + /** + * 入库通知单 + */ + public final static String WAREHOUSING_RECEIPT_CODE_PREIX = "RK"; + + /** + * 出库通知单 + */ + public final static String EX_WAREHOUSING_RECEIPT_CODE_PREIX = "CK"; + + + /** + * 发货通知单 + */ + public final static String DELIVER_ORDER_PREIX="FH"; + + /** + * 退货单 + */ + public final static String REFUND_ORDER_PREIX="TH"; + + /** + * 取消订单 + */ + public final static String CANCEL_ORDER_PREIX="QX"; + + /** + * 包裹编码 + */ + public final static String DELIVER_EXPRESS_PACKAGE_PREIX="EP"; + + /** + * 百世包裹编码 + */ + public final static String BS_DELIVER_EXPRESS_PACKAGE_PREIX="BSEP"; + + /** + * 系统商品级订单编号 + */ + public final static String CHANNEL_GOODS_PREIX ="DG"; + + /** + * 系统订单编号 + */ + public final static String CHANNEL_ORDER_PREIX ="GYO"; + + /** + * 系统订单号(外部-无订单*发货单) + */ + public final static String EX_CHANNEL_ORDER_PREIX ="EXO"; + + /** + * 库存 + */ + public final static String INVENTORY_GOODS_PREIX="KC"; + + /** + * 物流公司分组 + */ + public final static String EXPRESS_GROUP_PREIX="EG"; + + /** + * 地区分组 + */ + public final static String AREA_GROUP_PREIX="AG"; + + /** + * 运费模板 + */ + public final static String LOGISTICS_COST_TPL_PREIX="YFTC"; + + + + + public final static int METHOD_INVOKE_EXPIRE_TIME = 3; + + /** + * 包材模板编号 + */ + public final static String MATERIAL_TEMPLATE_PREIX = "BCTP"; + + public final static String MATERIAL_TEMPLATE_LINE_PREIX = "BCTPD"; + + public final static String MATERIAL_TEMPLATE_COPY_PREFIX= "_副本_"; + + /** + * 操作模版编号 + */ + public final static String OPERATING_COST_TEMPLATE_PREIX = "OCTP"; + + public final static String OPERATING_COST_TEMPLATE_COPY_PREFIX= "_副本_"; + + + public final static String SUPPLIER_DEFAULT_PWD = "yxadmin123"; + + + public final static String BS_DEFAULT_NAME = "百世默认"; + + + public final static String BILL_DETAIL_CODE_PREFIX= "ZDLS"; + + /** + * 账单编号 + */ + public final static String BILL_CODE_PREFIX= "YXZD"; + + public final static String TPL_COPY_PREFIX= "_副本_"; + + + +} diff --git a/common/src/main/java/com/dr/common/enums/AdminTypeEnum.java b/common/src/main/java/com/dr/common/enums/AdminTypeEnum.java new file mode 100644 index 0000000..e52016c --- /dev/null +++ b/common/src/main/java/com/dr/common/enums/AdminTypeEnum.java @@ -0,0 +1,54 @@ +package com.dr.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author rui.duan + * @version 1.0 + * @className WarehousingReceiptStatusEnum + * @description 管理员枚举 + * @date 2019-06-10 11:39 + */ +@Getter +@AllArgsConstructor +public enum AdminTypeEnum { + //待通知 + NONE_ADMIN(0,"非管理员"), + + IS_ADMIN(1,"管理员"),; + + private Integer code; + private String value; + + + /** + * 根据code获取值 + * @param code + * @return + */ + public static String getValueByCode(Integer code) { + AdminTypeEnum[] values = AdminTypeEnum.values(); + for (AdminTypeEnum type : values) { + if (type.code.equals(code)) { + return type.value; + } + } + return null; + } + + /** + * 根据value获取code + * @param value + * @return + */ + public static Integer getCodeByValue(String value) { + AdminTypeEnum[] values = AdminTypeEnum.values(); + for (AdminTypeEnum type : values) { + if (type.value.equalsIgnoreCase(value)) { + return type.code; + } + } + return null; + } +} diff --git a/common/src/main/java/com/dr/common/enums/PermissionTypeEnum.java b/common/src/main/java/com/dr/common/enums/PermissionTypeEnum.java new file mode 100644 index 0000000..545580e --- /dev/null +++ b/common/src/main/java/com/dr/common/enums/PermissionTypeEnum.java @@ -0,0 +1,67 @@ +package com.dr.common.enums; + +import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.List; + +/** + * @author rui.duan + * @version 1.0 + * @className WarehousingReceiptStatusEnum + * @description 菜单枚举 + * @date 2019-06-10 11:39 + */ +@Getter +@AllArgsConstructor +public enum PermissionTypeEnum { + + //待通知 + MENU(0,"菜单"), + + BUTTON(1,"按钮"),; + + private Integer code; + private String value; + + + /** + * 根据code获取值 + * @param code + * @return + */ + public static String getValueByCode(Integer code) { + PermissionTypeEnum[] values = PermissionTypeEnum.values(); + for (PermissionTypeEnum type : values) { + if (type.code.equals(code)) { + return type.value; + } + } + return null; + } + + public static List getCodes() { + List codes = Lists.newArrayList(); + PermissionTypeEnum[] values = PermissionTypeEnum.values(); + for (PermissionTypeEnum type : values) { + codes.add(type.getCode()); + } + return codes; + } + + /** + * 根据value获取code + * @param value + * @return + */ + public static Integer getCodeByValue(String value) { + PermissionTypeEnum[] values = PermissionTypeEnum.values(); + for (PermissionTypeEnum type : values) { + if (type.value.equalsIgnoreCase(value)) { + return type.code; + } + } + return null; + } +} diff --git a/common/src/main/java/com/dr/common/errorcode/BaseCode.java b/common/src/main/java/com/dr/common/errorcode/BaseCode.java new file mode 100644 index 0000000..a5d296a --- /dev/null +++ b/common/src/main/java/com/dr/common/errorcode/BaseCode.java @@ -0,0 +1,102 @@ +package com.dr.common.errorcode; + +/** + * @Author : Max. + * @Created : 2018-08-23 + * @E-mail : goday.max@gmail.com + * @Version : 1.0 + * @Desription : 系统基础错误码 10000 ~ 19999 + */ +public enum BaseCode implements Code { + SUCCESS(10000, "业务处理成功", "业务处理成功"), + SYSTEM_FAILD(10001, "网络走神了,请稍后重试", "网络走神了,请稍后重试"), + TIMED_OUT(10002, "业务处理超时", "系统处理超时,请重试"), + PARAM_ERROR(10003, "参数错误", "请检查参数是否正确"), + EXCEL_TEMPLE_ERROR(10004, "模板不能为空", "请检查模版路径是否正确"), + EXCEL_NOT_EMPTY_ERROR(10005, "excel文件不能为空", "请检查excel文件"), + EXCEL_DEAL_ERROR(10006, "excel文件处理失败", "请联系管理员"), + LOGIN_FAILED(10007,"账号或密码错误","登录失败,账号或密码错误"), + LOGIN_TOKEN_GEN_FAILED(10008, "生成token加密失败", "登录失败,请重试"), + LOGIN_TOKEN_GEN_PARAM_INVALID(10009, "生成token参数缺失", "登录失败,请重试"), + LOGIN_ELSEWHERE(10010, "token已经失效", "您的账号已在其他地方登录,请重新登录"), + LOGIN_INVALID(10011, "token校验失败", "登录失效,请重新登录"), + OBJECT_EMPTY(10012,"查找的数据不存在","查找的数据不存在"), + OPEN_TOKEN_CREATE_ERROR(10013,"openToken创建失败","openToken创建失败"), + OPEN_TOKEN_CREATE_GET_KEY_ERROR(10014,"密钥获取失败","openToken创建失败"), + OPEN_TOKEN_DECRYPT_ERROE(10015,"openToken解密失败","openToken解密失败"), + OPEN_TOKEN_VALID_ERROR(10016,"openToken校验失败","openToken校验失败"), + OPEN_TOKEN_VALID_TIME_ERROR(10017,"openToken已过期","openToken已过期"), + OPEN_SIGN_VALID_ERROR(10018,"签名校验失败","签名校验失败"), + USER_PASSWORD_VERIFY_ERROR(10019,"密码强度校验不通过,密密码规则(数字+英文,长度6-16位)","密码强度校验不通过,密密码规则(数字+英文,长度6-16位)"), + OPRATE_OBJECT_EMPTY(10020,"需要操作的数据为空","需要操作的数据为空"), + EXPORT_OBJECT_EMPTY(10021,"需要导出的数据为空","需要导出的数据为空"), + NOT_REPEAT_COMMIT(10022,"请勿重复提交","请勿重复提交"), + USER_AUTH_DISABLE(10023,"用户已停用","用户已停用无法操作"), + CANCEL_WMS_FAIL(10024,"取消通知失败","取消通知失败"), + EXCEL_TYPE_ERROR(10025, "导入的格式非excel文件", "导入失败,请下载模板查看格式"), + EXCEL_OVERFLOW(10026, "excel超出最大导出数量", "excel超出最大导出数量"), + LOGIN_UNKNOW_ACCOUNT(10027, "未知账户", "未知账户"), + LOGIN_PASSWORD_INCORRECT(10028, "密码不正确", "密码不正确"), + LOGIN_ACCOUNT_LOCK(10029, "账户已锁定", "账户已锁定"), + LOGIN_INCORRECT_OVER_TIMES(10030, "用户名或密码错误次数过多", "用户名或密码错误次数过多"), + LOGIN_INCORRECT_NAME_OR_PASSWORD(10031, "用户名或密码错误", "用户名或密码错误"), + LOGIN_VERIFYCODE_INCORRECT(10032, "验证码错误", "验证码错误"), + LOGIN_MANY_LOCATION(10033, "您已在别处登录,请您修改密码或重新登录", "您已在别处登录,请您修改密码或重新登录"), + + ; + + private final int code; + private final String info; + private final String fixTips; + + BaseCode(int code, String info, String fixTips) { + this.code = code; + this.info = info; + this.fixTips = fixTips; + } + + /** + * 错误码 + * eg: 200xx gateway + * 300xx user + * 400xx order + * 500xx core + * 600xx operator + * 700xx admin + *

+ * universal: + * 10000 ~ 19999 + * 10000 success + * 10001 system error + * 10002 timed out + * 10003 params error + * 10004 rpc timeout + * 10005 rpc invoke error + * + * @return + */ + @Override + public int getCode() { + return this.code; + } + + /** + * 错误码说明(内部日志,统计,查看使用) + * + * @return + */ + @Override + public String getInfo() { + return this.info; + } + + /** + * 错误码描述,对外输出 + * + * @return + */ + @Override + public String getFixTips() { + return this.fixTips; + } +} diff --git a/common/src/main/java/com/dr/common/errorcode/BizCode.java b/common/src/main/java/com/dr/common/errorcode/BizCode.java new file mode 100644 index 0000000..a069491 --- /dev/null +++ b/common/src/main/java/com/dr/common/errorcode/BizCode.java @@ -0,0 +1,71 @@ +package com.dr.common.errorcode; + +/** + * + */ +public enum BizCode implements Code { + + /**************************计费模块错误码******************************/ + CHARGE_PKG_INVALID(20000, "包裹信息不存在", "请检查包裹号是否合法"), + CHARGE_PKG_SKU_INVALID(20001, "包裹商品数据不存在", "请检查包裹商品信息是否存在"), + CREATE_JOB_FAIL(20002, "创建job失败", "请联系管理员"), + + + + ; + + private final int code; + private final String info; + private final String fixTips; + + BizCode(int code, String info, String fixTips) { + this.code = code; + this.info = info; + this.fixTips = fixTips; + } + + /** + * 错误码 + * eg: 200xx gateway + * 300xx user + * 400xx order + * 500xx core + * 600xx operator + * 700xx admin + *

+ * universal: + * 10000 ~ 19999 + * 10000 success + * 10001 system error + * 10002 timed out + * 10003 params error + * 10004 rpc timeout + * 10005 rpc invoke error + * + * @return + */ + @Override + public int getCode() { + return this.code; + } + + /** + * 错误码说明(内部日志,统计,查看使用) + * + * @return + */ + @Override + public String getInfo() { + return this.info; + } + + /** + * 错误码描述,对外输出 + * + * @return + */ + @Override + public String getFixTips() { + return this.fixTips; + } +} diff --git a/common/src/main/java/com/dr/common/errorcode/Code.java b/common/src/main/java/com/dr/common/errorcode/Code.java new file mode 100644 index 0000000..cfde5b3 --- /dev/null +++ b/common/src/main/java/com/dr/common/errorcode/Code.java @@ -0,0 +1,9 @@ +package com.dr.common.errorcode; + +public interface Code { + int getCode(); + + String getInfo(); + + String getFixTips(); +} diff --git a/common/src/main/java/com/dr/common/exception/BaseException.java b/common/src/main/java/com/dr/common/exception/BaseException.java new file mode 100644 index 0000000..ad391a3 --- /dev/null +++ b/common/src/main/java/com/dr/common/exception/BaseException.java @@ -0,0 +1,48 @@ +package com.dr.common.exception; + + +import com.dr.common.errorcode.Code; + +public class BaseException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + private int code; + private String msg; + + public BaseException(Code code) { + super(code.getFixTips()); + this.code = code.getCode(); + this.msg = code.getFixTips(); + } + + public BaseException(Code code, Throwable e) { + super(code.getFixTips(), e); + this.code = code.getCode(); + this.msg = code.getFixTips(); + } + + public BaseException(int code, String msg) { + super(msg); + this.code = code; + this.msg = msg; + } + + public BaseException(int code, String msg, Throwable e) { + super(msg, e); + this.code = code; + this.msg = msg; + } + + public int getCode() { + return this.code; + } + + public String getMsg() { + return this.msg; + } + + public BaseException(){ + super(); + } +} diff --git a/common/src/main/java/com/dr/common/exception/BizException.java b/common/src/main/java/com/dr/common/exception/BizException.java new file mode 100644 index 0000000..e55b0c6 --- /dev/null +++ b/common/src/main/java/com/dr/common/exception/BizException.java @@ -0,0 +1,25 @@ +package com.dr.common.exception; + + +import com.dr.common.errorcode.Code; + +/** + * + */ +public class BizException extends BaseException { + public BizException(Code code) { + super(code); + } + + public BizException(Code code, Throwable e) { + super(code, e); + } + + public BizException(int code, String msg) { + super(code, msg); + } + + public BizException(int code, String msg, Throwable e) { + super(code, msg, e); + } +} diff --git a/common/src/main/java/com/dr/common/httpclient/HttpClientUtil.java b/common/src/main/java/com/dr/common/httpclient/HttpClientUtil.java new file mode 100644 index 0000000..3e54232 --- /dev/null +++ b/common/src/main/java/com/dr/common/httpclient/HttpClientUtil.java @@ -0,0 +1,131 @@ +package com.dr.common.httpclient; + +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.NameValuePair; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.ssl.SSLContexts; +import org.apache.http.ssl.TrustStrategy; +import org.apache.http.util.EntityUtils; + +import javax.net.ssl.SSLContext; +import java.io.IOException; +import java.net.URI; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author zb Created in 4:18 PM 2019/5/16 + */ +@Slf4j +public class HttpClientUtil { + + public static String doGet(String url, Map param) { + + // 创建Httpclient对象 + CloseableHttpClient httpclient = HttpClients.createDefault(); + + String resultString = ""; + CloseableHttpResponse response = null; + try { + // 创建uri + URIBuilder builder = new URIBuilder(url); + if (param != null) { + for (String key : param.keySet()) { + builder.addParameter(key, param.get(key)); + } + } + URI uri = builder.build(); + + // 创建http GET请求 + HttpGet httpGet = new HttpGet(uri); + + // 执行请求 + response = httpclient.execute(httpGet); + // 判断返回状态是否为200 + if (response.getStatusLine().getStatusCode() == 200) { + resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (response != null) { + response.close(); + } + httpclient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return resultString; + } + + + public static String doPost(String url, Map param) { + // 创建Httpclient对象 + + CloseableHttpResponse response = null; + String resultString = ""; + CloseableHttpClient httpClient = null; + try{ + + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(1000).setConnectionRequestTimeout(1000) + .setSocketTimeout(5000).build(); + + SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() { + @Override + public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + return true; + } + }).build(); + + httpClient = HttpClients.custom() + .setDefaultRequestConfig(requestConfig) + .setSSLContext(sslContext).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) + .build(); + // 创建Http Post请求 + HttpPost httpPost = new HttpPost(url); + // 创建参数列表 + if (param != null) { + List paramList = new ArrayList<>(); + for (String key : param.keySet()) { + paramList.add(new BasicNameValuePair(key, param.get(key))); + } + // 模拟表单 + httpPost.addHeader("Content-Type", "application/json"); + httpPost.setEntity(new StringEntity(JSON.toJSON(param).toString(), "utf-8")); + } + // 执行http请求 + response = httpClient.execute(httpPost); + resultString = EntityUtils.toString(response.getEntity(), "utf-8"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (response != null) { + response.close(); + } + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return resultString; + } + +} diff --git a/common/src/main/java/com/dr/common/httpclient/HttpRequestResult.java b/common/src/main/java/com/dr/common/httpclient/HttpRequestResult.java new file mode 100644 index 0000000..870faeb --- /dev/null +++ b/common/src/main/java/com/dr/common/httpclient/HttpRequestResult.java @@ -0,0 +1,24 @@ +package com.dr.common.httpclient; + +import lombok.Data; + +/** + * @Description: http 请求结果 对象 + * @Author: luoxiaofei + * @Date: 2019-06-14 10:06 + **/ +@Data +public class HttpRequestResult { + + /** + * 返回结果code + */ + private Integer code; + + /** + * 返回描述 + */ + private String msg; + +} + diff --git a/common/src/main/java/com/dr/common/log/LoggerUtil.java b/common/src/main/java/com/dr/common/log/LoggerUtil.java new file mode 100644 index 0000000..d92a574 --- /dev/null +++ b/common/src/main/java/com/dr/common/log/LoggerUtil.java @@ -0,0 +1,85 @@ +package com.dr.common.log; + +import com.alibaba.fastjson.JSON; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; + +/** + * @author dr on 2018/8/10 09:55. + */ +public class LoggerUtil { + private static final char THREAD_RIGHT_TAG = ']'; + private static final char THREAD_LEFT_TAG = '['; + public static final char ENTERSTR = '\n'; + public static final char COMMA = ','; + public static final char MID_LINE = '-'; + + private LoggerUtil() { + } + + public static void error(Logger LOGGER, String scene, Object... msgs) { + LOGGER.error(getLogString(scene, msgs)); + } + + public static void error(Logger LOGGER, String scene, Throwable ex, Object... msgs) { + LOGGER.error(getLogString(scene, msgs), ex); + } + + public static void warn(Logger LOGGER, String scene, Throwable ex, Object... msgs) { + LOGGER.warn(getLogString(scene, msgs), ex); + } + + public static void warn(Logger LOGGER, String scene, Object... msgs) { + LOGGER.warn(getLogString(scene, msgs)); + } + + public static void info(Logger LOGGER, String scene, Object... msgs) { + if (LOGGER.isInfoEnabled()) { + LOGGER.info(getLogString(scene, msgs)); + } + + } + + public static void debug(Logger LOGGER, String scene, Object... msgs) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(getLogString(scene, msgs)); + } + + } + + public static void info(Logger LOGGER, String msg) { + if (LOGGER.isInfoEnabled()) { + LOGGER.info(msg); + } + + } + + public static void warn(Logger LOGGER, String msg) { + LOGGER.warn(msg); + } + + public static void error(Logger LOGGER, String msg, Throwable ex) { + LOGGER.error(msg, ex); + } + + public static String getLogString(String scene, Object... obj) { + StringBuilder log = new StringBuilder(); + log.append('[').append(Thread.currentThread().getId()).append(']'); + log.append(','); + log.append(StringUtils.isBlank(scene) ? '-' : scene); + log.append(','); + if (obj != null) { + Object[] var3 = obj; + int var4 = obj.length; + for(int var5 = 0; var5 < var4; ++var5) { + Object o = var3[var5]; + log.append(JSON.toJSON(o)); + log.append(','); + } + } + if (StringUtils.isNotBlank(log) && log.toString().endsWith(",")) { + log.delete(log.length() - 1, log.length()); + } + return log.toString(); + } +} diff --git a/common/src/main/java/com/dr/common/page/PageParam.java b/common/src/main/java/com/dr/common/page/PageParam.java new file mode 100644 index 0000000..48c60e5 --- /dev/null +++ b/common/src/main/java/com/dr/common/page/PageParam.java @@ -0,0 +1,29 @@ +package com.dr.common.page; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PageParam implements Serializable { + + private static final long serialVersionUID = 841937350585706077L; + + public static final int DEFAULT_PAGE_SIZE = 10; + /** 分页大小 */ + private Integer pageSize = DEFAULT_PAGE_SIZE; + /** 页码 */ + private Integer page = 1; + + public Integer getPageSize() { + return (pageSize == null || pageSize <= 0) ? DEFAULT_PAGE_SIZE : pageSize; + } + + public Integer getPage() { + return (page == null || page <= 0) ? 1 : page; + } +} diff --git a/common/src/main/java/com/dr/common/page/PageResult.java b/common/src/main/java/com/dr/common/page/PageResult.java new file mode 100644 index 0000000..08ccf74 --- /dev/null +++ b/common/src/main/java/com/dr/common/page/PageResult.java @@ -0,0 +1,52 @@ +package com.dr.common.page; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 分页对象 + * + * @author jiangdawei on 2018/8/31 11:05. + */ +@Data +public class PageResult implements Serializable { + private static final long serialVersionUID = -4106295362336919L; + + // 当前页 + private Integer currentPage = 1; + // 每页显示的总条数 + private Integer pageSize = 10; + // 总条数 + private Long totalNum; + // 是否有下一页 + private Integer isMore; + // 总页数 + private Integer totalPage; + // 开始索引 + private Integer startIndex; + // 分页结果 + private List data; + + public PageResult() { + super(); + } + + public PageResult(Integer currentPage, Integer pageSize, Long totalNum) { + super(); + this.currentPage = currentPage; + this.pageSize = pageSize; + this.totalNum = totalNum; + this.totalPage = ((int)(this.totalNum + this.pageSize - 1)) / this.pageSize; + this.startIndex = (this.currentPage - 1) * this.pageSize; + this.isMore = this.currentPage >= this.totalPage ? 0 : 1; + } + + public void setTotalNum(Long totalNum){ + this.totalNum =totalNum; + this.totalPage = ((int)(this.totalNum + this.pageSize - 1)) / this.pageSize; + } + + +} \ No newline at end of file diff --git a/common/src/main/java/com/dr/common/response/ApiResponse.java b/common/src/main/java/com/dr/common/response/ApiResponse.java new file mode 100644 index 0000000..06abd5d --- /dev/null +++ b/common/src/main/java/com/dr/common/response/ApiResponse.java @@ -0,0 +1,72 @@ +package com.dr.common.response; + + +import com.dr.common.errorcode.BaseCode; +import com.dr.common.errorcode.Code; +import com.dr.common.exception.BaseException; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ApiResponse implements Serializable { + private int code; + private String msg; + private T data; + + public ApiResponse(Code err) { + this.code = err.getCode(); + this.msg = err.getFixTips(); + } + + public ApiResponse(BaseException ex) { + this.code = ex.getCode(); + this.msg = ex.getMsg(); + } + + public ApiResponse(int code, String msg) { + this.code = code; + this.msg = msg; + } + + public ApiResponse success() { + this.code = BaseCode.SUCCESS.getCode(); + this.msg = BaseCode.SUCCESS.getInfo(); + return this; + } + + public ApiResponse success(T data) { + this.code = BaseCode.SUCCESS.getCode(); + this.msg = BaseCode.SUCCESS.getInfo(); + this.data = data; + return this; + } + + public ApiResponse error(Code code, T data) { + this.code = code.getCode(); + this.msg = code.getInfo(); + this.data = data; + return this; + } + + public ApiResponse error(Code code) { + this.code = code.getCode(); + this.msg = code.getInfo(); + this.data = null; + return this; + } + + public ApiResponse error(int code, String msg) { + this.code = code; + this.msg = msg; + this.data = null; + return this; + } +} diff --git a/common/src/main/java/com/dr/common/utils/auth/MD5Util.java b/common/src/main/java/com/dr/common/utils/auth/MD5Util.java new file mode 100644 index 0000000..e6a72df --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/auth/MD5Util.java @@ -0,0 +1,49 @@ +package com.dr.common.utils.auth; + +import com.google.common.io.ByteSource; +import org.apache.commons.lang3.StringUtils; + +import java.security.MessageDigest; + +public class MD5Util { + + + private static String byteArrayToHexString(byte b[]) { + StringBuffer resultSb = new StringBuffer(); + for (int i = 0; i < b.length; i++) + resultSb.append(byteToHexString(b[i])); + return resultSb.toString(); + } + + private static String byteToHexString(byte b) { + int n = b; + if (n < 0) + n += 256; + int d1 = n / 16; + int d2 = n % 16; + return hexDigits[d1] + hexDigits[d2]; + } + + public static String MD5Encode(String origin, String charsetname) { + String resultString = null; + try { + resultString = new String(origin); + MessageDigest md = MessageDigest.getInstance("MD5"); + if (charsetname == null || "".equals(charsetname)) + resultString = byteArrayToHexString(md.digest(resultString + .getBytes())); + else + resultString = byteArrayToHexString(md.digest(resultString + .getBytes(charsetname))); + } catch (Exception exception) { + exception.printStackTrace(); + } + return resultString; + } + + + + private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; +} + diff --git a/common/src/main/java/com/dr/common/utils/captcha/CaptchaUtil.java b/common/src/main/java/com/dr/common/utils/captcha/CaptchaUtil.java new file mode 100644 index 0000000..731d1bb --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/captcha/CaptchaUtil.java @@ -0,0 +1,116 @@ +package com.dr.common.utils.captcha; + + +import com.wf.captcha.GifCaptcha; +import com.wf.captcha.SpecCaptcha; +import com.wf.captcha.base.Captcha; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.awt.*; +import java.io.IOException; + +/** + * 验证码工具类,重写 + * 因为它没有提供修改验证码类型方法 + * + * @author dr + */ +@Slf4j +public class CaptchaUtil { + + // gif 类型验证码 + private static final int GIF_TYPE = 1; + // png 类型验证码 + private static final int PNG_TYPE = 0; + + // 验证码图片默认高度 + private static final int DEFAULT_HEIGHT = 48; + // 验证码图片默认宽度 + private static final int DEFAULT_WIDTH = 130; + // 验证码默认位数 + private static final int DEFAULT_LEN = 5; + + public static void out(HttpServletRequest request, HttpServletResponse response) throws IOException { + out(DEFAULT_LEN, request, response); + } + + public static void out(int len, HttpServletRequest request, HttpServletResponse response) throws IOException { + out(DEFAULT_WIDTH, DEFAULT_HEIGHT, len, null, request, response); + } + + public static void out(int len, Font font, HttpServletRequest request, HttpServletResponse response) throws IOException { + out(DEFAULT_WIDTH, DEFAULT_HEIGHT, len, null, font, request, response); + } + + public static void out(int width, int height, int len, Integer vType, HttpServletRequest request, HttpServletResponse response) throws IOException { + out(width, height, len, vType, null, request, response); + } + + public static void out(int width, int height, int len, Integer vType, Font font, HttpServletRequest request, HttpServletResponse response) throws IOException { + outCaptcha(width, height, len, font, GIF_TYPE, vType, request, response); + } + + public static void outPng(HttpServletRequest request, HttpServletResponse response) throws IOException { + outPng(DEFAULT_LEN, request, response); + } + + public static void outPng(int len, HttpServletRequest request, HttpServletResponse response) throws IOException { + outPng(DEFAULT_WIDTH, DEFAULT_HEIGHT, len, null, request, response); + } + + public static void outPng(int len, Font font, HttpServletRequest request, HttpServletResponse response) throws IOException { + outPng(DEFAULT_WIDTH, DEFAULT_HEIGHT, len, null, font, request, response); + } + + public static void outPng(int width, int height, int len, Integer vType, HttpServletRequest request, HttpServletResponse response) throws IOException { + outPng(width, height, len, vType, null, request, response); + } + + public static void outPng(int width, int height, int len, Integer vType, Font font, HttpServletRequest request, HttpServletResponse response) throws IOException { + outCaptcha(width, height, len, font, PNG_TYPE, vType, request, response); + } + + public static boolean verify(String code, HttpServletRequest request) { + HttpSession session = request.getSession(); + String sessionCode = (String) session.getAttribute("captcha"); + return StringUtils.equalsIgnoreCase(code, sessionCode); + } + + private static void outCaptcha(int width, int height, int len, Font font, int cType, Integer vType, HttpServletRequest request, HttpServletResponse response) throws IOException { + setHeader(response, cType); + Captcha captcha = null; + if (cType == GIF_TYPE) { + captcha = new GifCaptcha(width, height, len); + } else { + captcha = new SpecCaptcha(width, height, len); + } + if (font != null) { + captcha.setFont(font); + } + if (vType != null) { + captcha.setCharType(vType); + } + // 验证码存入session + HttpSession session = request.getSession(); + String code = captcha.text().toLowerCase(); + session.setAttribute("captcha", code); + captcha.out(response.getOutputStream()); + } + + public static void setHeader(HttpServletResponse response, int cType) { + if (cType == GIF_TYPE) { + response.setContentType(MediaType.IMAGE_GIF_VALUE); + } else { + response.setContentType(MediaType.IMAGE_PNG_VALUE); + } + response.setHeader(HttpHeaders.PRAGMA, "No-cache"); + response.setHeader(HttpHeaders.CACHE_CONTROL, "No-cache"); + response.setDateHeader(HttpHeaders.EXPIRES, 0L); + } +} diff --git a/common/src/main/java/com/dr/common/utils/date/DateUtil.java b/common/src/main/java/com/dr/common/utils/date/DateUtil.java new file mode 100644 index 0000000..e91b037 --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/date/DateUtil.java @@ -0,0 +1,622 @@ +package com.dr.common.utils.date; + +import com.google.common.collect.Lists; + +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAdjusters; +import java.util.Date; +import java.util.List; + +/** +* @date: 2019/11/1 +* @className: DateUtil +* @Param: +* @return: +* @author: rui.duan +* @description: 日期处理 +* +*/ +public class DateUtil extends Date{ + // 时间元素 + private static final String YEAR = "year"; + private static final String MONTH = "month"; + private static final String WEEK = "week"; + private static final String DAY = "day"; + private static final String HOUR = "hour"; + private static final String MINUTE = "minute"; + private static final String SECOND = "second"; + + // 星期元素 + private static final String MONDAY = "MONDAY";// 星期一 + private static final String TUESDAY = "TUESDAY";// 星期二 + private static final String WEDNESDAY = "WEDNESDAY";// 星期三 + private static final String THURSDAY = "THURSDAY";// 星期四 + private static final String FRIDAY = "FRIDAY";// 星期五 + private static final String SATURDAY = "SATURDAY";// 星期六 + private static final String SUNDAY = "SUNDAY";// 星期日 + + // 根据指定格式显示日期和时间 + /** yyyy-MM-dd */ + private static final DateTimeFormatter yyyyMMdd_EN = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + /** yyyy-MM-dd HH */ + private static final DateTimeFormatter yyyyMMddHH_EN = DateTimeFormatter.ofPattern("yyyy-MM-dd HH"); + /** yyyy-MM-dd HH:mm */ + private static final DateTimeFormatter yyyyMMddHHmm_EN = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + /** yyyy-MM-dd HH:mm:ss */ + private static final DateTimeFormatter yyyyMMddHHmmss_EN = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + /** HH:mm:ss */ + private static final DateTimeFormatter HHmmss_EN = DateTimeFormatter.ofPattern("HH:mm:ss"); + /** yyyy年MM月dd日 */ + private static final DateTimeFormatter yyyyMMdd_CN = DateTimeFormatter.ofPattern("yyyy年MM月dd日"); + /** yyyy年MM月dd日HH时 */ + private static final DateTimeFormatter yyyyMMddHH_CN = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时"); + /** yyyy年MM月dd日HH时mm分 */ + private static final DateTimeFormatter yyyyMMddHHmm_CN = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分"); + /** yyyy年MM月dd日HH时mm分ss秒 */ + private static final DateTimeFormatter yyyyMMddHHmmss_CN = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分ss秒"); + /** HH时mm分ss秒 */ + private static final DateTimeFormatter HHmmss_CN = DateTimeFormatter.ofPattern("HH时mm分ss秒"); + + // 本地时间显示格式:区分中文和外文显示 + private static final DateTimeFormatter SHOTDATE = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT); + private static final DateTimeFormatter FULLDATE = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL); + private static final DateTimeFormatter LONGDATE = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG); + private static final DateTimeFormatter MEDIUMDATE = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM); + + /** + * 获取当前日期 + * + * @return yyyy-MM-dd + * @author zero 2019/03/30 + */ + public static String getNowDate_EN() { + return String.valueOf(LocalDate.now()); + } + + /** + * 获取当前日期 + * + * @return 字符串yyyy-MM-dd HH:mm:ss + * @author zero 2019/03/30 + */ + public static String getNowTime_EN() { + return LocalDateTime.now().format(yyyyMMddHHmmss_EN); + } + + /** 获取当前时间(yyyy-MM-dd HH) */ + public static String getNowTime_EN_yMdH() { + return LocalDateTime.now().format(yyyyMMddHH_EN); + } + + /** 获取当前时间(yyyy年MM月dd日) */ + public static String getNowTime_CN_yMdH() { + return LocalDateTime.now().format(yyyyMMddHH_CN); + } + + /** 获取当前时间(yyyy-MM-dd HH:mm) */ + public static String getNowTime_EN_yMdHm() { + return LocalDateTime.now().format(yyyyMMddHHmm_EN); + } + + /** 获取当前时间(yyyy年MM月dd日HH时mm分) */ + public static String getNowTime_CN_yMdHm() { + return LocalDateTime.now().format(yyyyMMddHHmm_CN); + } + + /** 获取当前时间(HH时mm分ss秒) */ + public static String getNowTime_CN_HHmmss() { + return LocalDateTime.now().format(HHmmss_CN); + } + + /** + * 根据日期格式,获取当前时间 + * + * @param formatStr 日期格式
+ *

  • yyyy
  • + *
  • yyyy-MM-dd
  • + *
  • yyyy-MM-dd HH:mm:ss
  • + *
  • HH:mm:ss
  • + * @return + * @author zero 2019/03/30 + */ + public static String getTime(String formatStr) { + return LocalDateTime.now().format(DateTimeFormatter.ofPattern(formatStr)); + } + + /** + * 获取中文的当前日期 + * + * @return yyyy年mm月dd日 + * @author zero 2019/03/30 + */ + public static String getNowDate_CN() { + return LocalDate.now().format(yyyyMMdd_CN); + } + + /** + * 获取中文当前时间 + * + * @return yyyy年MM月dd日HH时mm分ss秒 + * @author zero 2019/03/30 + */ + public static String getNowTime_CN() { + return LocalDateTime.now().format(yyyyMMddHHmmss_CN); + } + + /** + * 简写本地当前日期:yy-M-dd
    + * 例如:19-3-30为2019年3月30日 + * + * @return 字符串yy-M-dd + * @author zero 2019/03/30 + */ + public static String getNowLocalTime_shot() { + return LocalDateTime.now().format(SHOTDATE); + } + + /** + * 根据当地日期显示格式:yyyy年M月dd日 星期?(中国) + * + * @return 形如:2019年3月30日 星期六 + * @author zero 2019/03/30 + */ + public static String getNowLocalTime_full() { + return LocalDateTime.now().format(FULLDATE); + } + + /** + * 根据当地显示日期格式:yyyy年M月dd日(中国) + * + * @return 形如 2019年3月30日 + * @author zero 2019/03/30 + */ + public static String getNowLocalTime_long() { + return LocalDateTime.now().format(LONGDATE); + } + + /** + * 根据当地显示日期格式:yyyy-M-dd(中国) + * + * @return 形如:2019-3-30 + * @author zero 2019/03/30 + */ + public static String getNowLocalTime_medium() { + return LocalDateTime.now().format(MEDIUMDATE); + } + + /** + * 获取当前日期的节点时间(年,月,周,日,时,分,秒) + * + * @param node 日期中的节点元素(年,月,周,日,时,分,秒) + * @return 节点数字,如创建此方法的时间:年 2019,月 3,日 30,周 6 + * @author zero 2019/03/30 星期六 + */ + public static Integer getNodeTime(String node) { + LocalDateTime today = LocalDateTime.now(); + Integer resultNode = null; + switch (node) { + case YEAR: + resultNode = today.getYear(); + break; + case MONTH: + resultNode = today.getMonthValue(); + break; + case WEEK: + resultNode = transformWeekEN2Num(String.valueOf(today.getDayOfWeek())); + break; + case DAY: + resultNode = today.getDayOfMonth(); + break; + case HOUR: + resultNode = today.getHour(); + break; + case MINUTE: + resultNode = today.getMinute(); + break; + case SECOND: + resultNode = today.getSecond(); + break; + default: + // 当前日期是当前年的第几天。例如:2019/1/3是2019年的第三天 + resultNode = today.getDayOfYear(); + break; + } + return resultNode; + } + + /** + * 将英文星期转换成数字 + * + * @param enWeek 英文星期 + * @return int,如果数字小于0,则检查,看是否输入错误 or 入参为null + * @author zero 2019/03/30 + */ + public static int transformWeekEN2Num(String enWeek) { + if (MONDAY.equals(enWeek)) { + return 1; + } else if (TUESDAY.equals(enWeek)) { + return 2; + } else if (WEDNESDAY.equals(enWeek)) { + return 3; + } else if (THURSDAY.equals(enWeek)) { + return 4; + } else if (FRIDAY.equals(enWeek)) { + return 5; + } else if (SATURDAY.equals(enWeek)) { + return 6; + } else if (SUNDAY.equals(enWeek)) { + return 7; + } else { + return -1; + } + } + + /** + * 获取当前日期之后(之后)的节点事件
    + *
      + * 比如当前时间为:2019-03-30 10:20:30 + *
    + *
  • node="hour",num=5L:2019-03-30 15:20:30
  • + *
  • node="day",num=1L:2019-03-31 10:20:30
  • + *
  • node="year",num=1L:2020-03-30 10:20:30
  • + * + * @param node 节点元素(“year”,"month","week","day","huor","minute","second") + * @param num 第几天(+:之后,-:之前) + * @return 之后或之后的日期 + * @author zero 2019/03/30 + */ + public static String getAfterOrPreNowTime(String node, Long num) { + LocalDateTime now = LocalDateTime.now(); + if (HOUR.equals(node)) { + return now.plusHours(num).format(yyyyMMddHHmmss_EN); + } else if (DAY.equals(node)) { + return now.plusDays(num).format(yyyyMMddHHmmss_EN); + } else if (WEEK.equals(node)) { + return now.plusWeeks(num).format(yyyyMMddHHmmss_EN); + } else if (MONTH.equals(node)) { + return now.plusMonths(num).format(yyyyMMddHHmmss_EN); + } else if (YEAR.equals(node)) { + return now.plusYears(num).format(yyyyMMddHHmmss_EN); + } else if (MINUTE.equals(node)) { + return now.plusMinutes(num).format(yyyyMMddHHmmss_EN); + } else if (SECOND.equals(node)) { + return now.plusSeconds(num).format(yyyyMMddHHmmss_EN); + } else { + return "Node is Error!"; + } + } + + /** + * 获取与当前日期相距num个之后(之前)的日期
    + *
      + * 比如当前时间为:2019-03-30 10:20:30的格式日期 + *
    • node="hour",num=5L:2019-03-30 15:20:30
    • + *
    • node="day",num=1L:2019-03-31 10:20:30
    • + *
    • node="year",num=1L:2020-03-30 10:20:30
    • + *
    + * + * @param dtf 格式化当前时间格式(dtf = yyyyMMddHHmmss_EN) + * @param node 节点元素(“year”,"month","week","day","huor","minute","second") + * @param num (+:之后,-:之前) + * @return 之后之前的日期 + * @author zero 2019/03/30 + */ + public static String getAfterOrPreNowTimePlus(DateTimeFormatter dtf, String node, Long num) { + LocalDateTime now = LocalDateTime.now(); + if (HOUR.equals(node)) { + return now.plusHours(num).format(dtf); + } else if (DAY.equals(node)) { + return now.plusDays(num).format(dtf); + } else if (WEEK.equals(node)) { + return now.plusWeeks(num).format(dtf); + } else if (MONTH.equals(node)) { + return now.plusMonths(num).format(dtf); + } else if (YEAR.equals(node)) { + return now.plusYears(num).format(dtf); + } else if (MINUTE.equals(node)) { + return now.plusMinutes(num).format(dtf); + } else if (SECOND.equals(node)) { + return now.plusSeconds(num).format(dtf); + } else { + return "Node is Error!"; + } + } + + /** + * 当前时间的hour,minute,second之后(之前)的时刻 + * + * @param node 时间节点元素(hour,minute,second) + * @param num 之后(之后)多久时,分,秒(+:之后,-:之前) + * @return HH:mm:ss 字符串 + * @author zero 2019/03/30 + */ + public static String getAfterOrPreNowTimeSimp(String node, Long num) { + LocalTime now = LocalTime.now(); + if (HOUR.equals(node)) { + return now.plusHours(num).format(HHmmss_EN); + } else if (MINUTE.equals(node)) { + return now.plusMinutes(num).format(HHmmss_EN); + } else if (SECOND.equals(node)) { + return now.plusSeconds(num).format(HHmmss_EN); + } else { + return "Node is Error!"; + } + } + + /** + * 检查重复事件,比如生日。 + * @param month + * @param dayOfMonth + * @return + * @author zero 2019/03/31 + */ + public static boolean isBirthday(int month, int dayOfMonth) { + MonthDay birthDay = MonthDay.of(month, dayOfMonth); + /** + * MonthDay只存储了月、日。 + */ + MonthDay curMonthDay = MonthDay.from(LocalDate.now()); + return birthDay.equals(curMonthDay); + } + + /** + * 获取当前日期第index日之后(之前)的日期(yyyy-MM-dd) + * + * @param index 第index天 + * @return 日期字符串:yyyy-MM-dd + * @author zero 2019/03/31 + */ + public static String getAfterOrPreDayDate(int index) { + return LocalDate.now().plus(index, ChronoUnit.DAYS).format(yyyyMMdd_EN); + } + + /** + * 获取当前日期第index周之前(之后)的日期(yyyy-MM-dd) + * + * @param index 第index周(+:之后,-:之前) + * @return 日期字符串:yyyy-MM-dd + * @author zero 2019/03/31 + */ + public static String getAfterOrPreWeekDate(int index) { + return LocalDate.now().plus(index, ChronoUnit.WEEKS).format(yyyyMMdd_EN); + } + + /** + * 获取当前日期第index月之前(之后)的日期(yyyy-MM-dd) + * + * @param index 第index月(+:之后,-:之前) + * @return 日期字符串:yyyy-MM-dd + * @author zero 2019/03/31 + */ + public static String getAfterOrPreMonthDate(int index) { + return LocalDate.now().plus(index, ChronoUnit.MONTHS).format(yyyyMMdd_EN); + } + + /** + * 获取当前日期第index年之前(之后)的日期(yyyy-MM-dd) + * + * @param index 第index年(+:之后,-:之前) + * @return 日期字符串:yyyy-MM-dd + * @author zero 2019/03/31 + */ + public static String getAfterOrPreYearDate(int index) { + return LocalDate.now().plus(index, ChronoUnit.YEARS).format(yyyyMMdd_EN); + } + + /** + * 获取指定日期之前之后的第index的日,周,月,年的日期 + * + * @param date 指定日期格式:yyyy-MM-dd + * @param node 时间节点元素(日周月年) + * @param index 之前之后第index个日期 + * @return yyyy-MM-dd 日期字符串 + * @author zero 2019/03/31 + */ + public static String getAfterOrPreDate(String date, String node, int index) { + date = date.trim(); + if (DAY.equals(node)) { + return LocalDate.parse(date).plus(index, ChronoUnit.DAYS).format(yyyyMMdd_EN); + } else if (WEEK.equals(node)) { + return LocalDate.parse(date).plus(index, ChronoUnit.WEEKS).format(yyyyMMdd_EN); + } else if (MONTH.equals(node)) { + return LocalDate.parse(date).plus(index, ChronoUnit.MONTHS).format(yyyyMMdd_EN); + } else if (YEAR.equals(node)) { + return LocalDate.parse(date).plus(index, ChronoUnit.YEARS).format(yyyyMMdd_EN); + } else { + return "Wrong date format!"; + } + } + + /** + * 检测:输入年份是否是闰年? + * + * @param date 日期格式:yyyy-MM-dd + * @return true:闰年,false:平年 + * @author zero 2019/03/31 + */ + public static boolean isLeapYear(String date) { + return LocalDate.parse(date.trim()).isLeapYear(); + } + + /** + * 计算两个日期字符串之间相差多少个周期(天,月,年) + * + * @param date1 yyyy-MM-dd + * @param date2 yyyy-MM-dd + * @param node 三者之一:(day,month,year) + * @return 相差多少周期 + * @author zero 2019/03/31 + */ + public static int peridCount(String date1, String date2, String node) { + date1 = date1.trim(); + date2 = date2.trim(); + if (DAY.equals(node)) { + return Period.between(LocalDate.parse(date1), LocalDate.parse(date2)).getDays(); + } else if (MONTH.equals(node)) { + return Period.between(LocalDate.parse(date1), LocalDate.parse(date2)).getMonths(); + } else if (YEAR.equals(node)) { + return Period.between(LocalDate.parse(date1), LocalDate.parse(date2)).getYears(); + } else { + return 0; + } + } + + /** + * 切割日期。按照周期切割成小段日期段。例如:
    + * + * @param startDate 开始日期(yyyy-MM-dd) + * @param endDate 结束日期(yyyy-MM-dd) + * @param period 周期(天,周,月,年) + * @return 切割之后的日期集合 + * @author zero 2019/04/02 + * @example + *
  • startDate="2019-02-28",endDate="2019-03-05",period="day"
  • + *
  • 结果为:[2019-02-28, 2019-03-01, 2019-03-02, 2019-03-03, 2019-03-04, 2019-03-05]

  • + *
  • startDate="2019-02-28",endDate="2019-03-25",period="week"
  • + *
  • 结果为:[2019-02-28,2019-03-06, 2019-03-07,2019-03-13, 2019-03-14,2019-03-20, + * 2019-03-21,2019-03-25]

  • + *
  • startDate="2019-02-28",endDate="2019-05-25",period="month"
  • + *
  • 结果为:[2019-02-28,2019-02-28, 2019-03-01,2019-03-31, 2019-04-01,2019-04-30, + * 2019-05-01,2019-05-25]

  • + *
  • startDate="2019-02-28",endDate="2020-05-25",period="year"
  • + *
  • 结果为:[2019-02-28,2019-12-31, 2020-01-01,2020-05-25]

  • + */ + public static List getPieDateRange(String startDate, String endDate, String period) { + List result = Lists.newArrayList(); + LocalDate end = LocalDate.parse(endDate, yyyyMMdd_EN); + LocalDate start = LocalDate.parse(startDate, yyyyMMdd_EN); + LocalDate tmp = start; + switch (period) { + case DAY: + while (start.isBefore(end) || start.isEqual(end)) { + result.add(start.toString()); + start = start.plusDays(1); + } + break; + case WEEK: + while (tmp.isBefore(end) || tmp.isEqual(end)) { + if (tmp.plusDays(6).isAfter(end)) { + result.add(tmp.toString() + "," + end); + } else { + result.add(tmp.toString() + "," + tmp.plusDays(6)); + } + tmp = tmp.plusDays(7); + } + break; + case MONTH: + while (tmp.isBefore(end) || tmp.isEqual(end)) { + LocalDate lastDayOfMonth = tmp.with(TemporalAdjusters.lastDayOfMonth()); + if (lastDayOfMonth.isAfter(end)) { + result.add(tmp.toString() + "," + end); + } else { + result.add(tmp.toString() + "," + lastDayOfMonth); + } + tmp = lastDayOfMonth.plusDays(1); + } + break; + case YEAR: + while (tmp.isBefore(end) || tmp.isEqual(end)) { + LocalDate lastDayOfYear = tmp.with(TemporalAdjusters.lastDayOfYear()); + if (lastDayOfYear.isAfter(end)) { + result.add(tmp.toString() + "," + end); + } else { + result.add(tmp.toString() + "," + lastDayOfYear); + } + tmp = lastDayOfYear.plusDays(1); + } + break; + default: + break; + } + return result; + } + + /** + * 指定日期月的最后一天(yyyy-MM-dd) + * + * @param curDate 日期格式(yyyy-MM-dd) + * @param firstOrLast true:第一天,false:最后一天 + * @return + * @author zero 2019/04/13 + */ + public static String getLastDayOfMonth(String curDate, boolean firstOrLast) { + if (firstOrLast) { + return LocalDate.parse(curDate, yyyyMMdd_EN).with(TemporalAdjusters.firstDayOfMonth()).toString(); + } else { + return LocalDate.parse(curDate, yyyyMMdd_EN).with(TemporalAdjusters.lastDayOfMonth()).toString(); + } + } + + /** + * 指定日期年的最后一天(yyyy-MM-dd) + * + * @param curDate 指定日期(格式:yyyy-MM-dd) + * @param firstOrLast true:第一天,false:最后一天 + * @return + * @author zero 2019/04/13 + */ + public static String getLastDayOfYear(String curDate, boolean firstOrLast) { + if (firstOrLast) { + return LocalDate.parse(curDate, yyyyMMdd_EN).with(TemporalAdjusters.firstDayOfYear()).toString(); + } else { + return LocalDate.parse(curDate, yyyyMMdd_EN).with(TemporalAdjusters.lastDayOfYear()).toString(); + } + } + + /** + * 获取下一个星期的日期 + * + * @param curDay yyyy-MM-dd + * @param dayOfWeek monday:1~sunday:7 + * @param isContainCurDay 是否包含当天,true:是,false:不包含 + * @return 日期(yyyy-MM-dd) + * @author zero 2019/04/02 + */ + public static String getNextWeekDate(String curDay, int dayOfWeek, boolean isContainCurDay) { + dayOfWeek = dayOfWeek < 1 || dayOfWeek > 7 ? 1 : dayOfWeek; + if (isContainCurDay) { + return LocalDate.parse(curDay).with(TemporalAdjusters.nextOrSame(DayOfWeek.of(dayOfWeek))).toString(); + } else { + return LocalDate.parse(curDay).with(TemporalAdjusters.next(DayOfWeek.of(dayOfWeek))).toString(); + } + } + + /** + * 获取上一个星期的日期 + * + * @param curDay 指定日期(yyyy-MM-dd) + * @param dayOfWeek 数字范围(monday:1~sunday:7) + * @param isCurDay 是否包含当天,true:是,false:不包含 + * @return 日期(yyyy-MM-dd) + * @author zero 2019/04/02 + */ + public static String getPreWeekDate(String curDay, int dayOfWeek, boolean isCurDay) { + dayOfWeek = dayOfWeek < 1 || dayOfWeek > 7 ? 1 : dayOfWeek; + if (isCurDay) { + return LocalDate.parse(curDay).with(TemporalAdjusters.previousOrSame(DayOfWeek.of(dayOfWeek))).toString(); + } else { + return LocalDate.parse(curDay).with(TemporalAdjusters.previous(DayOfWeek.of(dayOfWeek))).toString(); + } + } + + /** + * 获取指定日期当月的最后或第一个星期日期 + * + * @param curDay 指定日期(yyyy-MM-dd) + * @param dayOfWeek 周几(1~7) + * @param lastOrFirst true:最后一个,false本月第一个 + * @return 日期(yyyy-MM-dd) + * @author zero 2019/04/02 + */ + public static String getFirstOrLastWeekDate(String curDay, int dayOfWeek, boolean lastOrFirst) { + dayOfWeek = dayOfWeek < 1 || dayOfWeek > 7 ? 1 : dayOfWeek; + if (lastOrFirst) { + return LocalDate.parse(curDay).with(TemporalAdjusters.lastInMonth(DayOfWeek.of(dayOfWeek))).toString(); + } else { + return LocalDate.parse(curDay).with(TemporalAdjusters.firstInMonth(DayOfWeek.of(dayOfWeek))).toString(); + } + } +} diff --git a/common/src/main/java/com/dr/common/utils/date/JDKDateTimeUtil.java b/common/src/main/java/com/dr/common/utils/date/JDKDateTimeUtil.java new file mode 100644 index 0000000..799f7e9 --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/date/JDKDateTimeUtil.java @@ -0,0 +1,103 @@ +package com.dr.common.utils.date; + +import java.text.SimpleDateFormat; +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Date; + +/** + * @author zb Created in 5:29 PM 2018/10/29 + */ +public class JDKDateTimeUtil { + + + public static LocalDateTime date2LocalDateTime(Date date) { + Instant instant = date.toInstant(); + ZoneId zoneId = ZoneId.systemDefault(); + return instant.atZone(zoneId).toLocalDateTime(); + } + + public static LocalDate date2LocalDate(Date date) { + Instant instant = date.toInstant(); + ZoneId zoneId = ZoneId.systemDefault(); + return instant.atZone(zoneId).toLocalDate(); + } + + public static String localDateTime2String(LocalDateTime localDateTime) { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + return dateTimeFormatter.format(localDateTime); + } + + public static Date localDateTime2Date(LocalDateTime localDateTime) { + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime zdt = localDateTime.atZone(zoneId); + return Date.from(zdt.toInstant()); + } + + public static Date plusMonth(Date date, int month) { + return localDateTime2Date(date2LocalDateTime(date).plusMonths(month)); + } + + public static Date plusDays(Date date, int day) { + return localDateTime2Date(date2LocalDateTime(date).plusDays(day)); + } + + public static Date plusHours(Date date, int hour) { + return localDateTime2Date(date2LocalDateTime(date).plusHours(hour)); + } + + public static Date plusMinutes(Date date, int min) { + return localDateTime2Date(date2LocalDateTime(date).plusMinutes(min)); + } + + public static Date plusSeconds(Date date, int sec) { + return localDateTime2Date(date2LocalDateTime(date).plusSeconds(sec)); + } + + + public static String getStartOfDateStr(int day) { + Date date =localDateTime2Date(date2LocalDateTime(new Date()).plusDays(day)); + SimpleDateFormat temp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return temp.format(startOfToday(date)); + } + + public static String getEndOfDateStr(int day) { + Date date =localDateTime2Date(date2LocalDateTime(new Date()).plusDays(day)); + SimpleDateFormat temp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return temp.format(endOfToday(date)); + } + + public static Date offsetDays(int days) { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) + days); + + return cal.getTime(); + } + + public static Date startOfToday(Date date) { + LocalDateTime todayStart = LocalDateTime.of(date2LocalDate(date), LocalTime.MIN); + + return localDateTime2Date(todayStart); + } + + public static Date endOfToday(Date date) { + LocalDateTime end = LocalDateTime.of(date2LocalDate(date), LocalTime.MAX); + + return localDateTime2Date(end); + } + + + public static void main(String[] args) { + System.out.println(offsetDays(-1)); + + + System.out.println(date2LocalDateTime(new Date())); + System.out.println(localDateTime2String(date2LocalDateTime(new Date()))); + System.out.println(localDateTime2Date(date2LocalDateTime(new Date()))); + System.out.println(plusDays(new Date(), -30)); + System.out.println(startOfToday(new Date())); + System.out.println(endOfToday(new Date())); + System.out.println(getStartOfDateStr(-7)); + } +} diff --git a/common/src/main/java/com/dr/common/utils/date/JDKDateUtil.java b/common/src/main/java/com/dr/common/utils/date/JDKDateUtil.java new file mode 100644 index 0000000..fa561ac --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/date/JDKDateUtil.java @@ -0,0 +1,309 @@ +package com.dr.common.utils.date; + +import java.text.SimpleDateFormat; +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalAdjusters; +import java.util.Calendar; +import java.util.Date; + +/** + * @description: jdk8以上的时间工具类 + * @author: yangdehong + * @date: 2018/4/11 11:17 + */ +public class JDKDateUtil { + + /** + * LocalDateTime ----> DateUtil + * + * @param localDateTime + * @return + */ + public static Date localDateTimeToUdate(LocalDateTime localDateTime) { + ZoneId zone = ZoneId.systemDefault(); + Instant instant = localDateTime.atZone(zone).toInstant(); + Date date = Date.from(instant); + return date; + } + + /** + * LocalDate ----> DateUtil + * + * @param localDate + * @return + */ + public static Date localDateToUdate(LocalDate localDate) { + ZoneId zone = ZoneId.systemDefault(); + Instant instant = localDate.atStartOfDay().atZone(zone).toInstant(); + Date date = Date.from(instant); + return date; + } + + /** + * DateUtil ----> LocalDateTime + * + * @param date + * @return + */ + public static LocalDateTime uDateToLocalDateTime(Date date) { + Instant instant = date.toInstant(); + ZoneId zone = ZoneId.systemDefault(); + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone); + return localDateTime; + } + + /** + * DateUtil ----> LocalDate + * + * @param date + * @return + */ + public static LocalDate uDateToLocalDate(Date date) { + Instant instant = date.toInstant(); + ZoneId zone = ZoneId.systemDefault(); + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone); + LocalDate localDate = localDateTime.toLocalDate(); + return localDate; + } + + /** + * 获取指定月份天数 + * + * @param year + * @param month + * @return + */ + public static int getYearOrMonthDays(int year, int month) { + YearMonth yearMonth = YearMonth.of(year, month); + return yearMonth.lengthOfMonth(); + } + + public static int getYearOrMonthDays(int year, Month month) {// Month.AUGUST + YearMonth yearMonth = YearMonth.of(year, month); + return yearMonth.lengthOfMonth(); + } + + /** + * 指定年天数 + * + * @param year + * @return + */ + public static int getYearOrMonthDays(int year) { + return Year.now().length(); + } + + /** + * 当前月 天数 + * + * @return + */ + public static int getCurrentMonthDays() { + YearMonth currentYearMonth = YearMonth.now(); + return currentYearMonth.lengthOfMonth(); + } + + /** + * 当前年 天数 + * + * @return + */ + public static int getCurrentYearDays() { + YearMonth currentYearMonth = YearMonth.now(); + return currentYearMonth.lengthOfYear(); + } + + /** + * 获取当前年、月、日 + * + * @return + */ + public static int getCurrentYear() { + return YearMonth.now().getYear(); + } + + public static int getCurrentMonth() { + return YearMonth.now().getMonthValue(); + } + + public static int getCurrentDay() { + return MonthDay.now().getDayOfMonth(); + } + + /** + * 当前时间 + * + * @return + */ + public static LocalDate currentDate() { + return LocalDate.now(); + } + + public static LocalDateTime currentTime() { + return LocalDateTime.now(); + } + + /** + * 是否周末 + * + * @return + */ + public static boolean isWeekend() { + boolean flag = false; + DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek(); + if (dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY) { + flag = true; + } + return flag; + } + + /** + * 每周的第一天为礼拜一而不是周日 + * + * @return 每周第一天 + */ + public static Date getStartOfWeek() { + LocalDate inputDate = LocalDate.now(); + TemporalAdjuster firstOfWeek = TemporalAdjusters.ofDateAdjuster(localDate + -> localDate.minusDays(localDate.getDayOfWeek().getValue() - DayOfWeek.MONDAY.getValue())); + inputDate.with(firstOfWeek); + return localDate2Date(inputDate); + } + + /** + * 每个月第一天 + * + * @return 每个月第一天 + */ + public static Date getStartOfMonth(Date date) { + LocalDate inputDate = LocalDate.now(); + if (date != null) { + inputDate = uDateToLocalDate(date); + } + inputDate = inputDate.minusDays(inputDate.getDayOfMonth() - 1); + return localDate2Date(inputDate); + } + + /** + * 当前天之前的days天 + * + * @param days 向前推移的天数 + * @return 计算后的天数 + */ + public static Date minusDays(Long days) { + if (days == null) { + return new Date(); + } + LocalDate localDate = currentDate(); + localDate = localDate.minusDays(days); + return localDate2Date(localDate); + } + + /** + * LocalDate 转换为 Date + * + * @param localDate LocalDate时间 + * @return Date格式时间 + */ + public static Date localDate2Date(LocalDate localDate) { + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime zdt = localDate.atStartOfDay(zoneId); + return Date.from(zdt.toInstant()); + } + + public static Date getStartOfToday(String date) { + LocalDate localDate; + if (date != null) { + localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + } else { + localDate = currentDate(); + } + + return localDate2Date(localDate); + } + + public static Date getStartOfDate(String date) { + LocalDate localDate; + if (date != null) { + localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } else { + localDate = currentDate(); + } + + return localDate2Date(localDate); + } + + public static Date getEndOfToday(String date) { + LocalDate localDate; + if (date != null) { + localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + } else { + localDate = currentDate(); + } + LocalDateTime todayEnd = LocalDateTime.of(localDate, LocalTime.MAX); + + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime zdt = todayEnd.atZone(zoneId); + + return Date.from(zdt.toInstant()); + } + + public static Date addMinute(Date startTime, int minute) { + if (startTime == null) { + startTime = new Date(); + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(startTime); + calendar.add(Calendar.MINUTE, minute); + return calendar.getTime(); + } + + public static Date addDays(Date startTime, int days) { + if (startTime == null) { + startTime = new Date(); + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(startTime); + calendar.add(Calendar.DATE, days); + return calendar.getTime(); + } + + /** + * @Description: 获取当前月第一天 + * @Author: WCJ + * @Date: 2018/9/25 + */ + public static String mouthFirstDay() { + Calendar cale = Calendar.getInstance(); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + cale.add(Calendar.MONTH, 0); + cale.set(Calendar.DAY_OF_MONTH, 1); + String firstday = format.format(cale.getTime()); + return firstday; + } + + /** + * @Description: 获取当前月最后一天 + * @Author: WCJ + * @Date: 2018/9/25 + */ + public static String mouthLastDay() { + Calendar cale = Calendar.getInstance(); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + cale.add(Calendar.MONTH, 1); + cale.set(Calendar.DAY_OF_MONTH, 0); + String lastday = format.format(cale.getTime()); + return lastday; + } + + public static void main(String[] args) { +// LocalDate localDate = currentDate(); +// localDate = localDate.minusDays(11); +// System.out.println(localDate); +// System.out.println(getStartOfMonth()); +// System.out.println(mouthLastDay()); + } + +} diff --git a/common/src/main/java/com/dr/common/utils/excel/ExcelUtil.java b/common/src/main/java/com/dr/common/utils/excel/ExcelUtil.java new file mode 100644 index 0000000..714e909 --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/excel/ExcelUtil.java @@ -0,0 +1,221 @@ +package com.dr.common.utils.excel; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult; +import cn.afterturn.easypoi.excel.imports.ExcelImportService; +import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler; +import com.dr.common.constant.Constant; +import com.dr.common.errorcode.BaseCode; +import com.dr.common.exception.BizException; +import com.dr.common.log.LoggerUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.util.CollectionUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.net.URLEncoder; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +/** + * @author rui.duan + * @version 1.0 + * @className ExcelUtil + * @description excel导入导出方法 + * @date 2019-05-28 15:15 + */ +@Slf4j +public class ExcelUtil { + + /** + * 表格标题行数,默认0 + */ + public final static Integer DEFAULT_TITLE_ROWS = 0; + /** + * 表头行数,默认1 + */ + public final static Integer DEFAULT_HEAD_ROWS = 1; + + + private static final String EXCEL_XLS = "xls"; + private static final String EXCEL_XLSX = "xlsx"; + + + public static void exportExcel(List list, String title, String sheetName, Class pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response) { + ExportParams exportParams = new ExportParams(title, sheetName); + exportParams.setCreateHeadRows(isCreateHeader); + defaultExport(list, pojoClass, fileName, response, exportParams); + + } + + public static void exportExcel(List list, String title, String sheetName, Class pojoClass, String fileName, HttpServletResponse response) { + defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName)); + } + + + /** + * @description: 导出excel文件 + * @params: + * @return: + * @author: rui.duan + * @date: 2019-05-28 + */ + public static void exportExcel(List> list, String fileName, HttpServletResponse response) { + defaultExport(list, fileName, response); + } + + private static void defaultExport(List list, Class pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) { + if (CollectionUtils.isEmpty(list)) { + throw new BizException(BaseCode.EXPORT_OBJECT_EMPTY); + } + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list); + if (workbook != null) { + downLoadExcel(fileName, response, workbook); + } + } + + private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) { + ServletOutputStream outStream = null; + try { + + response.reset();//清空输出流 + String finalFileName = URLEncoder.encode(fileName, "UTF8"); + response.setCharacterEncoding("UTF-8"); + response.setHeader("content-Type", "application/vnd.ms-excel"); + response.setHeader("Content-Disposition", + "attachment;filename=" + finalFileName +"."+ExcelUtil.EXCEL_XLS); + outStream = response.getOutputStream(); + workbook.write(outStream); + outStream.close(); + } catch (IOException e) { + throw new BizException(BaseCode.EXCEL_DEAL_ERROR.getCode(), e.getMessage()); + } + } + + private static void defaultExport(List> list, String fileName, HttpServletResponse response) { + Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF); + if (workbook != null) { + downLoadExcel(fileName, response, workbook); + } + + } + + + /** + * @description: 从本地读取解析excel文件 + * @params: + * @return: + * @author: rui.duan + * @date: 2019-05-28 + */ + public static List importExcel(String filePath, Integer titleRows, Integer headerRows, Class pojoClass) { + if (StringUtils.isBlank(filePath)) { + return null; + } + ImportParams params = new ImportParams(); + params.setTitleRows(titleRows); + params.setHeadRows(headerRows); + List list = null; + try { + list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params); + } catch (NoSuchElementException e) { + throw new BizException(BaseCode.EXCEL_TEMPLE_ERROR); + } catch (Exception e) { + e.printStackTrace(); + throw new BizException(BaseCode.EXCEL_DEAL_ERROR.getCode(), e.getMessage()); + } + return list; + } + + + /** + * @param file http流文件 + * @param titleRows 表格标题行数,默认0 + * @param headerRows 表头行数,默认1 + * @param 需要解析的类型 + * @description: 导入excel文件 + * @return: + * @author: rui.duan + * @date: 2019-05-28 + */ + public static List importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class pojoClass) { + return importExcel(file, titleRows, headerRows, pojoClass,null); + } + + /** + * 添加自定义校验规则 + * @param file + * @param titleRows + * @param headerRows + * @param pojoClass + * @param excelVerifyHandler + * @param + * @return + */ + public static List importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class pojoClass,IExcelVerifyHandler excelVerifyHandler) + { + if (file == null) { + return null; + } + if (checkFile(file)) { + throw new BizException(BaseCode.EXCEL_TYPE_ERROR); + } + //设置导入参数 + ImportParams params = new ImportParams(); + //读取时标题行号 + params.setTitleRows(titleRows); + //读取时头部行号 + params.setHeadRows(headerRows); + //是否开启规则校验 + params.setNeedVerfiy(true); + if(null != excelVerifyHandler){ + //是否使用自定义校验 + params.setVerifyHandler(excelVerifyHandler); + } + List list = null; + try { + ExcelImportResult excelImportResult = new ExcelImportService().importExcelByIs(file.getInputStream(), pojoClass, params, true); + //拿到错误行信息 + List failList = excelImportResult.getFailList(); + if(!CollectionUtils.isEmpty(failList)){ + LoggerUtil.error(log, "导入数据格式有误", failList); + } + //获取正确行信息 + list = excelImportResult.getList(); + if (CollectionUtils.isEmpty(list)) { + throw new BizException(BaseCode.EXCEL_NOT_EMPTY_ERROR); + } else if (list.size() > Constant.LIMIT_IMPORT_COUNT) { + throw new BizException(BaseCode.EXCEL_OVERFLOW); + } + } catch (NoSuchElementException e) { + throw new BizException(BaseCode.EXCEL_NOT_EMPTY_ERROR); + } catch (Exception e) { + throw new BizException(BaseCode.EXCEL_DEAL_ERROR.getCode(), e.getMessage()); + } + return list; + } + + /** + * 检查该文件是否是xls,还是xlsx类型 + */ + private static boolean checkFile(MultipartFile file) { + boolean flg = false; + String name = file.getName(); + if (name.endsWith(EXCEL_XLSX) || name.endsWith(EXCEL_XLS)) { + flg = true; + } + return flg; + + } + +} diff --git a/common/src/main/java/com/dr/common/utils/file/FileUtil.java b/common/src/main/java/com/dr/common/utils/file/FileUtil.java new file mode 100644 index 0000000..9da12af --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/file/FileUtil.java @@ -0,0 +1,39 @@ +package com.dr.common.utils.file; + +import com.dr.common.log.LoggerUtil; +import lombok.extern.slf4j.Slf4j; + +import java.io.File; + +/** + * @ProjectName: code-diff + * @Package: com.dr.common.utils.file + * @Description: 文件处理类 + * @Author: duanrui + * @CreateDate: 2021/1/9 22:56 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +@Slf4j +public class FileUtil { + /** + * 删除目录下所有文件 + * + * @param dir + */ + public static void removeDir(File dir) { + if (null == dir) { + return; + } + File[] files = dir.listFiles(); + for (File file : files) { + if (file.isDirectory()) { + removeDir(file); + } else { + System.out.println(file + ":" + file.delete()); + } + } + LoggerUtil.info(log,dir + ":" + dir.delete()); + } +} diff --git a/common/src/main/java/com/dr/common/utils/list/ListUtils.java b/common/src/main/java/com/dr/common/utils/list/ListUtils.java new file mode 100644 index 0000000..490ebf4 --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/list/ListUtils.java @@ -0,0 +1,20 @@ +package com.dr.common.utils.list; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.function.Predicate; + +/** + * @author rui.duan + * @version 1.0 + * @className ListUtils + * @description 集合去重处理 + * @date 2019/11/21 4:09 下午 + */ +public class ListUtils { + public static Predicate distinctByKey(Function keyExtractor) { + Map map = new ConcurrentHashMap<>(); + return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; + } +} diff --git a/common/src/main/java/com/dr/common/utils/mapper/OrikaMapperUtils.java b/common/src/main/java/com/dr/common/utils/mapper/OrikaMapperUtils.java new file mode 100644 index 0000000..b6d41c7 --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/mapper/OrikaMapperUtils.java @@ -0,0 +1,113 @@ +package com.dr.common.utils.mapper; + +import ma.glasnost.orika.MapperFacade; +import ma.glasnost.orika.MapperFactory; +import ma.glasnost.orika.impl.DefaultMapperFactory; +import ma.glasnost.orika.metadata.Type; +import ma.glasnost.orika.metadata.TypeFactory; + +import java.util.List; + +/** + * Orika作为JavaBean深拷贝实现工具. + *

    + * 对Orika的功能做简单封装,实现BeanClassA 与 BeanClassB相互深度复制的功能. + * 不使用ApacheCommonBeanUtils、SpringBeanUtils和Dozer是因为他们的实现基本上都是基于属性反射查找机制,性能差距及内存消耗较大. + * {@see http://blog.sokolenko.me/2013/05/dozer-vs-orika-vs-manual.html} + * + * @Author : Max. + * @Created : 2018-08-31 + * @E-mail : goday.max@gmail.com + * @Version : 1.0 + * + */ +public class OrikaMapperUtils { + private static MapperFacade mapper; + + static { + MapperFactory factory = new DefaultMapperFactory.Builder().build(); + mapper = factory.getMapperFacade(); + } + + private OrikaMapperUtils() { + } + + /** + * 简单的复制出新类型对象. + *

    + * 内部实现是通过source.getClass() 获得源Class + */ + public static D map(S source, Class destinationClass) { + return mapper.map(source, destinationClass); + } + + /** + * 直接复制两个对象的属性 + *

    + */ + public static void map(S sourceObject, D destinationObject){ + mapper.map(sourceObject, destinationObject); + } + + /** + * 极致性能的复制出新类型对象. + *

    + * 预先通过{@link OrikaMapperUtils#getType(Class)} 静态获取并缓存Type类型,在此处传入 + */ + public static D map(S source, Type sourceType, Type destinationType) { + return mapper.map(source, sourceType, destinationType); + } + + + /** + * 简单的复制出新对象列表到ArrayList + *

    + * 不建议使用{@link MapperFacade#mapAsList(Object[], Class)}} 接口, sourceClass需要在遍历每一个元素的时候反射,实在有点慢 + */ + public static List mapList(Iterable sourceList, Class sourceClass, Class destinationClass) { + return mapper.mapAsList(sourceList, TypeFactory.valueOf(sourceClass), TypeFactory.valueOf(destinationClass)); + } + + /** + * 极致性能的复制出新类型对象到ArrayList. + *

    + * 预先通过{@link OrikaMapperUtils#getType(Class)} 静态获取并缓存Type类型,在此处传入 + */ + public static List mapList(Iterable sourceList, Type sourceType, Type destinationType) { + return mapper.mapAsList(sourceList, sourceType, destinationType); + } + + /** + * 简单复制出新对象列表到数组. + *

    + * 内部实现是通过source.getComponentType() 获得源Class + * + * @param destination 要复制到的目标数组 + * @param source 待复制的源数据数组 + * @param destinationClass 要复制到的目标数组数据元素Class + */ + public static D[] mapArray(final D[] destination, final S[] source, final Class destinationClass) { + return mapper.mapAsArray(destination, source, destinationClass); + } + + /** + * 极致性能的复制出新类型对象到数组. + *

    + * 需要预先通过{@link OrikaMapperUtils#getType(Class)} 静态获取并缓存转换所需Type类型,在此处传入 + * + * @param destination 要复制到的目标数组 + * @param source 待复制的源数据数组 + * @param sourceType 待复制的源数据数组实例类型 + * @param destinationType 要复制到的目标数组类型 + */ + public static D[] mapArray(D[] destination, S[] source, Type sourceType, Type destinationType) { + return mapper.mapAsArray(destination, source, sourceType, destinationType); + } + + /** + * 预先获取orika转换所需要的{@link Type},避免每次复制都做转换. + */ + public static Type getType(final Class rawType) { + return TypeFactory.valueOf(rawType); + } +} diff --git a/common/src/main/java/com/dr/common/utils/security/AESUtils.java b/common/src/main/java/com/dr/common/utils/security/AESUtils.java new file mode 100644 index 0000000..573640e --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/security/AESUtils.java @@ -0,0 +1,86 @@ +package com.dr.common.utils.security; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.util.Base64; + +/** + * @author ylw + * @description AES加密工具 + * @date 2019/5/2715:06 + */ +public class AESUtils { + private static final String ALG_NAME = "AES"; + private static final int ALG_KEY_SIZE = 128; + public static final String DEFAULT_KEY = "eLCrQHDHoBSJgJa+GaS1Fw=="; + private static final String ALG_FULL_NAME_AES_CBC_PKCS5 = "AES/CBC/PKCS5Padding"; + private static final byte[] AES_IV = initIv("AES/CBC/PKCS5Padding"); + + public AESUtils() { + } + + private static byte[] initIv(String algFullName) { + byte[] iv; + int i; + try { + Cipher cipher = Cipher.getInstance(algFullName); + int blockSize = cipher.getBlockSize(); + iv = new byte[blockSize]; + + for(i = 0; i < blockSize; ++i) { + iv[i] = 0; + } + + return iv; + } catch (Exception var5) { + int blockSize = 16; + iv = new byte[blockSize]; + + for(i = 0; i < blockSize; ++i) { + iv[i] = 0; + } + + return iv; + } + } + + public static String generatorKey() throws Exception { + try { + KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); + keyGenerator.init(128); + return Base64.getEncoder().encodeToString(keyGenerator.generateKey().getEncoded()); + } catch (Exception var1) { + throw new Exception("AES生成密钥失败:keySize = 128", var1); + } + } + + public static String encrypt(String content, String key, String charset) throws Exception { + try { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + IvParameterSpec iv = new IvParameterSpec(AES_IV); + cipher.init(1, new SecretKeySpec(Base64.getDecoder().decode(key.getBytes()), "AES"), iv); + byte[] encBytes = cipher.doFinal(content.getBytes(charset)); + return Base64.getEncoder().encodeToString(encBytes); + } catch (Exception var6) { + throw new Exception("AES加密失败:AesContent = " + content + "; charset = " + charset, var6); + } + } + + public static String decrypt(String content, String key, String charset) throws Exception { + try { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + IvParameterSpec iv = new IvParameterSpec(AES_IV); + cipher.init(2, new SecretKeySpec(Base64.getDecoder().decode(key.getBytes()), "AES"), iv); + byte[] cleanBytes = cipher.doFinal(Base64.getDecoder().decode(content.getBytes())); + return new String(cleanBytes, charset); + } catch (Exception var6) { + throw new Exception("AES解密失败:AesContent = " + content + "; charset = " + charset, var6); + } + } + + public static void main(String[] args) throws Exception { + System.out.println(encrypt("111", "eLCrQHDHoBSJgJa+GaS1Fw==", "UTF-8")); + } +} diff --git a/common/src/main/java/com/dr/common/utils/security/Md5Util.java b/common/src/main/java/com/dr/common/utils/security/Md5Util.java new file mode 100644 index 0000000..8035797 --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/security/Md5Util.java @@ -0,0 +1,54 @@ +package com.dr.common.utils.security; + +import com.dr.common.log.LoggerUtil; +import lombok.extern.slf4j.Slf4j; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * @author dr + * @description + * @date 2019/5/2915:21 + */ +@Slf4j +public class Md5Util { + /** + * 获得MD5摘要算法的 MessageDigest 对象 + */ + private static MessageDigest _mdInst = null; + private static char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + private static MessageDigest getMdInst() { + if (_mdInst == null) { + try { + _mdInst = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + LoggerUtil.warn(log,"MessageDigest 对象为空"); + } + } + return _mdInst; + } + + public final static String encode(String s) { + try { + byte[] btInput = s.getBytes(); + // 使用指定的字节更新摘要 + getMdInst().update(btInput); + // 获得密文 + byte[] md = getMdInst().digest(); + // 把密文转换成十六进制的字符串形式 + int j = md.length; + char str[] = new char[j * 2]; + int k = 0; + for (int i = 0; i < j; i++) { + byte byte0 = md[i]; + str[k++] = hexDigits[byte0 >>> 4 & 0xf]; + str[k++] = hexDigits[byte0 & 0xf]; + } + return new String(str); + } catch (Exception e) { + LoggerUtil.warn(log,"加密失败"); + return null; + } + } +} diff --git a/common/src/main/java/com/dr/common/utils/security/SaltUtil.java b/common/src/main/java/com/dr/common/utils/security/SaltUtil.java new file mode 100644 index 0000000..5423cbc --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/security/SaltUtil.java @@ -0,0 +1,30 @@ +package com.dr.common.utils.security; + +import java.util.Random; + +/** + * @author ylw + * @description 生成加密盐工具 + * @date 2019/5/2911:42 + */ +public class SaltUtil { + private static final Integer SALT_SIZE = 8; + + public static int getEncryptTimes(){ + int encryptTimes = (int) (1 + Math.random() * 4); + return encryptTimes; + } + + public static String generateSalt() { + String s = ""; + Random r = new Random(); + for (int i = 0; i < SALT_SIZE; i++) { + s += (char) (48 + r.nextInt( 43)); + } + return s.toLowerCase(); + } + + public static void main(String[] args) { + System.out.println(generateSalt()); + } +} diff --git a/common/src/main/java/com/dr/common/utils/spring/SpringBeanRegisterUtils.java b/common/src/main/java/com/dr/common/utils/spring/SpringBeanRegisterUtils.java new file mode 100644 index 0000000..f1883ec --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/spring/SpringBeanRegisterUtils.java @@ -0,0 +1,81 @@ +package com.dr.common.utils.spring; + +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.context.ConfigurableApplicationContext; + +import java.util.Map; + +/** + * SpringBean手动注册帮助类 + * @author shenxiangyu + * @date 2018-12-11 + */ +public class SpringBeanRegisterUtils { + /** + * 手动动态向Spring容器中注册Bean + * @param clazz + * @param beanName + * @param propName2BeanNameMap + */ + public static T register(Class clazz, String beanName, Map propName2BeanNameMap) { + if (clazz == null ) { + return null; + } + if (beanName == null) { + beanName = getDefaultBeanName(clazz); + } + // 将applicationContext转换为ConfigurableApplicationContext + ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) SpringCtxUtils.getContext(); + + // 获取bean工厂并转换为DefaultListableBeanFactory + DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory(); + + // 通过BeanDefinitionBuilder创建bean定义 + BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz); + + if (propName2BeanNameMap != null) { + for (String propName : propName2BeanNameMap.keySet()) { + String propBeanName = propName2BeanNameMap.get(propName); + + // 设置属性,此属性引用已经定义的bean:propBeanName,前提是这里propBeanName已经被spring容器管理了 + beanDefinitionBuilder.addPropertyReference(propName, propBeanName); + } + } + + // 注册bean + defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getRawBeanDefinition()); + + T obj = (T) SpringCtxUtils.getBean(beanName); + return obj; + } + + private static String getDefaultBeanName(Class clazz) { + String simpleName = clazz.getSimpleName(); + String defaultBeanName = (new StringBuilder()).append(Character.toLowerCase(simpleName.charAt(0))).append(simpleName.substring(1)).toString(); + return defaultBeanName; + } + + /** + * 使用默认beanName的重载方法 + * @param clazz + * @param propName2BeanNameMap + * @param + * @return + */ + public static T register(Class clazz, Map propName2BeanNameMap) { + String beanName = getDefaultBeanName(clazz); + return register(clazz, beanName, propName2BeanNameMap); + } + + /** + * 使用默认beanName和空属性配置的重载方法 + * @param clazz + * @param + * @return + */ + public static T register(Class clazz) { + String beanName = getDefaultBeanName(clazz); + return register(clazz, beanName, null); + } +} diff --git a/common/src/main/java/com/dr/common/utils/spring/SpringCtxUtils.java b/common/src/main/java/com/dr/common/utils/spring/SpringCtxUtils.java new file mode 100644 index 0000000..025de37 --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/spring/SpringCtxUtils.java @@ -0,0 +1,102 @@ +package com.dr.common.utils.spring; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +@Component +public final class SpringCtxUtils implements ApplicationContextAware { + private static ApplicationContext context; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringCtxUtils.context = applicationContext; + } + + public static ApplicationContext getContext() { + return context; + } + + /** + * 获取对象 + * + * @param beanIdOrName bean name + * @return Object 一个以所给名字注册的bean的实例 + * @throws BeansException 异常 + */ + @SuppressWarnings("unchecked") + public static T getBean(String beanIdOrName) throws BeansException { + return StringUtils.isEmpty(beanIdOrName) ? null : (T) context.getBean(beanIdOrName); + } + + /** + * 获取类型为requiredType的对象 + * + * @param clazz {@link Class} + * @return T + * @throws BeansException 异常 + */ + public static T getBean(Class clazz) throws BeansException { + return clazz == null ? null : (T) context.getBean(clazz); + } + + /** + * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true + * + * @param name bean name + * @return boolean + */ + public static boolean containsBean(String name) { + return context.containsBean(name); + } + + /** + * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) + * + * @param name bean name + * @return boolean + * @throws NoSuchBeanDefinitionException 异常 + */ + public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { + return context.isSingleton(name); + } + + /** + * @param name bean name + * @return Class 注册对象的类型 + * @throws NoSuchBeanDefinitionException 异常 + */ + public static Class getType(String name) throws NoSuchBeanDefinitionException { + return context.getType(name); + } + + /** + * 如果给定的bean名字在bean定义中有别名,则返回这些别名 + * + * @param name bean name + * @return stringsort array + * @throws NoSuchBeanDefinitionException 异常 + */ + public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { + return context.getAliases(name); + } + + /** + *

    +     *     静默获取bean,无视异常
    +     * 
    + * @param clazz + * @param + * @return + */ + public static T getBeanQuietly(Class clazz) { + try{ + return clazz == null ? null : (T) context.getBean(clazz); + }catch (Exception e){ + return null; + } + } +} diff --git a/common/src/main/java/com/dr/common/utils/string/PhoneUtils.java b/common/src/main/java/com/dr/common/utils/string/PhoneUtils.java new file mode 100644 index 0000000..f6aa884 --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/string/PhoneUtils.java @@ -0,0 +1,54 @@ +package com.dr.common.utils.string; + +import org.apache.commons.lang3.StringUtils; + +/** + * @className: PhoneUtils + * @description: 电话号码脱敏处理 + * @author: lxf + * @date: 2019-09-11 15:29 + * @version:1.0 + */ +public class PhoneUtils { + + private PhoneUtils() {} + + /** + * 手机号格式校验正则 + */ + public static final String PHONE_REGEX = "^1(3[0-9]|4[57]|5[0-35-9]|7[0135678]|8[0-9])\\d{8}$"; + + /** + * 手机号脱敏筛选正则 + */ + public static final String PHONE_BLUR_REGEX = "(\\d{3})\\d{4}(\\d{4})"; + + /** + * 手机号脱敏替换正则 + */ + public static final String PHONE_BLUR_REPLACE_REGEX = "$1****$2"; + + /** + * 手机号格式校验 + * @param phone + * @return + */ + public static final boolean checkPhone(String phone) { + if (StringUtils.isEmpty(phone)) { + return false; + } + return phone.matches(PHONE_REGEX); + } + + /** + * 手机号脱敏处理 未判断电话号码是否正确是因为电话号码多变 只判断长度 + * @param phone + * @return + */ + public static final String blurPhone(String phone) { + if (StringUtils.isEmpty(phone) || phone.length() < 9) { + return phone; + } + return phone.replaceAll(PHONE_BLUR_REGEX, PHONE_BLUR_REPLACE_REGEX); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/dr/common/utils/string/ScmStringUtil.java b/common/src/main/java/com/dr/common/utils/string/ScmStringUtil.java new file mode 100644 index 0000000..3f3972a --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/string/ScmStringUtil.java @@ -0,0 +1,23 @@ +package com.dr.common.utils.string; + +import org.springframework.util.ObjectUtils; + +/** + * @author rui.duan + * @version 1.0 + * @className StringUtil + * @description 字符串处理逻辑 + * @date 2019-06-26 18:09 + */ +public class ScmStringUtil { + + public static String escapeChar(String before){ + if(!ObjectUtils.isEmpty(before)){ + before = before.replaceAll("/", "//") ; + before = before.replaceAll("_", "/_") ; + before = before.replaceAll("%", "/%") ; + } + return before ; + } + +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..3aefcbe --- /dev/null +++ b/pom.xml @@ -0,0 +1,168 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.8.RELEASE + + com.dr + code-diff-parent + 1.0.0-SNAPSHOT + code-diff-parent + pom + Demo project for Spring Boot + + common + application + + + 1.8 + 1.9.0.RELEASE + 1.9.6 + 1.2.62 + 1.5.4 + 1.1.20 + 3.3.0 + 1.2.12 + 2.1.1 + 1.4.2 + 1.6.2 + 0.3.8 + + + + + + + + + + com.dr + common + ${project.version} + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis.version} + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pageHelper.version} + + + + cn.afterturn + easypoi-spring-boot-starter + ${easypoi.version} + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + com.alibaba + fastjson + ${fastjson.version} + + + ma.glasnost.orika + orika-core + ${orika-core.version} + + + + com.spring4all + swagger-spring-boot-starter + ${swagger.version} + + + com.github.xiaoymin + swagger-bootstrap-ui + ${swagger.ui.version} + + + + org.apache.shiro + shiro-spring-boot-web-starter + ${shiro.version} + + + + com.github.whvcse + easy-captcha + ${captcha.version} + + + + + com.google.guava + guava + 28.2-jre + + + + + com.offbytwo.jenkins + jenkins-client + ${jenkins.api.version} + + + + org.flywaydb + flyway-core + 5.2.4 + + + + com.github.javaparser + javaparser-core + 3.18.0 + + + + + + org.eclipse.jgit + org.eclipse.jgit + 5.10.0.202012080955-r + + + + + + + + + scm:git:https://github.com/rayduan/base-service.git + + + + + + org.apache.maven.plugins + maven-release-plugin + + true + v@{project.version} + false + -DskipTests + + + + + + + maven-deploy-plugin + 2.8.2 + + + + + From cded44431119431fd11026718c423afc99964f6d Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Tue, 12 Jan 2021 10:52:47 +0800 Subject: [PATCH 02/33] Update MethodParserUtils.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 注释修改 --- .../main/java/com/dr/code/diff/util/MethodParserUtils.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java index a6f707a..f8df176 100644 --- a/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java +++ b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java @@ -37,7 +37,7 @@ public static List parseMethods(String classFile) { List list = new ArrayList<>(); FileInputStream in = new FileInputStream(classFile); CompilationUnit cu = StaticJavaParser.parse(in); - //由于jacoco不会统计结构覆盖率,没比较计算接口的方法,此处排除接口类 + //由于jacoco不会统计接口覆盖率,没比较计算接口的方法,此处排除接口类 final List types = cu.getTypes(); boolean isInterface = types.stream().filter(t -> t instanceof ClassOrInterfaceDeclaration).anyMatch(t -> ((ClassOrInterfaceDeclaration) t).isInterface()); if (isInterface) { @@ -52,14 +52,14 @@ public static List parseMethods(String classFile) { } /** - * javaparser工具类核心方法,主要通过这个类便利class文件的方法,此方法主要是获取出代码的所有方法,然后再去对比方法是否存在差异 + * javaparser工具类核心方法,主要通过这个类遍历class文件的方法,此方法主要是获取出代码的所有方法,然后再去对比方法是否存在差异 */ private static class MethodVisitor extends VoidVisitorAdapter> { @Override public void visit(MethodDeclaration n, List list) { //删除注释 n.removeComment(); - //计算方法体的hash值,疑问,空格,特殊转义字符会影响结果,导致相同匹配为差异 + //计算方法体的hash值,疑问,空格,特殊转义字符会影响结果,导致相同匹配为差异?建议提交代码时统一工具格式化 String md5 = Md5Util.encode(n.toString()); MethodInfoResult result = MethodInfoResult.builder() .md5(md5) From 58110e6b1d22c3aab515fcc170ea02c8fd43f97c Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Tue, 12 Jan 2021 10:56:50 +0800 Subject: [PATCH 03/33] Update GitConfig.java --- .../main/java/com/dr/code/diff/config/GitConfig.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java index 11d9154..1bdad73 100644 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -34,9 +34,9 @@ /** * @author rui.duan * @version 1.0 - * @className ShiroConfig + * @className GitConfig * @description git配置类 - * @date 2019/11/19 2:30 下午 + * @date 2021/01/11 2:30 下午 */ @Configuration @Slf4j @@ -97,7 +97,7 @@ public Git cloneRepository(String gitUrl, String codePath, String commitId) { } /** - * 判断工作目录是否存在 + * 判断工作目录是否存在,本来可以每次拉去代码时删除再拉取,但是这样代码多的化IO比较大,所以就代码可以复用 * * @param codePath * @return @@ -153,7 +153,7 @@ public List diffMethods(DiffMethodParams diffMethodParams) { return null; } /** - * 获取原类的方法 + * 多线程获取旧代码和新代码的差异类及差异方法 */ List> priceFuture = validDiffList.stream().map(item -> getClassMethods(getClassFile(baseGit, item.getNewPath()), getClassFile(nowGit, item.getNewPath()), item)).collect(Collectors.toList()); return priceFuture.stream().map(CompletableFuture::join).filter(Objects::nonNull).collect(Collectors.toList()); @@ -185,7 +185,7 @@ private String getClassFile(Git git, String classPackage) { * @return */ private CompletableFuture getClassMethods(String oldClassFile, String mewClassFile, DiffEntry diffEntry) { - //多线程获取差异方法 + //多线程获取差异方法,此处只要考虑增量代码太多的情况下,每个类都需要遍历所有方法,采用多线程方式加快速度 return CompletableFuture.supplyAsync(() -> { //新增类直接标记,不用计算方法 if (DiffEntry.ChangeType.ADD.equals(diffEntry.getChangeType())) { From be4cda9057b493f9b641a494b6da23988874d2b3 Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Wed, 13 Jan 2021 00:29:18 +0800 Subject: [PATCH 04/33] =?UTF-8?q?[modify]=E7=B1=BB=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/dr/code/diff/config/GitConfig.java | 5 +++-- .../java/com/dr/code/diff/config/GitConfigTest.java | 11 ++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java index 1bdad73..2791c8c 100644 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -187,10 +187,11 @@ private String getClassFile(Git git, String classPackage) { private CompletableFuture getClassMethods(String oldClassFile, String mewClassFile, DiffEntry diffEntry) { //多线程获取差异方法,此处只要考虑增量代码太多的情况下,每个类都需要遍历所有方法,采用多线程方式加快速度 return CompletableFuture.supplyAsync(() -> { + String className = diffEntry.getNewPath().split("\\.")[0].split("src/main/java/")[1]; //新增类直接标记,不用计算方法 if (DiffEntry.ChangeType.ADD.equals(diffEntry.getChangeType())) { return ClassInfoResult.builder() - .classFile(diffEntry.getNewPath()) + .classFile(className) .type(DiffEntry.ChangeType.ADD.name()) .build(); } @@ -215,7 +216,7 @@ private CompletableFuture getClassMethods(String oldClassFile, return null; } ClassInfoResult result = ClassInfoResult.builder() - .classFile(diffEntry.getNewPath()) + .classFile(className) .methodInfos(diffMethods) .type(DiffEntry.ChangeType.MODIFY.name()) .build(); diff --git a/application/src/test/java/com/dr/code/diff/config/GitConfigTest.java b/application/src/test/java/com/dr/code/diff/config/GitConfigTest.java index 92ab2f2..56eeeb1 100644 --- a/application/src/test/java/com/dr/code/diff/config/GitConfigTest.java +++ b/application/src/test/java/com/dr/code/diff/config/GitConfigTest.java @@ -29,10 +29,15 @@ void cloneRepository() { @Test void diffMethods() { +// DiffMethodParams diff = DiffMethodParams.builder() +// .baseVersion("dac68b2f3976509b4204a66df8f5e71dffe023b7") +// .nowVersion("74c026849763f1f9f0dfc967949d0b581959c2ea") +// .gitUrl("https://github.com/rayduan/devops-data.git") +// .build(); DiffMethodParams diff = DiffMethodParams.builder() - .baseVersion("dac68b2f3976509b4204a66df8f5e71dffe023b7") - .nowVersion("74c026849763f1f9f0dfc967949d0b581959c2ea") - .gitUrl("https://github.com/rayduan/devops-data.git") + .baseVersion("db84201eea9be107073fa07c24e30262ac91d384") + .nowVersion("dca3a374ba9100c64b970081fad5db7335e99ff6") + .gitUrl("https://github.com/rayduan/base-service.git") .build(); gitConfig.diffMethods(diff); } From 14ae3703efefc7d0b9f1619e99650d99ae0bbd7b Mon Sep 17 00:00:00 2001 From: rayduan Date: Thu, 14 Jan 2021 13:17:03 +0800 Subject: [PATCH 05/33] =?UTF-8?q?[add]=E4=BF=AE=E6=94=B9=E5=8F=82=E6=95=B0?= =?UTF-8?q?=EF=BC=8C=E6=96=B9=E4=BE=BF=E5=90=8E=E7=BB=AD=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/dr/code/diff/util/MethodParserUtils.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java index f8df176..c1ac4fa 100644 --- a/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java +++ b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java @@ -4,9 +4,12 @@ import com.dr.common.utils.security.Md5Util; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; +import org.springframework.util.CollectionUtils; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -61,10 +64,21 @@ public void visit(MethodDeclaration n, List list) { n.removeComment(); //计算方法体的hash值,疑问,空格,特殊转义字符会影响结果,导致相同匹配为差异?建议提交代码时统一工具格式化 String md5 = Md5Util.encode(n.toString()); + //参数处理 + StringBuilder params = new StringBuilder(); + NodeList parameters = n.getParameters(); + if(!CollectionUtils.isEmpty(parameters)){ + for (int i = 0; i < parameters.size(); i++) { + params.append(parameters.get(i)); + if(i != parameters.size() -1){ + params.append(","); + } + } + } MethodInfoResult result = MethodInfoResult.builder() .md5(md5) .methodName(n.getNameAsString()) - .parameters(n.getParameters().toString()) + .parameters(params.toString()) .build(); list.add(result); super.visit(n, list); From 2eacb56222000fa31599e96497807502575496f7 Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Thu, 28 Jan 2021 09:54:42 +0800 Subject: [PATCH 06/33] Create LICENSE --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 831602db692706294e6922739117ba6d92839dcf Mon Sep 17 00:00:00 2001 From: rayduan Date: Thu, 28 Jan 2021 10:40:31 +0800 Subject: [PATCH 07/33] =?UTF-8?q?[add]=E6=B7=BB=E5=8A=A0svn=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=B1=BB=EF=BC=8C=E5=90=8E=E7=BB=AD=E5=81=9Asvn?= =?UTF-8?q?=E5=B7=AE=E5=BC=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ application/pom.xml | 5 +++++ pom.xml | 8 ++++++++ 3 files changed, 15 insertions(+) diff --git a/.gitignore b/.gitignore index 69db9df..44f4558 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ /application/application.iml /code-diff-parent.iml /common/common.iml +/common/target/classes/com/dr/common/ +/application/target/ diff --git a/application/pom.xml b/application/pom.xml index 45efe3f..be4faf6 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -77,6 +77,11 @@ org.eclipse.jgit + + org.tmatesoft.svnkit + svnkit + + com.github.javaparser diff --git a/pom.xml b/pom.xml index 3aefcbe..847f5d5 100644 --- a/pom.xml +++ b/pom.xml @@ -133,6 +133,14 @@ org.eclipse.jgit 5.10.0.202012080955-r + + + + org.tmatesoft.svnkit + svnkit + 1.10.1 + + From 92e8b80f829f1874a13c2ab6a120ce281d309d99 Mon Sep 17 00:00:00 2001 From: rayduan Date: Fri, 5 Mar 2021 10:18:00 +0800 Subject: [PATCH 08/33] =?UTF-8?q?[modify]=E4=BF=AE=E5=A4=8D=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E5=AD=98=E5=9C=A8=E4=BB=A3=E7=A0=81=E6=97=B6pull?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/dr/code/diff/config/GitConfig.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java index 2791c8c..0b3e9bd 100644 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -84,12 +84,15 @@ public Git cloneRepository(String gitUrl, String codePath, String commitId) { .setDirectory(new File(codePath)) .setBranch(commitId) .call(); + // 下载指定commitId/branch + git.checkout().setName(commitId).call(); } else { LoggerUtil.info(log, "本地代码存在,直接使用", gitUrl, codePath); git = Git.open(new File(codePath)); + //更新代码 + git.pull().call(); } - // 切换到指定commitId - git.checkout().setName(commitId).call(); + } catch (IOException | GitAPIException e) { e.printStackTrace(); } From c7373d64ca5eb102a2578ad3509abb99c48029d7 Mon Sep 17 00:00:00 2001 From: rayduan Date: Fri, 5 Mar 2021 10:50:40 +0800 Subject: [PATCH 09/33] =?UTF-8?q?[modify]=E4=BF=AE=E5=A4=8D=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E5=AD=98=E5=9C=A8=E4=BB=A3=E7=A0=81=E6=97=B6pull?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/dr/code/diff/config/GitConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java index 0b3e9bd..74dd2ec 100644 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -90,7 +90,7 @@ public Git cloneRepository(String gitUrl, String codePath, String commitId) { LoggerUtil.info(log, "本地代码存在,直接使用", gitUrl, codePath); git = Git.open(new File(codePath)); //更新代码 - git.pull().call(); + git.pull().setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)).call(); } } catch (IOException | GitAPIException e) { From 518372c1db3b8495930bbe12d1e1af65c96d424a Mon Sep 17 00:00:00 2001 From: rayduan Date: Fri, 5 Mar 2021 13:33:37 +0800 Subject: [PATCH 10/33] =?UTF-8?q?[modify]=E4=BF=AE=E5=A4=8D=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E5=AD=98=E5=9C=A8=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=88=86?= =?UTF-8?q?=E6=94=AF=E5=92=8CcommitId=E7=9A=84=E4=B8=8D=E5=90=8C=E6=93=8D?= =?UTF-8?q?=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/dr/code/diff/config/GitConfig.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java index 74dd2ec..b08cfb6 100644 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -10,6 +10,7 @@ import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.diff.DiffEntry; +import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevTree; @@ -89,8 +90,12 @@ public Git cloneRepository(String gitUrl, String codePath, String commitId) { } else { LoggerUtil.info(log, "本地代码存在,直接使用", gitUrl, codePath); git = Git.open(new File(codePath)); - //更新代码 - git.pull().setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)).call(); + git.getRepository().getFullBranch(); + //判断是分支还是commitId,分支做更新,commitId无法改变用原有的 + if(git.getRepository().exactRef(Constants.HEAD).isSymbolic()){ + //更新代码 + git.pull().setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)).call(); + } } } catch (IOException | GitAPIException e) { From a084323bf7532bbc8a6ac65cf77f77b7944bdbe2 Mon Sep 17 00:00:00 2001 From: rayduan Date: Fri, 5 Mar 2021 14:01:40 +0800 Subject: [PATCH 11/33] =?UTF-8?q?[modify]=E6=8F=90=E4=BE=9B=E8=BD=AC?= =?UTF-8?q?=E4=B9=89=E5=8C=96=E7=BB=93=E6=9E=9C=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/dr/code/diff/config/GitConfig.java | 1 - .../diff/controller/CodeDiffController.java | 7 ++- .../dr/common/response/UniqueApoResponse.java | 32 ++++++++++++ .../common/utils/string/BaseStringUtil.java | 50 +++++++++++++++++++ .../dr/common/utils/string/ScmStringUtil.java | 23 --------- 5 files changed, 87 insertions(+), 26 deletions(-) create mode 100644 common/src/main/java/com/dr/common/response/UniqueApoResponse.java create mode 100644 common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java delete mode 100644 common/src/main/java/com/dr/common/utils/string/ScmStringUtil.java diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java index b08cfb6..075a944 100644 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -97,7 +97,6 @@ public Git cloneRepository(String gitUrl, String codePath, String commitId) { git.pull().setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)).call(); } } - } catch (IOException | GitAPIException e) { e.printStackTrace(); } diff --git a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java index f0e1eb0..bf416e8 100644 --- a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java +++ b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java @@ -1,11 +1,14 @@ package com.dr.code.diff.controller; +import com.alibaba.fastjson.JSONArray; import com.dr.code.diff.dto.ClassInfoResult; import com.dr.code.diff.dto.DiffMethodParams; import com.dr.code.diff.service.CodeDiffService; import com.dr.code.diff.vo.result.CodeDiffResultVO; import com.dr.common.response.ApiResponse; +import com.dr.common.response.UniqueApoResponse; import com.dr.common.utils.mapper.OrikaMapperUtils; +import com.dr.common.utils.string.BaseStringUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -34,7 +37,7 @@ public class CodeDiffController { @ApiOperation("获取差异代码") @RequestMapping(value = "/list", method = RequestMethod.GET) - public ApiResponse> getList( + public UniqueApoResponse> getList( @ApiParam(required = true, name = "gitUrl", value = "git远程仓库地址") @RequestParam(value = "gitUrl") String gitUrl, @ApiParam(required = true, name = "baseVersion", value = "git原始分支或tag") @@ -48,7 +51,7 @@ public ApiResponse> getList( .build(); List diffCodeList = codeDiffService.getDiffCode(diffMethodParams); List codeDiffResultVOS = OrikaMapperUtils.mapList(diffCodeList, ClassInfoResult.class, CodeDiffResultVO.class); - return new ApiResponse>().success(codeDiffResultVOS); + return new UniqueApoResponse>().success(codeDiffResultVOS, BaseStringUtil.escapeChar(JSONArray.toJSON(codeDiffResultVOS).toString())); } diff --git a/common/src/main/java/com/dr/common/response/UniqueApoResponse.java b/common/src/main/java/com/dr/common/response/UniqueApoResponse.java new file mode 100644 index 0000000..f91a305 --- /dev/null +++ b/common/src/main/java/com/dr/common/response/UniqueApoResponse.java @@ -0,0 +1,32 @@ +package com.dr.common.response; + +import com.dr.common.errorcode.BaseCode; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.poi.ss.formula.functions.T; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.common.response + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/3/5 13:48 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class UniqueApoResponse extends ApiResponse{ + private String uniqueData; + + public UniqueApoResponse success(T data,String uniqueData) { + super.setCode(BaseCode.SUCCESS.getCode()); + super.setMsg(BaseCode.SUCCESS.getInfo()); + super.setData(data); + this.uniqueData = uniqueData; + return this; + } +} diff --git a/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java b/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java new file mode 100644 index 0000000..e3a1453 --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java @@ -0,0 +1,50 @@ +package com.dr.common.utils.string; + +import org.springframework.util.ObjectUtils; + +/** + * @author rui.duan + * @version 1.0 + * @className StringUtil + * @description 字符串处理逻辑 + * @date 2019-06-26 18:09 + */ +public class BaseStringUtil { + + public static String escapeChar(String before){ + if(!ObjectUtils.isEmpty(before)){ + before = before.replaceAll("/", "//") ; + before = before.replaceAll("_", "/_") ; + before = before.replaceAll("%", "/%") ; + } + return before ; + } + + /** + * solr检索时,转换特殊字符 + * + * @param s 需要转义的字符串 + * @return 返回转义后的字符串 + */ + public static String escapeQueryChars(String s) { + if(ObjectUtils.isEmpty(s)){ + return s; + } + StringBuilder sb = new StringBuilder(); + //查询字符串一般不会太长,挨个遍历也花费不了多少时间 + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + // These characters are part of the query syntax and must be escaped + if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' + || c == ':' || c == '^' || c == '[' || c == ']' || c == '\"' + || c == '{' || c == '}' || c == '~' || c == '*' || c == '?' + || c == '|' || c == '&' || c == ';' || c == '/' || c == '.' + || c == '$' || Character.isWhitespace(c)) { + sb.append('\\'); + } + sb.append(c); + } + return sb.toString(); + } + +} diff --git a/common/src/main/java/com/dr/common/utils/string/ScmStringUtil.java b/common/src/main/java/com/dr/common/utils/string/ScmStringUtil.java deleted file mode 100644 index 3f3972a..0000000 --- a/common/src/main/java/com/dr/common/utils/string/ScmStringUtil.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.dr.common.utils.string; - -import org.springframework.util.ObjectUtils; - -/** - * @author rui.duan - * @version 1.0 - * @className StringUtil - * @description 字符串处理逻辑 - * @date 2019-06-26 18:09 - */ -public class ScmStringUtil { - - public static String escapeChar(String before){ - if(!ObjectUtils.isEmpty(before)){ - before = before.replaceAll("/", "//") ; - before = before.replaceAll("_", "/_") ; - before = before.replaceAll("%", "/%") ; - } - return before ; - } - -} From 2167594187eba2e2a88db056036851a380b220b2 Mon Sep 17 00:00:00 2001 From: rayduan Date: Fri, 5 Mar 2021 16:25:34 +0800 Subject: [PATCH 12/33] =?UTF-8?q?[modify]=E6=8F=90=E4=BE=9B=E8=BD=AC?= =?UTF-8?q?=E4=B9=89=E5=8C=96=E7=BB=93=E6=9E=9C=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/dr/code/diff/controller/CodeDiffController.java | 1 - .../main/java/com/dr/common/utils/string/BaseStringUtil.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java index bf416e8..5cbdd14 100644 --- a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java +++ b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java @@ -5,7 +5,6 @@ import com.dr.code.diff.dto.DiffMethodParams; import com.dr.code.diff.service.CodeDiffService; import com.dr.code.diff.vo.result.CodeDiffResultVO; -import com.dr.common.response.ApiResponse; import com.dr.common.response.UniqueApoResponse; import com.dr.common.utils.mapper.OrikaMapperUtils; import com.dr.common.utils.string.BaseStringUtil; diff --git a/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java b/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java index e3a1453..6976991 100644 --- a/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java +++ b/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java @@ -13,7 +13,7 @@ public class BaseStringUtil { public static String escapeChar(String before){ if(!ObjectUtils.isEmpty(before)){ - before = before.replaceAll("/", "//") ; +// before = before.replaceAll("/", "//") ; before = before.replaceAll("_", "/_") ; before = before.replaceAll("%", "/%") ; } From 4e6b6e2a80548032fbe521ad01e6fa9ba144d8cf Mon Sep 17 00:00:00 2001 From: rayduan Date: Fri, 5 Mar 2021 17:08:11 +0800 Subject: [PATCH 13/33] =?UTF-8?q?[modify]=E6=8F=90=E4=BE=9B=E8=BD=AC?= =?UTF-8?q?=E4=B9=89=E5=8C=96=E7=BB=93=E6=9E=9C=E9=9B=86=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/dr/code/diff/config/GitConfig.java | 2 ++ .../dr/code/diff/controller/CodeDiffController.java | 2 +- .../com/dr/code/diff/vo/result/MethodInfoResultVO.java | 10 +++++----- .../com/dr/common/utils/string/BaseStringUtil.java | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java index 075a944..997989c 100644 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -6,6 +6,7 @@ import com.dr.code.diff.util.MethodParserUtils; import com.dr.common.log.LoggerUtil; import com.dr.common.utils.file.FileUtil; +import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; @@ -199,6 +200,7 @@ private CompletableFuture getClassMethods(String oldClassFile, if (DiffEntry.ChangeType.ADD.equals(diffEntry.getChangeType())) { return ClassInfoResult.builder() .classFile(className) + .methodInfos(Lists.newArrayList()) .type(DiffEntry.ChangeType.ADD.name()) .build(); } diff --git a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java index 5cbdd14..f1d554a 100644 --- a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java +++ b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java @@ -50,7 +50,7 @@ public UniqueApoResponse> getList( .build(); List diffCodeList = codeDiffService.getDiffCode(diffMethodParams); List codeDiffResultVOS = OrikaMapperUtils.mapList(diffCodeList, ClassInfoResult.class, CodeDiffResultVO.class); - return new UniqueApoResponse>().success(codeDiffResultVOS, BaseStringUtil.escapeChar(JSONArray.toJSON(codeDiffResultVOS).toString())); + return new UniqueApoResponse>().success(codeDiffResultVOS, JSONArray.toJSON(codeDiffResultVOS).toString()); } diff --git a/application/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java b/application/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java index dc6bc99..5914cb5 100644 --- a/application/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java +++ b/application/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java @@ -15,11 +15,11 @@ public class MethodInfoResultVO { - /** - * 方法的md5 - */ - @ApiModelProperty(name = "md5", value = "方法的md5", dataType = "string", example = "13E2BFB69F7D987A6DB4272400C94E9B") - public String md5; +// /** +// * 方法的md5 +// */ +// @ApiModelProperty(name = "md5", value = "方法的md5", dataType = "string", example = "13E2BFB69F7D987A6DB4272400C94E9B") +// public String md5; /** * 方法名 */ diff --git a/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java b/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java index 6976991..e3a1453 100644 --- a/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java +++ b/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java @@ -13,7 +13,7 @@ public class BaseStringUtil { public static String escapeChar(String before){ if(!ObjectUtils.isEmpty(before)){ -// before = before.replaceAll("/", "//") ; + before = before.replaceAll("/", "//") ; before = before.replaceAll("_", "/_") ; before = before.replaceAll("%", "/%") ; } From bcf6bed4322e3c0f2ea4ef1579e7ace12b4a8149 Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Sat, 6 Mar 2021 18:59:57 +0800 Subject: [PATCH 14/33] =?UTF-8?q?[modify]=E6=96=B0=E5=A2=9E=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E5=B7=A5=E7=A8=8B=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/dr/code/diff/config/GitConfig.java | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java index 997989c..ec3ffa2 100644 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -6,6 +6,8 @@ import com.dr.code.diff.util.MethodParserUtils; import com.dr.common.log.LoggerUtil; import com.dr.common.utils.file.FileUtil; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.eclipse.jgit.api.Git; @@ -93,7 +95,7 @@ public Git cloneRepository(String gitUrl, String codePath, String commitId) { git = Git.open(new File(codePath)); git.getRepository().getFullBranch(); //判断是分支还是commitId,分支做更新,commitId无法改变用原有的 - if(git.getRepository().exactRef(Constants.HEAD).isSymbolic()){ + if (git.getRepository().exactRef(Constants.HEAD).isSymbolic()) { //更新代码 git.pull().setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)).call(); } @@ -141,9 +143,9 @@ public Boolean checkGitWorkSpace(String gitUrl, String codePath) throws IOExcept public List diffMethods(DiffMethodParams diffMethodParams) { try { //原有代码git对象 - Git baseGit = cloneRepository(diffMethodParams.getGitUrl(), localBaseRepoDir + diffMethodParams.getBaseVersion(), diffMethodParams.getBaseVersion()); + Git baseGit = cloneRepository(diffMethodParams.getGitUrl(), getLocalDir(diffMethodParams.getGitUrl(), localBaseRepoDir, diffMethodParams.getBaseVersion()), diffMethodParams.getBaseVersion()); //现有代码git对象 - Git nowGit = cloneRepository(diffMethodParams.getGitUrl(), localBaseRepoDir + diffMethodParams.getNowVersion(), diffMethodParams.getNowVersion()); + Git nowGit = cloneRepository(diffMethodParams.getGitUrl(), getLocalDir(diffMethodParams.getGitUrl(), localBaseRepoDir, diffMethodParams.getNowVersion()), diffMethodParams.getNowVersion()); AbstractTreeIterator baseTree = prepareTreeParser(baseGit.getRepository(), diffMethodParams.getBaseVersion()); AbstractTreeIterator nowTree = prepareTreeParser(nowGit.getRepository(), diffMethodParams.getNowVersion()); //获取两个版本之间的差异代码 @@ -257,4 +259,30 @@ public static AbstractTreeIterator prepareTreeParser(Repository repository, Stri } return null; } + + /** + * 取远程代码本地存储路径 + * + * @param gitUrl + * @param localBaseRepoDir + * @param version + * @return + */ + public static String getLocalDir(String gitUrl, String localBaseRepoDir, String version) { + StringBuilder localDir = new StringBuilder(localBaseRepoDir); + if (Strings.isNullOrEmpty(gitUrl)) { + return ""; + } + String repoName = Splitter.on("/") + .splitToStream(gitUrl).reduce((first, second) -> second) + .map(e -> Splitter.on(".").splitToStream(e).findFirst().get()).get(); + localDir.append(repoName); + localDir.append("\\"); + localDir.append(version); + return localDir.toString(); + + + } } + + From df68b48d653cde8a1661dcc1e31b4c93a7abace8 Mon Sep 17 00:00:00 2001 From: rayduan Date: Mon, 8 Mar 2021 10:39:12 +0800 Subject: [PATCH 15/33] =?UTF-8?q?[modify]=E6=9B=B4=E6=96=B0=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 154 +++++++++++------------------------------------------- 1 file changed, 31 insertions(+), 123 deletions(-) diff --git a/README.md b/README.md index 5401ad9..d4f85d2 100644 --- a/README.md +++ b/README.md @@ -18,140 +18,48 @@ "msg": "业务处理成功", "data": [ { - "classFile": "collector/src/main/java/com/geely/collector/CollectorApplication.java", + "classFile": "com/dr/code/diff/config/GitConfig", "methodInfos": [ { - "md5": "13E2BFB69F7D987A6DB4272400C94E9B", - "methodName": "main", - "parameters": "[String[] args]" + "methodName": "cloneRepository", + "parameters": "String gitUrl,String codePath,String commitId" + }, + { + "methodName": "diffMethods", + "parameters": "DiffMethodParams diffMethodParams" + }, + { + "methodName": "getClassMethods", + "parameters": "String oldClassFile,String mewClassFile,DiffEntry diffEntry" } ], "type": "MODIFY" }, { - "classFile": "collector/src/main/java/com/geely/collector/bean/CodeQuality.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "collector/src/main/java/com/geely/collector/dao/basic/CodeQualityMapper.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "collector/src/main/java/com/geely/collector/dao/extension/CodeQualityExtensionMapper.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "collector/src/main/java/com/geely/collector/mvc/APIResponse.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "collector/src/main/java/com/geely/collector/mvc/BusinessException.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "collector/src/main/java/com/geely/collector/task/TestTask.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/gitlab/config/GitlabAPIConfig.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/gitlab/dto/CommitDetail.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/gitlab/dto/GitLabStats.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/gitlab/service/GitlabService.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/gitlab/service/impl/GitlabServiceImpl.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/sonar/Test.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/sonar/client/BaseHttpClient.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/sonar/client/MeasureClient.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/sonar/client/ProjectClient.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/sonar/client/authentication/PreemptiveAuth.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/sonar/config/SonarConnectionConf.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/sonar/dto/BaseModel.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/sonar/dto/MeasuresBean.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/sonar/dto/MeasuresResultDto.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/sonar/service/MeasureService.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/sonar/service/impl/MeasureServiceImpl.java", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "third-sdk/src/main/java/com/geely/sonar/util/HttpResponseValidator.java", - "methodInfos": null, - "type": "ADD" + "classFile": "com/dr/code/diff/controller/CodeDiffController", + "methodInfos": [ + { + "methodName": "getList", + "parameters": "@ApiParam(required = true, name = \"gitUrl\", value = \"git远程仓库地址\") @RequestParam(value = \"gitUrl\") String gitUrl,@ApiParam(required = true, name = \"baseVersion\", value = \"git原始分支或tag\") @RequestParam(value = \"baseVersion\") String baseVersion,@ApiParam(required = true, name = \"nowVersion\", value = \"git现分支或tag\") @RequestParam(value = \"nowVersion\") String nowVersion" + } + ], + "type": "MODIFY" }, { - "classFile": "third-sdk/src/main/java/com/geely/sonar/util/HttpResponseWrapper.java", - "methodInfos": null, - "type": "ADD" + "classFile": "com/dr/code/diff/service/impl/CodeDiffServiceImpl", + "methodInfos": [ + { + "methodName": "getDiffCode", + "parameters": "DiffMethodParams diffMethodParams" + } + ], + "type": "MODIFY" }, { - "classFile": "third-sdk/src/main/java/com/geely/sonar/util/SonarContant.java", - "methodInfos": null, + "classFile": "com/dr/common/utils/string/ScmStringUtil", + "methodInfos": [], "type": "ADD" } - ] + ], + "uniqueData": "[{\"classFile\":\"com/dr/code/diff/config/GitConfig\",\"methodInfos\":[{\"methodName\":\"cloneRepository\",\"parameters\":\"String gitUrl,String codePath,String commitId\"},{\"methodName\":\"diffMethods\",\"parameters\":\"DiffMethodParams diffMethodParams\"},{\"methodName\":\"getClassMethods\",\"parameters\":\"String oldClassFile,String mewClassFile,DiffEntry diffEntry\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/code/diff/controller/CodeDiffController\",\"methodInfos\":[{\"methodName\":\"getList\",\"parameters\":\"@ApiParam(required = true, name = \\\"gitUrl\\\", value = \\\"git远程仓库地址\\\") @RequestParam(value = \\\"gitUrl\\\") String gitUrl,@ApiParam(required = true, name = \\\"baseVersion\\\", value = \\\"git原始分支或tag\\\") @RequestParam(value = \\\"baseVersion\\\") String baseVersion,@ApiParam(required = true, name = \\\"nowVersion\\\", value = \\\"git现分支或tag\\\") @RequestParam(value = \\\"nowVersion\\\") String nowVersion\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/code/diff/service/impl/CodeDiffServiceImpl\",\"methodInfos\":[{\"methodName\":\"getDiffCode\",\"parameters\":\"DiffMethodParams diffMethodParams\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/common/utils/string/ScmStringUtil\",\"methodInfos\":[],\"type\":\"ADD\"}]" } From 4527a32676802051473d5652c8869d605ac83ba3 Mon Sep 17 00:00:00 2001 From: rayduan Date: Mon, 8 Mar 2021 11:15:34 +0800 Subject: [PATCH 16/33] =?UTF-8?q?[modify]Add=E7=B1=BB=EF=BC=8C=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E4=B8=BAnull?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/src/main/java/com/dr/code/diff/config/GitConfig.java | 1 - 1 file changed, 1 deletion(-) diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java index ec3ffa2..d1a55ed 100644 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -202,7 +202,6 @@ private CompletableFuture getClassMethods(String oldClassFile, if (DiffEntry.ChangeType.ADD.equals(diffEntry.getChangeType())) { return ClassInfoResult.builder() .classFile(className) - .methodInfos(Lists.newArrayList()) .type(DiffEntry.ChangeType.ADD.name()) .build(); } From 340192deafd3fabf82ee11b7c1201cfdf375bf85 Mon Sep 17 00:00:00 2001 From: rayduan Date: Mon, 8 Mar 2021 13:12:43 +0800 Subject: [PATCH 17/33] =?UTF-8?q?[modify]=E4=BF=AE=E5=A4=8Dnull=E8=A2=ABfa?= =?UTF-8?q?stjson=E8=BF=87=E6=BB=A4=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/dr/code/diff/controller/CodeDiffController.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java index f1d554a..b0c225e 100644 --- a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java +++ b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java @@ -1,6 +1,8 @@ package com.dr.code.diff.controller; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.serializer.SerializerFeature; import com.dr.code.diff.dto.ClassInfoResult; import com.dr.code.diff.dto.DiffMethodParams; import com.dr.code.diff.service.CodeDiffService; @@ -50,7 +52,7 @@ public UniqueApoResponse> getList( .build(); List diffCodeList = codeDiffService.getDiffCode(diffMethodParams); List codeDiffResultVOS = OrikaMapperUtils.mapList(diffCodeList, ClassInfoResult.class, CodeDiffResultVO.class); - return new UniqueApoResponse>().success(codeDiffResultVOS, JSONArray.toJSON(codeDiffResultVOS).toString()); + return new UniqueApoResponse>().success(codeDiffResultVOS, JSON.toJSONString(codeDiffResultVOS,SerializerFeature.WriteMapNullValue)); } From 64466172b934d21873ad50c0e59906d9d8d38284 Mon Sep 17 00:00:00 2001 From: rayduan Date: Tue, 9 Mar 2021 10:46:15 +0800 Subject: [PATCH 18/33] =?UTF-8?q?[modify]=E4=BC=98=E5=8C=96=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dr/code/diff/config/ExceptionAdvice.java | 92 +++++++++++++++++++ .../com/dr/code/diff/config/GitConfig.java | 4 +- .../diff/controller/CodeDiffController.java | 6 +- .../java/com/dr/common/errorcode/BizCode.java | 2 +- 4 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 application/src/main/java/com/dr/code/diff/config/ExceptionAdvice.java diff --git a/application/src/main/java/com/dr/code/diff/config/ExceptionAdvice.java b/application/src/main/java/com/dr/code/diff/config/ExceptionAdvice.java new file mode 100644 index 0000000..9574d3c --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/config/ExceptionAdvice.java @@ -0,0 +1,92 @@ +package com.dr.code.diff.config; + +import com.dr.common.errorcode.BaseCode; +import com.dr.common.exception.BizException; +import com.dr.common.log.LoggerUtil; +import com.dr.common.response.ApiResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.validation.BindException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingServletRequestParameterException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletResponse; + +/** + * controller统一参数异常切面通知 + * + * @author 异常处理 + */ +@ControllerAdvice +@Slf4j +public class ExceptionAdvice { + + @ExceptionHandler(Exception.class) + @ResponseBody + public ApiResponse handleException(Exception e) { + LoggerUtil.error(log, "未知异常", e); + ApiResponse response = new ApiResponse(BaseCode.SYSTEM_FAILD); + response.setData(e.getMessage()); + return response; + } + + @ExceptionHandler(BizException.class) + @ResponseBody + public ApiResponse handleBizException(HttpServletResponse resp, BizException e) { + LoggerUtil.info(log, "服务业务异常", e.getCode(), e.getMsg()); + return new ApiResponse(e); + } + + + @ExceptionHandler(MissingServletRequestParameterException.class) + @ResponseBody + public ApiResponse handleMissingServletRequestParameterException(MissingServletRequestParameterException e) { + LoggerUtil.error(log, "请求必传参数为空", e, e.getMessage()); + return new ApiResponse(BaseCode.PARAM_ERROR); + } + + + /*** + * 拦截HttpMessageNotReadableException + */ + @ExceptionHandler(HttpMessageNotReadableException.class) + @ResponseBody + public ApiResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { + LoggerUtil.error(log, "请求必传参数为空", e, e.getMessage()); + return new ApiResponse(BaseCode.PARAM_ERROR); + } + + + /** + * 拦截MethodArgumentNotValidException + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + @ResponseBody + public ApiResponse handleBindException(MethodArgumentNotValidException e) { + StringBuilder builder = new StringBuilder(); + e.getBindingResult().getFieldErrors().stream().forEach(x -> { + builder.append(x.getField()).append(":").append(x.getDefaultMessage()).append(";"); + }); + LoggerUtil.error(log, "请求参数校验异常", e, builder.toString()); + return new ApiResponse(BaseCode.PARAM_ERROR.getCode(), builder.toString()); + } + + /** + * 拦截BindException + */ + @ExceptionHandler(BindException.class) + @ResponseBody + public ApiResponse handleBindException(BindException e) { + StringBuilder builder = new StringBuilder(); + e.getFieldErrors().forEach(x -> builder.append(x.getField()) + .append(":") + .append(x.getDefaultMessage()) + .append(";")); + LoggerUtil.error(log, "请求参数校验异常", e, builder.toString()); + return new ApiResponse(BaseCode.PARAM_ERROR.getCode(), builder.toString()); + } + +} diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java index d1a55ed..0b5e5d8 100644 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -4,11 +4,12 @@ import com.dr.code.diff.dto.DiffMethodParams; import com.dr.code.diff.dto.MethodInfoResult; import com.dr.code.diff.util.MethodParserUtils; +import com.dr.common.errorcode.BizCode; +import com.dr.common.exception.BizException; import com.dr.common.log.LoggerUtil; import com.dr.common.utils.file.FileUtil; import com.google.common.base.Splitter; import com.google.common.base.Strings; -import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; @@ -102,6 +103,7 @@ public Git cloneRepository(String gitUrl, String codePath, String commitId) { } } catch (IOException | GitAPIException e) { e.printStackTrace(); + throw new BizException(BizCode.GIT_OPERATED_FAIlED); } return git; } diff --git a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java index b0c225e..41b2188 100644 --- a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java +++ b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java @@ -10,6 +10,8 @@ import com.dr.common.response.UniqueApoResponse; import com.dr.common.utils.mapper.OrikaMapperUtils; import com.dr.common.utils.string.BaseStringUtil; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -44,7 +46,7 @@ public UniqueApoResponse> getList( @ApiParam(required = true, name = "baseVersion", value = "git原始分支或tag") @RequestParam(value = "baseVersion") String baseVersion, @ApiParam(required = true, name = "nowVersion", value = "git现分支或tag") - @RequestParam(value = "nowVersion") String nowVersion) { + @RequestParam(value = "nowVersion") String nowVersion) throws JsonProcessingException { DiffMethodParams diffMethodParams = DiffMethodParams.builder() .gitUrl(gitUrl) .baseVersion(baseVersion) @@ -52,7 +54,7 @@ public UniqueApoResponse> getList( .build(); List diffCodeList = codeDiffService.getDiffCode(diffMethodParams); List codeDiffResultVOS = OrikaMapperUtils.mapList(diffCodeList, ClassInfoResult.class, CodeDiffResultVO.class); - return new UniqueApoResponse>().success(codeDiffResultVOS, JSON.toJSONString(codeDiffResultVOS,SerializerFeature.WriteMapNullValue)); + return new UniqueApoResponse>().success(codeDiffResultVOS, JSON.toJSONString(codeDiffResultVOS,SerializerFeature.WriteNullListAsEmpty)); } diff --git a/common/src/main/java/com/dr/common/errorcode/BizCode.java b/common/src/main/java/com/dr/common/errorcode/BizCode.java index a069491..d980693 100644 --- a/common/src/main/java/com/dr/common/errorcode/BizCode.java +++ b/common/src/main/java/com/dr/common/errorcode/BizCode.java @@ -6,7 +6,7 @@ public enum BizCode implements Code { /**************************计费模块错误码******************************/ - CHARGE_PKG_INVALID(20000, "包裹信息不存在", "请检查包裹号是否合法"), + GIT_OPERATED_FAIlED(20000, "git拉取代码失败", "请检查git参数配置"), CHARGE_PKG_SKU_INVALID(20001, "包裹商品数据不存在", "请检查包裹商品信息是否存在"), CREATE_JOB_FAIL(20002, "创建job失败", "请联系管理员"), From d807d40b9a14c8a1c0e2569f74522c750e70bd40 Mon Sep 17 00:00:00 2001 From: rayduan Date: Tue, 9 Mar 2021 10:46:45 +0800 Subject: [PATCH 19/33] =?UTF-8?q?[modify]=E4=BC=98=E5=8C=96=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .../java/com/dr/code/diff/controller/CodeDiffController.java | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 44f4558..18b3e89 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /common/common.iml /common/target/classes/com/dr/common/ /application/target/ +/common/target/classes/META-INF/ diff --git a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java index 41b2188..83294ab 100644 --- a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java +++ b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java @@ -1,7 +1,6 @@ package com.dr.code.diff.controller; import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.serializer.SerializerFeature; import com.dr.code.diff.dto.ClassInfoResult; import com.dr.code.diff.dto.DiffMethodParams; @@ -9,9 +8,7 @@ import com.dr.code.diff.vo.result.CodeDiffResultVO; import com.dr.common.response.UniqueApoResponse; import com.dr.common.utils.mapper.OrikaMapperUtils; -import com.dr.common.utils.string.BaseStringUtil; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -46,7 +43,7 @@ public UniqueApoResponse> getList( @ApiParam(required = true, name = "baseVersion", value = "git原始分支或tag") @RequestParam(value = "baseVersion") String baseVersion, @ApiParam(required = true, name = "nowVersion", value = "git现分支或tag") - @RequestParam(value = "nowVersion") String nowVersion) throws JsonProcessingException { + @RequestParam(value = "nowVersion") String nowVersion) { DiffMethodParams diffMethodParams = DiffMethodParams.builder() .gitUrl(gitUrl) .baseVersion(baseVersion) From 5f9dcf50c9fa1939fb6cbe8cf618536070337f30 Mon Sep 17 00:00:00 2001 From: rayduan Date: Tue, 9 Mar 2021 11:08:39 +0800 Subject: [PATCH 20/33] =?UTF-8?q?[modify]=E4=BF=AE=E5=A4=8D=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E8=BF=94=E5=9B=9E=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/dr/code/diff/util/MethodParserUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java index c1ac4fa..0382def 100644 --- a/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java +++ b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java @@ -9,6 +9,7 @@ import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; +import com.google.common.base.Splitter; import org.springframework.util.CollectionUtils; import java.io.FileInputStream; @@ -69,7 +70,7 @@ public void visit(MethodDeclaration n, List list) { NodeList parameters = n.getParameters(); if(!CollectionUtils.isEmpty(parameters)){ for (int i = 0; i < parameters.size(); i++) { - params.append(parameters.get(i)); + params.append(parameters.get(i).getType()); if(i != parameters.size() -1){ params.append(","); } From 084e5a8c229e749654b0e332643d0c4c836da5ba Mon Sep 17 00:00:00 2001 From: rayduan Date: Tue, 9 Mar 2021 17:10:18 +0800 Subject: [PATCH 21/33] =?UTF-8?q?[modify]=E5=8F=82=E6=95=B0=E5=88=86?= =?UTF-8?q?=E9=9A=94=E7=AC=A6=E7=94=B1=EF=BC=8C=E4=BF=AE=E6=94=B9=E4=B8=BA?= =?UTF-8?q?&?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/dr/code/diff/util/MethodParserUtils.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java index 0382def..67a69a6 100644 --- a/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java +++ b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java @@ -70,9 +70,10 @@ public void visit(MethodDeclaration n, List list) { NodeList parameters = n.getParameters(); if(!CollectionUtils.isEmpty(parameters)){ for (int i = 0; i < parameters.size(); i++) { - params.append(parameters.get(i).getType()); + String param = parameters.get(i).getType().toString(); + params.append(param.replaceAll(" ", "")); if(i != parameters.size() -1){ - params.append(","); + params.append("&"); } } } From c2a32e497baf3441aef0059f81c456076e71ac6d Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Tue, 9 Mar 2021 17:31:17 +0800 Subject: [PATCH 22/33] Update MethodParserUtils.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 参数分隔符改为& --- .../main/java/com/dr/code/diff/util/MethodParserUtils.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java index 0382def..67a69a6 100644 --- a/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java +++ b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java @@ -70,9 +70,10 @@ public void visit(MethodDeclaration n, List list) { NodeList parameters = n.getParameters(); if(!CollectionUtils.isEmpty(parameters)){ for (int i = 0; i < parameters.size(); i++) { - params.append(parameters.get(i).getType()); + String param = parameters.get(i).getType().toString(); + params.append(param.replaceAll(" ", "")); if(i != parameters.size() -1){ - params.append(","); + params.append("&"); } } } From 4455de22b073855014d0deb92f565666cb360ff3 Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Tue, 9 Mar 2021 17:31:26 +0800 Subject: [PATCH 23/33] Create MethodParserUtils.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 参数分隔符改为& From e08b5bafa25dce6a9a252cdc2715f21ebfc9521b Mon Sep 17 00:00:00 2001 From: rayduan Date: Tue, 16 Mar 2021 10:28:37 +0800 Subject: [PATCH 24/33] =?UTF-8?q?[modify]=E6=9B=B4=E6=96=B0=E6=89=93?= =?UTF-8?q?=E5=8C=85=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/pom.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/application/pom.xml b/application/pom.xml index be4faf6..0c686d7 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -101,4 +101,25 @@ + + + + + org.springframework.boot + spring-boot-maven-plugin + + + true + + + + + repackage + + + + + + + \ No newline at end of file From 5898450ab18910eccc67ab391d6ce2ca75396434 Mon Sep 17 00:00:00 2001 From: rayduan Date: Tue, 16 Mar 2021 12:38:11 +0800 Subject: [PATCH 25/33] =?UTF-8?q?[modify]linux=E8=B7=AF=E5=BE=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/dr/code/diff/config/GitConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java index 0b5e5d8..8ea0562 100644 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -278,7 +278,7 @@ public static String getLocalDir(String gitUrl, String localBaseRepoDir, String .splitToStream(gitUrl).reduce((first, second) -> second) .map(e -> Splitter.on(".").splitToStream(e).findFirst().get()).get(); localDir.append(repoName); - localDir.append("\\"); + localDir.append("/"); localDir.append(version); return localDir.toString(); From cdd6081aa8a02aa43ce6f21053f2bb73377d29ce Mon Sep 17 00:00:00 2001 From: rayduan Date: Tue, 16 Mar 2021 12:40:15 +0800 Subject: [PATCH 26/33] =?UTF-8?q?[modify]=E6=96=87=E6=A1=A3=E8=AF=B4?= =?UTF-8?q?=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + README.md | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 18b3e89..faa1f4e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ /common/target/classes/com/dr/common/ /application/target/ /common/target/classes/META-INF/ +/common/target/ diff --git a/README.md b/README.md index d4f85d2..361c8ba 100644 --- a/README.md +++ b/README.md @@ -63,3 +63,9 @@ ], "uniqueData": "[{\"classFile\":\"com/dr/code/diff/config/GitConfig\",\"methodInfos\":[{\"methodName\":\"cloneRepository\",\"parameters\":\"String gitUrl,String codePath,String commitId\"},{\"methodName\":\"diffMethods\",\"parameters\":\"DiffMethodParams diffMethodParams\"},{\"methodName\":\"getClassMethods\",\"parameters\":\"String oldClassFile,String mewClassFile,DiffEntry diffEntry\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/code/diff/controller/CodeDiffController\",\"methodInfos\":[{\"methodName\":\"getList\",\"parameters\":\"@ApiParam(required = true, name = \\\"gitUrl\\\", value = \\\"git远程仓库地址\\\") @RequestParam(value = \\\"gitUrl\\\") String gitUrl,@ApiParam(required = true, name = \\\"baseVersion\\\", value = \\\"git原始分支或tag\\\") @RequestParam(value = \\\"baseVersion\\\") String baseVersion,@ApiParam(required = true, name = \\\"nowVersion\\\", value = \\\"git现分支或tag\\\") @RequestParam(value = \\\"nowVersion\\\") String nowVersion\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/code/diff/service/impl/CodeDiffServiceImpl\",\"methodInfos\":[{\"methodName\":\"getDiffCode\",\"parameters\":\"DiffMethodParams diffMethodParams\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/common/utils/string/ScmStringUtil\",\"methodInfos\":[],\"type\":\"ADD\"}]" } + + +在linux系统部署时请注意修改代码的基础路径和日志路径,如: +```angular2html +java -jar -Dlog.path=/app/data2/devops/code-diff/logs -Dgit.local.base.dir=/app/data2/devops/code-diff/ application-1.0.0-SNAPSHOT.jar +``` From f093b10b6be142dbfefa5e582d87385dddec4473 Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Sun, 28 Mar 2021 15:41:22 +0800 Subject: [PATCH 27/33] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d4f85d2..b3b81ef 100644 --- a/README.md +++ b/README.md @@ -63,3 +63,5 @@ ], "uniqueData": "[{\"classFile\":\"com/dr/code/diff/config/GitConfig\",\"methodInfos\":[{\"methodName\":\"cloneRepository\",\"parameters\":\"String gitUrl,String codePath,String commitId\"},{\"methodName\":\"diffMethods\",\"parameters\":\"DiffMethodParams diffMethodParams\"},{\"methodName\":\"getClassMethods\",\"parameters\":\"String oldClassFile,String mewClassFile,DiffEntry diffEntry\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/code/diff/controller/CodeDiffController\",\"methodInfos\":[{\"methodName\":\"getList\",\"parameters\":\"@ApiParam(required = true, name = \\\"gitUrl\\\", value = \\\"git远程仓库地址\\\") @RequestParam(value = \\\"gitUrl\\\") String gitUrl,@ApiParam(required = true, name = \\\"baseVersion\\\", value = \\\"git原始分支或tag\\\") @RequestParam(value = \\\"baseVersion\\\") String baseVersion,@ApiParam(required = true, name = \\\"nowVersion\\\", value = \\\"git现分支或tag\\\") @RequestParam(value = \\\"nowVersion\\\") String nowVersion\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/code/diff/service/impl/CodeDiffServiceImpl\",\"methodInfos\":[{\"methodName\":\"getDiffCode\",\"parameters\":\"DiffMethodParams diffMethodParams\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/common/utils/string/ScmStringUtil\",\"methodInfos\":[],\"type\":\"ADD\"}]" } + +#近期github不稳定,请访问https://gitee.com/Dray/code-diff.git From 4c2b52dc2ba9dc51c161a2a5fa71f4b9cff1c165 Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Mon, 29 Mar 2021 16:43:57 +0800 Subject: [PATCH 28/33] Update README.md --- README.md | 324 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 275 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index c790845..15e8ca3 100644 --- a/README.md +++ b/README.md @@ -14,55 +14,281 @@ #### 2、运行项目,访问http://127.0.0.1:8085/doc.html 2.1 输入git地址,填写差异分支的旧版本,新版本,执行,就可以获取差异信息 2.2 { - "code": 10000, - "msg": "业务处理成功", - "data": [ - { - "classFile": "com/dr/code/diff/config/GitConfig", - "methodInfos": [ - { - "methodName": "cloneRepository", - "parameters": "String gitUrl,String codePath,String commitId" - }, - { - "methodName": "diffMethods", - "parameters": "DiffMethodParams diffMethodParams" - }, - { - "methodName": "getClassMethods", - "parameters": "String oldClassFile,String mewClassFile,DiffEntry diffEntry" - } - ], - "type": "MODIFY" - }, - { - "classFile": "com/dr/code/diff/controller/CodeDiffController", - "methodInfos": [ - { - "methodName": "getList", - "parameters": "@ApiParam(required = true, name = \"gitUrl\", value = \"git远程仓库地址\") @RequestParam(value = \"gitUrl\") String gitUrl,@ApiParam(required = true, name = \"baseVersion\", value = \"git原始分支或tag\") @RequestParam(value = \"baseVersion\") String baseVersion,@ApiParam(required = true, name = \"nowVersion\", value = \"git现分支或tag\") @RequestParam(value = \"nowVersion\") String nowVersion" - } - ], - "type": "MODIFY" - }, - { - "classFile": "com/dr/code/diff/service/impl/CodeDiffServiceImpl", - "methodInfos": [ - { - "methodName": "getDiffCode", - "parameters": "DiffMethodParams diffMethodParams" - } - ], - "type": "MODIFY" - }, - { - "classFile": "com/dr/common/utils/string/ScmStringUtil", - "methodInfos": [], - "type": "ADD" - } - ], - "uniqueData": "[{\"classFile\":\"com/dr/code/diff/config/GitConfig\",\"methodInfos\":[{\"methodName\":\"cloneRepository\",\"parameters\":\"String gitUrl,String codePath,String commitId\"},{\"methodName\":\"diffMethods\",\"parameters\":\"DiffMethodParams diffMethodParams\"},{\"methodName\":\"getClassMethods\",\"parameters\":\"String oldClassFile,String mewClassFile,DiffEntry diffEntry\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/code/diff/controller/CodeDiffController\",\"methodInfos\":[{\"methodName\":\"getList\",\"parameters\":\"@ApiParam(required = true, name = \\\"gitUrl\\\", value = \\\"git远程仓库地址\\\") @RequestParam(value = \\\"gitUrl\\\") String gitUrl,@ApiParam(required = true, name = \\\"baseVersion\\\", value = \\\"git原始分支或tag\\\") @RequestParam(value = \\\"baseVersion\\\") String baseVersion,@ApiParam(required = true, name = \\\"nowVersion\\\", value = \\\"git现分支或tag\\\") @RequestParam(value = \\\"nowVersion\\\") String nowVersion\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/code/diff/service/impl/CodeDiffServiceImpl\",\"methodInfos\":[{\"methodName\":\"getDiffCode\",\"parameters\":\"DiffMethodParams diffMethodParams\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/common/utils/string/ScmStringUtil\",\"methodInfos\":[],\"type\":\"ADD\"}]" - } + "code": 10000, + "msg": "业务处理成功", + "data": [ + { + "classFile": "com/dr/application/InstallCert", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/controller/Calculable", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/controller/JenkinsPluginController", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/controller/LoginController", + "methodInfos": [ + { + "methodName": "captcha", + "parameters": "HttpServletRequest&HttpServletResponse" + }, + { + "methodName": "login", + "parameters": "LoginUserParam&HttpServletRequest" + }, + { + "methodName": "testInt", + "parameters": "int&char" + }, + { + "methodName": "testInt", + "parameters": "String&int" + }, + { + "methodName": "testInt", + "parameters": "short&int" + }, + { + "methodName": "testInt", + "parameters": "int[]" + }, + { + "methodName": "testInt", + "parameters": "T[]" + }, + { + "methodName": "testInt", + "parameters": "Calculable&int&int" + }, + { + "methodName": "testInt", + "parameters": "Map&List&Set" + }, + { + "methodName": "display", + "parameters": "" + }, + { + "methodName": "a", + "parameters": "InnerClass" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/application/app/controller/RoleController", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/controller/TestController", + "methodInfos": [ + { + "methodName": "test", + "parameters": "" + }, + { + "methodName": "getPom", + "parameters": "HttpServletResponse" + }, + { + "methodName": "getDeList", + "parameters": "" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/application/app/controller/view/RoleViewController", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/param/AddRoleParam", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/vo/DependencyVO", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/vo/JenkinsPluginsVO", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/vo/RoleVO", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/config/ExceptionAdvice", + "methodInfos": [ + { + "methodName": "handleException", + "parameters": "Exception" + }, + { + "methodName": "handleMissingServletRequestParameterException", + "parameters": "MissingServletRequestParameterException" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/application/config/GitConfig", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/config/JenkinsConfig", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/ddd/StaticTest", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/ddd/Test", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/util/GitAdapter", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/common/errorcode/BizCode", + "methodInfos": [ + { + "methodName": "getCode", + "parameters": "" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/common/response/ApiResponse", + "methodInfos": [ + { + "methodName": "success", + "parameters": "" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/jenkins/JenkinsApplication", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/config/JenkinsConfigure", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/controller/JenkinsController", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/controller/TestApi", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/dto/JobAddDto", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/service/JenkinsService", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/service/impl/JenkinsServiceImpl", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/util/GenerateUniqueIdUtil", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/vo/DeviceVo", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/vo/GoodsVO", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/vo/JobAddVo", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/repository/user/dto/query/RoleQueryDto", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/repository/user/dto/result/RoleResultDto", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/user/service/impl/PermissionServiceImpl", + "methodInfos": [ + { + "methodName": "getPermissionByRoles", + "parameters": "List" + }, + { + "methodName": "buildMenuTree", + "parameters": "List" + }, + { + "methodName": "getSubMenus", + "parameters": "Long&Map>" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/user/service/impl/RoleServiceImpl", + "methodInfos": [ + { + "methodName": "getByUserId", + "parameters": "Long" + }, + { + "methodName": "getListByPage", + "parameters": "RoleQueryDto" + } + ], + "type": "MODIFY" + } + ], + "uniqueData": "[{\"classFile\":\"com/dr/application/InstallCert\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/Calculable\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/JenkinsPluginController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/LoginController\",\"methodInfos\":[{\"methodName\":\"captcha\",\"parameters\":\"HttpServletRequest&HttpServletResponse\"},{\"methodName\":\"login\",\"parameters\":\"LoginUserParam&HttpServletRequest\"},{\"methodName\":\"testInt\",\"parameters\":\"int&char\"},{\"methodName\":\"testInt\",\"parameters\":\"String&int\"},{\"methodName\":\"testInt\",\"parameters\":\"short&int\"},{\"methodName\":\"testInt\",\"parameters\":\"int[]\"},{\"methodName\":\"testInt\",\"parameters\":\"T[]\"},{\"methodName\":\"testInt\",\"parameters\":\"Calculable&int&int\"},{\"methodName\":\"testInt\",\"parameters\":\"Map&List&Set\"},{\"methodName\":\"display\",\"parameters\":\"\"},{\"methodName\":\"a\",\"parameters\":\"InnerClass\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/application/app/controller/RoleController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/TestController\",\"methodInfos\":[{\"methodName\":\"test\",\"parameters\":\"\"},{\"methodName\":\"getPom\",\"parameters\":\"HttpServletResponse\"},{\"methodName\":\"getDeList\",\"parameters\":\"\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/application/app/controller/view/RoleViewController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/param/AddRoleParam\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/vo/DependencyVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/vo/JenkinsPluginsVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/vo/RoleVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/config/ExceptionAdvice\",\"methodInfos\":[{\"methodName\":\"handleException\",\"parameters\":\"Exception\"},{\"methodName\":\"handleMissingServletRequestParameterException\",\"parameters\":\"MissingServletRequestParameterException\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/application/config/GitConfig\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/config/JenkinsConfig\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/ddd/StaticTest\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/ddd/Test\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/util/GitAdapter\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/common/errorcode/BizCode\",\"methodInfos\":[{\"methodName\":\"getCode\",\"parameters\":\"\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/common/response/ApiResponse\",\"methodInfos\":[{\"methodName\":\"success\",\"parameters\":\"\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/jenkins/JenkinsApplication\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/config/JenkinsConfigure\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/controller/JenkinsController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/controller/TestApi\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/dto/JobAddDto\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/service/JenkinsService\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/service/impl/JenkinsServiceImpl\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/util/GenerateUniqueIdUtil\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/vo/DeviceVo\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/vo/GoodsVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/vo/JobAddVo\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/repository/user/dto/query/RoleQueryDto\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/repository/user/dto/result/RoleResultDto\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/user/service/impl/PermissionServiceImpl\",\"methodInfos\":[{\"methodName\":\"getPermissionByRoles\",\"parameters\":\"List\"},{\"methodName\":\"buildMenuTree\",\"parameters\":\"List\"},{\"methodName\":\"getSubMenus\",\"parameters\":\"Long&Map>\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/user/service/impl/RoleServiceImpl\",\"methodInfos\":[{\"methodName\":\"getByUserId\",\"parameters\":\"Long\"},{\"methodName\":\"getListByPage\",\"parameters\":\"RoleQueryDto\"}],\"type\":\"MODIFY\"}]" +} 在linux系统部署时请注意修改代码的基础路径和日志路径,如: From 8b88b2f9cef1c71199cc40ce022a66ed32718b09 Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Mon, 29 Mar 2021 16:44:46 +0800 Subject: [PATCH 29/33] Update README.md --- README.md | 550 +++++++++++++++++++++++++++--------------------------- 1 file changed, 275 insertions(+), 275 deletions(-) diff --git a/README.md b/README.md index 15e8ca3..990a583 100644 --- a/README.md +++ b/README.md @@ -14,281 +14,281 @@ #### 2、运行项目,访问http://127.0.0.1:8085/doc.html 2.1 输入git地址,填写差异分支的旧版本,新版本,执行,就可以获取差异信息 2.2 { - "code": 10000, - "msg": "业务处理成功", - "data": [ - { - "classFile": "com/dr/application/InstallCert", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/app/controller/Calculable", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/app/controller/JenkinsPluginController", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/app/controller/LoginController", - "methodInfos": [ - { - "methodName": "captcha", - "parameters": "HttpServletRequest&HttpServletResponse" - }, - { - "methodName": "login", - "parameters": "LoginUserParam&HttpServletRequest" - }, - { - "methodName": "testInt", - "parameters": "int&char" - }, - { - "methodName": "testInt", - "parameters": "String&int" - }, - { - "methodName": "testInt", - "parameters": "short&int" - }, - { - "methodName": "testInt", - "parameters": "int[]" - }, - { - "methodName": "testInt", - "parameters": "T[]" - }, - { - "methodName": "testInt", - "parameters": "Calculable&int&int" - }, - { - "methodName": "testInt", - "parameters": "Map&List&Set" - }, - { - "methodName": "display", - "parameters": "" - }, - { - "methodName": "a", - "parameters": "InnerClass" - } - ], - "type": "MODIFY" - }, - { - "classFile": "com/dr/application/app/controller/RoleController", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/app/controller/TestController", - "methodInfos": [ - { - "methodName": "test", - "parameters": "" - }, - { - "methodName": "getPom", - "parameters": "HttpServletResponse" - }, - { - "methodName": "getDeList", - "parameters": "" - } - ], - "type": "MODIFY" - }, - { - "classFile": "com/dr/application/app/controller/view/RoleViewController", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/app/param/AddRoleParam", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/app/vo/DependencyVO", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/app/vo/JenkinsPluginsVO", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/app/vo/RoleVO", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/config/ExceptionAdvice", - "methodInfos": [ - { - "methodName": "handleException", - "parameters": "Exception" - }, - { - "methodName": "handleMissingServletRequestParameterException", - "parameters": "MissingServletRequestParameterException" - } - ], - "type": "MODIFY" - }, - { - "classFile": "com/dr/application/config/GitConfig", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/config/JenkinsConfig", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/ddd/StaticTest", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/ddd/Test", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/application/util/GitAdapter", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/common/errorcode/BizCode", - "methodInfos": [ - { - "methodName": "getCode", - "parameters": "" - } - ], - "type": "MODIFY" - }, - { - "classFile": "com/dr/common/response/ApiResponse", - "methodInfos": [ - { - "methodName": "success", - "parameters": "" - } - ], - "type": "MODIFY" - }, - { - "classFile": "com/dr/jenkins/JenkinsApplication", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/jenkins/config/JenkinsConfigure", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/jenkins/controller/JenkinsController", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/jenkins/controller/TestApi", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/jenkins/dto/JobAddDto", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/jenkins/service/JenkinsService", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/jenkins/service/impl/JenkinsServiceImpl", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/jenkins/util/GenerateUniqueIdUtil", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/jenkins/vo/DeviceVo", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/jenkins/vo/GoodsVO", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/jenkins/vo/JobAddVo", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/repository/user/dto/query/RoleQueryDto", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/repository/user/dto/result/RoleResultDto", - "methodInfos": null, - "type": "ADD" - }, - { - "classFile": "com/dr/user/service/impl/PermissionServiceImpl", - "methodInfos": [ - { - "methodName": "getPermissionByRoles", - "parameters": "List" - }, - { - "methodName": "buildMenuTree", - "parameters": "List" - }, - { - "methodName": "getSubMenus", - "parameters": "Long&Map>" - } - ], - "type": "MODIFY" - }, - { - "classFile": "com/dr/user/service/impl/RoleServiceImpl", - "methodInfos": [ - { - "methodName": "getByUserId", - "parameters": "Long" - }, - { - "methodName": "getListByPage", - "parameters": "RoleQueryDto" - } - ], - "type": "MODIFY" - } - ], - "uniqueData": "[{\"classFile\":\"com/dr/application/InstallCert\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/Calculable\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/JenkinsPluginController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/LoginController\",\"methodInfos\":[{\"methodName\":\"captcha\",\"parameters\":\"HttpServletRequest&HttpServletResponse\"},{\"methodName\":\"login\",\"parameters\":\"LoginUserParam&HttpServletRequest\"},{\"methodName\":\"testInt\",\"parameters\":\"int&char\"},{\"methodName\":\"testInt\",\"parameters\":\"String&int\"},{\"methodName\":\"testInt\",\"parameters\":\"short&int\"},{\"methodName\":\"testInt\",\"parameters\":\"int[]\"},{\"methodName\":\"testInt\",\"parameters\":\"T[]\"},{\"methodName\":\"testInt\",\"parameters\":\"Calculable&int&int\"},{\"methodName\":\"testInt\",\"parameters\":\"Map&List&Set\"},{\"methodName\":\"display\",\"parameters\":\"\"},{\"methodName\":\"a\",\"parameters\":\"InnerClass\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/application/app/controller/RoleController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/TestController\",\"methodInfos\":[{\"methodName\":\"test\",\"parameters\":\"\"},{\"methodName\":\"getPom\",\"parameters\":\"HttpServletResponse\"},{\"methodName\":\"getDeList\",\"parameters\":\"\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/application/app/controller/view/RoleViewController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/param/AddRoleParam\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/vo/DependencyVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/vo/JenkinsPluginsVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/vo/RoleVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/config/ExceptionAdvice\",\"methodInfos\":[{\"methodName\":\"handleException\",\"parameters\":\"Exception\"},{\"methodName\":\"handleMissingServletRequestParameterException\",\"parameters\":\"MissingServletRequestParameterException\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/application/config/GitConfig\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/config/JenkinsConfig\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/ddd/StaticTest\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/ddd/Test\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/util/GitAdapter\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/common/errorcode/BizCode\",\"methodInfos\":[{\"methodName\":\"getCode\",\"parameters\":\"\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/common/response/ApiResponse\",\"methodInfos\":[{\"methodName\":\"success\",\"parameters\":\"\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/jenkins/JenkinsApplication\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/config/JenkinsConfigure\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/controller/JenkinsController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/controller/TestApi\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/dto/JobAddDto\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/service/JenkinsService\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/service/impl/JenkinsServiceImpl\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/util/GenerateUniqueIdUtil\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/vo/DeviceVo\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/vo/GoodsVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/vo/JobAddVo\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/repository/user/dto/query/RoleQueryDto\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/repository/user/dto/result/RoleResultDto\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/user/service/impl/PermissionServiceImpl\",\"methodInfos\":[{\"methodName\":\"getPermissionByRoles\",\"parameters\":\"List\"},{\"methodName\":\"buildMenuTree\",\"parameters\":\"List\"},{\"methodName\":\"getSubMenus\",\"parameters\":\"Long&Map>\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/user/service/impl/RoleServiceImpl\",\"methodInfos\":[{\"methodName\":\"getByUserId\",\"parameters\":\"Long\"},{\"methodName\":\"getListByPage\",\"parameters\":\"RoleQueryDto\"}],\"type\":\"MODIFY\"}]" -} + "code": 10000, + "msg": "业务处理成功", + "data": [ + { + "classFile": "com/dr/application/InstallCert", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/controller/Calculable", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/controller/JenkinsPluginController", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/controller/LoginController", + "methodInfos": [ + { + "methodName": "captcha", + "parameters": "HttpServletRequest&HttpServletResponse" + }, + { + "methodName": "login", + "parameters": "LoginUserParam&HttpServletRequest" + }, + { + "methodName": "testInt", + "parameters": "int&char" + }, + { + "methodName": "testInt", + "parameters": "String&int" + }, + { + "methodName": "testInt", + "parameters": "short&int" + }, + { + "methodName": "testInt", + "parameters": "int[]" + }, + { + "methodName": "testInt", + "parameters": "T[]" + }, + { + "methodName": "testInt", + "parameters": "Calculable&int&int" + }, + { + "methodName": "testInt", + "parameters": "Map&List&Set" + }, + { + "methodName": "display", + "parameters": "" + }, + { + "methodName": "a", + "parameters": "InnerClass" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/application/app/controller/RoleController", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/controller/TestController", + "methodInfos": [ + { + "methodName": "test", + "parameters": "" + }, + { + "methodName": "getPom", + "parameters": "HttpServletResponse" + }, + { + "methodName": "getDeList", + "parameters": "" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/application/app/controller/view/RoleViewController", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/param/AddRoleParam", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/vo/DependencyVO", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/vo/JenkinsPluginsVO", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/vo/RoleVO", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/config/ExceptionAdvice", + "methodInfos": [ + { + "methodName": "handleException", + "parameters": "Exception" + }, + { + "methodName": "handleMissingServletRequestParameterException", + "parameters": "MissingServletRequestParameterException" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/application/config/GitConfig", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/config/JenkinsConfig", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/ddd/StaticTest", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/ddd/Test", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/util/GitAdapter", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/common/errorcode/BizCode", + "methodInfos": [ + { + "methodName": "getCode", + "parameters": "" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/common/response/ApiResponse", + "methodInfos": [ + { + "methodName": "success", + "parameters": "" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/jenkins/JenkinsApplication", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/config/JenkinsConfigure", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/controller/JenkinsController", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/controller/TestApi", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/dto/JobAddDto", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/service/JenkinsService", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/service/impl/JenkinsServiceImpl", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/util/GenerateUniqueIdUtil", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/vo/DeviceVo", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/vo/GoodsVO", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/vo/JobAddVo", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/repository/user/dto/query/RoleQueryDto", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/repository/user/dto/result/RoleResultDto", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/user/service/impl/PermissionServiceImpl", + "methodInfos": [ + { + "methodName": "getPermissionByRoles", + "parameters": "List" + }, + { + "methodName": "buildMenuTree", + "parameters": "List" + }, + { + "methodName": "getSubMenus", + "parameters": "Long&Map>" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/user/service/impl/RoleServiceImpl", + "methodInfos": [ + { + "methodName": "getByUserId", + "parameters": "Long" + }, + { + "methodName": "getListByPage", + "parameters": "RoleQueryDto" + } + ], + "type": "MODIFY" + } + ], + "uniqueData": "[{\"classFile\":\"com/dr/application/InstallCert\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/Calculable\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/JenkinsPluginController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/LoginController\",\"methodInfos\":[{\"methodName\":\"captcha\",\"parameters\":\"HttpServletRequest&HttpServletResponse\"},{\"methodName\":\"login\",\"parameters\":\"LoginUserParam&HttpServletRequest\"},{\"methodName\":\"testInt\",\"parameters\":\"int&char\"},{\"methodName\":\"testInt\",\"parameters\":\"String&int\"},{\"methodName\":\"testInt\",\"parameters\":\"short&int\"},{\"methodName\":\"testInt\",\"parameters\":\"int[]\"},{\"methodName\":\"testInt\",\"parameters\":\"T[]\"},{\"methodName\":\"testInt\",\"parameters\":\"Calculable&int&int\"},{\"methodName\":\"testInt\",\"parameters\":\"Map&List&Set\"},{\"methodName\":\"display\",\"parameters\":\"\"},{\"methodName\":\"a\",\"parameters\":\"InnerClass\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/application/app/controller/RoleController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/TestController\",\"methodInfos\":[{\"methodName\":\"test\",\"parameters\":\"\"},{\"methodName\":\"getPom\",\"parameters\":\"HttpServletResponse\"},{\"methodName\":\"getDeList\",\"parameters\":\"\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/application/app/controller/view/RoleViewController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/param/AddRoleParam\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/vo/DependencyVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/vo/JenkinsPluginsVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/vo/RoleVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/config/ExceptionAdvice\",\"methodInfos\":[{\"methodName\":\"handleException\",\"parameters\":\"Exception\"},{\"methodName\":\"handleMissingServletRequestParameterException\",\"parameters\":\"MissingServletRequestParameterException\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/application/config/GitConfig\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/config/JenkinsConfig\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/ddd/StaticTest\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/ddd/Test\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/util/GitAdapter\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/common/errorcode/BizCode\",\"methodInfos\":[{\"methodName\":\"getCode\",\"parameters\":\"\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/common/response/ApiResponse\",\"methodInfos\":[{\"methodName\":\"success\",\"parameters\":\"\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/jenkins/JenkinsApplication\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/config/JenkinsConfigure\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/controller/JenkinsController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/controller/TestApi\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/dto/JobAddDto\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/service/JenkinsService\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/service/impl/JenkinsServiceImpl\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/util/GenerateUniqueIdUtil\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/vo/DeviceVo\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/vo/GoodsVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/vo/JobAddVo\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/repository/user/dto/query/RoleQueryDto\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/repository/user/dto/result/RoleResultDto\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/user/service/impl/PermissionServiceImpl\",\"methodInfos\":[{\"methodName\":\"getPermissionByRoles\",\"parameters\":\"List\"},{\"methodName\":\"buildMenuTree\",\"parameters\":\"List\"},{\"methodName\":\"getSubMenus\",\"parameters\":\"Long&Map>\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/user/service/impl/RoleServiceImpl\",\"methodInfos\":[{\"methodName\":\"getByUserId\",\"parameters\":\"Long\"},{\"methodName\":\"getListByPage\",\"parameters\":\"RoleQueryDto\"}],\"type\":\"MODIFY\"}]" + } 在linux系统部署时请注意修改代码的基础路径和日志路径,如: From bae67f2f6fe0f57a11e1541972560bd802e10324 Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Mon, 5 Apr 2021 12:42:25 +0800 Subject: [PATCH 30/33] =?UTF-8?q?[modify]=E5=A2=9E=E5=8A=A0svn=E5=B7=AE?= =?UTF-8?q?=E5=BC=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dr/code/diff/config/CustomizeConfig.java | 56 ++++++ .../com/dr/code/diff/config/GitConfig.java | 4 +- .../dr/code/diff/dto/VersionControlDto.java | 44 +++++ .../com/dr/code/diff/util/GitRepoUtil.java | 168 ++++++++++++++++++ .../com/dr/code/diff/util/SvnRepoUtil.java | 49 +++++ .../diff/vercontrol/GitVersionControl.java | 68 +++++++ .../diff/vercontrol/SvnVersionControl.java | 23 +++ .../code/diff/vercontrol/VersionControl.java | 48 +++++ .../src/main/resources/application.yml | 10 +- 9 files changed, 465 insertions(+), 5 deletions(-) create mode 100644 application/src/main/java/com/dr/code/diff/config/CustomizeConfig.java create mode 100644 application/src/main/java/com/dr/code/diff/dto/VersionControlDto.java create mode 100644 application/src/main/java/com/dr/code/diff/util/GitRepoUtil.java create mode 100644 application/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java create mode 100644 application/src/main/java/com/dr/code/diff/vercontrol/GitVersionControl.java create mode 100644 application/src/main/java/com/dr/code/diff/vercontrol/SvnVersionControl.java create mode 100644 application/src/main/java/com/dr/code/diff/vercontrol/VersionControl.java diff --git a/application/src/main/java/com/dr/code/diff/config/CustomizeConfig.java b/application/src/main/java/com/dr/code/diff/config/CustomizeConfig.java new file mode 100644 index 0000000..9c9cf7c --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/config/CustomizeConfig.java @@ -0,0 +1,56 @@ +package com.dr.code.diff.config; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +/** + * @ProjectName: cmdb + * @Package: com.dr.cmdb.application.config + * @Description: 自定义参数 + * @Author: duanrui + * @CreateDate: 2021/3/18 9:49 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +@Data +@Configuration +public class CustomizeConfig { + + + /** + * git账号 + */ + @Value(value = "${git.userName}") + private String gitUserName; + /** + * git密码 + */ + @Value(value = "${git.password}") + private String gitPassWord; + + /** + * git下载代码到本地的根目录 + */ + @Value(value = "${git.local.base.dir}") + private String gitLocalBaseRepoDir; + + + /** + * git账号 + */ + @Value(value = "${svn.userName}") + private String svnUserName; + /** + * git密码 + */ + @Value(value = "${svn.password}") + private String svnPassWord; + + /** + * git下载代码到本地的根目录 + */ + @Value(value = "${svn.local.base.dir}") + private String svnLocalBaseRepoDir; +} diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java index 8ea0562..2ea7e6d 100644 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/GitConfig.java @@ -87,7 +87,7 @@ public Git cloneRepository(String gitUrl, String codePath, String commitId) { .setURI(gitUrl) .setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)) .setDirectory(new File(codePath)) - .setBranch(commitId) +// .setBranch(commitId) .call(); // 下载指定commitId/branch git.checkout().setName(commitId).call(); @@ -281,8 +281,6 @@ public static String getLocalDir(String gitUrl, String localBaseRepoDir, String localDir.append("/"); localDir.append(version); return localDir.toString(); - - } } diff --git a/application/src/main/java/com/dr/code/diff/dto/VersionControlDto.java b/application/src/main/java/com/dr/code/diff/dto/VersionControlDto.java new file mode 100644 index 0000000..b0e5095 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/dto/VersionControlDto.java @@ -0,0 +1,44 @@ +package com.dr.code.diff.dto; + +import lombok.Builder; +import lombok.Data; +import org.apache.poi.ss.formula.functions.T; + +import java.util.List; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.dto + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/4/5 10:10 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +@Data +@Builder +public class VersionControlDto { + + /** + * 远程仓库地址 + */ + private String repoUrl; + + /** + * git原始分支或tag/svn 版本 + */ + private String baseVersion; + + /** + * git现分支或tag、svn 版本 + */ + private String nowVersion; + + + private Object baseRepo; + + private Object nowRepo; + + private List diffClasses; +} diff --git a/application/src/main/java/com/dr/code/diff/util/GitRepoUtil.java b/application/src/main/java/com/dr/code/diff/util/GitRepoUtil.java new file mode 100644 index 0000000..74e8e2a --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/util/GitRepoUtil.java @@ -0,0 +1,168 @@ +package com.dr.code.diff.util; + +import com.dr.common.errorcode.BizCode; +import com.dr.common.exception.BizException; +import com.dr.common.log.LoggerUtil; +import com.dr.common.utils.file.FileUtil; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectReader; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.eclipse.jgit.treewalk.AbstractTreeIterator; +import org.eclipse.jgit.treewalk.CanonicalTreeParser; + +import java.io.File; +import java.io.IOException; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.util + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/4/5 11:16 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +@Slf4j +public class GitRepoUtil { + + + /** + * 克隆代码到本地 + * + * @param gitUrl + * @param codePath + * @param commitId + * @return + * @throws GitAPIException + * @throws IOException + */ + public static Git cloneRepository(String gitUrl, String codePath, String commitId,String gitUserName,String gitPassWord) { + Git git = null; + try { + if (!checkGitWorkSpace(gitUrl, codePath)) { + LoggerUtil.info(log, "本地代码不存在,clone", gitUrl, codePath); + git = Git.cloneRepository() + .setURI(gitUrl) + .setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)) + .setDirectory(new File(codePath)) +// .setBranch(commitId) + .call(); + // 下载指定commitId/branch + git.checkout().setName(commitId).call(); + } else { + LoggerUtil.info(log, "本地代码存在,直接使用", gitUrl, codePath); + git = Git.open(new File(codePath)); + git.getRepository().getFullBranch(); + //判断是分支还是commitId,分支做更新,commitId无法改变用原有的 + if (git.getRepository().exactRef(Constants.HEAD).isSymbolic()) { + //更新代码 + git.pull().setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)).call(); + } + } + } catch (IOException | GitAPIException e) { + e.printStackTrace(); + throw new BizException(BizCode.GIT_OPERATED_FAIlED); + } + return git; + } + + + /** + * 将代码转成树状 + * + * @param repository + * @param branchName + * @return + */ + public static AbstractTreeIterator prepareTreeParser(Repository repository, String branchName) { + try { + RevWalk walk = new RevWalk(repository); + RevTree tree; + tree = walk.parseTree(repository.resolve(branchName)); + CanonicalTreeParser TreeParser = new CanonicalTreeParser(); + try (ObjectReader reader = repository.newObjectReader()) { + TreeParser.reset(reader, tree.getId()); + } + walk.dispose(); + return TreeParser; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 取远程代码本地存储路径 + * + * @param gitUrl + * @param localBaseRepoDir + * @param version + * @return + */ + public static String getLocalDir(String gitUrl, String localBaseRepoDir, String version) { + StringBuilder localDir = new StringBuilder(localBaseRepoDir); + if (Strings.isNullOrEmpty(gitUrl)) { + return ""; + } + String repoName = Splitter.on("/") + .splitToStream(gitUrl).reduce((first, second) -> second) + .map(e -> Splitter.on(".").splitToStream(e).findFirst().get()).get(); + localDir.append(repoName); + localDir.append("/"); + localDir.append(version); + return localDir.toString(); + } + + + + /** + * 判断工作目录是否存在,本来可以每次拉去代码时删除再拉取,但是这样代码多的化IO比较大,所以就代码可以复用 + * + * @param codePath + * @return + */ + public static Boolean checkGitWorkSpace(String gitUrl, String codePath) throws IOException { + Boolean isExist = Boolean.FALSE; + File RepoGitDir = new File(codePath + "/.git"); + if (!RepoGitDir.exists()) { + return false; + } + Git git = Git.open(new File(codePath)); + if (null == git) { + return isExist; + } + Repository repository = git.getRepository(); + //解析本地代码,获取远程uri,是否是我们需要的git远程仓库 + String repoUrl = repository.getConfig().getString("remote", "origin", "url"); + if (gitUrl.equals(repoUrl)) { + isExist = Boolean.TRUE; + } else { + LoggerUtil.info(log, "本地存在其他仓的代码,先删除"); + FileUtil.removeDir(new File(codePath)); + } + return isExist; + } + + /** + * 获取class文件的地址 + * + * @param git + * @param classPackage + * @return + */ + public String getClassFile(Git git, String classPackage) { + StringBuilder builder = new StringBuilder(git.getRepository().getDirectory().getParent()); + return builder.append("/") + .append(classPackage).toString(); + } + +} diff --git a/application/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java b/application/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java new file mode 100644 index 0000000..419d5cf --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java @@ -0,0 +1,49 @@ +package com.dr.code.diff.util; + +import com.dr.common.errorcode.BizCode; +import com.dr.common.exception.BizException; +import com.dr.common.log.LoggerUtil; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.io.SVNRepository; +import org.tmatesoft.svn.core.io.SVNRepositoryFactory; +import org.tmatesoft.svn.core.wc.SVNWCUtil; + +import java.io.File; +import java.io.IOException; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.util + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/4/5 11:16 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +public class SvnRepoUtil { + + /** + * @date:2021/4/5 + * @className:SvnRepoUtil + * @author:Administrator + * @description: 获取svn代码仓 + * + */ + public static SVNRepository cloneRepository(String repoUrl, String codePath, String userName, String password) throws SVNException { + SVNWCUtil.createDefaultAuthenticationManager(new File(codePath), userName, password.toCharArray()); + SVNWCUtil.createDefaultOptions(true); + return SVNRepositoryFactory.create(SVNURL.parseURIEncoded(repoUrl)); + } + + + + +} diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/GitVersionControl.java b/application/src/main/java/com/dr/code/diff/vercontrol/GitVersionControl.java new file mode 100644 index 0000000..c2caa6c --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vercontrol/GitVersionControl.java @@ -0,0 +1,68 @@ +package com.dr.code.diff.vercontrol; + +import com.dr.code.diff.config.CustomizeConfig; +import com.dr.code.diff.dto.VersionControlDto; +import com.dr.code.diff.util.GitRepoUtil; +import com.google.common.collect.Lists; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.diff.DiffEntry; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.eclipse.jgit.treewalk.AbstractTreeIterator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.io.File; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.vercontrol + * @Description: 代码差异获取流程类定义 + * @Author: duanrui + * @CreateDate: 2021/4/5 9:56 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +@Component +public class GitVersionControl extends VersionControl { + + @Autowired + private CustomizeConfig customizeConfig; + + + @Override + public void getDiffCodeClasses() { + try { + String localBaseRepoDir = GitRepoUtil.getLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getGitLocalBaseRepoDir(), super.versionControlDto.getBaseVersion()); + String localNowRepoDir = GitRepoUtil.getLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getGitLocalBaseRepoDir(), super.versionControlDto.getNowVersion()); + //原有代码git对象 + Git baseGit = GitRepoUtil.cloneRepository(super.versionControlDto.getRepoUrl(), localBaseRepoDir, super.versionControlDto.getBaseVersion(), customizeConfig.getGitUserName(), customizeConfig.getGitPassWord()); + //现有代码git对象 + Git nowGit = GitRepoUtil.cloneRepository(super.versionControlDto.getRepoUrl(), localNowRepoDir, super.versionControlDto.getNowVersion(), customizeConfig.getGitUserName(), customizeConfig.getGitPassWord()); + AbstractTreeIterator baseTree = GitRepoUtil.prepareTreeParser(baseGit.getRepository(), super.versionControlDto.getBaseVersion()); + AbstractTreeIterator nowTree = GitRepoUtil.prepareTreeParser(nowGit.getRepository(), super.versionControlDto.getNowVersion()); + //获取两个版本之间的差异代码 + List diff = null; + diff = nowGit.diff().setOldTree(baseTree).setNewTree(nowTree).setShowNameAndStatusOnly(true).call(); + //过滤出有效的差异代码 + Collection validDiffList = diff.stream() + //只计算java文件 + .filter(e -> e.getNewPath().endsWith(".java")) + //排除测试文件 + .filter(e -> e.getNewPath().contains("src/main/java")) + //只计算新增和变更文件 + .filter(e -> DiffEntry.ChangeType.ADD.equals(e.getChangeType()) || DiffEntry.ChangeType.MODIFY.equals(e.getChangeType())) + .collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(validDiffList)) { + super.versionControlDto.setDiffClasses(Lists.newArrayList(validDiffList)); + } + } catch (GitAPIException e) { + e.printStackTrace(); + } + } +} diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/SvnVersionControl.java b/application/src/main/java/com/dr/code/diff/vercontrol/SvnVersionControl.java new file mode 100644 index 0000000..f4af7aa --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vercontrol/SvnVersionControl.java @@ -0,0 +1,23 @@ +package com.dr.code.diff.vercontrol; + +import com.dr.code.diff.dto.VersionControlDto; +import lombok.AllArgsConstructor; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.vercontrol + * @Description: 代码差异获取流程类定义 + * @Author: duanrui + * @CreateDate: 2021/4/5 9:56 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ + +public class SvnVersionControl extends VersionControl{ + + @Override + public void getDiffCodeClasses() { + + } +} diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/VersionControl.java b/application/src/main/java/com/dr/code/diff/vercontrol/VersionControl.java new file mode 100644 index 0000000..2a0e96c --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vercontrol/VersionControl.java @@ -0,0 +1,48 @@ +package com.dr.code.diff.vercontrol; + +import com.dr.code.diff.dto.VersionControlDto; +import lombok.Data; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.vercontrol + * @Description: 代码差异获取流程类定义 + * @Author: duanrui + * @CreateDate: 2021/4/5 9:56 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +@Data +public abstract class VersionControl { + + protected VersionControlDto versionControlDto; + + + public void handler(){ + getDiffCodeClasses(); + getDiffCodeMethods(); + } + + /** + * @date:2021/4/5 + * @className:VersionControl + * @author:Administrator + * @description: 获取差异类 + * + */ + public abstract void getDiffCodeClasses(); + + /** + * @date:2021/4/5 + * @className:VersionControl + * @author:Administrator + * @description: + * + */ + public void getDiffCodeMethods(){ + + } + + +} diff --git a/application/src/main/resources/application.yml b/application/src/main/resources/application.yml index 035a745..568e5ce 100644 --- a/application/src/main/resources/application.yml +++ b/application/src/main/resources/application.yml @@ -27,10 +27,16 @@ swagger: # sessionIdUrlRewritingEnabled: false git: userName: rayduan - password: FDsfret334 + password: duanrui1991 local: base: - dir: D:\git-test\ + dir: D:\git-test\git +svn: + userName: rayduan + password: duanrui1991 + local: + base: + dir: D:\git-test\svn server: port: 8085 servlet: From 1c15d4b634e2767ee97927c70d84994962dfe076 Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Mon, 5 Apr 2021 21:18:14 +0800 Subject: [PATCH 31/33] =?UTF-8?q?[modify]=E5=A2=9E=E5=8A=A0svn=E5=B7=AE?= =?UTF-8?q?=E5=BC=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/dr/code/diff/config/GitConfig.java | 287 ------------------ .../diff/controller/CodeDiffController.java | 31 +- .../com/dr/code/diff/dto/DiffEntryDto.java | 29 ++ .../dr/code/diff/dto/DiffMethodParams.java | 9 +- .../dr/code/diff/dto/VersionControlDto.java | 13 +- .../code/diff/enums/CodeManageTypeEnum.java | 54 ++++ .../dr/code/diff/service/CodeDiffService.java | 1 + .../service/impl/CodeDiffServiceImpl.java | 19 +- .../com/dr/code/diff/util/GitRepoUtil.java | 3 +- .../com/dr/code/diff/util/SvnRepoUtil.java | 50 ++- .../diff/vercontrol/SvnVersionControl.java | 23 -- .../code/diff/vercontrol/VersionControl.java | 114 ++++++- .../VersionControlHandlerFactory.java | 65 ++++ .../{ => git}/GitVersionControl.java | 26 +- .../svn/MySVNDiffStatusHandler.java | 51 ++++ .../code/diff/vercontrol/svn/MySVNEditor.java | 111 +++++++ .../vercontrol/svn/SvnVersionControl.java | 61 ++++ .../code/diff/vo/param/CodeDiffParamVO.java | 8 +- .../src/main/resources/application.yml | 8 +- .../dr/code/diff/config/GitConfigTest.java | 42 +-- .../vercontrol/SvnVersionControlTest.java | 34 +++ 21 files changed, 657 insertions(+), 382 deletions(-) delete mode 100644 application/src/main/java/com/dr/code/diff/config/GitConfig.java create mode 100644 application/src/main/java/com/dr/code/diff/dto/DiffEntryDto.java create mode 100644 application/src/main/java/com/dr/code/diff/enums/CodeManageTypeEnum.java delete mode 100644 application/src/main/java/com/dr/code/diff/vercontrol/SvnVersionControl.java create mode 100644 application/src/main/java/com/dr/code/diff/vercontrol/VersionControlHandlerFactory.java rename application/src/main/java/com/dr/code/diff/vercontrol/{ => git}/GitVersionControl.java (80%) create mode 100644 application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNDiffStatusHandler.java create mode 100644 application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNEditor.java create mode 100644 application/src/main/java/com/dr/code/diff/vercontrol/svn/SvnVersionControl.java create mode 100644 application/src/test/java/com/dr/code/diff/vercontrol/SvnVersionControlTest.java diff --git a/application/src/main/java/com/dr/code/diff/config/GitConfig.java b/application/src/main/java/com/dr/code/diff/config/GitConfig.java deleted file mode 100644 index 2ea7e6d..0000000 --- a/application/src/main/java/com/dr/code/diff/config/GitConfig.java +++ /dev/null @@ -1,287 +0,0 @@ -package com.dr.code.diff.config; - -import com.dr.code.diff.dto.ClassInfoResult; -import com.dr.code.diff.dto.DiffMethodParams; -import com.dr.code.diff.dto.MethodInfoResult; -import com.dr.code.diff.util.MethodParserUtils; -import com.dr.common.errorcode.BizCode; -import com.dr.common.exception.BizException; -import com.dr.common.log.LoggerUtil; -import com.dr.common.utils.file.FileUtil; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import lombok.extern.slf4j.Slf4j; -import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.errors.GitAPIException; -import org.eclipse.jgit.diff.DiffEntry; -import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.lib.ObjectReader; -import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.revwalk.RevTree; -import org.eclipse.jgit.revwalk.RevWalk; -import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; -import org.eclipse.jgit.treewalk.AbstractTreeIterator; -import org.eclipse.jgit.treewalk.CanonicalTreeParser; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.CollectionUtils; - -import javax.annotation.Resource; -import java.io.File; -import java.io.IOException; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; - -/** - * @author rui.duan - * @version 1.0 - * @className GitConfig - * @description git配置类 - * @date 2021/01/11 2:30 下午 - */ -@Configuration -@Slf4j -public class GitConfig { - - /** - * git账号 - */ - @Value(value = "${git.userName}") - private String gitUserName; - /** - * git密码 - */ - @Value(value = "${git.password}") - private String gitPassWord; - - /** - * git下载代码到本地的根目录 - */ - @Value(value = "${git.local.base.dir}") - private String localBaseRepoDir; - - - @Resource(name = "asyncExecutor") - private Executor executor; - - /** - * 克隆代码到本地 - * - * @param gitUrl - * @param codePath - * @param commitId - * @return - * @throws GitAPIException - * @throws IOException - */ - public Git cloneRepository(String gitUrl, String codePath, String commitId) { - Git git = null; - try { - if (!checkGitWorkSpace(gitUrl, codePath)) { - LoggerUtil.info(log, "本地代码不存在,clone", gitUrl, codePath); - git = Git.cloneRepository() - .setURI(gitUrl) - .setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)) - .setDirectory(new File(codePath)) -// .setBranch(commitId) - .call(); - // 下载指定commitId/branch - git.checkout().setName(commitId).call(); - } else { - LoggerUtil.info(log, "本地代码存在,直接使用", gitUrl, codePath); - git = Git.open(new File(codePath)); - git.getRepository().getFullBranch(); - //判断是分支还是commitId,分支做更新,commitId无法改变用原有的 - if (git.getRepository().exactRef(Constants.HEAD).isSymbolic()) { - //更新代码 - git.pull().setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)).call(); - } - } - } catch (IOException | GitAPIException e) { - e.printStackTrace(); - throw new BizException(BizCode.GIT_OPERATED_FAIlED); - } - return git; - } - - /** - * 判断工作目录是否存在,本来可以每次拉去代码时删除再拉取,但是这样代码多的化IO比较大,所以就代码可以复用 - * - * @param codePath - * @return - */ - public Boolean checkGitWorkSpace(String gitUrl, String codePath) throws IOException { - Boolean isExist = Boolean.FALSE; - File RepoGitDir = new File(codePath + "/.git"); - if (!RepoGitDir.exists()) { - return false; - } - Git git = Git.open(new File(codePath)); - if (null == git) { - return isExist; - } - Repository repository = git.getRepository(); - //解析本地代码,获取远程uri,是否是我们需要的git远程仓库 - String repoUrl = repository.getConfig().getString("remote", "origin", "url"); - if (gitUrl.equals(repoUrl)) { - isExist = Boolean.TRUE; - } else { - LoggerUtil.info(log, "本地存在其他仓的代码,先删除"); - FileUtil.removeDir(new File(codePath)); - } - return isExist; - } - - /** - * 获取差异方法 - * - * @param diffMethodParams - * @return - */ - public List diffMethods(DiffMethodParams diffMethodParams) { - try { - //原有代码git对象 - Git baseGit = cloneRepository(diffMethodParams.getGitUrl(), getLocalDir(diffMethodParams.getGitUrl(), localBaseRepoDir, diffMethodParams.getBaseVersion()), diffMethodParams.getBaseVersion()); - //现有代码git对象 - Git nowGit = cloneRepository(diffMethodParams.getGitUrl(), getLocalDir(diffMethodParams.getGitUrl(), localBaseRepoDir, diffMethodParams.getNowVersion()), diffMethodParams.getNowVersion()); - AbstractTreeIterator baseTree = prepareTreeParser(baseGit.getRepository(), diffMethodParams.getBaseVersion()); - AbstractTreeIterator nowTree = prepareTreeParser(nowGit.getRepository(), diffMethodParams.getNowVersion()); - //获取两个版本之间的差异代码 - List diff = nowGit.diff().setOldTree(baseTree).setNewTree(nowTree).setShowNameAndStatusOnly(true).call(); - //过滤出有效的差异代码 - Collection validDiffList = diff.stream() - //只计算java文件 - .filter(e -> e.getNewPath().endsWith(".java")) - //排除测试文件 - .filter(e -> e.getNewPath().contains("src/main/java")) - //只计算新增和变更文件 - .filter(e -> DiffEntry.ChangeType.ADD.equals(e.getChangeType()) || DiffEntry.ChangeType.MODIFY.equals(e.getChangeType())) - .collect(Collectors.toList()); - if (CollectionUtils.isEmpty(validDiffList)) { - return null; - } - /** - * 多线程获取旧代码和新代码的差异类及差异方法 - */ - List> priceFuture = validDiffList.stream().map(item -> getClassMethods(getClassFile(baseGit, item.getNewPath()), getClassFile(nowGit, item.getNewPath()), item)).collect(Collectors.toList()); - return priceFuture.stream().map(CompletableFuture::join).filter(Objects::nonNull).collect(Collectors.toList()); - } catch (GitAPIException e) { - e.printStackTrace(); - } - return null; - } - - /** - * 获取class文件的地址 - * - * @param git - * @param classPackage - * @return - */ - private String getClassFile(Git git, String classPackage) { - StringBuilder builder = new StringBuilder(git.getRepository().getDirectory().getParent()); - return builder.append("/") - .append(classPackage).toString(); - } - - /** - * 获取类的增量方法 - * - * @param oldClassFile 旧类的本地地址 - * @param mewClassFile 新类的本地地址 - * @param diffEntry 差异类 - * @return - */ - private CompletableFuture getClassMethods(String oldClassFile, String mewClassFile, DiffEntry diffEntry) { - //多线程获取差异方法,此处只要考虑增量代码太多的情况下,每个类都需要遍历所有方法,采用多线程方式加快速度 - return CompletableFuture.supplyAsync(() -> { - String className = diffEntry.getNewPath().split("\\.")[0].split("src/main/java/")[1]; - //新增类直接标记,不用计算方法 - if (DiffEntry.ChangeType.ADD.equals(diffEntry.getChangeType())) { - return ClassInfoResult.builder() - .classFile(className) - .type(DiffEntry.ChangeType.ADD.name()) - .build(); - } - List diffMethods; - //获取新类的所有方法 - List newMethodInfoResults = MethodParserUtils.parseMethods(mewClassFile); - //如果新类为空,没必要比较 - if (CollectionUtils.isEmpty(newMethodInfoResults)) { - return null; - } - //获取旧类的所有方法 - List oldMethodInfoResults = MethodParserUtils.parseMethods(oldClassFile); - //如果旧类为空,新类的方法所有为增量 - if (CollectionUtils.isEmpty(oldMethodInfoResults)) { - diffMethods = newMethodInfoResults; - } else { //否则,计算增量方法 - List md5s = oldMethodInfoResults.stream().map(MethodInfoResult::getMd5).collect(Collectors.toList()); - diffMethods = newMethodInfoResults.stream().filter(m -> !md5s.contains(m.getMd5())).collect(Collectors.toList()); - } - //没有增量方法,过滤掉 - if (CollectionUtils.isEmpty(diffMethods)) { - return null; - } - ClassInfoResult result = ClassInfoResult.builder() - .classFile(className) - .methodInfos(diffMethods) - .type(DiffEntry.ChangeType.MODIFY.name()) - .build(); - return result; - }, executor); - } - - - /** - * 将代码转成树状 - * - * @param repository - * @param branchName - * @return - */ - public static AbstractTreeIterator prepareTreeParser(Repository repository, String branchName) { - try { - RevWalk walk = new RevWalk(repository); - RevTree tree; - tree = walk.parseTree(repository.resolve(branchName)); - CanonicalTreeParser TreeParser = new CanonicalTreeParser(); - try (ObjectReader reader = repository.newObjectReader()) { - TreeParser.reset(reader, tree.getId()); - } - walk.dispose(); - return TreeParser; - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - /** - * 取远程代码本地存储路径 - * - * @param gitUrl - * @param localBaseRepoDir - * @param version - * @return - */ - public static String getLocalDir(String gitUrl, String localBaseRepoDir, String version) { - StringBuilder localDir = new StringBuilder(localBaseRepoDir); - if (Strings.isNullOrEmpty(gitUrl)) { - return ""; - } - String repoName = Splitter.on("/") - .splitToStream(gitUrl).reduce((first, second) -> second) - .map(e -> Splitter.on(".").splitToStream(e).findFirst().get()).get(); - localDir.append(repoName); - localDir.append("/"); - localDir.append(version); - return localDir.toString(); - } -} - - diff --git a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java index 83294ab..7f4a3bc 100644 --- a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java +++ b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.serializer.SerializerFeature; import com.dr.code.diff.dto.ClassInfoResult; import com.dr.code.diff.dto.DiffMethodParams; +import com.dr.code.diff.enums.CodeManageTypeEnum; import com.dr.code.diff.service.CodeDiffService; import com.dr.code.diff.vo.result.CodeDiffResultVO; import com.dr.common.response.UniqueApoResponse; @@ -35,9 +36,9 @@ public class CodeDiffController { @Autowired private CodeDiffService codeDiffService; - @ApiOperation("获取差异代码") - @RequestMapping(value = "/list", method = RequestMethod.GET) - public UniqueApoResponse> getList( + @ApiOperation("git获取差异代码") + @RequestMapping(value = "git/list", method = RequestMethod.GET) + public UniqueApoResponse> getGitList( @ApiParam(required = true, name = "gitUrl", value = "git远程仓库地址") @RequestParam(value = "gitUrl") String gitUrl, @ApiParam(required = true, name = "baseVersion", value = "git原始分支或tag") @@ -45,9 +46,31 @@ public UniqueApoResponse> getList( @ApiParam(required = true, name = "nowVersion", value = "git现分支或tag") @RequestParam(value = "nowVersion") String nowVersion) { DiffMethodParams diffMethodParams = DiffMethodParams.builder() - .gitUrl(gitUrl) + .repoUrl(gitUrl) .baseVersion(baseVersion) .nowVersion(nowVersion) + .codeManageTypeEnum(CodeManageTypeEnum.GIT) + .build(); + List diffCodeList = codeDiffService.getDiffCode(diffMethodParams); + List codeDiffResultVOS = OrikaMapperUtils.mapList(diffCodeList, ClassInfoResult.class, CodeDiffResultVO.class); + return new UniqueApoResponse>().success(codeDiffResultVOS, JSON.toJSONString(codeDiffResultVOS,SerializerFeature.WriteNullListAsEmpty)); + } + + + @ApiOperation("svn获取差异代码") + @RequestMapping(value = "svn/list", method = RequestMethod.GET) + public UniqueApoResponse> getSvnList( + @ApiParam(required = true, name = "svnUrl", value = "svn远程仓库地址") + @RequestParam(value = "svnUrl") String svnUrl, + @ApiParam(required = true, name = "baseVersion", value = "svn原始分支或tag") + @RequestParam(value = "baseVersion") String baseVersion, + @ApiParam(required = true, name = "nowVersion", value = "svn现分支或tag") + @RequestParam(value = "nowVersion") String nowVersion) { + DiffMethodParams diffMethodParams = DiffMethodParams.builder() + .repoUrl(svnUrl) + .baseVersion(baseVersion) + .nowVersion(nowVersion) + .codeManageTypeEnum(CodeManageTypeEnum.SVN) .build(); List diffCodeList = codeDiffService.getDiffCode(diffMethodParams); List codeDiffResultVOS = OrikaMapperUtils.mapList(diffCodeList, ClassInfoResult.class, CodeDiffResultVO.class); diff --git a/application/src/main/java/com/dr/code/diff/dto/DiffEntryDto.java b/application/src/main/java/com/dr/code/diff/dto/DiffEntryDto.java new file mode 100644 index 0000000..b111663 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/dto/DiffEntryDto.java @@ -0,0 +1,29 @@ +package com.dr.code.diff.dto; + +import lombok.Data; +import org.eclipse.jgit.diff.DiffEntry; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.dto + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/4/5 18:34 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +@Data +public class DiffEntryDto { + + + /** + * 文件包名 + */ + protected String newPath; + + /** + * 文件变更类型 + */ + private DiffEntry.ChangeType changeType; +} diff --git a/application/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java b/application/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java index 591dc3b..9efe09a 100644 --- a/application/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java +++ b/application/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java @@ -1,5 +1,6 @@ package com.dr.code.diff.dto; +import com.dr.code.diff.enums.CodeManageTypeEnum; import lombok.Builder; import lombok.Data; @@ -21,7 +22,7 @@ public class DiffMethodParams { /** * git 远程仓库地址 */ - private String gitUrl; + private String repoUrl; /** * git原始分支或tag @@ -34,4 +35,10 @@ public class DiffMethodParams { private String nowVersion; + /** + * 版本控制类型 + */ + private CodeManageTypeEnum codeManageTypeEnum; + + } diff --git a/application/src/main/java/com/dr/code/diff/dto/VersionControlDto.java b/application/src/main/java/com/dr/code/diff/dto/VersionControlDto.java index b0e5095..c3069dc 100644 --- a/application/src/main/java/com/dr/code/diff/dto/VersionControlDto.java +++ b/application/src/main/java/com/dr/code/diff/dto/VersionControlDto.java @@ -1,8 +1,9 @@ package com.dr.code.diff.dto; +import com.dr.code.diff.enums.CodeManageTypeEnum; import lombok.Builder; import lombok.Data; -import org.apache.poi.ss.formula.functions.T; +import org.eclipse.jgit.diff.DiffEntry; import java.util.List; @@ -17,7 +18,6 @@ * Copyright: Copyright (c) 2021 */ @Data -@Builder public class VersionControlDto { /** @@ -36,9 +36,12 @@ public class VersionControlDto { private String nowVersion; - private Object baseRepo; + /** + * 版本控制类型 + */ + private CodeManageTypeEnum codeManageTypeEnum; + - private Object nowRepo; - private List diffClasses; + private List diffClasses; } diff --git a/application/src/main/java/com/dr/code/diff/enums/CodeManageTypeEnum.java b/application/src/main/java/com/dr/code/diff/enums/CodeManageTypeEnum.java new file mode 100644 index 0000000..cbe1dfd --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/enums/CodeManageTypeEnum.java @@ -0,0 +1,54 @@ +package com.dr.code.diff.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author rui.duan + * @version 1.0 + * @className WarehousingReceiptStatusEnum + * @description 代码管理工具枚举 + * @date 2019-06-10 11:39 + */ +@Getter +@AllArgsConstructor +public enum CodeManageTypeEnum { + //待通知 + GIT(0,"git"), + + SVN(1,"svn"),; + + private Integer code; + private String value; + + + /** + * 根据code获取值 + * @param code + * @return + */ + public static String getValueByCode(Integer code) { + CodeManageTypeEnum[] values = CodeManageTypeEnum.values(); + for (CodeManageTypeEnum type : values) { + if (type.code.equals(code)) { + return type.value; + } + } + return null; + } + + /** + * 根据value获取code + * @param value + * @return + */ + public static Integer getCodeByValue(String value) { + CodeManageTypeEnum[] values = CodeManageTypeEnum.values(); + for (CodeManageTypeEnum type : values) { + if (type.value.equalsIgnoreCase(value)) { + return type.code; + } + } + return null; + } +} diff --git a/application/src/main/java/com/dr/code/diff/service/CodeDiffService.java b/application/src/main/java/com/dr/code/diff/service/CodeDiffService.java index 7d2a4d0..14578b4 100644 --- a/application/src/main/java/com/dr/code/diff/service/CodeDiffService.java +++ b/application/src/main/java/com/dr/code/diff/service/CodeDiffService.java @@ -26,4 +26,5 @@ public interface CodeDiffService { */ List getDiffCode(DiffMethodParams diffMethodParams); + } diff --git a/application/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java b/application/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java index a49ad11..e4e0b7d 100644 --- a/application/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java +++ b/application/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java @@ -1,9 +1,13 @@ package com.dr.code.diff.service.impl; -import com.dr.code.diff.config.GitConfig; import com.dr.code.diff.dto.ClassInfoResult; import com.dr.code.diff.dto.DiffMethodParams; +import com.dr.code.diff.dto.VersionControlDto; import com.dr.code.diff.service.CodeDiffService; +import com.dr.code.diff.vercontrol.VersionControlHandlerFactory; +import com.dr.code.diff.vercontrol.git.GitVersionControl; +import com.dr.code.diff.vercontrol.svn.SvnVersionControl; +import com.dr.common.utils.mapper.OrikaMapperUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -24,11 +28,16 @@ @Slf4j public class CodeDiffServiceImpl implements CodeDiffService { - @Autowired - private GitConfig gitConfig; - + /** + * @param diffMethodParams + * @date:2021/1/9 + * @className:CodeDiffService + * @author:Administrator + * @description: 获取差异代码 + */ @Override public List getDiffCode(DiffMethodParams diffMethodParams) { - return gitConfig.diffMethods(diffMethodParams); + VersionControlDto dto = OrikaMapperUtils.map(diffMethodParams, VersionControlDto.class); + return VersionControlHandlerFactory.processHandler(dto); } } diff --git a/application/src/main/java/com/dr/code/diff/util/GitRepoUtil.java b/application/src/main/java/com/dr/code/diff/util/GitRepoUtil.java index 74e8e2a..3a97b03 100644 --- a/application/src/main/java/com/dr/code/diff/util/GitRepoUtil.java +++ b/application/src/main/java/com/dr/code/diff/util/GitRepoUtil.java @@ -54,7 +54,7 @@ public static Git cloneRepository(String gitUrl, String codePath, String commitI .setURI(gitUrl) .setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)) .setDirectory(new File(codePath)) -// .setBranch(commitId) + .setBranch(commitId) .call(); // 下载指定commitId/branch git.checkout().setName(commitId).call(); @@ -113,6 +113,7 @@ public static String getLocalDir(String gitUrl, String localBaseRepoDir, String if (Strings.isNullOrEmpty(gitUrl)) { return ""; } + localDir.append("/"); String repoName = Splitter.on("/") .splitToStream(gitUrl).reduce((first, second) -> second) .map(e -> Splitter.on(".").splitToStream(e).findFirst().get()).get(); diff --git a/application/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java b/application/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java index 419d5cf..7fa81f6 100644 --- a/application/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java +++ b/application/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java @@ -1,5 +1,6 @@ package com.dr.code.diff.util; +import com.dr.code.diff.vercontrol.svn.MySVNEditor; import com.dr.common.errorcode.BizCode; import com.dr.common.exception.BizException; import com.dr.common.log.LoggerUtil; @@ -9,11 +10,15 @@ import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; +import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions; +import org.tmatesoft.svn.core.io.ISVNEditor; import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.io.SVNRepositoryFactory; -import org.tmatesoft.svn.core.wc.SVNWCUtil; +import org.tmatesoft.svn.core.wc.*; import java.io.File; import java.io.IOException; @@ -31,19 +36,42 @@ public class SvnRepoUtil { /** - * @date:2021/4/5 - * @className:SvnRepoUtil - * @author:Administrator - * @description: 获取svn代码仓 - * - */ - public static SVNRepository cloneRepository(String repoUrl, String codePath, String userName, String password) throws SVNException { - SVNWCUtil.createDefaultAuthenticationManager(new File(codePath), userName, password.toCharArray()); - SVNWCUtil.createDefaultOptions(true); - return SVNRepositoryFactory.create(SVNURL.parseURIEncoded(repoUrl)); + * @date:2021/4/5 + * @className:SvnRepoUtil + * @author:Administrator + * @description: 获取svn代码仓 + */ + public static void cloneRepository(String repoUrl, String codePath, String commitId, String userName, String password) { + try { + ISVNOptions options = SVNWCUtil.createDefaultOptions(true); + SVNUpdateClient updateClient = SVNClientManager.newInstance((DefaultSVNOptions) options, userName, password).getUpdateClient(); + updateClient.doCheckout(SVNURL.parseURIEncoded(repoUrl), new File(codePath), SVNRevision.create(Long.parseLong(commitId)), SVNRevision.create(Long.parseLong(commitId)), SVNDepth.INFINITY, false); + } catch (SVNException e) { + e.printStackTrace(); + } } + public static SVNDiffClient getSVNDiffClient(String userName, String password) { + ISVNOptions options = SVNWCUtil.createDefaultOptions(true); + //实例化客户端管理类 + return SVNClientManager.newInstance((DefaultSVNOptions) options, userName, password).getDiffClient(); + } + + + public static String getLocalDir(String gitUrl, String localBaseRepoDir, String version) { + StringBuilder localDir = new StringBuilder(localBaseRepoDir); + if (Strings.isNullOrEmpty(gitUrl)) { + return ""; + } + String repoName = Splitter.on("/") + .splitToStream(gitUrl).reduce((first, second) -> second).get(); + localDir.append("/"); + localDir.append(repoName); + localDir.append("/"); + localDir.append(version); + return localDir.toString(); + } } diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/SvnVersionControl.java b/application/src/main/java/com/dr/code/diff/vercontrol/SvnVersionControl.java deleted file mode 100644 index f4af7aa..0000000 --- a/application/src/main/java/com/dr/code/diff/vercontrol/SvnVersionControl.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.dr.code.diff.vercontrol; - -import com.dr.code.diff.dto.VersionControlDto; -import lombok.AllArgsConstructor; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.vercontrol - * @Description: 代码差异获取流程类定义 - * @Author: duanrui - * @CreateDate: 2021/4/5 9:56 - * @Version: 1.0 - *

    - * Copyright: Copyright (c) 2021 - */ - -public class SvnVersionControl extends VersionControl{ - - @Override - public void getDiffCodeClasses() { - - } -} diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/VersionControl.java b/application/src/main/java/com/dr/code/diff/vercontrol/VersionControl.java index 2a0e96c..b3c5f7e 100644 --- a/application/src/main/java/com/dr/code/diff/vercontrol/VersionControl.java +++ b/application/src/main/java/com/dr/code/diff/vercontrol/VersionControl.java @@ -1,7 +1,21 @@ package com.dr.code.diff.vercontrol; +import com.dr.code.diff.dto.ClassInfoResult; +import com.dr.code.diff.dto.DiffEntryDto; +import com.dr.code.diff.dto.MethodInfoResult; import com.dr.code.diff.dto.VersionControlDto; +import com.dr.code.diff.enums.CodeManageTypeEnum; +import com.dr.code.diff.util.MethodParserUtils; import lombok.Data; +import org.eclipse.jgit.diff.DiffEntry; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.stream.Collectors; /** * @ProjectName: code-diff-parent @@ -19,29 +33,109 @@ public abstract class VersionControl { protected VersionControlDto versionControlDto; - public void handler(){ + @Resource(name = "asyncExecutor") + private Executor executor; + + + /** + * 执行handler + * @return + */ + public List handler(VersionControlDto versionControlDto) { + this.versionControlDto = versionControlDto; getDiffCodeClasses(); - getDiffCodeMethods(); + return getDiffCodeMethods(); } + public abstract String getBaseDir(); + /** - * @date:2021/4/5 - * @className:VersionControl - * @author:Administrator - * @description: 获取差异类 - * - */ + * @date:2021/4/5 + * @className:VersionControl + * @author:Administrator + * @description: 获取差异类 + */ public abstract void getDiffCodeClasses(); + /** + * 获取操作类型 + */ + public abstract CodeManageTypeEnum getType(); + + /** + * @date:2021/4/5 + * @className:VersionControl + * @author:Administrator + * @description: 获取差异方法 + */ + public List getDiffCodeMethods() { + List> priceFuture = versionControlDto.getDiffClasses().stream() + .map(item -> getClassMethods(getClassFilePath(getBaseDir(), versionControlDto.getBaseVersion(), item.getNewPath()), getClassFilePath(getBaseDir(), versionControlDto.getNowVersion(), item.getNewPath()), item)) + .collect(Collectors.toList()); + return priceFuture.stream().map(CompletableFuture::join).filter(Objects::nonNull).collect(Collectors.toList()); + } + /** * @date:2021/4/5 * @className:VersionControl * @author:Administrator - * @description: + * @description: 获取类本地地址 * */ - public void getDiffCodeMethods(){ + private String getClassFilePath(String baseDir, String version, String classPath) { + StringBuilder builder = new StringBuilder(baseDir); + builder.append(version); + builder.append("/"); + builder.append(classPath); + return builder.toString(); + + } + /** + * 获取类的增量方法 + * + * @param oldClassFile 旧类的本地地址 + * @param mewClassFile 新类的本地地址 + * @param diffEntry 差异类 + * @return + */ + private CompletableFuture getClassMethods(String oldClassFile, String mewClassFile, DiffEntryDto diffEntry) { + //多线程获取差异方法,此处只要考虑增量代码太多的情况下,每个类都需要遍历所有方法,采用多线程方式加快速度 + return CompletableFuture.supplyAsync(() -> { + String className = diffEntry.getNewPath().split("\\.")[0].split("src/main/java/")[1]; + //新增类直接标记,不用计算方法 + if (DiffEntry.ChangeType.ADD.equals(diffEntry.getChangeType())) { + return ClassInfoResult.builder() + .classFile(className) + .type(DiffEntry.ChangeType.ADD.name()) + .build(); + } + List diffMethods; + //获取新类的所有方法 + List newMethodInfoResults = MethodParserUtils.parseMethods(mewClassFile); + //如果新类为空,没必要比较 + if (CollectionUtils.isEmpty(newMethodInfoResults)) { + return null; + } + //获取旧类的所有方法 + List oldMethodInfoResults = MethodParserUtils.parseMethods(oldClassFile); + //如果旧类为空,新类的方法所有为增量 + if (CollectionUtils.isEmpty(oldMethodInfoResults)) { + diffMethods = newMethodInfoResults; + } else { //否则,计算增量方法 + List md5s = oldMethodInfoResults.stream().map(MethodInfoResult::getMd5).collect(Collectors.toList()); + diffMethods = newMethodInfoResults.stream().filter(m -> !md5s.contains(m.getMd5())).collect(Collectors.toList()); + } + //没有增量方法,过滤掉 + if (CollectionUtils.isEmpty(diffMethods)) { + return null; + } + return ClassInfoResult.builder() + .classFile(className) + .methodInfos(diffMethods) + .type(DiffEntry.ChangeType.MODIFY.name()) + .build(); + }, executor); } diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/VersionControlHandlerFactory.java b/application/src/main/java/com/dr/code/diff/vercontrol/VersionControlHandlerFactory.java new file mode 100644 index 0000000..0f55264 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vercontrol/VersionControlHandlerFactory.java @@ -0,0 +1,65 @@ +package com.dr.code.diff.vercontrol; + +import com.dr.code.diff.dto.ClassInfoResult; +import com.dr.code.diff.dto.VersionControlDto; +import com.dr.code.diff.enums.CodeManageTypeEnum; +import com.google.common.collect.Lists; +import org.springframework.beans.BeansException; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.List; + +/** + * @ProjectName: cmdb + * @Package: com.dr.cmdb.application.filedcheck + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/3/30 10:10 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +@Component +public class VersionControlHandlerFactory implements CommandLineRunner, ApplicationContextAware { + private volatile ApplicationContext applicationContext; + + + private static List handlers; + + + /** + * 拼接变种责任链 + * @param args + */ + @Override + public void run(String... args) { + Collection checkHandlers = this.applicationContext.getBeansOfType(VersionControl.class).values(); + handlers = Lists.newArrayList(checkHandlers); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + /** + * 执行方法校验 + * @param versionControlDto + */ + public static List processHandler(VersionControlDto versionControlDto) { + List result = null; + for (int i = 0; i < handlers.size(); i++) { + if(versionControlDto.getCodeManageTypeEnum().equals(handlers.get(i).getType())){ + result = handlers.get(i).handler(versionControlDto); + } + } + return result; + + } + + +} diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/GitVersionControl.java b/application/src/main/java/com/dr/code/diff/vercontrol/git/GitVersionControl.java similarity index 80% rename from application/src/main/java/com/dr/code/diff/vercontrol/GitVersionControl.java rename to application/src/main/java/com/dr/code/diff/vercontrol/git/GitVersionControl.java index c2caa6c..8a7fb53 100644 --- a/application/src/main/java/com/dr/code/diff/vercontrol/GitVersionControl.java +++ b/application/src/main/java/com/dr/code/diff/vercontrol/git/GitVersionControl.java @@ -1,19 +1,19 @@ -package com.dr.code.diff.vercontrol; +package com.dr.code.diff.vercontrol.git; import com.dr.code.diff.config.CustomizeConfig; -import com.dr.code.diff.dto.VersionControlDto; +import com.dr.code.diff.dto.DiffEntryDto; +import com.dr.code.diff.enums.CodeManageTypeEnum; import com.dr.code.diff.util.GitRepoUtil; -import com.google.common.collect.Lists; +import com.dr.code.diff.vercontrol.VersionControl; +import com.dr.common.utils.mapper.OrikaMapperUtils; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.diff.DiffEntry; -import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; import org.eclipse.jgit.treewalk.AbstractTreeIterator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import java.io.File; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -35,6 +35,14 @@ public class GitVersionControl extends VersionControl { private CustomizeConfig customizeConfig; + /** + * 获取操作类型 + */ + @Override + public CodeManageTypeEnum getType() { + return CodeManageTypeEnum.GIT; + } + @Override public void getDiffCodeClasses() { try { @@ -59,10 +67,16 @@ public void getDiffCodeClasses() { .filter(e -> DiffEntry.ChangeType.ADD.equals(e.getChangeType()) || DiffEntry.ChangeType.MODIFY.equals(e.getChangeType())) .collect(Collectors.toList()); if (!CollectionUtils.isEmpty(validDiffList)) { - super.versionControlDto.setDiffClasses(Lists.newArrayList(validDiffList)); + List diffEntrys = OrikaMapperUtils.mapList(validDiffList, DiffEntry.class, DiffEntryDto.class); + super.versionControlDto.setDiffClasses(diffEntrys); } } catch (GitAPIException e) { e.printStackTrace(); } } + + @Override + public String getBaseDir() { + return GitRepoUtil.getLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getGitLocalBaseRepoDir(),""); + } } diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNDiffStatusHandler.java b/application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNDiffStatusHandler.java new file mode 100644 index 0000000..4a4e327 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNDiffStatusHandler.java @@ -0,0 +1,51 @@ +package com.dr.code.diff.vercontrol.svn; + +import com.dr.code.diff.dto.DiffEntryDto; +import org.eclipse.jgit.diff.DiffEntry; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.wc.ISVNDiffStatusHandler; +import org.tmatesoft.svn.core.wc.SVNDiffStatus; +import org.tmatesoft.svn.core.wc.SVNStatusType; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.vercontrol + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/4/5 18:06 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +public class MySVNDiffStatusHandler implements ISVNDiffStatusHandler { + + public final static List list = Collections.synchronizedList(new ArrayList());; + + + @Override + public void handleDiffStatus(SVNDiffStatus svnDiffStatus) throws SVNException { + //首先过滤java文件 + if(!svnDiffStatus.getPath().endsWith(".java")){ + return; + } + //过滤测试文件 + if(!svnDiffStatus.getPath().contains("src/main/java")){ + return; + } + DiffEntryDto entry = new DiffEntryDto(); + //只计算变更和新增文件 + if(SVNStatusType.STATUS_MODIFIED.equals(svnDiffStatus.getModificationType())){ + entry.setChangeType(DiffEntry.ChangeType.MODIFY); + }else if(SVNStatusType.STATUS_ADDED.equals(svnDiffStatus.getModificationType())){ + entry.setChangeType(DiffEntry.ChangeType.ADD); + }else{ + return; + } + entry.setNewPath(svnDiffStatus.getPath()); + list.add(entry); + } +} diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNEditor.java b/application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNEditor.java new file mode 100644 index 0000000..42678a9 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNEditor.java @@ -0,0 +1,111 @@ +package com.dr.code.diff.vercontrol.svn; + +import org.tmatesoft.svn.core.SVNCommitInfo; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNPropertyValue; +import org.tmatesoft.svn.core.io.ISVNEditor; +import org.tmatesoft.svn.core.io.diff.SVNDiffWindow; + +import java.io.OutputStream; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.vercontrol.svn + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/4/5 19:06 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +public class MySVNEditor implements ISVNEditor { + @Override + public void targetRevision(long l) throws SVNException { + + } + + @Override + public void openRoot(long l) throws SVNException { + + } + + @Override + public void deleteEntry(String s, long l) throws SVNException { + + } + + @Override + public void absentDir(String s) throws SVNException { + + } + + @Override + public void absentFile(String s) throws SVNException { + + } + + @Override + public void addDir(String s, String s1, long l) throws SVNException { + + } + + @Override + public void openDir(String s, long l) throws SVNException { + + } + + @Override + public void changeDirProperty(String s, SVNPropertyValue svnPropertyValue) throws SVNException { + + } + + @Override + public void closeDir() throws SVNException { + + } + + @Override + public void addFile(String s, String s1, long l) throws SVNException { + + } + + @Override + public void openFile(String s, long l) throws SVNException { + + } + + @Override + public void changeFileProperty(String s, String s1, SVNPropertyValue svnPropertyValue) throws SVNException { + + } + + @Override + public void closeFile(String s, String s1) throws SVNException { + + } + + @Override + public SVNCommitInfo closeEdit() throws SVNException { + return null; + } + + @Override + public void abortEdit() throws SVNException { + + } + + @Override + public void applyTextDelta(String s, String s1) throws SVNException { + + } + + @Override + public OutputStream textDeltaChunk(String s, SVNDiffWindow svnDiffWindow) throws SVNException { + return null; + } + + @Override + public void textDeltaEnd(String s) throws SVNException { + + } +} diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/svn/SvnVersionControl.java b/application/src/main/java/com/dr/code/diff/vercontrol/svn/SvnVersionControl.java new file mode 100644 index 0000000..e7f5a2b --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vercontrol/svn/SvnVersionControl.java @@ -0,0 +1,61 @@ +package com.dr.code.diff.vercontrol.svn; + +import com.dr.code.diff.config.CustomizeConfig; +import com.dr.code.diff.enums.CodeManageTypeEnum; +import com.dr.code.diff.util.SvnRepoUtil; +import com.dr.code.diff.vercontrol.VersionControl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.wc.SVNDiffClient; +import org.tmatesoft.svn.core.wc.SVNRevision; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.vercontrol + * @Description: svn差异代码获取 + * @Author: duanrui + * @CreateDate: 2021/4/5 9:56 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +@Component +public class SvnVersionControl extends VersionControl { + + @Autowired + private CustomizeConfig customizeConfig; + + + /** + * 获取操作类型 + */ + @Override + public CodeManageTypeEnum getType() { + return CodeManageTypeEnum.SVN; + } + + @Override + public void getDiffCodeClasses() { + try { + MySVNDiffStatusHandler.list.clear(); + String localBaseRepoDir = SvnRepoUtil.getLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getSvnLocalBaseRepoDir(), super.versionControlDto.getBaseVersion()); + String localNowRepoDir = SvnRepoUtil.getLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getSvnLocalBaseRepoDir(), super.versionControlDto.getNowVersion()); + SvnRepoUtil.cloneRepository(super.versionControlDto.getRepoUrl(), localBaseRepoDir, super.versionControlDto.getBaseVersion(), customizeConfig.getSvnUserName(), customizeConfig.getSvnPassWord()); + SvnRepoUtil.cloneRepository(super.versionControlDto.getRepoUrl(), localNowRepoDir, super.versionControlDto.getNowVersion(), customizeConfig.getSvnUserName(), customizeConfig.getSvnPassWord()); + SVNDiffClient svnDiffClient = SvnRepoUtil.getSVNDiffClient(customizeConfig.getSvnUserName(), customizeConfig.getSvnPassWord()); + svnDiffClient.doDiffStatus(SVNURL.parseURIEncoded(super.versionControlDto.getRepoUrl()), SVNRevision.create(Long.parseLong(super.versionControlDto.getBaseVersion())), SVNURL.parseURIEncoded(super.versionControlDto.getRepoUrl()), SVNRevision.create(Long.parseLong(super.versionControlDto.getNowVersion())), SVNDepth.INFINITY, true, new MySVNDiffStatusHandler()); + //将差异代码设置进集合 + super.versionControlDto.setDiffClasses(MySVNDiffStatusHandler.list); + } catch (SVNException e) { + e.printStackTrace(); + } + } + + @Override + public String getBaseDir() { + return SvnRepoUtil.getLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getSvnLocalBaseRepoDir(),""); + } +} diff --git a/application/src/main/java/com/dr/code/diff/vo/param/CodeDiffParamVO.java b/application/src/main/java/com/dr/code/diff/vo/param/CodeDiffParamVO.java index 8cba231..54e18cd 100644 --- a/application/src/main/java/com/dr/code/diff/vo/param/CodeDiffParamVO.java +++ b/application/src/main/java/com/dr/code/diff/vo/param/CodeDiffParamVO.java @@ -17,19 +17,19 @@ public class CodeDiffParamVO { /** * git 远程仓库地址 */ - @ApiModelProperty(name = "name", value = "git远程仓库地址", dataType = "String", example = "https://github.com/rayduan/code-diff.git") - private String gitUrl; + @ApiModelProperty(name = "name", value = "远程仓库地址", dataType = "String", example = "https://github.com/rayduan/code-diff.git") + private String repoUrl; /** * git原始分支或tag */ - @ApiModelProperty(name = "name", value = " git原始分支或tag", dataType = "String", example = "master") + @ApiModelProperty(name = "name", value = "原始分支或tag", dataType = "String", example = "master") private String baseVersion; /** * git现分支或tag */ - @ApiModelProperty(name = "name", value = " git现分支或tag", dataType = "String", example = "develop") + @ApiModelProperty(name = "name", value = "现分支或tag", dataType = "String", example = "develop") private String nowVersion; diff --git a/application/src/main/resources/application.yml b/application/src/main/resources/application.yml index 568e5ce..5c43037 100644 --- a/application/src/main/resources/application.yml +++ b/application/src/main/resources/application.yml @@ -30,13 +30,13 @@ git: password: duanrui1991 local: base: - dir: D:\git-test\git + dir: D:\git-test svn: - userName: rayduan - password: duanrui1991 + userName: admin + password: 123456 local: base: - dir: D:\git-test\svn + dir: D:\svn-test server: port: 8085 servlet: diff --git a/application/src/test/java/com/dr/code/diff/config/GitConfigTest.java b/application/src/test/java/com/dr/code/diff/config/GitConfigTest.java index 56eeeb1..a9d8f1b 100644 --- a/application/src/test/java/com/dr/code/diff/config/GitConfigTest.java +++ b/application/src/test/java/com/dr/code/diff/config/GitConfigTest.java @@ -17,28 +17,28 @@ */ class GitConfigTest extends CodeDiffApplicationTest { - @Autowired - private GitConfig gitConfig; +// @Autowired +// private GitConfig gitConfig; - @Test - void cloneRepository() { - String localRepo = "D:\\git-test\\base-service"; - String gitUrl = "http://192.168.75.128/rayduan/base-service.git"; - gitConfig.cloneRepository(gitUrl, localRepo, "2ea401406d775005245faa0a57d6e08db348433f"); - } - - @Test - void diffMethods() { +// @Test +// void cloneRepository() { +// String localRepo = "D:\\git-test\\base-service"; +// String gitUrl = "http://192.168.75.128/rayduan/base-service.git"; +// gitConfig.cloneRepository(gitUrl, localRepo, "2ea401406d775005245faa0a57d6e08db348433f"); +// } +// +// @Test +// void diffMethods() { +//// DiffMethodParams diff = DiffMethodParams.builder() +//// .baseVersion("dac68b2f3976509b4204a66df8f5e71dffe023b7") +//// .nowVersion("74c026849763f1f9f0dfc967949d0b581959c2ea") +//// .gitUrl("https://github.com/rayduan/devops-data.git") +//// .build(); // DiffMethodParams diff = DiffMethodParams.builder() -// .baseVersion("dac68b2f3976509b4204a66df8f5e71dffe023b7") -// .nowVersion("74c026849763f1f9f0dfc967949d0b581959c2ea") -// .gitUrl("https://github.com/rayduan/devops-data.git") +// .baseVersion("db84201eea9be107073fa07c24e30262ac91d384") +// .nowVersion("dca3a374ba9100c64b970081fad5db7335e99ff6") +// .gitUrl("https://github.com/rayduan/base-service.git") // .build(); - DiffMethodParams diff = DiffMethodParams.builder() - .baseVersion("db84201eea9be107073fa07c24e30262ac91d384") - .nowVersion("dca3a374ba9100c64b970081fad5db7335e99ff6") - .gitUrl("https://github.com/rayduan/base-service.git") - .build(); - gitConfig.diffMethods(diff); - } +// gitConfig.diffMethods(diff); +// } } \ No newline at end of file diff --git a/application/src/test/java/com/dr/code/diff/vercontrol/SvnVersionControlTest.java b/application/src/test/java/com/dr/code/diff/vercontrol/SvnVersionControlTest.java new file mode 100644 index 0000000..fac10b2 --- /dev/null +++ b/application/src/test/java/com/dr/code/diff/vercontrol/SvnVersionControlTest.java @@ -0,0 +1,34 @@ +package com.dr.code.diff.vercontrol; + +import com.dr.code.diff.CodeDiffApplicationTest; +import com.dr.code.diff.dto.VersionControlDto; +import com.dr.code.diff.vercontrol.svn.SvnVersionControl; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.vercontrol + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/4/5 14:03 + * @Version: 1.0 + *

    + * Copyright: Copyright (c) 2021 + */ +class SvnVersionControlTest extends CodeDiffApplicationTest { + + @Autowired + private SvnVersionControl svnVersionControl; + + @Test + void getDiffCodeClasses() { +// VersionControlDto build = VersionControlDto.builder() +// .repoUrl("svn://192.168.75.130/svn/code/code-diif") +// .baseVersion("3") +// .nowVersion("5") +// .build(); +// svnVersionControl.setVersionControlDto(build); +// svnVersionControl.getDiffCodeClasses(); + } +} \ No newline at end of file From 6ea90b091940cc5d2b1240dbd4a7f12fa1581da6 Mon Sep 17 00:00:00 2001 From: rayduan <719328408@qq.com> Date: Mon, 5 Apr 2021 21:26:50 +0800 Subject: [PATCH 32/33] [modify] --- application/src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/resources/application.yml b/application/src/main/resources/application.yml index 5c43037..bf70065 100644 --- a/application/src/main/resources/application.yml +++ b/application/src/main/resources/application.yml @@ -27,7 +27,7 @@ swagger: # sessionIdUrlRewritingEnabled: false git: userName: rayduan - password: duanrui1991 + password: 123456 local: base: dir: D:\git-test From 38aa34bef076213d5bc802e0517be68b507789f1 Mon Sep 17 00:00:00 2001 From: rayduan Date: Tue, 6 Apr 2021 15:04:12 +0800 Subject: [PATCH 33/33] =?UTF-8?q?[modify]=E5=A2=9E=E5=8A=A0=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/dr/code/diff/controller/CodeDiffController.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java index 7f4a3bc..799c74f 100644 --- a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java +++ b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java @@ -60,11 +60,11 @@ public UniqueApoResponse> getGitList( @ApiOperation("svn获取差异代码") @RequestMapping(value = "svn/list", method = RequestMethod.GET) public UniqueApoResponse> getSvnList( - @ApiParam(required = true, name = "svnUrl", value = "svn远程仓库地址") + @ApiParam(required = true, name = "svnUrl", value = "svn远程仓库地址,如svn:192.168.0.1:3690/svn") @RequestParam(value = "svnUrl") String svnUrl, - @ApiParam(required = true, name = "baseVersion", value = "svn原始分支或tag") + @ApiParam(required = true, name = "baseVersion", value = "svn原始分支,如:1") @RequestParam(value = "baseVersion") String baseVersion, - @ApiParam(required = true, name = "nowVersion", value = "svn现分支或tag") + @ApiParam(required = true, name = "nowVersion", value = "svn现分支,如:2") @RequestParam(value = "nowVersion") String nowVersion) { DiffMethodParams diffMethodParams = DiffMethodParams.builder() .repoUrl(svnUrl)