fix #39, fix gitee #I1IQKY

This commit is contained in:
oppofind 2020-07-03 01:43:35 +08:00
parent 7323c5e355
commit bba93b5060
7 changed files with 181 additions and 30 deletions

View File

@ -5,6 +5,8 @@
- 更新内容: - 更新内容:
1. 修改git #38 1. 修改git #38
2. 修改gitee #I1LBKO 2. 修改gitee #I1LBKO
3. 修改fix #39多泛型解析顺序问题
4. 优化支持gitee #I1IQKY常量解析需求
#### 版本号1.8.8 #### 版本号1.8.8
- 更新日期: 2020-06-21 - 更新日期: 2020-06-21
- 更新内容: - 更新内容:

View File

@ -48,7 +48,9 @@ public class ProjectDocConfigBuilder {
private Map<String, CustomRespField> customRespFieldMap = new ConcurrentHashMap<>(); private Map<String, CustomRespField> customRespFieldMap = new ConcurrentHashMap<>();
private Map<String,String> replaceClassMap = new ConcurrentHashMap<>(); private Map<String, String> replaceClassMap = new ConcurrentHashMap<>();
private Map<String, String> constantsMap = new ConcurrentHashMap<>();
private String serverUrl; private String serverUrl;
@ -75,6 +77,22 @@ public class ProjectDocConfigBuilder {
this.initClassFilesMap(); this.initClassFilesMap();
this.initCustomResponseFieldsMap(apiConfig); this.initCustomResponseFieldsMap(apiConfig);
this.initReplaceClassMap(apiConfig); this.initReplaceClassMap(apiConfig);
this.initConstants(apiConfig);
}
public JavaClass getClassByName(String simpleName) {
JavaClass cls = javaProjectBuilder.getClassByName(simpleName);
List<DocJavaField> fieldList = JavaClassUtil.getFields(cls, 0, new HashSet<>());
// handle inner class
if (Objects.isNull(cls.getFields()) || fieldList.isEmpty()) {
cls = classFilesMap.get(simpleName);
} else {
List<JavaClass> classList = cls.getNestedClasses();
for (JavaClass javaClass : classList) {
classFilesMap.put(javaClass.getFullyQualifiedName(), javaClass);
}
}
return cls;
} }
private void loadJavaSource(List<SourceCodePath> paths, JavaProjectBuilder builder) { private void loadJavaSource(List<SourceCodePath> paths, JavaProjectBuilder builder) {
@ -109,28 +127,35 @@ public class ProjectDocConfigBuilder {
} }
} }
private void initReplaceClassMap(ApiConfig config){ private void initReplaceClassMap(ApiConfig config) {
if (CollectionUtil.isNotEmpty(config.getApiObjectReplacements())) { if (CollectionUtil.isNotEmpty(config.getApiObjectReplacements())) {
for (ApiObjectReplacement replace : config.getApiObjectReplacements()) { for (ApiObjectReplacement replace : config.getApiObjectReplacements()) {
replaceClassMap.put(replace.getClassName(),replace.getReplacementClassName()); replaceClassMap.put(replace.getClassName(), replace.getReplacementClassName());
} }
} }
} }
private void initConstants(ApiConfig config) {
public JavaClass getClassByName(String simpleName) { List<ApiConstant> apiConstants;
JavaClass cls = javaProjectBuilder.getClassByName(simpleName); if (CollectionUtil.isEmpty(config.getApiConstants())) {
List<DocJavaField> fieldList = JavaClassUtil.getFields(cls, 0,new HashSet<>()); apiConstants = new ArrayList<>();
// handle inner class
if (Objects.isNull(cls.getFields()) || fieldList.isEmpty()) {
cls = classFilesMap.get(simpleName);
} else { } else {
List<JavaClass> classList = cls.getNestedClasses(); apiConstants = config.getApiConstants();
for (JavaClass javaClass : classList) { }
classFilesMap.put(javaClass.getFullyQualifiedName(), javaClass); try {
} for (ApiConstant apiConstant : apiConstants) {
Class<?> clzz = apiConstant.getConstantsClass();
if (Objects.isNull(clzz)) {
if (StringUtil.isEmpty(apiConstant.getConstantsClassName())) {
throw new RuntimeException("Enum class name can't be null.");
}
clzz = Class.forName(apiConstant.getConstantsClassName());
}
constantsMap.putAll(JavaClassUtil.getFinalFieldValue(clzz));
}
} catch (ClassNotFoundException | IllegalAccessException e) {
e.printStackTrace();
} }
return cls;
} }
@ -159,4 +184,8 @@ public class ProjectDocConfigBuilder {
public Map<String, String> getReplaceClassMap() { public Map<String, String> getReplaceClassMap() {
return replaceClassMap; return replaceClassMap;
} }
public Map<String, String> getConstantsMap() {
return constantsMap;
}
} }

View File

@ -27,7 +27,6 @@ import com.power.common.util.UrlUtil;
import com.power.doc.constants.DocGlobalConstants; import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.constants.Methods; import com.power.doc.constants.Methods;
import com.power.doc.constants.SpringMvcAnnotations; import com.power.doc.constants.SpringMvcAnnotations;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.request.RequestMapping; import com.power.doc.model.request.RequestMapping;
import com.power.doc.utils.DocUrlUtil; import com.power.doc.utils.DocUrlUtil;
import com.power.doc.utils.DocUtil; import com.power.doc.utils.DocUtil;
@ -36,6 +35,7 @@ import com.thoughtworks.qdox.model.JavaMethod;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
import static com.power.doc.constants.DocTags.IGNORE; import static com.power.doc.constants.DocTags.IGNORE;
@ -52,7 +52,7 @@ public class SpringMVCRequestMappingHandler {
* @param method JavaMethod * @param method JavaMethod
* @return RequestMapping * @return RequestMapping
*/ */
public RequestMapping handle(String serverUrl, String controllerBaseUrl, JavaMethod method) { public RequestMapping handle(String serverUrl, String controllerBaseUrl, JavaMethod method, Map<String, String> constantsMap) {
List<JavaAnnotation> annotations = method.getAnnotations(); List<JavaAnnotation> annotations = method.getAnnotations();
String url; String url;
String methodType = null; String methodType = null;
@ -87,15 +87,12 @@ public class SpringMVCRequestMappingHandler {
} else if (SpringMvcAnnotations.PUT_MAPPING.equals(annotationName) || DocGlobalConstants.PUT_MAPPING_FULLY.equals(annotationName)) { } else if (SpringMvcAnnotations.PUT_MAPPING.equals(annotationName) || DocGlobalConstants.PUT_MAPPING_FULLY.equals(annotationName)) {
shortUrl = DocUtil.handleMappingValue(annotation); shortUrl = DocUtil.handleMappingValue(annotation);
methodType = Methods.PUT.getValue(); methodType = Methods.PUT.getValue();
} else if (SpringMvcAnnotations.PATCH_MAPPING.equals(annotationName) || DocGlobalConstants.PATCH_MAPPING_FULLY.equals(annotationName)) { } else if (SpringMvcAnnotations.PATCH_MAPPING.equals(annotationName) || DocGlobalConstants.PATCH_MAPPING_FULLY.equals(annotationName)) {
shortUrl = DocUtil.handleMappingValue(annotation); shortUrl = DocUtil.handleMappingValue(annotation);
methodType = Methods.PATCH.getValue(); methodType = Methods.PATCH.getValue();
} else if (SpringMvcAnnotations.DELETE_MAPPING.equals(annotationName) || DocGlobalConstants.DELETE_MAPPING_FULLY.equals(annotationName)) { } else if (SpringMvcAnnotations.DELETE_MAPPING.equals(annotationName) || DocGlobalConstants.DELETE_MAPPING_FULLY.equals(annotationName)) {
shortUrl = DocUtil.handleMappingValue(annotation); shortUrl = DocUtil.handleMappingValue(annotation);
methodType = Methods.DELETE.getValue(); methodType = Methods.DELETE.getValue();
} }
} }
if (shortUrl != null) { if (shortUrl != null) {
@ -111,6 +108,16 @@ public class SpringMVCRequestMappingHandler {
url = UrlUtil.simplifyUrl(serverUrl + "/" + controllerBaseUrl + "/" + shortUrl); url = UrlUtil.simplifyUrl(serverUrl + "/" + controllerBaseUrl + "/" + shortUrl);
shortUrl = UrlUtil.simplifyUrl("/" + controllerBaseUrl + "/" + shortUrl); shortUrl = UrlUtil.simplifyUrl("/" + controllerBaseUrl + "/" + shortUrl);
} }
for (Map.Entry<String, String> entry : constantsMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (url.contains(key)) {
url = url.replace(key, value);
}
if (shortUrl.contains(key)) {
shortUrl = shortUrl.replace(key, value);
}
}
return RequestMapping.builder().setMediaType(mediaType).setMethodType(methodType) return RequestMapping.builder().setMediaType(mediaType).setMethodType(methodType)
.setUrl(url).setShortUrl(shortUrl).setDeprecated(deprecated); .setUrl(url).setShortUrl(shortUrl).setDeprecated(deprecated);
} }

View File

@ -136,6 +136,11 @@ public class ApiConfig {
*/ */
private List<RpcApiDependency> rpcApiDependencies; private List<RpcApiDependency> rpcApiDependencies;
/**
* list of api constant
*/
private List<ApiConstant> apiConstants;
/** /**
* @since 1.7.5 * @since 1.7.5
* project name * project name
@ -346,6 +351,14 @@ public class ApiConfig {
this.rpcApiDependencies = CollectionUtil.asList(rpcApiDependencies); this.rpcApiDependencies = CollectionUtil.asList(rpcApiDependencies);
} }
public List<ApiConstant> getApiConstants() {
return apiConstants;
}
public void setApiConstants(ApiConstant... apiConstants) {
this.apiConstants = CollectionUtil.asList(apiConstants);
}
public boolean isCoverOld() { public boolean isCoverOld() {
return coverOld; return coverOld;
} }
@ -433,4 +446,6 @@ public class ApiConfig {
public void setRecursionLimit(int recursionLimit) { public void setRecursionLimit(int recursionLimit) {
this.recursionLimit = recursionLimit; this.recursionLimit = recursionLimit;
} }
} }

View File

@ -0,0 +1,53 @@
package com.power.doc.model;
/**
* @author yu 2020/7/2.
*/
public class ApiConstant {
/**
* Constants class
*/
private Class constantsClass;
/**
* Constants class name
*/
private String constantsClassName;
/**
* Description
*/
private String description;
public static ApiConstant builder() {
return new ApiConstant();
}
public Class getConstantsClass() {
return constantsClass;
}
public ApiConstant setConstantsClass(Class constantsClass) {
this.constantsClass = constantsClass;
return this;
}
public String getConstantsClassName() {
return constantsClassName;
}
public ApiConstant setConstantsClassName(String constantsClassName) {
this.constantsClassName = constantsClassName;
return this;
}
public String getDescription() {
return description;
}
public ApiConstant setDescription(String description) {
this.description = description;
return this;
}
}

View File

@ -22,7 +22,10 @@
*/ */
package com.power.doc.template; package com.power.doc.template;
import com.power.common.util.*; import com.power.common.util.JsonFormatUtil;
import com.power.common.util.RandomUtil;
import com.power.common.util.StringUtil;
import com.power.common.util.UrlUtil;
import com.power.doc.builder.ProjectDocConfigBuilder; import com.power.doc.builder.ProjectDocConfigBuilder;
import com.power.doc.constants.*; import com.power.doc.constants.*;
import com.power.doc.handler.SpringMVCRequestHeaderHandler; import com.power.doc.handler.SpringMVCRequestHeaderHandler;
@ -103,6 +106,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
String clazName = cls.getCanonicalName(); String clazName = cls.getCanonicalName();
String classAuthor = JavaClassUtil.getClassTagsValue(cls, DocTags.AUTHOR, Boolean.TRUE); String classAuthor = JavaClassUtil.getClassTagsValue(cls, DocTags.AUTHOR, Boolean.TRUE);
List<JavaAnnotation> classAnnotations = cls.getAnnotations(); List<JavaAnnotation> classAnnotations = cls.getAnnotations();
Map<String, String> constantsMap = projectBuilder.getConstantsMap();
String baseUrl = ""; String baseUrl = "";
for (JavaAnnotation annotation : classAnnotations) { for (JavaAnnotation annotation : classAnnotations) {
String annotationName = annotation.getType().getValue(); String annotationName = annotation.getType().getValue();
@ -144,7 +148,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
apiMethodDoc.setDetail(apiNoteValue); apiMethodDoc.setDetail(apiNoteValue);
//handle request mapping //handle request mapping
RequestMapping requestMapping = new SpringMVCRequestMappingHandler() RequestMapping requestMapping = new SpringMVCRequestMappingHandler()
.handle(projectBuilder.getServerUrl(), baseUrl, method); .handle(projectBuilder.getServerUrl(), baseUrl, method, constantsMap);
//handle headers //handle headers
List<ApiReqHeader> apiReqHeaders = new SpringMVCRequestHeaderHandler().handle(method); List<ApiReqHeader> apiReqHeaders = new SpringMVCRequestHeaderHandler().handle(method);
apiMethodDoc.setRequestHeaders(apiReqHeaders); apiMethodDoc.setRequestHeaders(apiReqHeaders);
@ -194,6 +198,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
if (parameterList.size() < 1) { if (parameterList.size() < 1) {
return ApiRequestExample.builder().setUrl(apiMethodDoc.getUrl()); return ApiRequestExample.builder().setUrl(apiMethodDoc.getUrl());
} }
Map<String, String> constantsMap = configBuilder.getConstantsMap();
boolean requestFieldToUnderline = configBuilder.getApiConfig().isRequestFieldToUnderline(); boolean requestFieldToUnderline = configBuilder.getApiConfig().isRequestFieldToUnderline();
Map<String, String> replacementMap = configBuilder.getReplaceClassMap(); Map<String, String> replacementMap = configBuilder.getReplaceClassMap();
Map<String, String> pathParamsMap = new LinkedHashMap<>(); Map<String, String> pathParamsMap = new LinkedHashMap<>();
@ -267,6 +272,18 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
if (null != annotationOfName) { if (null != annotationOfName) {
paramName = StringUtil.removeQuotes(annotationOfName.toString()); paramName = StringUtil.removeQuotes(annotationOfName.toString());
} }
for (Map.Entry<String, String> entry : constantsMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
// replace param
if (paramName.contains(key)) {
paramName = paramName.replace(key, value);
}
// replace mockValue
if (mockValue.contains(entry.getKey())) {
mockValue = mockValue.replace(key, value);
}
}
if (SpringMvcAnnotations.REQUEST_BODY.equals(annotationName) || DocGlobalConstants.REQUEST_BODY_FULLY.equals(annotationName)) { if (SpringMvcAnnotations.REQUEST_BODY.equals(annotationName) || DocGlobalConstants.REQUEST_BODY_FULLY.equals(annotationName)) {
apiMethodDoc.setContentType(JSON_CONTENT_TYPE); apiMethodDoc.setContentType(JSON_CONTENT_TYPE);
if (JavaClassValidateUtil.isPrimitive(simpleTypeName)) { if (JavaClassValidateUtil.isPrimitive(simpleTypeName)) {
@ -393,6 +410,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
private List<ApiParam> requestParams(final JavaMethod javaMethod, final String tagName, ProjectDocConfigBuilder builder) { private List<ApiParam> requestParams(final JavaMethod javaMethod, final String tagName, ProjectDocConfigBuilder builder) {
boolean isStrict = builder.getApiConfig().isStrict(); boolean isStrict = builder.getApiConfig().isStrict();
Map<String, CustomRespField> responseFieldMap = new HashMap<>(); Map<String, CustomRespField> responseFieldMap = new HashMap<>();
Map<String, String> replacementMap = builder.getReplaceClassMap(); Map<String, String> replacementMap = builder.getReplaceClassMap();
String className = javaMethod.getDeclaringClass().getCanonicalName(); String className = javaMethod.getDeclaringClass().getCanonicalName();
Map<String, String> paramTagMap = DocUtil.getParamsComments(javaMethod, tagName, className); Map<String, String> paramTagMap = DocUtil.getParamsComments(javaMethod, tagName, className);
@ -400,6 +418,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
if (parameterList.size() < 1) { if (parameterList.size() < 1) {
return null; return null;
} }
Map<String, String> constantsMap = builder.getConstantsMap();
boolean requestFieldToUnderline = builder.getApiConfig().isRequestFieldToUnderline(); boolean requestFieldToUnderline = builder.getApiConfig().isRequestFieldToUnderline();
Set<String> jsonParamSet = this.jsonParamSet(parameterList); Set<String> jsonParamSet = this.jsonParamSet(parameterList);
List<ApiParam> paramList = new ArrayList<>(); List<ApiParam> paramList = new ArrayList<>();
@ -465,6 +484,13 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
if (null != annotationOfName) { if (null != annotationOfName) {
paramName = StringUtil.removeQuotes(annotationOfName.toString()); paramName = StringUtil.removeQuotes(annotationOfName.toString());
} }
for (Map.Entry<String, String> entry : constantsMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (paramName.contains(key)) {
paramName = paramName.replace(key, value);
}
}
AnnotationValue annotationRequired = annotation.getProperty(DocAnnotationConstants.REQUIRED_PROP); AnnotationValue annotationRequired = annotation.getProperty(DocAnnotationConstants.REQUIRED_PROP);
if (null != annotationRequired) { if (null != annotationRequired) {
strRequired = annotationRequired.toString(); strRequired = annotationRequired.toString();
@ -518,7 +544,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate<ApiDoc> {
//参数列表 当为枚举时 //参数列表 当为枚举时
else if (javaClass.isEnum()) { else if (javaClass.isEnum()) {
String o = JavaClassUtil.getEnumParams(javaClass); String o = JavaClassUtil.getEnumParams(javaClass);
ApiParam param = ApiParam.of().setField(paramName) ApiParam param = ApiParam.of().setField(paramName)
.setType("enum").setDesc(StringUtil.removeQuotes(o)).setRequired(required).setVersion(DocGlobalConstants.DEFAULT_VERSION); .setType("enum").setDesc(StringUtil.removeQuotes(o)).setRequired(required).setVersion(DocGlobalConstants.DEFAULT_VERSION);
paramList.add(param); paramList.add(param);

View File

@ -36,10 +36,9 @@ import com.thoughtworks.qdox.model.expression.TypeRef;
import com.thoughtworks.qdox.model.impl.DefaultJavaField; import com.thoughtworks.qdox.model.impl.DefaultJavaField;
import com.thoughtworks.qdox.model.impl.DefaultJavaParameterizedType; import com.thoughtworks.qdox.model.impl.DefaultJavaParameterizedType;
import java.util.ArrayList; import java.lang.reflect.Field;
import java.util.List; import java.lang.reflect.Modifier;
import java.util.Objects; import java.util.*;
import java.util.Set;
/** /**
* Handle JavaClass * Handle JavaClass
@ -166,10 +165,10 @@ public class JavaClassUtil {
//如果枚举值不为空 //如果枚举值不为空
if (!CollectionUtil.isEmpty(exceptions)) { if (!CollectionUtil.isEmpty(exceptions)) {
stringBuilder.append(" -("); stringBuilder.append(" -(");
for(int i=0 ;i<exceptions.size();i++){ for (int i = 0; i < exceptions.size(); i++) {
stringBuilder.append(exceptions.get(i)); stringBuilder.append(exceptions.get(i));
if(i != exceptions.size() - 1) { if (i != exceptions.size() - 1) {
stringBuilder.append(","); stringBuilder.append(",");
} }
} }
@ -304,6 +303,26 @@ public class JavaClassUtil {
return null; return null;
} }
/**
* Get Map of final field and value
* @param clazz Java class
* @return Map
* @throws IllegalAccessException IllegalAccessException
*/
public static Map<String, String> getFinalFieldValue(Class<?> clazz) throws IllegalAccessException {
String className = getClassSimpleName(clazz.getName());
Field[] fields = clazz.getDeclaredFields();
Map<String, String> constants = new HashMap<>();
for (Field field : fields) {
boolean isFinal = Modifier.isFinal(field.getModifiers());
if (isFinal) {
String name = field.getName();
constants.put(className + "." + name, String.valueOf(field.get(null)));
}
}
return constants;
}
private static void addGroupClass(List<AnnotationValue> annotationValueList, List<String> javaClassList) { private static void addGroupClass(List<AnnotationValue> annotationValueList, List<String> javaClassList) {
if (CollectionUtil.isEmpty(annotationValueList)) { if (CollectionUtil.isEmpty(annotationValueList)) {
return; return;