1 package io.swagger.v3.core.util;
2
3 import com.fasterxml.jackson.core.JsonParser;
4 import com.fasterxml.jackson.core.JsonProcessingException;
5 import com.fasterxml.jackson.databind.DeserializationContext;
6 import com.fasterxml.jackson.databind.JsonDeserializer;
7 import com.fasterxml.jackson.databind.JsonNode;
8 import com.fasterxml.jackson.databind.node.ObjectNode;
9 import com.fasterxml.jackson.databind.node.TextNode;
10 import io.swagger.v3.oas.models.media.ArraySchema;
11 import io.swagger.v3.oas.models.media.BooleanSchema;
12 import io.swagger.v3.oas.models.media.ComposedSchema;
13 import io.swagger.v3.oas.models.media.DateSchema;
14 import io.swagger.v3.oas.models.media.DateTimeSchema;
15 import io.swagger.v3.oas.models.media.EmailSchema;
16 import io.swagger.v3.oas.models.media.IntegerSchema;
17 import io.swagger.v3.oas.models.media.MapSchema;
18 import io.swagger.v3.oas.models.media.NumberSchema;
19 import io.swagger.v3.oas.models.media.ObjectSchema;
20 import io.swagger.v3.oas.models.media.PasswordSchema;
21 import io.swagger.v3.oas.models.media.Schema;
22 import io.swagger.v3.oas.models.media.StringSchema;
23 import io.swagger.v3.oas.models.media.UUIDSchema;
24 import org.apache.commons.lang3.StringUtils;
25
26 import java.io.IOException;
27
28 public class ModelDeserializer extends JsonDeserializer<Schema> {
29     @Override
30     public Schema deserialize(JsonParser jp, DeserializationContext ctxt)
31             throws IOException, JsonProcessingException {
32         JsonNode node = jp.getCodec().readTree(jp);
33         JsonNode allOf = node.get("allOf");
34         JsonNode anyOf = node.get("anyOf");
35         JsonNode oneOf = node.get("oneOf");
36
37         Schema schema = null;
38
39         if (allOf != null || anyOf != null || oneOf != null) {
40
41             ComposedSchema composedSchema = Json.mapper().convertValue(node, ComposedSchema.class);
42             return composedSchema;
43
44         } else {
45
46             JsonNode type = node.get("type");
47             String format = node.get("format") == null ? "" : node.get("format").textValue();
48
49             if (type != null && "array".equals(((TextNode) type).textValue())) {
50                 schema = Json.mapper().convertValue(node, ArraySchema.class);
51             } else if (type != null) {
52                 if (type.textValue().equals("integer")) {
53                     schema = Json.mapper().convertValue(node, IntegerSchema.class);
54                     if (StringUtils.isBlank(format)) {
55                         schema.setFormat(null);
56                     }
57                 } else if (type.textValue().equals("number")) {
58                     schema = Json.mapper().convertValue(node, NumberSchema.class);
59                 } else if (type.textValue().equals("boolean")) {
60                     schema = Json.mapper().convertValue(node, BooleanSchema.class);
61                 } else if (type.textValue().equals("string")) {
62                     if ("date".equals(format)) {
63                         schema = Json.mapper().convertValue(node, DateSchema.class);
64                     } else if ("date-time".equals(format)) {
65                         schema = Json.mapper().convertValue(node, DateTimeSchema.class);
66                     } else if ("email".equals(format)) {
67                         schema = Json.mapper().convertValue(node, EmailSchema.class);
68                     } else if ("password".equals(format)) {
69                         schema = Json.mapper().convertValue(node, PasswordSchema.class);
70                     } else if ("uuid".equals(format)) {
71                         schema = Json.mapper().convertValue(node, UUIDSchema.class);
72                     } else {
73                         schema = Json.mapper().convertValue(node, StringSchema.class);
74                     }
75                 } else if (type.textValue().equals("object")) {
76                     schema = deserializeObjectSchema(node);
77                 }
78             } else if (node.get("$ref") != null) {
79                 schema = new Schema().$ref(node.get("$ref").asText());
80             } else { // assume object
81                 schema = deserializeObjectSchema(node);
82             }
83         }
84
85         return schema;
86     }
87
88     private Schema deserializeObjectSchema(JsonNode node) {
89         JsonNode additionalProperties = node.get("additionalProperties");
90         Schema schema = null;
91         if (additionalProperties != null) {
92             // try first to convert to Schema, if it fails it must be a boolean
93             try {
94                 Schema innerSchema = Json.mapper().convertValue(additionalProperties, Schema.class);
95                 ((ObjectNode)node).remove("additionalProperties");
96                 MapSchema ms = Json.mapper().convertValue(node, MapSchema.class);
97                 ms.setAdditionalProperties(innerSchema);
98                 schema = ms;
99             } catch (Exception e) {
100                 Boolean additionalPropsBoolean = Json.mapper().convertValue(additionalProperties, Boolean.class);
101                 if (additionalPropsBoolean) {
102                     schema = Json.mapper().convertValue(node, MapSchema.class);
103                 } else {
104                     schema = Json.mapper().convertValue(node, ObjectSchema.class);
105                 }
106                 schema.setAdditionalProperties(additionalPropsBoolean);
107             }
108
109         } else {
110             schema = Json.mapper().convertValue(node, ObjectSchema.class);
111         }
112         return schema;
113     }
114 }
115