use of io.swagger.v3.oas.models.media.Discriminator in project swagger-parser by swagger-api.
the class OpenAPIDeserializerTest method testDeserializeWithDiscriminator.
@Test
public void testDeserializeWithDiscriminator() {
String yaml = "openapi: 3.0.0\n" + "servers: []\n" + "info:\n" + " version: ''\n" + " title: ''\n" + "paths: {}\n" + "components:\n" + " schemas:\n" + " Animal:\n" + " type: object\n" + " discriminator:\n" + " propertyName: petType\n" + " description: |\n" + " A basic `Animal` object which can extend to other animal types.\n" + " required:\n" + " - commonName\n" + " - petType\n" + " properties:\n" + " commonName:\n" + " description: the household name of the animal\n" + " type: string\n" + " petType:\n" + " description: |\n" + " The discriminator for the animal type. It _must_\n" + " match one of the concrete schemas by name (i.e. `Cat`)\n" + " for proper deserialization\n" + " type: string";
OpenAPIV3Parser parser = new OpenAPIV3Parser();
SwaggerParseResult result = parser.readContents(yaml, null, null);
Set<String> messages = new HashSet<>(result.getMessages());
assertFalse(messages.contains("attribute definitions.Animal.discriminator is unexpected"));
}
use of io.swagger.v3.oas.models.media.Discriminator in project swagger-parser by swagger-api.
the class OpenAPIDeserializerTest method testDeserializeWithNumericEnumDiscriminator.
@Test
public void testDeserializeWithNumericEnumDiscriminator() {
String yaml = "openapi: 3.0.0\n" + "components:\n" + " schemas:\n" + " Animal:\n" + " type: object\n" + " discriminator:\n" + " propertyName: petType\n" + " description: |\n" + " A basic `Animal` object which can extend to other animal types.\n" + " required:\n" + " - commonName\n" + " - petType\n" + " properties:\n" + " commonName:\n" + " description: the household name of the animal\n" + " type: string\n" + " petType:\n" + " enum:\n" + " - 1\n" + " - 2";
OpenAPIV3Parser parser = new OpenAPIV3Parser();
SwaggerParseResult result = parser.readContents(yaml, null, null);
Map<String, Schema> properties = result.getOpenAPI().getComponents().getSchemas().get("Animal").getProperties();
assertTrue(properties.containsKey("commonName"));
assertTrue(properties.containsKey("petType"));
assertEquals(properties.get("petType").getType(), "number");
}
use of io.swagger.v3.oas.models.media.Discriminator in project swagger-parser by swagger-api.
the class OpenAPIDeserializer method getSchema.
public Schema getSchema(ObjectNode node, String location, ParseResult result) {
if (node == null) {
return null;
}
// Added to handle NPE from ResolverCache when Trying to dereference a schema
if (result == null) {
result = new ParseResult();
result.setAllowEmptyStrings(true);
}
Schema schema = null;
ArrayNode oneOfArray = getArray("oneOf", node, false, location, result);
ArrayNode allOfArray = getArray("allOf", node, false, location, result);
ArrayNode anyOfArray = getArray("anyOf", node, false, location, result);
ObjectNode itemsNode = getObject("items", node, false, location, result);
if ((allOfArray != null) || (anyOfArray != null) || (oneOfArray != null)) {
ComposedSchema composedSchema = new ComposedSchema();
if (allOfArray != null) {
for (JsonNode n : allOfArray) {
if (n.isObject()) {
schema = getSchema((ObjectNode) n, location, result);
composedSchema.addAllOfItem(schema);
}
}
schema = composedSchema;
}
if (anyOfArray != null) {
for (JsonNode n : anyOfArray) {
if (n.isObject()) {
schema = getSchema((ObjectNode) n, location, result);
composedSchema.addAnyOfItem(schema);
}
}
schema = composedSchema;
}
if (oneOfArray != null) {
for (JsonNode n : oneOfArray) {
if (n.isObject()) {
schema = getSchema((ObjectNode) n, location, result);
composedSchema.addOneOfItem(schema);
}
}
schema = composedSchema;
}
}
if (itemsNode != null) {
ArraySchema items = new ArraySchema();
if (itemsNode.getNodeType().equals(JsonNodeType.OBJECT)) {
items.setItems(getSchema(itemsNode, location, result));
} else if (itemsNode.getNodeType().equals(JsonNodeType.ARRAY)) {
for (JsonNode n : itemsNode) {
if (n.isValueNode()) {
items.setItems(getSchema(itemsNode, location, result));
}
}
}
schema = items;
}
Boolean additionalPropertiesBoolean = getBoolean("additionalProperties", node, false, location, result);
ObjectNode additionalPropertiesObject = additionalPropertiesBoolean == null ? getObject("additionalProperties", node, false, location, result) : null;
Object additionalProperties = additionalPropertiesObject != null ? getSchema(additionalPropertiesObject, location, result) : additionalPropertiesBoolean;
if (additionalProperties != null) {
if (schema == null) {
schema = additionalProperties.equals(Boolean.FALSE) ? new ObjectSchema() : new MapSchema();
}
schema.setAdditionalProperties(additionalProperties);
}
if (schema == null) {
schema = SchemaTypeUtil.createSchemaByType(node);
}
JsonNode ref = node.get("$ref");
if (ref != null) {
if (ref.getNodeType().equals(JsonNodeType.STRING)) {
if (location.startsWith("paths")) {
try {
String[] components = ref.asText().split("#/components");
if ((ref.asText().startsWith("#/components")) && (components.length > 1)) {
String[] childComponents = components[1].split("/");
String[] newChildComponents = Arrays.copyOfRange(childComponents, 1, childComponents.length);
boolean isValidComponent = ReferenceValidator.valueOf(newChildComponents[0]).validateComponent(this.components, newChildComponents[1]);
if (!isValidComponent) {
result.missing(location, ref.asText());
}
}
} catch (Exception e) {
result.missing(location, ref.asText());
}
}
String mungedRef = mungedRef(ref.textValue());
if (mungedRef != null) {
schema.set$ref(mungedRef);
} else {
schema.set$ref(ref.asText());
}
return schema;
} else {
result.invalidType(location, "$ref", "string", node);
return null;
}
}
String value = getString("title", node, false, location, result);
if ((result.isAllowEmptyStrings() && value != null) || (!result.isAllowEmptyStrings() && !StringUtils.isBlank(value))) {
schema.setTitle(value);
}
ObjectNode discriminatorNode = getObject("discriminator", node, false, location, result);
if (discriminatorNode != null) {
schema.setDiscriminator(getDiscriminator(discriminatorNode, location, result));
}
BigDecimal bigDecimal = getBigDecimal("multipleOf", node, false, location, result);
if (bigDecimal != null) {
if (bigDecimal.compareTo(BigDecimal.ZERO) > 0) {
schema.setMultipleOf(bigDecimal);
} else {
result.warning(location, "multipleOf value must be > 0");
}
}
bigDecimal = getBigDecimal("maximum", node, false, location, result);
if (bigDecimal != null) {
schema.setMaximum(bigDecimal);
}
Boolean bool = getBoolean("exclusiveMaximum", node, false, location, result);
if (bool != null) {
schema.setExclusiveMaximum(bool);
}
bigDecimal = getBigDecimal("minimum", node, false, location, result);
if (bigDecimal != null) {
schema.setMinimum(bigDecimal);
}
bool = getBoolean("exclusiveMinimum", node, false, location, result);
if (bool != null) {
schema.setExclusiveMinimum(bool);
}
Integer integer = getInteger("minLength", node, false, location, result);
if (integer != null) {
schema.setMinLength(integer);
}
integer = getInteger("maxLength", node, false, location, result);
if (integer != null) {
schema.setMaxLength(integer);
}
String pattern = getString("pattern", node, false, location, result);
if (result.isAllowEmptyStrings() && pattern != null) {
schema.setPattern(pattern);
}
integer = getInteger("maxItems", node, false, location, result);
if (integer != null) {
schema.setMaxItems(integer);
}
integer = getInteger("minItems", node, false, location, result);
if (integer != null) {
schema.setMinItems(integer);
}
bool = getBoolean("uniqueItems", node, false, location, result);
if (bool != null) {
schema.setUniqueItems(bool);
}
integer = getInteger("maxProperties", node, false, location, result);
if (integer != null) {
schema.setMaxProperties(integer);
}
integer = getInteger("minProperties", node, false, location, result);
if (integer != null) {
schema.setMinProperties(integer);
}
ArrayNode required = getArray("required", node, false, location, result);
if (required != null) {
List<String> requiredList = new ArrayList<>();
for (JsonNode n : required) {
if (n.getNodeType().equals(JsonNodeType.STRING)) {
requiredList.add(((TextNode) n).textValue());
} else {
result.invalidType(location, "required", "string", n);
}
}
if (requiredList.size() > 0) {
schema.setRequired(requiredList);
}
}
ArrayNode enumArray = getArray("enum", node, false, location, result);
if (enumArray != null) {
for (JsonNode n : enumArray) {
if (n.isNumber()) {
schema.addEnumItemObject(n.numberValue());
} else if (n.isBoolean()) {
schema.addEnumItemObject(n.booleanValue());
} else if (n.isValueNode()) {
try {
schema.addEnumItemObject(getDecodedObject(schema, n.asText(null)));
} catch (ParseException e) {
result.invalidType(location, String.format("enum=`%s`", e.getMessage()), schema.getFormat(), n);
}
} else if (n.isContainerNode()) {
schema.addEnumItemObject(n.isNull() ? null : n);
} else {
result.invalidType(location, "enum", "value", n);
}
}
}
value = getString("type", node, false, location, result);
if (StringUtils.isBlank(schema.getType())) {
if ((result.isAllowEmptyStrings() && value != null) || (!result.isAllowEmptyStrings() && !StringUtils.isBlank(value))) {
schema.setType(value);
} else {
// may have an enum where type can be inferred
JsonNode enumNode = node.get("enum");
if (enumNode != null && enumNode.isArray()) {
String type = inferTypeFromArray((ArrayNode) enumNode);
schema.setType(type);
}
}
if ("array".equals(schema.getType()) && !(schema instanceof ArraySchema && ((ArraySchema) schema).getItems() != null)) {
result.missing(location, "items");
}
}
ObjectNode notObj = getObject("not", node, false, location, result);
if (notObj != null) {
Schema not = getSchema(notObj, location, result);
if (not != null) {
schema.setNot(not);
}
}
Map<String, Schema> properties = new LinkedHashMap<>();
ObjectNode propertiesObj = getObject("properties", node, false, location, result);
Schema property = null;
Set<String> keys = getKeys(propertiesObj);
for (String name : keys) {
JsonNode propertyValue = propertiesObj.get(name);
if (!propertyValue.getNodeType().equals(JsonNodeType.OBJECT)) {
result.invalidType(location, "properties", "object", propertyValue);
} else {
if (propertiesObj != null) {
property = getSchema((ObjectNode) propertyValue, location, result);
if (property != null) {
properties.put(name, property);
}
}
}
}
if (propertiesObj != null) {
schema.setProperties(properties);
}
value = getString("description", node, false, location, result);
if ((result.isAllowEmptyStrings() && value != null) || (!result.isAllowEmptyStrings() && !StringUtils.isBlank(value))) {
schema.setDescription(value);
}
value = getString("format", node, false, location, result);
if ((result.isAllowEmptyStrings() && value != null) || (!result.isAllowEmptyStrings() && !StringUtils.isBlank(value))) {
schema.setFormat(value);
}
// sets default value according to the schema type
if (node.get("default") != null) {
if (!StringUtils.isBlank(schema.getType())) {
if (schema.getType().equals("array")) {
ArrayNode array = getArray("default", node, false, location, result);
if (array != null) {
schema.setDefault(array);
}
} else if (schema.getType().equals("string")) {
value = getString("default", node, false, location, result);
if ((result.isAllowEmptyStrings() && value != null) || (!result.isAllowEmptyStrings() && !StringUtils.isBlank(value))) {
try {
schema.setDefault(getDecodedObject(schema, value));
} catch (ParseException e) {
result.invalidType(location, String.format("default=`%s`", e.getMessage()), schema.getFormat(), node);
}
}
} else if (schema.getType().equals("boolean")) {
bool = getBoolean("default", node, false, location, result);
if (bool != null) {
schema.setDefault(bool);
}
} else if (schema.getType().equals("object")) {
Object object = getObject("default", node, false, location, result);
if (object != null) {
schema.setDefault(object);
}
} else if (schema.getType().equals("integer")) {
Integer number = getInteger("default", node, false, location, result);
if (number != null) {
schema.setDefault(number);
}
} else if (schema.getType().equals("number")) {
BigDecimal number = getBigDecimal("default", node, false, location, result);
if (number != null) {
schema.setDefault(number);
}
}
}
}
bool = getBoolean("nullable", node, false, location, result);
if (bool != null) {
schema.setNullable(bool);
}
bool = getBoolean("readOnly", node, false, location, result);
if (bool != null) {
schema.setReadOnly(bool);
}
bool = getBoolean("writeOnly", node, false, location, result);
if (bool != null) {
schema.setWriteOnly(bool);
}
bool = Optional.ofNullable(getBoolean("writeOnly", node, false, location, result)).orElse(false) && Optional.ofNullable(getBoolean("readOnly", node, false, location, result)).orElse(false);
if (bool == true) {
result.warning(location, " writeOnly and readOnly are both present");
}
ObjectNode xmlNode = getObject("xml", node, false, location, result);
if (xmlNode != null) {
XML xml = getXml(xmlNode, location, result);
if (xml != null) {
schema.setXml(xml);
}
}
ObjectNode externalDocs = getObject("externalDocs", node, false, location, result);
if (externalDocs != null) {
ExternalDocumentation docs = getExternalDocs(externalDocs, location, result);
if (docs != null) {
schema.setExternalDocs(docs);
}
}
Object example = getAnyExample("example", node, location, result);
if (example != null) {
schema.setExample(example instanceof NullNode ? null : example);
}
bool = getBoolean("deprecated", node, false, location, result);
if (bool != null) {
schema.setDeprecated(bool);
}
Map<String, Object> extensions = getExtensions(node);
if (extensions != null && extensions.size() > 0) {
schema.setExtensions(extensions);
}
Set<String> schemaKeys = getKeys(node);
for (String key : schemaKeys) {
if (!SCHEMA_KEYS.contains(key) && !key.startsWith("x-")) {
result.extra(location, key, node.get(key));
}
}
return schema;
}
use of io.swagger.v3.oas.models.media.Discriminator in project swagger-parser by swagger-api.
the class OpenAPIV3ParserTest method testDiscriminatorSingleFileInternalMapping.
@Test
public void testDiscriminatorSingleFileInternalMapping() throws Exception {
OpenAPI openAPI = new OpenAPIV3Parser().read("./discriminator-mapping-resolution/single-file-internal-mapping.yaml");
Assert.assertNotNull(openAPI);
Schema cat = openAPI.getComponents().getSchemas().get("Cat");
Assert.assertNotNull(cat);
}
use of io.swagger.v3.oas.models.media.Discriminator in project swagger-parser by swagger-api.
the class OpenAPIV3ParserTest method testDiscriminatorSingleFileNoMapping.
@Test
public void testDiscriminatorSingleFileNoMapping() throws Exception {
OpenAPI openAPI = new OpenAPIV3Parser().read("./discriminator-mapping-resolution/single-file-no-mapping.yaml");
Assert.assertNotNull(openAPI);
Schema cat = openAPI.getComponents().getSchemas().get("Cat");
Assert.assertNotNull(cat);
}
Aggregations