com.power.doc.builder.SourceBuilder Maven / Gradle / Ivy
package com.power.doc.builder;
import com.power.common.util.CollectionUtil;
import com.power.common.util.JsonFormatUtil;
import com.power.common.util.StringUtil;
import com.power.doc.model.*;
import com.power.doc.utils.DocClassUtil;
import com.power.doc.utils.DocUtil;
import com.thoughtworks.qdox.JavaProjectBuilder;
import com.thoughtworks.qdox.model.*;
import java.io.File;
import java.lang.reflect.Field;
import java.util.*;
public class SourceBuilder {
private static final String GET_MAPPING = "GetMapping";
private static final String POST_MAPPING = "PostMapping";
private static final String REQUEST_MAPPING = "RequestMapping";
private static final String REQUEST_BODY = "RequestBody";
private static final String REQUEST_PARAM = "RequestParam";
private static final String SERVLET_REQUEST = "javax.servlet.http.HttpServletRequest";
private static final String MODEL_VIEW = "org.springframework.web.servlet.ModelAndView";
private static final String MODEL = "org.springframework.ui.Model";
private static final String BINDING_RESULT = "org.springframework.validation.BindingResult";
private static final String JSON_CONTENT_TYPE = "application/json";
public Map javaFilesMap = new HashMap<>();
private JavaProjectBuilder builder;
private Collection javaClasses;
private boolean isStrict = false;//严格模式
private List headers;
public Map fieldMap = new HashMap<>();
/**
* if isStrict value is true,it while check all method
*
* @param isStrict strict flag
*/
public SourceBuilder(boolean isStrict) {
loadJavaFiles(null);
this.isStrict = isStrict;
}
/**
* use custom config
*
* @param config config
*/
public SourceBuilder(ApiConfig config) {
if (null == config) {
throw new NullPointerException("ApiConfig can't be null.");
}
loadJavaFiles(config.getSourcePath());
this.headers = config.getRequestHeaders();
if (CollectionUtil.isNotEmpty(config.getCustomResponseFields())) {
for (CustomRespField field : config.getCustomResponseFields()) {
fieldMap.put(field.getName(), field);
}
}
}
/**
* 加载项目的源代码
*
* @param path
*/
private void loadJavaFiles(String path) {
JavaProjectBuilder builder = new JavaProjectBuilder();
if (StringUtil.isEmpty(path)) {
builder.addSourceTree(new File("src/main/java"));
} else {
builder.addSourceTree(new File(path));
}
this.builder = builder;
this.javaClasses = builder.getClasses();
for (JavaClass cls : javaClasses) {
javaFilesMap.put(cls.getName(), cls.getName());
}
}
/**
* 检测controller上的注解
*
* @param cls
* @return
*/
private int checkController(JavaClass cls) {
int counter = 0;
List classAnnotations = cls.getAnnotations();
for (JavaAnnotation annotation : classAnnotations) {
String annotationName = annotation.getType().getName();
if ("Controller".equals(annotationName) || "RestController".equals(annotationName)) {
counter++;
}
}
return counter;
}
public List getControllerApiData() {
List apiDocList = new ArrayList<>();
for (JavaClass cls : javaClasses) {
int counter = checkController(cls);
if (counter > 0) {
String controllerName = cls.getName();
List apiMethodDocs = buildControllerMethod(cls);
ApiDoc apiDoc = new ApiDoc();
apiDoc.setDesc(cls.getComment());
apiDoc.setName(controllerName);
apiDoc.setList(apiMethodDocs);
apiDocList.add(apiDoc);
}
}
return apiDocList;
}
/**
* 包括包名
*
* @param controller controller的名称
* @return ApiDoc
*/
public ApiDoc getSingleControllerApiData(String controller) {
if (!javaFilesMap.containsKey(controller)) {
throw new RuntimeException("Unable to find " + controller + " in your project");
}
JavaClass cls = builder.getClassByName(controller);
int counter = checkController(cls);
if (counter > 0) {
String controllerName = cls.getName();
List apiMethodDocs = buildControllerMethod(cls);
ApiDoc apiDoc = new ApiDoc();
apiDoc.setList(apiMethodDocs);
apiDoc.setName(controllerName);
return apiDoc;
} else {
throw new RuntimeException(controller + " is not a Controller in your project");
}
}
public List buildControllerMethod(final JavaClass cls) {
List classAnnotations = cls.getAnnotations();
String baseUrl = null;
for (JavaAnnotation annotation : classAnnotations) {
String annotationName = annotation.getType().getName();
if (REQUEST_MAPPING.equals(annotationName)) {
baseUrl = annotation.getNamedParameter("value").toString();
baseUrl = baseUrl.replaceAll("\"", "");
}
}
List methods = cls.getMethods();
List methodDocList = new ArrayList<>(methods.size());
for (JavaMethod method : methods) {
if (StringUtil.isEmpty(method.getComment()) && isStrict) {
throw new RuntimeException("Unable to find comment for method " + method.getName() + " in " + cls.getName());
}
ApiMethodDoc apiMethodDoc = new ApiMethodDoc();
apiMethodDoc.setDesc(method.getComment());
List annotations = method.getAnnotations();
String url = null;
String methodType = null;
int methodCounter = 0;
for (JavaAnnotation annotation : annotations) {
String annotationName = annotation.getType().getName();
if (REQUEST_MAPPING.equals(annotationName)) {
if (null == annotation.getNamedParameter("value")) {
throw new NullPointerException("Unable to find RequestMapping value for method " + method.getName() + " in " + cls.getName());
}
url = annotation.getNamedParameter("value").toString();
if (url.contains("POST")) {
methodType = "post";
} else {
methodType = "get";
}
methodCounter++;
} else if (GET_MAPPING.equals(annotationName)) {
if (null == annotation.getNamedParameter("value")) {
throw new NullPointerException("Unable to find GetMapping value for method " + method.getName() + " in " + cls.getName());
}
url = annotation.getNamedParameter("value").toString();
methodType = "get";
methodCounter++;
} else if (POST_MAPPING.equals(annotationName)) {
if (null == annotation.getNamedParameter("value")) {
throw new NullPointerException("Unable to find PostMapping value for method " + method.getName() + " in " + cls.getName());
}
url = annotation.getNamedParameter("value").toString();
methodType = "post";
methodCounter++;
}
}
if (methodCounter > 0) {
if ("void".equals(method.getReturnType().getFullyQualifiedName())) {
throw new RuntimeException(method.getName() + " method in " + cls.getName() + " can't be return type 'void'");
}
url = url.replaceAll("\"", "").trim();
apiMethodDoc.setType(methodType);
if (StringUtil.isNotEmpty(baseUrl)) {
apiMethodDoc.setUrl((baseUrl + "/" + url).replace("//", "/"));
} else {
apiMethodDoc.setUrl((url).replace("//", "/"));
}
String comment = getCommentTag(method, "param", cls.getName());
apiMethodDoc.setRequestParams(comment);
String requestJson = buildReqJson(method, apiMethodDoc);
apiMethodDoc.setRequestUsage(JsonFormatUtil.formatJson(requestJson));
apiMethodDoc.setResponseUsage(buildReturnJson(method, this.fieldMap));
String str = buildMethodReturn(method, apiMethodDoc);
apiMethodDoc.setResponseParams(str);
apiMethodDoc.setHeaders(createHeaders(this.headers));
methodDocList.add(apiMethodDoc);
}
}
return methodDocList;
}
/**
* create request headers
*
* @param headers
* @return
*/
private String createHeaders(List headers) {
StringBuilder builder = new StringBuilder();
if (CollectionUtil.isEmpty(headers)) {
headers = new ArrayList<>(0);
}
for (ApiReqHeader header : headers) {
builder.append(header.getName()).append("|");
builder.append(header.getType()).append("|");
builder.append(header.getDesc()).append("\n");
}
return builder.toString();
}
private String buildMethodReturn(JavaMethod method, ApiMethodDoc apiMethodDoc) {
String returnType = method.getReturnType().getGenericCanonicalName();
String typeName = method.getReturnType().getFullyQualifiedName();
if (DocClassUtil.isPrimitive(typeName)) {
return primitiveReturnRespComment(DocClassUtil.processTypeNameForParams(typeName));
}
if (DocClassUtil.isCollection(typeName)) {
String gicName = returnType.substring(returnType.indexOf("<") + 1, returnType.lastIndexOf(">"));
if (DocClassUtil.isPrimitive(gicName)) {
return primitiveReturnRespComment("array of " + DocClassUtil.processTypeNameForParams(gicName));
}
String param = buildParams(gicName, "", 0, null, fieldMap, true);
return param;
}
if (DocClassUtil.isMap(typeName)) {
String[] keyValue = DocClassUtil.getMapKeyValueType(returnType);
if (DocClassUtil.isPrimitive(keyValue[1])) {
return primitiveReturnRespComment("key value");
}
String param = buildParams(keyValue[1], "", 0, null, fieldMap, true);
return param;
}
if (StringUtil.isNotEmpty(returnType)) {
String param = buildParams(returnType, "", 0, null, fieldMap, true);
return param;
}
return null;
}
/**
* @param className
* @param pre
* @param i 缩进计数器
* @param isRequired
* @param responseFieldMap
* @param isResp
* @return
*/
private String buildParams(String className, String pre, int i, String isRequired,
Map responseFieldMap, boolean isResp) {
StringBuilder params0 = new StringBuilder();
String simpleName = DocClassUtil.getSimpleName(className);
String[] globGicName = DocClassUtil.getSimpleGicName(className);
JavaClass cls = builder.getClassByName(simpleName);
List fields = getFields(cls, 0);
int n = 0;
out:
for (JavaField field : fields) {
String fieldName = field.getName();
if (!"serialVersionUID".equals(fieldName)) {
String typeSimpleName = field.getType().getSimpleName();
String subTypeName = field.getType().getFullyQualifiedName();
String fieldGicName = field.getType().getGenericCanonicalName();
List javaAnnotations = field.getAnnotations();
String strRequired = "false";
int annotationCounter = 0;
an:
for (JavaAnnotation annotation : javaAnnotations) {
if ("JsonIgnore".equals(annotation.getType().getSimpleName()) && isResp) {
continue out;
} else if ("JSONField".equals(annotation.getType().getSimpleName()) && isResp) {
if (null != annotation.getProperty("serialize")) {
if ("false".equals(annotation.getProperty("serialize").toString())) {
continue out;
}
} else if (null != annotation.getProperty("name")) {
fieldName = annotation.getProperty("name").toString().replace("\"", "");
}
} else if ("JsonProperty".equals(annotation.getType().getSimpleName()) && isResp) {
if (null != annotation.getProperty("value")) {
fieldName = annotation.getProperty("value").toString().replace("\"", "");
}
} else if (DocClassUtil.isJSR303Required(annotation.getType().getSimpleName())) {
strRequired = "true";
annotationCounter++;
break an;
}
}
if (annotationCounter < 1) {
List paramTags = field.getTags();
doc:
for (DocletTag docletTag : paramTags) {
if (DocClassUtil.isRequiredTag(docletTag.getName())) {
strRequired = "true";
break doc;
}
}
}
//cover comment
CustomRespField customResponseField = responseFieldMap.get(field.getName());
String comment;
if (null != customResponseField) {
comment = customResponseField.getDesc();
} else {
comment = field.getComment();
}
if (DocClassUtil.isPrimitive(subTypeName)) {
params0.append(pre);
params0.append(fieldName).append("|")
.append(DocClassUtil.processTypeNameForParams(typeSimpleName.toLowerCase())).append("|");
if (StringUtil.isNotEmpty(comment)) {
if (StringUtil.isEmpty(isRequired)) {
params0.append(comment).append("\n");
} else {
params0.append(comment).append("|").append(strRequired).append("\n");
}
} else {
if (StringUtil.isEmpty(isRequired)) {
params0.append("no comment.").append("\n");
} else {
params0.append("no comment.").append("|").append(strRequired).append("\n");
}
}
} else {
params0.append(pre);
params0.append(fieldName).append("|")
.append(DocClassUtil.processTypeNameForParams(typeSimpleName.toLowerCase())).append("|");
if (StringUtil.isNotEmpty(comment)) {
if (StringUtil.isEmpty(isRequired)) {
params0.append(comment).append("\n");
} else {
params0.append(comment).append("|").append(strRequired).append("\n");
}
} else {
if (StringUtil.isEmpty(isRequired)) {
params0.append("no comment.").append("\n");
} else {
params0.append("no comment|").append(strRequired).append("\n");
}
}
StringBuilder preBuilder = new StringBuilder();
for (int j = 0; j < i; j++) {
preBuilder.append(" ");
}
preBuilder.append("└─");
if (DocClassUtil.isMap(subTypeName)) {
String gNameTemp = field.getType().getGenericCanonicalName();
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)) {
params0.append(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp));
}
} else {
params0.append(buildParams(valType, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp));
}
}
} else if (DocClassUtil.isCollection(subTypeName)) {
String gNameTemp = field.getType().getGenericCanonicalName();
String gName = DocClassUtil.getSimpleGicName(gNameTemp)[0];
if (!DocClassUtil.isPrimitive(gName)) {
if (!simpleName.equals(gName)) {
if (gName.length() == 1) {
int len = globGicName.length;
String gicName = (n < len) ? globGicName[n] : globGicName[len - 1];
if (!DocClassUtil.isPrimitive(gicName) && !simpleName.equals(gicName)) {
params0.append(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp));
}
} else {
params0.append(buildParams(gName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp));
}
}
}
} else if (subTypeName.length() == 1 || "java.lang.Object".equals(subTypeName)) {
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)) {
params0.append(buildParams(gName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp));
}
} else if (DocClassUtil.isMap(simple)) {
String valType = DocClassUtil.getMapKeyValueType(gicName)[1];
if (!DocClassUtil.isPrimitive(valType)) {
params0.append(buildParams(valType, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp));
}
} else {
params0.append(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp));
}
} else {
params0.append(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp));
}
} else {
params0.append(buildParams(subTypeName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp));
}
}
n++;
} else if (DocClassUtil.isArray(subTypeName)) {
fieldGicName = fieldGicName.substring(0, fieldGicName.indexOf("["));
params0.append(buildParams(fieldGicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp));
} else if (simpleName.equals(subTypeName)) {
//do nothing
} else {
params0.append(buildParams(fieldGicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp));
}
}
}
}
return params0.toString();
}
private String primitiveReturnRespComment(String typeName) {
StringBuilder comments = new StringBuilder();
comments.append("no param name|").append(typeName).append("|").append("接口直接返回").append(typeName).append("类型值\n");
return comments.toString();
}
/**
* 构建返回的json
*
* @param method
* @return
*/
private String buildReturnJson(JavaMethod method, Map responseFieldMap) {
String returnType = method.getReturnType().getGenericCanonicalName();
String typeName = method.getReturnType().getFullyQualifiedName();
return JsonFormatUtil.formatJson(buildJson(typeName, returnType, responseFieldMap, true));
}
/**
* @param typeName
* @param genericCanonicalName
* @param responseFieldMap
* @param isResp 是否是响应返回
* @return
*/
private String buildJson(String typeName, String genericCanonicalName, Map responseFieldMap, boolean isResp) {
if (DocClassUtil.isPrimitive(typeName)) {
return DocUtil.jsonValueByType(typeName).replace("\"", "");
}
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("[");
String gNameTemp = globGicName[0];
String gName = DocClassUtil.isArray(typeName) ? gNameTemp.substring(0, gNameTemp.indexOf("[")) : globGicName[0];
if ("java.lang.Object".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, responseFieldMap, isResp);
data.append(json);
} else if (DocClassUtil.isCollection(typeName)) {
data.append("{\"waring\":\"You may use java.util.Object instead of display generics in the List\"}");
} else {
String json = buildJson(gName, gName, responseFieldMap, isResp);
data.append(json);
}
data.append("]");
return data.toString();
} else if (DocClassUtil.isMap(typeName)) {
String gNameTemp = genericCanonicalName;
String[] getKeyValType = DocClassUtil.getMapKeyValueType(gNameTemp);
if (!"java.lang.String".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 ("java.lang.Object".equals(gicName)) {
data.append("{").append("\"mapKey\":").append("{\"waring\":\"You may use java.util.Object for Map value; Api-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, responseFieldMap, isResp);
data.append("{").append("\"mapKey\":").append(json).append("}");
} else {
data.append("{").append("\"mapKey\":").append(buildJson(gicName, gNameTemp, responseFieldMap, isResp)).append("}");
}
return data.toString();
} else if ("java.lang.Object".equals(typeName)) {
if ("java.lang.Object".equals(typeName)) {
throw new RuntimeException("Please do not return java.lang.Object directly in api interface.");
}
} else {
List fields = getFields(cls, 0);
int i = 0;
out:
for (JavaField field : fields) {
String fieldName = field.getName();
if (!"serialVersionUID".equals(fieldName)) {
List annotations = field.getAnnotations();
for (JavaAnnotation annotation : annotations) {
if ("JsonIgnore".equals(annotation.getType().getSimpleName()) && isResp) {
continue out;
} else if ("JSONField".equals(annotation.getType().getSimpleName()) && isResp) {
if (null != annotation.getProperty("serialize")) {
if ("false".equals(annotation.getProperty("serialize").toString())) {
continue out;
}
} else if (null != annotation.getProperty("name")) {
fieldName = annotation.getProperty("name").toString().replace("\"", "");
}
} else if ("JsonProperty".equals(annotation.getType().getSimpleName()) && isResp) {
if (null != annotation.getProperty("value")) {
fieldName = annotation.getProperty("value").toString().replace("\"", "");
}
}
}
String typeSimpleName = field.getType().getSimpleName();
String subTypeName = field.getType().getFullyQualifiedName();
String fieldGicName = field.getType().getGenericCanonicalName();
data0.append("\"").append(fieldName).append("\":");
if (DocClassUtil.isPrimitive(typeSimpleName)) {
CustomRespField customResponseField = responseFieldMap.get(fieldName);
if (null != customResponseField) {
Object val = customResponseField.getValue();
if (null != val) {
if ("String".equals(typeSimpleName)) {
data0.append("\"").append(val).append("\",");
} else {
data0.append(val).append(",");
}
} else {
data0.append(DocUtil.getValByTypeAndFieldName(typeSimpleName, field.getName())).append(",");
}
} else {
data0.append(DocUtil.getValByTypeAndFieldName(typeSimpleName, field.getName())).append(",");
}
} else {
if (DocClassUtil.isCollection(subTypeName) || DocClassUtil.isArray(subTypeName)) {
fieldGicName = DocClassUtil.isArray(subTypeName) ? fieldGicName.substring(0, fieldGicName.indexOf("[")) : fieldGicName;
String gicName = DocClassUtil.getSimpleGicName(fieldGicName)[0];
if ("java.lang.String".equals(gicName)) {
data0.append("[").append("\"").append(buildJson(gicName, fieldGicName, responseFieldMap, isResp)).append("\"]").append(",");
} else if (gicName.length() == 1) {
String gicName1 = (i < globGicName.length) ? globGicName[i] : globGicName[globGicName.length - 1];
if ("java.lang.String".equals(gicName1)) {
data0.append("[").append("\"").append(buildJson(gicName1, gicName1, responseFieldMap, isResp)).append("\"]").append(",");
} else {
if (!typeName.equals(gicName1)) {
data0.append("[").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, responseFieldMap, isResp)).append("]").append(",");
} else {
data0.append("[{\"$ref\":\"..\"}]").append(",");
}
}
} else {
if (!typeName.equals(gicName)) {
data0.append("[").append(buildJson(gicName, fieldGicName, responseFieldMap, isResp)).append("]").append(",");
} else {
data0.append("[{\"$ref\":\"..\"}]").append(",");
}
}
} else if (DocClassUtil.isMap(subTypeName)) {
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 ("java.lang.String".equals(gicName1)) {
data0.append("{").append("\"mapKey\":\"").append(buildJson(gicName1, gicName1, responseFieldMap, isResp)).append("\"},");
} else {
if (!typeName.equals(gicName1)) {
data0.append("{").append("\"mapKey\":").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, responseFieldMap, isResp)).append("},");
} else {
data0.append("{\"mapKey\":{}},");
}
}
} else {
data0.append("{").append("\"mapKey\":").append(buildJson(gicName, fieldGicName, responseFieldMap, isResp)).append("},");
}
} else if (subTypeName.length() == 1) {
if (!typeName.equals(genericCanonicalName)) {
String gicName = globGicName[i];
if (gicName.contains("<")) {
String simple = DocClassUtil.getSimpleName(gicName);
data0.append(buildJson(simple, gicName, responseFieldMap, isResp)).append(",");
} else {
if (DocClassUtil.isPrimitive(gicName)) {
data0.append(DocUtil.jsonValueByType(gicName)).append(",");
} else {
data0.append(buildJson(gicName, gicName, responseFieldMap, isResp)).append(",");
}
}
} else {
data0.append("{\"waring\":\"You may have used non-display generics.\"},");
}
i++;
} else if ("java.lang.Object".equals(subTypeName)) {
if (i < globGicName.length) {
String gicName = globGicName[i];
if (!typeName.equals(genericCanonicalName)) {
if (DocClassUtil.isPrimitive(gicName)) {
data0.append("\"").append(buildJson(gicName, genericCanonicalName, responseFieldMap, isResp)).append("\",");
} else {
data0.append(buildJson(gicName, gicName, responseFieldMap, isResp)).append(",");
}
} else {
data0.append("{\"waring\":\"You may have used non-display generics.\"},");
}
} else {
data0.append("{\"waring\":\"You may have used non-display generics.\"},");
}
} else if (typeName.equals(subTypeName)) {
data0.append("{\"$ref\":\"...\"}").append(",");
} else {
//
data0.append(buildJson(subTypeName, fieldGicName, responseFieldMap, isResp)).append(",");
}
}
}
}
}
if (data0.toString().contains(",")) {
data0.deleteCharAt(data0.lastIndexOf(","));
}
data0.append("}");
return data0.toString();
}
private String buildReqJson(JavaMethod method, ApiMethodDoc apiMethodDoc) {
List parameterList = method.getParameters();
for (JavaParameter parameter : parameterList) {
JavaType javaType = parameter.getType();
String simpleTypeName = javaType.getValue();
String gicTypeName = javaType.getGenericCanonicalName();
String typeName = javaType.getFullyQualifiedName();
String paraName = parameter.getName();
if (!MODEL.equals(typeName) && !MODEL_VIEW.equals(typeName) &&
!SERVLET_REQUEST.equals(typeName) && !BINDING_RESULT.equals(typeName)) {
List annotations = parameter.getAnnotations();
int requestBodyCounter = 0;
for (JavaAnnotation annotation : annotations) {
String annotationName = annotation.getType().getName();
if (REQUEST_BODY.equals(annotationName)) {
requestBodyCounter++;
apiMethodDoc.setContentType(JSON_CONTENT_TYPE);
if (DocClassUtil.isPrimitive(simpleTypeName)) {
StringBuilder builder = new StringBuilder();
builder.append("{\"").append(paraName).append("\":");
builder.append(DocUtil.jsonValueByType(simpleTypeName)).append("}");
return builder.toString();
} else {
return buildJson(typeName, gicTypeName, this.fieldMap, false);
}
}
}
if (requestBodyCounter < 1) {
//非json
return "Api-doc cannot currently provide examples of parameters for the RequestParam request mode";
}
}
}
return "Does not require any request parameters.";
}
private String getCommentTag(final JavaMethod javaMethod, final String tagName, final String className) {
//对请求参数的注释目前不做任何修复
Map responseFieldMap = new HashMap<>();
List paramTags = javaMethod.getTagsByName(tagName);
Map paramTagMap = new HashMap<>();
for (DocletTag docletTag : paramTags) {
String value = docletTag.getValue();
if (StringUtil.isEmpty(value)) {
throw new RuntimeException("ERROR: #" + javaMethod.getName()
+ "() - bad @param javadoc from " + className);
}
String pName;
String pValue;
int idx = value.indexOf("\n");
//如果存在换行
if (idx > -1) {
pName = value.substring(0, idx);
pValue = value.substring(idx + 1);
} else {
pName = (value.indexOf(" ") > -1) ? value.substring(0, value.indexOf(" ")) : value;
pValue = value.indexOf(" ") > -1 ? value.substring(value.indexOf(' ') + 1) : "No Comment";
}
paramTagMap.put(pName, pValue);
}
List parameterList = javaMethod.getParameters();
if (parameterList.size() > 0) {
StringBuilder params = new StringBuilder();
int requestBodyCounter = 0;
StringBuilder reqBodyParams = new StringBuilder();
StringBuilder reqParam = new StringBuilder();
for (JavaParameter parameter : parameterList) {
String typeName = parameter.getType().getGenericCanonicalName();
String simpleName = parameter.getType().getValue().toLowerCase();
String fullTypeName = parameter.getType().getFullyQualifiedName();
if (!MODEL.equals(typeName) && !MODEL_VIEW.equals(typeName) &&
!SERVLET_REQUEST.equals(typeName) && !BINDING_RESULT.equals(typeName)) {
if (!paramTagMap.containsKey(parameter.getName())) {
throw new RuntimeException("Unable to find javadoc @param for actual param \""
+ parameter.getName() + "\" in method " + javaMethod.getName() + " from " + className);
}
List annotations = parameter.getAnnotations();
if (annotations.size() == 0) {
//default set required is true
if (DocClassUtil.isCollection(fullTypeName)) {
String[] gicNameArr = DocClassUtil.getSimpleGicName(typeName);
String gicName = gicNameArr[0];
String typeTemp = "";
if (DocClassUtil.isPrimitive(gicName)) {
typeTemp = " of " + DocClassUtil.processTypeNameForParams(gicName);
reqParam.append(parameter.getName()).append("|")
.append(DocClassUtil.processTypeNameForParams(simpleName)).append(typeTemp).append("|")
.append(paramTagMap.get(parameter.getName())).append("|true\n");
} else {
reqParam.append(parameter.getName()).append("|")
.append(DocClassUtil.processTypeNameForParams(simpleName)).append(typeTemp).append("|")
.append(paramTagMap.get(parameter.getName())).append("|true\n");
String strPrams = buildParams(gicNameArr[0], "└─", 1, "true", responseFieldMap, false);
reqParam.append(strPrams);
}
} else if (DocClassUtil.isPrimitive(simpleName)) {
reqParam.append(parameter.getName()).append("|")
.append(DocClassUtil.processTypeNameForParams(simpleName)).append("|")
.append(paramTagMap.get(parameter.getName())).append("|true\n");
} else {
reqParam.append(buildParams(fullTypeName, "", 0, "true", responseFieldMap, false));
}
}
for (JavaAnnotation annotation : annotations) {
String annotationName = annotation.getType().getName();
if (REQUEST_BODY.equals(annotationName)) {
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)) {
reqBodyParams.append(parameter.getName()).append("|")
.append(DocClassUtil.processTypeNameForParams(simpleName)).append("|")
.append(paramTagMap.get(parameter.getName())).append("|true\n");
} else {
if (DocClassUtil.isCollection(fullTypeName)) {
String[] gicNameArr = DocClassUtil.getSimpleGicName(typeName);
if (DocClassUtil.isPrimitive(gicNameArr[0])) {
reqBodyParams.append(parameter.getName()).append("|")
.append(DocClassUtil.processTypeNameForParams(simpleName)).append("|")
.append(paramTagMap.get(parameter.getName())).append("|true\n");
} else {
String strPrams = buildParams(gicNameArr[0], "", 0, "true", responseFieldMap, false);
reqBodyParams.append(strPrams);
}
} else if (DocClassUtil.isMap(fullTypeName)) {
String[] gicNameArr = DocClassUtil.getSimpleGicName(typeName);
String strPrams = buildParams(gicNameArr[1], "", 0, "true", responseFieldMap, false);
reqBodyParams.append(strPrams);
} else {
reqBodyParams.append(buildParams(typeName, "", 0, "true", responseFieldMap, false));
}
}
requestBodyCounter++;
} else {
String required = "true";
if (null != annotation.getProperty("required")) {
required = annotation.getProperty("required").toString();
}
reqParam.append(parameter.getName()).append("|")
.append(DocClassUtil.processTypeNameForParams(simpleName)).append("|")
.append(paramTagMap.get(parameter.getName())).append("|")
.append(required).append("\n");
}
}
}
}
if (requestBodyCounter > 0) {
params.append(reqBodyParams);
return params.toString();
}
params.append(reqParam);
return params.toString();
}
return null;
}
/**
* @param cls1
* @param i 递归计数器
* @return
*/
private List getFields(JavaClass cls1, int i) {
List fieldList = new ArrayList<>();
if (null == cls1) {
return fieldList;
} else if ("Object".equals(cls1.getSimpleName()) || "Timestamp".equals(cls1.getSimpleName()) ||
"Date".equals(cls1.getSimpleName())) {
return fieldList;
} else if (i < 1) {
i++;
JavaClass pcls = cls1.getSuperJavaClass();
fieldList.addAll(getFields(pcls, i));
fieldList.addAll(cls1.getFields());
} else {
i++;
JavaClass pcls = cls1.getSuperJavaClass();
fieldList.addAll(getFields(pcls, i));
List fieldsTemp = new ArrayList<>();
for (JavaField field : cls1.getFields()) {
if (CollectionUtil.isNotEmpty(field.getModifiers())) {
if (!"private".equals(field.getModifiers().get(0))) {
fieldsTemp.add(field);
}
}
}
fieldList.addAll(fieldsTemp);
}
return fieldList;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy