de.thingweb.typesystem.jsonschema.JsonSchemaType.java Source code

Java tutorial

Introduction

Here is the source code for de.thingweb.typesystem.jsonschema.JsonSchemaType.java

Source

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Siemens AG and the thingweb community
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package de.thingweb.typesystem.jsonschema;

import java.io.StringReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeType;

public class JsonSchemaType {

    static final List<String> SIMPLE_TYPES = Arrays.asList("boolean", "integer", "number", "null", "string");

    static final List<String> COMPOSED_TYPES = Arrays.asList("array", "object");

    public static boolean isSimpleType(String type) {
        return isOfType(type, SIMPLE_TYPES);
    }

    public static boolean isComposedType(String type) {
        return isOfType(type, COMPOSED_TYPES);
    }

    private static boolean isOfType(String type, List<String> types) {
        boolean isOfType = false;

        try {
            // TODO use JSON schema parser
            if (type != null) {

                ObjectMapper mapper = new ObjectMapper();
                JsonNode valueType = mapper.readValue(new StringReader(type), JsonNode.class);
                if (valueType != null) {
                    JsonNode value = valueType.findValue("type");
                    if (value != null) {
                        isOfType = types.contains(value.asText());
                    }
                }
            }
        } catch (Exception e) {
            // failure --> no JSON schema
        }

        return isOfType;
    }

    public static JsonType getJsonType(String type) throws JsonSchemaException {
        JsonType jtype = null;
        try {
            // TODO use JSON schema parser
            if (type != null) {

                ObjectMapper mapper = new ObjectMapper();
                JsonNode jsonSchemaNode = mapper.readValue(new StringReader(type), JsonNode.class);
                jtype = getJsonType(jsonSchemaNode);
            }
        } catch (Exception e) {
            // failure --> no JSON schema
        }

        return jtype;
    }

    public static JsonType getJsonType(JsonNode jsonSchemaNode) throws JsonSchemaException {
        JsonType jtype = null;

        if (jsonSchemaNode != null) {
            JsonNode typeNode = jsonSchemaNode.findValue("type");
            if (typeNode != null) {
                switch (typeNode.asText()) {
                case "boolean":
                    jtype = new JsonBoolean();
                    break;
                case "integer":
                case "number":
                    boolean exclusiveMinimum = false;
                    JsonNode exclusiveMinimumNode = jsonSchemaNode.findValue("exclusiveMinimum");
                    if (exclusiveMinimumNode != null
                            && exclusiveMinimumNode.getNodeType() == JsonNodeType.BOOLEAN) {
                        exclusiveMinimum = exclusiveMinimumNode.asBoolean();
                    }
                    boolean exclusiveMaximum = false;
                    JsonNode exclusiveMaximumNode = jsonSchemaNode.findValue("exclusiveMaximum");
                    if (exclusiveMaximumNode != null
                            && exclusiveMaximumNode.getNodeType() == JsonNodeType.BOOLEAN) {
                        exclusiveMaximum = exclusiveMaximumNode.asBoolean();
                    }

                    if ("integer".equals(typeNode.asText())) {
                        jtype = new JsonInteger();
                        JsonNode minimumNode = jsonSchemaNode.findValue("minimum");
                        if (minimumNode != null && minimumNode.getNodeType() == JsonNodeType.NUMBER) {
                            ((JsonInteger) jtype).setMinimum(minimumNode.asLong());
                        }
                        JsonNode maximumNode = jsonSchemaNode.findValue("maximum");
                        if (maximumNode != null && maximumNode.getNodeType() == JsonNodeType.NUMBER) {
                            ((JsonInteger) jtype).setMaximum(maximumNode.asLong());
                        }
                    } else {
                        assert ("number".equals(typeNode.asText()));

                        jtype = new JsonNumber();
                        JsonNode minimumNode = jsonSchemaNode.findValue("minimum");
                        if (minimumNode != null && minimumNode.getNodeType() == JsonNodeType.NUMBER) {
                            ((JsonNumber) jtype).setMinimum(minimumNode.asDouble());
                        }
                        JsonNode maximumNode = jsonSchemaNode.findValue("maximum");
                        if (maximumNode != null && maximumNode.getNodeType() == JsonNodeType.NUMBER) {
                            ((JsonNumber) jtype).setMaximum(maximumNode.asDouble());
                        }
                    }

                    ((AbstractJsonNumeric) jtype).setExclusiveMinimum(exclusiveMinimum);
                    ((AbstractJsonNumeric) jtype).setExclusiveMaximum(exclusiveMaximum);

                    break;
                case "null":
                    jtype = new JsonNull();
                    break;
                case "string":
                    jtype = new JsonString();
                    break;
                case "array":
                    JsonNode itemsNode = jsonSchemaNode.findValue("items");
                    if (itemsNode != null && JsonNodeType.OBJECT == itemsNode.getNodeType()) {
                        jtype = new JsonArray(getJsonType(itemsNode));
                    } else {
                        throw new JsonSchemaException("items not object");
                    }

                    break;
                case "object":
                    JsonNode propertiesNode = jsonSchemaNode.findValue("properties");
                    if (propertiesNode != null && JsonNodeType.OBJECT == propertiesNode.getNodeType()) {
                        Iterator<Entry<String, JsonNode>> iter = propertiesNode.fields();
                        Map<String, JsonType> properties = new HashMap<String, JsonType>();
                        while (iter.hasNext()) {
                            Entry<String, JsonNode> e = iter.next();
                            JsonNode nodeProp = e.getValue();
                            properties.put(e.getKey(), getJsonType(nodeProp));
                        }
                        jtype = new JsonObject(properties);
                    } else {
                        throw new JsonSchemaException("Properties not object");
                    }
                    // required
                    JsonNode requiredNode = jsonSchemaNode.findValue("required");
                    if (requiredNode != null && JsonNodeType.ARRAY == requiredNode.getNodeType()) {
                        ArrayNode an = (ArrayNode) requiredNode;
                        Iterator<JsonNode> iterReq = an.elements();
                        while (iterReq.hasNext()) {
                            JsonNode nreq = iterReq.next();
                            if (JsonNodeType.STRING == nreq.getNodeType()) {
                                ((JsonObject) jtype).addRequired(nreq.asText());
                            } else {
                                throw new JsonSchemaException("Unexpected required node: " + nreq);
                            }
                        }
                    }
                    break;
                }
            }
        }

        return jtype;
    }

}