io.swagger.v3.parser.util.ResolverFully Maven / Gradle / Ivy
package io.swagger.v3.parser.util;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.callbacks.Callback;
import io.swagger.v3.oas.models.examples.Example;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.MediaType;
import io.swagger.v3.oas.models.media.ObjectSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.parser.models.RefFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static io.swagger.v3.parser.util.RefUtils.computeDefinitionName;
import static io.swagger.v3.parser.util.RefUtils.computeRefFormat;
import static io.swagger.v3.parser.util.RefUtils.isAnExternalRefFormat;
public class ResolverFully {
private static final Logger LOGGER = LoggerFactory.getLogger(ResolverFully.class);
private boolean aggregateCombinators;
public ResolverFully() {
this(true);
}
public ResolverFully(boolean aggregateCombinators) {
this.aggregateCombinators = aggregateCombinators;
}
private Map schemas;
private Map resolvedModels = new HashMap<>();
private Map examples;
private Map requestBodies;
public void resolveFully(OpenAPI openAPI) {
if (openAPI.getComponents() != null && openAPI.getComponents().getRequestBodies() != null) {
requestBodies = openAPI.getComponents().getRequestBodies();
if (requestBodies == null) {
requestBodies = new HashMap<>();
}
}
if (openAPI.getComponents() != null && openAPI.getComponents().getSchemas() != null) {
schemas = openAPI.getComponents().getSchemas();
if (schemas == null) {
schemas = new HashMap<>();
}
}
if (openAPI.getComponents() != null && openAPI.getComponents().getExamples() != null) {
examples = openAPI.getComponents().getExamples();
if (examples == null) {
examples = 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);
}
}
}
}
}
RequestBody refRequestBody = op.getRequestBody();
if (refRequestBody != null){
RequestBody requestBody = refRequestBody.get$ref() != null ? resolveRequestBody(refRequestBody) : refRequestBody;
if (requestBody.getContent() != null) {
Map content = requestBody.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);
}
if(content.get(mediaType).getExamples() != null) {
Map resolved = resolveExample(content.get(mediaType).getExamples());
response.getContent().get(mediaType).setExamples(resolved);
}
}
}
}
}
}
}
public RequestBody resolveRequestBody(RequestBody requestBody){
RefFormat refFormat = computeRefFormat(requestBody.get$ref());
String $ref = requestBody.get$ref();
if (!isAnExternalRefFormat(refFormat)){
if (requestBodies != null && !requestBodies.isEmpty()) {
String referenceKey = computeDefinitionName($ref);
return requestBodies.getOrDefault(referenceKey, requestBody);
}
}
return requestBody;
}
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;
if(arrayModel.getItems().get$ref() != null) {
arrayModel.setItems(resolveSchema(arrayModel.getItems()));
} else {
arrayModel.setItems(arrayModel.getItems());
}
return arrayModel;
}
if (schema instanceof ObjectSchema) {
ObjectSchema obj = (ObjectSchema) schema;
if(obj.getProperties() != null) {
Map updated = new LinkedHashMap<>();
for(String propertyName : obj.getProperties().keySet()) {
Schema innerProperty = obj.getProperties().get(propertyName);
// reference check
if(schema != innerProperty) {
Schema resolved = resolveSchema(innerProperty);
updated.put(propertyName, resolved);
}
}
obj.setProperties(updated);
}
return obj;
}
if(schema instanceof ComposedSchema) {
ComposedSchema composedSchema = (ComposedSchema) schema;
boolean adjacent = false;
if (aggregateCombinators) {
Schema model = SchemaTypeUtil.createSchema(composedSchema.getType(), composedSchema.getFormat());
Set requiredProperties = new HashSet<>();
Set
© 2015 - 2024 Weber Informatics LLC | Privacy Policy