com.ly.doc.builder.openapi.AbstractOpenApiBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of smart-doc Show documentation
Show all versions of smart-doc Show documentation
Smart-doc is a tool that supports both JAVA RESTFUL API and Apache Dubbo RPC interface document
generation.
/*
* smart-doc
*
* Copyright (C) 2018-2023 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.ly.doc.builder.openapi;
import com.ly.doc.constants.ComponentTypeEnum;
import com.ly.doc.model.*;
import com.power.common.util.CollectionUtil;
import com.power.common.util.StringUtil;
import com.ly.doc.builder.DocBuilderTemplate;
import com.ly.doc.builder.ProjectDocConfigBuilder;
import com.ly.doc.constants.DocGlobalConstants;
import com.ly.doc.factory.BuildTemplateFactory;
import com.ly.doc.model.openapi.OpenApiTag;
import com.ly.doc.template.IDocBuildTemplate;
import com.ly.doc.utils.DocUtil;
import com.ly.doc.utils.OpenApiSchemaUtil;
import com.thoughtworks.qdox.JavaProjectBuilder;
import java.util.*;
import java.util.stream.Collectors;
import static com.ly.doc.constants.DocGlobalConstants.*;
/**
* @author xingzi
* Date 2022/10/12 18:49
*/
@SuppressWarnings("all")
public abstract class AbstractOpenApiBuilder {
private String componentKey;
public String getComponentKey() {
return componentKey;
}
public void setComponentKey(String componentKey) {
this.componentKey = componentKey;
}
abstract String getModuleName();
/**
* Create OpenAPI definition
*
* @param apiConfig Configuration of smart-doc
* @param apiDocList List of API DOC
*/
abstract void openApiCreate(ApiConfig apiConfig, List apiDocList);
/**
* Build request
*
* @param apiConfig Configuration of smart-doc
* @param apiMethodDoc Data of method
* @param apiDoc singe api doc
* @return Map of request urls
*/
abstract Map buildPathUrlsRequest(ApiConfig apiConfig, ApiMethodDoc apiMethodDoc, ApiDoc apiDoc);
/**
* response body
*
* @param apiMethodDoc ApiMethodDoc
*/
abstract Map buildResponsesBody(ApiConfig apiConfig, ApiMethodDoc apiMethodDoc);
protected static final Map STRING_COMPONENT = new HashMap<>();
static {
STRING_COMPONENT.put("type", "string");
STRING_COMPONENT.put("format", "string");
}
/**
* Build openapi paths
*
* @param apiConfig Configuration of smart-doc
* @param apiDocList List of API DOC
* @param tags tags
*/
public Map buildPaths(ApiConfig apiConfig, List apiDocList, Set tags) {
Map pathMap = new HashMap<>(500);
Set methodDocs = DocMapping.METHOD_DOCS;
for (ApiMethodDoc methodDoc : methodDocs) {
String [] paths = methodDoc.getPath().split(";");
for(String path : paths) {
path = path.trim();
Map request = buildPathUrls(apiConfig, methodDoc, methodDoc.getClazzDoc());
if (!pathMap.containsKey(path)) {
pathMap.put(path, request);
} else {
Map oldRequest = (Map) pathMap.get(path);
oldRequest.putAll(request);
}
}
}
for (Map.Entry docEntry : DocMapping.TAG_DOC.entrySet()) {
String tag = docEntry.getKey();
tags.addAll(docEntry.getValue().getClazzDocs()
.stream()
//optimize tag content for compatible to swagger
.map(doc -> OpenApiTag.of(doc.getName(), doc.getDesc()))
.collect(Collectors.toSet()));
}
return pathMap;
}
/**
* Build path urls
*
* @param apiConfig ApiConfig
* @param apiMethodDoc Method
* @param apiDoc ApiDoc
*/
public Map buildPathUrls(ApiConfig apiConfig, ApiMethodDoc apiMethodDoc, ApiDoc apiDoc) {
Map request = new HashMap<>(4);
request.put(apiMethodDoc.getType().toLowerCase(), buildPathUrlsRequest(apiConfig, apiMethodDoc, apiDoc));
return request;
}
/**
* Build content for responses and requestBody
*
* @param apiConfig ApiConfig
* @param apiMethodDoc ApiMethodDoc
* @param isRep is response
*/
public Map buildContent(ApiConfig apiConfig, ApiMethodDoc apiMethodDoc, boolean isRep) {
Map content = new HashMap<>(8);
String contentType = apiMethodDoc.getContentType();
if (isRep) {
contentType = "*/*";
}
content.put(contentType, buildContentBody(apiConfig, apiMethodDoc, isRep));
return content;
}
/**
* Build data of content
*
* @param apiConfig ApiConfig
* @param apiMethodDoc ApiMethodDoc
* @param isRep is response
*/
public Map buildContentBody(ApiConfig apiConfig, ApiMethodDoc apiMethodDoc, boolean isRep) {
Map content = new HashMap<>(8);
if (Objects.nonNull(apiMethodDoc.getReturnSchema()) && isRep) {
content.put("schema", apiMethodDoc.getReturnSchema());
} else if (!isRep && Objects.nonNull(apiMethodDoc.getRequestSchema())) {
content.put("schema", apiMethodDoc.getRequestSchema());
} else {
content.put("schema", buildBodySchema(apiMethodDoc, isRep));
}
if (OPENAPI_2_COMPONENT_KRY.equals(componentKey) && !isRep) {
content.put("name", apiMethodDoc.getName());
}
if (OPENAPI_3_COMPONENT_KRY.equals(componentKey) &&
(!isRep && apiConfig.isRequestExample() || (isRep && apiConfig.isResponseExample()))) {
content.put("examples", buildBodyExample(apiMethodDoc, isRep));
}
return content;
}
/**
* Build schema of Body
*
* @param apiMethodDoc ApiMethodDoc
* @param isRep is response
*/
public Map buildBodySchema(ApiMethodDoc apiMethodDoc, boolean isRep) {
Map schema = new HashMap<>(10);
Map innerScheme = new HashMap<>(10);
// For response
if (isRep) {
String responseRef = componentKey + OpenApiSchemaUtil.getClassNameFromParams(apiMethodDoc.getResponseParams());
if (apiMethodDoc.getIsResponseArray() == 1) {
schema.put("type", ARRAY);
innerScheme.put("$ref", responseRef);
schema.put("items", innerScheme);
} else if (CollectionUtil.isNotEmpty(apiMethodDoc.getResponseParams())) {
schema.put("$ref", responseRef);
}
return schema;
}
// for request
String requestRef;
String randomName = ComponentTypeEnum.getRandomName(ApiConfig.getInstance().getComponentType(), apiMethodDoc);
if (apiMethodDoc.getContentType().equals(DocGlobalConstants.URL_CONTENT_TYPE)) {
requestRef = componentKey + OpenApiSchemaUtil.getClassNameFromParams(apiMethodDoc.getQueryParams());
} else {
requestRef = componentKey + OpenApiSchemaUtil.getClassNameFromParams(apiMethodDoc.getRequestParams());
}
//remove special characters in url
if (CollectionUtil.isNotEmpty(apiMethodDoc.getRequestParams())) {
if (apiMethodDoc.getIsRequestArray() == 1) {
schema.put("type", ARRAY);
innerScheme.put("$ref", requestRef);
schema.put("items", innerScheme);
} else {
schema.put("$ref", requestRef);
}
}
return schema;
}
/**
* Build body example
*
* @param apiMethodDoc ApiMethodDoc
* @param isRep is response
*/
public static Map buildBodyExample(ApiMethodDoc apiMethodDoc, boolean isRep) {
Map content = new HashMap<>(8);
content.put("json", buildExampleData(apiMethodDoc, isRep));
return content;
}
/**
* Build example data
*
* @param apiMethodDoc ApiMethodDoc
* @param isRep is response
*/
public static Map buildExampleData(ApiMethodDoc apiMethodDoc, boolean isRep) {
Map content = new HashMap<>(8);
content.put("summary", "test data");
if (!isRep) {
content.put("value", StringUtil.isEmpty(
apiMethodDoc.getRequestExample().getJsonBody()) ? apiMethodDoc.getRequestExample().getExampleBody() :
apiMethodDoc.getRequestExample().getJsonBody());
} else {
content.put("value", apiMethodDoc.getResponseUsage());
}
return content;
}
/**
* Build request parameters
*
* @param apiMethodDoc API data for the method
*/
abstract List