Java tutorial
package com.fasterxml.jackson.module.jsonSchema; import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import com.fasterxml.jackson.databind.BeanProperty; import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes; import com.fasterxml.jackson.module.jsonSchema.types.*; /** * The type wraps the json schema specification at : * <a href="http://tools.ietf.org/id/draft-zyp-json-schema-03.txt"> Json JsonSchema * Draft </a> <blockquote> JSON (JavaScript Object Notation) JsonSchema defines the * media type "application/schema+json", a JSON based format for defining the * structure of JSON data. JSON JsonSchema provides a contract for what JSON data is * required for a given application and how to interact with it. JSON JsonSchema is * intended to define validation, documentation, hyperlink navigation, and * interaction control of JSON data. </blockquote> * * <blockquote> JSON (JavaScript Object Notation) JsonSchema is a JSON media type * for defining the structure of JSON data. JSON JsonSchema provides a contract for * what JSON data is required for a given application and how to interact with * it. JSON JsonSchema is intended to define validation, documentation, hyperlink * navigation, and interaction control of JSON data. </blockquote> * * An example JSON JsonSchema provided by the JsonSchema draft: * * <pre> * { * "name":"Product", * "properties":{ * "id":{ * "type":"number", * "description":"Product identifier", * "required":true * }, * "name":{ * "description":"Name of the product", * "type":"string", * "required":true * }, * "price":{ * "required":true, * "type": "number", * "minimum":0, * "required":true * }, * "tags":{ * "type":"array", * "items":{ * "type":"string" * } * } * }, * "links":[ * { * "rel":"full", * "href":"{id}" * }, * { * "rel":"comments", * "href":"comments/?id={id}" * } * ] * } * </pre> * * @author jphelan */ @JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonTypeInfo(use = Id.CUSTOM, include = As.PROPERTY, property = "type") @JsonTypeIdResolver(JsonSchemaIdResolver.class) public abstract class JsonSchema { /** * This attribute defines a URI of a schema that contains the full * representation of this schema. When a validator encounters this * attribute, it SHOULD replace the current schema with the schema * referenced by the value's URI (if known and available) and re- validate * the instance. This URI MAY be relative or absolute, and relative URIs * SHOULD be resolved against the URI of the current schema. */ @JsonProperty private String $ref; /** * This attribute defines a URI of a JSON JsonSchema that is the schema of the * current schema. When this attribute is defined, a validator SHOULD use * the schema referenced by the value's URI (if known and available) when * resolving Hyper JsonSchema (Section 6) links (Section 6.1). * * A validator MAY use this attribute's value to determine which version of * JSON JsonSchema the current schema is written in, and provide the appropriate * validation features and behavior. Therefore, it is RECOMMENDED that all * schema authors include this attribute in their schemas to prevent * conflicts with future JSON JsonSchema specification changes. */ @JsonProperty private String $schema; /** * This attribute takes the same values as the "type" attribute, however if * the instance matches the type or if this value is an array and the * instance matches any type or schema in the array, then this instance is * not valid. */ @JsonProperty private JsonSchema[] disallow; /** * The value of this property MUST be another schema which will provide a * base schema which the current schema will inherit from. The inheritance * rules are such that any instance that is valid according to the current * schema MUST be valid according to the referenced schema. This MAY also be * an array, in which case, the instance MUST be valid for all the schemas * in the array. A schema that extends another schema MAY define additional * attributes, constrain existing attributes, or add other constraints. * * Conceptually, the behavior of extends can be seen as validating an * instance against all constraints in the extending schema as well as the * extended schema(s). More optimized implementations that merge schemas are * possible, but are not required. An example of using "extends": * * { "description":"An adult", "properties":{"age":{"minimum": 21}}, * "extends":"person" } { "description":"Extended schema", * "properties":{"deprecated":{"type": "boolean"}}, * "extends":"http://json-schema.org/draft-03/schema" } */ private JsonSchema[] extendsextends; /** * This attribute defines the current URI of this schema (this attribute is * effectively a "self" link). This URI MAY be relative or absolute. If the * URI is relative it is resolved against the current URI of the parent * schema it is contained in. If this schema is not contained in any parent * schema, the current URI of the parent schema is held to be the URI under * which this schema was addressed. If id is missing, the current URI of a * schema is defined to be that of the parent schema. The current URI of the * schema is also used to construct relative references such as for $ref. */ @JsonProperty private String id; /** * This attribute indicates if the instance must have a value, and not be * undefined. This is false by default, making the instance optional. */ @JsonProperty private Boolean required = null; /** * This attribute indicates if the instance is not modifiable. * This is false by defaul, making the instance modifiable. */ @JsonProperty private Boolean readonly = null; /** * This attribute is a string that provides a full description of the of * purpose the instance property. */ private String description; /** * Attempt to return this JsonSchema as an {@link AnySchema} * @return this as an AnySchema if possible, or null otherwise */ public AnySchema asAnySchema() { return null; } /** * Attempt to return this JsonSchema as an {@link ArraySchema} * @return this as an ArraySchema if possible, or null otherwise */ public ArraySchema asArraySchema() { return null; } /** * Attempt to return this JsonSchema as a {@link BooleanSchema} * @return this as a BooleanSchema if possible, or null otherwise */ public BooleanSchema asBooleanSchema() { return null; } /** * Attempt to return this JsonSchema as a {@link ContainerTypeSchema} * @return this as an ContainerTypeSchema if possible, or null otherwise */ public ContainerTypeSchema asContainerSchema() { return null; } /** * Attempt to return this JsonSchema as an {@link IntegerSchema} * @return this as an IntegerSchema if possible, or null otherwise */ public IntegerSchema asIntegerSchema() { return null; } /** * Attempt to return this JsonSchema as a {@link NullSchema} * @return this as a NullSchema if possible, or null otherwise */ public NullSchema asNullSchema() { return null; } /** * Attempt to return this JsonSchema as a {@link NumberSchema} * @return this as a NumberSchema if possible, or null otherwise */ public NumberSchema asNumberSchema() { return null; } /** * Attempt to return this JsonSchema as an {@link ObjectSchema} * @return this as an ObjectSchema if possible, or null otherwise */ public ObjectSchema asObjectSchema() { return null; } /** * Attempt to return this JsonSchema as a {@link SimpleTypeSchema} * @return this as a SimpleTypeSchema if possible, or null otherwise */ public SimpleTypeSchema asSimpleTypeSchema() { return null; } /** * Attempt to return this JsonSchema as a {@link StringSchema} * @return this as a StringSchema if possible, or null otherwise */ public StringSchema asStringSchema() { return null; } /** * Attempt to return this JsonSchema as an {@link UnionTypeSchema} * @return this as a UnionTypeSchema if possible, or null otherwise */ public UnionTypeSchema asUnionTypeSchema() { return null; } /** * Attempt to return this JsonSchema as a {@link ValueTypeSchema} * @return this as a ValueTypeSchema if possible, or null otherwise */ public ValueTypeSchema asValueSchemaSchema() { return null; } /** * A utility method allowing to easily chain calls to equals() on members * without taking any risk regarding the ternary operator precedence. * * @return (object1 == null ? object2 == null : object1.equals(object2)) */ protected static boolean equals(Object object1, Object object2) { return (object1 == null ? object2 == null : object1.equals(object2)); } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (obj == this) return true; if (obj == null) return false; if (!(obj instanceof JsonSchema)) return false; JsonSchema that = ((JsonSchema) obj); return equals(getType(), getType()) && equals(getRequired(), that.getRequired()) && equals(getReadonly(), that.getReadonly()) && equals(get$ref(), that.get$ref()) && equals(get$schema(), that.get$schema()) && equals(getDisallow(), that.getDisallow()) && equals(getExtends(), that.getExtends()); } public String get$ref() { return $ref; } public String get$schema() { return $schema; } public JsonSchema[] getDisallow() { return disallow; } public JsonSchema[] getExtends() { return extendsextends; } public String getId() { return id; } public Boolean getRequired() { return required; } public Boolean getReadonly() { return readonly; } public String getDescription() { return description; } @JsonIgnore public abstract JsonFormatTypes getType(); /** * determine if this JsonSchema is an {@link AnySchema}. * * @return true if this JsonSchema is an AnySchema, false otherwise */ @JsonIgnore public boolean isAnySchema() { return false; } /** * determine if this JsonSchema is an {@link ArraySchema}. * * @return true if this JsonSchema is an ArraySchema, false otherwise */ @JsonIgnore public boolean isArraySchema() { return false; } /** * determine if this JsonSchema is an {@link BooleanSchema}. * * @return true if this JsonSchema is an BooleanSchema, false otherwise */ @JsonIgnore public boolean isBooleanSchema() { return false; } /** * determine if this JsonSchema is an {@link ContainerTypeSchema}. * * @return true if this JsonSchema is an ContainerTypeSchema, false otherwise */ @JsonIgnore public boolean isContainerTypeSchema() { return false; } /** * determine if this JsonSchema is an {@link IntegerSchema}. * * @return true if this JsonSchema is an IntegerSchema, false otherwise */ @JsonIgnore public boolean isIntegerSchema() { return false; } /** * determine if this JsonSchema is an {@link NullSchema}. * * @return true if this JsonSchema is an NullSchema, false otherwise */ @JsonIgnore public boolean isNullSchema() { return false; } /** * determine if this JsonSchema is an {@link NumberSchema}. * * @return true if this JsonSchema is an NumberSchema, false otherwise */ @JsonIgnore public boolean isNumberSchema() { return false; } /** * determine if this JsonSchema is an {@link ObjectSchema}. * * @return true if this JsonSchema is an ObjectSchema, false otherwise */ @JsonIgnore public boolean isObjectSchema() { return false; } /** * determine if this JsonSchema is an {@link SimpleTypeSchema}. * * @return true if this JsonSchema is an SimpleTypeSchema, false otherwise */ @JsonIgnore public boolean isSimpleTypeSchema() { return false; } /** * determine if this JsonSchema is an {@link StringSchema}. * * @return true if this JsonSchema is an StringSchema, false otherwise */ @JsonIgnore public boolean isStringSchema() { return false; } /** * determine if this JsonSchema is an {@link UnionTypeSchema}. * * @return true if this JsonSchema is an UnionTypeSchema, false otherwise */ @JsonIgnore public boolean isUnionTypeSchema() { return false; } /** * determine if this JsonSchema is an {@link ValueTypeSchema}. * * @return true if this JsonSchema is an ValueTypeSchema, false otherwise */ @JsonIgnore public boolean isValueTypeSchema() { return false; } public void set$ref(String $ref) { this.$ref = $ref; } public void set$schema(String $schema) { this.$schema = $schema; } public void setDisallow(JsonSchema[] disallow) { this.disallow = disallow; } public void setExtends(JsonSchema[] extendsextends) { this.extendsextends = extendsextends; } public void setId(String id) { this.id = id; } public void setRequired(Boolean required) { this.required = required; } public void setReadonly(Boolean readonly) { this.readonly = readonly; } public void setDescription(String description) { this.description = description; } /** * Override this to add information specific to the property of bean * For example, bean validation annotations could be used to specify * value constraints in the schema * @param beanProperty */ public void enrichWithBeanProperty(BeanProperty beanProperty) { setDescription(beanProperty.getMetadata().getDescription()); } /** * Create a schema which verifies only that an object is of the given format. * @param format the format to expect * @return the schema verifying the given format */ public static JsonSchema minimalForFormat(JsonFormatTypes format) { switch (format) { case ARRAY: return new ArraySchema(); case OBJECT: return new ObjectSchema(); case BOOLEAN: return new BooleanSchema(); case INTEGER: return new IntegerSchema(); case NUMBER: return new NumberSchema(); case STRING: return new StringSchema(); case NULL: return new NullSchema(); default: return new AnySchema(); } } }