代码拆分
This commit is contained in:
parent
f24306c0bb
commit
4cb5604413
|
@ -0,0 +1,131 @@
|
||||||
|
package com.power.doc.builder;
|
||||||
|
|
||||||
|
import com.power.common.util.CollectionUtil;
|
||||||
|
import com.power.common.util.StringUtil;
|
||||||
|
import com.power.doc.constants.DocGlobalConstants;
|
||||||
|
import com.power.doc.model.ApiConfig;
|
||||||
|
import com.power.doc.model.CustomRespField;
|
||||||
|
import com.power.doc.model.SourceCodePath;
|
||||||
|
import com.power.doc.utils.JavaClassUtil;
|
||||||
|
import com.thoughtworks.qdox.JavaProjectBuilder;
|
||||||
|
import com.thoughtworks.qdox.model.JavaClass;
|
||||||
|
import com.thoughtworks.qdox.model.JavaField;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import static com.power.doc.constants.DocGlobalConstants.DEFAULT_SERVER_URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yu 2019/12/21.
|
||||||
|
*/
|
||||||
|
public class ProjectDocConfigBuilder {
|
||||||
|
|
||||||
|
private JavaProjectBuilder javaProjectBuilder;
|
||||||
|
|
||||||
|
private Map<String, JavaClass> classFilesMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private Map<String, CustomRespField> customRespFieldMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private String serverUrl;
|
||||||
|
|
||||||
|
private ApiConfig apiConfig;
|
||||||
|
|
||||||
|
|
||||||
|
public ProjectDocConfigBuilder(ApiConfig apiConfig, JavaProjectBuilder javaProjectBuilder) {
|
||||||
|
if (null == apiConfig) {
|
||||||
|
throw new NullPointerException("ApiConfig can't be null.");
|
||||||
|
}
|
||||||
|
this.apiConfig = apiConfig;
|
||||||
|
if (Objects.isNull(javaProjectBuilder)) {
|
||||||
|
javaProjectBuilder = new JavaProjectBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtil.isEmpty(apiConfig.getServerUrl())) {
|
||||||
|
this.serverUrl = DEFAULT_SERVER_URL;
|
||||||
|
} else {
|
||||||
|
this.serverUrl = apiConfig.getServerUrl();
|
||||||
|
}
|
||||||
|
this.javaProjectBuilder = javaProjectBuilder;
|
||||||
|
this.loadJavaSource(apiConfig.getSourceCodePaths(),this.javaProjectBuilder);
|
||||||
|
this.initClassFilesMap(apiConfig);
|
||||||
|
this.initCustomResponseFieldsMap(apiConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadJavaSource(List<SourceCodePath> paths,JavaProjectBuilder builder) {
|
||||||
|
if (CollectionUtil.isEmpty(paths)) {
|
||||||
|
builder.addSourceTree(new File(DocGlobalConstants.PROJECT_CODE_PATH));
|
||||||
|
} else {
|
||||||
|
if (!paths.contains(DocGlobalConstants.PROJECT_CODE_PATH)) {
|
||||||
|
builder.addSourceTree(new File(DocGlobalConstants.PROJECT_CODE_PATH));
|
||||||
|
}
|
||||||
|
for (SourceCodePath path : paths) {
|
||||||
|
if (null == path) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String strPath = path.getPath();
|
||||||
|
if (StringUtil.isNotEmpty(strPath)) {
|
||||||
|
strPath = strPath.replace("\\", "/");
|
||||||
|
builder.addSourceTree(new File(strPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initClassFilesMap(ApiConfig config) {
|
||||||
|
Collection<JavaClass> javaClasses = javaProjectBuilder.getClasses();
|
||||||
|
for (JavaClass cls : javaClasses) {
|
||||||
|
classFilesMap.put(cls.getFullyQualifiedName(), cls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initCustomResponseFieldsMap(ApiConfig config){
|
||||||
|
if (CollectionUtil.isNotEmpty(config.getCustomResponseFields())) {
|
||||||
|
for (CustomRespField field : config.getCustomResponseFields()) {
|
||||||
|
customRespFieldMap.put(field.getName(), field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public JavaClass getClassByName(String simpleName) {
|
||||||
|
JavaClass cls = javaProjectBuilder.getClassByName(simpleName);
|
||||||
|
List<JavaField> fieldList = JavaClassUtil.getFields(cls, 0);
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public JavaProjectBuilder getJavaProjectBuilder() {
|
||||||
|
return javaProjectBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Map<String, JavaClass> getClassFilesMap() {
|
||||||
|
return classFilesMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, CustomRespField> getCustomRespFieldMap() {
|
||||||
|
return customRespFieldMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerUrl() {
|
||||||
|
return serverUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiConfig getApiConfig() {
|
||||||
|
return apiConfig;
|
||||||
|
}
|
||||||
|
}
|
|
@ -993,7 +993,7 @@ public class SourceBuilder {
|
||||||
boolean containsBrace = apiMethodDoc.getUrl().replace(DEFAULT_SERVER_URL, "").contains("{");
|
boolean containsBrace = apiMethodDoc.getUrl().replace(DEFAULT_SERVER_URL, "").contains("{");
|
||||||
Map<String, String> paramsMap = new LinkedHashMap<>();
|
Map<String, String> paramsMap = new LinkedHashMap<>();
|
||||||
Map<String, String> paramsComments = DocUtil.getParamsComments(method, DocTags.PARAM, null);
|
Map<String, String> paramsComments = DocUtil.getParamsComments(method, DocTags.PARAM, null);
|
||||||
List<String> springMvcRequestAnnotations = SpringMvcRequestAnnotations.listSpringMvcRequestAnnotations();
|
List<String> springMvcRequestAnnotations = SpringMvcRequestAnnotationsEnum.listSpringMvcRequestAnnotations();
|
||||||
for (JavaParameter parameter : parameterList) {
|
for (JavaParameter parameter : parameterList) {
|
||||||
JavaType javaType = parameter.getType();
|
JavaType javaType = parameter.getType();
|
||||||
String simpleTypeName = javaType.getValue();
|
String simpleTypeName = javaType.getValue();
|
||||||
|
@ -1272,7 +1272,7 @@ public class SourceBuilder {
|
||||||
if (paramAdded) {
|
if (paramAdded) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
List<String> validatorAnnotations = DocValidatorAnnotations.listValidatorAnnotations();
|
List<String> validatorAnnotations = DocValidatorAnnotationEnum.listValidatorAnnotations();
|
||||||
if (REQUEST_PARAM.equals(annotationName) ||
|
if (REQUEST_PARAM.equals(annotationName) ||
|
||||||
DocAnnotationConstants.SHORT_PATH_VARIABLE.equals(annotationName)) {
|
DocAnnotationConstants.SHORT_PATH_VARIABLE.equals(annotationName)) {
|
||||||
AnnotationValue annotationValue = annotation.getProperty(DocAnnotationConstants.VALUE_PROP);
|
AnnotationValue annotationValue = annotation.getProperty(DocAnnotationConstants.VALUE_PROP);
|
||||||
|
|
|
@ -1198,7 +1198,7 @@ public class SourceBuilders {
|
||||||
if (paramAdded) {
|
if (paramAdded) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
List<String> validatorAnnotations = DocValidatorAnnotations.listValidatorAnnotations();
|
List<String> validatorAnnotations = DocValidatorAnnotationEnum.listValidatorAnnotations();
|
||||||
if (REQUEST_PARAM.equals(annotationName) ||
|
if (REQUEST_PARAM.equals(annotationName) ||
|
||||||
DocAnnotationConstants.SHORT_PATH_VARIABLE.equals(annotationName)) {
|
DocAnnotationConstants.SHORT_PATH_VARIABLE.equals(annotationName)) {
|
||||||
AnnotationValue annotationValue = annotation.getProperty(DocAnnotationConstants.VALUE_PROP);
|
AnnotationValue annotationValue = annotation.getProperty(DocAnnotationConstants.VALUE_PROP);
|
||||||
|
|
|
@ -35,5 +35,15 @@ public class DocAnnotationConstants {
|
||||||
|
|
||||||
public static final String SHORT_REQUSRT_HEADER = "RequestHeader";
|
public static final String SHORT_REQUSRT_HEADER = "RequestHeader";
|
||||||
|
|
||||||
|
public static final String REQUEST_MAPPING = "RequestMapping";
|
||||||
|
|
||||||
|
private static final String GET_MAPPING = "GetMapping";
|
||||||
|
|
||||||
|
private static final String POST_MAPPING = "PostMapping";
|
||||||
|
|
||||||
|
private static final String PUT_MAPPING = "PutMapping";
|
||||||
|
|
||||||
|
private static final String DELETE_MAPPING = "DeleteMapping";
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,4 +104,6 @@ public class DocGlobalConstants {
|
||||||
public static final String HTTP_POST = "POST";
|
public static final String HTTP_POST = "POST";
|
||||||
|
|
||||||
public static final String SHORT_MULTIPART_FILE_FULLY = "MultipartFile";
|
public static final String SHORT_MULTIPART_FILE_FULLY = "MultipartFile";
|
||||||
|
|
||||||
|
public static final String DEFAULT_SERVER_URL = "http://{server}";
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.util.List;
|
||||||
*
|
*
|
||||||
* @author yu 2019/9/19.
|
* @author yu 2019/9/19.
|
||||||
*/
|
*/
|
||||||
public enum DocValidatorAnnotations {
|
public enum DocValidatorAnnotationEnum {
|
||||||
|
|
||||||
|
|
||||||
NOT_EMPTY("NotEmpty"),
|
NOT_EMPTY("NotEmpty"),
|
||||||
|
@ -50,13 +50,13 @@ public enum DocValidatorAnnotations {
|
||||||
|
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
DocValidatorAnnotations(String value) {
|
DocValidatorAnnotationEnum(String value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> listValidatorAnnotations() {
|
public static List<String> listValidatorAnnotations() {
|
||||||
List<String> annotations = new ArrayList<>();
|
List<String> annotations = new ArrayList<>();
|
||||||
for (DocValidatorAnnotations annotation : DocValidatorAnnotations.values()) {
|
for (DocValidatorAnnotationEnum annotation : DocValidatorAnnotationEnum.values()) {
|
||||||
annotations.add(annotation.value);
|
annotations.add(annotation.value);
|
||||||
}
|
}
|
||||||
return annotations;
|
return annotations;
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.power.doc.constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yu 2019/12/21.
|
||||||
|
*/
|
||||||
|
public class SpringMvcAnnotations {
|
||||||
|
|
||||||
|
public static final String REQUEST_MAPPING = "RequestMapping";
|
||||||
|
|
||||||
|
public static final String GET_MAPPING = "GetMapping";
|
||||||
|
|
||||||
|
public static final String POST_MAPPING = "PostMapping";
|
||||||
|
|
||||||
|
public static final String PUT_MAPPING = "PutMapping";
|
||||||
|
|
||||||
|
public static final String DELETE_MAPPING = "DeleteMapping";
|
||||||
|
|
||||||
|
public static final String REQUEST_HERDER = "RequestHeader";
|
||||||
|
|
||||||
|
public static final String REQUEST_PARAM = "RequestParam";
|
||||||
|
|
||||||
|
public static final String REQUEST_BODY = "RequestBody";
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ import java.util.List;
|
||||||
/**
|
/**
|
||||||
* @author yu 2019/12/20.
|
* @author yu 2019/12/20.
|
||||||
*/
|
*/
|
||||||
public enum SpringMvcRequestAnnotations {
|
public enum SpringMvcRequestAnnotationsEnum {
|
||||||
|
|
||||||
PATH_VARIABLE("PathVariable"),
|
PATH_VARIABLE("PathVariable"),
|
||||||
REQ_PARAM ("RequestParam"),
|
REQ_PARAM ("RequestParam"),
|
||||||
|
@ -15,13 +15,13 @@ public enum SpringMvcRequestAnnotations {
|
||||||
;
|
;
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
SpringMvcRequestAnnotations(String value) {
|
SpringMvcRequestAnnotationsEnum(String value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> listSpringMvcRequestAnnotations() {
|
public static List<String> listSpringMvcRequestAnnotations() {
|
||||||
List<String> annotations = new ArrayList<>();
|
List<String> annotations = new ArrayList<>();
|
||||||
for (SpringMvcRequestAnnotations annotation : SpringMvcRequestAnnotations.values()) {
|
for (SpringMvcRequestAnnotationsEnum annotation : SpringMvcRequestAnnotationsEnum.values()) {
|
||||||
annotations.add(annotation.value);
|
annotations.add(annotation.value);
|
||||||
}
|
}
|
||||||
return annotations;
|
return annotations;
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.power.doc.constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yu 2019/12/22.
|
||||||
|
*/
|
||||||
|
public class ValidatorAnnotations {
|
||||||
|
|
||||||
|
public static final String VALID = "Valid";
|
||||||
|
}
|
|
@ -0,0 +1,306 @@
|
||||||
|
package com.power.doc.helper;
|
||||||
|
|
||||||
|
import com.power.common.util.JsonFormatUtil;
|
||||||
|
import com.power.common.util.StringUtil;
|
||||||
|
import com.power.doc.builder.ProjectDocConfigBuilder;
|
||||||
|
import com.power.doc.constants.DocAnnotationConstants;
|
||||||
|
import com.power.doc.constants.DocGlobalConstants;
|
||||||
|
import com.power.doc.constants.DocTags;
|
||||||
|
import com.power.doc.model.ApiReturn;
|
||||||
|
import com.power.doc.model.CustomRespField;
|
||||||
|
import com.power.doc.utils.DocClassUtil;
|
||||||
|
import com.power.doc.utils.DocUtil;
|
||||||
|
import com.power.doc.utils.JavaClassUtil;
|
||||||
|
import com.power.doc.utils.JavaFieldUtil;
|
||||||
|
import com.thoughtworks.qdox.model.JavaAnnotation;
|
||||||
|
import com.thoughtworks.qdox.model.JavaClass;
|
||||||
|
import com.thoughtworks.qdox.model.JavaField;
|
||||||
|
import com.thoughtworks.qdox.model.JavaMethod;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yu 2019/12/21.
|
||||||
|
*/
|
||||||
|
public class JsonBuildHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* build return json
|
||||||
|
*
|
||||||
|
* @param method The JavaMethod object
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public static String buildReturnJson(JavaMethod method, ProjectDocConfigBuilder builder) {
|
||||||
|
if ("void".equals(method.getReturnType().getFullyQualifiedName())) {
|
||||||
|
return "This api return nothing.";
|
||||||
|
}
|
||||||
|
ApiReturn apiReturn = DocClassUtil.processReturnType(method.getReturnType().getGenericCanonicalName());
|
||||||
|
String returnType = apiReturn.getGenericCanonicalName();
|
||||||
|
String typeName = apiReturn.getSimpleName();
|
||||||
|
return JsonFormatUtil.formatJson(buildJson(typeName, returnType, true, 0, new HashMap<>(),builder));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param typeName type name
|
||||||
|
* @param genericCanonicalName genericCanonicalName
|
||||||
|
* @param isResp Response flag
|
||||||
|
* @param counter Recursive counter
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
private static String buildJson(String typeName, String genericCanonicalName,
|
||||||
|
boolean isResp, int counter, Map<String, String> registryClasses, ProjectDocConfigBuilder builder) {
|
||||||
|
if (registryClasses.containsKey(typeName) && counter > registryClasses.size()) {
|
||||||
|
return "{\"$ref\":\"...\"}";
|
||||||
|
}
|
||||||
|
registryClasses.put(typeName, typeName);
|
||||||
|
if (DocClassUtil.isMvcIgnoreParams(typeName)) {
|
||||||
|
if (DocGlobalConstants.MODE_AND_VIEW_FULLY.equals(typeName)) {
|
||||||
|
return "Forward or redirect to a page view.";
|
||||||
|
} else {
|
||||||
|
return "Error restful return.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (DocClassUtil.isPrimitive(typeName)) {
|
||||||
|
return StringUtil.removeQuotes(DocUtil.jsonValueByType(typeName));
|
||||||
|
}
|
||||||
|
StringBuilder data0 = new StringBuilder();
|
||||||
|
JavaClass cls = builder.getClassByName(typeName);
|
||||||
|
data0.append("{");
|
||||||
|
String[] globGicName = DocClassUtil.getSimpleGicName(genericCanonicalName);
|
||||||
|
StringBuilder data = new StringBuilder();
|
||||||
|
if (DocClassUtil.isCollection(typeName) || DocClassUtil.isArray(typeName)) {
|
||||||
|
data.append("[");
|
||||||
|
if (globGicName.length == 0) {
|
||||||
|
data.append("{\"object\":\"any object\"}");
|
||||||
|
data.append("]");
|
||||||
|
return data.toString();
|
||||||
|
}
|
||||||
|
String gNameTemp = globGicName[0];
|
||||||
|
String gName = DocClassUtil.isArray(typeName) ? gNameTemp.substring(0, gNameTemp.indexOf("[")) : globGicName[0];
|
||||||
|
if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(gName)) {
|
||||||
|
data.append("{\"waring\":\"You may use java.util.Object instead of display generics in the List\"}");
|
||||||
|
} else if (DocClassUtil.isPrimitive(gName)) {
|
||||||
|
data.append(DocUtil.jsonValueByType(gName)).append(",");
|
||||||
|
data.append(DocUtil.jsonValueByType(gName));
|
||||||
|
} else if (gName.contains("<")) {
|
||||||
|
String simple = DocClassUtil.getSimpleName(gName);
|
||||||
|
String json = buildJson(simple, gName, isResp, counter + 1, registryClasses,builder);
|
||||||
|
data.append(json);
|
||||||
|
} else if (DocClassUtil.isCollection(gName)) {
|
||||||
|
data.append("\"any object\"");
|
||||||
|
} else {
|
||||||
|
String json = buildJson(gName, gName, isResp, counter + 1, registryClasses,builder);
|
||||||
|
data.append(json);
|
||||||
|
}
|
||||||
|
data.append("]");
|
||||||
|
return data.toString();
|
||||||
|
} else if (DocClassUtil.isMap(typeName)) {
|
||||||
|
String gNameTemp = genericCanonicalName;
|
||||||
|
String[] getKeyValType = DocClassUtil.getMapKeyValueType(gNameTemp);
|
||||||
|
if (getKeyValType.length == 0) {
|
||||||
|
data.append("{\"mapKey\":{}}");
|
||||||
|
return data.toString();
|
||||||
|
}
|
||||||
|
if (!DocGlobalConstants.JAVA_STRING_FULLY.equals(getKeyValType[0])) {
|
||||||
|
throw new RuntimeException("Map's key can only use String for json,but you use " + getKeyValType[0]);
|
||||||
|
}
|
||||||
|
String gicName = gNameTemp.substring(gNameTemp.indexOf(",") + 1, gNameTemp.lastIndexOf(">"));
|
||||||
|
if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(gicName)) {
|
||||||
|
data.append("{").append("\"mapKey\":").append("{\"waring\":\"You may use java.util.Object for Map value; smart-doc can't be handle.\"}").append("}");
|
||||||
|
} else if (DocClassUtil.isPrimitive(gicName)) {
|
||||||
|
data.append("{").append("\"mapKey1\":").append(DocUtil.jsonValueByType(gicName)).append(",");
|
||||||
|
data.append("\"mapKey2\":").append(DocUtil.jsonValueByType(gicName)).append("}");
|
||||||
|
} else if (gicName.contains("<")) {
|
||||||
|
String simple = DocClassUtil.getSimpleName(gicName);
|
||||||
|
String json = buildJson(simple, gicName, isResp, counter + 1, registryClasses,builder);
|
||||||
|
data.append("{").append("\"mapKey\":").append(json).append("}");
|
||||||
|
} else {
|
||||||
|
data.append("{").append("\"mapKey\":").append(buildJson(gicName, gNameTemp, isResp, counter + 1, registryClasses,builder)).append("}");
|
||||||
|
}
|
||||||
|
return data.toString();
|
||||||
|
} else if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(typeName)) {
|
||||||
|
if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(typeName)) {
|
||||||
|
data.append("{\"object\":\" any object\"},");
|
||||||
|
// throw new RuntimeException("Please do not return java.lang.Object directly in api interface.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
List<JavaField> fields = JavaClassUtil.getFields(cls, 0);
|
||||||
|
boolean isGenerics = JavaFieldUtil.checkGenerics(fields);
|
||||||
|
int i = 0;
|
||||||
|
out:
|
||||||
|
for (JavaField field : fields) {
|
||||||
|
String subTypeName = field.getType().getFullyQualifiedName();
|
||||||
|
String fieldName = field.getName();
|
||||||
|
if ("this$0".equals(fieldName) ||
|
||||||
|
"serialVersionUID".equals(fieldName) ||
|
||||||
|
DocClassUtil.isIgnoreFieldTypes(subTypeName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Map<String, String> tagsMap = DocUtil.getFieldTagsValue(field);
|
||||||
|
if (!isResp) {
|
||||||
|
if (tagsMap.containsKey(DocTags.IGNORE)) {
|
||||||
|
continue out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<JavaAnnotation> annotations = field.getAnnotations();
|
||||||
|
for (JavaAnnotation annotation : annotations) {
|
||||||
|
String annotationName = annotation.getType().getSimpleName();
|
||||||
|
if (DocAnnotationConstants.SHORT_JSON_IGNORE.equals(annotationName) && isResp) {
|
||||||
|
continue out;
|
||||||
|
} else if (DocAnnotationConstants.SHORT_JSON_FIELD.equals(annotationName) && isResp) {
|
||||||
|
if (null != annotation.getProperty(DocAnnotationConstants.SERIALIZE_PROP)) {
|
||||||
|
if (Boolean.FALSE.toString().equals(annotation.getProperty(DocAnnotationConstants.SERIALIZE_PROP).toString())) {
|
||||||
|
continue out;
|
||||||
|
}
|
||||||
|
} else if (null != annotation.getProperty(DocAnnotationConstants.NAME_PROP)) {
|
||||||
|
fieldName = StringUtil.removeQuotes(annotation.getProperty(DocAnnotationConstants.NAME_PROP).toString());
|
||||||
|
}
|
||||||
|
} else if (DocAnnotationConstants.SHORT_JSON_PROPERTY.equals(annotationName) && isResp) {
|
||||||
|
if (null != annotation.getProperty(DocAnnotationConstants.VALUE_PROP)) {
|
||||||
|
fieldName = StringUtil.removeQuotes(annotation.getProperty(DocAnnotationConstants.VALUE_PROP).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String typeSimpleName = field.getType().getSimpleName();
|
||||||
|
|
||||||
|
String fieldGicName = field.getType().getGenericCanonicalName();
|
||||||
|
data0.append("\"").append(fieldName).append("\":");
|
||||||
|
if (DocClassUtil.isPrimitive(subTypeName)) {
|
||||||
|
String fieldValue = "";
|
||||||
|
if (tagsMap.containsKey(DocTags.MOCK) && StringUtil.isNotEmpty(tagsMap.get(DocTags.MOCK))) {
|
||||||
|
fieldValue = tagsMap.get(DocTags.MOCK);
|
||||||
|
if ("String".equals(typeSimpleName)) {
|
||||||
|
fieldValue = DocUtil.handleJsonStr(fieldValue);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fieldValue = DocUtil.getValByTypeAndFieldName(typeSimpleName, field.getName());
|
||||||
|
}
|
||||||
|
CustomRespField customResponseField = builder.getCustomRespFieldMap().get(fieldName);
|
||||||
|
if (null != customResponseField) {
|
||||||
|
Object val = customResponseField.getValue();
|
||||||
|
if (null != val) {
|
||||||
|
if ("String".equals(typeSimpleName)) {
|
||||||
|
data0.append(DocUtil.handleJsonStr(String.valueOf(val))).append(",");
|
||||||
|
} else {
|
||||||
|
data0.append(val).append(",");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data0.append(fieldValue).append(",");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data0.append(fieldValue).append(",");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (DocClassUtil.isCollection(subTypeName) || DocClassUtil.isArray(subTypeName)) {
|
||||||
|
fieldGicName = DocClassUtil.isArray(subTypeName) ? fieldGicName.substring(0, fieldGicName.indexOf("[")) : fieldGicName;
|
||||||
|
if (DocClassUtil.getSimpleGicName(fieldGicName).length == 0) {
|
||||||
|
data0.append("{\"object\":\"any object\"},");
|
||||||
|
continue out;
|
||||||
|
}
|
||||||
|
String gicName = DocClassUtil.getSimpleGicName(fieldGicName)[0];
|
||||||
|
|
||||||
|
if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName)) {
|
||||||
|
data0.append("[").append("\"").append(buildJson(gicName, fieldGicName, isResp, counter + 1, registryClasses,builder)).append("\"]").append(",");
|
||||||
|
} else if (DocGlobalConstants.JAVA_LIST_FULLY.equals(gicName)) {
|
||||||
|
data0.append("{\"object\":\"any object\"},");
|
||||||
|
} else if (gicName.length() == 1) {
|
||||||
|
if (globGicName.length == 0) {
|
||||||
|
data0.append("{\"object\":\"any object\"},");
|
||||||
|
continue out;
|
||||||
|
}
|
||||||
|
String gicName1 = (i < globGicName.length) ? globGicName[i] : globGicName[globGicName.length - 1];
|
||||||
|
if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName1)) {
|
||||||
|
data0.append("[").append("\"").append(buildJson(gicName1, gicName1, isResp, counter + 1, registryClasses,builder)).append("\"]").append(",");
|
||||||
|
} else {
|
||||||
|
if (!typeName.equals(gicName1)) {
|
||||||
|
data0.append("[").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, counter + 1, registryClasses,builder)).append("]").append(",");
|
||||||
|
} else {
|
||||||
|
data0.append("[{\"$ref\":\"..\"}]").append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!typeName.equals(gicName)) {
|
||||||
|
if (DocClassUtil.isMap(gicName)) {
|
||||||
|
data0.append("[{\"mapKey\":{}}],");
|
||||||
|
continue out;
|
||||||
|
}
|
||||||
|
data0.append("[").append(buildJson(gicName, fieldGicName, isResp, counter + 1, registryClasses,builder)).append("]").append(",");
|
||||||
|
} else {
|
||||||
|
data0.append("[{\"$ref\":\"..\"}]").append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (DocClassUtil.isMap(subTypeName)) {
|
||||||
|
if (DocClassUtil.isMap(fieldGicName)) {
|
||||||
|
data0.append("{").append("\"mapKey\":{}},");
|
||||||
|
continue out;
|
||||||
|
}
|
||||||
|
String gicName = fieldGicName.substring(fieldGicName.indexOf(",") + 1, fieldGicName.indexOf(">"));
|
||||||
|
if (gicName.length() == 1) {
|
||||||
|
String gicName1 = (i < globGicName.length) ? globGicName[i] : globGicName[globGicName.length - 1];
|
||||||
|
if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName1)) {
|
||||||
|
data0.append("{").append("\"mapKey\":\"").append(buildJson(gicName1, gicName1, isResp, counter + 1, registryClasses,builder)).append("\"},");
|
||||||
|
} else {
|
||||||
|
if (!typeName.equals(gicName1)) {
|
||||||
|
data0.append("{").append("\"mapKey\":").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, counter + 1, registryClasses,builder)).append("},");
|
||||||
|
} else {
|
||||||
|
data0.append("{\"mapKey\":{}},");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data0.append("{").append("\"mapKey\":").append(buildJson(gicName, fieldGicName, isResp, counter + 1, registryClasses,builder)).append("},");
|
||||||
|
}
|
||||||
|
} else if (subTypeName.length() == 1) {
|
||||||
|
if (!typeName.equals(genericCanonicalName)) {
|
||||||
|
String gicName = globGicName[i];
|
||||||
|
if (DocClassUtil.isPrimitive(gicName)) {
|
||||||
|
data0.append(DocUtil.jsonValueByType(gicName)).append(",");
|
||||||
|
} else {
|
||||||
|
String simple = DocClassUtil.getSimpleName(gicName);
|
||||||
|
data0.append(buildJson(simple, gicName, isResp, counter + 1, registryClasses,builder)).append(",");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data0.append("{\"waring\":\"You may have used non-display generics.\"},");
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
} else if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) {
|
||||||
|
if (isGenerics) {
|
||||||
|
data0.append("{\"object\":\"any object\"},");
|
||||||
|
} else if (i < globGicName.length) {
|
||||||
|
String gicName = globGicName[i];
|
||||||
|
if (!typeName.equals(genericCanonicalName)) {
|
||||||
|
if (DocClassUtil.isPrimitive(gicName)) {
|
||||||
|
data0.append("\"").append(buildJson(gicName, genericCanonicalName, isResp, counter + 1, registryClasses,builder)).append("\",");
|
||||||
|
} else {
|
||||||
|
String simpleName = DocClassUtil.getSimpleName(gicName);
|
||||||
|
data0.append(buildJson(simpleName, gicName, isResp, counter + 1, registryClasses,builder)).append(",");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data0.append("{\"waring\":\"You may have used non-display generics.\"},");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data0.append("{\"waring\":\"You may have used non-display generics.\"},");
|
||||||
|
}
|
||||||
|
if (!isGenerics) i++;
|
||||||
|
} else if (typeName.equals(subTypeName)) {
|
||||||
|
data0.append("{\"$ref\":\"...\"}").append(",");
|
||||||
|
} else {
|
||||||
|
JavaClass javaClass = builder.getJavaProjectBuilder().getClassByName(subTypeName);
|
||||||
|
if (!isResp && javaClass.isEnum()) {
|
||||||
|
Object value = JavaClassUtil.getEnumValue(javaClass, Boolean.FALSE);
|
||||||
|
data0.append(value).append(",");
|
||||||
|
} else {
|
||||||
|
data0.append(buildJson(subTypeName, fieldGicName,isResp, counter + 1, registryClasses,builder)).append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (data0.toString().contains(",")) {
|
||||||
|
data0.deleteCharAt(data0.lastIndexOf(","));
|
||||||
|
}
|
||||||
|
data0.append("}");
|
||||||
|
return data0.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,305 @@
|
||||||
|
package com.power.doc.helper;
|
||||||
|
|
||||||
|
import com.power.common.util.CollectionUtil;
|
||||||
|
import com.power.common.util.StringUtil;
|
||||||
|
import com.power.doc.builder.ProjectDocConfigBuilder;
|
||||||
|
import com.power.doc.constants.DocAnnotationConstants;
|
||||||
|
import com.power.doc.constants.DocGlobalConstants;
|
||||||
|
import com.power.doc.constants.DocTags;
|
||||||
|
import com.power.doc.model.ApiParam;
|
||||||
|
import com.power.doc.model.CustomRespField;
|
||||||
|
import com.power.doc.utils.DocClassUtil;
|
||||||
|
import com.power.doc.utils.DocUtil;
|
||||||
|
import com.power.doc.utils.JavaClassUtil;
|
||||||
|
import com.power.doc.utils.JavaFieldUtil;
|
||||||
|
import com.thoughtworks.qdox.model.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.power.doc.constants.DocGlobalConstants.NO_COMMENTS_FOUND;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yu 2019/12/21.
|
||||||
|
*/
|
||||||
|
public class ParamsBuildHelper {
|
||||||
|
|
||||||
|
public static List<ApiParam> buildParams(String className, String pre, int i, String isRequired,
|
||||||
|
Map<String, CustomRespField> responseFieldMap, boolean isResp,
|
||||||
|
Map<String, String> registryClasses,ProjectDocConfigBuilder projectBuilder) {
|
||||||
|
if (StringUtil.isEmpty(className)) {
|
||||||
|
throw new RuntimeException("Class name can't be null or empty.");
|
||||||
|
}
|
||||||
|
// Check circular reference
|
||||||
|
List<ApiParam> paramList = new ArrayList<>();
|
||||||
|
if (registryClasses.containsKey(className) && i > registryClasses.size()) {
|
||||||
|
return paramList;
|
||||||
|
}
|
||||||
|
// Registry class
|
||||||
|
registryClasses.put(className, className);
|
||||||
|
String simpleName = DocClassUtil.getSimpleName(className);
|
||||||
|
String[] globGicName = DocClassUtil.getSimpleGicName(className);
|
||||||
|
JavaClass cls = projectBuilder.getClassByName(simpleName);
|
||||||
|
List<JavaField> fields = JavaClassUtil.getFields(cls, 0);
|
||||||
|
int n = 0;
|
||||||
|
if (DocClassUtil.isPrimitive(simpleName)) {
|
||||||
|
paramList.addAll(primitiveReturnRespComment(DocClassUtil.processTypeNameForParams(simpleName)));
|
||||||
|
} else if (DocClassUtil.isCollection(simpleName) || DocClassUtil.isArray(simpleName)) {
|
||||||
|
if (!DocClassUtil.isCollection(globGicName[0])) {
|
||||||
|
String gicName = globGicName[0];
|
||||||
|
if (DocClassUtil.isArray(gicName)) {
|
||||||
|
gicName = gicName.substring(0, gicName.indexOf("["));
|
||||||
|
}
|
||||||
|
paramList.addAll(buildParams(gicName, pre, i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
} else if (DocClassUtil.isMap(simpleName)) {
|
||||||
|
if (globGicName.length == 2) {
|
||||||
|
paramList.addAll(buildParams(globGicName[1], pre, i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
} else if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(className)) {
|
||||||
|
ApiParam param = ApiParam.of().setField(pre + "any object").setType("object");
|
||||||
|
if (StringUtil.isEmpty(isRequired)) {
|
||||||
|
param.setDesc(DocGlobalConstants.ANY_OBJECT_MSG).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
} else {
|
||||||
|
param.setDesc(DocGlobalConstants.ANY_OBJECT_MSG).setRequired(false).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
}
|
||||||
|
paramList.add(param);
|
||||||
|
} else {
|
||||||
|
boolean isGenerics = JavaFieldUtil.checkGenerics(fields);
|
||||||
|
out:
|
||||||
|
for (JavaField field : fields) {
|
||||||
|
String fieldName = field.getName();
|
||||||
|
String subTypeName = field.getType().getFullyQualifiedName();
|
||||||
|
if ("this$0".equals(fieldName) ||
|
||||||
|
"serialVersionUID".equals(fieldName) ||
|
||||||
|
DocClassUtil.isIgnoreFieldTypes(subTypeName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String typeSimpleName = field.getType().getSimpleName();
|
||||||
|
String fieldGicName = field.getType().getGenericCanonicalName();
|
||||||
|
List<JavaAnnotation> javaAnnotations = field.getAnnotations();
|
||||||
|
|
||||||
|
Map<String, String> tagsMap = DocUtil.getFieldTagsValue(field);
|
||||||
|
String since = DocGlobalConstants.DEFAULT_VERSION;//since tag value
|
||||||
|
if (!isResp) {
|
||||||
|
pre:
|
||||||
|
if (tagsMap.containsKey(DocTags.IGNORE)) {
|
||||||
|
continue out;
|
||||||
|
} else if (tagsMap.containsKey(DocTags.SINCE)) {
|
||||||
|
since = tagsMap.get(DocTags.SINCE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (tagsMap.containsKey(DocTags.SINCE)) {
|
||||||
|
since = tagsMap.get(DocTags.SINCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean strRequired = false;
|
||||||
|
int annotationCounter = 0;
|
||||||
|
an:
|
||||||
|
for (JavaAnnotation annotation : javaAnnotations) {
|
||||||
|
String annotationName = annotation.getType().getSimpleName();
|
||||||
|
if (DocAnnotationConstants.SHORT_JSON_IGNORE.equals(annotationName) && isResp) {
|
||||||
|
continue out;
|
||||||
|
} else if (DocAnnotationConstants.SHORT_JSON_FIELD.equals(annotationName) && isResp) {
|
||||||
|
if (null != annotation.getProperty(DocAnnotationConstants.SERIALIZE_PROP)) {
|
||||||
|
if (Boolean.FALSE.toString().equals(annotation.getProperty(DocAnnotationConstants.SERIALIZE_PROP).toString())) {
|
||||||
|
continue out;
|
||||||
|
}
|
||||||
|
} else if (null != annotation.getProperty(DocAnnotationConstants.NAME_PROP)) {
|
||||||
|
fieldName = StringUtil.removeQuotes(annotation.getProperty(DocAnnotationConstants.NAME_PROP).toString());
|
||||||
|
}
|
||||||
|
} else if (DocAnnotationConstants.SHORT_JSON_PROPERTY.equals(annotationName) && isResp) {
|
||||||
|
if (null != annotation.getProperty(DocAnnotationConstants.VALUE_PROP)) {
|
||||||
|
fieldName = StringUtil.removeQuotes(annotation.getProperty(DocAnnotationConstants.VALUE_PROP).toString());
|
||||||
|
}
|
||||||
|
} else if (DocClassUtil.isJSR303Required(annotationName)) {
|
||||||
|
strRequired = true;
|
||||||
|
annotationCounter++;
|
||||||
|
break an;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (annotationCounter < 1) {
|
||||||
|
doc:
|
||||||
|
if (tagsMap.containsKey(DocTags.REQUIRED)) {
|
||||||
|
strRequired = true;
|
||||||
|
break doc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//cover comment
|
||||||
|
CustomRespField customResponseField = responseFieldMap.get(field.getName());
|
||||||
|
String comment;
|
||||||
|
if (null != customResponseField && StringUtil.isNotEmpty(customResponseField.getDesc())) {
|
||||||
|
comment = customResponseField.getDesc();
|
||||||
|
} else {
|
||||||
|
comment = field.getComment();
|
||||||
|
}
|
||||||
|
if (StringUtil.isNotEmpty(comment)) {
|
||||||
|
comment = DocUtil.replaceNewLineToHtmlBr(comment);
|
||||||
|
}
|
||||||
|
if (DocClassUtil.isPrimitive(subTypeName)) {
|
||||||
|
ApiParam param = ApiParam.of().setField(pre + fieldName);
|
||||||
|
String processedType = DocClassUtil.processTypeNameForParams(typeSimpleName.toLowerCase());
|
||||||
|
param.setType(processedType);
|
||||||
|
if (StringUtil.isNotEmpty(comment)) {
|
||||||
|
commonHandleParam(paramList, param, isRequired, comment, since, strRequired);
|
||||||
|
} else {
|
||||||
|
commonHandleParam(paramList, param, isRequired, NO_COMMENTS_FOUND, since, strRequired);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ApiParam param = ApiParam.of().setField(pre + fieldName);
|
||||||
|
JavaClass javaClass = projectBuilder.getClassByName(subTypeName);
|
||||||
|
String enumComments = javaClass.getComment();
|
||||||
|
if (StringUtil.isNotEmpty(enumComments) && javaClass.isEnum()) {
|
||||||
|
enumComments = DocUtil.replaceNewLineToHtmlBr(enumComments);
|
||||||
|
comment = comment + "(See: " + enumComments + ")";
|
||||||
|
}
|
||||||
|
String processedType = DocClassUtil.processTypeNameForParams(typeSimpleName.toLowerCase());
|
||||||
|
param.setType(processedType);
|
||||||
|
if (!isResp && javaClass.isEnum()) {
|
||||||
|
List<JavaMethod> methods = javaClass.getMethods();
|
||||||
|
int index = 0;
|
||||||
|
String reTypeName = "string";
|
||||||
|
enumOut:
|
||||||
|
for (JavaMethod method : methods) {
|
||||||
|
JavaType type = method.getReturnType();
|
||||||
|
reTypeName = type.getCanonicalName();
|
||||||
|
List<JavaAnnotation> javaAnnotationList = method.getAnnotations();
|
||||||
|
for (JavaAnnotation annotation : javaAnnotationList) {
|
||||||
|
if (annotation.getType().getSimpleName().contains("JsonValue")) {
|
||||||
|
break enumOut;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CollectionUtil.isEmpty(javaAnnotations) && index < 1) {
|
||||||
|
break enumOut;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
param.setType(DocClassUtil.processTypeNameForParams(reTypeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtil.isNotEmpty(comment)) {
|
||||||
|
commonHandleParam(paramList, param, isRequired, comment, since, strRequired);
|
||||||
|
} else {
|
||||||
|
commonHandleParam(paramList, param, isRequired, NO_COMMENTS_FOUND, since, strRequired);
|
||||||
|
}
|
||||||
|
StringBuilder preBuilder = new StringBuilder();
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
preBuilder.append(DocGlobalConstants.FIELD_SPACE);
|
||||||
|
}
|
||||||
|
preBuilder.append("└─");
|
||||||
|
if (DocClassUtil.isMap(subTypeName)) {
|
||||||
|
String gNameTemp = field.getType().getGenericCanonicalName();
|
||||||
|
if (DocClassUtil.isMap(gNameTemp)) {
|
||||||
|
ApiParam param1 = ApiParam.of().setField(preBuilder.toString() + "any object")
|
||||||
|
.setType("object").setDesc(DocGlobalConstants.ANY_OBJECT_MSG).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
paramList.add(param1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String valType = DocClassUtil.getMapKeyValueType(gNameTemp)[1];
|
||||||
|
if (!DocClassUtil.isPrimitive(valType)) {
|
||||||
|
if (valType.length() == 1) {
|
||||||
|
String gicName = (n < globGicName.length) ? globGicName[n] : globGicName[globGicName.length - 1];
|
||||||
|
if (!DocClassUtil.isPrimitive(gicName) && !simpleName.equals(gicName)) {
|
||||||
|
paramList.addAll(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
paramList.addAll(buildParams(valType, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (DocClassUtil.isCollection(subTypeName)) {
|
||||||
|
String gNameTemp = field.getType().getGenericCanonicalName();
|
||||||
|
String[] gNameArr = DocClassUtil.getSimpleGicName(gNameTemp);
|
||||||
|
if (gNameArr.length == 0) {
|
||||||
|
continue out;
|
||||||
|
}
|
||||||
|
String gName = DocClassUtil.getSimpleGicName(gNameTemp)[0];
|
||||||
|
if (!DocClassUtil.isPrimitive(gName)) {
|
||||||
|
if (!simpleName.equals(gName) && !gName.equals(simpleName)) {
|
||||||
|
if (gName.length() == 1) {
|
||||||
|
int len = globGicName.length;
|
||||||
|
if (len > 0) {
|
||||||
|
String gicName = (n < len) ? globGicName[n] : globGicName[len - 1];
|
||||||
|
if (!DocClassUtil.isPrimitive(gicName) && !simpleName.equals(gicName)) {
|
||||||
|
paramList.addAll(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
paramList.addAll(buildParams(gName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (subTypeName.length() == 1 || DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) {
|
||||||
|
if (isGenerics && DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) {
|
||||||
|
ApiParam param1 = ApiParam.of().setField(preBuilder.toString() + "any object")
|
||||||
|
.setType("object").setDesc(DocGlobalConstants.ANY_OBJECT_MSG).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
paramList.add(param1);
|
||||||
|
} else if (!simpleName.equals(className)) {
|
||||||
|
if (n < globGicName.length) {
|
||||||
|
String gicName = globGicName[n];
|
||||||
|
String simple = DocClassUtil.getSimpleName(gicName);
|
||||||
|
if (DocClassUtil.isPrimitive(simple)) {
|
||||||
|
//do nothing
|
||||||
|
} else if (gicName.contains("<")) {
|
||||||
|
if (DocClassUtil.isCollection(simple)) {
|
||||||
|
String gName = DocClassUtil.getSimpleGicName(gicName)[0];
|
||||||
|
if (!DocClassUtil.isPrimitive(gName)) {
|
||||||
|
paramList.addAll(buildParams(gName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
} else if (DocClassUtil.isMap(simple)) {
|
||||||
|
String valType = DocClassUtil.getMapKeyValueType(gicName)[1];
|
||||||
|
if (!DocClassUtil.isPrimitive(valType)) {
|
||||||
|
paramList.addAll(buildParams(valType, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
paramList.addAll(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
paramList.addAll(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
paramList.addAll(buildParams(subTypeName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
} else if (DocClassUtil.isArray(subTypeName)) {
|
||||||
|
fieldGicName = fieldGicName.substring(0, fieldGicName.indexOf("["));
|
||||||
|
if (className.equals(fieldGicName)) {
|
||||||
|
//do nothing
|
||||||
|
} else if (!DocClassUtil.isPrimitive(fieldGicName)) {
|
||||||
|
paramList.addAll(buildParams(fieldGicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
} else if (simpleName.equals(subTypeName)) {
|
||||||
|
//do nothing
|
||||||
|
} else {
|
||||||
|
if (!javaClass.isEnum()) {
|
||||||
|
paramList.addAll(buildParams(fieldGicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return paramList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ApiParam> primitiveReturnRespComment(String typeName) {
|
||||||
|
StringBuilder comments = new StringBuilder();
|
||||||
|
comments.append("The api directly returns the ").append(typeName).append(" type value.");
|
||||||
|
ApiParam apiParam = ApiParam.of().setField("No field")
|
||||||
|
.setType(typeName).setDesc(comments.toString()).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
List<ApiParam> paramList = new ArrayList<>();
|
||||||
|
paramList.add(apiParam);
|
||||||
|
return paramList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void commonHandleParam(List<ApiParam> paramList, ApiParam param, String isRequired, String comment, String since, boolean strRequired) {
|
||||||
|
if (StringUtil.isEmpty(isRequired)) {
|
||||||
|
param.setDesc(comment).setVersion(since);
|
||||||
|
paramList.add(param);
|
||||||
|
} else {
|
||||||
|
param.setDesc(comment).setVersion(since).setRequired(strRequired);
|
||||||
|
paramList.add(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.power.doc.template;
|
||||||
|
|
||||||
|
import com.power.common.util.CollectionUtil;
|
||||||
|
import com.power.common.util.StringUtil;
|
||||||
|
import com.power.doc.builder.ProjectDocConfigBuilder;
|
||||||
|
import com.power.doc.helper.ParamsBuildHelper;
|
||||||
|
import com.power.doc.model.*;
|
||||||
|
import com.power.doc.utils.DocClassUtil;
|
||||||
|
import com.power.doc.utils.DocUtil;
|
||||||
|
import com.thoughtworks.qdox.model.JavaClass;
|
||||||
|
import com.thoughtworks.qdox.model.JavaMethod;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yu 2019/12/21.
|
||||||
|
*/
|
||||||
|
public interface FrameworkDocBuildTemplate {
|
||||||
|
|
||||||
|
|
||||||
|
default String createDocRenderHeaders(List<ApiReqHeader> headers, boolean isAdoc) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
if (CollectionUtil.isEmpty(headers)) {
|
||||||
|
headers = new ArrayList<>(0);
|
||||||
|
}
|
||||||
|
for (ApiReqHeader header : headers) {
|
||||||
|
if (isAdoc) {
|
||||||
|
builder.append("|");
|
||||||
|
}
|
||||||
|
builder.append(header.getName()).append("|")
|
||||||
|
.append(header.getType()).append("|")
|
||||||
|
.append(header.getDesc()).append("|")
|
||||||
|
.append(header.isRequired()).append("|")
|
||||||
|
.append(header.getSince()).append("\n");
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
default void handleApiDoc(JavaClass cls, List<ApiDoc> apiDocList, List<ApiMethodDoc> apiMethodDocs, int order, boolean isUseMD5) {
|
||||||
|
String controllerName = cls.getName();
|
||||||
|
ApiDoc apiDoc = new ApiDoc();
|
||||||
|
apiDoc.setOrder(order);
|
||||||
|
apiDoc.setName(controllerName);
|
||||||
|
apiDoc.setAlias(controllerName);
|
||||||
|
if (isUseMD5) {
|
||||||
|
String name = DocUtil.handleId(apiDoc.getName());
|
||||||
|
apiDoc.setAlias(name);
|
||||||
|
}
|
||||||
|
apiDoc.setDesc(cls.getComment());
|
||||||
|
apiDoc.setList(apiMethodDocs);
|
||||||
|
apiDocList.add(apiDoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
default List<ApiParam> buildReturnApiParams(JavaMethod method, String controllerName, ProjectDocConfigBuilder projectBuilder) {
|
||||||
|
if ("void".equals(method.getReturnType().getFullyQualifiedName())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ApiReturn apiReturn = DocClassUtil.processReturnType(method.getReturnType().getGenericCanonicalName());
|
||||||
|
String returnType = apiReturn.getGenericCanonicalName();
|
||||||
|
String typeName = apiReturn.getSimpleName();
|
||||||
|
if (this.ignoreReturnObject(typeName)) {
|
||||||
|
throw new RuntimeException("Smart-doc can't support " + typeName + " as method return in " + controllerName);
|
||||||
|
}
|
||||||
|
if (DocClassUtil.isPrimitive(typeName)) {
|
||||||
|
return ParamsBuildHelper.primitiveReturnRespComment(DocClassUtil.processTypeNameForParams(typeName));
|
||||||
|
}
|
||||||
|
if (DocClassUtil.isCollection(typeName)) {
|
||||||
|
if (returnType.contains("<")) {
|
||||||
|
String gicName = returnType.substring(returnType.indexOf("<") + 1, returnType.lastIndexOf(">"));
|
||||||
|
if (DocClassUtil.isPrimitive(gicName)) {
|
||||||
|
return ParamsBuildHelper.primitiveReturnRespComment("array of " + DocClassUtil.processTypeNameForParams(gicName));
|
||||||
|
}
|
||||||
|
return ParamsBuildHelper.buildParams(gicName, "", 0, null, projectBuilder.getCustomRespFieldMap(), true, new HashMap<>(), projectBuilder);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (DocClassUtil.isMap(typeName)) {
|
||||||
|
String[] keyValue = DocClassUtil.getMapKeyValueType(returnType);
|
||||||
|
if (keyValue.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (DocClassUtil.isPrimitive(keyValue[1])) {
|
||||||
|
return ParamsBuildHelper.primitiveReturnRespComment("key value");
|
||||||
|
}
|
||||||
|
return ParamsBuildHelper.buildParams(keyValue[1], "", 0, null, projectBuilder.getCustomRespFieldMap(), true, new HashMap<>(), projectBuilder);
|
||||||
|
}
|
||||||
|
if (StringUtil.isNotEmpty(returnType)) {
|
||||||
|
return ParamsBuildHelper.buildParams(returnType, "", 0, null, projectBuilder.getCustomRespFieldMap(), true, new HashMap<>(), projectBuilder);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ApiDoc> getApiData(ProjectDocConfigBuilder projectBuilder);
|
||||||
|
|
||||||
|
|
||||||
|
boolean ignoreReturnObject(String typeName);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,420 @@
|
||||||
|
package com.power.doc.template;
|
||||||
|
|
||||||
|
import com.power.common.util.JsonFormatUtil;
|
||||||
|
import com.power.common.util.StringUtil;
|
||||||
|
import com.power.common.util.UrlUtil;
|
||||||
|
import com.power.doc.builder.ProjectDocConfigBuilder;
|
||||||
|
import com.power.doc.constants.*;
|
||||||
|
import com.power.doc.helper.JsonBuildHelper;
|
||||||
|
import com.power.doc.helper.ParamsBuildHelper;
|
||||||
|
import com.power.doc.model.*;
|
||||||
|
import com.power.doc.utils.DocClassUtil;
|
||||||
|
import com.power.doc.utils.DocUrlUtil;
|
||||||
|
import com.power.doc.utils.DocUtil;
|
||||||
|
import com.thoughtworks.qdox.model.JavaAnnotation;
|
||||||
|
import com.thoughtworks.qdox.model.JavaClass;
|
||||||
|
import com.thoughtworks.qdox.model.JavaMethod;
|
||||||
|
import com.thoughtworks.qdox.model.JavaParameter;
|
||||||
|
import com.thoughtworks.qdox.model.expression.AnnotationValue;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.power.doc.constants.DocGlobalConstants.NO_COMMENTS_FOUND;
|
||||||
|
import static com.power.doc.constants.DocTags.IGNORE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yu 2019/12/21.
|
||||||
|
*/
|
||||||
|
public class SpringBootDocBuildTemplate implements FrameworkDocBuildTemplate {
|
||||||
|
|
||||||
|
private List<ApiReqHeader> headers;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ApiDoc> getApiData(ProjectDocConfigBuilder projectBuilder) {
|
||||||
|
ApiConfig apiConfig = projectBuilder.getApiConfig();
|
||||||
|
this.headers = apiConfig.getRequestHeaders();
|
||||||
|
List<ApiDoc> apiDocList = new ArrayList<>();
|
||||||
|
int order = 0;
|
||||||
|
for (JavaClass cls : projectBuilder.getJavaProjectBuilder().getClasses()) {
|
||||||
|
if (checkController(cls)) {
|
||||||
|
if (StringUtil.isNotEmpty(apiConfig.getPackageFilters())) {
|
||||||
|
if (DocUtil.isMatch(apiConfig.getPackageFilters(), cls.getCanonicalName())) {
|
||||||
|
order++;
|
||||||
|
List<ApiMethodDoc> apiMethodDocs = buildControllerMethod(cls,apiConfig,projectBuilder);
|
||||||
|
this.handleApiDoc(cls, apiDocList, apiMethodDocs,order,apiConfig.isMd5EncryptedHtmlName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
order++;
|
||||||
|
List<ApiMethodDoc> apiMethodDocs = buildControllerMethod(cls,apiConfig,projectBuilder);
|
||||||
|
this.handleApiDoc(cls, apiDocList, apiMethodDocs,order,apiConfig.isMd5EncryptedHtmlName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return apiDocList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean ignoreReturnObject(String typeName) {
|
||||||
|
if (DocClassUtil.isMvcIgnoreParams(typeName)) {
|
||||||
|
if (DocGlobalConstants.MODE_AND_VIEW_FULLY.equals(typeName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ApiMethodDoc> buildControllerMethod(final JavaClass cls,ApiConfig apiConfig,ProjectDocConfigBuilder projectBuilder) {
|
||||||
|
String clazName = cls.getCanonicalName();
|
||||||
|
List<JavaAnnotation> classAnnotations = cls.getAnnotations();
|
||||||
|
String baseUrl = "";
|
||||||
|
for (JavaAnnotation annotation : classAnnotations) {
|
||||||
|
String annotationName = annotation.getType().getName();
|
||||||
|
if (DocAnnotationConstants.REQUEST_MAPPING.equals(annotationName) || DocGlobalConstants.REQUEST_MAPPING_FULLY.equals(annotationName)) {
|
||||||
|
baseUrl = StringUtil.removeQuotes(annotation.getNamedParameter("value").toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<JavaMethod> methods = cls.getMethods();
|
||||||
|
List<ApiMethodDoc> methodDocList = new ArrayList<>(methods.size());
|
||||||
|
int methodOrder = 0;
|
||||||
|
for (JavaMethod method : methods) {
|
||||||
|
List<ApiReqHeader> apiReqHeaders = new ArrayList<>();
|
||||||
|
if (method.getModifiers().contains("private")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (StringUtil.isEmpty(method.getComment()) && apiConfig.isStrict()) {
|
||||||
|
throw new RuntimeException("Unable to find comment for method " + method.getName() + " in " + cls.getCanonicalName());
|
||||||
|
}
|
||||||
|
methodOrder++;
|
||||||
|
ApiMethodDoc apiMethodDoc = new ApiMethodDoc();
|
||||||
|
apiMethodDoc.setOrder(methodOrder);
|
||||||
|
apiMethodDoc.setDesc(method.getComment());
|
||||||
|
apiMethodDoc.setName(method.getName());
|
||||||
|
String methodUid = DocUtil.handleId(clazName + method.getName()) ;
|
||||||
|
apiMethodDoc.setMethodId(methodUid);
|
||||||
|
String apiNoteValue = DocUtil.getNormalTagComments(method, DocTags.API_NOTE, cls.getName());
|
||||||
|
if (StringUtil.isEmpty(apiNoteValue)) {
|
||||||
|
apiNoteValue = method.getComment();
|
||||||
|
}
|
||||||
|
String authorValue = DocUtil.getNormalTagComments(method, DocTags.AUTHOR, cls.getName());
|
||||||
|
if (apiConfig.isShowAuthor() && StringUtil.isNotEmpty(authorValue)) {
|
||||||
|
apiMethodDoc.setAuthor(authorValue);
|
||||||
|
}
|
||||||
|
apiMethodDoc.setDetail(apiNoteValue);
|
||||||
|
List<JavaAnnotation> annotations = method.getAnnotations();
|
||||||
|
String url = null;
|
||||||
|
String methodType = null;
|
||||||
|
boolean isPostMethod = false;
|
||||||
|
int methodCounter = 0;
|
||||||
|
for (JavaAnnotation annotation : annotations) {
|
||||||
|
String annotationName = annotation.getType().getName();
|
||||||
|
if (SpringMvcAnnotations.REQUEST_MAPPING.equals(annotationName) || DocGlobalConstants.REQUEST_MAPPING_FULLY.equals(annotationName)) {
|
||||||
|
url = DocUtil.handleMappingValue(annotation);
|
||||||
|
Object nameParam = annotation.getNamedParameter("method");
|
||||||
|
if (null != nameParam) {
|
||||||
|
methodType = nameParam.toString();
|
||||||
|
methodType = DocUtil.handleHttpMethod(methodType);
|
||||||
|
if ("POST".equals(methodType) || "PUT".equals(methodType)) {
|
||||||
|
isPostMethod = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
methodType = Methods.GET.getValue();
|
||||||
|
}
|
||||||
|
methodCounter++;
|
||||||
|
} else if (SpringMvcAnnotations.GET_MAPPING.equals(annotationName) || DocGlobalConstants.GET_MAPPING_FULLY.equals(annotationName)) {
|
||||||
|
url = DocUtil.handleMappingValue(annotation);
|
||||||
|
methodType = Methods.GET.getValue();
|
||||||
|
methodCounter++;
|
||||||
|
} else if (SpringMvcAnnotations.POST_MAPPING.equals(annotationName) || DocGlobalConstants.POST_MAPPING_FULLY.equals(annotationName)) {
|
||||||
|
url = DocUtil.handleMappingValue(annotation);
|
||||||
|
methodType = Methods.POST.getValue();
|
||||||
|
methodCounter++;
|
||||||
|
isPostMethod = true;
|
||||||
|
} else if (SpringMvcAnnotations.PUT_MAPPING.equals(annotationName) || DocGlobalConstants.PUT_MAPPING_FULLY.equals(annotationName)) {
|
||||||
|
url = DocUtil.handleMappingValue(annotation);
|
||||||
|
methodType = Methods.PUT.getValue();
|
||||||
|
methodCounter++;
|
||||||
|
} else if (SpringMvcAnnotations.DELETE_MAPPING.equals(annotationName) || DocGlobalConstants.DELETE_MAPPING_FULLY.equals(annotationName)) {
|
||||||
|
url = DocUtil.handleMappingValue(annotation);
|
||||||
|
methodType = Methods.DELETE.getValue();
|
||||||
|
methodCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (JavaParameter javaParameter : method.getParameters()) {
|
||||||
|
List<JavaAnnotation> javaAnnotations = javaParameter.getAnnotations();
|
||||||
|
String className = method.getDeclaringClass().getCanonicalName();
|
||||||
|
Map<String, String> paramMap = DocUtil.getParamsComments(method, DocTags.PARAM, className);
|
||||||
|
String paramName = javaParameter.getName();
|
||||||
|
ApiReqHeader apiReqHeader;
|
||||||
|
for (JavaAnnotation annotation : javaAnnotations) {
|
||||||
|
String annotationName = annotation.getType().getName();
|
||||||
|
if (SpringMvcAnnotations.REQUEST_HERDER.equals(annotationName)) {
|
||||||
|
apiReqHeader = new ApiReqHeader();
|
||||||
|
Map<String, Object> requestHeaderMap = annotation.getNamedParameterMap();
|
||||||
|
if (requestHeaderMap.get(DocAnnotationConstants.VALUE_PROP) != null) {
|
||||||
|
apiReqHeader.setName(StringUtil.removeQuotes((String) requestHeaderMap.get(DocAnnotationConstants.VALUE_PROP)));
|
||||||
|
} else {
|
||||||
|
apiReqHeader.setName(paramName);
|
||||||
|
}
|
||||||
|
StringBuilder desc = new StringBuilder();
|
||||||
|
String comments = paramMap.get(paramName);
|
||||||
|
desc.append(comments);
|
||||||
|
|
||||||
|
if (requestHeaderMap.get(DocAnnotationConstants.DEFAULT_VALUE_PROP) != null) {
|
||||||
|
desc.append("(defaultValue: ")
|
||||||
|
.append(StringUtil.removeQuotes((String) requestHeaderMap.get(DocAnnotationConstants.DEFAULT_VALUE_PROP)))
|
||||||
|
.append(")");
|
||||||
|
}
|
||||||
|
apiReqHeader.setDesc(desc.toString());
|
||||||
|
if (requestHeaderMap.get(DocAnnotationConstants.REQUIRED_PROP) != null) {
|
||||||
|
apiReqHeader.setRequired(!Boolean.FALSE.toString().equals(requestHeaderMap.get(DocAnnotationConstants.REQUIRED_PROP)));
|
||||||
|
} else {
|
||||||
|
apiReqHeader.setRequired(true);
|
||||||
|
}
|
||||||
|
String typeName = javaParameter.getType().getValue().toLowerCase();
|
||||||
|
apiReqHeader.setType(DocClassUtil.processTypeNameForParams(typeName));
|
||||||
|
apiReqHeaders.add(apiReqHeader);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
apiMethodDoc.setRequestHeaders(apiReqHeaders);
|
||||||
|
if (methodCounter > 0) {
|
||||||
|
// if ("void".equals(method.getReturnType().getFullyQualifiedName())) {
|
||||||
|
// throw new RuntimeException(method.getName() + " method in " + cls.getCanonicalName() + " can't be return type 'void'");
|
||||||
|
// }
|
||||||
|
if (null != method.getTagByName(IGNORE)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
url = StringUtil.removeQuotes(url);
|
||||||
|
|
||||||
|
String[] urls = url.split(",");
|
||||||
|
if (urls.length > 1) {
|
||||||
|
url = DocUrlUtil.getMvcUrls(projectBuilder.getServerUrl(),baseUrl, Arrays.asList(urls));
|
||||||
|
} else {
|
||||||
|
url = UrlUtil.simplifyUrl(projectBuilder.getServerUrl() + "/" + baseUrl + "/" + url);
|
||||||
|
}
|
||||||
|
apiMethodDoc.setType(methodType);
|
||||||
|
apiMethodDoc.setUrl(url);
|
||||||
|
List<ApiParam> requestParams = requestParams(method, DocTags.PARAM, cls.getCanonicalName(),projectBuilder);
|
||||||
|
apiMethodDoc.setRequestParams(requestParams);
|
||||||
|
String requestJson = buildReqJson(method,apiMethodDoc,isPostMethod);
|
||||||
|
if (StringUtil.isNotEmpty(requestJson) && !requestJson.startsWith("http")) {
|
||||||
|
requestJson = JsonFormatUtil.formatJson(requestJson);
|
||||||
|
}
|
||||||
|
apiMethodDoc.setRequestUsage(requestJson);
|
||||||
|
|
||||||
|
apiMethodDoc.setResponseUsage(JsonBuildHelper.buildReturnJson(method,projectBuilder));
|
||||||
|
List<ApiParam> responseParams = buildReturnApiParams(method, cls.getGenericFullyQualifiedName(),projectBuilder);
|
||||||
|
apiMethodDoc.setResponseParams(responseParams);
|
||||||
|
|
||||||
|
List<ApiReqHeader> allApiReqHeaders;
|
||||||
|
if (this.headers != null) {
|
||||||
|
allApiReqHeaders = Stream.of(this.headers, apiReqHeaders)
|
||||||
|
.flatMap(Collection::stream)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
allApiReqHeaders = apiReqHeaders;
|
||||||
|
}
|
||||||
|
//reduce create in template
|
||||||
|
apiMethodDoc.setHeaders(this.createDocRenderHeaders(allApiReqHeaders, apiConfig.isAdoc()));
|
||||||
|
apiMethodDoc.setRequestHeaders(allApiReqHeaders);
|
||||||
|
methodDocList.add(apiMethodDoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return methodDocList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String buildReqJson(JavaMethod method, ApiMethodDoc apiMethodDoc, Boolean isPostMethod){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get tag
|
||||||
|
*
|
||||||
|
* @param javaMethod The JavaMethod method
|
||||||
|
* @param tagName The doc tag name
|
||||||
|
* @param className The class name
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
private List<ApiParam> requestParams(final JavaMethod javaMethod, final String tagName, final String className,ProjectDocConfigBuilder builder) {
|
||||||
|
boolean isStrict = builder.getApiConfig().isStrict();
|
||||||
|
Map<String, CustomRespField> responseFieldMap = new HashMap<>();
|
||||||
|
Map<String, String> paramTagMap = DocUtil.getParamsComments(javaMethod, tagName, className);
|
||||||
|
List<JavaParameter> parameterList = javaMethod.getParameters();
|
||||||
|
if (parameterList.size() < 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<ApiParam> paramList = new ArrayList<>();
|
||||||
|
int requestBodyCounter = 0;
|
||||||
|
List<ApiParam> reqBodyParamsList = new ArrayList<>();
|
||||||
|
out:
|
||||||
|
for (JavaParameter parameter : parameterList) {
|
||||||
|
boolean paramAdded = false;
|
||||||
|
String paramName = parameter.getName();
|
||||||
|
String typeName = parameter.getType().getGenericCanonicalName();
|
||||||
|
String simpleName = parameter.getType().getValue().toLowerCase();
|
||||||
|
String fullTypeName = parameter.getType().getFullyQualifiedName();
|
||||||
|
JavaClass javaClass = builder.getClassByName(fullTypeName);
|
||||||
|
if (!DocClassUtil.isMvcIgnoreParams(typeName)) {
|
||||||
|
if (!paramTagMap.containsKey(paramName) && DocClassUtil.isPrimitive(fullTypeName) && isStrict) {
|
||||||
|
throw new RuntimeException("ERROR: Unable to find javadoc @param for actual param \""
|
||||||
|
+ paramName + "\" in method " + javaMethod.getName() + " from " + className);
|
||||||
|
}
|
||||||
|
String comment = paramTagMap.get(paramName);
|
||||||
|
if (StringUtil.isEmpty(comment)) {
|
||||||
|
comment = NO_COMMENTS_FOUND;
|
||||||
|
}
|
||||||
|
List<JavaAnnotation> annotations = parameter.getAnnotations();
|
||||||
|
if (annotations.size() == 0) {
|
||||||
|
//default set required is true
|
||||||
|
if (DocClassUtil.isCollection(fullTypeName) || DocClassUtil.isArray(fullTypeName)) {
|
||||||
|
String[] gicNameArr = DocClassUtil.getSimpleGicName(typeName);
|
||||||
|
String gicName = gicNameArr[0];
|
||||||
|
if (DocClassUtil.isArray(gicName)) {
|
||||||
|
gicName = gicName.substring(0, gicName.indexOf("["));
|
||||||
|
}
|
||||||
|
String typeTemp = "";
|
||||||
|
if (DocClassUtil.isPrimitive(gicName)) {
|
||||||
|
typeTemp = " of " + DocClassUtil.processTypeNameForParams(gicName);
|
||||||
|
ApiParam param = ApiParam.of().setField(paramName)
|
||||||
|
.setType(DocClassUtil.processTypeNameForParams(simpleName) + typeTemp)
|
||||||
|
.setDesc(comment).setRequired(true).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
paramList.add(param);
|
||||||
|
} else {
|
||||||
|
ApiParam param = ApiParam.of().setField(paramName)
|
||||||
|
.setType(DocClassUtil.processTypeNameForParams(simpleName) + typeTemp)
|
||||||
|
.setDesc(comment).setRequired(true).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
paramList.add(param);
|
||||||
|
paramList.addAll(ParamsBuildHelper.buildParams(gicNameArr[0], "└─", 1, "true", responseFieldMap, false, new HashMap<>(),builder));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (DocClassUtil.isPrimitive(simpleName)) {
|
||||||
|
ApiParam param = ApiParam.of().setField(paramName)
|
||||||
|
.setType(DocClassUtil.processTypeNameForParams(simpleName))
|
||||||
|
.setDesc(comment).setRequired(true).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
paramList.add(param);
|
||||||
|
} else if (DocGlobalConstants.JAVA_MAP_FULLY.equals(typeName)) {
|
||||||
|
ApiParam param = ApiParam.of().setField(paramName)
|
||||||
|
.setType("map").setDesc(comment).setRequired(true).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
paramList.add(param);
|
||||||
|
} else if (javaClass.isEnum()) {
|
||||||
|
ApiParam param = ApiParam.of().setField(paramName)
|
||||||
|
.setType("string").setDesc(comment).setRequired(true).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
paramList.add(param);
|
||||||
|
} else {
|
||||||
|
paramList.addAll(ParamsBuildHelper.buildParams(fullTypeName, "", 0, "true", responseFieldMap, false, new HashMap<>(),builder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (JavaAnnotation annotation : annotations) {
|
||||||
|
String required = "true";
|
||||||
|
AnnotationValue annotationRequired = annotation.getProperty(DocAnnotationConstants.REQUIRED_PROP);
|
||||||
|
if (null != annotationRequired) {
|
||||||
|
required = annotationRequired.toString();
|
||||||
|
}
|
||||||
|
String annotationName = annotation.getType().getName();
|
||||||
|
if (SpringMvcAnnotations.REQUEST_BODY.equals(annotationName) || (ValidatorAnnotations.VALID.equals(annotationName) && annotations.size() == 1)) {
|
||||||
|
if (requestBodyCounter > 0) {
|
||||||
|
throw new RuntimeException("You have use @RequestBody Passing multiple variables for method "
|
||||||
|
+ javaMethod.getName() + " in " + className + ",@RequestBody annotation could only bind one variables.");
|
||||||
|
}
|
||||||
|
if (DocClassUtil.isPrimitive(fullTypeName)) {
|
||||||
|
ApiParam bodyParam = ApiParam.of()
|
||||||
|
.setField(paramName).setType(DocClassUtil.processTypeNameForParams(simpleName))
|
||||||
|
.setDesc(comment).setRequired(Boolean.valueOf(required));
|
||||||
|
reqBodyParamsList.add(bodyParam);
|
||||||
|
} else {
|
||||||
|
if (DocClassUtil.isCollection(fullTypeName) || DocClassUtil.isArray(fullTypeName)) {
|
||||||
|
String[] gicNameArr = DocClassUtil.getSimpleGicName(typeName);
|
||||||
|
String gicName = gicNameArr[0];
|
||||||
|
if (DocClassUtil.isArray(gicName)) {
|
||||||
|
gicName = gicName.substring(0, gicName.indexOf("["));
|
||||||
|
}
|
||||||
|
if (DocClassUtil.isPrimitive(gicName)) {
|
||||||
|
ApiParam bodyParam = ApiParam.of()
|
||||||
|
.setField(paramName).setType(DocClassUtil.processTypeNameForParams(simpleName))
|
||||||
|
.setDesc(comment).setRequired(Boolean.valueOf(required)).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
reqBodyParamsList.add(bodyParam);
|
||||||
|
} else {
|
||||||
|
reqBodyParamsList.addAll(ParamsBuildHelper.buildParams(gicNameArr[0], "", 0, "true", responseFieldMap, false, new HashMap<>(),builder));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (DocClassUtil.isMap(fullTypeName)) {
|
||||||
|
if (DocGlobalConstants.JAVA_MAP_FULLY.equals(typeName)) {
|
||||||
|
ApiParam apiParam = ApiParam.of().setField(paramName).setType("map")
|
||||||
|
.setDesc(comment).setRequired(Boolean.valueOf(required)).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
paramList.add(apiParam);
|
||||||
|
continue out;
|
||||||
|
}
|
||||||
|
String[] gicNameArr = DocClassUtil.getSimpleGicName(typeName);
|
||||||
|
reqBodyParamsList.addAll(ParamsBuildHelper.buildParams(gicNameArr[1], "", 0, "true", responseFieldMap, false, new HashMap<>(),builder));
|
||||||
|
} else {
|
||||||
|
reqBodyParamsList.addAll(ParamsBuildHelper.buildParams(typeName, "", 0, "true", responseFieldMap, false, new HashMap<>(),builder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requestBodyCounter++;
|
||||||
|
} else {
|
||||||
|
if (paramAdded) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
List<String> validatorAnnotations = DocValidatorAnnotationEnum.listValidatorAnnotations();
|
||||||
|
if (SpringMvcAnnotations.REQUEST_PARAM.equals(annotationName) ||
|
||||||
|
DocAnnotationConstants.SHORT_PATH_VARIABLE.equals(annotationName)) {
|
||||||
|
AnnotationValue annotationValue = annotation.getProperty(DocAnnotationConstants.VALUE_PROP);
|
||||||
|
if (null != annotationValue) {
|
||||||
|
paramName = StringUtil.removeQuotes(annotationValue.toString());
|
||||||
|
}
|
||||||
|
AnnotationValue annotationOfName = annotation.getProperty(DocAnnotationConstants.NAME_PROP);
|
||||||
|
if (null != annotationOfName) {
|
||||||
|
paramName = StringUtil.removeQuotes(annotationOfName.toString());
|
||||||
|
}
|
||||||
|
ApiParam param = ApiParam.of().setField(paramName)
|
||||||
|
.setType(DocClassUtil.processTypeNameForParams(simpleName))
|
||||||
|
.setDesc(comment).setRequired(Boolean.valueOf(required)).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
paramList.add(param);
|
||||||
|
paramAdded = true;
|
||||||
|
} else if (validatorAnnotations.contains(annotationName)) {
|
||||||
|
ApiParam param = ApiParam.of().setField(paramName)
|
||||||
|
.setType(DocClassUtil.processTypeNameForParams(simpleName))
|
||||||
|
.setDesc(comment).setRequired(Boolean.valueOf(required)).setVersion(DocGlobalConstants.DEFAULT_VERSION);
|
||||||
|
paramList.add(param);
|
||||||
|
paramAdded = true;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (requestBodyCounter > 0) {
|
||||||
|
paramList.addAll(reqBodyParamsList);
|
||||||
|
return paramList;
|
||||||
|
}
|
||||||
|
return paramList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check controller
|
||||||
|
*
|
||||||
|
* @param cls
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean checkController(JavaClass cls) {
|
||||||
|
List<JavaAnnotation> classAnnotations = cls.getAnnotations();
|
||||||
|
for (JavaAnnotation annotation : classAnnotations) {
|
||||||
|
String annotationName = annotation.getType().getName();
|
||||||
|
if (DocAnnotationConstants.SHORT_CONTROLLER.equals(annotationName)
|
||||||
|
|| DocAnnotationConstants.SHORT_REST_CONTROLLER.equals(annotationName)
|
||||||
|
|| DocGlobalConstants.REST_CONTROLLER_FULLY.equals(annotationName)
|
||||||
|
|| DocGlobalConstants.CONTROLLER_FULLY.equals(annotationName)
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.power.doc.utils;
|
||||||
|
|
||||||
|
import com.power.common.util.StringUtil;
|
||||||
|
import com.power.common.util.UrlUtil;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yu 2019/12/22.
|
||||||
|
*/
|
||||||
|
public class DocUrlUtil {
|
||||||
|
|
||||||
|
public static String getMvcUrls(String baseServer, String baseUrl, List<String> urls) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int size = urls.size();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
String url = baseServer + "/" + baseUrl + "/" + StringUtil.trimBlank(urls.get(i))
|
||||||
|
.replace("[", "").replace("]", "");
|
||||||
|
sb.append(UrlUtil.simplifyUrl(url));
|
||||||
|
if (i < size - 1) {
|
||||||
|
sb.append(";\t");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.power.doc.utils;
|
||||||
|
|
||||||
|
import com.thoughtworks.qdox.model.JavaClass;
|
||||||
|
import com.thoughtworks.qdox.model.JavaField;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle JavaClass
|
||||||
|
* @author yu 2019/12/21.
|
||||||
|
*/
|
||||||
|
public class JavaClassUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get fields
|
||||||
|
*
|
||||||
|
* @param cls1 The JavaClass object
|
||||||
|
* @param i Recursive counter
|
||||||
|
* @return list of JavaField
|
||||||
|
*/
|
||||||
|
public static List<JavaField> getFields(JavaClass cls1, int i) {
|
||||||
|
List<JavaField> fieldList = new ArrayList<>();
|
||||||
|
if (null == cls1) {
|
||||||
|
return fieldList;
|
||||||
|
} else if ("Object".equals(cls1.getSimpleName()) || "Timestamp".equals(cls1.getSimpleName()) ||
|
||||||
|
"Date".equals(cls1.getSimpleName()) || "Locale".equals(cls1.getSimpleName())) {
|
||||||
|
return fieldList;
|
||||||
|
} else {
|
||||||
|
JavaClass pcls = cls1.getSuperJavaClass();
|
||||||
|
fieldList.addAll(getFields(pcls, i));
|
||||||
|
fieldList.addAll(cls1.getFields());
|
||||||
|
}
|
||||||
|
return fieldList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get enum value
|
||||||
|
* @param javaClass enum class
|
||||||
|
* @param returnEnum is return method
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Object getEnumValue(JavaClass javaClass, boolean returnEnum) {
|
||||||
|
List<JavaField> javaFields = javaClass.getEnumConstants();
|
||||||
|
Object value = null;
|
||||||
|
int index = 0;
|
||||||
|
for (JavaField javaField : javaFields) {
|
||||||
|
String simpleName = javaField.getType().getSimpleName();
|
||||||
|
StringBuilder valueBuilder = new StringBuilder();
|
||||||
|
valueBuilder.append("\"").append(javaField.getName()).append("\"").toString();
|
||||||
|
if (returnEnum) {
|
||||||
|
value = valueBuilder.toString();
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (!DocClassUtil.isPrimitive(simpleName) && index < 1) {
|
||||||
|
if (null != javaField.getEnumConstantArguments()) {
|
||||||
|
value = javaField.getEnumConstantArguments().get(0);
|
||||||
|
} else {
|
||||||
|
value = valueBuilder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.power.doc.utils;
|
||||||
|
|
||||||
|
import com.thoughtworks.qdox.model.JavaField;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yu 2019/12/21.
|
||||||
|
*/
|
||||||
|
public class JavaFieldUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param fields
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean checkGenerics(List<JavaField> fields) {
|
||||||
|
checkGenerics:
|
||||||
|
for (JavaField field : fields) {
|
||||||
|
if (field.getType().getFullyQualifiedName().length() == 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ public class DocClassUtilTest {
|
||||||
@Test
|
@Test
|
||||||
public void testProcessReturnType() {
|
public void testProcessReturnType() {
|
||||||
String typeName = "org.springframework.web.context.request.async.WebAsyncTask";
|
String typeName = "org.springframework.web.context.request.async.WebAsyncTask";
|
||||||
|
System.out.println(typeName.hashCode());
|
||||||
ApiReturn apiReturn = DocClassUtil.processReturnType(typeName);
|
ApiReturn apiReturn = DocClassUtil.processReturnType(typeName);
|
||||||
System.out.println(apiReturn.getGenericCanonicalName());
|
System.out.println(apiReturn.getGenericCanonicalName());
|
||||||
System.out.println(apiReturn.getSimpleName());
|
System.out.println(apiReturn.getSimpleName());
|
||||||
|
|
Loading…
Reference in New Issue