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

io.swagger.parser.v3.util.ResolverFully Maven / Gradle / Ivy

There is a newer version: 2.0.0-rc1
Show newest version
package io.swagger.parser.v3.util;

import io.swagger.oas.models.OpenAPI;
import io.swagger.oas.models.Operation;
import io.swagger.oas.models.PathItem;
import io.swagger.oas.models.callbacks.Callback;
import io.swagger.oas.models.media.ArraySchema;
import io.swagger.oas.models.media.ComposedSchema;
import io.swagger.oas.models.media.MediaType;
import io.swagger.oas.models.media.Schema;
import io.swagger.oas.models.parameters.Parameter;
import io.swagger.oas.models.responses.ApiResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

public class ResolverFully {
    private static final Logger LOGGER = LoggerFactory.getLogger(ResolverFully.class);

    private Map schemas;
    private Map resolvedModels = new HashMap<>();




    public void resolveFully(OpenAPI openAPI) {

        if (openAPI.getComponents().getSchemas() != null) {
            schemas = openAPI.getComponents().getSchemas();
            if (schemas == null) {
                schemas = new HashMap<>();
            }
        }

        if(openAPI.getPaths() != null) {
            for (String pathname : openAPI.getPaths().keySet()) {
                PathItem pathItem = openAPI.getPaths().get(pathname);
                resolvePath(pathItem);
            }
        }
    }

    public void resolvePath(PathItem pathItem){
        for(Operation op : pathItem.readOperations()) {
            // inputs
            if (op.getParameters() != null) {
                for (Parameter parameter : op.getParameters()) {
                    if (parameter.getSchema() != null) {
                        Schema resolved = resolveSchema(parameter.getSchema());
                        if (resolved != null) {
                            parameter.setSchema(resolved);
                        }
                    }
                    if(parameter.getContent() != null){
                        Map content = parameter.getContent();
                        for (String key: content.keySet()){
                            if (content.get(key) != null && content.get(key).getSchema() != null ){
                                Schema resolvedSchema = resolveSchema(content.get(key).getSchema());
                                if (resolvedSchema != null) {
                                    content.get(key).setSchema(resolvedSchema);
                                }
                            }
                        }
                    }
                }
            }

            if (op.getCallbacks() != null){
                Map callbacks = op.getCallbacks();
                for (String name : callbacks.keySet()) {
                    Callback callback = callbacks.get(name);
                    if (callback != null) {
                        for(String callbackName : callback.keySet()) {
                            PathItem path = callback.get(callbackName);
                            if(path != null){
                                resolvePath(path);
                            }

                        }
                    }
                }
            }

            if (op.getRequestBody() != null && op.getRequestBody().getContent() != null){
                Map content = op.getRequestBody().getContent();
                for (String key: content.keySet()){
                    if (content.get(key) != null && content.get(key).getSchema() != null ){
                        Schema resolved = resolveSchema(content.get(key).getSchema());
                        if (resolved != null) {
                            content.get(key).setSchema(resolved);
                        }
                    }
                }
            }
            // responses
            if(op.getResponses() != null) {
                for(String code : op.getResponses().keySet()) {
                    ApiResponse response = op.getResponses().get(code);
                    if (response.getContent() != null) {
                        Map content = response.getContent();
                        for(String mediaType: content.keySet()){
                            if(content.get(mediaType).getSchema() != null) {
                                Schema resolved = resolveSchema(content.get(mediaType).getSchema());
                                response.getContent().get(mediaType).setSchema(resolved);
                            }
                        }
                    }
                }
            }
        }
    }


    public Schema resolveSchema(Schema schema) {
        if(schema.get$ref() != null) {
            String ref= schema.get$ref();
            ref = ref.substring(ref.lastIndexOf("/") + 1);
            Schema resolved = schemas.get(ref);
            if(resolved == null) {
                LOGGER.error("unresolved model " + ref);
                return schema;
            }
            if(this.resolvedModels.containsKey(ref)) {
                LOGGER.debug("avoiding infinite loop");
                return this.resolvedModels.get(ref);
            }
            this.resolvedModels.put(ref, schema);

            Schema model = resolveSchema(resolved);

            // if we make it without a resolution loop, we can update the reference
            this.resolvedModels.put(ref, model);
            return model;
        }
        if(schema instanceof ArraySchema) {
            ArraySchema arrayModel = (ArraySchema) schema;
            Schema items = arrayModel.getItems();
            if(items.get$ref() != null) {
                Schema resolved = resolveSchema(items);
                arrayModel.setItems(resolved);
            }
            return arrayModel;
        }

        if (schema.getProperties() != null) {
            Schema model = schema;
            Map updated = new LinkedHashMap<>();
            Map properties = model.getProperties();
            for (String propertyName : properties.keySet()) {
                Schema property = (Schema) model.getProperties().get(propertyName);
                Schema resolved = resolveSchema(property);
                updated.put(propertyName, resolved);
            }

            for (String key : updated.keySet()) {
                Schema property = updated.get(key);

                if (property.getProperties() != model.getProperties()) {
                    if(property.getType() == null) {
                        property.setType("object");
                    }
                    model.addProperties(key, property);
                } else {
                    LOGGER.debug("not adding recursive properties, using generic object");
                    Schema newSchema = new Schema();
                    newSchema.setType("object");
                    model.addProperties(key, newSchema);
                }

            }
            return model;
        }

        if(schema instanceof ComposedSchema) {
            ComposedSchema composedSchema = (ComposedSchema) schema;
            Schema model = new Schema();
            Set requiredProperties = new HashSet<>();
            if(composedSchema.getAllOf() != null){
                for(Schema innerModel : composedSchema.getAllOf()) {
                    Schema resolved = resolveSchema(innerModel);
                    Map properties = resolved.getProperties();
                    if (resolved.getProperties() != null) {
                        int count = 0;
                        for (String key : properties.keySet()) {
                            Schema prop = (Schema) resolved.getProperties().get(key);
                            if (prop.getRequired() != null) {
                                if (prop.getRequired().get(count) != null) {
                                    requiredProperties.add(key);
                                }
                            }
                            count++;
                            model.addProperties(key, resolveSchema(prop));
                        }
                    }

                }
            }else if(composedSchema.getOneOf() != null){
                for(Schema innerModel : composedSchema.getOneOf()) {
                    Schema resolved = resolveSchema(innerModel);
                    Map properties = resolved.getProperties();
                    if (resolved.getProperties() != null) {
                        int count = 0;
                        for (String key : properties.keySet()) {
                            Schema prop = (Schema) resolved.getProperties().get(key);
                            if (prop.getRequired() != null) {
                                if (prop.getRequired().get(count) != null) {
                                    requiredProperties.add(key);
                                }
                            }
                            count++;
                            model.addProperties(key, resolveSchema(prop));
                        }
                    }

                }

            }else if(composedSchema.getAnyOf() != null){
                for(Schema innerModel : composedSchema.getAnyOf()) {
                    Schema resolved = resolveSchema(innerModel);
                    Map properties = resolved.getProperties();
                    if (resolved.getProperties() != null) {
                        int count = 0;
                        for (String key : properties.keySet()) {
                            Schema prop = (Schema) resolved.getProperties().get(key);
                            if (prop.getRequired() != null) {
                                if (prop.getRequired().get(count) != null) {
                                    requiredProperties.add(key);
                                }
                            }
                            count++;
                            model.addProperties(key, resolveSchema(prop));
                        }
                    }

                }
            }
            if(requiredProperties.size() > 0) {
                model.setRequired(new ArrayList<>(requiredProperties));
            }
            if(composedSchema.getExtensions() != null) {
                Map extensions = composedSchema.getExtensions();
                for(String key : extensions.keySet()) {
                    model.addExtension(key, composedSchema.getExtensions().get(key));
                }
            }
            return model;
        }
        LOGGER.error("no type match for " + schema);
        return schema;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy