merge to master

# Conflicts:
#	src/main/java/com/power/doc/utils/DocClassUtil.java
This commit is contained in:
oppofind 2019-12-21 15:36:51 +08:00
commit 9cff66e84c
8 changed files with 185 additions and 114 deletions

View File

@ -4,7 +4,6 @@ package com.power.doc.builder;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.power.common.util.FileUtil; import com.power.common.util.FileUtil;
import com.power.common.util.ValidateUtil;
import com.power.doc.constants.DocGlobalConstants; import com.power.doc.constants.DocGlobalConstants;
import com.power.doc.model.ApiConfig; import com.power.doc.model.ApiConfig;
import com.power.doc.model.ApiDoc; import com.power.doc.model.ApiDoc;
@ -17,6 +16,7 @@ import com.power.doc.model.postman.request.RequestBean;
import com.power.doc.model.postman.request.body.BodyBean; import com.power.doc.model.postman.request.body.BodyBean;
import com.power.doc.model.postman.request.header.HeaderBean; import com.power.doc.model.postman.request.header.HeaderBean;
import com.thoughtworks.qdox.JavaProjectBuilder; import com.thoughtworks.qdox.JavaProjectBuilder;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -36,7 +36,7 @@ public class PostmanJsonBuilder {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate(); DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config); builderTemplate.checkAndInit(config);
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder(); JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
SourceBuilder sourceBuilder = new SourceBuilder(config,javaProjectBuilder); SourceBuilder sourceBuilder = new SourceBuilder(config, javaProjectBuilder);
List<ApiDoc> apiDocList = sourceBuilder.getControllerApiData(); List<ApiDoc> apiDocList = sourceBuilder.getControllerApiData();
RequestItem requestItem = new RequestItem(); RequestItem requestItem = new RequestItem();
@ -97,7 +97,8 @@ public class PostmanJsonBuilder {
if (apiMethodDoc.getType().equals(DocGlobalConstants.HTTP_POST)) { if (apiMethodDoc.getType().equals(DocGlobalConstants.HTTP_POST)) {
requestBean.setBody(buildBodyBean(apiMethodDoc)); requestBean.setBody(buildBodyBean(apiMethodDoc));
} else { } else {
if (!ValidateUtil.isNotUrl(apiMethodDoc.getRequestUsage())) { if (StringUtils.isNotBlank(apiMethodDoc.getRequestUsage()) &&
apiMethodDoc.getRequestUsage().startsWith("http")) {
requestBean.setUrl(apiMethodDoc.getRequestUsage()); requestBean.setUrl(apiMethodDoc.getRequestUsage());
} }
} }

View File

@ -285,7 +285,10 @@ public class SourceBuilder {
List<ApiParam> requestParams = requestParams(method, DocTags.PARAM, cls.getCanonicalName()); List<ApiParam> requestParams = requestParams(method, DocTags.PARAM, cls.getCanonicalName());
apiMethodDoc.setRequestParams(requestParams); apiMethodDoc.setRequestParams(requestParams);
String requestJson = buildReqJson(method, apiMethodDoc, isPostMethod); String requestJson = buildReqJson(method, apiMethodDoc, isPostMethod);
apiMethodDoc.setRequestUsage(JsonFormatUtil.formatJson(requestJson)); if (StringUtil.isNotEmpty(requestJson) && !requestJson.startsWith("http")) {
requestJson = JsonFormatUtil.formatJson(requestJson);
}
apiMethodDoc.setRequestUsage(requestJson);
apiMethodDoc.setResponseUsage(buildReturnJson(method, this.fieldMap)); apiMethodDoc.setResponseUsage(buildReturnJson(method, this.fieldMap));
List<ApiParam> responseParams = buildReturnApiParams(method, cls.getGenericFullyQualifiedName()); List<ApiParam> responseParams = buildReturnApiParams(method, cls.getGenericFullyQualifiedName());
@ -491,22 +494,18 @@ public class SourceBuilder {
String fieldGicName = field.getType().getGenericCanonicalName(); String fieldGicName = field.getType().getGenericCanonicalName();
List<JavaAnnotation> javaAnnotations = field.getAnnotations(); List<JavaAnnotation> javaAnnotations = field.getAnnotations();
List<DocletTag> paramTags = field.getTags(); Map<String, String> tagsMap = DocUtil.getFieldTagsValue(field);
String since = DocGlobalConstants.DEFAULT_VERSION;//since tag value String since = DocGlobalConstants.DEFAULT_VERSION;//since tag value
if (!isResp) { if (!isResp) {
pre: pre:
for (DocletTag docletTag : paramTags) { if (tagsMap.containsKey(DocTags.IGNORE)) {
if (DocClassUtil.isIgnoreTag(docletTag.getName())) { continue out;
continue out; } else if (tagsMap.containsKey(DocTags.SINCE)) {
} else if (DocTags.SINCE.equals(docletTag.getName())) { since = tagsMap.get(DocTags.SINCE);
since = docletTag.getValue();
}
} }
} else { } else {
for (DocletTag docletTag : paramTags) { if (tagsMap.containsKey(DocTags.SINCE)) {
if (DocTags.SINCE.equals(docletTag.getName())) { since = tagsMap.get(DocTags.SINCE);
since = docletTag.getValue();
}
} }
} }
@ -537,11 +536,9 @@ public class SourceBuilder {
} }
if (annotationCounter < 1) { if (annotationCounter < 1) {
doc: doc:
for (DocletTag docletTag : paramTags) { if (tagsMap.containsKey(DocTags.REQUIRED)) {
if (DocClassUtil.isRequiredTag(docletTag.getName())) { strRequired = true;
strRequired = true; break doc;
break doc;
}
} }
} }
//cover comment //cover comment
@ -824,13 +821,10 @@ public class SourceBuilder {
DocClassUtil.isIgnoreFieldTypes(subTypeName)) { DocClassUtil.isIgnoreFieldTypes(subTypeName)) {
continue; continue;
} }
List<DocletTag> paramTags = field.getTags(); Map<String, String> tagsMap = DocUtil.getFieldTagsValue(field);
if (!isResp) { if (!isResp) {
pre: if (tagsMap.containsKey(DocTags.IGNORE)) {
for (DocletTag docletTag : paramTags) { continue out;
if (DocClassUtil.isIgnoreTag(docletTag.getName())) {
continue out;
}
} }
} }
List<JavaAnnotation> annotations = field.getAnnotations(); List<JavaAnnotation> annotations = field.getAnnotations();
@ -857,20 +851,29 @@ public class SourceBuilder {
String fieldGicName = field.getType().getGenericCanonicalName(); String fieldGicName = field.getType().getGenericCanonicalName();
data0.append("\"").append(fieldName).append("\":"); data0.append("\"").append(fieldName).append("\":");
if (DocClassUtil.isPrimitive(subTypeName)) { 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 = responseFieldMap.get(fieldName); CustomRespField customResponseField = responseFieldMap.get(fieldName);
if (null != customResponseField) { if (null != customResponseField) {
Object val = customResponseField.getValue(); Object val = customResponseField.getValue();
if (null != val) { if (null != val) {
if ("String".equals(typeSimpleName)) { if ("String".equals(typeSimpleName)) {
data0.append("\"").append(val).append("\","); data0.append(DocUtil.handleJsonStr(String.valueOf(val))).append(",");
} else { } else {
data0.append(val).append(","); data0.append(val).append(",");
} }
} else { } else {
data0.append(DocUtil.getValByTypeAndFieldName(typeSimpleName, field.getName())).append(","); data0.append(fieldValue).append(",");
} }
} else { } else {
data0.append(DocUtil.getValByTypeAndFieldName(typeSimpleName, field.getName())).append(","); data0.append(fieldValue).append(",");
} }
} else { } else {
if (DocClassUtil.isCollection(subTypeName) || DocClassUtil.isArray(subTypeName)) { if (DocClassUtil.isCollection(subTypeName) || DocClassUtil.isArray(subTypeName)) {
@ -991,6 +994,8 @@ 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);
List<String> springMvcRequestAnnotations = SpringMvcRequestAnnotations.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();
@ -998,85 +1003,98 @@ public class SourceBuilder {
String typeName = javaType.getFullyQualifiedName(); String typeName = javaType.getFullyQualifiedName();
JavaClass javaClass = builder.getClassByName(typeName); JavaClass javaClass = builder.getClassByName(typeName);
String paraName = parameter.getName(); String paraName = parameter.getName();
if (!DocClassUtil.isMvcIgnoreParams(typeName)) { if (DocClassUtil.isMvcIgnoreParams(typeName)) {
//file upload continue;
if (gicTypeName.contains(DocGlobalConstants.MULTIPART_FILE_FULLY)) { }
apiMethodDoc.setContentType(MULTIPART_TYPE); String mockValue = "";
return DocClassUtil.isArray(typeName) ? "Use FormData upload files." : "Use FormData upload file."; if (DocClassUtil.isPrimitive(simpleTypeName)) {
mockValue = paramsComments.get(paraName);
if(mockValue.contains("|")){
mockValue = mockValue.substring(mockValue.lastIndexOf("|") + 1, mockValue.length());
} else {
mockValue ="";
} }
List<JavaAnnotation> annotations = parameter.getAnnotations(); if (StringUtil.isEmpty(mockValue)) {
int requestBodyCounter = 0; mockValue = DocUtil.getValByTypeAndFieldName(simpleTypeName, paraName, true);
String defaultVal = null;
boolean notHasRequestParams = true;
for (JavaAnnotation annotation : annotations) {
String fullName = annotation.getType().getFullyQualifiedName();
if (!fullName.contains(DocGlobalConstants.SPRING_WEB_ANNOTATION_PACKAGE)) {
continue;
}
String annotationName = annotation.getType().getSimpleName();
if (REQUEST_BODY.equals(annotationName) || DocGlobalConstants.REQUEST_BODY_FULLY.equals(annotationName)) {
requestBodyCounter++;
apiMethodDoc.setContentType(JSON_CONTENT_TYPE);
if (DocClassUtil.isPrimitive(simpleTypeName)) {
StringBuilder builder = new StringBuilder();
builder.append("{\"")
.append(paraName)
.append("\":")
.append(DocUtil.jsonValueByType(simpleTypeName))
.append("}");
return builder.toString();
} else {
return buildJson(typeName, gicTypeName, this.fieldMap, false, 0, new HashMap<>());
}
}
if (DocAnnotationConstants.SHORT_REQ_PARAM.equals(annotationName)) {
notHasRequestParams = false;
}
AnnotationValue annotationDefaultVal = annotation.getProperty(DocAnnotationConstants.DEFAULT_VALUE_PROP);
if (null != annotationDefaultVal) {
defaultVal = StringUtil.removeQuotes(annotationDefaultVal.toString());
}
AnnotationValue annotationValue = annotation.getProperty(DocAnnotationConstants.VALUE_PROP);
if (null != annotationValue) {
paraName = StringUtil.removeQuotes(annotationValue.toString());
}
AnnotationValue annotationOfName = annotation.getProperty(DocAnnotationConstants.NAME_PROP);
if (null != annotationOfName) {
paraName = StringUtil.removeQuotes(annotationOfName.toString());
}
if (REQUEST_HERDER.equals(annotationName)) {
paraName = null;
}
}
if (DocClassUtil.isPrimitive(typeName) && parameterList.size() == 1
&& isPostMethod && notHasRequestParams && !containsBrace) {
apiMethodDoc.setContentType(JSON_CONTENT_TYPE);
StringBuilder builder = new StringBuilder();
builder.append("{\"")
.append(paraName)
.append("\":")
.append(DocUtil.jsonValueByType(simpleTypeName))
.append("}");
return builder.toString();
}
if (requestBodyCounter < 1 && paraName != null) {
if (javaClass.isEnum()) {
Object value = this.handleEnumValue(javaClass, Boolean.TRUE);
paramsMap.put(paraName, StringUtil.removeQuotes(String.valueOf(value)));
} else if (annotations.size() < 1 && !DocClassUtil.isPrimitive(typeName)) {
return "Smart-doc can't support create form-data example,It is recommended to use @RequestBody to receive parameters.";
} else if (StringUtil.isEmpty(defaultVal) && DocClassUtil.isPrimitive(typeName)) {
paramsMap.put(paraName, DocUtil.getValByTypeAndFieldName(simpleTypeName, paraName,
true));
} else if ((StringUtil.isEmpty(defaultVal) && DocClassUtil.isPrimitiveArray(typeName))) {
paramsMap.put(paraName, DocUtil.getValByTypeAndFieldName(simpleTypeName, paraName,
true));
} else {
paramsMap.put(paraName, defaultVal);
}
} }
} }
//file upload
if (gicTypeName.contains(DocGlobalConstants.MULTIPART_FILE_FULLY)) {
apiMethodDoc.setContentType(MULTIPART_TYPE);
return DocClassUtil.isArray(typeName) ? "Use FormData upload files." : "Use FormData upload file.";
}
List<JavaAnnotation> annotations = parameter.getAnnotations();
int requestBodyCounter = 0;
String defaultVal = null;
boolean notHasRequestParams = true;
for (JavaAnnotation annotation : annotations) {
String fullName = annotation.getType().getSimpleName();
if (!springMvcRequestAnnotations.contains(fullName)) {
continue;
}
String annotationName = annotation.getType().getSimpleName();
if (REQUEST_BODY.equals(annotationName) || DocGlobalConstants.REQUEST_BODY_FULLY.equals(annotationName)) {
requestBodyCounter++;
apiMethodDoc.setContentType(JSON_CONTENT_TYPE);
if (DocClassUtil.isPrimitive(simpleTypeName)) {
StringBuilder builder = new StringBuilder();
builder.append("{\"")
.append(paraName)
.append("\":")
.append(DocUtil.handleJsonStr(mockValue))
.append("}");
return builder.toString();
} else {
return buildJson(typeName, gicTypeName, this.fieldMap, false, 0, new HashMap<>());
}
}
if (DocAnnotationConstants.SHORT_REQ_PARAM.equals(annotationName)) {
notHasRequestParams = false;
}
AnnotationValue annotationDefaultVal = annotation.getProperty(DocAnnotationConstants.DEFAULT_VALUE_PROP);
if (null != annotationDefaultVal) {
defaultVal = StringUtil.removeQuotes(annotationDefaultVal.toString());
}
AnnotationValue annotationValue = annotation.getProperty(DocAnnotationConstants.VALUE_PROP);
if (null != annotationValue) {
paraName = StringUtil.removeQuotes(annotationValue.toString());
}
AnnotationValue annotationOfName = annotation.getProperty(DocAnnotationConstants.NAME_PROP);
if (null != annotationOfName) {
paraName = StringUtil.removeQuotes(annotationOfName.toString());
}
if (REQUEST_HERDER.equals(annotationName)) {
paraName = null;
}
}
if (DocClassUtil.isPrimitive(typeName) && parameterList.size() == 1
&& isPostMethod && notHasRequestParams && !containsBrace) {
apiMethodDoc.setContentType(JSON_CONTENT_TYPE);
StringBuilder builder = new StringBuilder();
builder.append("{\"")
.append(paraName)
.append("\":")
.append(DocUtil.handleJsonStr(mockValue))
.append("}");
return builder.toString();
}
if (requestBodyCounter < 1 && paraName != null) {
if (javaClass.isEnum()) {
Object value = this.handleEnumValue(javaClass, Boolean.TRUE);
paramsMap.put(paraName, StringUtil.removeQuotes(String.valueOf(value)));
} else if (annotations.size() < 1 && !DocClassUtil.isPrimitive(typeName)) {
return "Smart-doc can't support create form-data example,It is recommended to use @RequestBody to receive parameters.";
} else if (StringUtil.isEmpty(defaultVal) && DocClassUtil.isPrimitive(typeName)) {
paramsMap.put(paraName, mockValue);
} else if ((StringUtil.isEmpty(defaultVal) && DocClassUtil.isPrimitiveArray(typeName))) {
paramsMap.put(paraName, mockValue);
} else {
paramsMap.put(paraName, defaultVal);
}
}
} }
String url; String url;
if (containsBrace && !(apiMethodDoc.getUrl().equals(DEFAULT_SERVER_URL))) { if (containsBrace && !(apiMethodDoc.getUrl().equals(DEFAULT_SERVER_URL))) {
@ -1101,7 +1119,7 @@ public class SourceBuilder {
} else { } else {
url = DocUtil.formatAndRemove(uri, paramsMapTemp); url = DocUtil.formatAndRemove(uri, paramsMapTemp);
url = UrlUtil.urlJoin(url, paramsMapTemp); url = UrlUtil.urlJoin(url, paramsMapTemp);
if (uriCounter == 0) { if (uriCounter == 0 && urls.length > 1) {
urlBuilder.append(url).append(";\t"); urlBuilder.append(url).append(";\t");
} else { } else {
urlBuilder.append(url); urlBuilder.append(url);
@ -1159,6 +1177,10 @@ public class SourceBuilder {
String comment = paramTagMap.get(paramName); String comment = paramTagMap.get(paramName);
if (StringUtil.isEmpty(comment)) { if (StringUtil.isEmpty(comment)) {
comment = NO_COMMENTS_FOUND; comment = NO_COMMENTS_FOUND;
} else {
if(comment.contains("|")){
comment = comment.substring(0,comment.indexOf("|"));
}
} }
List<JavaAnnotation> annotations = parameter.getAnnotations(); List<JavaAnnotation> annotations = parameter.getAnnotations();
if (annotations.size() == 0) { if (annotations.size() == 0) {

View File

@ -34,4 +34,9 @@ public class DocTags {
* custom ignore tag * custom ignore tag
*/ */
public static final String IGNORE = "ignore"; public static final String IGNORE = "ignore";
/**
* custom @mock tag
*/
public static final String MOCK = "mock";
} }

View File

@ -0,0 +1,29 @@
package com.power.doc.constants;
import java.util.ArrayList;
import java.util.List;
/**
* @author yu 2019/12/20.
*/
public enum SpringMvcRequestAnnotations {
PATH_VARIABLE("PathVariable"),
REQ_PARAM ("RequestParam"),
REQUEST_BODY("RequestBody"),
REQUEST_HERDER ("RequestHeader"),
;
private String value;
SpringMvcRequestAnnotations(String value) {
this.value = value;
}
public static List<String> listSpringMvcRequestAnnotations() {
List<String> annotations = new ArrayList<>();
for (SpringMvcRequestAnnotations annotation : SpringMvcRequestAnnotations.values()) {
annotations.add(annotation.value);
}
return annotations;
}
}

View File

@ -13,7 +13,7 @@ public class ApiDataDictionary {
/** /**
* enumClass * enumClass
*/ */
private Class enumClass; private Class<? extends Enum> enumClass;
/** /**
* enum class name * enum class name

View File

@ -9,7 +9,7 @@ public class ApiErrorCodeDictionary {
/** /**
* enumClass * enumClass
*/ */
private Class enumClass; private Class<? extends Enum> enumClass;
/** /**
* enum class name * enum class name

View File

@ -445,7 +445,6 @@ public class DocClassUtil {
* @return ApiReturn * @return ApiReturn
*/ */
public static ApiReturn processReturnType(String fullyName) { public static ApiReturn processReturnType(String fullyName) {
System.out.println("返回类的类名:"+fullyName);
ApiReturn apiReturn = new ApiReturn(); ApiReturn apiReturn = new ApiReturn();
//support web flux //support web flux
@ -489,7 +488,6 @@ public class DocClassUtil {
} }
return apiReturn; return apiReturn;
} }
/** /**
* Get annotation simpleName * Get annotation simpleName
* *

View File

@ -9,10 +9,12 @@ import com.power.doc.constants.DocAnnotationConstants;
import com.power.doc.constants.DocGlobalConstants; import com.power.doc.constants.DocGlobalConstants;
import com.thoughtworks.qdox.model.DocletTag; import com.thoughtworks.qdox.model.DocletTag;
import com.thoughtworks.qdox.model.JavaAnnotation; import com.thoughtworks.qdox.model.JavaAnnotation;
import com.thoughtworks.qdox.model.JavaField;
import com.thoughtworks.qdox.model.JavaMethod; import com.thoughtworks.qdox.model.JavaMethod;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* Description: * Description:
@ -144,9 +146,7 @@ public class DocUtil {
return jsonValueByType(typeName); return jsonValueByType(typeName);
} else { } else {
if ("string".equals(type.toLowerCase())) { if ("string".equals(type.toLowerCase())) {
StringBuilder builder = new StringBuilder(); return handleJsonStr(value.toString());
builder.append("\"").append(value).append("\"");
return builder.toString();
} else { } else {
return value.toString(); return value.toString();
} }
@ -291,7 +291,7 @@ public class DocUtil {
Map<String, String> paramTagMap = new HashMap<>(); Map<String, String> paramTagMap = new HashMap<>();
for (DocletTag docletTag : paramTags) { for (DocletTag docletTag : paramTags) {
String value = docletTag.getValue(); String value = docletTag.getValue();
if (StringUtil.isEmpty(value)) { if (StringUtil.isEmpty(value)&&StringUtil.isNotEmpty(className)) {
throw new RuntimeException("ERROR: #" + javaMethod.getName() throw new RuntimeException("ERROR: #" + javaMethod.getName()
+ "() - bad @" + tagName + " javadoc from " + className + ", must be add comment if you use it."); + "() - bad @" + tagName + " javadoc from " + className + ", must be add comment if you use it.");
} }
@ -324,6 +324,16 @@ public class DocUtil {
return getFirstKeyAndValue(map); return getFirstKeyAndValue(map);
} }
/**
* Get field tags
* @param field JavaField
* @return map
*/
public static Map<String, String> getFieldTagsValue(final JavaField field) {
List<DocletTag> paramTags = field.getTags();
return paramTags.stream().collect(Collectors.toMap(DocletTag::getName, DocletTag::getValue));
}
/** /**
* Get the first element of a map. * Get the first element of a map.
* *
@ -371,4 +381,10 @@ public class DocUtil {
} }
return null; return null;
} }
public static String handleJsonStr(String content){
StringBuilder builder = new StringBuilder();
builder.append("\"").append(content).append("\"");
return builder.toString();
}
} }