项目结构变更
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
package com.codechecker.model;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 索引中的 HTTP/Feign 接口:方法、URI、入参/返回类型简单名。
|
||||
*/
|
||||
public class ApiEndpoint {
|
||||
private final String httpMethod;
|
||||
private final String uri;
|
||||
private final String sourceFile;
|
||||
private final Set<String> paramTypes;
|
||||
private final Set<String> returnTypes;
|
||||
|
||||
public ApiEndpoint(String httpMethod, String uri, String sourceFile,
|
||||
Set<String> paramTypes, Set<String> returnTypes) {
|
||||
this.httpMethod = httpMethod;
|
||||
this.uri = uri;
|
||||
this.sourceFile = sourceFile;
|
||||
this.paramTypes = paramTypes == null ? Set.of() : new LinkedHashSet<>(paramTypes);
|
||||
this.returnTypes = returnTypes == null ? Set.of() : new LinkedHashSet<>(returnTypes);
|
||||
}
|
||||
|
||||
public String getHttpMethod() {
|
||||
return httpMethod;
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
/** 定义该接口的 Java 源文件相对路径 */
|
||||
public String getSourceFile() {
|
||||
return sourceFile;
|
||||
}
|
||||
|
||||
/** 入参涉及的类型简单名集合 */
|
||||
public Set<String> getParamTypes() {
|
||||
return paramTypes;
|
||||
}
|
||||
|
||||
/** 返回值涉及的类型简单名集合(已剥离泛型包装) */
|
||||
public Set<String> getReturnTypes() {
|
||||
return returnTypes;
|
||||
}
|
||||
|
||||
/** 去重用键:METHOD + URI */
|
||||
public String endpointKey() {
|
||||
return httpMethod + " " + uri;
|
||||
}
|
||||
|
||||
/** 通知展示行:GET /api/foo */
|
||||
public String displayLine() {
|
||||
return httpMethod + " " + uri;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.codechecker.model;
|
||||
|
||||
/**
|
||||
* Git 扫描得到的单个 Java 模型类变更记录。
|
||||
*/
|
||||
public class ChangedClassFile {
|
||||
/** Git diff 状态:修改 / 删除 / 重命名 */
|
||||
public enum ChangeStatus {
|
||||
MODIFIED, DELETED, RENAMED
|
||||
}
|
||||
|
||||
private final String relativePath;
|
||||
private final String oldRelativePath;
|
||||
private final ChangeStatus status;
|
||||
private final String className;
|
||||
private final String oldClassName;
|
||||
private final ClassType classType;
|
||||
|
||||
/** 修改或删除(无路径变化) */
|
||||
public ChangedClassFile(String relativePath, ChangeStatus status, String className, ClassType classType) {
|
||||
this(relativePath, null, status, className, null, classType);
|
||||
}
|
||||
|
||||
/** 重命名或同路径类名变更 */
|
||||
public ChangedClassFile(String relativePath, String oldRelativePath, ChangeStatus status,
|
||||
String className, String oldClassName, ClassType classType) {
|
||||
this.relativePath = relativePath;
|
||||
this.oldRelativePath = oldRelativePath;
|
||||
this.status = status;
|
||||
this.className = className;
|
||||
this.oldClassName = oldClassName;
|
||||
this.classType = classType;
|
||||
}
|
||||
|
||||
/** 新提交中的相对路径 */
|
||||
public String getRelativePath() {
|
||||
return relativePath;
|
||||
}
|
||||
|
||||
/** 旧提交中的相对路径,未变路径则为 null */
|
||||
public String getOldRelativePath() {
|
||||
return oldRelativePath;
|
||||
}
|
||||
|
||||
/** 读取旧版本源码时使用的路径 */
|
||||
public String pathForOldCommit() {
|
||||
return oldRelativePath != null ? oldRelativePath : relativePath;
|
||||
}
|
||||
|
||||
public ChangeStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/** 当前简单类名 */
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
/** 重命名前简单类名 */
|
||||
public String getOldClassName() {
|
||||
return oldClassName;
|
||||
}
|
||||
|
||||
public ClassType getClassType() {
|
||||
return classType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.codechecker.model;
|
||||
|
||||
/**
|
||||
* 单次类变更的类型,决定通知内容与影响分析策略。
|
||||
*/
|
||||
public enum ClassChangeKind {
|
||||
/** 文件已删除 */
|
||||
DELETED,
|
||||
/** 仅字段变更 */
|
||||
FIELDS_ONLY,
|
||||
/** 仅类名变更,字段不变 */
|
||||
RENAME_ONLY,
|
||||
/** 类名与字段同时变更 */
|
||||
RENAME_AND_FIELDS
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.codechecker.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 单次类变更的完整报告:变更类型、字段 diff、接口/转换影响,供通知渲染。
|
||||
*/
|
||||
public class ClassChangeReport {
|
||||
private final String className;
|
||||
private final String oldClassName;
|
||||
private final ClassType classType;
|
||||
private final ClassChangeKind changeKind;
|
||||
private final String sourceFile;
|
||||
private final String classDescription;
|
||||
private final List<FieldChange> fieldChanges = new ArrayList<>();
|
||||
private final List<ApiEndpoint> inputImpactEndpoints = new ArrayList<>();
|
||||
private final List<String> conversionEntities = new ArrayList<>();
|
||||
private final List<ApiEndpoint> frontendImpactEndpoints = new ArrayList<>();
|
||||
private final boolean conversionCheckEnabled;
|
||||
|
||||
public ClassChangeReport(String className, String oldClassName, ClassType classType,
|
||||
ClassChangeKind changeKind, String sourceFile,
|
||||
boolean conversionCheckEnabled, String classDescription) {
|
||||
this.className = className;
|
||||
this.oldClassName = oldClassName;
|
||||
this.classType = classType;
|
||||
this.changeKind = changeKind;
|
||||
this.sourceFile = sourceFile;
|
||||
this.conversionCheckEnabled = conversionCheckEnabled;
|
||||
this.classDescription = classDescription == null ? "" : classDescription.trim();
|
||||
}
|
||||
|
||||
/** 当前(新)简单类名 */
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
/** 重命名前的简单类名,未重命名则为 null */
|
||||
public String getOldClassName() {
|
||||
return oldClassName;
|
||||
}
|
||||
|
||||
/** 是否发生类名变更 */
|
||||
public boolean isRenamed() {
|
||||
return oldClassName != null && !oldClassName.equals(className);
|
||||
}
|
||||
|
||||
/** 是否仅类名变更、字段无变化 */
|
||||
public boolean isRenameOnly() {
|
||||
return changeKind == ClassChangeKind.RENAME_ONLY;
|
||||
}
|
||||
|
||||
public ClassType getClassType() {
|
||||
return classType;
|
||||
}
|
||||
|
||||
public ClassChangeKind getChangeKind() {
|
||||
return changeKind;
|
||||
}
|
||||
|
||||
/** Git 相对路径,通知「文件路径」展示用 */
|
||||
public String getSourceFile() {
|
||||
return sourceFile;
|
||||
}
|
||||
|
||||
/** 类级中文说明(@Schema / 类 Javadoc),无则空串 */
|
||||
public String getClassDescription() {
|
||||
return classDescription;
|
||||
}
|
||||
|
||||
/** 是否整文件删除 */
|
||||
public boolean isDeleted() {
|
||||
return changeKind == ClassChangeKind.DELETED;
|
||||
}
|
||||
|
||||
public List<FieldChange> getFieldChanges() {
|
||||
return fieldChanges;
|
||||
}
|
||||
|
||||
/** 入参引用该类的接口(request 影响) */
|
||||
public List<ApiEndpoint> getInputImpactEndpoints() {
|
||||
return inputImpactEndpoints;
|
||||
}
|
||||
|
||||
/** Dto→Entity 转换目标类名列表 */
|
||||
public List<String> getConversionEntities() {
|
||||
return conversionEntities;
|
||||
}
|
||||
|
||||
/** 返回值引用该类的接口(response 影响) */
|
||||
public List<ApiEndpoint> getFrontendImpactEndpoints() {
|
||||
return frontendImpactEndpoints;
|
||||
}
|
||||
|
||||
/** 是否启用类转换检测 */
|
||||
public boolean isConversionCheckEnabled() {
|
||||
return conversionCheckEnabled;
|
||||
}
|
||||
|
||||
/** 追加一条字段变更 */
|
||||
public void addFieldChange(FieldChange change) {
|
||||
fieldChanges.add(change);
|
||||
}
|
||||
|
||||
/** 追加 request 影响接口(按 endpointKey 去重) */
|
||||
public void addInputImpact(ApiEndpoint endpoint) {
|
||||
if (inputImpactEndpoints.stream().noneMatch(e -> e.endpointKey().equals(endpoint.endpointKey()))) {
|
||||
inputImpactEndpoints.add(endpoint);
|
||||
}
|
||||
}
|
||||
|
||||
/** 追加关联 Entity 类名(去重) */
|
||||
public void addConversionEntity(String entityName) {
|
||||
if (!conversionEntities.contains(entityName)) {
|
||||
conversionEntities.add(entityName);
|
||||
}
|
||||
}
|
||||
|
||||
/** 追加 response 影响接口(按 endpointKey 去重) */
|
||||
public void addFrontendImpact(ApiEndpoint endpoint) {
|
||||
if (frontendImpactEndpoints.stream().noneMatch(e -> e.endpointKey().equals(endpoint.endpointKey()))) {
|
||||
frontendImpactEndpoints.add(endpoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.codechecker.model;
|
||||
|
||||
/**
|
||||
* 目标模型类后缀类型,决定通知模版中展示哪些影响段落。
|
||||
*/
|
||||
public enum ClassType {
|
||||
DTO("Dto"),
|
||||
VO("Vo"),
|
||||
ENTITY("Entity"),
|
||||
MODEL("Model");
|
||||
|
||||
private final String label;
|
||||
|
||||
ClassType(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
/** 通知中展示的类型标签 */
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/** 根据简单类名后缀识别类型,不匹配则 null */
|
||||
public static ClassType fromClassName(String className) {
|
||||
if (className.endsWith("Dto")) {
|
||||
return DTO;
|
||||
}
|
||||
if (className.endsWith("VO")) {
|
||||
return VO;
|
||||
}
|
||||
if (className.endsWith("Vo")) {
|
||||
return VO;
|
||||
}
|
||||
if (className.endsWith("Entity")) {
|
||||
return ENTITY;
|
||||
}
|
||||
if (className.endsWith("Model")) {
|
||||
return MODEL;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 判断类名是否属于当前类型 */
|
||||
public boolean isTargetSuffix(String className) {
|
||||
return fromClassName(className) == this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.codechecker.model;
|
||||
|
||||
/**
|
||||
* 字段级 diff 结果,用于通知中的 [新增]/[删除]/[修改]/[重命名] 行。
|
||||
*/
|
||||
public class FieldChange {
|
||||
/** 字段变更种类 */
|
||||
public enum ChangeKind {
|
||||
ADDED, REMOVED, MODIFIED, RENAMED
|
||||
}
|
||||
|
||||
private final ChangeKind kind;
|
||||
private final String fieldName;
|
||||
private final String oldFieldName;
|
||||
private final String description;
|
||||
private final String oldType;
|
||||
private final String newType;
|
||||
private final String oldDescription;
|
||||
private final String detail;
|
||||
|
||||
private FieldChange(ChangeKind kind, String fieldName, String oldFieldName, String description,
|
||||
String oldType, String newType, String oldDescription, String detail) {
|
||||
this.kind = kind;
|
||||
this.fieldName = fieldName;
|
||||
this.oldFieldName = oldFieldName;
|
||||
this.description = description;
|
||||
this.oldType = oldType;
|
||||
this.newType = newType;
|
||||
this.oldDescription = oldDescription;
|
||||
this.detail = detail;
|
||||
}
|
||||
|
||||
/** 构造新增字段变更 */
|
||||
public static FieldChange added(FieldInfo field) {
|
||||
return new FieldChange(ChangeKind.ADDED, field.getName(), null, field.getDescription(),
|
||||
null, field.getType(), null, null);
|
||||
}
|
||||
|
||||
/** 构造删除字段变更 */
|
||||
public static FieldChange removed(FieldInfo field) {
|
||||
return new FieldChange(ChangeKind.REMOVED, field.getName(), null, field.getDescription(),
|
||||
field.getType(), null, field.getDescription(), null);
|
||||
}
|
||||
|
||||
/** 构造修改字段变更,detail 通常为类型变化描述 */
|
||||
public static FieldChange modified(FieldInfo oldField, FieldInfo newField, String detail) {
|
||||
return new FieldChange(ChangeKind.MODIFIED, newField.getName(), null, newField.getDescription(),
|
||||
oldField.getType(), newField.getType(), oldField.getDescription(), detail);
|
||||
}
|
||||
|
||||
/** 构造字段重命名;类型变化时 detail 为 oldType → newType */
|
||||
public static FieldChange renamed(FieldInfo oldField, FieldInfo newField) {
|
||||
String typeDetail = oldField.getType().equals(newField.getType())
|
||||
? null
|
||||
: oldField.getType() + " → " + newField.getType();
|
||||
return new FieldChange(ChangeKind.RENAMED, newField.getName(), oldField.getName(),
|
||||
newField.getDescription(), oldField.getType(), newField.getType(),
|
||||
oldField.getDescription(), typeDetail);
|
||||
}
|
||||
|
||||
public ChangeKind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
/** 重命名前的字段名,仅 RENAMED 时有值 */
|
||||
public String getOldFieldName() {
|
||||
return oldFieldName;
|
||||
}
|
||||
|
||||
/** 变更后的字段说明(通知「说明」段) */
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getOldType() {
|
||||
return oldType;
|
||||
}
|
||||
|
||||
public String getNewType() {
|
||||
return newType;
|
||||
}
|
||||
|
||||
public String getOldDescription() {
|
||||
return oldDescription;
|
||||
}
|
||||
|
||||
/** 结构性变更详情,重命名时为类型变化描述 */
|
||||
public String getDetail() {
|
||||
return detail;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.codechecker.model;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 解析后的单个字段:名称、类型、业务说明(Schema/注释)。
|
||||
*/
|
||||
public class FieldInfo {
|
||||
private final String name;
|
||||
private final String type;
|
||||
private final String description;
|
||||
|
||||
public FieldInfo(String name, String type, String description) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.description = description == null ? "" : description;
|
||||
}
|
||||
|
||||
/** 字段名 */
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** 字段类型(简单名) */
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/** 字段说明文案 */
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof FieldInfo)) {
|
||||
return false;
|
||||
}
|
||||
FieldInfo other = (FieldInfo) o;
|
||||
return Objects.equals(name, other.name)
|
||||
&& Objects.equals(type, other.type)
|
||||
&& Objects.equals(description, other.description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, type, description);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user