All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fastchar.openapi.FastCharOpenAPI Maven / Gradle / Ivy

The newest version!
package com.fastchar.openapi;

import com.fastchar.core.FastAction;
import com.fastchar.core.FastChar;
import com.fastchar.core.FastHttpMethod;
import com.fastchar.core.FastRoute;
import com.fastchar.openapi.annotation.*;
import com.fastchar.utils.FastBooleanUtils;
import com.fastchar.utils.FastEnumUtils;
import com.fastchar.utils.FastStringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

public class FastCharOpenAPI {


    public Object buildOpenAPI(String defaultServer) {

        Map openAPI = new HashMap<>();
        FastCharOpenAPIConfig openAPIConfig = FastChar.getConfig(FastCharOpenAPIConfig.class);

        openAPI.put("openapi", openAPIConfig.getOpenApiVersion());
        List> server = openAPIConfig.getServer();
        if (server.isEmpty()) {
            Map serverItem = new HashMap<>();
            serverItem.put("url", defaultServer);
            serverItem.put("description", "默认接口地址");
            server.add(serverItem);
        }
        openAPI.put("servers", server);
        Map info = openAPIConfig.getInfo();
        Map contact = openAPIConfig.getContact();
        if (!contact.isEmpty()) {
            info.put("contact", contact);
        }
        Map license = openAPIConfig.getLicense();
        if (!license.isEmpty()) {
            info.put("license", license);
        }
        if (!info.isEmpty()) {
            openAPI.put("info", info);
        }

        List allRoute = FastChar.getRoutes();

        List methods = new ArrayList<>();
        try {
            for (Field field : FastHttpMethod.class.getFields()) {
                methods.add(field.get(FastHttpMethod.class).toString());
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        Map paths = new HashMap<>();
        for (FastRoute fastRoute : allRoute) {
            Map pathItem = new HashMap<>();
            for (String httpMethod : methods) {

                Map pathInfo = new HashMap<>();

                List tags = new ArrayList<>();

                List parameters = new ArrayList<>();

                Class actionClass = fastRoute.getActionClass();
                AFastAPIGroup[] actionClassAFastAPIGroup = actionClass.getAnnotationsByType(AFastAPIGroup.class);
                for (AFastAPIGroup annotation : actionClassAFastAPIGroup) {
                    tags.add(annotation.value());
                }

                Method method = fastRoute.getMethod();

                if (method.isAnnotationPresent(Deprecated.class)) {
                    pathInfo.put("deprecated", true);
                }

                AFastAPITitle[] apiTitles = method.getAnnotationsByType(AFastAPITitle.class);
                if (apiTitles.length == 0) {
                    continue;
                }

                for (AFastAPITitle apiTitle : apiTitles) {
                    if (!apiTitle.method().equalsIgnoreCase(httpMethod)) {
                        continue;
                    }
                    pathInfo.put("summary", apiTitle.value());
                    pathInfo.put("description", FastStringUtils.defaultValue(apiTitle.desc(), apiTitle.value()));
                }

                if (!pathInfo.containsKey("summary")) {
                    continue;
                }


                AFastAPIHeader[] methodAFastAPIHeader = method.getAnnotationsByType(AFastAPIHeader.class);
                for (AFastAPIHeader annotation : methodAFastAPIHeader) {
                    if (!annotation.method().equalsIgnoreCase(httpMethod)) {
                        continue;
                    }
                    Map header = new LinkedHashMap<>();
                    header.put("name", annotation.name());
                    header.put("in", "header");
                    header.put("description", FastStringUtils.defaultValue(annotation.name(), annotation.desc()));
                    header.put("required", annotation.required());
                    header.put("example", annotation.example());
                    header.put("schema", safeType(annotation.type()));

                    parameters.add(header);
                }


                AFastAPIGroup[] methodAFastAPIGroup = method.getAnnotationsByType(AFastAPIGroup.class);
                for (AFastAPIGroup annotation : methodAFastAPIGroup) {
                    tags.add(annotation.value());
                }

                Map requestParams = new LinkedHashMap<>();
                boolean hasFile = false;

                List requiredParams = new ArrayList<>();
                AFastAPIParam[] methodAFastAPIParam = method.getAnnotationsByType(AFastAPIParam.class);
                for (AFastAPIParam annotation : methodAFastAPIParam) {
                    if (!annotation.method().equalsIgnoreCase(httpMethod)) {
                        continue;
                    }
                    List values = this.safeValues(annotation.value());
//                格式:name type desc required example

                    String name = annotation.name();
                    String type = annotation.type();
                    String desc = annotation.desc();
                    boolean required = annotation.required();
                    String example = annotation.example();
                    if (!values.isEmpty()) {
                        name = values.get(0);
                    }
                    if (FastStringUtils.isEmpty(name)) {
                        continue;
                    }
                    if (values.size() > 1) {
                        type = values.get(1);
                    }
                    if (values.size() > 2) {
                        desc = values.get(2);
                    }
                    if (values.size() > 3) {
                        required = FastBooleanUtils.formatToBoolean(values.get(3), required);
                    }
                    if (values.size() > 4) {
                        example = values.get(4);
                    }

                    Map param = new HashMap<>(safeType(type));
                    param.put("description", desc);
                    param.put("example", example);

                    Class aClass = annotation.enumClass();
                    if (aClass.isEnum()) {
                        String real_type = String.valueOf(param.get("type"));

                        List enumValues = new ArrayList<>();
                        Enum[] enums = FastEnumUtils.getEnumValues(aClass);
                        for (Enum anEnum : enums) {

                            if (real_type.equalsIgnoreCase("integer")) {
                                enumValues.add(anEnum.ordinal() + "(" + anEnum.name() + ")");
                            } else {
                                enumValues.add(anEnum.name());
                            }
                        }
                        param.put("enum", enumValues);
                    }

                    String[] enums = annotation.enums();
                    if (enums.length > 0) {
                        param.put("enum", enums);
                    }

                    requestParams.put(name, param);
                    hasFile = FastStringUtils.defaultValue(param.get("format"), "").equalsIgnoreCase("binary");
                    if (required) {
                        requiredParams.add(name);
                    }
                }

                Map requestBody = new LinkedHashMap<>();
                Map requestBodyContent = new LinkedHashMap<>();

                Map requestBodyContentSchema = new LinkedHashMap<>();
                requestBodyContentSchema.put("type", "object");
                requestBodyContentSchema.put("required", requiredParams);
                requestBodyContentSchema.put("properties", requestParams);

                if (hasFile) {
                    Map mediaTypeContent = new HashMap<>();
                    mediaTypeContent.put("schema", requestBodyContentSchema);
                    requestBodyContent.put("multipart/form-data", mediaTypeContent);
                } else {
                    Map mediaTypeContent = new HashMap<>();
                    mediaTypeContent.put("schema", requestBodyContentSchema);
                    requestBodyContent.put("application/x-www-form-urlencoded", mediaTypeContent);
                }

                requestBody.put("content", requestBodyContent);
                pathInfo.put("requestBody", requestBody);


                Map response = new HashMap<>();

                AFastAPIResponse[] methodAFastAPIResponse = method.getAnnotationsByType(AFastAPIResponse.class);
                for (AFastAPIResponse annotation : methodAFastAPIResponse) {
                    if (!annotation.method().equalsIgnoreCase(httpMethod)) {
                        continue;
                    }

                    Map responseMap = new HashMap<>();
                    responseMap.put("description", annotation.desc().replace("\n", "
")); Map responseContent = new HashMap<>(); Map responseExamples = new HashMap<>(); for (int i = 0; i < annotation.examples().length; i++) { String example = annotation.examples()[i]; if (FastStringUtils.isEmpty(example)) { continue; } Map exampleContent = new HashMap<>(); exampleContent.put("summary", annotation.desc()); exampleContent.put("value", example); responseExamples.put(String.valueOf(i + 1), exampleContent); } Map responseExamplesMap = new HashMap<>(); if (!responseExamples.isEmpty()) { responseExamplesMap.put("examples", responseExamples); } if (!responseExamplesMap.isEmpty()) { responseContent.put(annotation.contentType(), responseExamplesMap); } if (!responseContent.isEmpty()) { responseMap.put("content", responseContent); } response.put(String.valueOf(annotation.statusCode()), responseMap); } if (!response.isEmpty()) { pathInfo.put("responses", response); } if (tags.isEmpty()) { tags.add(openAPIConfig.getDefaultApiGroup()); } pathInfo.put("tags", tags); if (!parameters.isEmpty()) { pathInfo.put("parameters", parameters); } pathItem.put(httpMethod, pathInfo); } if (pathItem.isEmpty()) { continue; } paths.put(fastRoute.getRoute(), pathItem); } openAPI.put("paths", paths); return openAPI; } private Map safeType(String type) { Map map = new HashMap<>(); if (type.equalsIgnoreCase("int")) { map.put("type", "integer"); map.put("format", "int32"); } else if (type.equalsIgnoreCase("long")) { map.put("type", "integer"); map.put("format", "int64"); } else if (type.equalsIgnoreCase("float")) { map.put("type", "number"); map.put("format", "float"); } else if (type.equalsIgnoreCase("double")) { map.put("type", "number"); map.put("format", "double"); } else if (type.equalsIgnoreCase("string")) { map.put("type", "string"); } else if (type.equalsIgnoreCase("byte")) { map.put("type", "string"); map.put("format", "byte"); } else if (type.equalsIgnoreCase("binary") || type.equalsIgnoreCase("file")) { map.put("type", "string"); map.put("format", "binary"); } else if (type.equalsIgnoreCase("boolean")) { map.put("type", "boolean"); } else if (type.equalsIgnoreCase("date")) { map.put("type", "string"); map.put("format", "date"); } else if (type.equalsIgnoreCase("dateTime")) { map.put("type", "string"); map.put("format", "dateTime"); } else if (type.equalsIgnoreCase("password")) { map.put("type", "string"); map.put("format", "password"); } return map; } private List safeValues(String value) { List values = new ArrayList<>(); String[] splitArray = value.split(" "); for (String item : splitArray) { if (FastStringUtils.isEmpty(item)) { continue; } values.add(item); } return values; } }