package io.github.robwin.swagger.test;
import io.swagger.models.*;
import io.swagger.models.properties.Property;
import java.util.*;
/**
* Provide a means to retrieve values from various objects in the schema. Provides a means of falling back to 'global'
* settings if they're not defined locally in a definition or path object. Also permits resolving local
* {@code $ref}-erences and types making use of {@code allOf}-style inheritance.
*/
class SchemaObjectResolver {
private Swagger expected;
private Swagger actual;
SchemaObjectResolver(Swagger expected, Swagger actual) {
this.expected = expected;
this.actual = actual;
}
List<String> getExpectedConsumes(Operation op) {
return getListWithFallback(op.getConsumes(), expected.getConsumes());
}
List<String> getActualConsumes(Operation op) {
return getListWithFallback(op.getConsumes(), actual.getConsumes());
}
List<String> getExpectedProduces(Operation op) {
return getListWithFallback(op.getProduces(), expected.getProduces());
}
List<String> getActualProduces(Operation op) {
return getListWithFallback(op.getProduces(), actual.getProduces());
}
Map<String, Property> resolvePropertiesFromExpected(Model definition) {
return resolveProperties(definition, expected, new HashSet<String>());
}
Map<String, Property> resolvePropertiesFromActual(Model definition) {
return resolveProperties(definition, actual, new HashSet<String>());
}
private Map<String, Property> resolveProperties(Model definition, Swagger owningSchema, Set<String> seenRefs) {
Map<String, Property> result;
final Map<String, Property> definitionProperties = definition.getProperties();
if (definition instanceof RefModel) {
// Don't navigate ref-def cycles infinitely
final RefModel refDef = (RefModel) definition;
if (seenRefs.contains(refDef.getSimpleRef())) {
return Collections.emptyMap();
} else {
seenRefs.add(refDef.getSimpleRef());
}
result = resolveProperties(findDefinition(owningSchema.getDefinitions(), refDef), owningSchema, seenRefs);
} else if (definition instanceof ComposedModel) {
Map<String, Property> allProperties = new HashMap<>();
if (definitionProperties != null) {
allProperties.putAll(definitionProperties);
}
for (final Model childDefinition : ((ComposedModel)definition).getAllOf()) {
allProperties.putAll(resolveProperties(childDefinition, owningSchema, seenRefs));
}
result = allProperties;
} else {
result = definitionProperties;
}
return result;
}
private Model findDefinition(Map<String, Model> defs, RefModel refModel) {
return defs.get(refModel.getSimpleRef());
}
private <A> List<A> getListWithFallback(List<A> localDefn, List<A> globalDefn) {
final List<A> result;
if (localDefn != null && !localDefn.isEmpty()) {
result = localDefn;
} else if (globalDefn != null) {
result = globalDefn;
} else {
result = Collections.emptyList();
}
return result;
}
}