All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.relayr.java.model.models.schema.ValueSchema Maven / Gradle / Ivy

package io.relayr.java.model.models.schema;

import com.google.gson.annotations.SerializedName;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import io.relayr.java.model.models.transport.DeviceReading;

/**
 * Implements JSON Schema as defined
 * in @see documentation
 */
public class ValueSchema implements Serializable, SchemaValidator {

    /** Validation keywords for numeric instances (number and integer) */
    protected Number minimum;
    //If "exclusiveMinimum" is present, "minimum" MUST also be present.
    //if "exclusiveMinimum" is not present, or has boolean value false, then the instance is valid if it is greater than, or equal to, the value of "minimum";
    //if "exclusiveMinimum" is present and has boolean value true, the instance is valid if it is strictly greater than the value of "minimum".
    protected Boolean exclusiveMinimum;

    protected Number maximum;
    //If "exclusiveMaximum" is present, "maximum" MUST also be present.
    //if "exclusiveMaximum" is not present, or has boolean value false, then the instance is valid if it is lower than, or equal to, the value of "maximum";
    //if "exclusiveMaximum" has boolean value true, the instance is valid if it is strictly lower than the value of "maximum".
    protected Boolean exclusiveMaximum;

    //This number MUST be strictly greater than 0.
    protected Number multipleOf;

    /** Validation keywords for strings */
    //This integer MUST be greater than, or equal to, 0.
    protected Integer maxLength;
    //This integer MUST be greater than, or equal to, 0.
    protected Integer minLength;
    //This string SHOULD be a valid regular expression, according to the ECMA 262 regular expression dialect.
    protected String pattern;

    /** Validation keywords for arrays */
    //The value of "additionalItems" MUST be either a boolean or an object. If it is an object, this object MUST be a valid JSON Schema.
    protected Object additionalItems;

    //The value of "items" MUST be either an object or an array. If it is an object, this object MUST be a valid JSON Schema.
    //If it is an array, items of this array MUST be objects, and each of these objects MUST be a valid JSON Schema.
    protected Object items;

    //This integer MUST be greater than, or equal to, 0.
    protected Integer maxItems;
    //This integer MUST be greater than, or equal to, 0.
    protected Integer minItems;
    protected boolean uniqueItems;

    /** Validation keywords for objects */
    //This integer MUST be greater than, or equal to, 0.
    protected int maxProperties;
    //This integer MUST be greater than, or equal to, 0.
    protected int minProperties;
    //Elements of this array MUST be strings, and MUST be unique.
    protected List required;

    //MUST be a boolean or an object. If it is an object, it MUST also be a valid JSON Schema.
    protected Object additionalProperties;
    //MUST be an object. Each value of this object MUST be an object, and each object MUST be a valid JSON Schema.
    protected Object properties;
    //MUST be an object. Each property name of this object SHOULD be a valid regular expression,
    //according to the ECMA 262 regular expression dialect. Each property value of this object MUST be an object,
    // and each object MUST be a valid JSON Schema.
    protected Object patternProperties;

    //MUST be an object. Each value of this object MUST be either an object or an array.
    protected Object dependencies;

    @SerializedName("default") protected Object defaultValue;

    /** Validation keywords for any instance type */
    protected List allOf;
    protected List anyOf;
    protected List oneOf;
    protected Object not;
    protected Object definitions;

    //MUST be an array. This array MUST have at least one element. Elements in the array MUST be unique.
    //Elements in the array MAY be of any type, including null.
    @SerializedName("enum") protected List enums;

    //String values MUST be one of the seven primitive types defined by the core specification.
    private String type;
    protected SchemaType schemaType;
    protected String title;
    protected String description;
    protected String unit;

    public ValueSchema(ValueSchema schema) {
        title = schema.title;
        description = schema.description;
        unit = schema.unit;
        schemaType = schema.schemaType;

        not = schema.not;
        allOf = schema.allOf;
        anyOf = schema.anyOf;
        oneOf = schema.oneOf;
        enums = schema.enums;
        definitions = schema.definitions;
        defaultValue = schema.defaultValue;
    }

    /**
     * Returns one of the {@link SchemaType} as defined
     * in @see documentation
     */
    public SchemaType getSchemaType() {
        if (schemaType == null) schemaType = SchemaType.getByType(type);
        return schemaType;
    }

    /** @return true if schema type is {@link SchemaType#NUMBER} false otherwise */
    public boolean isNumberSchema() {
        if (schemaType == null) schemaType = SchemaType.getByType(type);
        return schemaType == SchemaType.NUMBER;
    }

    /** @return true if schema type is {@link SchemaType#INTEGER} false otherwise */
    public boolean isIntegerSchema() {
        if (schemaType == null) schemaType = SchemaType.getByType(type);
        return schemaType == SchemaType.INTEGER;
    }

    /** @return true if schema type is {@link SchemaType#STRING} false otherwise */
    public boolean isStringSchema() {
        if (schemaType == null) schemaType = SchemaType.getByType(type);
        return schemaType == SchemaType.STRING;
    }

    /** @return true if schema type is {@link SchemaType#ARRAY} false otherwise */
    public boolean isArraySchema() {
        if (schemaType == null) schemaType = SchemaType.getByType(type);
        return schemaType == SchemaType.ARRAY;
    }

    /** @return true if schema type is {@link SchemaType#BOOLEAN} false otherwise */
    public boolean isBooleanSchema() {
        if (schemaType == null) schemaType = SchemaType.getByType(type);
        return schemaType == SchemaType.BOOLEAN;
    }

    /** @return true if schema type is {@link SchemaType#OBJECT} false otherwise */
    public boolean isObjectSchema() {
        if (schemaType == null) schemaType = SchemaType.getByType(type);
        return schemaType == SchemaType.OBJECT;
    }

    /**
     * Returns unit of measurement as a String value.
     * Use unit to describe {@link DeviceReading} accurately.
     */
    public String getUnit() {
        return unit;
    }

    public String getTitle() {
        return title;
    }

    public String getDescription() {
        return description;
    }

    public List getAllOf() {
        return allOf;
    }

    public List getAnyOf() {
        return anyOf;
    }

    public List getOneOf() {
        return oneOf;
    }

    public Object getNot() {
        return not;
    }

    public Object getDefaultValue() {
        return defaultValue;
    }

    /** @return possible values for this field. If these are not defined String can be anything. */
    public List getEnums() {
        if (enums == null) return new ArrayList<>();
        return enums;
    }

    public NumberSchema asNumber() {
        return new NumberSchema(this);
    }

    public IntegerSchema asInteger() {
        return new IntegerSchema(this);
    }

    public StringSchema asString() {
        return new StringSchema(this);
    }

    public ArraySchema asArray() {
        return new ArraySchema(this);
    }

    public BooleanSchema asBoolean() {
        return new BooleanSchema(this);
    }

    public ObjectSchema asObject() {
        return new ObjectSchema(this);
    }

    @Override public boolean validate(Object value) {
        switch (getSchemaType()) {
            case BOOLEAN:
                return asBoolean().validate(value);
            case INTEGER:
                return asInteger().validate(value);
            case NUMBER:
                return asNumber().validate(value);
            case ARRAY:
                return asArray().validate(value);
            case OBJECT:
                return asObject().validate(value);
            case STRING:
                return asString().validate(value);
            default:
                return validateNull(value);
        }
    }

    protected boolean validateNull(Object value) {
        return schemaType == SchemaType.NULL && value == null || value != null;
    }
}