Skip to content

Commit

Permalink
Merge pull request #784 from shalousun/master
Browse files Browse the repository at this point in the history
feat: Optimize Duplicate Code
  • Loading branch information
shalousun authored Apr 23, 2024
2 parents f4012af + e884bb7 commit 20a427c
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/main/java/com/ly/doc/constants/FrameworkEnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public enum FrameworkEnum {
/**
* JAX-RS
*/
JAX_RS("JAX-RS", "com.ly.doc.template.JaxrsDocBuildTemplate");
JAX_RS("JAX-RS", "com.ly.doc.template.JAXRSDocBuildTemplate");

/**
* Framework name
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/ly/doc/template/IDocBuildTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ default List<T> getApiData(ProjectDocConfigBuilder projectBuilder) {
DocBuildHelper docBuildHelper = DocBuildHelper.create(projectBuilder);

preRender(docBuildHelper);

// get candidate classes
Collection<JavaClass> candidateClasses = getCandidateClasses(projectBuilder, docBuildHelper);
List<T> apiList = renderApi(projectBuilder, candidateClasses);

Expand Down
17 changes: 9 additions & 8 deletions src/main/java/com/ly/doc/template/IRestDocTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ default List<ApiDoc> processApiData(ProjectDocConfigBuilder projectBuilder, Fram
order = Integer.parseInt(strOrder);
}

List<ApiMethodDoc> apiMethodDocs = buildEntryPointMethod(cls, apiConfig, projectBuilder,
List<ApiMethodDoc> apiMethodDocs = this.buildEntryPointMethod(cls, apiConfig, projectBuilder,
frameworkAnnotations, configApiReqParams, baseMappingHandler, headerHandler);
if (CollectionUtil.isEmpty(apiMethodDocs)) {
continue;
}
this.handleApiDoc(cls, apiDocList, apiMethodDocs, order, apiConfig.isMd5EncryptedHtmlName());
}
apiDocList = handleTagsApiDoc(apiDocList);
apiDocList = this.handleTagsApiDoc(apiDocList);
if (apiConfig.isSortByTitle()) {
Collections.sort(apiDocList);
} else if (setCustomOrder) {
Expand Down Expand Up @@ -480,8 +480,7 @@ default List<ApiMethodDoc> buildEntryPointMethod(
}

// build request json
ApiRequestExample requestExample = buildReqJson(docJavaMethod, apiMethodDoc, requestMapping.getMethodType(),
projectBuilder, frameworkAnnotations);
ApiRequestExample requestExample = buildReqJson(docJavaMethod, apiMethodDoc, projectBuilder, frameworkAnnotations);
String requestJson = requestExample.getExampleBody();
// set request example detail
apiMethodDoc.setRequestExample(requestExample);
Expand Down Expand Up @@ -823,8 +822,9 @@ else if (javaClass.isEnum()) {
return ApiParamTreeUtil.buildMethodReqParam(paramList, queryReqParamMap, pathReqParamMap, requestBodyCounter);
}

default ApiRequestExample buildReqJson(DocJavaMethod javaMethod, ApiMethodDoc apiMethodDoc, String methodType,
default ApiRequestExample buildReqJson(DocJavaMethod javaMethod, ApiMethodDoc apiMethodDoc,
ProjectDocConfigBuilder configBuilder, FrameworkAnnotations frameworkAnnotations) {
String methodType = apiMethodDoc.getType();
JavaMethod method = javaMethod.getJavaMethod();
Map<String, String> pathParamsMap = new LinkedHashMap<>();
Map<String, String> queryParamsMap = new LinkedHashMap<>();
Expand Down Expand Up @@ -1044,13 +1044,14 @@ default ApiRequestExample buildReqJson(DocJavaMethod javaMethod, ApiMethodDoc ap

// set content-type to fromData
boolean hasFormDataUploadFile = formDataList.stream().anyMatch(form -> Objects.equals(form.getType(), DocGlobalConstants.PARAM_TYPE_FILE));
Map<Boolean, List<FormData>> formDataGroupMap = formDataList.stream()
.collect(Collectors.groupingBy(e -> Objects.equals(e.getType(), DocGlobalConstants.PARAM_TYPE_FILE)));
List<FormData> fileFormDataList = formDataGroupMap.getOrDefault(Boolean.TRUE, new ArrayList<>());
if (hasFormDataUploadFile) {
apiMethodDoc.setContentType(FILE_CONTENT_TYPE);
}

Map<Boolean, List<FormData>> formDataGroupMap = formDataList.stream()
.collect(Collectors.groupingBy(e -> Objects.equals(e.getType(), DocGlobalConstants.PARAM_TYPE_FILE)));
List<FormData> fileFormDataList = formDataGroupMap.getOrDefault(Boolean.TRUE, new ArrayList<>());

requestExample.setFormDataList(formDataList);
String[] paths = apiMethodDoc.getPath().split(";");
String path = paths[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@

import com.ly.doc.builder.ProjectDocConfigBuilder;
import com.ly.doc.constants.*;
import com.ly.doc.handler.DefaultWebSocketRequestHandler;
import com.ly.doc.handler.JaxrsHeaderHandler;
import com.ly.doc.handler.JaxrsPathHandler;
import com.ly.doc.handler.*;
import com.ly.doc.helper.FormDataBuildHelper;
import com.ly.doc.helper.JsonBuildHelper;
import com.ly.doc.helper.ParamsBuildHelper;
Expand All @@ -41,7 +39,6 @@
import com.thoughtworks.qdox.model.*;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand All @@ -54,14 +51,10 @@
* @author Zxq
* @since 2021/7/15
*/
public class JaxrsDocBuildTemplate implements IDocBuildTemplate<ApiDoc>, IWebSocketDocBuildTemplate<WebSocketDoc>, IRestDocTemplate, IWebSocketTemplate {
public class JAXRSDocBuildTemplate implements IDocBuildTemplate<ApiDoc>, IWebSocketDocBuildTemplate<WebSocketDoc>, IRestDocTemplate, IWebSocketTemplate {

private static final Logger log = Logger.getLogger(JaxrsDocBuildTemplate.class.getName());
private static final Logger log = Logger.getLogger(JAXRSDocBuildTemplate.class.getName());

/**
* api index
*/
private final AtomicInteger atomicInteger = new AtomicInteger(1);
/**
* headers
*/
Expand All @@ -71,45 +64,25 @@ public class JaxrsDocBuildTemplate implements IDocBuildTemplate<ApiDoc>, IWebSoc
@Override
public List<ApiDoc> renderApi(ProjectDocConfigBuilder projectBuilder, Collection<JavaClass> candidateClasses) {
ApiConfig apiConfig = projectBuilder.getApiConfig();
FrameworkAnnotations frameworkAnnotations = registeredAnnotations();
this.headers = apiConfig.getRequestHeaders();
List<ApiDoc> apiDocList = new ArrayList<>();
int order = 0;
boolean setCustomOrder = false;
// exclude class is ignore
for (JavaClass cls : candidateClasses) {
if (StringUtil.isNotEmpty(apiConfig.getPackageFilters())) {
// from smart config
if (!DocUtil.isMatch(apiConfig.getPackageFilters(), cls)) {
continue;
}
}
// from tag
DocletTag ignoreTag = cls.getTagByName(DocTags.IGNORE);
if (!isEntryPoint(cls, frameworkAnnotations) || Objects.nonNull(ignoreTag)) {
continue;
}
String strOrder = JavaClassUtil.getClassTagsValue(cls, DocTags.ORDER, Boolean.TRUE);
order++;
if (ValidateUtil.isNonNegativeInteger(strOrder)) {
setCustomOrder = true;
order = Integer.parseInt(strOrder);
}
List<ApiMethodDoc> apiMethodDocs = buildControllerMethod(cls, apiConfig, projectBuilder, frameworkAnnotations);
this.handleApiDoc(cls, apiDocList, apiMethodDocs, order, apiConfig.isMd5EncryptedHtmlName());
}
List<ApiReqParam> configApiReqParams = Stream.of(apiConfig.getRequestHeaders(), apiConfig.getRequestParams()).filter(Objects::nonNull)
.flatMap(Collection::stream).collect(Collectors.toList());
FrameworkAnnotations frameworkAnnotations = this.registeredAnnotations();
List<ApiDoc> apiDocList = this.processApiData(projectBuilder, frameworkAnnotations,
configApiReqParams, new SpringMVCRequestMappingHandler(), new SpringMVCRequestHeaderHandler(), candidateClasses);
// sort
if (apiConfig.isSortByTitle()) {
Collections.sort(apiDocList);
} else if (setCustomOrder) {
// while set custom oder
return apiDocList.stream()
.sorted(Comparator.comparing(ApiDoc::getOrder))
.peek(p -> p.setOrder(atomicInteger.getAndAdd(1))).collect(Collectors.toList());
}
return apiDocList;
}

@Override
public List<ApiMethodDoc> buildEntryPointMethod(JavaClass cls, ApiConfig apiConfig, ProjectDocConfigBuilder projectBuilder,
FrameworkAnnotations frameworkAnnotations, List<ApiReqParam> configApiReqParams, IRequestMappingHandler baseMappingHandler, IHeaderHandler headerHandler) {
return buildControllerMethod(cls, apiConfig, projectBuilder, frameworkAnnotations);
}

@Override
public List<WebSocketDoc> renderWebSocketApi(ProjectDocConfigBuilder projectBuilder, Collection<JavaClass> candidateClasses) {
FrameworkAnnotations frameworkAnnotations = registeredAnnotations();
Expand Down Expand Up @@ -215,7 +188,7 @@ private List<ApiMethodDoc> buildControllerMethod(final JavaClass cls, ApiConfig
}
List<ApiReqParam> allApiReqParams;
allApiReqParams = apiReqParams;
if (this.headers != null) {
if (Objects.nonNull(this.headers)) {
allApiReqParams = Stream.of(this.headers, apiReqParams)
.flatMap(Collection::stream).distinct().collect(Collectors.toList());
}
Expand All @@ -234,8 +207,7 @@ private List<ApiMethodDoc> buildControllerMethod(final JavaClass cls, ApiConfig
apiMethodDoc.setRequestHeaders(allApiReqParams);

// build request json
ApiRequestExample requestExample = buildReqJson(docJavaMethod, apiMethodDoc, jaxPathMapping.getMethodType(),
projectBuilder);
ApiRequestExample requestExample = buildReqJson(docJavaMethod, apiMethodDoc, projectBuilder);
String requestJson = requestExample.getExampleBody();
// set request example detail
apiMethodDoc.setRequestExample(requestExample);
Expand Down Expand Up @@ -406,7 +378,6 @@ private ApiMethodReqParam requestParams(final DocJavaMethod docJavaMethod, Proje
} else {
isRequestBody = true;
}

boolean required = Boolean.parseBoolean(strRequired);
boolean queryParam = !isRequestBody && !isPathVariable;
if (JavaClassValidateUtil.isCollection(fullyQualifiedName) || JavaClassValidateUtil.isArray(fullyQualifiedName)) {
Expand Down Expand Up @@ -556,8 +527,8 @@ else if (javaClass.isEnum()) {
.setQueryParams(queryParams);
}

private ApiRequestExample buildReqJson(DocJavaMethod javaMethod, ApiMethodDoc apiMethodDoc, String methodType,
ProjectDocConfigBuilder configBuilder) {
private ApiRequestExample buildReqJson(DocJavaMethod javaMethod, ApiMethodDoc apiMethodDoc, ProjectDocConfigBuilder configBuilder) {
String methodType = apiMethodDoc.getType();
JavaMethod method = javaMethod.getJavaMethod();
Map<String, String> pathParamsMap = new LinkedHashMap<>();
List<DocJavaParameter> parameterList = getJavaParameterList(configBuilder, javaMethod, null);
Expand Down
83 changes: 83 additions & 0 deletions src/main/java/com/ly/doc/utils/CurlUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,22 @@
*/
package com.ly.doc.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import com.ly.doc.constants.DocGlobalConstants;
import com.ly.doc.constants.Methods;
import com.ly.doc.model.ApiMethodDoc;
import com.ly.doc.model.ApiReqParam;
import com.ly.doc.model.FormData;
import com.ly.doc.model.request.ApiRequestExample;
import com.power.common.util.CollectionUtil;
import com.power.common.util.StringUtil;
import com.ly.doc.model.request.CurlRequest;
import com.power.common.util.UrlUtil;

/**
* @author yu 2020/12/21.
Expand Down Expand Up @@ -82,4 +89,80 @@ public static String toCurl(CurlRequest request) {
}
return sb.toString();
}

public void setExampleBody(ApiMethodDoc apiMethodDoc, ApiRequestExample requestExample,
List<FormData> formDataList,
Map<String, String> pathParamsMap, Map<String, String> queryParamsMap) {
String methodType = apiMethodDoc.getType();
String[] paths = apiMethodDoc.getPath().split(";");
String path = paths[0];
String body;
String exampleBody;
String url;
List<ApiReqParam> reqHeaderList = apiMethodDoc.getRequestHeaders();
Map<Boolean, List<FormData>> formDataGroupMap = formDataList.stream()
.collect(Collectors.groupingBy(e -> Objects.equals(e.getType(), DocGlobalConstants.PARAM_TYPE_FILE)));
List<FormData> fileFormDataList = formDataGroupMap.getOrDefault(Boolean.TRUE, new ArrayList<>());
// curl send file to convert
final Map<String, String> formDataToMap = DocUtil.formDataToMap(formDataList);
// formData add to params '--data'
queryParamsMap.putAll(formDataToMap);
if (Methods.POST.getValue().equals(methodType) || Methods.PUT.getValue().equals(methodType)) {
// for post put
path = DocUtil.formatAndRemove(path, pathParamsMap);
body = UrlUtil.urlJoin(DocGlobalConstants.EMPTY, queryParamsMap)
.replace("?", DocGlobalConstants.EMPTY);
url = apiMethodDoc.getServerUrl() + "/" + path;
url = UrlUtil.simplifyUrl(url);

if (requestExample.isJson()) {
if (StringUtil.isNotEmpty(body)) {
url = url + "?" + body;
}
CurlRequest curlRequest = CurlRequest.builder()
.setBody(requestExample.getJsonBody())
.setContentType(apiMethodDoc.getContentType())
.setType(methodType)
.setReqHeaders(reqHeaderList)
.setUrl(url);
exampleBody = CurlUtil.toCurl(curlRequest);
} else {
CurlRequest curlRequest;
if (StringUtil.isNotEmpty(body)) {
curlRequest = CurlRequest.builder()
.setBody(body)
.setContentType(apiMethodDoc.getContentType())
.setFileFormDataList(fileFormDataList)
.setType(methodType)
.setReqHeaders(reqHeaderList)
.setUrl(url);
} else {
curlRequest = CurlRequest.builder()
.setBody(requestExample.getJsonBody())
.setContentType(apiMethodDoc.getContentType())
.setFileFormDataList(fileFormDataList)
.setType(methodType)
.setReqHeaders(reqHeaderList)
.setUrl(url);
}
exampleBody = CurlUtil.toCurl(curlRequest);
}
requestExample.setExampleBody(exampleBody).setUrl(url);
} else {
// for get delete
url = "";
//formatRequestUrl(pathParamsMap, queryParamsMap, apiMethodDoc.getServerUrl(), path);
CurlRequest curlRequest = CurlRequest.builder()
.setBody(requestExample.getJsonBody())
.setContentType(apiMethodDoc.getContentType())
.setType(methodType)
.setReqHeaders(reqHeaderList)
.setUrl(url);
exampleBody = CurlUtil.toCurl(curlRequest);

requestExample.setExampleBody(exampleBody)
.setJsonBody(requestExample.isJson() ? requestExample.getJsonBody() : DocGlobalConstants.EMPTY)
.setUrl(url);
}
}
}

0 comments on commit 20a427c

Please sign in to comment.