enums);
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/JsonSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/JsonSchema.java
deleted file mode 100644
index e79a68a818..0000000000
--- a/src/main/java/com/fasterxml/jackson/databind/jsonschema/JsonSchema.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.fasterxml.jackson.databind.jsonschema;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonValue;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-/**
- * Container for a logical JSON Schema instance.
- * Internally schema data is stored as a JSON Tree
- * (instance of {@link JsonNode} is the root
- * of schema document)
- *
- * @author Ryan Heaton
- * @see JSON Schema
- */
-public class JsonSchema
-{
- private final ObjectNode schema;
-
- /**
- * Main constructor for schema instances.
- *
- * This is the creator constructor used by Jackson itself when
- * deserializing instances. It is so-called delegating creator,
- * meaning that its argument will be bound by Jackson before
- * constructor gets called.
- */
- @JsonCreator
- public JsonSchema(ObjectNode schema)
- {
- this.schema = schema;
- }
-
- /**
- * Method for accessing root JSON object of the contained schema.
- *
- * Note: this method is specified with {@link JsonValue} annotation
- * to represent serialization to use; same as if explicitly
- * serializing returned object.
- *
- * @return Root node of the schema tree
- */
- @JsonValue
- public ObjectNode getSchemaNode()
- {
- return schema;
- }
-
- @Override
- public String toString()
- {
- return this.schema.toString();
- }
-
- @Override
- public boolean equals(Object o)
- {
- if (o == this) return true;
- if (o == null) return false;
- if (!(o instanceof JsonSchema)) return false;
-
- JsonSchema other = (JsonSchema) o;
- if (schema == null) {
- return other.schema == null;
- }
- return schema.equals(other.schema);
- }
-
- /**
- * Get the default schema node.
- *
- * @return The default schema node.
- */
- public static JsonNode getDefaultSchemaNode()
- {
- ObjectNode objectNode = JsonNodeFactory.instance.objectNode();
- objectNode.put("type", "any");
- // "required" is false by default, no need to include
- //objectNode.put("required", false);
- return objectNode;
- }
-
-}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/JsonSerializableSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/JsonSerializableSchema.java
deleted file mode 100644
index a2935693b5..0000000000
--- a/src/main/java/com/fasterxml/jackson/databind/jsonschema/JsonSerializableSchema.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.fasterxml.jackson.databind.jsonschema;
-
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Retention;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Target;
-
-import com.fasterxml.jackson.annotation.JacksonAnnotation;
-
-/**
- * Annotation that can be used to define JSON Schema definition for
- * the annotated class.
- *
- * Note that annotation is often not needed: for example, regular
- * Jackson beans that Jackson can introspect can be used without
- * annotations, to produce JSON schema definition.
- *
- * @author Ryan Heaton
- * @author Tatu Saloranta
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@JacksonAnnotation
-public @interface JsonSerializableSchema
-{
- /**
- * Marker value used to indicate that property has "no value";
- * needed because annotations can not have null as default
- * value.
- */
- public final static String NO_VALUE = "##irrelevant";
-
- /**
- * Property that can be used to indicate id of the type when
- * generating JSON Schema; empty String indicates that no id
- * is defined.
- */
- public String id() default "";
-
- /**
- * The schema type for this JsonSerializable instance.
- * Possible values: "string", "number", "boolean", "object", "array", "null", "any"
- *
- * @return The schema type for this JsonSerializable instance.
- */
- public String schemaType() default "any";
-
- /**
- * If the schema type is "object", JSON definition of properties of the object as
- * a String.
- *
- * @return The node representing the schema properties, or "##irrelevant" if irrelevant.
- */
- public String schemaObjectPropertiesDefinition() default NO_VALUE;
-
- /**
- * If the schema type if "array", JSON definition of the schema for item types contained.
- *
- * @return The schema for the items in the array, or "##irrelevant" if irrelevant.
- */
- public String schemaItemDefinition() default NO_VALUE;
-}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/SchemaAware.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/SchemaAware.java
deleted file mode 100644
index f3505cd37d..0000000000
--- a/src/main/java/com/fasterxml/jackson/databind/jsonschema/SchemaAware.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.fasterxml.jackson.databind.jsonschema;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.SerializerProvider;
-
-import java.lang.reflect.Type;
-
-/**
- * Marker interface for schema-aware serializers.
- */
-public interface SchemaAware
-{
- /**
- * Get the representation of the schema to which this serializer will conform.
- *
- * @param provider The serializer provider.
- * @param typeHint A hint about the type.
- * @return Json-schema for this serializer.
- */
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException;
-
- /**
- * Get the representation of the schema to which this serializer will conform.
- *
- * @param provider The serializer provider.
- * @param isOptional Is the type optional
- * @param typeHint A hint about the type.
- * @return Json-schema for this serializer.
- */
- public JsonNode getSchema(SerializerProvider provider, Type typeHint, boolean isOptional)
- throws JsonMappingException;
-}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/AnySchemaFactory.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/AnySchemaFactory.java
new file mode 100644
index 0000000000..36143fa453
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/AnySchemaFactory.java
@@ -0,0 +1,34 @@
+package com.fasterxml.jackson.databind.jsonschema.factories;
+
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonAnyFormatVisitor;
+import com.fasterxml.jackson.databind.jsonschema.types.AnySchema;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonSchema;
+
+public class AnySchemaFactory extends SchemaFactory implements
+ JsonAnyFormatVisitor {
+
+ protected SchemaFactory parent;
+ protected AnySchema anySchema;
+
+ public AnySchemaFactory(SchemaFactory parent) {
+ this.parent = parent;
+ setProvider(parent.getProvider());
+ anySchema = new AnySchema();
+ }
+
+ /**
+ * @param provider
+ */
+ public AnySchemaFactory(SerializerProvider provider) {
+ parent = null;
+ setProvider(provider);
+ anySchema = new AnySchema();
+ }
+
+ public JsonSchema getSchema() {
+ return anySchema;
+ }
+
+
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/ArraySchemaFactory.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/ArraySchemaFactory.java
new file mode 100644
index 0000000000..8303d1e144
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/ArraySchemaFactory.java
@@ -0,0 +1,68 @@
+package com.fasterxml.jackson.databind.jsonschema.factories;
+
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorAware;
+import com.fasterxml.jackson.databind.jsonschema.types.ArraySchema;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonSchema;
+import com.fasterxml.jackson.databind.jsonschema.types.SchemaType;
+
+public class ArraySchemaFactory extends SchemaFactory
+ implements JsonArrayFormatVisitor {
+
+ protected SchemaFactory parent;
+ protected ArraySchema arraySchema;
+ protected BeanProperty _property;
+
+ public ArraySchemaFactory(SchemaFactory parent, BeanProperty property) {
+ this.parent = parent;
+ setProvider(parent.getProvider());
+ arraySchema = new ArraySchema();
+ }
+
+ public ArraySchemaFactory(SchemaFactory schemaFactory) {
+ this(schemaFactory, null);
+ }
+
+ /**
+ * @param provider
+ */
+ public ArraySchemaFactory(SerializerProvider provider) {
+ parent = null;
+ setProvider(provider);
+ arraySchema = new ArraySchema();
+ }
+
+ public void itemsFormat(JavaType contentType) {
+ // An array of object matches any values, thus we leave the schema empty.
+ if (contentType.getRawClass() != Object.class) {
+
+ JsonSerializer ser;
+ try {
+ ser = getProvider().findValueSerializer(contentType, _property);
+ if (ser instanceof JsonFormatVisitorAware) {
+ SchemaFactoryProvider visitor = new SchemaFactoryProvider();
+ visitor.setProvider(provider);
+ ((JsonFormatVisitorAware) ser).acceptJsonFormatVisitor(visitor, contentType);
+ arraySchema.setItemsSchema(visitor.finalSchema());
+ }
+ } catch (JsonMappingException e) {
+ //TODO: log error
+ }
+ }
+ }
+
+ public void itemsFormat(SchemaType format) {
+ arraySchema.setItemsSchema(JsonSchema.minimalForFormat(format));
+ }
+
+ public JsonSchema getSchema() {
+ return arraySchema;
+ }
+
+
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/BooleanSchemaFactory.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/BooleanSchemaFactory.java
new file mode 100644
index 0000000000..b084a3699d
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/BooleanSchemaFactory.java
@@ -0,0 +1,30 @@
+package com.fasterxml.jackson.databind.jsonschema.factories;
+
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonBooleanFormatVisitor;
+import com.fasterxml.jackson.databind.jsonschema.types.BooleanSchema;
+import com.fasterxml.jackson.databind.jsonschema.types.ValueTypeSchema;
+
+public class BooleanSchemaFactory extends ValueTypeSchemaFactory implements
+ JsonBooleanFormatVisitor {
+
+ protected BooleanSchema booleanSchema;
+
+ public BooleanSchemaFactory(SchemaFactory parent) {
+ super(parent);
+ booleanSchema = new BooleanSchema();
+ }
+
+ /**
+ * @param provider
+ */
+ public BooleanSchemaFactory(SerializerProvider provider) {
+ super(provider);
+ booleanSchema = new BooleanSchema();
+ }
+
+ public ValueTypeSchema getValueSchema() {
+ return booleanSchema;
+ }
+
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/IntegerSchemaFactory.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/IntegerSchemaFactory.java
new file mode 100644
index 0000000000..93d308b3d1
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/IntegerSchemaFactory.java
@@ -0,0 +1,30 @@
+package com.fasterxml.jackson.databind.jsonschema.factories;
+
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonIntegerFormatVisitor;
+import com.fasterxml.jackson.databind.jsonschema.types.IntegerSchema;
+import com.fasterxml.jackson.databind.jsonschema.types.ValueTypeSchema;
+
+public class IntegerSchemaFactory extends ValueTypeSchemaFactory implements
+ JsonIntegerFormatVisitor {
+
+ protected IntegerSchema integerSchema;
+
+ public IntegerSchemaFactory(SchemaFactory parent) {
+ super(parent);
+ integerSchema = new IntegerSchema();
+ }
+
+ /**
+ * @param provider
+ */
+ public IntegerSchemaFactory(SerializerProvider provider) {
+ super(provider);
+ integerSchema = new IntegerSchema();
+ }
+
+ public ValueTypeSchema getValueSchema() {
+ return integerSchema;
+ }
+
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/NullSchemaFactory.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/NullSchemaFactory.java
new file mode 100644
index 0000000000..8963fd11d4
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/NullSchemaFactory.java
@@ -0,0 +1,33 @@
+package com.fasterxml.jackson.databind.jsonschema.factories;
+
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonNullFormatVisitor;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonSchema;
+import com.fasterxml.jackson.databind.jsonschema.types.NullSchema;
+
+public class NullSchemaFactory extends SchemaFactory implements
+ JsonNullFormatVisitor {
+
+ protected SchemaFactory parent;
+ protected NullSchema nullSchema;
+
+ public NullSchemaFactory(SchemaFactory parent) {
+ this.parent = parent;
+ setProvider(parent.getProvider());
+ nullSchema = new NullSchema();
+ }
+
+ /**
+ * @param provider
+ */
+ public NullSchemaFactory(SerializerProvider provider) {
+ parent = null;
+ setProvider(provider);
+ nullSchema = new NullSchema();
+ }
+
+ public JsonSchema getSchema() {
+ return nullSchema;
+ }
+
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/NumberSchemaFactory.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/NumberSchemaFactory.java
new file mode 100644
index 0000000000..a0cabeb5eb
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/NumberSchemaFactory.java
@@ -0,0 +1,33 @@
+package com.fasterxml.jackson.databind.jsonschema.factories;
+
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonNumberFormatVisitor;
+import com.fasterxml.jackson.databind.jsonschema.types.NumberSchema;
+import com.fasterxml.jackson.databind.jsonschema.types.ValueTypeSchema;
+
+public class NumberSchemaFactory extends ValueTypeSchemaFactory implements
+ JsonNumberFormatVisitor {
+
+ protected NumberSchema numberSchema;
+
+ public NumberSchemaFactory(SchemaFactory parent) {
+ super(parent);
+ this.parent = parent;
+ numberSchema = new NumberSchema();
+ }
+
+ /**
+ * @param provider
+ */
+ public NumberSchemaFactory(SerializerProvider provider) {
+ super(provider);
+ numberSchema = new NumberSchema();
+ }
+
+ @Override
+ protected ValueTypeSchema getValueSchema() {
+ return numberSchema;
+ }
+
+
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/ObjectSchemaFactory.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/ObjectSchemaFactory.java
new file mode 100644
index 0000000000..0ada476b38
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/ObjectSchemaFactory.java
@@ -0,0 +1,96 @@
+package com.fasterxml.jackson.databind.jsonschema.factories;
+
+
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorAware;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonSchema;
+import com.fasterxml.jackson.databind.jsonschema.types.ObjectSchema;
+import com.fasterxml.jackson.databind.jsonschema.types.SchemaType;
+import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
+
+public class ObjectSchemaFactory extends SchemaFactory
+ implements JsonObjectFormatVisitor {
+
+ protected SchemaFactory parent;
+ protected ObjectSchema objectSchema;
+
+ public ObjectSchemaFactory(SchemaFactory parent) {
+ this.parent = parent;
+ setProvider(parent.getProvider());
+ objectSchema = new ObjectSchema();
+ }
+
+ /**
+ * @param provider
+ */
+ public ObjectSchemaFactory(SerializerProvider provider) {
+ parent = null;
+ setProvider(provider);
+ objectSchema = new ObjectSchema();
+ }
+
+ public JsonSchema getSchema() {
+ return objectSchema;
+ }
+
+ private JsonSerializer getSer(BeanPropertyWriter writer) {
+ JsonSerializer ser = writer.getSerializer();
+ if (ser == null) {
+ Class> serType = writer.getPropertyType();
+ try {
+ return getProvider().findValueSerializer(serType, writer);
+ } catch (JsonMappingException e) {
+ // TODO: log error
+ }
+ }
+ return ser;
+ }
+
+ protected JsonSchema propertySchema(BeanPropertyWriter writer) {
+ SchemaFactoryProvider visitor = new SchemaFactoryProvider();
+ visitor.setProvider(provider);
+ JsonSerializer ser = getSer(writer);
+ if (ser != null && ser instanceof JsonFormatVisitorAware) {
+ ((JsonFormatVisitorAware)ser).acceptJsonFormatVisitor(visitor, writer.getType());
+ } else {
+ visitor.expectAnyFormat(writer.getType());
+ }
+ return visitor.finalSchema();
+ }
+
+ protected JsonSchema propertySchema(JsonFormatVisitorAware handler, JavaType propertyTypeHint) {
+ SchemaFactoryProvider visitor = new SchemaFactoryProvider();
+ visitor.setProvider(provider);
+ handler.acceptJsonFormatVisitor(visitor, propertyTypeHint);
+ return visitor.finalSchema();
+ }
+
+ public void property(BeanPropertyWriter writer) {
+ objectSchema.putProperty(writer.getName(), propertySchema(writer));
+ }
+
+ public void optionalProperty(BeanPropertyWriter writer) {
+ objectSchema.putOptionalProperty(writer.getName(), propertySchema(writer));
+ }
+
+ public void property(String name, JsonFormatVisitorAware handler, JavaType propertyTypeHint) {
+ objectSchema.putProperty(name, propertySchema(handler, propertyTypeHint));
+ }
+
+ public void optionalProperty(String name, JsonFormatVisitorAware handler, JavaType propertyTypeHint) {
+ objectSchema.putOptionalProperty(name, propertySchema(handler, propertyTypeHint));
+ }
+
+ public void property(String name) {
+ objectSchema.putProperty(name, JsonSchema.minimalForFormat(SchemaType.ANY));
+ }
+
+ public void optionalProperty(String name) {
+ objectSchema.putOptionalProperty(name, JsonSchema.minimalForFormat(SchemaType.ANY));
+ }
+
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/SchemaFactory.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/SchemaFactory.java
new file mode 100644
index 0000000000..e7b6e3af62
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/SchemaFactory.java
@@ -0,0 +1,26 @@
+package com.fasterxml.jackson.databind.jsonschema.factories;
+
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonSchema;
+
+public abstract class SchemaFactory {
+
+
+ protected SerializerProvider provider;
+
+
+ /**
+ * {@link SchemaFactory#provider}
+ * @param provider the provider to set
+ */
+ public void setProvider(SerializerProvider provider) {
+ this.provider = provider;
+ }
+
+ public SerializerProvider getProvider() {
+ return provider;
+ }
+
+ public abstract JsonSchema getSchema();
+
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/SchemaFactoryProvider.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/SchemaFactoryProvider.java
new file mode 100644
index 0000000000..d1b5e184e4
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/SchemaFactoryProvider.java
@@ -0,0 +1,89 @@
+package com.fasterxml.jackson.databind.jsonschema.factories;
+
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonAnyFormatVisitor;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonBooleanFormatVisitor;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonIntegerFormatVisitor;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonNullFormatVisitor;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonNumberFormatVisitor;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;
+import com.fasterxml.jackson.databind.jsonschema.factories.*;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonSchema;
+
+/**
+ * @author jphelan
+ *
+ */
+public class SchemaFactoryProvider implements JsonFormatVisitorWrapper{
+
+ protected SerializerProvider provider;
+ private SchemaFactory delegate;
+
+ /**
+ * {@link SchemaFactory#provider}
+ * @param provider the provider to set
+ */
+ public void setProvider(SerializerProvider provider) {
+ this.provider = provider;
+ }
+
+ public SerializerProvider getProvider() {
+ return provider;
+ }
+
+
+ public JsonAnyFormatVisitor expectAnyFormat(JavaType convertedType) {
+ delegate = new AnySchemaFactory(provider);
+ return (JsonAnyFormatVisitor) delegate;
+ }
+
+ public JsonArrayFormatVisitor expectArrayFormat(JavaType convertedType) {
+ delegate = new ArraySchemaFactory(provider);
+ return (JsonArrayFormatVisitor) delegate;
+ }
+
+ public JsonBooleanFormatVisitor expectBooleanFormat(JavaType convertedType) {
+ delegate = new BooleanSchemaFactory(provider);
+ return (JsonBooleanFormatVisitor) delegate;
+ }
+
+ public JsonSchema finalSchema() {
+ assert delegate != null : "SchemaFactory must envoke a delegate method before it can return a JsonSchema.";
+ if (delegate == null) {
+ return null;
+ } else {
+ return delegate.getSchema();
+ }
+
+ }
+
+ public JsonIntegerFormatVisitor expectIntegerFormat(JavaType convertedType) {
+ delegate = new IntegerSchemaFactory(provider);
+ return (JsonIntegerFormatVisitor) delegate;
+ }
+
+ public JsonNullFormatVisitor expectNullFormat(JavaType convertedType) {
+ delegate = new NullSchemaFactory(provider);
+ return (JsonNullFormatVisitor) delegate;
+ }
+
+ public JsonNumberFormatVisitor expectNumberFormat(JavaType convertedType) {
+ delegate = new NumberSchemaFactory(provider);
+ return (JsonNumberFormatVisitor) delegate;
+ }
+
+ public JsonObjectFormatVisitor expectObjectFormat(JavaType convertedType) {
+ delegate = new ObjectSchemaFactory(provider);
+ return (JsonObjectFormatVisitor) delegate;
+ }
+
+ public JsonStringFormatVisitor expectStringFormat(JavaType convertedType) {
+ delegate = new StringSchemaFactory(provider);
+ return (JsonStringFormatVisitor) delegate;
+ }
+
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/StringSchemaFactory.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/StringSchemaFactory.java
new file mode 100644
index 0000000000..c1bca67e60
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/StringSchemaFactory.java
@@ -0,0 +1,30 @@
+package com.fasterxml.jackson.databind.jsonschema.factories;
+
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;
+import com.fasterxml.jackson.databind.jsonschema.types.StringSchema;
+import com.fasterxml.jackson.databind.jsonschema.types.ValueTypeSchema;
+
+public class StringSchemaFactory extends ValueTypeSchemaFactory
+ implements JsonStringFormatVisitor{
+
+ protected StringSchema stringSchema;
+
+ public StringSchemaFactory(SchemaFactory parent) {
+ super(parent);
+ stringSchema = new StringSchema();
+ }
+
+ /**
+ * @param provider
+ */
+ public StringSchemaFactory(SerializerProvider provider) {
+ super(provider);
+ stringSchema = new StringSchema();
+ }
+
+ public ValueTypeSchema getValueSchema() {
+ return stringSchema;
+ }
+
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/ValueTypeSchemaFactory.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/ValueTypeSchemaFactory.java
new file mode 100644
index 0000000000..9a052704d1
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/factories/ValueTypeSchemaFactory.java
@@ -0,0 +1,44 @@
+package com.fasterxml.jackson.databind.jsonschema.factories;
+
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonValueFormatVisitor;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonSchema;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonValueFormat;
+import com.fasterxml.jackson.databind.jsonschema.types.ValueTypeSchema;
+
+public abstract class ValueTypeSchemaFactory extends SchemaFactory implements
+ JsonValueFormatVisitor {
+
+ protected SchemaFactory parent;
+
+ protected ValueTypeSchemaFactory(SchemaFactory parent) {
+ this.parent = parent;
+ setProvider(parent.getProvider());
+ }
+
+ /**
+ * @param provider
+ */
+ public ValueTypeSchemaFactory(SerializerProvider provider) {
+ parent = null;
+ setProvider(provider);
+ }
+
+ public JsonSchema getSchema() {
+ return getValueSchema();
+ }
+ protected abstract ValueTypeSchema getValueSchema();
+
+ public void format(JsonValueFormat format) {
+ getValueSchema().setFormat(format);
+
+ }
+
+ public void enumTypes(Set enums) {
+ getValueSchema().setEnums(enums);
+
+ }
+
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/package-info.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/package-info.java
deleted file mode 100644
index 443dcf48f9..0000000000
--- a/src/main/java/com/fasterxml/jackson/databind/jsonschema/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Classes needed for JSON schema support (currently just ability
- * to generate schemas using serialization part of data mapping)
- */
-package com.fasterxml.jackson.databind.jsonschema;
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/AnySchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/AnySchema.java
new file mode 100644
index 0000000000..7f197a8c4e
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/AnySchema.java
@@ -0,0 +1,73 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * This class represents a {@link JsonSchema} of type any
+ * @author jphelan
+ *
+ */
+public class AnySchema extends SimpleTypeSchema {
+
+ /**
+ * This provides an enumeration of all possible values that are valid
+ for the instance property. This MUST be an array, and each item in
+ the array represents a possible value for the instance value. If
+ this attribute is defined, the instance value MUST be one of the
+ values in the array in order for the schema to be valid. Comparison
+ of enum values uses the same algorithm as defined in "uniqueItems"
+ (Section 5.15).
+ */
+ @JsonProperty
+ private Set enums;
+
+ @JsonIgnore
+ private final SchemaType type = SchemaType.ANY;
+
+ //instance initializer block
+ {
+ enums = new HashSet();
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#asAnySchema()
+ */
+ @Override
+ public AnySchema asAnySchema() { return this; }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof AnySchema) {
+ AnySchema that = ((AnySchema)obj);
+ return super.equals(obj) &&
+ enums == null ? that.enums == null : enums.equals(that.enums);
+ } else {
+ return false;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#isAnySchema()
+ */
+ @Override
+ public boolean isAnySchema() { return true; }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#getType()
+ */
+ @Override
+ public SchemaType getType() {
+ return type;
+ }
+
+ public void setEnums(Set enums) {
+ this.enums = enums;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/ArraySchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/ArraySchema.java
new file mode 100644
index 0000000000..f0cfeba286
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/ArraySchema.java
@@ -0,0 +1,384 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+/*
+ * This attribute defines the allowed items in an instance array, and
+ MUST be a jsonSchema or an array of jsonSchemas. The default value is an
+ empty jsonSchema which allows any value for items in the instance array.
+ */
+public class ArraySchema extends ContainerTypeSchema {
+
+
+ /**
+ * see {@link AdditionalItems}
+ */
+ @JsonProperty
+ private ArraySchema.AdditionalItems additionalItems;
+
+ /**
+ * see {@link Items}
+ */
+ @JsonProperty
+ private ArraySchema.Items items;
+
+ /**This attribute defines the maximum number of values in an array*/
+ @JsonProperty
+ private Integer maxItems;
+
+ /**This attribute defines the minimum number of values in an array*/
+ @JsonProperty
+ private Integer minItems;
+
+ @JsonIgnore
+ private final SchemaType type = SchemaType.ARRAY;
+
+ /**
+ * This attribute indicates that all items in an array instance MUST be
+ unique (contains no two identical values).
+
+ Two instance are consider equal if they are both of the same type
+ and:
+
+ are null; or are booleans/numbers/strings and have the same value; or
+
+ are arrays, contains the same number of items, and each item in
+ the array is equal to the corresponding item in the other array;
+ or
+
+ are objects, contains the same property names, and each property
+ in the object is equal to the corresponding property in the other
+ object.
+ */
+ @JsonProperty
+ private Boolean uniqueItems = null;
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#asArraySchema()
+ */
+ @Override
+ public ArraySchema asArraySchema() { return this; }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ArraySchema) {
+ ArraySchema that = (ArraySchema) obj;
+ return getAdditionalItems() == null ? that.getAdditionalItems() == null :
+ getAdditionalItems().equals(that.getAdditionalItems()) &&
+ getItems() == null ? that.getItems() == null :
+ getItems().equals(that.getItems()) &&
+ getMaxItems() == null ? that.getMaxItems() == null :
+ getMaxItems().equals(that.getMaxItems()) &&
+ getMinItems() == null ? that.getMinItems() == null :
+ getMinItems().equals(that.getMinItems()) &&
+ getUniqueItems() == null ? that.getUniqueItems() == null :
+ getUniqueItems().equals(that.getUniqueItems()) &&
+ super.equals(obj);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * {@link ArraySchema#additionalItems}
+ * @return the additionalItems
+ */
+ public ArraySchema.AdditionalItems getAdditionalItems() {
+ return additionalItems;
+ }
+
+ /**
+ * {@link ArraySchema#items}
+ * @return the items
+ */
+ public ArraySchema.Items getItems() {
+ return items;
+ }
+ /**
+ * {@link ArraySchema#maxItems}
+ * @return the maxItems
+ */
+ public Integer getMaxItems() {
+ return maxItems;
+ }
+
+
+ /**
+ * {@link ArraySchema#minItems}
+ * @return the minItems
+ */
+ public Integer getMinItems() {
+ return minItems;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#getType()
+ */
+ @Override
+ public SchemaType getType() {
+ return type;
+ }
+
+ /**
+ * {@link ArraySchema#uniqueItems}
+ * @return the uniqueItems
+ */
+ public Boolean getUniqueItems() {
+ return uniqueItems;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#isArraySchema()
+ */
+ @Override
+ public boolean isArraySchema() { return true; }
+
+ /**
+ * {@link ArraySchema#additionalItems}
+ * @param additionalItems the additionalItems to set
+ */
+ public void setAdditionalItems(ArraySchema.AdditionalItems additionalItems) {
+ this.additionalItems = additionalItems;
+ }
+
+ /**
+ * {@link ArraySchema#items}
+ * @param items the items to set
+ */
+ public void setItems(ArraySchema.Items items) {
+ this.items = items;
+ }
+
+ /**
+ * Convenience method to set the json schema for the {@link ArraySchema#items}
+ * field
+ * @param jsonSchema
+ */
+ public void setItemsSchema(JsonSchema jsonSchema) {
+ items = new SingleItems(jsonSchema);
+ }
+ /**
+ * {@link ArraySchema#maxItems}
+ * @param maxItems the maxItems to set
+ */
+ public void setMaxItems(Integer maxItems) {
+ this.maxItems = maxItems;
+ }
+
+ /**
+ * {@link ArraySchema#minItems}
+ * @param minItems the minItems to set
+ */
+ public void setMinItems(Integer minItems) {
+ this.minItems = minItems;
+ }
+
+ /**
+ * {@link ArraySchema#uniqueItems}
+ * @param uniqueItems the uniqueItems to set
+ */
+ public void setUniqueItems(Boolean uniqueItems) {
+ this.uniqueItems = uniqueItems;
+ }
+
+ /**
+ * This provides a definition for additional items in an array instance
+ when tuple definitions of the items is provided.
+ */
+ public static abstract class AdditionalItems {
+
+ @JsonCreator
+ public static Items jsonCreator(Map props) {
+ // not implemented for jsonSchema
+ return null;
+ //KNOWN ISSUE: pending https://github.com/FasterXML/jackson-databind/issues/43
+ }
+ }
+
+ /**
+ * When this attribute value is an array of jsonSchemas and the instance
+ value is an array, each position in the instance array MUST conform
+ to the jsonSchema in the corresponding position for this array. This
+ called tuple typing. When tuple typing is used, additional items are
+ allowed, disallowed, or constrained by the "additionalItems"
+ */
+ public static class ArrayItems extends ArraySchema.Items {
+ @JsonProperty
+ private JsonSchema[] jsonSchemas;
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.ArraySchema.Items#asArrayItems()
+ */
+ @Override
+ public ArrayItems asArrayItems() { return this; }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof Items) {
+ ArrayItems that = (ArrayItems) obj;
+ return getJsonSchemas() == null ? that.getJsonSchemas() == null :
+ getJsonSchemas().equals(that.getJsonSchemas());
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * {@link ArraySchema.ArrayItems#jsonSchemas}
+ * @return the jsonSchemas
+ */
+ public JsonSchema[] getJsonSchemas() {
+ return jsonSchemas;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.ArraySchema.Items#isArrayItems()
+ */
+ @Override
+ public boolean isArrayItems() { return true; }
+
+ }
+
+ /**
+ * This attribute defines the allowed items in an instance array, and
+ MUST be a jsonSchema or an array of jsonSchemas. The default value is an
+ empty jsonSchema which allows any value for items in the instance array.
+ */
+ public static abstract class Items {
+
+ @JsonIgnore
+ public boolean isSingleItems() { return false; }
+
+ @JsonIgnore
+ public boolean isArrayItems() { return false; }
+
+ public SingleItems asSingleItems() { return null; }
+ public ArrayItems asArrayItems() { return null; }
+
+ @JsonCreator
+ public static Items jsonCreator(Map props) {
+ //for now only support deserialization of singleItems
+ Object typeFound = props.get("type");
+ if (typeFound == null || ! (typeFound instanceof String)) {
+ return null;
+ }
+ String type = (String) typeFound;
+ JsonSchema schema = JsonSchema.minimalForFormat(SchemaType.forValue(type));
+ //KNOWN ISSUE: pending https://github.com/FasterXML/jackson-databind/issues/43
+ //only deserialize items as minimal schema for type
+ return new SingleItems(schema);
+ }
+
+ }
+
+ /**
+ * This can be false
+ to indicate additional items in the array are not allowed
+ */
+ public static class NoAdditionalItems extends AdditionalItems {
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof NoAdditionalItems;
+ }
+ @JsonValue
+ public Boolean value() { return false; }
+ }
+
+ /**
+ * or it can
+ be a jsonSchema that defines the jsonSchema of the additional items.
+ */
+ public static class SchemaAdditionalItems extends AdditionalItems {
+
+ @JsonIgnore
+ private JsonSchema jsonSchema;
+
+ public SchemaAdditionalItems(JsonSchema schema) {
+ jsonSchema = schema;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof SchemaAdditionalItems &&
+ getJsonSchema() == null ? ((SchemaAdditionalItems)obj).getJsonSchema() == null :
+ getJsonSchema().equals(((SchemaAdditionalItems)obj).getJsonSchema());
+ }
+
+ @JsonValue
+ public JsonSchema getJsonSchema() {
+ return jsonSchema;
+ }
+ }
+
+ /**
+ * When this attribute value is a jsonSchema and the instance value is an
+ array, then all the items in the array MUST be valid according to the
+ jsonSchema.
+ */
+ public static class SingleItems extends ArraySchema.Items {
+ @JsonIgnore
+ private JsonSchema jsonSchema;
+
+ public SingleItems(JsonSchema jsonSchema) {
+ this.jsonSchema = jsonSchema;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof SingleItems &&
+ getSchema() == null ? ((SingleItems)obj).getSchema() == null :
+ getSchema().equals(((SingleItems)obj).getSchema());
+ }
+
+ /**
+ * {@link ArraySchema.SingleItems#jsonSchema}
+ * @return the jsonSchema
+ */
+ @JsonValue
+ public JsonSchema getSchema() {
+ return jsonSchema;
+ }
+
+ /**
+ * {@link ArraySchema.SingleItems#jsonSchema}
+ * @param jsonSchema the jsonSchema to set
+ */
+ public void setSchema(JsonSchema jsonSchema) {
+ this.jsonSchema = jsonSchema;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.ArraySchema.Items#isSingleItems()
+ */
+ @Override
+ public boolean isSingleItems() { return true; }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.ArraySchema.Items#asSingleItems()
+ */
+ @Override
+ public SingleItems asSingleItems() { return this; }
+ }
+
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/BooleanSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/BooleanSchema.java
new file mode 100644
index 0000000000..2d0bbb9bfa
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/BooleanSchema.java
@@ -0,0 +1,34 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+/**
+ * This class represents a {@link JsonSchema} of type boolean
+ * @author jphelan
+ *
+ */
+public class BooleanSchema extends ValueTypeSchema {
+
+ @JsonIgnore
+ private final SchemaType type = SchemaType.BOOLEAN;
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#isBooleanSchema()
+ */
+ @Override
+ public boolean isBooleanSchema() { return true; }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#getType()
+ */
+ @Override
+ public SchemaType getType() {
+ return type;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#asBooleanSchema()
+ */
+ @Override
+ public BooleanSchema asBooleanSchema() { return this; }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/ContainerTypeSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/ContainerTypeSchema.java
new file mode 100644
index 0000000000..c73b14cad6
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/ContainerTypeSchema.java
@@ -0,0 +1,74 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * This class encapsulates the functionality of container type {@link JsonSchema}
+ * Array and Object
+ * @author jphelan
+ *
+ */
+public abstract class ContainerTypeSchema extends SimpleTypeSchema {
+ /**
+ * This provides an enumeration of all possible values that are valid
+ for the instance property. This MUST be an array, and each item in
+ the array represents a possible value for the instance value. If
+ this attribute is defined, the instance value MUST be one of the
+ values in the array in order for the schema to be valid. Comparison
+ of enum values uses the same algorithm as defined in "uniqueItems"
+ (Section 5.15).
+ */
+ @JsonProperty(required = true)
+ private Set enums;
+
+ //instance initializer block
+ {
+ enums = new HashSet();
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#asContainerSchema()
+ */
+ @Override
+ public ContainerTypeSchema asContainerSchema() { return this; }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.SimpleTypeSchema#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ContainerTypeSchema) {
+ ContainerTypeSchema that = (ContainerTypeSchema)obj;
+ return getEnums() == null ? that.getEnums() == null :
+ getEnums().equals(that.getEnums()) &&
+ super.equals(obj);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * {@link ContainerTypeSchema#enums}
+ * @return the enums
+ */
+ public Set getEnums() {
+ return enums;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#isContainerTypeSchema()
+ */
+ @Override
+ public boolean isContainerTypeSchema() { return true; }
+
+ /**
+ * {@link ContainerTypeSchema#enums}
+ * @param enums the enums to set
+ */
+ public void setEnums(Set enums) {
+ this.enums = enums;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/HyperSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/HyperSchema.java
new file mode 100644
index 0000000000..3019549e34
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/HyperSchema.java
@@ -0,0 +1,347 @@
+ package com.fasterxml.jackson.databind.jsonschema.types;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * This class represents the HyperSchema portion of a {@link JsonSchema}
+ * It is a skeleton intended as a starting point for customization.
+ * @author jphelan
+ *
+ */
+public class HyperSchema extends JsonSchema {
+
+
+ /**
+ * This attribute indicates that the instance property SHOULD NOT be
+ changed. Attempts by a user agent to modify the value of this
+ property are expected to be rejected by a server.
+ */
+ @JsonProperty
+ private String readOnly;
+
+ /**
+ * If the instance property value is a string, this attribute defines
+ that the string SHOULD be interpreted as binary data and decoded
+ using the encoding named by this jsonSchema property. RFC 2045, Sec 6.1
+ [RFC2045] lists the possible values for this property.
+ */
+ @JsonProperty
+ private String contentEncoding;
+
+
+ /**
+ * This attribute is a URI that defines what the instance's URI MUST
+ start with in order to validate. The value of the "pathStart"
+ attribute MUST be resolved as per RFC 3986, Sec 5 [RFC3986], and is
+ relative to the instance's URI.
+
+ When multiple schemas have been referenced for an instance, the user
+ agent can determine if this jsonSchema is applicable for a particular
+ instance by determining if the URI of the instance begins with the
+ the value of the "pathStart" attribute. If the URI of the instance
+ does not start with this URI, or if another jsonSchema specifies a
+ starting URI that is longer and also matches the instance, this
+ jsonSchema SHOULD NOT be applied to the instance. Any jsonSchema that does
+ not have a pathStart attribute SHOULD be considered applicable to all
+ the instances for which it is referenced.
+ */
+ @JsonProperty
+ private String pathStart;
+
+ /**
+ * This attribute defines the media type of the instance representations
+ that this jsonSchema is defining.
+ */
+ @JsonProperty
+ private String mediaType;
+
+ /**
+ * This property indicates the fragment resolution protocol to use for
+ resolving fragment identifiers in URIs within the instance
+ representations. This applies to the instance object URIs and all
+ children of the instance object's URIs. The default fragment
+ resolution protocol is "slash-delimited", which is defined below.
+ Other fragment resolution protocols MAY be used, but are not defined
+ in this document.
+
+ The fragment identifier is based on RFC 2396, Sec 5 [RFC2396], and
+ defines the mechanism for resolving references to entities within a
+ document.
+ */
+ @JsonProperty
+ private String fragmentResolution;
+ /**
+ * 6.2.1. slash-delimited fragment resolution
+
+ With the slash-delimited fragment resolution protocol, the fragment
+ identifier is interpreted as a series of property reference tokens
+ that start with and are delimited by the "/" character (\x2F). Each
+ property reference token is a series of unreserved or escaped URI
+ characters. Each property reference token SHOULD be interpreted,
+ starting from the beginning of the fragment identifier, as a path
+ reference in the target JSON structure. The final target value of
+ the fragment can be determined by starting with the root of the JSON
+ structure from the representation of the resource identified by the
+ pre-fragment URI. If the target is a JSON object, then the new
+ target is the value of the property with the name identified by the
+ next property reference token in the fragment. If the target is a
+ JSON array, then the target is determined by finding the item in
+ array the array with the index defined by the next property reference
+ token (which MUST be a number). The target is successively updated
+ for each property reference token, until the entire fragment has been
+ traversed.
+
+ Property names SHOULD be URI-encoded. In particular, any "/" in a
+ property name MUST be encoded to avoid being interpreted as a
+ property delimiter.
+
+ For example, for the following JSON representation:
+
+ {
+ "foo":{
+ "anArray":[
+ {"prop":44}
+ ],
+ "another prop":{
+ "baz":"A string"
+ }
+ }
+ }
+
+ The following fragment identifiers would be resolved:
+
+ fragment identifier resolution
+ ------------------- ----------
+ # self, the root of the resource itself
+ #/foo the object referred to by the foo property
+ #/foo/another%20prop the object referred to by the "another prop"
+ property of the object referred to by the
+ "foo" property
+ #/foo/another%20prop/baz the string referred to by the value of "baz"
+ property of the "another prop" property of
+ the object referred to by the "foo" property
+ #/foo/anArray/0 the first object in the "anArray" array
+
+ 6.2.2. dot-delimited fragment resolution
+
+ The dot-delimited fragment resolution protocol is the same as slash-
+ delimited fragment resolution protocol except that the "." character
+ (\x2E) is used as the delimiter between property names (instead of
+ "/") and the path does not need to start with a ".". For example,
+ #.foo and #foo are a valid fragment identifiers for referencing the
+ value of the foo propery.
+ */
+
+ @JsonProperty
+ private LinkDescriptionObject[] links;
+
+ /**
+ * A link description object is used to describe link relations. In the
+ context of a jsonSchema, it defines the link relations of the instances
+ of the jsonSchema, and can be parameterized by the instance values. The
+ link description format can be used on its own in regular (non-jsonSchema
+ documents), and use of this format can be declared by referencing the
+ normative link description jsonSchema as the the jsonSchema for the data
+ structure that uses the links.
+ */
+ public class LinkDescriptionObject {
+
+ /**
+ * The value of the "href" link description property indicates the
+ target URI of the related resource. The value of the instance
+ property SHOULD be resolved as a URI-Reference per RFC 3986 [RFC3986]
+ and MAY be a relative URI. The base URI to be used for relative
+ resolution SHOULD be the URI used to retrieve the instance object
+ (not the jsonSchema) when used within a jsonSchema. Also, when links are
+ used within a jsonSchema, the URI SHOULD be parametrized by the property
+ values of the instance object, if property values exist for the
+ corresponding variables in the template (otherwise they MAY be
+ provided from alternate sources, like user input).
+
+ Instance property values SHOULD be substituted into the URIs where
+ matching braces ('{', '}') are found surrounding zero or more
+ characters, creating an expanded URI. Instance property value
+ substitutions are resolved by using the text between the braces to
+ denote the property name from the instance to get the value to
+ substitute. For example, if an href value is defined:
+
+ http://somesite.com/{id}
+
+ Then it would be resolved by replace the value of the "id" property
+ value from the instance object. If the value of the "id" property
+ was "45", the expanded URI would be:
+
+ http://somesite.com/45
+
+ If matching braces are found with the string "@" (no quotes) between
+ the braces, then the actual instance value SHOULD be used to replace
+ the braces, rather than a property value. This should only be used
+ in situations where the instance is a scalar (string, boolean, or
+ number), and not for objects or arrays.
+
+ */
+ @JsonProperty
+ private String href;
+
+ /**
+ * The value of the "rel" property indicates the name of the relation to
+ the target resource. The relation to the target SHOULD be
+ interpreted as specifically from the instance object that the jsonSchema
+ (or sub-jsonSchema) applies to, not just the top level resource that
+ contains the object within its hierarchy. If a resource JSON
+ representation contains a sub object with a property interpreted as a
+ link, that sub-object holds the relation with the target. A relation
+ to target from the top level resource MUST be indicated with the
+ jsonSchema describing the top level JSON representation.
+
+ Relationship definitions SHOULD NOT be media type dependent, and
+ users are encouraged to utilize existing accepted relation
+ definitions, including those in existing relation registries (see RFC
+ 4287 [RFC4287]). However, we define these relations here for clarity
+ of normative interpretation within the context of JSON hyper jsonSchema
+ defined relations:
+
+ self If the relation value is "self", when this property is
+ encountered in the instance object, the object represents a
+ resource and the instance object is treated as a full
+ representation of the target resource identified by the specified
+ URI.
+
+ full This indicates that the target of the link is the full
+ representation for the instance object. The object that contains
+ this link possibly may not be the full representation.
+
+ describedby This indicates the target of the link is the jsonSchema for
+ the instance object. This MAY be used to specifically denote the
+ schemas of objects within a JSON object hierarchy, facilitating
+ polymorphic type data structures.
+
+ root This relation indicates that the target of the link SHOULD be
+ treated as the root or the body of the representation for the
+ purposes of user agent interaction or fragment resolution. All
+ other properties of the instance objects can be regarded as meta-
+ data descriptions for the data.
+
+ The following relations are applicable for schemas (the jsonSchema as the
+ "from" resource in the relation):
+
+ instances This indicates the target resource that represents
+ collection of instances of a jsonSchema.
+
+ create This indicates a target to use for creating new instances of
+ a jsonSchema. This link definition SHOULD be a submission link with a
+ non-safe method (like POST).
+
+ For example, if a jsonSchema is defined:
+
+ {
+ "links": [
+ {
+ "rel": "self"
+ "href": "{id}"
+ },
+ {
+ "rel": "up"
+ "href": "{upId}"
+ },
+ {
+ "rel": "children"
+ "href": "?upId={id}"
+ }
+ ]
+ }
+
+ And if a collection of instance resource's JSON representation was
+ retrieved:
+
+ GET /Resource/
+
+ [
+ {
+ "id": "thing",
+ "upId": "parent"
+ },
+ {
+ "id": "thing2",
+ "upId": "parent"
+ }
+ ]
+
+ This would indicate that for the first item in the collection, its
+ own (self) URI would resolve to "/Resource/thing" and the first
+ item's "up" relation SHOULD be resolved to the resource at
+ "/Resource/parent". The "children" collection would be located at
+ "/Resource/?upId=thing".
+ */
+ @JsonProperty
+ private String rel;
+
+ /**
+ * This property value is a jsonSchema that defines the expected structure
+ of the JSON representation of the target of the link.
+ */
+ @JsonProperty
+ private JsonSchema targetSchema;
+
+ /**
+ * This attribute defines which method can be used to access the target
+ resource. In an HTTP environment, this would be "GET" or "POST"
+ (other HTTP methods such as "PUT" and "DELETE" have semantics that
+ are clearly implied by accessed resources, and do not need to be
+ defined here). This defaults to "GET".
+ */
+ @JsonProperty
+ private String method;
+
+ /**
+ * If present, this property indicates a query media type format that
+ the server supports for querying or posting to the collection of
+ instances at the target resource. The query can be suffixed to the
+ target URI to query the collection with property-based constraints on
+ the resources that SHOULD be returned from the server or used to post
+ data to the resource (depending on the method). For example, with
+ the following jsonSchema:
+
+ {
+ "links":[
+ {
+ "enctype":"application/x-www-form-urlencoded",
+ "method":"GET",
+ "href":"/Product/",
+ "properties":{
+ "name":{"description":"name of the product"}
+ }
+ }
+ ]
+ }
+ This indicates that the client can query the server for instances
+ that have a specific name:
+
+ /Product/?name=Slinky
+
+ If no enctype or method is specified, only the single URI specified
+ by the href property is defined. If the method is POST,
+ "application/json" is the default media type.
+ */
+ @JsonProperty
+ private String enctype;
+
+ /**
+ * This attribute contains a jsonSchema which defines the acceptable
+ structure of the submitted request (for a GET request, this jsonSchema
+ would define the properties for the query string and for a POST
+ request, this would define the body).
+ */
+ @JsonProperty
+ private JsonSchema jsonSchema;
+
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#getType()
+ */
+ @Override
+ public SchemaType getType() {
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/IntegerSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/IntegerSchema.java
new file mode 100644
index 0000000000..4baaaacb7c
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/IntegerSchema.java
@@ -0,0 +1,60 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * This class represents a {@link JsonSchema} as an integer type
+ * @author jphelan
+ *
+ */
+public class IntegerSchema extends NumberSchema {
+
+ /**
+ * This attribute defines what value the number instance must be
+ divisible by with no remainder (the result of the division must be an
+ integer.) The value of this attribute SHOULD NOT be 0.
+ */
+ @JsonProperty
+ private Integer divisibleBy;
+
+ @JsonProperty(required = true)
+ public final SchemaType type = SchemaType.INTEGER;
+
+ @Override
+ public IntegerSchema asIntegerSchema() { return this; }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.NumberSchema#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof IntegerSchema) {
+ IntegerSchema that = (IntegerSchema)obj;
+ return getDivisibleBy() == null ? that.getDivisibleBy() == null :
+ getDivisibleBy().equals(that.getDivisibleBy()) &&
+ super.equals(obj);
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * {@link IntegerSchema#divisibleBy}
+ * @return the divisibleBy
+ */
+ public Integer getDivisibleBy() {
+ return divisibleBy;
+ }
+
+ @Override
+ public boolean isIntegerSchema() { return true; }
+
+ /**
+ * {@link IntegerSchema#divisibleBy}
+ * @param divisibleBy the divisibleBy to set
+ */
+ public void setDivisibleBy(Integer divisibleBy) {
+ this.divisibleBy = divisibleBy;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/JsonSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/JsonSchema.java
new file mode 100644
index 0000000000..09482afb0b
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/JsonSchema.java
@@ -0,0 +1,612 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
+import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
+import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+
+/**
+ * The type wraps the json schema specification at :
+ * Json JsonSchema
+ * Draft 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.
+ *
+ * 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.
+ *
+ * An example JSON JsonSchema provided by the JsonSchema draft:
+ *
+ *
+ * {
+ * "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}"
+ * }
+ * ]
+ * }
+ *
+ *
+ * @author jphelan
+ */
+@JsonInclude(Include.NON_EMPTY)
+@JsonTypeInfo(use = Id.CUSTOM, include = As.PROPERTY, property = "type")
+@JsonTypeIdResolver(JsonSchema.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" }
+ */
+ @JsonIgnore
+ 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;
+
+
+ /**
+ * 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;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof JsonSchema) {
+ JsonSchema that = ((JsonSchema)obj);
+ return that.getType() == getType() &&
+ getRequired() == null ? that.getRequired() == null :
+ getRequired().equals(that.getRequired()) &&
+ get$ref() == null ? that.get$ref() == null :
+ get$ref().equals(that.get$ref()) &&
+ get$schema() == null ? that.get$schema() == null :
+ get$schema().equals(that.get$schema()) &&
+ getDisallow() == null ? that.getDisallow() == null :
+ getDisallow().equals(that.getDisallow()) &&
+ getExtends() == null ? that.getExtends() == null :
+ getExtends().equals(that.getExtends());
+ }
+ return false;
+ }
+
+ /**
+ * {@link JsonSchema#$ref}
+ *
+ * @return the $ref
+ */
+ public String get$ref() {
+ return $ref;
+ }
+
+ /**
+ * {@link JsonSchema#$schema}
+ *
+ * @return the $schema
+ */
+ public String get$schema() {
+ return $schema;
+ }
+
+ /**
+ * {@link JsonSchema#disallow}
+ *
+ * @return the disallow
+ */
+ public JsonSchema[] getDisallow() {
+ return disallow;
+ }
+
+ /**
+ * {@link JsonSchema#extendsextends}
+ *
+ * @return the extendsextends
+ */
+ @JsonGetter("extends")
+ public JsonSchema[] getExtends() {
+ return extendsextends;
+ }
+
+ /**
+ * {@link JsonSchema#id}
+ *
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * {@link JsonSchema#required}
+ *
+ * @return the required
+ */
+ public Boolean getRequired() {
+ return required;
+ }
+
+ @JsonIgnore
+ public abstract SchemaType 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;
+ }
+
+ /**
+ * {@link JsonSchema#$ref}
+ *
+ * @param $ref
+ * the $ref to set
+ */
+ public void set$ref(String $ref) {
+ this.$ref = $ref;
+ }
+
+ /**
+ * {@link JsonSchema#$schema}
+ *
+ * @param $schema
+ * the $schema to set
+ */
+ public void set$schema(String $schema) {
+ this.$schema = $schema;
+ }
+
+ /**
+ * {@link JsonSchema#disallow}
+ *
+ * @param disallow
+ * the disallow to set
+ */
+ public void setDisallow(JsonSchema[] disallow) {
+ this.disallow = disallow;
+ }
+
+ /**
+ * {@link JsonSchema#extendsextends}
+ *
+ * @param extendsextends
+ * the extendsextends to set
+ */
+ @JsonSetter("extends")
+ public void setExtends(JsonSchema[] extendsextends) {
+ this.extendsextends = extendsextends;
+ }
+
+ /**
+ * {@link JsonSchema#id}
+ *
+ * @param id
+ * the id to set
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * {@link JsonSchema#required}
+ *
+ * @param required
+ * the required to set
+ */
+ public void setRequired(Boolean required) {
+ this.required = required;
+ }
+
+ /**
+ * 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(SchemaType 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();
+ }
+ }
+
+ public static class JsonSchemaIdResolver implements TypeIdResolver {
+
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsontype.TypeIdResolver#idFromValue(java.lang.Object)
+ */
+ public String idFromValue(Object value) {
+ if ( value instanceof JsonSchema) {
+ return ((JsonSchema)value).getType().value();
+ } else {
+ return null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsontype.TypeIdResolver#idFromValueAndType(java.lang.Object, java.lang.Class)
+ */
+ public String idFromValueAndType(Object value, Class> suggestedType) {
+ return idFromValue(value);
+ }
+
+ private static JavaType any = TypeFactory.defaultInstance().constructType(AnySchema.class);
+ private static JavaType array = TypeFactory.defaultInstance().constructType(ArraySchema.class);
+ private static JavaType booleanboolean = TypeFactory.defaultInstance().constructType(BooleanSchema.class);
+ private static JavaType integer = TypeFactory.defaultInstance().constructType(IntegerSchema.class);
+ private static JavaType nullnull = TypeFactory.defaultInstance().constructType(NullSchema.class);
+ private static JavaType number = TypeFactory.defaultInstance().constructType(NumberSchema.class);
+ private static JavaType object = TypeFactory.defaultInstance().constructType(ObjectSchema.class);
+ private static JavaType string = TypeFactory.defaultInstance().constructType(StringSchema.class);
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsontype.TypeIdResolver#typeFromId(java.lang.String)
+ */
+ public JavaType typeFromId(String id) {
+ switch (SchemaType.forValue(id)) {
+ case ANY: return any;
+ case ARRAY: return array;
+ case BOOLEAN: return booleanboolean;
+ case INTEGER: return integer;
+ case NULL: return nullnull;
+ case NUMBER: return number;
+ case OBJECT: return object;
+ case STRING: return string;
+ default:
+ return null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsontype.TypeIdResolver#getMechanism()
+ */
+ public Id getMechanism() {
+ return Id.CUSTOM;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsontype.TypeIdResolver#init(com.fasterxml.jackson.databind.JavaType)
+ */
+ public void init(JavaType baseType) { }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsontype.TypeIdResolver#idFromBaseType()
+ */
+ public String idFromBaseType() {
+ return null;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/JsonValueFormat.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/JsonValueFormat.java
new file mode 100644
index 0000000000..d4d4a2bb3f
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/JsonValueFormat.java
@@ -0,0 +1,124 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+/**
+ * This enum represents the encoded format for a jsonSchema value type
+ * @author jphelan
+ *
+ */
+public enum JsonValueFormat {
+ /**
+ * This SHOULD be a date in ISO 8601 format of YYYY-MM-
+ DDThh:mm:ssZ in UTC time. This is the recommended form of date/
+ timestamp.
+ */
+ DATE_TIME {
+ @Override
+ public String toString() { return "date-time"; }
+ },
+
+ /**
+ * This SHOULD be a date in the format of YYYY-MM-DD. It is
+ recommended that you use the "date-time" format instead of "date"
+ unless you need to transfer only the date part.
+ */
+ DATE {
+ @Override
+ public String toString() { return "date"; }
+ },
+
+ /**
+ * This SHOULD be a time in the format of hh:mm:ss. It is
+ recommended that you use the "date-time" format instead of "time"
+ unless you need to transfer only the time part.
+ */
+ TIME {
+ @Override
+ public String toString() { return "time"; }
+ },
+
+ /**
+ * This SHOULD be the difference, measured in
+ milliseconds, between the specified time and midnight, 00:00 of
+ January 1, 1970 UTC. The value SHOULD be a number (integer or
+ float).
+ */
+ UTC_MILLISEC {
+ @Override
+ public String toString() { return "utc-millisec"; }
+ },
+
+ /**
+ * A regular expression, following the regular expression
+ specification from ECMA 262/Perl 5.
+ */
+ REGEX {
+ @Override
+ public String toString() { return "regex"; }
+ },
+
+ /**
+ * This is a CSS color (like "#FF0000" or "red"), based on CSS
+ 2.1 [W3C.CR-CSS21-20070719].
+ */
+ COLOR {
+ @Override
+ public String toString() { return "color"; }
+ },
+
+ /**
+ * This is a CSS style definition (like "color: red; background-
+ color:#FFF"), based on CSS 2.1 [W3C.CR-CSS21-20070719].
+ */
+ STYLE {
+ @Override
+ public String toString() { return "style"; }
+ },
+
+ /**
+ * This SHOULD be a phone number (format MAY follow E.123).
+ */
+ PHONE {
+ @Override
+ public String toString() { return "phone"; }
+ },
+
+ /**
+ * This value SHOULD be a URI..
+ */
+ URI {
+ @Override
+ public String toString() { return "uri"; }
+ },
+
+ /**
+ * This SHOULD be an email address.
+ */
+ EMAIL {
+ @Override
+ public String toString() { return "email"; }
+ },
+ /**
+ * This SHOULD be an ip version 4 address.
+ */
+ IP_ADDRESS {
+ @Override
+ public String toString() { return "ip-address"; }
+ },
+
+ /**
+ * This SHOULD be an ip version 6 address.
+ */
+ IPV6 {
+ @Override
+ public String toString() { return "ipv6"; }
+ },
+
+ /**
+ * This SHOULD be a host-name.
+ */
+ HOST_NAME {
+ @Override
+ public String toString() { return "host-name"; }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/NullSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/NullSchema.java
new file mode 100644
index 0000000000..83c5acdad3
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/NullSchema.java
@@ -0,0 +1,36 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+/**
+ * This class represents a {@link JsonSchema} as a null type
+ * @author jphelan
+ */
+public class NullSchema extends SimpleTypeSchema {
+
+ @JsonIgnore
+ private final SchemaType type = SchemaType.NULL;
+
+ @Override
+ public NullSchema asNullSchema() { return this; }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof NullSchema && super.equals(obj));
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#getType()
+ */
+ @Override
+ public SchemaType getType() {
+ return type;
+ }
+
+ @Override
+ public boolean isNullSchema() { return true; }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/NumberSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/NumberSchema.java
new file mode 100644
index 0000000000..c1ff5aa002
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/NumberSchema.java
@@ -0,0 +1,135 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * This class represents a {@link JsonSchema} as a number type
+ * @author jphelan
+ *
+ */
+public class NumberSchema extends ValueTypeSchema {
+
+ /**
+ * This attribute indicates if the value of the instance (if the
+ instance is a number) can not equal the number defined by the
+ "maximum" attribute.
+ */
+ @JsonProperty
+ private Boolean exclusiveMaximum;
+
+ /**
+ * This attribute indicates if the value of the instance (if the
+ instance is a number) can not equal the number defined by the
+ "minimum" attribute.
+ */
+ @JsonProperty
+ private Boolean exclusiveMinimum;
+
+ /**This attribute defines the maximum value of the instance property*/
+ @JsonProperty
+ private Double maximum = null;
+
+ /**This attribute defines the minimum value of the instance property*/
+ @JsonProperty
+ private Double minimum = null;
+
+ @JsonIgnore
+ private final SchemaType type = SchemaType.NUMBER;
+
+ @Override
+ public NumberSchema asNumberSchema() { return this; }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.ValueTypeSchema#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof NumberSchema) {
+ NumberSchema that = (NumberSchema)obj;
+ return getExclusiveMaximum() == null ? that.getExclusiveMaximum() == null :
+ getExclusiveMaximum().equals(that.getExclusiveMaximum()) &&
+ getExclusiveMinimum() == null ? that.getExclusiveMinimum() == null :
+ getExclusiveMinimum().equals(that.getExclusiveMinimum()) &&
+ getMaximum() == null ? that.getMaximum() == null :
+ getMaximum().equals(that.getMaximum()) &&
+ getMinimum() == null ? that.getMinimum() == null :
+ getMinimum().equals(that.getMinimum()) &&
+ super.equals(obj);
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * {@link NumberSchema#exclusiveMaximum}
+ * @return the exclusiveMaximum
+ */
+ public Boolean getExclusiveMaximum() {
+ return exclusiveMaximum;
+ }
+
+ /**
+ * {@link NumberSchema#exclusiveMinimum}
+ * @return the exclusiveMinimum
+ */
+ public Boolean getExclusiveMinimum() {
+ return exclusiveMinimum;
+ }
+ /**
+ * {@link NumberSchema#maximum}
+ * @return the maximum
+ */
+ public Double getMaximum() {
+ return maximum;
+ }
+ /**
+ * {@link NumberSchema#minimum}
+ * @return the minimum
+ */
+ public Double getMinimum() {
+ return minimum;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#getType()
+ */
+ @Override
+ public SchemaType getType() {
+ return type;
+ }
+
+ @Override
+ public boolean isNumberSchema() { return true; }
+ /**
+ * {@link NumberSchema#exclusiveMaximum}
+ * @param exclusiveMaximum the exclusiveMaximum to set
+ */
+ public void setExclusiveMaximum(Boolean exclusiveMaximum) {
+ this.exclusiveMaximum = exclusiveMaximum;
+ }
+ /**
+ * {@link NumberSchema#exclusiveMinimum}
+ * @param exclusiveMinimum the exclusiveMinimum to set
+ */
+ public void setExclusiveMinimum(Boolean exclusiveMinimum) {
+ this.exclusiveMinimum = exclusiveMinimum;
+ }
+
+ /**
+ * {@link NumberSchema#maximum}
+ * @param maximum the maximum to set
+ */
+ public void setMaximum(Double maximum) {
+ this.maximum = maximum;
+ }
+
+ /**
+ * {@link NumberSchema#minimum}
+ * @param minimum the minimum to set
+ */
+ public void setMinimum(Double minimum) {
+ this.minimum = minimum;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/ObjectSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/ObjectSchema.java
new file mode 100644
index 0000000000..af65dc45fd
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/ObjectSchema.java
@@ -0,0 +1,395 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+/**
+ * This type represents a {@link JsonSchema} as an object type
+ * @author jphelan
+ *
+ */
+public class ObjectSchema extends ContainerTypeSchema {
+
+ /**
+ * This attribute defines a jsonSchema for all properties that are not
+ * explicitly defined in an object type definition. If specified, the value
+ * MUST be a jsonSchema or a boolean. If false is provided, no additional
+ * properties are allowed beyond the properties defined in the jsonSchema. The
+ * default value is an empty jsonSchema which allows any value for additional
+ * properties.
+ */
+ @JsonProperty
+ private AdditionalProperties additionalProperties;
+
+ /**
+ * This attribute is an object that defines the requirements of a property
+ * on an instance object. If an object instance has a property with the same
+ * name as a property in this attribute's object, then the instance must be
+ * valid against the attribute's property value
+ */
+ @JsonProperty
+ private List dependencies;
+
+ /**
+ *
+ This attribute is an object that defines the jsonSchema for a set of property
+ * names of an object instance. The name of each property of this
+ * attribute's object is a regular expression pattern in the ECMA 262/Perl 5
+ * format, while the value is a jsonSchema. If the pattern matches the name of a
+ * property on the instance object, the value of the instance's property
+ * MUST be valid against the pattern name's jsonSchema value.
+ */
+ @JsonProperty
+ private Map patternProperties;
+
+ /**
+ * This attribute is an object with property definitions that define the
+ * valid values of instance object property values. When the instance value
+ * is an object, the property values of the instance object MUST conform to
+ * the property definitions in this object. In this object, each property
+ * definition's value MUST be a jsonSchema, and the property's name MUST be the
+ * name of the instance property that it defines. The instance property
+ * value MUST be valid according to the jsonSchema from the property definition.
+ * Properties are considered unordered, the order of the instance properties
+ * MAY be in any order.
+ */
+ @JsonProperty
+ private Map properties;
+
+ @JsonIgnore
+ private final SchemaType type = SchemaType.OBJECT;
+
+ // instance initializer block
+ {
+ dependencies = new ArrayList();
+ patternProperties = new HashMap();
+ properties = new HashMap();
+ }
+
+ public boolean addSchemaDependency(String depender, JsonSchema parentMustMatch) {
+ return dependencies
+ .add(new SchemaDependency(depender, parentMustMatch));
+ }
+
+ public boolean addSimpleDependency(String depender, String dependsOn) {
+ return dependencies.add(new SimpleDependency(depender, dependsOn));
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#asObjectSchema()
+ */
+ @Override
+ public ObjectSchema asObjectSchema() {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ObjectSchema) {
+ ObjectSchema that = (ObjectSchema) obj;
+ return getAdditionalProperties() == null ? that.getAdditionalProperties() == null :
+ getAdditionalProperties().equals(that.getAdditionalProperties()) &&
+ getDependencies() == null ? that.getDependencies() == null :
+ getDependencies().equals(that.getDependencies()) &&
+ getPatternProperties() == null ? that.getPatternProperties() == null :
+ getPatternProperties().equals(that.getPatternProperties()) &&
+ getProperties() == null ? that.getProperties() == null :
+ getProperties().equals(that.getProperties()) &&
+ super.equals(obj);
+ } else {
+ return false;
+ }
+
+ }
+
+ /**
+ * {@link ObjectSchema#additionalProperties}
+ *
+ * @return the additionalProperties
+ */
+ public AdditionalProperties getAdditionalProperties() {
+ return additionalProperties;
+ }
+
+ /**
+ * {@link ObjectSchema#dependencies}
+ *
+ * @return the dependencies
+ */
+ public List getDependencies() {
+ return dependencies;
+ }
+
+ /**
+ * {@link ObjectSchema#patternProperties}
+ *
+ * @return the patternProperties
+ */
+ public Map getPatternProperties() {
+ return patternProperties;
+ }
+
+ /**
+ * {@link ObjectSchema#properties}
+ *
+ * @return the properties
+ */
+ public Map getProperties() {
+ return properties;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#getType()
+ */
+ @Override
+ public SchemaType getType() {
+ return type;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#isObjectSchema()
+ */
+ @Override
+ public boolean isObjectSchema() {
+ return true;
+ }
+
+ public void putOptionalProperty(String name, JsonSchema jsonSchema) {
+ properties.put(name, jsonSchema);
+ }
+
+ public JsonSchema putPatternProperty(String regex, JsonSchema value) {
+ return patternProperties.put(regex, value);
+ }
+
+ public JsonSchema putProperty(String name, JsonSchema value) {
+ value.setRequired(true);
+ return properties.put(name, value);
+ }
+
+ public void rejectAdditionalProperties() {
+ additionalProperties = NoAdditionalProperties.instance;
+ }
+
+ /**
+ * {@link ObjectSchema#additionalProperties}
+ *
+ * @param additionalProperties
+ * the additionalProperties to set
+ */
+ public void setAdditionalProperties(
+ AdditionalProperties additionalProperties) {
+ this.additionalProperties = additionalProperties;
+ }
+
+ /**
+ * {@link ObjectSchema#dependencies}
+ *
+ * @param dependencies
+ * the dependencies to set
+ */
+ public void setDependencies(List dependencies) {
+ this.dependencies = dependencies;
+ }
+
+ /**
+ * {@link ObjectSchema#patternProperties}
+ *
+ * @param patternProperties
+ * the patternProperties to set
+ */
+ public void setPatternProperties(Map patternProperties) {
+ this.patternProperties = patternProperties;
+ }
+
+ /**
+ * {@link ObjectSchema#properties}
+ *
+ * @param properties
+ * the properties to set
+ */
+ public void setProperties(Map properties) {
+ this.properties = properties;
+ }
+
+ public static abstract class AdditionalProperties {
+
+ @JsonCreator
+ public AdditionalProperties jsonCreator() {
+ //KNOWN ISSUE: pending https://github.com/FasterXML/jackson-databind/issues/43
+ return null;
+ }
+ }
+
+ public static abstract class Dependency {
+ @JsonCreator
+ public Dependency jsonCreator() {
+ //KNOWN ISSUE: pending https://github.com/FasterXML/jackson-databind/issues/43
+ return null;
+ }
+ }
+
+ public static class NoAdditionalProperties extends AdditionalProperties {
+ public final Boolean schema = false;
+
+ protected NoAdditionalProperties() {
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof NoAdditionalProperties;
+ }
+
+ @JsonValue
+ public Boolean value() {
+ return schema;
+ }
+
+ public static final NoAdditionalProperties instance = new NoAdditionalProperties();
+ }
+
+ public static class SchemaAdditionalProperties extends AdditionalProperties {
+
+ @JsonProperty
+ private JsonSchema jsonSchema;
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof SchemaAdditionalProperties &&
+ getJsonSchema() == null ? ((SchemaAdditionalProperties)obj).getJsonSchema() == null :
+ getJsonSchema().equals(((SchemaAdditionalProperties)obj).getJsonSchema());
+ }
+
+ /**
+ * {@link ObjectSchema.SchemaAdditionalProperties#jsonSchema}
+ * @return the jsonSchema
+ */
+ public JsonSchema getJsonSchema() {
+ return jsonSchema;
+ }
+
+ public SchemaAdditionalProperties(JsonSchema jsonSchema) {
+ this.jsonSchema = jsonSchema;
+ }
+ }
+
+ /**
+ * JsonSchema Dependency If the dependency value is a jsonSchema, then the instance
+ * object MUST be valid against the jsonSchema.
+ */
+ public static class SchemaDependency extends Dependency {
+
+ @JsonProperty(required = true)
+ private String depender;
+
+ @JsonProperty(required = true)
+ private JsonSchema parentMustMatch;
+
+ public SchemaDependency(String depender, JsonSchema parentMustMatch) {
+ this.depender = depender;
+ this.parentMustMatch = parentMustMatch;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof SchemaDependency) {
+ SchemaDependency that = (SchemaDependency) obj;
+ return getDepender() == null ? that.getDepender() == null :
+ getDepender().equals(that.getDepender()) &&
+ getParentMustMatch() == null ? that.getParentMustMatch() == null :
+ getParentMustMatch().equals(that.getParentMustMatch());
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * {@link ObjectSchema.SchemaDependency#depender}
+ * @return the depender
+ */
+ public String getDepender() {
+ return depender;
+ }
+
+ /**
+ * {@link ObjectSchema.SchemaDependency#parentMustMatch}
+ * @return the parentMustMatch
+ */
+ public JsonSchema getParentMustMatch() {
+ return parentMustMatch;
+ }
+ }
+
+ /**
+ * Simple Dependency If the dependency value is a string, then the instance
+ * object MUST have a property with the same name as the dependency value.
+ * If the dependency value is an array of strings, then the instance object
+ * MUST have a property with the same name as each string in the dependency
+ * value's array.
+ */
+ public static class SimpleDependency extends Dependency {
+
+ @JsonProperty(required = true)
+ private String depender;
+
+ @JsonProperty(required = true)
+ private String dependsOn;
+
+ public SimpleDependency(String depender, String dependsOn) {
+ this.depender = depender;
+ this.dependsOn = dependsOn;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof SchemaDependency) {
+ SimpleDependency that = (SimpleDependency) obj;
+ return getDepender() == null ? that.getDepender() == null :
+ getDepender().equals(that.getDepender()) &&
+ getDependsOn() == null ? that.getDependsOn() == null :
+ getDependsOn().equals(that.getDependsOn());
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * {@link ObjectSchema.SimpleDependency#depender}
+ * @return the depender
+ */
+ public String getDepender() {
+ return depender;
+ }
+
+ /**
+ * {@link ObjectSchema.SimpleDependency#dependsOn}
+ * @return the dependsOn
+ */
+ public String getDependsOn() {
+ return dependsOn;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/SchemaType.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/SchemaType.java
new file mode 100644
index 0000000000..481c726f5b
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/SchemaType.java
@@ -0,0 +1,27 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+public enum SchemaType {
+
+ STRING,
+ NUMBER,
+ INTEGER,
+ BOOLEAN,
+ OBJECT,
+ ARRAY,
+ NULL,
+ ANY;
+
+
+ @JsonValue
+ public String value() {
+ return this.name().toLowerCase();
+ }
+
+ @JsonCreator
+ public static SchemaType forValue(String s) {
+ return valueOf(s.toUpperCase());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/SimpleTypeSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/SimpleTypeSchema.java
new file mode 100644
index 0000000000..3c8a0db0ac
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/SimpleTypeSchema.java
@@ -0,0 +1,128 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+/**
+ * This class encapsulates the functionality of {@link JsonSchema} simple types
+ * @author jphelan
+ *
+ */
+public abstract class SimpleTypeSchema extends JsonSchema {
+
+ /**
+ * This attribute defines the default value of the instance when the
+ * instance is undefined.
+ */
+ @JsonIgnore
+ private String defaultdefault;
+ /**
+ * This attribute is a string that provides a full description of the of
+ * purpose the instance property.
+ */
+ @JsonProperty
+ private String description;
+ /**
+ * This attribute is a string that provides a short description of the
+ * instance property.
+ */
+ @JsonProperty
+ private String title;
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#asSimpleTypeSchema()
+ */
+ @Override
+ public SimpleTypeSchema asSimpleTypeSchema() {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof SimpleTypeSchema) {
+ SimpleTypeSchema that = (SimpleTypeSchema)obj;
+ return getDefault() == null ? that.getDefault() == null :
+ getDefault().equals(that.getDefault()) &&
+ getDescription() == null ? that.getDescription() == null :
+ getDescription().equals(that.getDescription()) &&
+ getTitle() == null ? that.getTitle() == null :
+ getTitle().equals(that.getTitle()) &&
+ super.equals(obj);
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * {@link SimpleTypeSchema#defaultdefault}
+ *
+ * @return the defaultdefault
+ */
+ @JsonGetter("default")
+ public String getDefault() {
+ return defaultdefault;
+ }
+
+ /**
+ * {@link SimpleTypeSchema#description}
+ *
+ * @return the description
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * {@link SimpleTypeSchema#title}
+ *
+ * @return the title
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#isSimpleTypeSchema()
+ */
+ @Override
+ public boolean isSimpleTypeSchema() {
+ return true;
+ }
+
+ /**
+ * {@link SimpleTypeSchema#defaultdefault}
+ *
+ * @param defaultdefault
+ * the defaultdefault to set
+ */
+ @JsonSetter("default")
+ public void setDefault(String defaultdefault) {
+ this.defaultdefault = defaultdefault;
+ }
+
+ /**
+ * {@link SimpleTypeSchema#description}
+ *
+ * @param description
+ * the description to set
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * {@link SimpleTypeSchema#title}
+ *
+ * @param title
+ * the title to set
+ */
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/StringSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/StringSchema.java
new file mode 100644
index 0000000000..f17dc25a09
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/StringSchema.java
@@ -0,0 +1,131 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * This represents a {@link JsonSchema} as a String
+ * @author jphelan
+ *
+ */
+public class StringSchema extends ValueTypeSchema {
+
+ /** this defines the maximum length of the string. */
+ @JsonProperty
+ private Integer maxLength;
+
+ /** this defines the minimum length of the string. */
+ @JsonProperty
+ private Integer minLength;
+ /**
+ * this provides a regular expression that a string instance MUST match in
+ * order to be valid. Regular expressions SHOULD follow the regular
+ * expression specification from ECMA 262/Perl 5
+ */
+ @JsonProperty
+ private String pattern;
+
+ @JsonIgnore
+ private final SchemaType type = SchemaType.STRING;
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#asStringSchema()
+ */
+ @Override
+ public StringSchema asStringSchema() {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.ValueTypeSchema#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof StringSchema) {
+ StringSchema that = (StringSchema)obj;
+ return getMaxLength() == null ? that.getMaxLength() == null :
+ getMaxLength().equals(that.getMaxLength()) &&
+ getMinLength() == null ? that.getMinLength() == null :
+ getMinLength().equals(that.getMinLength()) &&
+ getPattern() == null ? that.getPattern() == null :
+ getPattern().equals(that.getPattern()) &&
+ super.equals(obj);
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * {@link StringSchema#maxLength}
+ *
+ * @return the maxLength
+ */
+ public Integer getMaxLength() {
+ return maxLength;
+ }
+
+ /**
+ * {@link StringSchema#minLength}
+ *
+ * @return the minLength
+ */
+ public Integer getMinLength() {
+ return minLength;
+ }
+
+ /**
+ * {@link StringSchema#pattern}
+ *
+ * @return the pattern
+ */
+ public String getPattern() {
+ return pattern;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#getType()
+ */
+ @Override
+ public SchemaType getType() {
+ return type;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#isStringSchema()
+ */
+ @Override
+ public boolean isStringSchema() {
+ return true;
+ }
+
+ /**
+ * {@link StringSchema#maxLength}
+ *
+ * @param maxLength
+ * the maxLength to set
+ */
+ public void setMaxLength(Integer maxLength) {
+ this.maxLength = maxLength;
+ }
+
+ /**
+ * {@link StringSchema#minLength}
+ *
+ * @param minLength
+ * the minLength to set
+ */
+ public void setMinLength(Integer minLength) {
+ this.minLength = minLength;
+ }
+
+ /**
+ * {@link StringSchema#pattern}
+ *
+ * @param pattern
+ * the pattern to set
+ */
+ public void setPattern(String pattern) {
+ this.pattern = pattern;
+ }
+}
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/UnionTypeSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/UnionTypeSchema.java
new file mode 100644
index 0000000000..9f9d4ef751
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/UnionTypeSchema.java
@@ -0,0 +1,73 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * This class represents a {@link JsonSchema} as a Union Type Schema:
+ * "An array of two or more simple type definitions. Each
+ item in the array MUST be a simple type definition or a schema.
+ The instance value is valid if it is of the same type as one of
+ the simple type definitions, or valid by one of the schemas, in
+ the array."
+
+ * @author jphelan
+ *
+ */
+public class UnionTypeSchema extends JsonSchema {
+
+ @JsonProperty
+ private ValueTypeSchema[] elements;
+
+ @Override
+ public UnionTypeSchema asUnionTypeSchema() {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof UnionTypeSchema) {
+ UnionTypeSchema that = (UnionTypeSchema) obj;
+ return getElements() == null ? that.getElements() == null :
+ getElements().equals(that.getElements()) &&
+ super.equals(obj);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * {@link UnionTypeSchema#elements}
+ *
+ * @return the elements
+ */
+ public ValueTypeSchema[] getElements() {
+ return elements;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#getType()
+ */
+ @Override
+ public SchemaType getType() {
+ return null;
+ }
+
+ @Override
+ public boolean isUnionTypeSchema() {
+ return true;
+ }
+
+ /**
+ * {@link UnionTypeSchema#elements}
+ *
+ * @param elements
+ * the elements to set
+ */
+ public void setElements(ValueTypeSchema[] elements) {
+ assert elements.length >= 2 : "Union Type Schemas must contain two or more Simple Type Schemas";
+ this.elements = elements;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/ValueTypeSchema.java b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/ValueTypeSchema.java
new file mode 100644
index 0000000000..0358b10c55
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/databind/jsonschema/types/ValueTypeSchema.java
@@ -0,0 +1,104 @@
+package com.fasterxml.jackson.databind.jsonschema.types;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * This class represents a {@link JsonSchema}
+ * A primitive type.
+ */
+public abstract class ValueTypeSchema extends SimpleTypeSchema {
+
+ /**
+ * This provides an enumeration of all possible values that are valid
+ for the instance property. This MUST be an array, and each item in
+ the array represents a possible value for the instance value. If
+ this attribute is defined, the instance value MUST be one of the
+ values in the array in order for the schema to be valid. Comparison
+ of enum values uses the same algorithm as defined in "uniqueItems"
+ (Section 5.15).
+ */
+ @JsonProperty
+ private Set enums;
+
+ /**
+ * This property defines the type of data, content type, or microformat to
+ * be expected in the instance property values. A format attribute MAY be
+ * one of the values listed below, and if so, SHOULD adhere to the semantics
+ * describing for the format. A format SHOULD only be used to give meaning
+ * to primitive types (string, integer, number, or boolean). Validators MAY
+ * (but are not required to) validate that the instance values conform to a
+ * format.
+ *
+ * Additional custom formats MAY be created. These custom formats MAY be
+ * expressed as an URI, and this URI MAY reference a schema of that
+ */
+ @JsonProperty
+ private JsonValueFormat format;
+
+ //instance initializer block
+ {
+ enums = new HashSet();
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#asValueSchemaSchema()
+ */
+ @Override
+ public ValueTypeSchema asValueSchemaSchema() { return this; }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ValueTypeSchema) {
+ ValueTypeSchema that = (ValueTypeSchema) obj;
+ return getEnums() == null ? that.getEnums() == null :
+ getEnums().equals(that.getEnums()) &&
+ getFormat() == null ? that.getFormat() == null :
+ getFormat().equals(that.getFormat()) &&
+ super.equals(obj);
+ }
+ return false;
+ }
+
+ /**
+ * {@link ValueTypeSchema#enums}
+ * @return the enums
+ */
+ public Set getEnums() {
+ return enums;
+ }
+ /**
+ * {@link ValueTypeSchema#format}
+ * @return the format
+ */
+ public JsonValueFormat getFormat() {
+ return format;
+ }
+
+ /* (non-Javadoc)
+ * @see com.fasterxml.jackson.databind.jsonschema.types.JsonSchema#isValueTypeSchema()
+ */
+ @Override
+ public boolean isValueTypeSchema() { return true; }
+
+ /**
+ * {@link ValueTypeSchema#enums}
+ * @param enums the enums to set
+ */
+ public void setEnums(Set enums) {
+ this.enums = enums;
+ }
+
+ /**
+ * {@link ValueTypeSchema#format}
+ * @param format the format to set
+ */
+ public void setFormat(JsonValueFormat format) {
+ this.format = format;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyFilter.java b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyFilter.java
index e2171111c5..938aaa1c25 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyFilter.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyFilter.java
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
@@ -38,6 +39,6 @@ public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider
* processing
*
*/
- public void depositSchemaProperty(BeanPropertyWriter writer, ObjectNode propertiesNode,
+ public void depositSchemaProperty(BeanPropertyWriter writer, JsonObjectFormatVisitor objectVisitor,
SerializerProvider provider);
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/DefaultSerializerProvider.java b/src/main/java/com/fasterxml/jackson/databind/ser/DefaultSerializerProvider.java
index c54d97eb8e..81af6124ac 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/DefaultSerializerProvider.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/DefaultSerializerProvider.java
@@ -13,9 +13,8 @@
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.ObjectIdInfo;
-import com.fasterxml.jackson.databind.jsonschema.JsonSchema;
-import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
-import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorAware;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.ser.impl.WritableObjectId;
import com.fasterxml.jackson.databind.util.ClassUtil;
@@ -233,12 +232,11 @@ public void serializeValue(JsonGenerator jgen, Object value, JavaType rootType,
/**
* The method to be called by {@link ObjectMapper} and {@link ObjectWriter}
- * to generate JSON schema for
- * given type.
+ TODO:fillme
*
* @param type The type for which to generate schema
*/
- public JsonSchema generateJsonSchema(Class> type)
+ public void acceptJsonFormatVisitor(Class> type, JsonFormatVisitorWrapper visitor)
throws JsonMappingException
{
if (type == null) {
@@ -248,16 +246,12 @@ public JsonSchema generateJsonSchema(Class> type)
* type information it needs is accessible via "untyped" serializer)
*/
JsonSerializer ser = findValueSerializer(type, null);
- JsonNode schemaNode = (ser instanceof SchemaAware) ?
- ((SchemaAware) ser).getSchema(this, null) :
- JsonSchema.getDefaultSchemaNode();
- if (!(schemaNode instanceof ObjectNode)) {
- throw new IllegalArgumentException("Class " + type.getName() +
- " would not be serialized as a JSON object and therefore has no schema");
+ if (ser instanceof JsonFormatVisitorAware) {
+ ((JsonFormatVisitorAware) ser).acceptJsonFormatVisitor(visitor, constructType(type));
+ } else {
+ visitor.expectAnyFormat(constructType(type));
}
- return new JsonSchema((ObjectNode) schemaNode);
}
-
/**
* Method that can be called to see if this serializer provider
* can find a serializer for an instance of given class.
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/impl/FailingSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/impl/FailingSerializer.java
index f62d2d19e4..1ce8bd889f 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/impl/FailingSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/impl/FailingSerializer.java
@@ -1,13 +1,12 @@
package com.fasterxml.jackson.databind.ser.impl;
import java.io.IOException;
-import java.lang.reflect.Type;
import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
/**
@@ -35,9 +34,8 @@ public void serialize(Object value, JsonGenerator jgen, SerializerProvider provi
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return null;
+ ;
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/impl/IndexedStringListSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/impl/IndexedStringListSerializer.java
index fce74ea756..6311e0278f 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/impl/IndexedStringListSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/impl/IndexedStringListSerializer.java
@@ -7,6 +7,8 @@
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor;
+import com.fasterxml.jackson.databind.jsonschema.types.SchemaType;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StaticListSerializerBase;
@@ -44,9 +46,11 @@ public IndexedStringListSerializer(JsonSerializer> ser) {
}
- @Override protected JsonNode contentSchema() {
- return createSchemaNode("string", true);
- }
+ @Override
+ protected void acceptContentVisitor(JsonArrayFormatVisitor visitor) {
+ visitor.itemsFormat(SchemaType.STRING);
+
+ }
/*
/**********************************************************
@@ -147,4 +151,5 @@ private final void serializeUsingCustom(List value, JsonGenerator jgen,
wrapAndThrow(provider, e, value, i);
}
}
+
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/impl/SimpleBeanPropertyFilter.java b/src/main/java/com/fasterxml/jackson/databind/ser/impl/SimpleBeanPropertyFilter.java
index e5f7283568..e6f9cd873f 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/impl/SimpleBeanPropertyFilter.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/impl/SimpleBeanPropertyFilter.java
@@ -5,7 +5,7 @@
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
import com.fasterxml.jackson.databind.ser.BeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.std.BeanSerializerBase;
@@ -79,9 +79,9 @@ public void serializeAsField(Object bean, JsonGenerator jgen,
}
public void depositSchemaProperty(BeanPropertyWriter writer,
- ObjectNode propertiesNode, SerializerProvider provider) {
+ JsonObjectFormatVisitor objectVisitor, SerializerProvider provider) {
if (_propertiesToInclude.contains(writer.getName())) {
- BeanSerializerBase.depositSchemaProperty(writer, propertiesNode, provider);
+ BeanSerializerBase.depositSchemaProperty(writer, objectVisitor);
}
}
}
@@ -111,9 +111,9 @@ public void serializeAsField(Object bean, JsonGenerator jgen,
}
public void depositSchemaProperty(BeanPropertyWriter writer,
- ObjectNode propertiesNode, SerializerProvider provider) {
+ JsonObjectFormatVisitor objectVisitor, SerializerProvider provider) {
if (!_propertiesToExclude.contains(writer.getName())) {
- BeanSerializerBase.depositSchemaProperty(writer, propertiesNode, provider);
+ BeanSerializerBase.depositSchemaProperty(writer, objectVisitor);
}
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/impl/StringArraySerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/impl/StringArraySerializer.java
index 8e69ad5b64..aa559275e5 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/impl/StringArraySerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/impl/StringArraySerializer.java
@@ -1,13 +1,14 @@
package com.fasterxml.jackson.databind.ser.impl;
import java.io.IOException;
-import java.lang.reflect.Type;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.jsonschema.types.SchemaType;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.ContainerSerializer;
@@ -169,10 +170,8 @@ private void serializeContentsSlow(String[] value, JsonGenerator jgen, Serialize
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("array", true);
- o.put("items", createSchemaNode("string"));
- return o;
+ visitor.expectArrayFormat(null).itemsFormat(SchemaType.STRING);
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/impl/StringCollectionSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/impl/StringCollectionSerializer.java
index 3fbc406ad2..3fbf7d4395 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/impl/StringCollectionSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/impl/StringCollectionSerializer.java
@@ -7,6 +7,8 @@
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor;
+import com.fasterxml.jackson.databind.jsonschema.types.SchemaType;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StaticListSerializerBase;
@@ -44,9 +46,11 @@ protected StringCollectionSerializer(JsonSerializer> ser)
_serializer = (JsonSerializer) ser;
}
- @Override protected JsonNode contentSchema() {
- return createSchemaNode("string", true);
- }
+ @Override
+ protected void acceptContentVisitor(JsonArrayFormatVisitor visitor) {
+ visitor.itemsFormat(SchemaType.STRING);
+
+ }
/*
/**********************************************************
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnknownSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnknownSerializer.java
index 392d09acb7..d434bc74e4 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnknownSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnknownSerializer.java
@@ -1,11 +1,11 @@
package com.fasterxml.jackson.databind.ser.impl;
import java.io.IOException;
-import java.lang.reflect.Type;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
@@ -42,8 +42,8 @@ public final void serializeWithType(Object value, JsonGenerator jgen, Serializer
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException {
- return null;
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) {
+ visitor.expectAnyFormat(typeHint);
}
protected void failForEmpty(Object value) throws JsonMappingException
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/ArraySerializerBase.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/ArraySerializerBase.java
index 15073c3057..7801c82743 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/ArraySerializerBase.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/ArraySerializerBase.java
@@ -2,11 +2,13 @@
import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
-import com.fasterxml.jackson.databind.ser.*;
+import com.fasterxml.jackson.databind.ser.ContainerSerializer;
/**
* Intermediate base class for serializers used for various
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/AsArraySerializerBase.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/AsArraySerializerBase.java
index 813bf99fd0..335dbe4f71 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/AsArraySerializerBase.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/AsArraySerializerBase.java
@@ -4,13 +4,18 @@
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.jsonschema.JsonSchema;
-import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
-import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.ContainerSerializer;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap;
@@ -166,24 +171,24 @@ protected abstract void serializeContents(T value, JsonGenerator jgen, Serialize
throws IOException, JsonGenerationException;
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
/* 15-Jan-2010, tatu: This should probably be rewritten, given that
* more information about content type is actually being explicitly
* passed. So there should be less need to try to re-process that
* information.
*/
- ObjectNode o = createSchemaNode("array", true);
+ //ObjectNode o = createSchemaNode("array", true);
+ JsonArrayFormatVisitor arrayVisitor =
+ visitor.expectArrayFormat(typeHint);
JavaType contentType = null;
if (typeHint != null) {
- JavaType javaType = provider.constructType(typeHint);
- contentType = javaType.getContentType();
+ contentType = typeHint.getContentType();
if (contentType == null) { // could still be parametrized (Iterators)
if (typeHint instanceof ParameterizedType) {
Type[] typeArgs = ((ParameterizedType) typeHint).getActualTypeArguments();
if (typeArgs.length == 1) {
- contentType = provider.constructType(typeArgs[0]);
+ contentType = visitor.getProvider().constructType(typeArgs[0]);
}
}
}
@@ -193,19 +198,8 @@ public JsonNode getSchema(SerializerProvider provider, Type typeHint)
}
if (contentType != null) {
JsonNode schemaNode = null;
- // 15-Oct-2010, tatu: We can't serialize plain Object.class; but what should it produce here? Untyped?
- if (contentType.getRawClass() != Object.class) {
- JsonSerializer ser = provider.findValueSerializer(contentType, _property);
- if (ser instanceof SchemaAware) {
- schemaNode = ((SchemaAware) ser).getSchema(provider, null);
- }
- }
- if (schemaNode == null) {
- schemaNode = JsonSchema.getDefaultSchemaNode();
- }
- o.put("items", schemaNode);
+ arrayVisitor.itemsFormat(contentType);
}
- return o;
}
protected final JsonSerializer _findAndAddDynamic(PropertySerializerMap map,
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java
index 4fdc52dc8b..7a3c834f80 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java
@@ -1,25 +1,38 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashSet;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
-import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.io.SerializedString;
-
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.AnnotationIntrospector;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.ObjectIdInfo;
-import com.fasterxml.jackson.databind.jsonschema.JsonSchema;
-import com.fasterxml.jackson.databind.jsonschema.JsonSerializableSchema;
-import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorAware;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fasterxml.jackson.databind.ser.*;
+import com.fasterxml.jackson.databind.ser.AnyGetterWriter;
+import com.fasterxml.jackson.databind.ser.BeanPropertyFilter;
+import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
+import com.fasterxml.jackson.databind.ser.BeanSerializerBuilder;
+import com.fasterxml.jackson.databind.ser.ContainerSerializer;
+import com.fasterxml.jackson.databind.ser.ContextualSerializer;
+import com.fasterxml.jackson.databind.ser.FilterProvider;
+import com.fasterxml.jackson.databind.ser.ResolvableSerializer;
import com.fasterxml.jackson.databind.ser.impl.ObjectIdWriter;
import com.fasterxml.jackson.databind.ser.impl.PropertyBasedObjectIdGenerator;
import com.fasterxml.jackson.databind.ser.impl.WritableObjectId;
@@ -35,7 +48,7 @@
public abstract class BeanSerializerBase
extends StdSerializer
implements ContextualSerializer, ResolvableSerializer,
- SchemaAware
+ JsonFormatVisitorAware
{
final protected static BeanPropertyWriter[] NO_PROPS = new BeanPropertyWriter[0];
@@ -626,45 +639,49 @@ protected BeanPropertyFilter findFilter(SerializerProvider provider)
return filter;
}
- @Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("object", true);
- // [JACKSON-813]: Add optional JSON Schema id attribute, if found
- // NOTE: not optimal, does NOT go through AnnotationIntrospector etc:
- JsonSerializableSchema ann = _handledType.getAnnotation(JsonSerializableSchema.class);
- if (ann != null) {
- String id = ann.id();
- if (id != null && id.length() > 0) {
- o.put("id", id);
- }
- }
+ //deposit your output format
+ JsonObjectFormatVisitor objectVisitor = visitor.expectObjectFormat(typeHint);
- //todo: should the classname go in the title?
- //o.put("title", _className);
- ObjectNode propertiesNode = o.objectNode();
- final BeanPropertyFilter filter;
if (_propertyFilterId != null) {
- filter = findFilter(provider);
- } else {
- filter = null;
- }
+ try {
+ BeanPropertyFilter filter = findFilter(visitor.getProvider());
+ for (int i = 0; i < _props.length; i++) {
+ BeanPropertyWriter prop = _props[i];
+ filter.depositSchemaProperty(prop, objectVisitor, visitor.getProvider());
+ }
+ return;
+ } catch (JsonMappingException e) {
+ // TODO Auto-generated catch block
+
+ }
+ }
for (int i = 0; i < _props.length; i++) {
BeanPropertyWriter prop = _props[i];
- if (filter != null) {
- filter.depositSchemaProperty(prop, propertiesNode, provider);
- continue;
- }
- depositSchemaProperty(prop, propertiesNode, provider);
+ JavaType propType = prop.getSerializationType();
+ BeanSerializerBase.depositSchemaProperty(prop, objectVisitor);
}
- o.put("properties", propertiesNode);
- return o;
}
/**
+ * Attempt to add the output of the given {@link BeanPropertyWriter} in the given {@link ObjectNode}.
+ * Otherwise, add the default schema {@link JsonNode} in place of the writer's output
+ *
+ * @param writer Bean property serializer to use to create schema value
+ * @param propertiesNode Node which the given property would exist within
+ */
+ public static void depositSchemaProperty(BeanPropertyWriter writer, JsonObjectFormatVisitor objectVisitor) {
+ if (isPropertyRequired(writer, objectVisitor.getProvider())) {
+ objectVisitor.property(writer);
+ } else {
+ objectVisitor.optionalProperty(writer);
+ }
+ }
+
+ /**
* Determines if a bean property is required, as determined by
* {@link com.fasterxml.jackson.databind.AnnotationIntrospector#hasRequiredMarker}.
*
@@ -678,45 +695,5 @@ public static boolean isPropertyRequired(final BeanPropertyWriter prop, final Se
return (value == null) ? false : value.booleanValue();
}
- /**
- * Attempt to add the output of the given {@link BeanPropertyWriter} in the given {@link ObjectNode}.
- * Otherwise, add the default schema {@link JsonNode} in place of the writer's output
- *
- * @param writer Bean property serializer to use to create schema value
- * @param propertiesNode Node which the given property would exist within
- * @param provider Provider that can be used for accessing dynamic aspects of serialization
- * processing
- *
- * {@link BeanPropertyFilter#depositSchemaProperty(BeanPropertyWriter, ObjectNode, SerializerProvider)}
- */
- public static void depositSchemaProperty(BeanPropertyWriter writer, ObjectNode propertiesNode, SerializerProvider provider)
- {
- JavaType propType = writer.getSerializationType();
- // 03-Dec-2010, tatu: SchemaAware REALLY should use JavaType, but alas it doesn't...
- Type hint = (propType == null) ? writer.getGenericPropertyType() : propType.getRawClass();
- JsonNode schemaNode;
- // Maybe it already has annotated/statically configured serializer?
- JsonSerializer ser = writer.getSerializer();
-
- try {
- if (ser == null) { // nope
- Class> serType = writer.getRawSerializationType();
- if (serType == null) {
- serType = writer.getPropertyType();
- }
- ser = provider.findValueSerializer(serType, writer);
- }
- boolean isOptional = !BeanSerializerBase.isPropertyRequired(writer, provider);
- if (ser instanceof SchemaAware) {
- schemaNode = ((SchemaAware) ser).getSchema(provider, hint, isOptional) ;
- } else {
- schemaNode = JsonSchema.getDefaultSchemaNode();
- }
- } catch (JsonMappingException e) {
- schemaNode = JsonSchema.getDefaultSchemaNode();
- // TODO: handle in better way (why not throw?)
- }
- propertiesNode.put(writer.getName(), schemaNode);
- }
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/BooleanSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/BooleanSerializer.java
index 56c456fd6d..3d87cc4118 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/BooleanSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/BooleanSerializer.java
@@ -1,14 +1,13 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
-
-import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
/**
* Serializer used for primitive boolean, as well as java.util.Boolean
@@ -41,8 +40,8 @@ public void serialize(Boolean value, JsonGenerator jgen, SerializerProvider prov
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("boolean", !_forPrimitive);
+ visitor.expectBooleanFormat(typeHint);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/CalendarSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/CalendarSerializer.java
index 847a93b298..eb4c77f702 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/CalendarSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/CalendarSerializer.java
@@ -4,8 +4,8 @@
import java.text.DateFormat;
import java.util.Calendar;
-import com.fasterxml.jackson.core.*;
-
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/CollectionSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/CollectionSerializer.java
index 2e85d39277..06e1b89a58 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/CollectionSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/CollectionSerializer.java
@@ -4,7 +4,8 @@
import java.util.Collection;
import java.util.Iterator;
-import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/DateSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/DateSerializer.java
index 8834edd22d..6ea25e0921 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/DateSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/DateSerializer.java
@@ -2,11 +2,11 @@
import java.io.IOException;
import java.text.DateFormat;
-import java.util.*;
+import java.util.Date;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
/**
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/DateTimeSerializerBase.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/DateTimeSerializerBase.java
index 59a2d5e650..424cebed8a 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/DateTimeSerializerBase.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/DateTimeSerializerBase.java
@@ -1,7 +1,6 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Locale;
@@ -10,8 +9,15 @@
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.introspect.Annotated;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonValueFormat;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.util.StdDateFormat;
@@ -100,17 +106,20 @@ public boolean isEmpty(T value) {
protected abstract long _timestamp(T value);
- @Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
//todo: (ryan) add a format for the date in the schema?
boolean asNumber = _useTimestamp;
if (!asNumber) {
if (_customFormat == null) {
- asNumber = provider.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+ asNumber = visitor.getProvider().isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
}
- return createSchemaNode(asNumber ? "number" : "string", true);
+ if (asNumber) {
+ visitor.expectNumberFormat(typeHint).format(JsonValueFormat.UTC_MILLISEC);
+ } else {
+ visitor.expectStringFormat(typeHint).format(JsonValueFormat.DATE_TIME);
+ }
}
/*
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/EnumMapSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/EnumMapSerializer.java
index faf39db6ee..92fdbb6913 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/EnumMapSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/EnumMapSerializer.java
@@ -3,15 +3,20 @@
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
-import java.util.*;
+import java.util.EnumMap;
+import java.util.Map;
-import com.fasterxml.jackson.core.*;
-
-
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
-import com.fasterxml.jackson.databind.jsonschema.JsonSchema;
-import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorAware;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -250,27 +255,31 @@ protected void serializeContentsUsing(EnumMap extends Enum>,?> value, JsonGe
@SuppressWarnings("unchecked")
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("object", true);
+ JsonObjectFormatVisitor objectVisitor = visitor.expectObjectFormat(typeHint);
if (typeHint instanceof ParameterizedType) {
Type[] typeArgs = ((ParameterizedType) typeHint).getActualTypeArguments();
if (typeArgs.length == 2) {
- JavaType enumType = provider.constructType(typeArgs[0]);
- JavaType valueType = provider.constructType(typeArgs[1]);
+ JavaType enumType = visitor.getProvider().constructType(typeArgs[0]);
+ JavaType valueType = visitor.getProvider().constructType(typeArgs[1]);
ObjectNode propsNode = JsonNodeFactory.instance.objectNode();
Class> enumClass = (Class>) enumType.getRawClass();
for (Enum> enumValue : enumClass.getEnumConstants()) {
- JsonSerializer ser = provider.findValueSerializer(valueType.getRawClass(), _property);
- JsonNode schemaNode = (ser instanceof SchemaAware) ?
- ((SchemaAware) ser).getSchema(provider, null) :
- JsonSchema.getDefaultSchemaNode();
- propsNode.put(provider.getConfig().getAnnotationIntrospector().findEnumValue((Enum>)enumValue), schemaNode);
+ JsonSerializer ser;
+ String name = visitor.getProvider().getConfig().getAnnotationIntrospector().findEnumValue((Enum>)enumValue);
+ try {
+ ser = visitor.getProvider().findValueSerializer(valueType.getRawClass(), _property);
+ if (ser instanceof JsonFormatVisitorAware) {
+ objectVisitor.property(name, (JsonFormatVisitorAware) ser, valueType);
+ }
+ continue;
+ } catch (JsonMappingException e) {
+ //TODO: log error
+ }
+ objectVisitor.property(name);
}
- o.put("properties", propsNode);
}
}
- return o;
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/EnumSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/EnumSerializer.java
index 3b908ee264..8573d172c0 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/EnumSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/EnumSerializer.java
@@ -1,19 +1,27 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Set;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
-import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.io.SerializedString;
-
-
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.AnnotationIntrospector;
+import com.fasterxml.jackson.databind.BeanDescription;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializationConfig;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.introspect.Annotated;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.util.EnumValues;
@@ -141,23 +149,23 @@ public final void serialize(Enum> en, JsonGenerator jgen, SerializerProvider p
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
// [JACKSON-684]: serialize as index?
- if (_serializeAsIndex(provider)) {
- return createSchemaNode("integer", true);
- }
- ObjectNode objectNode = createSchemaNode("string", true);
- if (typeHint != null) {
- JavaType type = provider.constructType(typeHint);
- if (type.isEnumType()) {
- ArrayNode enumNode = objectNode.putArray("enum");
- for (SerializedString value : _values.values()) {
- enumNode.add(value.getValue());
- }
- }
- }
- return objectNode;
+ if (visitor.getProvider().isEnabled(SerializationFeature.WRITE_ENUMS_USING_INDEX)) {
+ visitor.expectIntegerFormat(typeHint);
+ } else {
+ JsonStringFormatVisitor stringVisitor = visitor.expectStringFormat(typeHint);
+ if (typeHint != null) {
+ if (typeHint.isEnumType()) {
+ Set enums = new HashSet();
+ for (SerializedString value : _values.values()) {
+ enums.add(value.getValue());
+ }
+ stringVisitor.enumTypes(enums);
+ }
+ }
+ }
}
/*
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/EnumSetSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/EnumSetSerializer.java
index e1edbf6c4b..db7cd7597e 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/EnumSetSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/EnumSetSerializer.java
@@ -3,9 +3,12 @@
import java.io.IOException;
import java.util.EnumSet;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
public class EnumSetSerializer
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/InetAddressSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/InetAddressSerializer.java
index 834a2e7488..8371f775ab 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/InetAddressSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/InetAddressSerializer.java
@@ -3,8 +3,8 @@
import java.io.IOException;
import java.net.InetAddress;
-import com.fasterxml.jackson.core.*;
-
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/IterableSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/IterableSerializer.java
index aa65e10cf0..962864a839 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/IterableSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/IterableSerializer.java
@@ -3,8 +3,8 @@
import java.io.IOException;
import java.util.Iterator;
-import com.fasterxml.jackson.core.*;
-
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/JsonValueSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/JsonValueSerializer.java
index 364957a53e..4557b8543c 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/JsonValueSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/JsonValueSerializer.java
@@ -4,14 +4,19 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
-import com.fasterxml.jackson.databind.jsonschema.JsonSchema;
-import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorAware;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.BeanSerializer;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
@@ -31,7 +36,7 @@
@JacksonStdImpl
public class JsonValueSerializer
extends StdSerializer
- implements ContextualSerializer, SchemaAware
+ implements ContextualSerializer, JsonFormatVisitorAware
{
protected final Method _accessorMethod;
@@ -230,12 +235,13 @@ public void serializeWithType(Object bean, JsonGenerator jgen, SerializerProvide
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return (_valueSerializer instanceof SchemaAware) ?
- ((SchemaAware) _valueSerializer).getSchema(provider, null) :
- JsonSchema.getDefaultSchemaNode();
+ if (_valueSerializer instanceof JsonFormatVisitorAware) {
+ ((JsonFormatVisitorAware) _valueSerializer).acceptJsonFormatVisitor(visitor, null);
+ } else {
+ visitor.expectAnyFormat(typeHint);
+ }
}
protected boolean isNaturalTypeWithStdHandling(Class> rawType, JsonSerializer> ser)
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/MapSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/MapSerializer.java
index 127d4a373d..95e8cadf9b 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/MapSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/MapSerializer.java
@@ -1,16 +1,23 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
-import java.util.*;
-
-import com.fasterxml.jackson.core.*;
-
-
-import com.fasterxml.jackson.databind.*;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.AnnotationIntrospector;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
-import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.ContainerSerializer;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap;
@@ -466,12 +473,9 @@ protected void serializeTypedFields(Map,?> value, JsonGenerator jgen, Serializ
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("object", true);
- //(ryan) even though it's possible to statically determine the "value" type of the map,
- // there's no way to statically determine the keys, so the "Entries" can't be determined.
- return o;
+ visitor.expectObjectFormat(null);
}
/*
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/NonTypedScalarSerializerBase.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/NonTypedScalarSerializerBase.java
index 16050e55b3..2d4da7f72c 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/NonTypedScalarSerializerBase.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/NonTypedScalarSerializerBase.java
@@ -2,8 +2,8 @@
import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/NullSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/NullSerializer.java
index 75fcc0bc09..ec127f4b5b 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/NullSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/NullSerializer.java
@@ -1,12 +1,13 @@
package com.fasterxml.jackson.databind.ser.std;
-import java.lang.reflect.Type;
import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
/**
* This is a simple dummy serializer that will just output literal
@@ -31,9 +32,8 @@ public void serialize(Object value, JsonGenerator jgen, SerializerProvider provi
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("null");
+ visitor.expectNullFormat(typeHint);
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/NumberSerializers.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/NumberSerializers.java
index 81d0bbb1eb..d33e01a5c8 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/NumberSerializers.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/NumberSerializers.java
@@ -1,14 +1,17 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
/**
* Container class for serializers used for handling standard JDK-provided types.
@@ -71,9 +74,9 @@ public void serialize(Integer value, JsonGenerator jgen, SerializerProvider prov
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("integer", true);
+ visitor.expectIntegerFormat(typeHint);
}
}
@@ -98,9 +101,9 @@ public void serialize(Number value, JsonGenerator jgen, SerializerProvider provi
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("integer", true);
+ visitor.expectIntegerFormat(typeHint);
}
}
@@ -120,9 +123,9 @@ public void serialize(Long value, JsonGenerator jgen, SerializerProvider provide
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("number", true);
+ visitor.expectNumberFormat(typeHint);
}
}
@@ -142,9 +145,9 @@ public void serialize(Float value, JsonGenerator jgen, SerializerProvider provid
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("number", true);
+ visitor.expectNumberFormat(typeHint);
}
}
@@ -171,9 +174,9 @@ public void serialize(Double value, JsonGenerator jgen, SerializerProvider provi
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("number", true);
+ visitor.expectNumberFormat(typeHint);
}
}
@@ -219,9 +222,9 @@ public void serialize(Number value, JsonGenerator jgen, SerializerProvider provi
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("number", true);
+ visitor.expectNumberFormat(typeHint);
}
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/ObjectArraySerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/ObjectArraySerializer.java
index 29b301c0a7..7733aede29 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/ObjectArraySerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/ObjectArraySerializer.java
@@ -2,20 +2,20 @@
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Type;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
-import com.fasterxml.jackson.databind.jsonschema.JsonSchema;
-import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
-import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.ContainerSerializer;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap;
-import com.fasterxml.jackson.databind.type.ArrayType;
/**
* Generic serializer for Object arrays (Object[]
).
@@ -295,27 +295,9 @@ public void serializeTypedContents(Object[] value, JsonGenerator jgen, Serialize
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("array", true);
- if (typeHint != null) {
- JavaType javaType = provider.constructType(typeHint);
- if (javaType.isArrayType()) {
- Class> componentType = ((ArrayType) javaType).getContentType().getRawClass();
- // 15-Oct-2010, tatu: We can't serialize plain Object.class; but what should it produce here? Untyped?
- if (componentType == Object.class) {
- o.put("items", JsonSchema.getDefaultSchemaNode());
- } else {
- JsonSerializer ser = provider.findValueSerializer(componentType, _property);
- JsonNode schemaNode = (ser instanceof SchemaAware) ?
- ((SchemaAware) ser).getSchema(provider, null) :
- JsonSchema.getDefaultSchemaNode();
- o.put("items", schemaNode);
- }
- }
- }
- return o;
+ visitor.expectArrayFormat(typeHint).itemsFormat(_elementType);
}
protected final JsonSerializer _findAndAddDynamic(PropertySerializerMap map,
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/RawSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/RawSerializer.java
index 75af722333..99850927c1 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/RawSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/RawSerializer.java
@@ -1,12 +1,14 @@
package com.fasterxml.jackson.databind.ser.std;
-import java.lang.reflect.Type;
import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
/**
@@ -44,9 +46,8 @@ public void serializeWithType(T value, JsonGenerator jgen, SerializerProvider pr
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- // type not really known, but since it is a JSON string:
- return createSchemaNode("string", true);
+ visitor.expectStringFormat(typeHint);
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/SerializableSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/SerializableSerializer.java
index d1c2633fb1..98011dd66c 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/SerializableSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/SerializableSerializer.java
@@ -1,22 +1,17 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
import java.util.concurrent.atomic.AtomicReference;
-import com.fasterxml.jackson.core.*;
-
-
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializable;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
-import com.fasterxml.jackson.databind.jsonschema.JsonSerializableSchema;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fasterxml.jackson.databind.type.TypeFactory;
/**
* Generic handler for types that implement {@link JsonSerializable}.
@@ -51,56 +46,8 @@ public final void serializeWithType(JsonSerializable value, JsonGenerator jgen,
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode objectNode = createObjectNode();
- String schemaType = "any";
- String objectProperties = null;
- String itemDefinition = null;
- if (typeHint != null) {
- Class> rawClass = TypeFactory.rawClass(typeHint);
- if (rawClass.isAnnotationPresent(JsonSerializableSchema.class)) {
- JsonSerializableSchema schemaInfo = rawClass.getAnnotation(JsonSerializableSchema.class);
- schemaType = schemaInfo.schemaType();
- if (!JsonSerializableSchema.NO_VALUE.equals(schemaInfo.schemaObjectPropertiesDefinition())) {
- objectProperties = schemaInfo.schemaObjectPropertiesDefinition();
- }
- if (!JsonSerializableSchema.NO_VALUE.equals(schemaInfo.schemaItemDefinition())) {
- itemDefinition = schemaInfo.schemaItemDefinition();
- }
- }
- }
- /* 19-Mar-2012, tatu: geez, this is butt-ugly abonimation of code...
- * really, really should not require back ref to an ObjectMapper.
- */
- objectNode.put("type", schemaType);
- if (objectProperties != null) {
- try {
- objectNode.put("properties", _getObjectMapper().readTree(objectProperties));
- } catch (IOException e) {
- throw new JsonMappingException("Failed to parse @JsonSerializableSchema.schemaObjectPropertiesDefinition value");
- }
- }
- if (itemDefinition != null) {
- try {
- objectNode.put("items", _getObjectMapper().readTree(itemDefinition));
- } catch (IOException e) {
- throw new JsonMappingException("Failed to parse @JsonSerializableSchema.schemaItemDefinition value");
- }
- }
- // always optional, no need to specify:
- //objectNode.put("required", false);
- return objectNode;
+ visitor.expectAnyFormat(typeHint);
}
-
- private final static synchronized ObjectMapper _getObjectMapper()
- {
- ObjectMapper mapper = _mapperReference.get();
- if (mapper == null) {
- mapper = new ObjectMapper();
- _mapperReference.set(mapper);
- }
- return mapper;
}
-}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/SqlDateSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/SqlDateSerializer.java
index a5d6fb56cd..fdbd2a0759 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/SqlDateSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/SqlDateSerializer.java
@@ -1,14 +1,14 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
-
-import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonValueFormat;
/**
* Compared to regular {@link java.util.Date} serialization, we do use String
@@ -29,9 +29,8 @@ public void serialize(java.sql.Date value, JsonGenerator jgen, SerializerProvide
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- //todo: (ryan) add a format for the date in the schema?
- return createSchemaNode("string", true);
+ visitor.expectStringFormat(typeHint).format(JsonValueFormat.DATE_TIME);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/SqlTimeSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/SqlTimeSerializer.java
index 8e12b425be..2800bcc679 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/SqlTimeSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/SqlTimeSerializer.java
@@ -1,14 +1,14 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
-
-import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonValueFormat;
@JacksonStdImpl
public class SqlTimeSerializer
@@ -24,8 +24,8 @@ public void serialize(java.sql.Time value, JsonGenerator jgen, SerializerProvide
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("string", true);
+ visitor.expectStringFormat(typeHint).format(JsonValueFormat.DATE_TIME);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/StaticListSerializerBase.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/StaticListSerializerBase.java
index fece1eb39b..1aff32344f 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/StaticListSerializerBase.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/StaticListSerializerBase.java
@@ -1,11 +1,10 @@
package com.fasterxml.jackson.databind.ser.std;
-import java.lang.reflect.Type;
-import java.util.*;
+import java.util.Collection;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
/**
* Intermediate base class for Lists, Collections and Arrays
@@ -24,11 +23,9 @@ public boolean isEmpty(T value) {
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("array", true);
- o.put("items", contentSchema());
- return o;
+ acceptContentVisitor(visitor.expectArrayFormat(typeHint));
}
/*
@@ -37,5 +34,5 @@ public JsonNode getSchema(SerializerProvider provider, Type typeHint)
/**********************************************************
*/
- protected abstract JsonNode contentSchema();
+ protected abstract void acceptContentVisitor(JsonArrayFormatVisitor visitor);
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdArraySerializers.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdArraySerializers.java
index c89cf48c97..beac71ed3e 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdArraySerializers.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdArraySerializers.java
@@ -1,15 +1,19 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
import java.util.HashMap;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
+import com.fasterxml.jackson.databind.jsonschema.types.SchemaType;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
-import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.ContainerSerializer;
import com.fasterxml.jackson.databind.type.TypeFactory;
@@ -129,11 +133,9 @@ public void serializeContents(boolean[] value, JsonGenerator jgen, SerializerPro
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("array", true);
- o.put("items", createSchemaNode("boolean"));
- return o;
+ visitor.expectArrayFormat(typeHint).itemsFormat(SchemaType.BOOLEAN);
}
}
@@ -175,12 +177,9 @@ public void serializeWithType(byte[] value, JsonGenerator jgen, SerializerProvid
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("array", true);
- ObjectNode itemSchema = createSchemaNode("string"); //binary values written as strings?
- o.put("items", itemSchema);
- return o;
+ visitor.expectArrayFormat(typeHint).itemsFormat(SchemaType.STRING);
}
}
@@ -241,12 +240,9 @@ public void serializeContents(short[] value, JsonGenerator jgen, SerializerProvi
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- //no "short" type defined by json
- ObjectNode o = createSchemaNode("array", true);
- o.put("items", createSchemaNode("integer"));
- return o;
+ visitor.expectArrayFormat(typeHint).itemsFormat(SchemaType.INTEGER);
}
}
@@ -308,13 +304,9 @@ private final void _writeArrayContents(JsonGenerator jgen, char[] value)
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("array", true);
- ObjectNode itemSchema = createSchemaNode("string");
- itemSchema.put("type", "string");
- o.put("items", itemSchema);
- return o;
+ visitor.expectArrayFormat(typeHint).itemsFormat(SchemaType.STRING);
}
}
@@ -367,11 +359,9 @@ public void serializeContents(int[] value, JsonGenerator jgen, SerializerProvide
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("array", true);
- o.put("items", createSchemaNode("integer"));
- return o;
+ visitor.expectArrayFormat(typeHint).itemsFormat(SchemaType.INTEGER);
}
}
@@ -433,11 +423,9 @@ public void serializeContents(long[] value, JsonGenerator jgen, SerializerProvid
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("array", true);
- o.put("items", createSchemaNode("number", true));
- return o;
+ visitor.expectArrayFormat(typeHint).itemsFormat(SchemaType.NUMBER);
}
}
@@ -500,11 +488,9 @@ public void serializeContents(float[] value, JsonGenerator jgen, SerializerProvi
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("array", true);
- o.put("items", createSchemaNode("number"));
- return o;
+ visitor.expectArrayFormat(typeHint).itemsFormat(SchemaType.NUMBER);
}
}
@@ -557,11 +543,9 @@ public void serializeContents(double[] value, JsonGenerator jgen, SerializerProv
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- ObjectNode o = createSchemaNode("array", true);
- o.put("items", createSchemaNode("number"));
- return o;
+ visitor.expectArrayFormat(typeHint).itemsFormat(SchemaType.NUMBER);
}
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdContainerSerializers.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdContainerSerializers.java
index 5785481faa..c3533e1d50 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdContainerSerializers.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdContainerSerializers.java
@@ -1,11 +1,12 @@
package com.fasterxml.jackson.databind.ser.std;
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.ContainerSerializer;
import com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer;
import com.fasterxml.jackson.databind.ser.impl.IteratorSerializer;
-import com.fasterxml.jackson.databind.ser.std.CollectionSerializer;
/**
* Dummy container class to group standard container serializers: serializers
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdJdkSerializers.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdJdkSerializers.java
index 0f2a52080f..0270ae8c28 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdJdkSerializers.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdJdkSerializers.java
@@ -1,13 +1,23 @@
package com.fasterxml.jackson.databind.ser.std;
-import java.io.*;
-import java.lang.reflect.Type;
-import java.util.*;
-import java.util.concurrent.atomic.*;
-
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.*;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Currency;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.ser.BasicSerializerFactory;
import com.fasterxml.jackson.databind.util.Provider;
@@ -77,9 +87,9 @@ public void serialize(AtomicBoolean value, JsonGenerator jgen, SerializerProvide
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("boolean", true);
+ visitor.expectBooleanFormat(typeHint);
}
}
@@ -96,9 +106,9 @@ public void serialize(AtomicInteger value, JsonGenerator jgen, SerializerProvide
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("integer", true);
+ visitor.expectIntegerFormat(typeHint);
}
}
@@ -115,9 +125,9 @@ public void serialize(AtomicLong value, JsonGenerator jgen, SerializerProvider p
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("integer", true);
+ visitor.expectIntegerFormat(typeHint);
}
}
@@ -134,9 +144,9 @@ public void serialize(AtomicReference> value, JsonGenerator jgen, SerializerPr
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("any", true);
+ visitor.expectAnyFormat(typeHint);
}
}
@@ -163,9 +173,9 @@ public void serialize(File value, JsonGenerator jgen, SerializerProvider provide
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("string", true);
+ visitor.expectStringFormat(typeHint);
}
}
@@ -186,9 +196,9 @@ public void serialize(Class> value, JsonGenerator jgen, SerializerProvider pro
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("string", true);
+ visitor.expectStringFormat(typeHint);
}
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializer.java
index f8401f3d9b..1d64986d84 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializer.java
@@ -1,15 +1,13 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
import java.util.Date;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
/**
* Specialized serializer that can be used as the generic key
@@ -35,9 +33,8 @@ public void serialize(Object value, JsonGenerator jgen, SerializerProvider provi
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("string");
+ visitor.expectStringFormat(typeHint);
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializers.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializers.java
index fe73e800b8..bcb91e89d9 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializers.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializers.java
@@ -4,8 +4,8 @@
import java.util.Calendar;
import java.util.Date;
-import com.fasterxml.jackson.core.*;
-
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdScalarSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdScalarSerializer.java
index aa1ff3e6d0..1387e3d813 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdScalarSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdScalarSerializer.java
@@ -1,13 +1,12 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
public abstract class StdScalarSerializer
@@ -44,9 +43,8 @@ public void serializeWithType(T value, JsonGenerator jgen, SerializerProvider pr
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("string", true);
+ visitor.expectAnyFormat(typeHint);
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdSerializer.java
index ba3e3b8b79..abd487dc21 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/StdSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/StdSerializer.java
@@ -2,24 +2,27 @@
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Type;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
-import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
-import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorAware;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
/**
* Base class used by all standard serializers, and can also
* be used for custom serializers (in fact, this is the recommended
* base class to use).
- * Provides convenience methods for implementing {@link SchemaAware}
+ * Provides convenience methods for implementing {@link JsonFormatVisitorAware}
*/
public abstract class StdSerializer
extends JsonSerializer
- implements SchemaAware
+ implements JsonFormatVisitorAware
{
/**
* Nominal type supported, usually declared type of
@@ -71,57 +74,19 @@ public abstract void serialize(T value, JsonGenerator jgen, SerializerProvider p
/*
/**********************************************************
- /* Helper methods for JSON Schema generation
+ /* Helper methods for JSON JsonSchema generation
/**********************************************************
*/
/**
- * Default implementation simply claims type is "string"; usually
+ * Default implementation specifies no format. This behavior is usually
* overriden by custom serializers.
*/
// @Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException
- {
- return createSchemaNode("string");
- }
-
- /**
- * Default implementation simply claims type is "string"; usually
- * overriden by custom serializers.
- */
-// @Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint, boolean isOptional)
- throws JsonMappingException
- {
- ObjectNode schema = (ObjectNode) getSchema(provider, typeHint);
- if (!isOptional) {
- schema.put("required", !isOptional);
- }
- return schema;
- }
-
- protected ObjectNode createObjectNode() {
- return JsonNodeFactory.instance.objectNode();
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) {
+ visitor.expectAnyFormat(typeHint);
}
-
- protected ObjectNode createSchemaNode(String type)
- {
- ObjectNode schema = createObjectNode();
- schema.put("type", type);
- return schema;
- }
-
- protected ObjectNode createSchemaNode(String type, boolean isOptional)
- {
- ObjectNode schema = createSchemaNode(type);
- // as per [JACKSON-563]. Note that 'required' defaults to false
- if (!isOptional) {
- schema.put("required", !isOptional);
- }
- return schema;
- }
-
+
/*
/**********************************************************
/* Helper methods for exception handling
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/StringSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/StringSerializer.java
index eb142f5d15..ec2911e0be 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/StringSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/StringSerializer.java
@@ -1,13 +1,13 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
/**
* This is the special serializer for regular {@link java.lang.String}s.
@@ -37,8 +37,8 @@ public void serialize(String value, JsonGenerator jgen, SerializerProvider provi
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("string", true);
+ visitor.expectStringFormat(typeHint);
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/TimeZoneSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/TimeZoneSerializer.java
index 71f2bf581a..17eaa67c1c 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/TimeZoneSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/TimeZoneSerializer.java
@@ -3,8 +3,8 @@
import java.io.IOException;
import java.util.TimeZone;
-import com.fasterxml.jackson.core.*;
-
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/ToStringSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/ToStringSerializer.java
index bb65ca3721..1b5acabc65 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/ToStringSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/ToStringSerializer.java
@@ -1,14 +1,13 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
/**
@@ -74,10 +73,9 @@ public void serializeWithType(Object value, JsonGenerator jgen, SerializerProvid
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
- throws JsonMappingException
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
- return createSchemaNode("string", true);
+ visitor.expectStringFormat(typeHint);
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/TokenBufferSerializer.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/TokenBufferSerializer.java
index 73eb789dd6..07a8f2edfd 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/TokenBufferSerializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/TokenBufferSerializer.java
@@ -1,13 +1,13 @@
package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
-import java.lang.reflect.Type;
-import com.fasterxml.jackson.core.*;
-
-import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.util.TokenBuffer;
@@ -53,12 +53,12 @@ public final void serializeWithType(TokenBuffer value, JsonGenerator jgen, Seria
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint)
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
/* 01-Jan-2010, tatu: Not 100% sure what we should say here:
* type is basically not known. This seems closest
* approximation
*/
- return createSchemaNode("any", true);
+ visitor.expectAnyFormat(typeHint);
}
}
diff --git a/src/test/java/com/fasterxml/jackson/databind/jsonschema/TestGenerateJsonSchema.java b/src/test/java/com/fasterxml/jackson/databind/jsonschema/TestGenerateJsonSchema.java
index 58c9534788..43c0f4dd89 100644
--- a/src/test/java/com/fasterxml/jackson/databind/jsonschema/TestGenerateJsonSchema.java
+++ b/src/test/java/com/fasterxml/jackson/databind/jsonschema/TestGenerateJsonSchema.java
@@ -1,13 +1,17 @@
package com.fasterxml.jackson.databind.jsonschema;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.jsonschema.factories.SchemaFactory;
+import com.fasterxml.jackson.databind.jsonschema.factories.SchemaFactoryProvider;
+import com.fasterxml.jackson.databind.jsonschema.types.ObjectSchema;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonSchema;
+import com.fasterxml.jackson.databind.jsonschema.types.ArraySchema.Items;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
@@ -30,7 +34,7 @@ public static class SimpleBean
private String property2;
private String[] property3;
private Collection property4;
- @JsonProperty(required=true)
+ @JsonProperty(required = true)
private String property5;
public int getProperty1()
@@ -88,7 +92,7 @@ public class TrivialBean {
public String name;
}
- @JsonSerializableSchema(id="myType")
+ //@JsonSerializableSchema(id="myType")
public class BeanWithId {
public String value;
}
@@ -107,7 +111,10 @@ public class BeanWithId {
public void testGeneratingJsonSchema()
throws Exception
{
- JsonSchema jsonSchema = MAPPER.generateJsonSchema(SimpleBean.class);
+ ObjectMapper m = new ObjectMapper();
+ SchemaFactoryProvider visitor = new SchemaFactoryProvider();
+ m.acceptJsonFormatVisitor(SimpleBean.class, visitor);
+ JsonSchema jsonSchema = visitor.finalSchema();
assertNotNull(jsonSchema);
@@ -116,33 +123,45 @@ public void testGeneratingJsonSchema()
assertFalse(jsonSchema.equals(null));
assertFalse(jsonSchema.equals("foo"));
- // other basic things
- assertNotNull(jsonSchema.toString());
- assertNotNull(JsonSchema.getDefaultSchemaNode());
-
- ObjectNode root = jsonSchema.getSchemaNode();
- assertEquals("object", root.get("type").asText());
- assertEquals(false, root.path("required").booleanValue());
- JsonNode propertiesSchema = root.get("properties");
- assertNotNull(propertiesSchema);
- JsonNode property1Schema = propertiesSchema.get("property1");
- assertNotNull(property1Schema);
- assertEquals("integer", property1Schema.get("type").asText());
- assertEquals(false, property1Schema.path("required").booleanValue());
- JsonNode property2Schema = propertiesSchema.get("property2");
- assertNotNull(property2Schema);
- assertEquals("string", property2Schema.get("type").asText());
- assertEquals(false, property2Schema.path("required").booleanValue());
- JsonNode property3Schema = propertiesSchema.get("property3");
- assertNotNull(property3Schema);
- assertEquals("array", property3Schema.get("type").asText());
- assertEquals(false, property3Schema.path("required").booleanValue());
- assertEquals("string", property3Schema.get("items").get("type").asText());
- JsonNode property4Schema = propertiesSchema.get("property4");
- assertNotNull(property4Schema);
- assertEquals("array", property4Schema.get("type").asText());
- assertEquals(false, property4Schema.path("required").booleanValue());
- assertEquals("number", property4Schema.get("items").get("type").asText());
+ assertTrue(jsonSchema.isObjectSchema());
+ ObjectSchema object = jsonSchema.asObjectSchema();
+ assertNotNull(object);
+ Map properties = object.getProperties();
+ assertNotNull(properties);
+ JsonSchema prop1 = properties.get("property1");
+ assertNotNull(prop1);
+ assertTrue(prop1.isIntegerSchema());
+ assertNull(prop1.getRequired());
+
+ JsonSchema prop2 = properties.get("property2");
+ assertNotNull(prop2);
+ assertTrue(prop2.isStringSchema());
+ assertNull(prop2.getRequired());
+
+ JsonSchema prop3 = properties.get("property3");
+ assertNotNull(prop3);
+ assertTrue(prop3.isArraySchema());
+ assertNull(prop3.getRequired());
+ Items items = prop3.asArraySchema().getItems();
+ assertTrue(items.isSingleItems());
+ JsonSchema itemType = items.asSingleItems().getSchema();
+ assertNotNull(itemType);
+ assertTrue(itemType.isStringSchema());
+
+ JsonSchema prop4 = properties.get("property4");
+ assertNotNull(prop4);
+ assertTrue(prop4.isArraySchema());
+ assertNull(prop4.getRequired());
+ items = prop4.asArraySchema().getItems();
+ assertTrue(items.isSingleItems());
+ itemType = items.asSingleItems().getSchema();
+ assertNotNull(itemType);
+ assertTrue(itemType.isNumberSchema());
+
+ JsonSchema prop5 = properties.get("property5");
+ assertNotNull(prop5);
+ assertTrue(prop5.getRequired());
+
}
@JsonFilter("filteredBean")
@@ -167,10 +186,19 @@ protected static class FilteredBean {
public void testGeneratingJsonSchemaWithFilters() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.setFilters(secretFilterProvider);
- JsonSchema schema = mapper.generateJsonSchema(FilteredBean.class);
- JsonNode node = schema.getSchemaNode().get("properties");
- assertTrue(node.has("obvious"));
- assertFalse(node.has("secret"));
+ SchemaFactoryProvider visitor = new SchemaFactoryProvider();
+ mapper.acceptJsonFormatVisitor(FilteredBean.class, visitor);
+ JsonSchema jsonSchema = visitor.finalSchema();
+ assertNotNull(jsonSchema);
+ assertTrue(jsonSchema.isObjectSchema());
+ ObjectSchema object = jsonSchema.asObjectSchema();
+ assertNotNull(object);
+ Map properties = object.getProperties();
+ assertNotNull(properties);
+ JsonSchema obvious = properties.get("obvious");
+ assertNotNull(obvious);
+ assertTrue(obvious.isStringSchema());
+ assertNull(properties.get("secret"));
}
/**
@@ -180,14 +208,16 @@ public void testGeneratingJsonSchemaWithFilters() throws Exception {
public void testSchemaSerialization()
throws Exception
{
- JsonSchema jsonSchema = MAPPER.generateJsonSchema(SimpleBean.class);
- Map result = writeAndMap(MAPPER, jsonSchema);
- assertNotNull(result);
- // no need to check out full structure, just basics...
- assertEquals("object", result.get("type"));
- // only add 'required' if it is true...
- assertNull(result.get("required"));
- assertNotNull(result.get("properties"));
+ SchemaFactoryProvider visitor = new SchemaFactoryProvider();
+ MAPPER.acceptJsonFormatVisitor(SimpleBean.class, visitor);
+ JsonSchema jsonSchema = visitor.finalSchema();
+ Map result = writeAndMap(MAPPER, jsonSchema);
+ assertNotNull(result);
+ // no need to check out full structure, just basics...
+ assertEquals("object", result.get("type"));
+ // only add 'required' if it is true...
+ assertNull(result.get("required"));
+ assertNotNull(result.get("properties"));
}
public void testInvalidCall()
@@ -195,7 +225,9 @@ public void testInvalidCall()
{
// not ok to pass null
try {
- MAPPER.generateJsonSchema(null);
+ SchemaFactoryProvider visitor = new SchemaFactoryProvider();
+ MAPPER.acceptJsonFormatVisitor(null, visitor);
+ JsonSchema jsonSchema = visitor.finalSchema();
fail("Should have failed");
} catch (IllegalArgumentException iae) {
verifyException(iae, "class must be provided");
@@ -207,19 +239,30 @@ public void testInvalidCall()
*/
public void testThatObjectsHaveNoItems() throws Exception
{
- JsonSchema jsonSchema = MAPPER.generateJsonSchema(TrivialBean.class);
- String json = jsonSchema.toString().replaceAll("\"", "'");
+ SchemaFactoryProvider visitor = new SchemaFactoryProvider();
+ MAPPER.acceptJsonFormatVisitor(TrivialBean.class, visitor);
+ JsonSchema jsonSchema = visitor.finalSchema();
+ Map result = writeAndMap(MAPPER, jsonSchema);
// can we count on ordering being stable? I think this is true with current ObjectNode impl
// as perh [JACKSON-563]; 'required' is only included if true
- assertEquals("{'type':'object','properties':{'name':{'type':'string'}}}",
- json);
+ assertFalse(result.containsKey("items"));
+
}
- public void testSchemaId() throws Exception
+ @SuppressWarnings({ "unchecked", "rawtypes", "serial" })
+ public void testSchemaId() throws Exception
{
- JsonSchema jsonSchema = MAPPER.generateJsonSchema(BeanWithId.class);
- String json = jsonSchema.toString().replaceAll("\"", "'");
- assertEquals("{'type':'object','id':'myType','properties':{'value':{'type':'string'}}}",
- json);
+ SchemaFactoryProvider visitor = new SchemaFactoryProvider();
+ MAPPER.acceptJsonFormatVisitor(BeanWithId.class, visitor);
+ JsonSchema jsonSchema = visitor.finalSchema();
+ Map result = writeAndMap(MAPPER, jsonSchema);
+
+ assertEquals(new HashMap() {{
+ put("type", "object");
+ put("properties",
+ new HashMap(){{ put("value",
+ new HashMap() {{ put("type", "string");}}
+ );}}
+ );}}, result);
}
}
diff --git a/src/test/java/com/fasterxml/jackson/databind/jsonschema/TestReadJsonSchema.java b/src/test/java/com/fasterxml/jackson/databind/jsonschema/TestReadJsonSchema.java
index ef3513b63d..e05e887912 100644
--- a/src/test/java/com/fasterxml/jackson/databind/jsonschema/TestReadJsonSchema.java
+++ b/src/test/java/com/fasterxml/jackson/databind/jsonschema/TestReadJsonSchema.java
@@ -3,7 +3,9 @@
import java.util.*;
import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.jsonschema.JsonSchema;
+import com.fasterxml.jackson.databind.jsonschema.factories.SchemaFactory;
+import com.fasterxml.jackson.databind.jsonschema.factories.SchemaFactoryProvider;
+import com.fasterxml.jackson.databind.jsonschema.types.JsonSchema;
/**
* Trivial test to ensure {@link JsonSchema} can be also deserialized
@@ -50,12 +52,14 @@ static class Schemable {
public void testDeserializeSimple() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
- JsonSchema schema = mapper.generateJsonSchema(Schemable.class);
- assertNotNull(schema);
+ SchemaFactoryProvider visitor = new SchemaFactoryProvider();
+ mapper.acceptJsonFormatVisitor(Schemable.class, visitor);
+ JsonSchema jsonSchema = visitor.finalSchema();
+ assertNotNull(jsonSchema);
- String schemaStr = mapper.writeValueAsString(schema);
+ String schemaStr = mapper.writeValueAsString(jsonSchema);
assertNotNull(schemaStr);
JsonSchema result = mapper.readValue(schemaStr, JsonSchema.class);
- assertEquals("Trying to read from '"+schemaStr+"'", schema, result);
+ assertEquals("Trying to read from '"+schemaStr+"'", jsonSchema, result);
}
}
diff --git a/src/test/java/com/fasterxml/jackson/databind/module/TestSimpleModule.java b/src/test/java/com/fasterxml/jackson/databind/module/TestSimpleModule.java
index 1400401357..a92ccd5d71 100644
--- a/src/test/java/com/fasterxml/jackson/databind/module/TestSimpleModule.java
+++ b/src/test/java/com/fasterxml/jackson/databind/module/TestSimpleModule.java
@@ -1,13 +1,13 @@
package com.fasterxml.jackson.databind.module;
import java.io.IOException;
-import java.lang.reflect.Type;
import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.module.SimpleDeserializers;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.module.SimpleSerializers;
@@ -52,8 +52,8 @@ public void serialize(CustomBean value, JsonGenerator jgen, SerializerProvider p
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException {
- return null;
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) {
+ visitor.expectAnyFormat(typeHint);
}
}
@@ -86,8 +86,8 @@ public void serialize(SimpleEnum value, JsonGenerator jgen, SerializerProvider p
}
@Override
- public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException {
- return null;
+ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) {
+ visitor.expectAnyFormat(typeHint);
}
}