diff --git a/CHANGELOG.md b/CHANGELOG.md index 48c7437..be6eafd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## smart-doc版本 版本小于1.0都属于试用,正式1.0起始发布将会等到文中提到的问题解决后才发布。 +#### 版本号:2.0.9 +- 更新日期: 2020-03-12 +- 更新内容: + 1. 支持UUID和ZonedDateTime字段类型,#89。 + 2. 对map参数增加开关来兼容旧项目,还是不建议使用map参数。 + 3. 完成和Torna的对接。 #### 版本号:2.0.8 - 更新日期: 2020-02-26 - 更新内容: diff --git a/README.md b/README.md index 7ba46fa..cf5314a 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,10 @@ smart-doc does not need to inject annotations into the code like Swagger. - Support for exporting error codes and data dictionary codes to API documentation. - The debug html5 page fully supports file upload and download testing. - Support Apache Dubbo RPC. +## Best Practice +smart-doc + [Torna](http://torna.cn) form an industry-leading document generation and management solution, using smart-doc to complete Java source code analysis and extract annotations to generate API documents without intrusion, and automatically push the documents to the Torna enterprise-level interface document management platform. + +![smart-doc+torna](http://torna.cn/assets/images/case/smart-doc.png) ## Getting Started [Smart-doc Samples](https://github.com/shalousun/smart-doc-demo.git)。 ``` @@ -108,6 +112,10 @@ When you need to use smart-doc to generate more API document information, you ca "requestExample":"true",//Whether to display the request example in the document, the default value is true. "responseExample":"true",//Whether to display the response example in the document, the default is true. "displayActualType":false,//display actual type of generic, + "appKey": "xxx",// torna appKey, @since 2.0.9 + "appToken": "xxx", //torna appToken,@since 2.0.9 + "secret": "xx",//torna secret,@since 2.0.9 + "openUrl": "torna server/api/",//torna server url,@since 2.0.9 "ignoreRequestParams":[ //The request parameter object will be discarded when generating the document.@since 1.9.2 "org.springframework.ui.ModelMap" ], @@ -166,13 +174,15 @@ So the project configuration can also refer to the introduction of smart-doc. #### Run Plugin with MAVEN command ``` // Generate html -mvn -Dfile.encoding=UTF-8 smart-doc: html +mvn -Dfile.encoding=UTF-8 smart-doc:html // Generate markdown -mvn -Dfile.encoding=UTF-8 smart-doc: markdown +mvn -Dfile.encoding=UTF-8 smart-doc:markdown // Generate adoc -mvn -Dfile.encoding=UTF-8 smart-doc: adoc +mvn -Dfile.encoding=UTF-8 smart-doc:adoc // Generate postman collection -mvn -Dfile.encoding=UTF-8 smart-doc: postman +mvn -Dfile.encoding=UTF-8 smart-doc:postman +// Generate document and send to Torna +mvn -Dfile.encoding=UTF-8 smart-doc:torna-rest // Apache Dubbo RPC // Generate html diff --git a/README_CN.md b/README_CN.md index e817ba9..9a70930 100644 --- a/README_CN.md +++ b/README_CN.md @@ -32,6 +32,11 @@ $\color{red}{你给我的star,胜过所有读过的诗—smart-doc}$ - 支持Maven、Gradle插件式轻松集成。 - 支持Apache Dubbo RPC接口文档生成。 - debug接口调试html5页面完全支持文件上传,下载(@download tag标记下载方法)测试。 + +## Best Practice +smart-doc + [Torna](http://torna.cn) 组成行业领先的文档生成和管理解决方案,使用smart-doc无侵入完成Java源代码分析和提取注释生成API文档,自动将文档推送到Torna企业级接口文档管理平台。 + +![smart-doc+torna](http://torna.cn/assets/images/case/smart-doc.png) ## Getting Started smart-doc使用和测试可参考[smart-doc demo](https://gitee.com/devin-alan/api-doc-test.git)。 ``` @@ -114,6 +119,12 @@ smart-doc官方目前已经开发完成[Maven插件](https://gitee.com/smart-doc "requestExample":"true",//是否将请求示例展示在文档中,默认true,@since 1.9.0 "responseExample":"true",//是否将响应示例展示在文档中,默认为true,@since 1.9.0 "displayActualType":false,//配置true会在注释栏自动显示泛型的真实类型短类名,@since 1.9.6 + "appKey": "xxx",// torna平台对接appKey,, @since 2.0.9 + "appToken": "xxx", //torna平台appToken,@since 2.0.9 + "secret": "xx",//torna平台secret,@since 2.0.9 + "openUrl": "torna server/api/",//torna平台地址,填写自己的私有化部署地址@since 2.0.9 + "debugEnvName":"测试环境", //torna测试环境 + "debugEnvUrl":"http://127.0.0.1",//torna "ignoreRequestParams":[ //忽略请求参数对象,把不想生成文档的参数对象屏蔽掉,@since 1.9.2 "org.springframework.ui.ModelMap" ], @@ -189,6 +200,8 @@ mvn -Dfile.encoding=UTF-8 smart-doc:adoc mvn -Dfile.encoding=UTF-8 smart-doc:postman // 生成 Open Api 3.0+,Since smart-doc-maven-plugin 1.1.5 mvn -Dfile.encoding=UTF-8 smart-doc:openapi +// 生成文档推送到Torna平台 +mvn -Dfile.encoding=UTF-8 smart-doc:torna-rest // Apache Dubbo RPC文档 // Generate html diff --git a/pom.xml b/pom.xml index fbf2cb1..cfc1b9f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 smart-doc jar - 2.0.8 + 2.0.9 smart-doc https://github.com/smart-doc-group/smart-doc.git @@ -72,6 +72,11 @@ gson 2.8.6 + + org.slf4j + slf4j-api + 1.7.30 + diff --git a/src/main/java/com/power/doc/builder/OpenApiBuilder.java b/src/main/java/com/power/doc/builder/OpenApiBuilder.java index 3f67e3e..a08715a 100644 --- a/src/main/java/com/power/doc/builder/OpenApiBuilder.java +++ b/src/main/java/com/power/doc/builder/OpenApiBuilder.java @@ -270,7 +270,7 @@ public class OpenApiBuilder { } else if (!isRep && Objects.nonNull(apiMethodDoc.getRequestSchema())) { content.put("schema", apiMethodDoc.getRequestSchema()); } else { - content.put("schema", buildBodySchema(apiMethodDoc.getPath(), isRep)); + content.put("schema", buildBodySchema(apiMethodDoc, isRep)); } } content.put("examples", buildBodyExample(apiMethodDoc, isRep)); @@ -281,18 +281,37 @@ public class OpenApiBuilder { /** * content body 的schema 信息 * - * @param url 请求的url 去除server + * @param apiMethodDoc 请求方法参数 去除server * @param isRep 是否是返回数据 * @return */ - private static Map buildBodySchema(String url, boolean isRep) { + private static Map buildBodySchema(ApiMethodDoc apiMethodDoc, boolean isRep) { Map schema = new HashMap<>(10); + //当类型为数组时使用 + Map innerScheme = new HashMap<>(10); + //去除url中的特殊字符 - if (isRep) { - schema.put("$ref", "#/components/schemas/" + url.replaceAll(PATH_REGEX, "_") + "response"); - } else { - schema.put("$ref", "#/components/schemas/" + url.replaceAll(PATH_REGEX, "_") + "request"); + String responseRef = "#/components/schemas/" + apiMethodDoc.getPath().replaceAll(PATH_REGEX, "_") + "response"; + String requestRef = "#/components/schemas/" + apiMethodDoc.getPath().replaceAll(PATH_REGEX, "_") + "request"; + + //如果是数组类型 + if(DocGlobalConstants.ARRAY.equals(apiMethodDoc.getType())){ + schema.put("type",DocGlobalConstants.ARRAY); + if (isRep) { + innerScheme.put("$ref", responseRef); + } else { + innerScheme.put("$ref", requestRef); + } + schema.put("items",innerScheme); } + else { + if (isRep) { + schema.put("$ref", responseRef); + } else { + schema.put("$ref", requestRef); + } + } + return schema; } diff --git a/src/main/java/com/power/doc/builder/TornaBuilder.java b/src/main/java/com/power/doc/builder/TornaBuilder.java new file mode 100644 index 0000000..d149eb1 --- /dev/null +++ b/src/main/java/com/power/doc/builder/TornaBuilder.java @@ -0,0 +1,278 @@ +/* + * smart-doc https://github.com/shalousun/smart-doc + * + * Copyright (C) 2018-2021 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.builder; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.power.common.util.CollectionUtil; +import com.power.common.util.OkHttp3Util; +import com.power.common.util.StringUtil; +import com.power.doc.constants.TornaConstants; +import com.power.doc.model.*; +import com.power.doc.model.torna.Apis; +import com.power.doc.model.torna.DebugEnv; +import com.power.doc.model.torna.HttpParam; +import com.power.doc.model.torna.TornaApi; +import com.power.doc.template.SpringBootDocBuildTemplate; +import com.thoughtworks.qdox.JavaProjectBuilder; + +import java.util.ArrayList; +import java.util.List; + +import static com.power.doc.constants.TornaConstants.PUSH; + + +/** + * @author xingzi 2021/2/2 18:05 + **/ +public class TornaBuilder { + + /** + * build controller api + * + * @param config config + */ + public static void buildApiDoc(ApiConfig config) { + JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder(); + buildApiDoc(config, javaProjectBuilder); + + + } + + /** + * Only for smart-doc maven plugin and gradle plugin. + * + * @param config ApiConfig + * @param javaProjectBuilder ProjectDocConfigBuilder + */ + public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) { + config.setParamsDataToTree(true); + DocBuilderTemplate builderTemplate = new DocBuilderTemplate(); + builderTemplate.checkAndInit(config); + ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder); + List apiDocList = new SpringBootDocBuildTemplate().getApiData(configBuilder); + buildTorna(apiDocList, config); + } + + /** + * build torna Data + * + * @param apiDocs apiData + * @param apiConfig ApiConfig + */ + public static void buildTorna(List apiDocs, ApiConfig apiConfig) { + Apis api; + for (ApiDoc a : apiDocs) { + api = new Apis(); + api.setName(a.getDesc()); + //推送接口分类 CATEGORY_CREATE + String responseMsg = OkHttp3Util.syncPost(apiConfig.getOpenUrl(), + TornaConstants.buildParams(TornaConstants.CATEGORY_CREATE, new Gson().toJson(api), apiConfig)); + //pushApi + pushApi(responseMsg, a, apiConfig); + + + JsonElement element = JsonParser.parseString(responseMsg); + //如果推送成功 + if (TornaConstants.SUCCESS_CODE.equals(element.getAsJsonObject().get(TornaConstants.CODE).getAsString())) { + //pushApi + pushApi(responseMsg, a, apiConfig); + System.out.println("推送成功"); + } else { + System.out.println(element.getAsJsonObject().get(TornaConstants.MESSAGE).getAsString()); + System.out.println("接口配置错误,请检查torna相关配置。"); + break; + } + } + } + + /** + * push api + * @param responseMsg returnmsg + * @param a apiDoc + * @param config config + */ + public static void pushApi(String responseMsg, ApiDoc a, ApiConfig config) { + JsonElement element = JsonParser.parseString(responseMsg); + //如果获取分类成功 + if (TornaConstants.SUCCESS_CODE.equals(element.getAsJsonObject().get(TornaConstants.CODE).getAsString())) { + //获取分类id + String labelId = element.getAsJsonObject().get(TornaConstants.DATA) + .getAsJsonObject() + .get(TornaConstants.ID).getAsString(); + List apiMethodDocs = a.getList(); + //参数列表 + List apis = new ArrayList<>(); + //环境列表 + List debugEnvs = new ArrayList<>(); + //推送文档数据 + TornaApi tornaApi = new TornaApi(); + Apis methodApi; + DebugEnv debugEnv; + //遍历分类接口 + for (ApiMethodDoc apiMethodDoc : apiMethodDocs) { + /** + * "name": "获取商品信息", + * "description": "获取商品信息", + * "url": "/goods/get", + * "httpMethod": "GET", + * "contentType": "application/json", + * "isFolder": "1", + * "parentId": "", + * "isShow": "1", + */ + methodApi = new Apis(); + methodApi.setIsFolder(TornaConstants.NO); + methodApi.setName(apiMethodDoc.getDesc()); + methodApi.setUrl(apiMethodDoc.getUrl()); + methodApi.setHttpMethod(apiMethodDoc.getType()); + methodApi.setContentType(apiMethodDoc.getContentType()); + methodApi.setParentId(labelId); + methodApi.setDescription(apiMethodDoc.getDetail()); + methodApi.setIsShow(TornaConstants.YES); + debugEnv = new DebugEnv(); + debugEnv.setName(config.getDebugEnvName()); + debugEnv.setUrl(config.getDebugEnvUrl()); + /** + * { + * "name": "goodsName", + * "type": "string", + * "required": "1", + * "maxLength": "128", + * "example": "iphone12", + * "description": "商品名称描述", + * "parentId": "", + * "enumInfo": { + * "name": "支付枚举", + * "description": "支付状态", + * "items": [ + * { + * "name": "WAIT_PAY", + * "type": "string", + * "value": "0", + * "description": "未支付" + * } + * ] + * } + * } + */ + methodApi.setHeaderParams(buildHerder(apiMethodDoc.getRequestHeaders())); + methodApi.setResponseParams(buildParams(apiMethodDoc.getResponseParams())); + //formData + if (CollectionUtil.isNotEmpty(apiMethodDoc.getQueryParams())) { + methodApi.setRequestParams(buildParams(apiMethodDoc.getQueryParams())); + } + //Json + if (CollectionUtil.isNotEmpty(apiMethodDoc.getRequestParams())) { + methodApi.setRequestParams(buildParams(apiMethodDoc.getRequestParams())); + } + apis.add(methodApi); + debugEnvs.add(debugEnv); + } + tornaApi.setApis(apis); + tornaApi.setDebugEnvs(debugEnvs); + + OkHttp3Util.syncPost(config.getOpenUrl(), + TornaConstants.buildParams(PUSH, new Gson().toJson(tornaApi), config)); + debugEnvs.clear(); + + } else { + System.out.println("Error: " + element.getAsJsonObject() + .get(TornaConstants.MESSAGE).getAsString()); + } + } + + /** + * build request header + * + * @param apiReqHeaders 请求头参数列表 + * @return List of HttpParam + */ + public static List buildHerder(List apiReqHeaders) { + /** + * name": "token", + * "required": "1", + * "example": "iphone12", + * "description": "商品名称描述" + */ + HttpParam httpParam; + List headers = new ArrayList<>(); + for (ApiReqHeader header : apiReqHeaders) { + httpParam = new HttpParam(); + httpParam.setName(header.getName()); + httpParam.setRequired(header.isRequired() ? TornaConstants.YES : TornaConstants.NO); + httpParam.setExample(StringUtil.removeQuotes(header.getValue())); + httpParam.setDescription(header.getDesc()); + headers.add(httpParam); + } + return headers; + } + + /** + * build request response params + * + * @param apiParams 参数列表 + * @return List of HttpParam + */ + public static List buildParams(List apiParams) { + HttpParam httpParam; + List bodies = new ArrayList<>(); + /** + * "name": "goodsName", + * "type": "string", + * "required": "1", + * "maxLength": "128", + * "example": "iphone12", + * "description": "商品名称描述", + * "parentId": "", + * "enumInfo": { + * "name": "支付枚举", + * "description": "支付状态", + * "items": [ + * { + * "name": "WAIT_PAY", + * "type": "string", + * "value": "0", + * "description": "未支付" + */ + for (ApiParam apiParam : apiParams) { + httpParam = new HttpParam(); + httpParam.setName(apiParam.getField()); + httpParam.setType(apiParam.getType()); + httpParam.setRequired(apiParam.isRequired() ? TornaConstants.YES : TornaConstants.NO); + httpParam.setExample(StringUtil.removeQuotes(apiParam.getValue())); + httpParam.setDescription(apiParam.getDesc()); + if (TornaConstants.ARRAY.equals(httpParam.getType())) { + if (apiParam.getChildren() != null) { + httpParam.setChildren(buildParams(apiParam.getChildren())); + } + } + bodies.add(httpParam); + + } + return bodies; + } + +} + diff --git a/src/main/java/com/power/doc/constants/DocGlobalConstants.java b/src/main/java/com/power/doc/constants/DocGlobalConstants.java index 167029f..45f6638 100644 --- a/src/main/java/com/power/doc/constants/DocGlobalConstants.java +++ b/src/main/java/com/power/doc/constants/DocGlobalConstants.java @@ -200,4 +200,6 @@ public interface DocGlobalConstants { String YAPI_JSON = "/yapi.json"; String DUBBO_SWAGGER = "org.apache.dubbo.rpc.protocol.rest.integration.swagger.DubboSwaggerApiListingResource"; + + String ARRAY = "array"; } diff --git a/src/main/java/com/power/doc/constants/TornaConstants.java b/src/main/java/com/power/doc/constants/TornaConstants.java new file mode 100644 index 0000000..57cd88d --- /dev/null +++ b/src/main/java/com/power/doc/constants/TornaConstants.java @@ -0,0 +1,153 @@ +/* + * smart-doc https://github.com/shalousun/smart-doc + * + * Copyright (C) 2018-2021 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.constants; + +import com.power.doc.model.ApiConfig; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * @author xingzi 2020/2/2 + */ +public class TornaConstants { + + + public static final String ID = "id"; + public static final String CODE = "code"; + public static final String MESSAGE = "msg"; + public static final String DATA = "data"; + public static final String SUCCESS_CODE = "0"; + + + public static final String YES = "1"; + public static final String NO = "0"; + public static final String ARRAY = "array"; + + public static final String CATEGORY_CREATE = "doc.category.create"; + public static final String PUSH = "doc.push"; + + + /** + * build torna params + * + * @param name interface name + * @param data json + * @param config ApiConfig + * @return Map + */ + public static Map buildParams(String name, String data, ApiConfig config) { + Map param = new HashMap<>(8); + try { + if (StringUtils.isNotBlank(data)) { + data = URLEncoder.encode(data, "utf-8"); + } + // 公共参数 + param.put("name", name); + param.put("app_key", config.getAppKey()); + param.put("data", data); + param.put("timestamp", getTime()); + param.put("version", "1.0"); + param.put("access_token", config.getAppToken()); + String sign = buildSign(param, config.getSecret()); + param.put("sign", sign); + return param; + } catch (IOException e) { + e.printStackTrace(); + } + return param; + } + + /** + * 构建签名 + * + * @param paramsMap 参数 + * @param secret 密钥 + * @return String + */ + public static String buildSign(Map paramsMap, String secret) { + Set keySet = paramsMap.keySet(); + List paramNames = new ArrayList<>(keySet); + + Collections.sort(paramNames); + StringBuilder paramNameValue = new StringBuilder(); + for (String paramName : paramNames) { + Object value = paramsMap.get(paramName); + if (value != null) { + paramNameValue.append(paramName).append(value); + } + } + String source = secret + paramNameValue.toString() + secret; + return md5(source); + } + + /** + * 生成md5,全部大写 + * + * @param message 消息 + * @return String + */ + public static String md5(String message) { + try { + // 1 创建一个提供信息摘要算法的对象,初始化为md5算法对象 + MessageDigest md = MessageDigest.getInstance("MD5"); + + // 2 将消息变成byte数组 + byte[] input = message.getBytes(); + + // 3 计算后获得字节数组,这就是那128位了 + byte[] buff = md.digest(input); + + // 4 把数组每一字节(一个字节占八位)换成16进制连成md5字符串 + return byte2hex(buff); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * 二进制转十六进制字符串 + * + * @param bytes byte array + * @return String + */ + private static String byte2hex(byte[] bytes) { + StringBuilder sign = new StringBuilder(); + for (int i = 0; i < bytes.length; i++) { + String hex = Integer.toHexString(bytes[i] & 0xFF); + if (hex.length() == 1) { + sign.append("0"); + } + sign.append(hex.toUpperCase()); + } + return sign.toString(); + } + + public static String getTime() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + } +} diff --git a/src/main/java/com/power/doc/helper/JsonBuildHelper.java b/src/main/java/com/power/doc/helper/JsonBuildHelper.java index 996493b..38ffb0a 100644 --- a/src/main/java/com/power/doc/helper/JsonBuildHelper.java +++ b/src/main/java/com/power/doc/helper/JsonBuildHelper.java @@ -163,7 +163,7 @@ public class JsonBuildHelper { data.append("{\"mapKey\":{}}"); return data.toString(); } - if (!DocGlobalConstants.JAVA_STRING_FULLY.equals(getKeyValType[0])) { + if ((!DocGlobalConstants.JAVA_STRING_FULLY.equals(getKeyValType[0])) && apiConfig.isStrict()) { 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(">")); diff --git a/src/main/java/com/power/doc/helper/ParamsBuildHelper.java b/src/main/java/com/power/doc/helper/ParamsBuildHelper.java index f025a76..81e6a65 100644 --- a/src/main/java/com/power/doc/helper/ParamsBuildHelper.java +++ b/src/main/java/com/power/doc/helper/ParamsBuildHelper.java @@ -357,6 +357,14 @@ public class ParamsBuildHelper { } } } + else { + String builder = "[" + + DocUtil.jsonValueByType(gName) + + "," + + DocUtil.jsonValueByType(gName) + + "]"; + param.setValue(DocUtil.handleJsonStr(builder)); + } } else if (subTypeName.length() == 1 || DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) { // handle java generic or object if (isGenerics && DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) { diff --git a/src/main/java/com/power/doc/model/ApiConfig.java b/src/main/java/com/power/doc/model/ApiConfig.java index f32e0a2..3e6fb6f 100644 --- a/src/main/java/com/power/doc/model/ApiConfig.java +++ b/src/main/java/com/power/doc/model/ApiConfig.java @@ -25,6 +25,7 @@ package com.power.doc.model; import com.power.common.util.CollectionUtil; import com.power.doc.constants.DocLanguage; import com.power.doc.model.rpc.RpcApiDependency; +import com.power.doc.model.torna.DebugEnv; import java.util.List; import java.util.Objects; @@ -270,6 +271,107 @@ public class ApiConfig { */ private boolean createDebugPage; + /** + * public static final String APP_KEY = "20201216788835306945118208"; + * public static final String SECRET = "W.ZyGMOB9Q0UqujVxnfi@.I#V&tUUYZR"; + * public static final String APP_TOKEN = "2f9a7d3858a147b7845ebb48785d4dc7"; + * public static final String OPEN_URL = "http://torna.opensphere.cn/api/"; + * @return + */ + /** + * Torna appKey + */ + private String appKey; + /** + * Torna Secret + */ + private String secret; + /** + * Torna appToken + */ + private String appToken; + /** + * Torna openUrl + */ + private String openUrl; + + /** + * 调试环境名称 + */ + private String debugEnvName; + /** + * 调试环境请求路径 + */ + private String debugEnvUrl; + + public void setSourceCodePaths(List sourceCodePaths) { + this.sourceCodePaths = sourceCodePaths; + } + + public void setRequestHeaders(List requestHeaders) { + this.requestHeaders = requestHeaders; + } + + public void setCustomResponseFields(List customResponseFields) { + this.customResponseFields = customResponseFields; + } + + public void setRevisionLogs(List revisionLogs) { + this.revisionLogs = revisionLogs; + } + + public void setDataDictionaries(List dataDictionaries) { + this.dataDictionaries = dataDictionaries; + } + + public void setErrorCodeDictionaries(List errorCodeDictionaries) { + this.errorCodeDictionaries = errorCodeDictionaries; + } + + public void setApiObjectReplacements(List apiObjectReplacements) { + this.apiObjectReplacements = apiObjectReplacements; + } + + public void setRpcApiDependencies(List rpcApiDependencies) { + this.rpcApiDependencies = rpcApiDependencies; + } + + public void setApiConstants(List apiConstants) { + this.apiConstants = apiConstants; + } + + public String getAppKey() { + return appKey; + } + + public void setAppKey(String appKey) { + this.appKey = appKey; + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + public String getAppToken() { + return appToken; + } + + public void setAppToken(String appToken) { + this.appToken = appToken; + } + + public String getOpenUrl() { + return openUrl; + } + + public void setOpenUrl(String openUrl) { + this.openUrl = openUrl; + } + public String getServerUrl() { return serverUrl; } @@ -603,6 +705,22 @@ public class ApiConfig { this.createDebugPage = createDebugPage; } + public String getDebugEnvName() { + return debugEnvName; + } + + public void setDebugEnvName(String debugEnvName) { + this.debugEnvName = debugEnvName; + } + + public String getDebugEnvUrl() { + return debugEnvUrl; + } + + public void setDebugEnvUrl(String debugEnvUrl) { + this.debugEnvUrl = debugEnvUrl; + } + @Override public String toString() { final StringBuilder sb = new StringBuilder("{"); diff --git a/src/main/java/com/power/doc/model/torna/Apis.java b/src/main/java/com/power/doc/model/torna/Apis.java new file mode 100644 index 0000000..e3a0e49 --- /dev/null +++ b/src/main/java/com/power/doc/model/torna/Apis.java @@ -0,0 +1,149 @@ +/* + * smart-doc https://github.com/shalousun/smart-doc + * + * Copyright (C) 2018-2021 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.model.torna; + +import java.util.List; + +/** + * @author xingzi 2021/2/8 10:07 + **/ +public class Apis { + private String name; + private String description; + private String url; + private String httpMethod; + private String contentType; + private String isFolder; + private String parentId; + private String isShow; + private List headerParams; + private List requestParams; + private List responseParams; + private String errorCodeParams; + private String items; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getHttpMethod() { + return httpMethod; + } + + public void setHttpMethod(String httpMethod) { + this.httpMethod = httpMethod; + } + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public String getIsFolder() { + return isFolder; + } + + public void setIsFolder(String isFolder) { + this.isFolder = isFolder; + } + + public String getParentId() { + return parentId; + } + + public void setParentId(String parentId) { + this.parentId = parentId; + } + + public String getIsShow() { + return isShow; + } + + public void setIsShow(String isShow) { + this.isShow = isShow; + } + + + public List getRequestParams() { + return requestParams; + } + + public void setRequestParams(List requestParams) { + this.requestParams = requestParams; + } + + public List getHeaderParams() { + return headerParams; + } + + public void setHeaderParams(List headerParams) { + this.headerParams = headerParams; + } + + public List getResponseParams() { + return responseParams; + } + + public void setResponseParams(List responseParams) { + this.responseParams = responseParams; + } + + public String getErrorCodeParams() { + return errorCodeParams; + } + + public void setErrorCodeParams(String errorCodeParams) { + this.errorCodeParams = errorCodeParams; + } + + public String getItems() { + return items; + } + + public void setItems(String items) { + this.items = items; + } +} diff --git a/src/main/java/com/power/doc/model/torna/DebugEnv.java b/src/main/java/com/power/doc/model/torna/DebugEnv.java new file mode 100644 index 0000000..740e820 --- /dev/null +++ b/src/main/java/com/power/doc/model/torna/DebugEnv.java @@ -0,0 +1,48 @@ +/* + * smart-doc https://github.com/shalousun/smart-doc + * + * Copyright (C) 2018-2021 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.model.torna; + +/** + * @author Lixin 2021/2/25 1:18 + **/ +public class DebugEnv { + + private String name; + private String url; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/src/main/java/com/power/doc/model/torna/EnumInfo.java b/src/main/java/com/power/doc/model/torna/EnumInfo.java new file mode 100644 index 0000000..5c72c8a --- /dev/null +++ b/src/main/java/com/power/doc/model/torna/EnumInfo.java @@ -0,0 +1,72 @@ +/* + * smart-doc https://github.com/shalousun/smart-doc + * + * Copyright (C) 2018-2021 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.model.torna; + +import java.util.List; + +/** + * @author: xingzi 2021/2/25 12:13 + **/ +public class EnumInfo { + /** + * "enumInfo": { + * "name": "支付枚举", + * "description": "支付状态", + * "items": [ + * { + * "name": "WAIT_PAY", + * "type": "string", + * "value": "0", + * "description": "未支付" + * } + * ] + * } + */ + private String name; + private String description; + private List items; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/src/main/java/com/power/doc/model/torna/HttpParam.java b/src/main/java/com/power/doc/model/torna/HttpParam.java new file mode 100644 index 0000000..0469f9f --- /dev/null +++ b/src/main/java/com/power/doc/model/torna/HttpParam.java @@ -0,0 +1,140 @@ +/* + * smart-doc https://github.com/shalousun/smart-doc + * + * Copyright (C) 2018-2021 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.model.torna; + +import java.util.List; + +/** + * @author xingzi 2021/2/8 22:40 + **/ +public class HttpParam { + + private String name; + private String type; + private String value; + private String required; + private String maxLength; + private String example; + private String description; + private String parentId; + private String code; + private String msg; + private String solution; + private List children; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getRequired() { + return required; + } + + public void setRequired(String required) { + this.required = required; + } + + public String getMaxLength() { + return maxLength; + } + + public void setMaxLength(String maxLength) { + this.maxLength = maxLength; + } + + public String getExample() { + return example; + } + + public void setExample(String example) { + this.example = example; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getParentId() { + return parentId; + } + + public void setParentId(String parentId) { + this.parentId = parentId; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public String getSolution() { + return solution; + } + + public void setSolution(String solution) { + this.solution = solution; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } +} diff --git a/src/main/java/com/power/doc/model/torna/Item.java b/src/main/java/com/power/doc/model/torna/Item.java new file mode 100644 index 0000000..f1a809f --- /dev/null +++ b/src/main/java/com/power/doc/model/torna/Item.java @@ -0,0 +1,73 @@ +/* + * smart-doc https://github.com/shalousun/smart-doc + * + * Copyright (C) 2018-2021 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.model.torna; + +/** + * @author xingzi 2021/2/25 12:29 + **/ +public class Item { + /** + * { + * * "name": "WAIT_PAY", + * * "type": "string", + * * "value": "0", + * * "description": "未支付" + * * } + */ + private String name; + private String type; + private String value; + private String description; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/src/main/java/com/power/doc/model/torna/TornaApi.java b/src/main/java/com/power/doc/model/torna/TornaApi.java new file mode 100644 index 0000000..a10a9e9 --- /dev/null +++ b/src/main/java/com/power/doc/model/torna/TornaApi.java @@ -0,0 +1,59 @@ +/* + * smart-doc https://github.com/shalousun/smart-doc + * + * Copyright (C) 2018-2021 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.model.torna; + +import java.util.List; + +/** + * @author xingzi 2021/2/25 1:09 + **/ +public class TornaApi { + + /** + * "debugEnvs": [ + * { + * "name": "测试环境", + * "url": "http://10.1.30.165:2222" + * } + * ], + * "apis": [ + */ + List debugEnvs; + List apis; + + public List getDebugEnvs() { + return debugEnvs; + } + + public void setDebugEnvs(List debugEnvs) { + this.debugEnvs = debugEnvs; + } + + public List getApis() { + return apis; + } + + public void setApis(List apis) { + this.apis = apis; + } +} diff --git a/src/test/java/com/power/doc/ApiDocTest.java b/src/test/java/com/power/doc/ApiDocTest.java index b87747e..393a682 100644 --- a/src/test/java/com/power/doc/ApiDocTest.java +++ b/src/test/java/com/power/doc/ApiDocTest.java @@ -4,6 +4,7 @@ import com.power.common.util.DateTimeUtil; import com.power.doc.builder.HtmlApiDocBuilder; import com.power.doc.builder.OpenApiBuilder; import com.power.doc.builder.PostmanJsonBuilder; +import com.power.doc.builder.TornaBuilder; import com.power.doc.enums.OrderEnum; import com.power.doc.model.*; import org.junit.Test; @@ -30,17 +31,24 @@ public class ApiDocTest { ApiConfig config = new ApiConfig(); config.setServerUrl("http://localhost:8080"); //config.setStrict(true); + config.setOpenUrl("http://torna.opensphere.cn/api/"); + config.setAppKey("20201216788835306945118208"); + config.setAppToken("2f9a7d3858a147b7845ebb48785d4dc7"); + config.setSecret("W.ZyGMOB9Q0UqujVxnfi@.I#V&tUUYZR"); + config.setDebugEnvName("测试环境"); + config.setDebugEnvUrl("http://127.0.0.1"); config.setAllInOne(true); config.setOutPath("d:\\md3"); config.setMd5EncryptedHtmlName(true); //不指定SourcePaths默认加载代码为项目src/main/java下的 config.setSourceCodePaths( - SourceCodePath.builder().setDesc("本项目代码").setPath("C:\\Users\\xingzi\\Desktop\\smart\\api-doc-test\\src\\main\\java\\com\\power\\doc") - + SourceCodePath.builder().setDesc("本项目代码") + .setPath("C:\\Users\\xingzi\\Desktop\\api-doc-test\\src\\main\\java") //SourcePath.path().setPath("F:\\Personal\\project\\smart\\src\\main\\java") //SourcePath.path().setDesc("加载项目外代码").setPath("E:\\ApplicationPower\\ApplicationPower\\Common-util\\src\\main\\java") ); + config.setPackageFilters("com.power.doc.controller.UserController"); config.setDataDictionaries( ApiDataDictionary.builder().setTitle("订单字典").setEnumClass(OrderEnum.class).setCodeField("code").setDescField("desc") ); @@ -67,7 +75,8 @@ public class ApiDocTest { long start = System.currentTimeMillis(); // OpenApiBuilder.buildOpenApi(config); - HtmlApiDocBuilder.buildApiDoc(config); + //HtmlApiDocBuilder.buildApiDoc(config); + TornaBuilder.buildApiDoc(config); long end = System.currentTimeMillis(); DateTimeUtil.printRunTime(end, start); }