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

com.paas.swagger.plugin.ServiceModelToSwagger2MapperPlugin Maven / Gradle / Ivy

The newest version!
package com.paas.swagger.plugin;

import io.swagger.models.*;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Documentation;
import springfox.documentation.service.ResourceListing;
import springfox.documentation.swagger2.mappers.SecurityMapper;
import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2MapperImpl;
import springfox.documentation.swagger2.mappers.VendorExtensionsMapper;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class ServiceModelToSwagger2MapperPlugin extends ServiceModelToSwagger2MapperImpl
{

    private static final String SCHEMA_DEFINITIONS = "#/definitions/";

    @Autowired
    private ApiBeanMapper beanMapper;
    @Autowired
    private SecurityMapper securityMapper;
    @Autowired
    private VendorExtensionsMapper vendorExtensionsMapper;

    private Model cloneNewModelPutDefinitions(Model model, Map properties)
    {
        Model newModel = (Model) model.clone();
        newModel.getProperties().clear();
        newModel.setProperties(properties);
        return newModel;
    }

    private Map propertiesFilter(Map properties, Map definitions, String operationId)
    {
        return properties;
    }

    /**
     * 处理 refModel 对象
     *
     * @param refModel    refModel 对象
     * @param definitions 对象定义集合
     * @param operationId 接口 Id
     * @return 新的refModel
     */
    private Model processModel(Model refModel, Map definitions, String operationId)
    {
        Model newRefModel = refModel;
        String reference = refModel.getReference();
        if (StringUtils.isEmpty(reference))
        {
            return newRefModel;
        }
        String modelName = reference.substring((reference.lastIndexOf('/') + 1));
        Model model = definitions.get(modelName);
        Map properties = model.getProperties();
        if (null == properties)
        {
            return newRefModel;
        }
        Map newProperties = propertiesFilter(properties, definitions, operationId);
        int len = model.getProperties().size();
        int newLen = newProperties.size();
        if (len != newLen)
        {
            String definitionsName = (modelName + ":" + operationId);
            String newReference = SCHEMA_DEFINITIONS + definitionsName;
            newRefModel = (Model) refModel.clone();
            newRefModel.setReference(newReference);
            // 处理refModel 内嵌属性
            newProperties.forEach((name, prop) ->
            {
                if (prop instanceof RefProperty && !refModel.getReference().equals(((RefProperty) prop).get$ref()))
                {
                    newProperties.put(name, processRefProperty((RefProperty) prop, definitions, operationId));
                }
                if (prop instanceof RefProperty && refModel.getReference().equals(((RefProperty) prop).get$ref()))
                {
                    RefProperty refProperty = new RefProperty(newReference);
                    newProperties.put(name, refProperty);
                }
                if (prop instanceof ArrayProperty)
                {
                    Property property = ((ArrayProperty) prop).getItems();
                    if (property instanceof RefProperty && !refModel.getReference().equals(((RefProperty) property).get$ref()))
                    {
                        newProperties.put(name, processRefProperty((RefProperty) property, definitions, operationId));
                    }
                    if (property instanceof RefProperty && refModel.getReference().equals(((RefProperty) property).get$ref()))
                    {
                        RefProperty refProperty = new RefProperty(newReference);
                        newProperties.put(name, refProperty);
                    }
                }

            });
            Model newModel = cloneNewModelPutDefinitions(model, newProperties);
            definitions.put(definitionsName, newModel);
        }
        return newRefModel;
    }

    private RefProperty processRefProperty(RefProperty refProperty, Map definitions, String operationId)
    {
        RefProperty newRefProperty = new RefProperty(refProperty.get$ref());
        String reference = refProperty.get$ref();
        String modelName = reference.substring((reference.lastIndexOf('/') + 1));
        if (!definitions.containsKey(modelName))
        {
            return refProperty;
        }
        Model model = definitions.get(modelName);
        Map properties = model.getProperties();
        if (null == properties)
        {
            return newRefProperty;
        }
        Map newProperties = propertiesFilter(properties, definitions, operationId);
        int len = properties.size();
        int newLen = newProperties.size();
        if (len != newLen)
        {

            String definitionsName = (modelName + ":" + operationId);
            String newReference = SCHEMA_DEFINITIONS + definitionsName;

            newRefProperty = new RefProperty(SCHEMA_DEFINITIONS + definitionsName);
            // 处理refModel 内嵌属性
            newProperties.forEach((name, prop) ->
            {
                if (prop instanceof RefProperty && !prop.equals(refProperty))
                {
                    newProperties.put(name, processRefProperty((RefProperty) prop, definitions, operationId));
                }
                if (prop instanceof RefProperty && refProperty.get$ref().startsWith(((RefProperty) prop).get$ref()))
                {
                    RefProperty newRef = new RefProperty(newReference);
                    newProperties.put(name, newRef);
                }
                if (prop instanceof ArrayProperty)
                {
                    Property property = ((ArrayProperty) prop).getItems();
                    if (property instanceof RefProperty && !property.equals(refProperty))
                    {
                        ArrayProperty arrayProperty = new ArrayProperty(processRefProperty((RefProperty) property, definitions, operationId));
                        newProperties.put(name, arrayProperty);
                    }
                    if (property instanceof RefProperty && refProperty.get$ref().startsWith(((RefProperty) property).get$ref()))
                    {
                        RefProperty newRef = new RefProperty(newReference);
                        ArrayProperty arrayProperty = new ArrayProperty(newRef);
                        newProperties.put(name, arrayProperty);
                    }
                }

            });

            // 改变属性定向的 model
            Model newModel = cloneNewModelPutDefinitions(model, newProperties);
            definitions.put(definitionsName, newModel);
        }
        return newRefProperty;
    }

    private Response processRequestResponse(Response response, Map definitions, String operationId)
    {
        Response newResponse = response;
        Model refModel = response.getResponseSchema();
        if (refModel instanceof RefModel)
        {
            String reference = refModel.getReference();
            String modelName = reference.substring((reference.lastIndexOf('/') + 1));
            Model model = definitions.get(modelName);
            Map properties = model.getProperties();
            if (null == properties)
            {
                return newResponse;
            }
            Map newProperties = propertiesFilter(properties, definitions, operationId);
            String definitionsName = (modelName + ":" + operationId);
            String newReference = SCHEMA_DEFINITIONS + definitionsName;
            Model newRefModel = (Model) refModel.clone();
            newRefModel.setReference(newReference);
            properties.forEach((name, prop) ->
            {
                if (prop instanceof RefProperty)
                {
                    newProperties.put(name, processRefProperty((RefProperty) prop, definitions, operationId));
                }
                if (prop instanceof ArrayProperty)
                {
                    Property property = ((ArrayProperty) prop).getItems();
                    if (property instanceof RefProperty)
                    {
                        Property items = processRefProperty((RefProperty) property, definitions, operationId);
                        ArrayProperty arrayProperty = new ArrayProperty(items);
                        newProperties.put(name, arrayProperty);
                    }
                }
            });
            Model newModel = cloneNewModelPutDefinitions(model, newProperties);
            definitions.put(definitionsName, newModel);
            newResponse = new RefResponse(newReference);
            newResponse.setResponseSchema(newRefModel);
        }
        return newResponse;
    }

    @Override
    public Swagger mapDocumentation(Documentation from)
    {
        if (from == null)
        {
            return null;
        }

        Swagger swagger = new Swagger();

        swagger.setVendorExtensions(vendorExtensionsMapper.mapExtensions(from.getVendorExtensions()));
        swagger.setSchemes(mapSchemes(from.getSchemes()));
        Map oldPaths = mapApiListings(from.getApiListings());
        Map definitions = beanMapper.modelsFromApiListings(from.getApiListings());
        // 接口定义排序
        Map paths = new LinkedHashMap<>();
        oldPaths.entrySet().stream().filter(stringPathEntry -> null != stringPathEntry.getValue()
                && ((null != stringPathEntry.getValue().getGet() && stringPathEntry.getValue().getGet().getVendorExtensions().containsKey("x-order"))
                || (null != stringPathEntry.getValue().getPost() && stringPathEntry.getValue().getPost().getVendorExtensions().containsKey("x-order"))))
                .sorted((o1, o2) ->
                {
                    int position1 = Integer.MAX_VALUE;
                    int position2 = Integer.MAX_VALUE;
                    if (o1.getValue().getGet() != null)
                    {
                        position1 = Integer.parseInt(o1.getValue().getGet().getVendorExtensions().get("x-order").toString());
                    }
                    if (o1.getValue().getPost() != null)
                    {
                        position1 = Integer.parseInt(o1.getValue().getPost().getVendorExtensions().get("x-order").toString());
                    }
                    if (o2.getValue().getGet() != null)
                    {
                        position2 = Integer.parseInt(o2.getValue().getGet().getVendorExtensions().get("x-order").toString());
                    }
                    if (o2.getValue().getPost() != null)
                    {
                        position2 = Integer.parseInt(o2.getValue().getPost().getVendorExtensions().get("x-order").toString());
                    }
                    return position1 - position2;
                }).forEach(e -> paths.put(e.getKey(), e.getValue()));
        swagger.setPaths(paths);
        swagger.setHost(from.getHost());

        swagger.setDefinitions(definitions);
        swagger.setSecurityDefinitions(securityMapper.toSecuritySchemeDefinitions(from.getResourceListing()));
        ApiInfo info = fromResourceListingInfo(from);
        if (info != null)
        {
            swagger.setInfo(mapApiInfo(info));
        }
        swagger.setBasePath(from.getBasePath());
        swagger.setTags(tagSetToTagList(from.getTags()));
        List list2 = from.getConsumes();
        if (list2 != null)
        {
            swagger.setConsumes(new ArrayList(list2));
        }
        else
        {
            swagger.setConsumes(null);
        }
        List list3 = from.getProduces();
        if (list3 != null)
        {
            swagger.setProduces(new ArrayList(list3));
        }
        else
        {
            swagger.setProduces(null);
        }

        return swagger;
    }

    private ApiInfo fromResourceListingInfo(Documentation documentation)
    {
        if (documentation == null)
        {
            return null;
        }
        ResourceListing resourceListing = documentation.getResourceListing();
        if (resourceListing == null)
        {
            return null;
        }
        return resourceListing.getInfo();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy