diff --git a/src/main/java/com/power/doc/builder/rpc/RpcDocBuilderTemplate.java b/src/main/java/com/power/doc/builder/rpc/RpcDocBuilderTemplate.java index 07dd028..e089a26 100644 --- a/src/main/java/com/power/doc/builder/rpc/RpcDocBuilderTemplate.java +++ b/src/main/java/com/power/doc/builder/rpc/RpcDocBuilderTemplate.java @@ -65,8 +65,8 @@ public class RpcDocBuilderTemplate extends BaseDocBuilderTemplate { mapper.binding(TemplateVariable.DESC.getVariable(), rpcDoc.getDesc()); mapper.binding(TemplateVariable.NAME.getVariable(), rpcDoc.getName()); mapper.binding(TemplateVariable.LIST.getVariable(), rpcDoc.getList()); - mapper.binding(TemplateVariable.PROTOCOL.getVariable(), rpcDoc.getProtocol()); mapper.binding(TemplateVariable.AUTHOR.getVariable(), rpcDoc.getAuthor()); + mapper.binding(TemplateVariable.PROTOCOL.getVariable(), rpcDoc.getProtocol()); mapper.binding(TemplateVariable.VERSION.getVariable(), rpcDoc.getVersion()); mapper.binding(TemplateVariable.URI.getVariable(), rpcDoc.getUri()); FileUtil.nioWriteFile(mapper.render(), config.getOutPath() + FILE_SEPARATOR + rpcDoc.getShortName() + fileExtension); @@ -128,9 +128,9 @@ public class RpcDocBuilderTemplate extends BaseDocBuilderTemplate { */ public RpcApiAllData getApiData(ApiConfig config, JavaProjectBuilder javaProjectBuilder) { RpcApiAllData apiAllData = new RpcApiAllData(); + apiAllData.setLanguage(config.getLanguage().getCode()); apiAllData.setProjectName(config.getProjectName()); apiAllData.setProjectId(DocUtil.generateId(config.getProjectName())); - apiAllData.setLanguage(config.getLanguage().getCode()); apiAllData.setApiDocList(listOfApiData(config, javaProjectBuilder)); apiAllData.setErrorCodeList(errorCodeDictToList(config)); apiAllData.setRevisionLogs(config.getRevisionLogs()); diff --git a/src/main/java/com/power/doc/builder/rpc/RpcHtmlBuilder.java b/src/main/java/com/power/doc/builder/rpc/RpcHtmlBuilder.java index 112b5de..f356f64 100644 --- a/src/main/java/com/power/doc/builder/rpc/RpcHtmlBuilder.java +++ b/src/main/java/com/power/doc/builder/rpc/RpcHtmlBuilder.java @@ -148,10 +148,10 @@ public class RpcHtmlBuilder { apiTemplate.binding(TemplateVariable.DESC.getVariable(), rpcDoc.getDesc()); apiTemplate.binding(TemplateVariable.NAME.getVariable(), rpcDoc.getName()); apiTemplate.binding(TemplateVariable.LIST.getVariable(), rpcDoc.getList()); - apiTemplate.binding(TemplateVariable.PROTOCOL.getVariable(),rpcDoc.getProtocol()); - apiTemplate.binding(TemplateVariable.AUTHOR.getVariable(),rpcDoc.getAuthor()); - apiTemplate.binding(TemplateVariable.VERSION.getVariable(),rpcDoc.getVersion()); - apiTemplate.binding(TemplateVariable.URI.getVariable(),rpcDoc.getUri()); + apiTemplate.binding(TemplateVariable.PROTOCOL.getVariable(), rpcDoc.getProtocol()); + apiTemplate.binding(TemplateVariable.AUTHOR.getVariable(), rpcDoc.getAuthor()); + apiTemplate.binding(TemplateVariable.VERSION.getVariable(), rpcDoc.getVersion()); + apiTemplate.binding(TemplateVariable.URI.getVariable(), rpcDoc.getUri()); String html = MarkDownUtil.toHtml(apiTemplate.render()); htmlApiDoc = BeetlTemplateUtil.getByName(HTML_API_DOC_TPL); @@ -159,7 +159,7 @@ public class RpcHtmlBuilder { htmlApiDoc.binding(TemplateVariable.TITLE.getVariable(), rpcDoc.getDesc()); htmlApiDoc.binding(TemplateVariable.CREATE_TIME.getVariable(), strTime); htmlApiDoc.binding(TemplateVariable.VERSION.getVariable(), now); - FileUtil.nioWriteFile(htmlApiDoc.render(), outPath + FILE_SEPARATOR + rpcDoc.getAlias() + ".html"); + FileUtil.nioWriteFile(htmlApiDoc.render(), outPath + FILE_SEPARATOR + rpcDoc.getShortName() + ".html"); } } @@ -191,22 +191,25 @@ public class RpcHtmlBuilder { */ private static void buildDependency(ApiConfig config) { List apiDependencies = config.getRpcApiDependencies(); + Template template; if (CollectionUtil.isNotEmpty(config.getRpcApiDependencies())) { String rpcConfig = config.getRpcConsumerConfig(); String rpcConfigConfigContent = null; if (Objects.nonNull(rpcConfig)) { rpcConfigConfigContent = FileUtil.getFileContent(rpcConfig); } - Template template = BeetlTemplateUtil.getByName(RPC_DEPENDENCY_MD_TPL); + template = BeetlTemplateUtil.getByName(RPC_DEPENDENCY_MD_TPL); template.binding(TemplateVariable.RPC_CONSUMER_CONFIG.getVariable(), rpcConfigConfigContent); template.binding(TemplateVariable.DEPENDENCY_LIST.getVariable(), apiDependencies); - String dictHtml = MarkDownUtil.toHtml(template.render()); - Template dictTpl = BeetlTemplateUtil.getByName(HTML_API_DOC_TPL); - dictTpl.binding(TemplateVariable.VERSION.getVariable(), now); - dictTpl.binding(TemplateVariable.TITLE.getVariable(), DICT_EN_TITLE); - dictTpl.binding(TemplateVariable.HTML.getVariable(), dictHtml); - dictTpl.binding(TemplateVariable.CREATE_TIME.getVariable(), DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND)); - FileUtil.nioWriteFile(dictTpl.render(), config.getOutPath() + FILE_SEPARATOR + "dependency.html"); + } else { + template = BeetlTemplateUtil.getByName(RPC_DEPENDENCY_EMPTY_MD_TPL); } + String dictHtml = MarkDownUtil.toHtml(template.render()); + Template dictTpl = BeetlTemplateUtil.getByName(HTML_API_DOC_TPL); + dictTpl.binding(TemplateVariable.VERSION.getVariable(), now); + dictTpl.binding(TemplateVariable.TITLE.getVariable(), DICT_EN_TITLE); + dictTpl.binding(TemplateVariable.HTML.getVariable(), dictHtml); + dictTpl.binding(TemplateVariable.CREATE_TIME.getVariable(), DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND)); + FileUtil.nioWriteFile(dictTpl.render(), config.getOutPath() + FILE_SEPARATOR + "dependency.html"); } } diff --git a/src/main/java/com/power/doc/builder/rpc/RpcMarkdownBuilder.java b/src/main/java/com/power/doc/builder/rpc/RpcMarkdownBuilder.java index ade90b5..eda293a 100644 --- a/src/main/java/com/power/doc/builder/rpc/RpcMarkdownBuilder.java +++ b/src/main/java/com/power/doc/builder/rpc/RpcMarkdownBuilder.java @@ -67,7 +67,7 @@ public class RpcMarkdownBuilder { List apiDocList = docBuildTemplate.getApiData(configBuilder); if (config.isAllInOne()) { String version = config.isCoverOld() ? "" : "-V" + DateTimeUtil.long2Str(System.currentTimeMillis(), DATE_FORMAT); - builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, RPC_ALL_IN_ONE_MD_TPL, "DubboAllInOne" + version + ".md"); + builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, RPC_ALL_IN_ONE_MD_TPL, "rpc-all" + version + ".md"); } else { builderTemplate.buildApiDoc(apiDocList, config, RPC_API_DOC_MD_TPL, API_EXTENSION); builderTemplate.buildErrorCodeDoc(config, ERROR_CODE_LIST_MD_TPL, ERROR_CODE_LIST_MD); diff --git a/src/main/java/com/power/doc/constants/DocGlobalConstants.java b/src/main/java/com/power/doc/constants/DocGlobalConstants.java index 06e8a94..87c8c2c 100644 --- a/src/main/java/com/power/doc/constants/DocGlobalConstants.java +++ b/src/main/java/com/power/doc/constants/DocGlobalConstants.java @@ -61,6 +61,8 @@ public interface DocGlobalConstants { String RPC_DEPENDENCY_MD_TPL = "dubbo/DubboApiDependency.md"; + String RPC_DEPENDENCY_EMPTY_MD_TPL = "dubbo/DubboApiDependencyEmpty.md"; + String RPC_API_DOC_MD_TPL = "dubbo/Dubbo.md"; String RPC_ALL_IN_ONE_MD_TPL = "dubbo/DubboAllInOne.md"; diff --git a/src/main/java/com/power/doc/helper/JsonBuildHelper.java b/src/main/java/com/power/doc/helper/JsonBuildHelper.java index d36a96e..940af0b 100644 --- a/src/main/java/com/power/doc/helper/JsonBuildHelper.java +++ b/src/main/java/com/power/doc/helper/JsonBuildHelper.java @@ -1,356 +1,356 @@ -/* - * smart-doc https://github.com/shalousun/smart-doc - * - * Copyright (C) 2018-2020 smart-doc - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -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.ApiConfig; -import com.power.doc.model.ApiReturn; -import com.power.doc.model.CustomRespField; -import com.power.doc.model.DocJavaField; -import com.power.doc.utils.*; -import com.thoughtworks.qdox.model.*; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; - - - -/** - * @author yu 2019/12/21. - */ -public class JsonBuildHelper { - - /** - * build return json - * - * @param method The JavaMethod object - * @param builder ProjectDocConfigBuilder builder - * @return String - */ - public static String buildReturnJson(JavaMethod method, ProjectDocConfigBuilder builder) { - if (method.getReturns().isVoid()) { - return "This api return nothing."; - } - ApiReturn apiReturn = DocClassUtil.processReturnType(method.getReturnType().getGenericCanonicalName()); - String returnType = JavaClassUtil.javaTypeFormat(apiReturn.getGenericCanonicalName()); - String typeName = apiReturn.getSimpleName(); - return JsonFormatUtil.formatJson(buildJson(typeName, returnType, Boolean.TRUE, 0, new HashMap<>(), builder)); - } - - /** - * @param typeName type name - * @param genericCanonicalName genericCanonicalName - * @param isResp Response flag - * @param counter Recursive counter - * @param registryClasses class container - * @param builder project config builder - * @return String - */ - public static String buildJson(String typeName, String genericCanonicalName, - boolean isResp, int counter, Map registryClasses, ProjectDocConfigBuilder builder) { - - //存储泛型所对应的实体类 - Map genericMap = new HashMap<>(10); - JavaClass javaClass = builder.getJavaProjectBuilder().getClassByName(typeName); - ApiConfig apiConfig = builder.getApiConfig(); - if (counter > apiConfig.getRecursionLimit()) { - return "{\"$ref\":\"...\"}"; - } - if (registryClasses.containsKey(typeName) && counter > registryClasses.size()) { - return "{\"$ref\":\"...\"}"; - } - int nextLevel = counter + 1; - registryClasses.put(typeName, typeName); - if (JavaClassValidateUtil.isMvcIgnoreParams(typeName,builder.getApiConfig().getIgnoreRequestParams())) { - if (DocGlobalConstants.MODE_AND_VIEW_FULLY.equals(typeName)) { - return "Forward or redirect to a page view."; - } else { - return "Error restful return."; - } - } - if (JavaClassValidateUtil.isPrimitive(typeName)) { - return StringUtil.removeQuotes(DocUtil.jsonValueByType(typeName)); - } - if (javaClass.isEnum()) { - return String.valueOf(JavaClassUtil.getEnumValue(javaClass, Boolean.FALSE)); - } - boolean skipTransientField = apiConfig.isSkipTransientField(); - StringBuilder data0 = new StringBuilder(); - JavaClass cls = builder.getClassByName(typeName); - - - data0.append("{"); - String[] globGicName = DocClassUtil.getSimpleGicName(genericCanonicalName); - //添加泛型对应关系 - JavaClassUtil.genericParamMap(genericMap, cls, globGicName); - StringBuilder data = new StringBuilder(); - if (JavaClassValidateUtil.isCollection(typeName) || JavaClassValidateUtil.isArray(typeName)) { - data.append("["); - if (globGicName.length == 0) { - data.append("{\"object\":\"any object\"}"); - data.append("]"); - return data.toString(); - } - String gNameTemp = globGicName[0]; - String gName = JavaClassValidateUtil.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 (JavaClassValidateUtil.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, nextLevel, registryClasses, builder); - data.append(json); - } else if (JavaClassValidateUtil.isCollection(gName)) { - data.append("\"any object\""); - } else { - String json = buildJson(gName, gName, isResp, nextLevel, registryClasses, builder); - data.append(json); - } - data.append("]"); - return data.toString(); - } else if (JavaClassValidateUtil.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 (JavaClassValidateUtil.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, nextLevel, 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)) { - data.append("{\"object\":\" any object\"},"); - // throw new RuntimeException("Please do not return java.lang.Object directly in api interface."); - } else { - boolean requestFieldToUnderline = builder.getApiConfig().isRequestFieldToUnderline(); - boolean responseFieldToUnderline = builder.getApiConfig().isResponseFieldToUnderline(); - List fields = JavaClassUtil.getFields(cls, 0, new HashSet<>()); - boolean isGenerics = JavaFieldUtil.checkGenerics(fields); - out: - for (DocJavaField docField : fields) { - JavaField field = docField.getJavaField(); - String subTypeName = docField.getFullyQualifiedName(); - String fieldName = field.getName(); - if (field.isStatic() || "this$0".equals(fieldName) || - JavaClassValidateUtil.isIgnoreFieldTypes(subTypeName)) { - continue; - } - if (field.isTransient() && skipTransientField) { - continue; - } - if ((responseFieldToUnderline && isResp) || (requestFieldToUnderline && !isResp)) { - fieldName = StringUtil.camelToUnderline(fieldName); - } - Map tagsMap = DocUtil.getFieldTagsValue(field, docField); - if (!isResp) { - if (tagsMap.containsKey(DocTags.IGNORE)) { - continue out; - } - } - List annotations = docField.getAnnotations(); - for (JavaAnnotation annotation : annotations) { - String annotationName = annotation.getType().getValue(); - if (DocAnnotationConstants.SHORT_JSON_IGNORE.equals(annotationName)) { - continue out; - } else if (DocAnnotationConstants.SHORT_JSON_FIELD.equals(annotationName)) { - 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)) { - if (null != annotation.getProperty(DocAnnotationConstants.VALUE_PROP)) { - fieldName = StringUtil.removeQuotes(annotation.getProperty(DocAnnotationConstants.VALUE_PROP).toString()); - } - } - } - String typeSimpleName = field.getType().getSimpleName(); - - String fieldGicName = docField.getGenericCanonicalName(); - data0.append("\"").append(fieldName).append("\":"); - if (JavaClassValidateUtil.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 (JavaClassValidateUtil.isCollection(subTypeName) || JavaClassValidateUtil.isArray(subTypeName)) { - if (globGicName.length > 0 && "java.util.List".equals(fieldGicName)) { - fieldGicName = fieldGicName + ""; - } - fieldGicName = JavaClassValidateUtil.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, nextLevel, 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 = genericMap.get(gicName) == null ? globGicName[0] : genericMap.get(gicName); - if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName1)) { - data0.append("[").append("\"").append(buildJson(gicName1, gicName1, isResp, nextLevel, registryClasses, builder)).append("\"]").append(","); - } else { - if (!typeName.equals(gicName1)) { - data0.append("[").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, nextLevel, registryClasses, builder)).append("]").append(","); - } else { - data0.append("[{\"$ref\":\"..\"}]").append(","); - } - } - } else { - if (!typeName.equals(gicName)) { - if (JavaClassValidateUtil.isMap(gicName)) { - data0.append("[{\"mapKey\":{}}],"); - continue out; - } - data0.append("[").append(buildJson(gicName, fieldGicName, isResp, nextLevel, registryClasses, builder)).append("]").append(","); - } else { - data0.append("[{\"$ref\":\"..\"}]").append(","); - } - } - } else if (JavaClassValidateUtil.isMap(subTypeName)) { - if (JavaClassValidateUtil.isMap(fieldGicName)) { - data0.append("{").append("\"mapKey\":{}},"); - continue out; - } - String gicName = fieldGicName.substring(fieldGicName.indexOf(",") + 1, fieldGicName.indexOf(">")); - if (gicName.length() == 1) { - String gicName1 = genericMap.get(gicName) == null ? globGicName[0] : genericMap.get(gicName); - if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName1)) { - data0.append("{").append("\"mapKey\":\"").append(buildJson(gicName1, gicName1, isResp, nextLevel, registryClasses, builder)).append("\"},"); - } else { - if (!typeName.equals(gicName1)) { - data0.append("{").append("\"mapKey\":").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, nextLevel, registryClasses, builder)).append("},"); - } else { - data0.append("{\"mapKey\":{}},"); - } - } - } else { - data0.append("{").append("\"mapKey\":").append(buildJson(gicName, fieldGicName, isResp, nextLevel, registryClasses, builder)).append("},"); - } - } else if (subTypeName.length() == 1) { - if (!typeName.equals(genericCanonicalName)) { - String gicName = genericMap.get(subTypeName) == null ? globGicName[0] : genericMap.get(subTypeName); - if (JavaClassValidateUtil.isPrimitive(gicName)) { - data0.append(DocUtil.jsonValueByType(gicName)).append(","); - } else { - String simple = DocClassUtil.getSimpleName(gicName); - data0.append(buildJson(simple, gicName, isResp, nextLevel, registryClasses, builder)).append(","); - } - } else { - data0.append("{\"waring\":\"You may have used non-display generics.\"},"); - } - } else if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) { - if (isGenerics) { - data0.append("{\"object\":\"any object\"},"); - } else if (globGicName.length > 0) { - String gicName = genericMap.get(subTypeName) == null ? globGicName[0] : genericMap.get(subTypeName); - if (!typeName.equals(genericCanonicalName)) { - if (JavaClassValidateUtil.isPrimitive(gicName)) { - data0.append("\"").append(buildJson(gicName, genericCanonicalName, isResp, nextLevel, registryClasses, builder)).append("\","); - } else { - String simpleName = DocClassUtil.getSimpleName(gicName); - data0.append(buildJson(simpleName, gicName, isResp, nextLevel, 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.\"},"); - } - } else if (typeName.equals(subTypeName)) { - data0.append("{\"$ref\":\"...\"}").append(","); - } else { - 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, nextLevel, registryClasses, builder)).append(","); - } - } - } - } - } - if (data0.toString().contains(",")) { - data0.deleteCharAt(data0.lastIndexOf(",")); - } - data0.append("}"); - return data0.toString(); - } - - -} +/* + * smart-doc https://github.com/shalousun/smart-doc + * + * Copyright (C) 2018-2020 smart-doc + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +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.ApiConfig; +import com.power.doc.model.ApiReturn; +import com.power.doc.model.CustomRespField; +import com.power.doc.model.DocJavaField; +import com.power.doc.utils.*; +import com.thoughtworks.qdox.model.*; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + + + +/** + * @author yu 2019/12/21. + */ +public class JsonBuildHelper { + + /** + * build return json + * + * @param method The JavaMethod object + * @param builder ProjectDocConfigBuilder builder + * @return String + */ + public static String buildReturnJson(JavaMethod method, ProjectDocConfigBuilder builder) { + if (method.getReturns().isVoid()) { + 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, Boolean.TRUE, 0, new HashMap<>(), builder)); + } + + /** + * @param typeName type name + * @param genericCanonicalName genericCanonicalName + * @param isResp Response flag + * @param counter Recursive counter + * @param registryClasses class container + * @param builder project config builder + * @return String + */ + public static String buildJson(String typeName, String genericCanonicalName, + boolean isResp, int counter, Map registryClasses, ProjectDocConfigBuilder builder) { + + //存储泛型所对应的实体类 + Map genericMap = new HashMap<>(10); + JavaClass javaClass = builder.getJavaProjectBuilder().getClassByName(typeName); + ApiConfig apiConfig = builder.getApiConfig(); + if (counter > apiConfig.getRecursionLimit()) { + return "{\"$ref\":\"...\"}"; + } + if (registryClasses.containsKey(typeName) && counter > registryClasses.size()) { + return "{\"$ref\":\"...\"}"; + } + int nextLevel = counter + 1; + registryClasses.put(typeName, typeName); + if (JavaClassValidateUtil.isMvcIgnoreParams(typeName,builder.getApiConfig().getIgnoreRequestParams())) { + if (DocGlobalConstants.MODE_AND_VIEW_FULLY.equals(typeName)) { + return "Forward or redirect to a page view."; + } else { + return "Error restful return."; + } + } + if (JavaClassValidateUtil.isPrimitive(typeName)) { + return StringUtil.removeQuotes(DocUtil.jsonValueByType(typeName)); + } + if (javaClass.isEnum()) { + return String.valueOf(JavaClassUtil.getEnumValue(javaClass, Boolean.FALSE)); + } + boolean skipTransientField = apiConfig.isSkipTransientField(); + StringBuilder data0 = new StringBuilder(); + JavaClass cls = builder.getClassByName(typeName); + + + data0.append("{"); + String[] globGicName = DocClassUtil.getSimpleGicName(genericCanonicalName); + //添加泛型对应关系 + JavaClassUtil.genericParamMap(genericMap, cls, globGicName); + StringBuilder data = new StringBuilder(); + if (JavaClassValidateUtil.isCollection(typeName) || JavaClassValidateUtil.isArray(typeName)) { + data.append("["); + if (globGicName.length == 0) { + data.append("{\"object\":\"any object\"}"); + data.append("]"); + return data.toString(); + } + String gNameTemp = globGicName[0]; + String gName = JavaClassValidateUtil.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 (JavaClassValidateUtil.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, nextLevel, registryClasses, builder); + data.append(json); + } else if (JavaClassValidateUtil.isCollection(gName)) { + data.append("\"any object\""); + } else { + String json = buildJson(gName, gName, isResp, nextLevel, registryClasses, builder); + data.append(json); + } + data.append("]"); + return data.toString(); + } else if (JavaClassValidateUtil.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 (JavaClassValidateUtil.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, nextLevel, 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)) { + data.append("{\"object\":\" any object\"},"); + // throw new RuntimeException("Please do not return java.lang.Object directly in api interface."); + } else { + boolean requestFieldToUnderline = builder.getApiConfig().isRequestFieldToUnderline(); + boolean responseFieldToUnderline = builder.getApiConfig().isResponseFieldToUnderline(); + List fields = JavaClassUtil.getFields(cls, 0, new HashSet<>()); + boolean isGenerics = JavaFieldUtil.checkGenerics(fields); + out: + for (DocJavaField docField : fields) { + JavaField field = docField.getJavaField(); + String subTypeName = docField.getFullyQualifiedName(); + String fieldName = field.getName(); + if (field.isStatic() || "this$0".equals(fieldName) || + JavaClassValidateUtil.isIgnoreFieldTypes(subTypeName)) { + continue; + } + if (field.isTransient() && skipTransientField) { + continue; + } + if ((responseFieldToUnderline && isResp) || (requestFieldToUnderline && !isResp)) { + fieldName = StringUtil.camelToUnderline(fieldName); + } + Map tagsMap = DocUtil.getFieldTagsValue(field, docField); + if (!isResp) { + if (tagsMap.containsKey(DocTags.IGNORE)) { + continue out; + } + } + List annotations = docField.getAnnotations(); + for (JavaAnnotation annotation : annotations) { + String annotationName = annotation.getType().getValue(); + if (DocAnnotationConstants.SHORT_JSON_IGNORE.equals(annotationName)) { + continue out; + } else if (DocAnnotationConstants.SHORT_JSON_FIELD.equals(annotationName)) { + 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)) { + if (null != annotation.getProperty(DocAnnotationConstants.VALUE_PROP)) { + fieldName = StringUtil.removeQuotes(annotation.getProperty(DocAnnotationConstants.VALUE_PROP).toString()); + } + } + } + String typeSimpleName = field.getType().getSimpleName(); + + String fieldGicName = docField.getGenericCanonicalName(); + data0.append("\"").append(fieldName).append("\":"); + if (JavaClassValidateUtil.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 (JavaClassValidateUtil.isCollection(subTypeName) || JavaClassValidateUtil.isArray(subTypeName)) { + if (globGicName.length > 0 && "java.util.List".equals(fieldGicName)) { + fieldGicName = fieldGicName + ""; + } + fieldGicName = JavaClassValidateUtil.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, nextLevel, 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 = genericMap.get(gicName) == null ? globGicName[0] : genericMap.get(gicName); + if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName1)) { + data0.append("[").append("\"").append(buildJson(gicName1, gicName1, isResp, nextLevel, registryClasses, builder)).append("\"]").append(","); + } else { + if (!typeName.equals(gicName1)) { + data0.append("[").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, nextLevel, registryClasses, builder)).append("]").append(","); + } else { + data0.append("[{\"$ref\":\"..\"}]").append(","); + } + } + } else { + if (!typeName.equals(gicName)) { + if (JavaClassValidateUtil.isMap(gicName)) { + data0.append("[{\"mapKey\":{}}],"); + continue out; + } + data0.append("[").append(buildJson(gicName, fieldGicName, isResp, nextLevel, registryClasses, builder)).append("]").append(","); + } else { + data0.append("[{\"$ref\":\"..\"}]").append(","); + } + } + } else if (JavaClassValidateUtil.isMap(subTypeName)) { + if (JavaClassValidateUtil.isMap(fieldGicName)) { + data0.append("{").append("\"mapKey\":{}},"); + continue out; + } + String gicName = fieldGicName.substring(fieldGicName.indexOf(",") + 1, fieldGicName.indexOf(">")); + if (gicName.length() == 1) { + String gicName1 = genericMap.get(gicName) == null ? globGicName[0] : genericMap.get(gicName); + if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName1)) { + data0.append("{").append("\"mapKey\":\"").append(buildJson(gicName1, gicName1, isResp, nextLevel, registryClasses, builder)).append("\"},"); + } else { + if (!typeName.equals(gicName1)) { + data0.append("{").append("\"mapKey\":").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, nextLevel, registryClasses, builder)).append("},"); + } else { + data0.append("{\"mapKey\":{}},"); + } + } + } else { + data0.append("{").append("\"mapKey\":").append(buildJson(gicName, fieldGicName, isResp, nextLevel, registryClasses, builder)).append("},"); + } + } else if (subTypeName.length() == 1) { + if (!typeName.equals(genericCanonicalName)) { + String gicName = genericMap.get(subTypeName) == null ? globGicName[0] : genericMap.get(subTypeName); + if (JavaClassValidateUtil.isPrimitive(gicName)) { + data0.append(DocUtil.jsonValueByType(gicName)).append(","); + } else { + String simple = DocClassUtil.getSimpleName(gicName); + data0.append(buildJson(simple, gicName, isResp, nextLevel, registryClasses, builder)).append(","); + } + } else { + data0.append("{\"waring\":\"You may have used non-display generics.\"},"); + } + } else if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) { + if (isGenerics) { + data0.append("{\"object\":\"any object\"},"); + } else if (globGicName.length > 0) { + String gicName = genericMap.get(subTypeName) == null ? globGicName[0] : genericMap.get(subTypeName); + if (!typeName.equals(genericCanonicalName)) { + if (JavaClassValidateUtil.isPrimitive(gicName)) { + data0.append("\"").append(buildJson(gicName, genericCanonicalName, isResp, nextLevel, registryClasses, builder)).append("\","); + } else { + String simpleName = DocClassUtil.getSimpleName(gicName); + data0.append(buildJson(simpleName, gicName, isResp, nextLevel, 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.\"},"); + } + } else if (typeName.equals(subTypeName)) { + data0.append("{\"$ref\":\"...\"}").append(","); + } else { + 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, nextLevel, registryClasses, builder)).append(","); + } + } + } + } + } + if (data0.toString().contains(",")) { + data0.deleteCharAt(data0.lastIndexOf(",")); + } + data0.append("}"); + return data0.toString(); + } + + +} diff --git a/src/main/java/com/power/doc/template/IDocBuildTemplate.java b/src/main/java/com/power/doc/template/IDocBuildTemplate.java index ab70862..ebdf09b 100644 --- a/src/main/java/com/power/doc/template/IDocBuildTemplate.java +++ b/src/main/java/com/power/doc/template/IDocBuildTemplate.java @@ -97,7 +97,7 @@ public interface IDocBuildTemplate { return null; } ApiReturn apiReturn = DocClassUtil.processReturnType(method.getReturnType().getGenericCanonicalName()); - String returnType = JavaClassUtil.javaTypeFormat(apiReturn.getGenericCanonicalName()); + String returnType = apiReturn.getGenericCanonicalName(); String typeName = apiReturn.getSimpleName(); if (this.ignoreReturnObject(typeName,projectBuilder.getApiConfig().getIgnoreRequestParams())) { return null; diff --git a/src/main/java/com/power/doc/template/RpcDocBuildTemplate.java b/src/main/java/com/power/doc/template/RpcDocBuildTemplate.java index 32d706d..58d2629 100644 --- a/src/main/java/com/power/doc/template/RpcDocBuildTemplate.java +++ b/src/main/java/com/power/doc/template/RpcDocBuildTemplate.java @@ -22,7 +22,6 @@ */ package com.power.doc.template; -import com.google.gson.Gson; import com.power.common.util.StringUtil; import com.power.common.util.ValidateUtil; import com.power.doc.builder.ProjectDocConfigBuilder; @@ -283,7 +282,7 @@ public class RpcDocBuildTemplate implements IDocBuildTemplate { StringBuilder methodBuilder = new StringBuilder(); JavaType returnType = method.getReturnType(); String simpleReturn = returnType.getCanonicalName(); - String returnClass = JavaClassUtil.javaTypeFormat(returnType.getGenericCanonicalName()); + String returnClass = returnType.getGenericCanonicalName(); returnClass = returnClass.replace(simpleReturn, JavaClassUtil.getClassSimpleName(simpleReturn)); String[] arrays = DocClassUtil.getSimpleGicName(returnClass); for (String str : arrays) { @@ -292,7 +291,14 @@ public class RpcDocBuildTemplate implements IDocBuildTemplate { } String[] generics = str.split("[<,]"); for (String generic : generics) { - returnClass = returnClass.replaceAll(generic, JavaClassUtil.getClassSimpleName(generic)); + if (generic.contains("extends")) { + String className = generic.substring(generic.lastIndexOf(" ")+1); + returnClass = returnClass.replace(className, JavaClassUtil.getClassSimpleName(className)); + } + if (generic.length() != 1 && !generic.contains("extends")) { + returnClass = returnClass.replaceAll(generic, JavaClassUtil.getClassSimpleName(generic)); + } + } } methodBuilder.append(returnClass).append(" "); diff --git a/src/main/java/com/power/doc/template/SpringBootDocBuildTemplate.java b/src/main/java/com/power/doc/template/SpringBootDocBuildTemplate.java index 4bd1d04..c21f527 100644 --- a/src/main/java/com/power/doc/template/SpringBootDocBuildTemplate.java +++ b/src/main/java/com/power/doc/template/SpringBootDocBuildTemplate.java @@ -239,7 +239,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate { JavaType javaType = parameter.getType(); String paramName = parameter.getName(); String typeName = javaType.getFullyQualifiedName(); - String gicTypeName = JavaClassUtil.javaTypeFormat(javaType.getGenericCanonicalName()); + String gicTypeName = javaType.getGenericCanonicalName(); String commentClass = paramsComments.get(paramName); //ignore request params diff --git a/src/main/resources/template/dubbo/DubboApiDependencyEmpty.md b/src/main/resources/template/dubbo/DubboApiDependencyEmpty.md new file mode 100644 index 0000000..70b7d74 --- /dev/null +++ b/src/main/resources/template/dubbo/DubboApiDependencyEmpty.md @@ -0,0 +1,17 @@ +# Add dependency + +``` + + Your api group + Your api artifactId + 1.0.0 + +``` + +Consumer config +``` +dubbo: + registry: + protocol: zookeeper + address: localhost:2181 +``` \ No newline at end of file diff --git a/src/main/resources/template/dubbo/DubboIndex.btl b/src/main/resources/template/dubbo/DubboIndex.btl index 3e40cfa..ac83748 100644 --- a/src/main/resources/template/dubbo/DubboIndex.btl +++ b/src/main/resources/template/dubbo/DubboIndex.btl @@ -24,17 +24,17 @@ <% for(api in apiDocList){ %> -
  • - ${api.order+1} ${api.desc} +
  • + ${api.order+1} ${api.desc}