merge to master

This commit is contained in:
oppofind 2020-01-09 20:18:02 +08:00
commit 2cdb1ef9c5
24 changed files with 289 additions and 1572 deletions

View File

@ -160,4 +160,11 @@
8. postman json生成支持所有参数自动回填。再也不用自己建参数了。
9. 优化对实体类中枚举字段的支持。
10. 增加对实体中静态常量常量字段的过滤。
#### 版本号1.8.1
- 更新日期: 2020-01-xx
- 更新内容:
1. 增加对接口get方法的分析。
2. 增加对第三方jar中list泛型数据的解析。
3. 删除原来冗长的SourceBuilder代码。
4. 修改AdocDocBuilder、HtmlApiDocBuilder、ApiDocBuilder的方法名规范化单元测试的升级需要做小部分变更。

View File

@ -152,10 +152,11 @@ mvn clean install -Dmaven.test.skip=true
These are only part of the companies using smart-doc, for reference only. If you are using smart-doc, please [add your company here](https://github.com/shalousun/smart-doc/issues/12) to tell us your scenario to make smart-doc better.
![iFLYTEK](https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/iflytek.png)
![OnePlus](https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/oneplus.png)
![Xiaomi](https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/xiaomi.png)
![远盟健康](https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/yuanmengjiankang.png)
![上海普彻信息科技](https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/puqie_gaitubao_100x100.jpg)
&nbsp;&nbsp;<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/oneplus.png" title="OnePlus" width="83px" height="83px"/>
&nbsp;&nbsp;<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/xiaomi.png" title="Xiaomi" width="170px" height="83px"/>
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/yuanmengjiankang.png" title="yuanmengjiankang" width="260px" height="83px"/>
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/zhongkezhilian.png" title="zhongkezhilian" width="272px" height="83px"/>
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/puqie_gaitubao_100x100.jpg" title="puqie" width="83px" height="83px"/>
## License
Smart-doc is under the Apache 2.0 license. See the [LICENSE](https://github.com/shalousun/smart-doc/blob/master/license.txt) file for details.
## Contact

View File

@ -162,11 +162,13 @@ Smart-doc is under the Apache 2.0 license. See the [LICENSE](https://gitee.com
## Who is using
> 排名不分先后,更多接入公司,欢迎在[https://gitee.com/sunyurepository/smart-doc/issues/I1594T](https://gitee.com/sunyurepository/smart-doc/issues/I1594T)登记(仅供开源用户参考)
![科大讯飞](https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/iflytek.png)
![一加手机](https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/oneplus.png)
![小米](https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/xiaomi.png)
![远盟健康](https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/yuanmengjiankang.png)
![上海普彻信息科技](https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/puqie_gaitubao_100x100.jpg)
![iFLYTEK](https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/iflytek.png)
&nbsp;&nbsp;<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/oneplus.png" title="一加" width="83px" height="83px"/>
&nbsp;&nbsp;<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/xiaomi.png" title="小米" width="170px" height="83px"/>
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/yuanmengjiankang.png" title="远盟健康" width="260px" height="83px"/>
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/zhongkezhilian.png" title="中科智链" width="272px" height="83px"/>
<img src="https://raw.githubusercontent.com/shalousun/smart-doc/dev/images/known-users/puqie_gaitubao_100x100.jpg" title="普切信息科技" width="83px" height="83px"/>
## Contact
愿意参与构建smart-doc或者是需要交流问题可以加入qq群

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -32,7 +32,7 @@
</developers>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<flexmark.version>0.50.40</flexmark.version>
<flexmark.version>0.50.46</flexmark.version>
</properties>
<dependencies>
<dependency>
@ -44,7 +44,7 @@
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>3.0.15.RELEASE</version>
<version>3.0.16.RELEASE</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.qdox</groupId>
@ -106,7 +106,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.1.0</version>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>

View File

@ -26,11 +26,20 @@ public class AdocDocBuilder {
*
* @param config ApiConfig
*/
public static void builderControllersApi(ApiConfig config) {
public static void builderApiDoc(ApiConfig config) {
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
buildApiDoc(config,javaProjectBuilder);
}
/**
* Used for plugin
* @param config ApiConfig
* @param javaProjectBuilder ProjectDocConfigBuilder
*/
public static void buildApiDoc(ApiConfig config,JavaProjectBuilder javaProjectBuilder) {
config.setAdoc(true);
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config);
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config,javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = new SpringBootDocBuildTemplate();
List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
@ -48,10 +57,11 @@ public class AdocDocBuilder {
* @param config ApiConfig
* @param controllerName controller name
*/
public static void buildSingleControllerApi(ApiConfig config, String controllerName) {
config.setAdoc(true);
public static void buildSingleApiDoc(ApiConfig config, String controllerName) {
config.setAdoc(false);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, new JavaProjectBuilder());
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config);
builderTemplate.buildSingleControllerApi(config.getOutPath(), controllerName, API_DOC_ADOC_TPL, API_EXTENSION);
builderTemplate.buildSingleApi(configBuilder, controllerName, API_DOC_ADOC_TPL, API_EXTENSION);
}
}

View File

@ -3,6 +3,8 @@ package com.power.doc.builder;
import com.power.doc.model.ApiAllData;
import com.power.doc.model.ApiConfig;
import com.power.doc.model.ApiDoc;
import com.power.doc.template.IDocBuildTemplate;
import com.power.doc.template.SpringBootDocBuildTemplate;
import com.thoughtworks.qdox.JavaProjectBuilder;
/**
@ -24,20 +26,4 @@ public class ApiDataBuilder {
builderTemplate.getApiData(config,javaProjectBuilder);
return builderTemplate.getApiData(config,javaProjectBuilder);
}
/**
* Get single api data
*
* @param config ApiConfig
* @param controllerName controller name
* @return ApiDoc
*/
public static ApiDoc getApiData(ApiConfig config, String controllerName) {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInitForGetApiData(config);
config.setMd5EncryptedHtmlName(true);
JavaProjectBuilder projectBuilder = new JavaProjectBuilder();
SourceBuilder sourceBuilder = new SourceBuilder(config,projectBuilder);
return sourceBuilder.getSingleControllerApiData(controllerName);
}
}

View File

@ -25,17 +25,26 @@ public class ApiDocBuilder {
/**
* @param config ApiConfig
*/
public static void builderControllersApi(ApiConfig config) {
config.setAdoc(false);
public static void buildApiDoc(ApiConfig config) {
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
buildApiDoc(config, javaProjectBuilder);
}
/**
* Used for plugin
* @param config ApiConfig
* @param javaProjectBuilder ProjectDocConfigBuilder
*/
public static void buildApiDoc(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
config.setAdoc(false);
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config,javaProjectBuilder);
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = new SpringBootDocBuildTemplate();
List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
if (config.isAllInOne()) {
String version = config.isCoverOld() ? "" : "-V" + DateTimeUtil.long2Str(System.currentTimeMillis(), DATE_FORMAT);
builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder,ALL_IN_ONE_MD_TPL, "AllInOne" + version + ".md");
builderTemplate.buildAllInOne(apiDocList, config, javaProjectBuilder, ALL_IN_ONE_MD_TPL, "AllInOne" + version + ".md");
} else {
builderTemplate.buildApiDoc(apiDocList, config, API_DOC_MD_TPL, API_EXTENSION);
builderTemplate.buildErrorCodeDoc(config, ERROR_CODE_LIST_MD_TPL, ERROR_CODE_LIST_MD);
@ -48,10 +57,12 @@ public class ApiDocBuilder {
* @param config (ApiConfig
* @param controllerName controller name
*/
public static void buildSingleControllerApi(ApiConfig config, String controllerName) {
public static void buildSingleApiDoc(ApiConfig config, String controllerName) {
config.setAdoc(false);
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config, javaProjectBuilder);
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config);
builderTemplate.buildSingleControllerApi(config.getOutPath(), controllerName, API_DOC_MD_TPL, API_EXTENSION);
builderTemplate.buildSingleApi(configBuilder, controllerName, API_DOC_MD_TPL, API_EXTENSION);
}
}

View File

@ -66,7 +66,7 @@ public class DocBuilderTemplate {
public ApiAllData getApiData(ApiConfig config, JavaProjectBuilder javaProjectBuilder) {
ApiAllData apiAllData = new ApiAllData();
apiAllData.setProjectName(config.getProjectName());
apiAllData.setProjectId(DocUtil.handleId(config.getProjectName()));
apiAllData.setProjectId(DocUtil.generateId(config.getProjectName()));
apiAllData.setLanguage(config.getLanguage().getCode());
apiAllData.setApiDocList(listOfApiData(config, javaProjectBuilder));
apiAllData.setErrorCodeList(errorCodeDictToList(config));
@ -167,15 +167,16 @@ public class DocBuilderTemplate {
* @param template template
* @param fileExtension file extension
*/
public void buildSingleControllerApi(String outPath, String controllerName, String template, String fileExtension) {
FileUtil.mkdirs(outPath);
SourceBuilder sourceBuilder = new SourceBuilder(Boolean.TRUE, new JavaProjectBuilder());
ApiDoc doc = sourceBuilder.getSingleControllerApiData(controllerName);
public void buildSingleApi(ProjectDocConfigBuilder projectBuilder, String controllerName, String template, String fileExtension) {
ApiConfig config = projectBuilder.getApiConfig();
FileUtil.mkdirs(config.getOutPath());
IDocBuildTemplate docBuildTemplate = new SpringBootDocBuildTemplate();
ApiDoc doc = docBuildTemplate.getSingleApiData(projectBuilder,controllerName);
Template mapper = BeetlTemplateUtil.getByName(template);
mapper.binding(TemplateVariable.DESC.getVariable(), doc.getDesc());
mapper.binding(TemplateVariable.NAME.getVariable(), doc.getName());
mapper.binding(TemplateVariable.LIST.getVariable(), doc.getList());
FileUtil.writeFileNotAppend(mapper.render(), outPath + FILE_SEPARATOR + doc.getName() + fileExtension);
FileUtil.writeFileNotAppend(mapper.render(), config.getOutPath() + FILE_SEPARATOR + doc.getName() + fileExtension);
}
/**

View File

@ -37,10 +37,19 @@ public class HtmlApiDocBuilder {
*
* @param config config
*/
public static void builderControllersApi(ApiConfig config) {
public static void buildApiDoc(ApiConfig config) {
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
buildApiDoc(config,javaProjectBuilder);
}
/**
* Used for plugin
* @param config ApiConfig
* @param javaProjectBuilder ProjectDocConfigBuilder
*/
public static void buildApiDoc(ApiConfig config,JavaProjectBuilder javaProjectBuilder) {
DocBuilderTemplate builderTemplate = new DocBuilderTemplate();
builderTemplate.checkAndInit(config);
JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
ProjectDocConfigBuilder configBuilder = new ProjectDocConfigBuilder(config,javaProjectBuilder);
IDocBuildTemplate docBuildTemplate = new SpringBootDocBuildTemplate();
List<ApiDoc> apiDocList = docBuildTemplate.getApiData(configBuilder);
@ -52,11 +61,10 @@ public class HtmlApiDocBuilder {
List<ApiDocDict> apiDocDictList = builderTemplate.buildDictionary(config,javaProjectBuilder);
buildIndex(apiDocList, config);
copyCss(config.getOutPath());
buildApiDoc(apiDocList, config.getOutPath());
buildDoc(apiDocList, config.getOutPath());
buildErrorCodeDoc(config.getErrorCodes(), config.getOutPath());
buildDictionary(apiDocDictList, config.getOutPath());
}
}
private static void copyCss(String outPath) {
@ -111,7 +119,7 @@ public class HtmlApiDocBuilder {
* @param apiDocList list of api doc
* @param outPath output path
*/
private static void buildApiDoc(List<ApiDoc> apiDocList, String outPath) {
private static void buildDoc(List<ApiDoc> apiDocList, String outPath) {
FileUtil.mkdirs(outPath);
Template htmlApiDoc;
String strTime = DateTimeUtil.long2Str(now, DateTimeUtil.DATE_FORMAT_SECOND);

View File

@ -12,6 +12,7 @@ import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import java.io.File;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -50,6 +51,7 @@ public class ProjectDocConfigBuilder {
} else {
this.serverUrl = apiConfig.getServerUrl();
}
javaProjectBuilder.setEncoding(Charset.defaultCharset().toString());
this.javaProjectBuilder = javaProjectBuilder;
this.loadJavaSource(apiConfig.getSourceCodePaths(),this.javaProjectBuilder);
this.initClassFilesMap();

File diff suppressed because it is too large Load Diff

View File

@ -105,8 +105,6 @@ public class DocGlobalConstants {
public static final String POSTMAN_MODE_RAW ="raw";
public static final String HTTP_POST = "POST";
public static final String SHORT_MULTIPART_FILE_FULLY = "MultipartFile";
public static final String DEFAULT_SERVER_URL = "http://{server}";
@ -118,8 +116,4 @@ public class DocGlobalConstants {
public static final String CURL_POST_JSON = "curl -X POST -H 'Content-Type: application/json; charset=utf-8' -i ";
public static final String ENMPTY = "";
public static final String STATIC = "static";
public static final String FINAL = "final";
}

View File

@ -70,10 +70,7 @@ public class FormDataBuildHelper {
String subTypeName = field.getType().getFullyQualifiedName();
String fieldGicName = field.getType().getGenericCanonicalName();
JavaClass javaClass = builder.getJavaProjectBuilder().getClassByName(subTypeName);
boolean ignoreField = field.getModifiers().stream()
.anyMatch(str -> str.equals(DocGlobalConstants.STATIC) || str.equals(DocGlobalConstants.FINAL));
if (ignoreField || "this$0".equals(fieldName) ||
"serialVersionUID".equals(fieldName) ||
if (field.isStatic() || "this$0".equals(fieldName) ||
JavaClassValidateUtil.isIgnoreFieldTypes(subTypeName)) {
continue;
}

View File

@ -26,18 +26,18 @@ public class JsonBuildHelper {
/**
* build return json
*
* @param method The JavaMethod object
* @param method The JavaMethod object
* @param builder ProjectDocConfigBuilder builder
* @return String
*/
public static String buildReturnJson(JavaMethod method, ProjectDocConfigBuilder builder) {
if ("void".equals(method.getReturnType().getFullyQualifiedName())) {
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, true, 0, new HashMap<>(),builder));
return JsonFormatUtil.formatJson(buildJson(typeName, returnType, Boolean.TRUE, 0, new HashMap<>(), builder));
}
/**
@ -45,8 +45,8 @@ public class JsonBuildHelper {
* @param genericCanonicalName genericCanonicalName
* @param isResp Response flag
* @param counter Recursive counter
* @param registryClasses class container
* @param builder project config builder
* @param registryClasses class container
* @param builder project config builder
* @return String
*/
public static String buildJson(String typeName, String genericCanonicalName,
@ -66,7 +66,7 @@ public class JsonBuildHelper {
if (JavaClassValidateUtil.isPrimitive(typeName)) {
return StringUtil.removeQuotes(DocUtil.jsonValueByType(typeName));
}
if(javaClass.isEnum()){
if (javaClass.isEnum()) {
return String.valueOf(JavaClassUtil.getEnumValue(javaClass, Boolean.FALSE));
}
StringBuilder data0 = new StringBuilder();
@ -90,12 +90,12 @@ public class JsonBuildHelper {
data.append(DocUtil.jsonValueByType(gName));
} else if (gName.contains("<")) {
String simple = DocClassUtil.getSimpleName(gName);
String json = buildJson(simple, gName, isResp, counter + 1, registryClasses,builder);
String json = buildJson(simple, gName, isResp, counter + 1, registryClasses, builder);
data.append(json);
} else if (JavaClassValidateUtil.isCollection(gName)) {
data.append("\"any object\"");
} else {
String json = buildJson(gName, gName, isResp, counter + 1, registryClasses,builder);
String json = buildJson(gName, gName, isResp, counter + 1, registryClasses, builder);
data.append(json);
}
data.append("]");
@ -118,10 +118,10 @@ public class JsonBuildHelper {
data.append("\"mapKey2\":").append(DocUtil.jsonValueByType(gicName)).append("}");
} else if (gicName.contains("<")) {
String simple = DocClassUtil.getSimpleName(gicName);
String json = buildJson(simple, gicName, isResp, counter + 1, registryClasses,builder);
String json = buildJson(simple, gicName, isResp, counter + 1, registryClasses, builder);
data.append("{").append("\"mapKey\":").append(json).append("}");
} else {
data.append("{").append("\"mapKey\":").append(buildJson(gicName, gNameTemp, isResp, counter + 1, registryClasses,builder)).append("}");
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)) {
@ -137,11 +137,7 @@ public class JsonBuildHelper {
for (JavaField field : fields) {
String subTypeName = field.getType().getFullyQualifiedName();
String fieldName = field.getName();
boolean ignoreField = field.getModifiers().stream()
.anyMatch(str -> str.equals(DocGlobalConstants.STATIC) || str.equals(DocGlobalConstants.FINAL));
if (ignoreField || "this$0".equals(fieldName) ||
"serialVersionUID".equals(fieldName) ||
if (field.isStatic() || "this$0".equals(fieldName) ||
JavaClassValidateUtil.isIgnoreFieldTypes(subTypeName)) {
continue;
}
@ -201,7 +197,11 @@ public class JsonBuildHelper {
}
} else {
if (JavaClassValidateUtil.isCollection(subTypeName) || JavaClassValidateUtil.isArray(subTypeName)) {
if (globGicName.length > 0 && "java.util.List".equals(fieldGicName)) {
fieldGicName = fieldGicName + "<T>";
}
fieldGicName = JavaClassValidateUtil.isArray(subTypeName) ? fieldGicName.substring(0, fieldGicName.indexOf("[")) : fieldGicName;
if (DocClassUtil.getSimpleGicName(fieldGicName).length == 0) {
data0.append("{\"object\":\"any object\"},");
continue out;
@ -209,7 +209,7 @@ public class JsonBuildHelper {
String gicName = DocClassUtil.getSimpleGicName(fieldGicName)[0];
if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName)) {
data0.append("[").append("\"").append(buildJson(gicName, fieldGicName, isResp, counter + 1, registryClasses,builder)).append("\"]").append(",");
data0.append("[").append("\"").append(buildJson(gicName, fieldGicName, isResp, counter + 1, registryClasses, builder)).append("\"]").append(",");
} else if (DocGlobalConstants.JAVA_LIST_FULLY.equals(gicName)) {
data0.append("{\"object\":\"any object\"},");
} else if (gicName.length() == 1) {
@ -219,10 +219,10 @@ public class JsonBuildHelper {
}
String gicName1 = (i < globGicName.length) ? globGicName[i] : globGicName[globGicName.length - 1];
if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName1)) {
data0.append("[").append("\"").append(buildJson(gicName1, gicName1, isResp, counter + 1, registryClasses,builder)).append("\"]").append(",");
data0.append("[").append("\"").append(buildJson(gicName1, gicName1, isResp, counter + 1, registryClasses, builder)).append("\"]").append(",");
} else {
if (!typeName.equals(gicName1)) {
data0.append("[").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, counter + 1, registryClasses,builder)).append("]").append(",");
data0.append("[").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, counter + 1, registryClasses, builder)).append("]").append(",");
} else {
data0.append("[{\"$ref\":\"..\"}]").append(",");
}
@ -233,7 +233,7 @@ public class JsonBuildHelper {
data0.append("[{\"mapKey\":{}}],");
continue out;
}
data0.append("[").append(buildJson(gicName, fieldGicName, isResp, counter + 1, registryClasses,builder)).append("]").append(",");
data0.append("[").append(buildJson(gicName, fieldGicName, isResp, counter + 1, registryClasses, builder)).append("]").append(",");
} else {
data0.append("[{\"$ref\":\"..\"}]").append(",");
}
@ -247,16 +247,16 @@ public class JsonBuildHelper {
if (gicName.length() == 1) {
String gicName1 = (i < globGicName.length) ? globGicName[i] : globGicName[globGicName.length - 1];
if (DocGlobalConstants.JAVA_STRING_FULLY.equals(gicName1)) {
data0.append("{").append("\"mapKey\":\"").append(buildJson(gicName1, gicName1, isResp, counter + 1, registryClasses,builder)).append("\"},");
data0.append("{").append("\"mapKey\":\"").append(buildJson(gicName1, gicName1, isResp, counter + 1, registryClasses, builder)).append("\"},");
} else {
if (!typeName.equals(gicName1)) {
data0.append("{").append("\"mapKey\":").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, counter + 1, registryClasses,builder)).append("},");
data0.append("{").append("\"mapKey\":").append(buildJson(DocClassUtil.getSimpleName(gicName1), gicName1, isResp, counter + 1, registryClasses, builder)).append("},");
} else {
data0.append("{\"mapKey\":{}},");
}
}
} else {
data0.append("{").append("\"mapKey\":").append(buildJson(gicName, fieldGicName, isResp, counter + 1, registryClasses,builder)).append("},");
data0.append("{").append("\"mapKey\":").append(buildJson(gicName, fieldGicName, isResp, counter + 1, registryClasses, builder)).append("},");
}
} else if (subTypeName.length() == 1) {
if (!typeName.equals(genericCanonicalName)) {
@ -265,7 +265,7 @@ public class JsonBuildHelper {
data0.append(DocUtil.jsonValueByType(gicName)).append(",");
} else {
String simple = DocClassUtil.getSimpleName(gicName);
data0.append(buildJson(simple, gicName, isResp, counter + 1, registryClasses,builder)).append(",");
data0.append(buildJson(simple, gicName, isResp, counter + 1, registryClasses, builder)).append(",");
}
} else {
data0.append("{\"waring\":\"You may have used non-display generics.\"},");
@ -278,10 +278,10 @@ public class JsonBuildHelper {
String gicName = globGicName[i];
if (!typeName.equals(genericCanonicalName)) {
if (JavaClassValidateUtil.isPrimitive(gicName)) {
data0.append("\"").append(buildJson(gicName, genericCanonicalName, isResp, counter + 1, registryClasses,builder)).append("\",");
data0.append("\"").append(buildJson(gicName, genericCanonicalName, isResp, counter + 1, registryClasses, builder)).append("\",");
} else {
String simpleName = DocClassUtil.getSimpleName(gicName);
data0.append(buildJson(simpleName, gicName, isResp, counter + 1, registryClasses,builder)).append(",");
data0.append(buildJson(simpleName, gicName, isResp, counter + 1, registryClasses, builder)).append(",");
}
} else {
data0.append("{\"waring\":\"You may have used non-display generics.\"},");
@ -293,12 +293,12 @@ public class JsonBuildHelper {
} else if (typeName.equals(subTypeName)) {
data0.append("{\"$ref\":\"...\"}").append(",");
} else {
javaClass = builder.getJavaProjectBuilder().getClassByName(subTypeName);
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, counter + 1, registryClasses,builder)).append(",");
data0.append(buildJson(subTypeName, fieldGicName, isResp, counter + 1, registryClasses, builder)).append(",");
}
}
}

View File

@ -23,8 +23,8 @@ import static com.power.doc.constants.DocGlobalConstants.NO_COMMENTS_FOUND;
public class ParamsBuildHelper {
public static List<ApiParam> buildParams(String className, String pre, int i, String isRequired,
Map<String, CustomRespField> responseFieldMap, boolean isResp,
Map<String, String> registryClasses,ProjectDocConfigBuilder projectBuilder) {
Map<String, CustomRespField> responseFieldMap, boolean isResp,
Map<String, String> registryClasses, ProjectDocConfigBuilder projectBuilder) {
if (StringUtil.isEmpty(className)) {
throw new RuntimeException("Class name can't be null or empty.");
}
@ -48,11 +48,11 @@ public class ParamsBuildHelper {
if (JavaClassValidateUtil.isArray(gicName)) {
gicName = gicName.substring(0, gicName.indexOf("["));
}
paramList.addAll(buildParams(gicName, pre, i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(gicName, pre, i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
} else if (JavaClassValidateUtil.isMap(simpleName)) {
if (globGicName.length == 2) {
paramList.addAll(buildParams(globGicName[1], pre, i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(globGicName[1], pre, i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
} else if (DocGlobalConstants.JAVA_OBJECT_FULLY.equals(className)) {
ApiParam param = ApiParam.of().setField(pre + "any object").setType("object");
@ -68,10 +68,7 @@ public class ParamsBuildHelper {
for (JavaField field : fields) {
String fieldName = field.getName();
String subTypeName = field.getType().getFullyQualifiedName();
boolean ignoreField = field.getModifiers().stream()
.anyMatch(str -> str.equals(DocGlobalConstants.STATIC) || str.equals(DocGlobalConstants.FINAL));
if (ignoreField || "this$0".equals(fieldName) ||
"serialVersionUID".equals(fieldName) ||
if (field.isStatic() || "this$0".equals(fieldName) ||
JavaClassValidateUtil.isIgnoreFieldTypes(subTypeName)) {
continue;
}
@ -201,14 +198,17 @@ public class ParamsBuildHelper {
if (valType.length() == 1) {
String gicName = (n < globGicName.length) ? globGicName[n] : globGicName[globGicName.length - 1];
if (!JavaClassValidateUtil.isPrimitive(gicName) && !simpleName.equals(gicName)) {
paramList.addAll(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
} else {
paramList.addAll(buildParams(valType, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(valType, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
}
} else if (JavaClassValidateUtil.isCollection(subTypeName)) {
String gNameTemp = field.getType().getGenericCanonicalName();
if (globGicName.length > 0 && "java.util.List".equals(gNameTemp)) {
gNameTemp = gNameTemp + "<T>";
}
String[] gNameArr = DocClassUtil.getSimpleGicName(gNameTemp);
if (gNameArr.length == 0) {
continue out;
@ -221,11 +221,11 @@ public class ParamsBuildHelper {
if (len > 0) {
String gicName = (n < len) ? globGicName[n] : globGicName[len - 1];
if (!JavaClassValidateUtil.isPrimitive(gicName) && !simpleName.equals(gicName)) {
paramList.addAll(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
}
} else {
paramList.addAll(buildParams(gName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(gName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
}
}
@ -244,21 +244,21 @@ public class ParamsBuildHelper {
if (JavaClassValidateUtil.isCollection(simple)) {
String gName = DocClassUtil.getSimpleGicName(gicName)[0];
if (!JavaClassValidateUtil.isPrimitive(gName)) {
paramList.addAll(buildParams(gName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(gName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
} else if (JavaClassValidateUtil.isMap(simple)) {
String valType = DocClassUtil.getMapKeyValueType(gicName)[1];
if (!JavaClassValidateUtil.isPrimitive(valType)) {
paramList.addAll(buildParams(valType, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(valType, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
} else {
paramList.addAll(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
} else {
paramList.addAll(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(gicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
} else {
paramList.addAll(buildParams(subTypeName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(subTypeName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
n++;
}
@ -267,13 +267,13 @@ public class ParamsBuildHelper {
if (className.equals(fieldGicName)) {
//do nothing
} else if (!JavaClassValidateUtil.isPrimitive(fieldGicName)) {
paramList.addAll(buildParams(fieldGicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(fieldGicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
} else if (simpleName.equals(subTypeName)) {
//do nothing
} else {
if (!javaClass.isEnum()) {
paramList.addAll(buildParams(fieldGicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses,projectBuilder));
paramList.addAll(buildParams(fieldGicName, preBuilder.toString(), i + 1, isRequired, responseFieldMap, isResp, registryClasses, projectBuilder));
}
}
}

View File

@ -4,6 +4,9 @@ import com.google.gson.Gson;
import com.power.common.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.UUID;
/**
@ -11,17 +14,16 @@ import java.util.UUID;
*/
public class InfoBean {
private String _postman_id;
private String _postman_id = UUID.randomUUID().toString();
private String name;
String schema ;
public InfoBean(String name) {
if(StringUtils.isBlank(name)){
this.name = "smart-doc";
this.name = "smart-doc "+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("YYYY-MM-DD HH:MM:SS"));
}
else {
this.name = name;
}
this._postman_id =UUID.randomUUID().toString();
this.schema = "https://schema.getpostman.com/json/collection/v2.0.0/collection.json";
}
}

View File

@ -10,7 +10,10 @@ import com.power.doc.utils.DocUtil;
import com.power.doc.utils.JavaClassValidateUtil;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.JavaType;
import com.thoughtworks.qdox.model.JavaTypeVariable;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -60,7 +63,7 @@ public interface IDocBuildTemplate {
apiDoc.setName(controllerName);
apiDoc.setAlias(controllerName);
if (isUseMD5) {
String name = DocUtil.handleId(apiDoc.getName());
String name = DocUtil.generateId(apiDoc.getName());
apiDoc.setAlias(name);
}
apiDoc.setDesc(cls.getComment());
@ -70,7 +73,7 @@ public interface IDocBuildTemplate {
default List<ApiParam> buildReturnApiParams(JavaMethod method, String controllerName, ProjectDocConfigBuilder projectBuilder) {
if ("void".equals(method.getReturnType().getFullyQualifiedName())) {
if (method.getReturns().isVoid()) {
return null;
}
ApiReturn apiReturn = DocClassUtil.processReturnType(method.getReturnType().getGenericCanonicalName());
@ -88,7 +91,7 @@ public interface IDocBuildTemplate {
if (JavaClassValidateUtil.isPrimitive(gicName)) {
return ParamsBuildHelper.primitiveReturnRespComment("array of " + DocClassUtil.processTypeNameForParams(gicName));
}
return ParamsBuildHelper.buildParams(gicName, "", 0, null, projectBuilder.getCustomRespFieldMap(), true, new HashMap<>(), projectBuilder);
return ParamsBuildHelper.buildParams(gicName, "", 0, null, projectBuilder.getCustomRespFieldMap(), Boolean.TRUE, new HashMap<>(), projectBuilder);
} else {
return null;
}
@ -101,16 +104,18 @@ public interface IDocBuildTemplate {
if (JavaClassValidateUtil.isPrimitive(keyValue[1])) {
return ParamsBuildHelper.primitiveReturnRespComment("key value");
}
return ParamsBuildHelper.buildParams(keyValue[1], "", 0, null, projectBuilder.getCustomRespFieldMap(), true, new HashMap<>(), projectBuilder);
return ParamsBuildHelper.buildParams(keyValue[1], "", 0, null, projectBuilder.getCustomRespFieldMap(), Boolean.TRUE, new HashMap<>(), projectBuilder);
}
if (StringUtil.isNotEmpty(returnType)) {
return ParamsBuildHelper.buildParams(returnType, "", 0, null, projectBuilder.getCustomRespFieldMap(), true, new HashMap<>(), projectBuilder);
return ParamsBuildHelper.buildParams(returnType, "", 0, null, projectBuilder.getCustomRespFieldMap(), Boolean.TRUE, new HashMap<>(), projectBuilder);
}
return null;
}
List<ApiDoc> getApiData(ProjectDocConfigBuilder projectBuilder);
ApiDoc getSingleApiData(ProjectDocConfigBuilder projectBuilder,String apiClassName);
boolean ignoreReturnObject(String typeName);

View File

@ -61,6 +61,11 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate {
return apiDocList;
}
@Override
public ApiDoc getSingleApiData(ProjectDocConfigBuilder projectBuilder,String apiClassName) {
return null;
}
@Override
public boolean ignoreReturnObject(String typeName) {
if (JavaClassValidateUtil.isMvcIgnoreParams(typeName)) {
@ -78,7 +83,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate {
for (JavaAnnotation annotation : classAnnotations) {
String annotationName = annotation.getType().getName();
if (DocAnnotationConstants.REQUEST_MAPPING.equals(annotationName) || DocGlobalConstants.REQUEST_MAPPING_FULLY.equals(annotationName)) {
if(annotation.getNamedParameter("value")!=null){
if (annotation.getNamedParameter("value") != null) {
baseUrl = StringUtil.removeQuotes(annotation.getNamedParameter("value").toString());
}
}
@ -87,7 +92,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate {
List<ApiMethodDoc> methodDocList = new ArrayList<>(methods.size());
int methodOrder = 0;
for (JavaMethod method : methods) {
if (method.getModifiers().contains("private")) {
if (method.isPrivate()) {
continue;
}
if (StringUtil.isEmpty(method.getComment()) && apiConfig.isStrict()) {
@ -98,7 +103,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate {
apiMethodDoc.setOrder(methodOrder);
apiMethodDoc.setDesc(method.getComment());
apiMethodDoc.setName(method.getName());
String methodUid = DocUtil.handleId(clazName + method.getName());
String methodUid = DocUtil.generateId(clazName + method.getName());
apiMethodDoc.setMethodId(methodUid);
String apiNoteValue = DocUtil.getNormalTagComments(method, DocTags.API_NOTE, cls.getName());
if (StringUtil.isEmpty(apiNoteValue)) {
@ -131,7 +136,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate {
String requestJson = requestExample.getExampleBody();
// set request example detail
apiMethodDoc.setRequestExample(requestExample);
apiMethodDoc.setRequestUsage(requestJson==null?requestExample.getUrl():requestJson);
apiMethodDoc.setRequestUsage(requestJson == null ? requestExample.getUrl() : requestJson);
// build response usage
apiMethodDoc.setResponseUsage(JsonBuildHelper.buildReturnJson(method, projectBuilder));
// build response params
@ -220,11 +225,11 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate {
.append("\":")
.append(DocUtil.handleJsonStr(mockValue))
.append("}");
requestExample.setJsonBody(builder.toString()).setJson(true);
requestExample.setJsonBody(JsonFormatUtil.formatJson(builder.toString())).setJson(true);
paramAdded = true;
} else {
String json = JsonBuildHelper.buildJson(typeName, gicTypeName, Boolean.FALSE, 0, new HashMap<>(), configBuilder);
requestExample.setJsonBody(json).setJson(true);
requestExample.setJsonBody(JsonFormatUtil.formatJson(json)).setJson(true);
paramAdded = true;
}
} else if (SpringMvcAnnotations.PATH_VARIABLE.contains(annotationName)) {
@ -261,7 +266,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate {
gicName = gicName.substring(0, gicName.indexOf("["));
}
if (!JavaClassValidateUtil.isPrimitive(gicName)) {
throw new RuntimeException("FormData can't support binding Collection<T> on method "
throw new RuntimeException("Spring MVC can't support binding Collection on method "
+ method.getName() + "Check it in " + method.getDeclaringClass().getCanonicalName());
}
FormData formData = new FormData();
@ -303,7 +308,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate {
url = UrlUtil.simplifyUrl(url);
if (requestExample.isJson()) {
if (StringUtil.isNotEmpty(requestExample.getJsonBody())) {
exampleBody = DocGlobalConstants.CURL_POST_JSON + url + " --data \'" + JsonFormatUtil.formatJson(requestExample.getJsonBody()) + "\n'";
exampleBody = DocGlobalConstants.CURL_POST_JSON + url + " --data \'" + requestExample.getJsonBody() + "\n'";
} else {
exampleBody = DocGlobalConstants.CURL_POST + url;
}
@ -411,7 +416,7 @@ public class SpringBootDocBuildTemplate implements IDocBuildTemplate {
if (null != annotationRequired) {
required = annotationRequired.toString();
}
String annotationName = annotation.getType().getName();
String annotationName = JavaClassUtil.getAnnotationSimpleName(annotation.getType().getName());
if (SpringMvcAnnotations.REQUEST_BODY.equals(annotationName) || (ValidatorAnnotations.VALID.equals(annotationName) && annotations.size() == 1)) {
if (requestBodyCounter > 0) {
throw new RuntimeException("You have use @RequestBody Passing multiple variables for method "

View File

@ -363,7 +363,7 @@ public class DocUtil {
* @param value value
* @return String
*/
public static String handleId(String value) {
public static String generateId(String value) {
if (StringUtil.isEmpty(value)) {
return null;
}

View File

@ -1,8 +1,10 @@
package com.power.doc.utils;
import com.power.common.util.StringUtil;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.impl.DefaultJavaField;
import java.util.ArrayList;
import java.util.List;
@ -29,6 +31,21 @@ public class JavaClassUtil {
"Date".equals(cls1.getSimpleName()) || "Locale".equals(cls1.getSimpleName())) {
return fieldList;
} else {
String className = cls1.getFullyQualifiedName();
if (cls1.isInterface() &&
!JavaClassValidateUtil.isCollection(className) &&
!JavaClassValidateUtil.isMap(className)) {
List<JavaMethod> methods = cls1.getMethods();
for (JavaMethod javaMethod : methods) {
String methodName = javaMethod.getName();
if (!methodName.startsWith("get")) {
continue;
}
methodName = StringUtil.firstToLowerCase(methodName.substring(3, methodName.length()));
JavaField javaField = new DefaultJavaField(javaMethod.getReturns(), methodName);
fieldList.add(javaField);
}
}
JavaClass pcls = cls1.getSuperJavaClass();
fieldList.addAll(getFields(pcls, i));
fieldList.addAll(cls1.getFields());
@ -40,7 +57,7 @@ public class JavaClassUtil {
/**
* get enum value
*
* @param javaClass enum class
* @param javaClass enum class
* @param formDataEnum is return method
* @return Object
*/

View File

@ -14,7 +14,6 @@ public class JavaFieldUtil {
* @return boolean
*/
public static boolean checkGenerics(List<JavaField> fields) {
checkGenerics:
for (JavaField field : fields) {
if (field.getType().getFullyQualifiedName().length() == 1) {
return true;

View File

@ -0,0 +1,50 @@
{
"serverUrl": "http://127.0.0.1",
"isStrict": false,
"allInOne": true,
"outPath": "D://md2",
"coverOld": true,
"packageFilters": "",
"md5EncryptedHtmlName": false,
"projectName": "smart-doc",
"skipTransientField": true,
"revisionLogs": [
{
"version": "1.0",
"status": "use",
"author": "author",
"revisionTime": "2019-10-12",
"remarks": "desc"
}
],
"errorCodes": [
{
"value": "200",
"type": "string",
"desc": "desc"
}
],
"customResponseFields": [
{
"name": "name",
"desc": "desc",
"ownerClassName": "ownerClassName",
"value": "value"
}
],
"requestHeaders": [
{
"name": "token",
"type": "string",
"desc": "desc",
"required": false,
"since": "-"
}
],
"sourceCodePaths": [
{
"path": "src/main/java",
"desc": "测试"
}
]
}

View File

@ -0,0 +1,66 @@
{
"serverUrl": "http://127.0.0.1",
"isStrict": false,
"allInOne": true,
"outPath": "D://md2",
"coverOld": true,
"packageFilters": "",
"md5EncryptedHtmlName": false,
"projectName": "smart-doc",
"skipTransientField": true,
"dataDictionaries": [
{
"title": "title",
"enumClassName": "com.data.Enum",
"codeField": "codeField",
"descField": "descField"
}
],
"errorCodeDictionaries": [
{
"title": "title",
"enumClassName": "com.data.Enum",
"codeField": "codeField",
"descField": "descField"
}
],
"revisionLogs": [
{
"version": "1.0",
"status": "use",
"author": "author",
"revisionTime": "2019-10-12",
"remarks": "desc"
}
],
"errorCodes": [
{
"value": "200",
"type": "string",
"desc": "desc"
}
],
"customResponseFields": [
{
"name": "name",
"desc": "desc",
"ownerClassName": "ownerClassName",
"value": "value"
}
],
"requestHeaders": [
{
"name": "token",
"type": "string",
"desc": "desc",
"required": false,
"since": "-"
}
],
"sourceCodePaths": [
{
"path": "src/main/java",
"desc": "测试"
}
]
}