Merge remote-tracking branch 'origin/torna'

This commit is contained in:
oppofind 2021-03-12 23:23:29 +08:00
commit 61807e0b94
18 changed files with 1178 additions and 16 deletions

View File

@ -1,5 +1,11 @@
## smart-doc版本 ## smart-doc版本
版本小于1.0都属于试用正式1.0起始发布将会等到文中提到的问题解决后才发布。 版本小于1.0都属于试用正式1.0起始发布将会等到文中提到的问题解决后才发布。
#### 版本号2.0.9
- 更新日期: 2020-03-12
- 更新内容:
1. 支持UUID和ZonedDateTime字段类型#89。
2. 对map参数增加开关来兼容旧项目还是不建议使用map参数。
3. 完成和Torna的对接。
#### 版本号2.0.8 #### 版本号2.0.8
- 更新日期: 2020-02-26 - 更新日期: 2020-02-26
- 更新内容: - 更新内容:

View File

@ -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. - Support for exporting error codes and data dictionary codes to API documentation.
- The debug html5 page fully supports file upload and download testing. - The debug html5 page fully supports file upload and download testing.
- Support Apache Dubbo RPC. - 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 ## Getting Started
[Smart-doc Samples](https://github.com/shalousun/smart-doc-demo.git)。 [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. "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. "responseExample":"true",//Whether to display the response example in the document, the default is true.
"displayActualType":false,//display actual type of generic, "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 "ignoreRequestParams":[ //The request parameter object will be discarded when generating the document.@since 1.9.2
"org.springframework.ui.ModelMap" "org.springframework.ui.ModelMap"
], ],
@ -173,6 +181,8 @@ mvn -Dfile.encoding=UTF-8 smart-doc: markdown
mvn -Dfile.encoding=UTF-8 smart-doc:adoc mvn -Dfile.encoding=UTF-8 smart-doc:adoc
// Generate postman collection // 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 // Apache Dubbo RPC
// Generate html // Generate html

View File

@ -32,6 +32,11 @@ $\color{red}{你给我的star胜过所有读过的诗—smart-doc}$
- 支持Maven、Gradle插件式轻松集成。 - 支持Maven、Gradle插件式轻松集成。
- 支持Apache Dubbo RPC接口文档生成。 - 支持Apache Dubbo RPC接口文档生成。
- debug接口调试html5页面完全支持文件上传下载(@download tag标记下载方法)测试。 - 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 ## Getting Started
smart-doc使用和测试可参考[smart-doc demo](https://gitee.com/devin-alan/api-doc-test.git)。 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 "requestExample":"true",//是否将请求示例展示在文档中默认true@since 1.9.0
"responseExample":"true",//是否将响应示例展示在文档中默认为true@since 1.9.0 "responseExample":"true",//是否将响应示例展示在文档中默认为true@since 1.9.0
"displayActualType":false,//配置true会在注释栏自动显示泛型的真实类型短类名@since 1.9.6 "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 "ignoreRequestParams":[ //忽略请求参数对象,把不想生成文档的参数对象屏蔽掉,@since 1.9.2
"org.springframework.ui.ModelMap" "org.springframework.ui.ModelMap"
], ],
@ -189,6 +200,8 @@ mvn -Dfile.encoding=UTF-8 smart-doc:adoc
mvn -Dfile.encoding=UTF-8 smart-doc:postman mvn -Dfile.encoding=UTF-8 smart-doc:postman
// 生成 Open Api 3.0+,Since smart-doc-maven-plugin 1.1.5 // 生成 Open Api 3.0+,Since smart-doc-maven-plugin 1.1.5
mvn -Dfile.encoding=UTF-8 smart-doc:openapi mvn -Dfile.encoding=UTF-8 smart-doc:openapi
// 生成文档推送到Torna平台
mvn -Dfile.encoding=UTF-8 smart-doc:torna-rest
// Apache Dubbo RPC文档 // Apache Dubbo RPC文档
// Generate html // Generate html

View File

@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>smart-doc</artifactId> <artifactId>smart-doc</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>2.0.8</version> <version>2.0.9</version>
<name>smart-doc</name> <name>smart-doc</name>
<url>https://github.com/smart-doc-group/smart-doc.git</url> <url>https://github.com/smart-doc-group/smart-doc.git</url>
@ -72,6 +72,11 @@
<artifactId>gson</artifactId> <artifactId>gson</artifactId>
<version>2.8.6</version> <version>2.8.6</version>
</dependency> </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>

View File

@ -270,7 +270,7 @@ public class OpenApiBuilder {
} else if (!isRep && Objects.nonNull(apiMethodDoc.getRequestSchema())) { } else if (!isRep && Objects.nonNull(apiMethodDoc.getRequestSchema())) {
content.put("schema", apiMethodDoc.getRequestSchema()); content.put("schema", apiMethodDoc.getRequestSchema());
} else { } else {
content.put("schema", buildBodySchema(apiMethodDoc.getPath(), isRep)); content.put("schema", buildBodySchema(apiMethodDoc, isRep));
} }
} }
content.put("examples", buildBodyExample(apiMethodDoc, isRep)); content.put("examples", buildBodyExample(apiMethodDoc, isRep));
@ -281,18 +281,37 @@ public class OpenApiBuilder {
/** /**
* content body 的schema 信息 * content body 的schema 信息
* *
* @param url 请求的url 去除server * @param apiMethodDoc 请求方法参数 去除server
* @param isRep 是否是返回数据 * @param isRep 是否是返回数据
* @return * @return
*/ */
private static Map<String, Object> buildBodySchema(String url, boolean isRep) { private static Map<String, Object> buildBodySchema(ApiMethodDoc apiMethodDoc, boolean isRep) {
Map<String, Object> schema = new HashMap<>(10); Map<String, Object> schema = new HashMap<>(10);
//当类型为数组时使用
Map<String, Object> innerScheme = new HashMap<>(10);
//去除url中的特殊字符 //去除url中的特殊字符
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) { if (isRep) {
schema.put("$ref", "#/components/schemas/" + url.replaceAll(PATH_REGEX, "_") + "response"); innerScheme.put("$ref", responseRef);
} else { } else {
schema.put("$ref", "#/components/schemas/" + url.replaceAll(PATH_REGEX, "_") + "request"); innerScheme.put("$ref", requestRef);
} }
schema.put("items",innerScheme);
}
else {
if (isRep) {
schema.put("$ref", responseRef);
} else {
schema.put("$ref", requestRef);
}
}
return schema; return schema;
} }

View File

@ -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<ApiDoc> apiDocList = new SpringBootDocBuildTemplate().getApiData(configBuilder);
buildTorna(apiDocList, config);
}
/**
* build torna Data
*
* @param apiDocs apiData
* @param apiConfig ApiConfig
*/
public static void buildTorna(List<ApiDoc> 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<ApiMethodDoc> apiMethodDocs = a.getList();
//参数列表
List<Apis> apis = new ArrayList<>();
//环境列表
List<DebugEnv> 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<HttpParam> buildHerder(List<ApiReqHeader> apiReqHeaders) {
/**
* name": "token",
* "required": "1",
* "example": "iphone12",
* "description": "商品名称描述"
*/
HttpParam httpParam;
List<HttpParam> 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<HttpParam> buildParams(List<ApiParam> apiParams) {
HttpParam httpParam;
List<HttpParam> 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;
}
}

View File

@ -200,4 +200,6 @@ public interface DocGlobalConstants {
String YAPI_JSON = "/yapi.json"; String YAPI_JSON = "/yapi.json";
String DUBBO_SWAGGER = "org.apache.dubbo.rpc.protocol.rest.integration.swagger.DubboSwaggerApiListingResource"; String DUBBO_SWAGGER = "org.apache.dubbo.rpc.protocol.rest.integration.swagger.DubboSwaggerApiListingResource";
String ARRAY = "array";
} }

View File

@ -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<String, String> buildParams(String name, String data, ApiConfig config) {
Map<String, String> 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<String, ?> paramsMap, String secret) {
Set<String> keySet = paramsMap.keySet();
List<String> 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());
}
}

View File

@ -163,7 +163,7 @@ public class JsonBuildHelper {
data.append("{\"mapKey\":{}}"); data.append("{\"mapKey\":{}}");
return data.toString(); 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]); 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(">")); String gicName = gNameTemp.substring(gNameTemp.indexOf(",") + 1, gNameTemp.lastIndexOf(">"));

View File

@ -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)) { } else if (subTypeName.length() == 1 || DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) {
// handle java generic or object // handle java generic or object
if (isGenerics && DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) { if (isGenerics && DocGlobalConstants.JAVA_OBJECT_FULLY.equals(subTypeName)) {

View File

@ -25,6 +25,7 @@ package com.power.doc.model;
import com.power.common.util.CollectionUtil; import com.power.common.util.CollectionUtil;
import com.power.doc.constants.DocLanguage; import com.power.doc.constants.DocLanguage;
import com.power.doc.model.rpc.RpcApiDependency; import com.power.doc.model.rpc.RpcApiDependency;
import com.power.doc.model.torna.DebugEnv;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -270,6 +271,107 @@ public class ApiConfig {
*/ */
private boolean createDebugPage; 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<SourceCodePath> sourceCodePaths) {
this.sourceCodePaths = sourceCodePaths;
}
public void setRequestHeaders(List<ApiReqHeader> requestHeaders) {
this.requestHeaders = requestHeaders;
}
public void setCustomResponseFields(List<CustomRespField> customResponseFields) {
this.customResponseFields = customResponseFields;
}
public void setRevisionLogs(List<RevisionLog> revisionLogs) {
this.revisionLogs = revisionLogs;
}
public void setDataDictionaries(List<ApiDataDictionary> dataDictionaries) {
this.dataDictionaries = dataDictionaries;
}
public void setErrorCodeDictionaries(List<ApiErrorCodeDictionary> errorCodeDictionaries) {
this.errorCodeDictionaries = errorCodeDictionaries;
}
public void setApiObjectReplacements(List<ApiObjectReplacement> apiObjectReplacements) {
this.apiObjectReplacements = apiObjectReplacements;
}
public void setRpcApiDependencies(List<RpcApiDependency> rpcApiDependencies) {
this.rpcApiDependencies = rpcApiDependencies;
}
public void setApiConstants(List<ApiConstant> 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() { public String getServerUrl() {
return serverUrl; return serverUrl;
} }
@ -603,6 +705,22 @@ public class ApiConfig {
this.createDebugPage = createDebugPage; 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 @Override
public String toString() { public String toString() {
final StringBuilder sb = new StringBuilder("{"); final StringBuilder sb = new StringBuilder("{");

View File

@ -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<HttpParam> headerParams;
private List<HttpParam> requestParams;
private List<HttpParam> 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<HttpParam> getRequestParams() {
return requestParams;
}
public void setRequestParams(List<HttpParam> requestParams) {
this.requestParams = requestParams;
}
public List<HttpParam> getHeaderParams() {
return headerParams;
}
public void setHeaderParams(List<HttpParam> headerParams) {
this.headerParams = headerParams;
}
public List<HttpParam> getResponseParams() {
return responseParams;
}
public void setResponseParams(List<HttpParam> 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;
}
}

View File

@ -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;
}
}

View File

@ -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<Item> 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<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
}

View File

@ -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<HttpParam> 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<HttpParam> getChildren() {
return children;
}
public void setChildren(List<HttpParam> children) {
this.children = children;
}
}

View File

@ -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;
}
}

View File

@ -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<DebugEnv> debugEnvs;
List<Apis> apis;
public List<DebugEnv> getDebugEnvs() {
return debugEnvs;
}
public void setDebugEnvs(List<DebugEnv> debugEnvs) {
this.debugEnvs = debugEnvs;
}
public List<Apis> getApis() {
return apis;
}
public void setApis(List<Apis> apis) {
this.apis = apis;
}
}

View File

@ -4,6 +4,7 @@ import com.power.common.util.DateTimeUtil;
import com.power.doc.builder.HtmlApiDocBuilder; import com.power.doc.builder.HtmlApiDocBuilder;
import com.power.doc.builder.OpenApiBuilder; import com.power.doc.builder.OpenApiBuilder;
import com.power.doc.builder.PostmanJsonBuilder; import com.power.doc.builder.PostmanJsonBuilder;
import com.power.doc.builder.TornaBuilder;
import com.power.doc.enums.OrderEnum; import com.power.doc.enums.OrderEnum;
import com.power.doc.model.*; import com.power.doc.model.*;
import org.junit.Test; import org.junit.Test;
@ -30,17 +31,24 @@ public class ApiDocTest {
ApiConfig config = new ApiConfig(); ApiConfig config = new ApiConfig();
config.setServerUrl("http://localhost:8080"); config.setServerUrl("http://localhost:8080");
//config.setStrict(true); //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.setAllInOne(true);
config.setOutPath("d:\\md3"); config.setOutPath("d:\\md3");
config.setMd5EncryptedHtmlName(true); config.setMd5EncryptedHtmlName(true);
//不指定SourcePaths默认加载代码为项目src/main/java下的 //不指定SourcePaths默认加载代码为项目src/main/java下的
config.setSourceCodePaths( 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().setPath("F:\\Personal\\project\\smart\\src\\main\\java")
//SourcePath.path().setDesc("加载项目外代码").setPath("E:\\ApplicationPower\\ApplicationPower\\Common-util\\src\\main\\java") //SourcePath.path().setDesc("加载项目外代码").setPath("E:\\ApplicationPower\\ApplicationPower\\Common-util\\src\\main\\java")
); );
config.setPackageFilters("com.power.doc.controller.UserController");
config.setDataDictionaries( config.setDataDictionaries(
ApiDataDictionary.builder().setTitle("订单字典").setEnumClass(OrderEnum.class).setCodeField("code").setDescField("desc") ApiDataDictionary.builder().setTitle("订单字典").setEnumClass(OrderEnum.class).setCodeField("code").setDescField("desc")
); );
@ -67,7 +75,8 @@ public class ApiDocTest {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
// OpenApiBuilder.buildOpenApi(config); // OpenApiBuilder.buildOpenApi(config);
HtmlApiDocBuilder.buildApiDoc(config); //HtmlApiDocBuilder.buildApiDoc(config);
TornaBuilder.buildApiDoc(config);
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
DateTimeUtil.printRunTime(end, start); DateTimeUtil.printRunTime(end, start);
} }