diff --git a/.gitignore b/.gitignore
index c3bde803..928d242b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@ target
*.ipr
*.iws
.idea
+/bin/
diff --git a/pom.xml b/pom.xml
index 25e8da84..d259401e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,10 +8,10 @@
com.fasterxml.jackson.module
jackson-module-jsonSchema
jackson-module-jsonSchema
- 2.9.3-SNAPSHOT
+ 4.0.0-SNAPSHOT
bundle
Add-on module for Jackson (http://jackson.codehaus.org) to support
-JSON Schema (http://tools.ietf.org/html/draft-zyp-json-schema-03) version 3 generation.
+JSON Schema http://json-schema.org/ Currently v3 and start of v4 support.
https://github.com/FasterXML/jackson-module-jsonSchema
@@ -49,7 +49,19 @@ JSON Schema (http://tools.ietf.org/html/draft-zyp-json-schema-03) version 3 gene
javax.validation
validation-api
- 1.1.0.Final
+ 2.0.0.Final
+
+
+ org.hibernate
+ hibernate-validator
+ 6.0.4.Final
+ provided
+
+
+ org.glassfish
+ javax.el
+ 3.0.1-b08
+ provided
@@ -57,7 +69,12 @@ JSON Schema (http://tools.ietf.org/html/draft-zyp-json-schema-03) version 3 gene
junit
test
-
+
+ org.hamcrest
+ hamcrest-all
+ 1.3
+ test
+
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/JsonSchema.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/JsonSchema.java
index 3461a314..015aad30 100644
--- a/src/main/java/com/fasterxml/jackson/module/jsonSchema/JsonSchema.java
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/JsonSchema.java
@@ -1,12 +1,32 @@
package com.fasterxml.jackson.module.jsonSchema;
-import com.fasterxml.jackson.annotation.*;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+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.BeanProperty;
import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes;
-import com.fasterxml.jackson.module.jsonSchema.types.*;
+import com.fasterxml.jackson.module.jsonSchema.factories.WrapperFactory.JsonSchemaVersion;
+import com.fasterxml.jackson.module.jsonSchema.types.AnySchema;
+import com.fasterxml.jackson.module.jsonSchema.types.ArraySchema;
+import com.fasterxml.jackson.module.jsonSchema.types.BooleanSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.ContainerTypeSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.IntegerSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.NullSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.NumberSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.ObjectSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.SimpleTypeSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.StringSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.UnionTypeSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.ValueTypeSchema;
/**
* The type wraps the json schema specification at :
@@ -33,7 +53,7 @@
* "id":{
* "type":"number",
* "description":"Product identifier",
- * "required":true
+ * "required":true
* },
* "name":{
* "description":"Name of the product",
@@ -73,6 +93,21 @@
@JsonTypeIdResolver(JsonSchemaIdResolver.class)
public abstract class JsonSchema
{
+ @JsonIgnore
+ protected JsonSchemaVersion version;
+
+ protected JsonSchema() {
+ //jackson deserialization only
+ }
+
+ protected JsonSchema(JsonSchemaVersion version) {
+ this.version = version;
+ }
+
+ protected JsonSchema(JsonSchemaVersion version, boolean set$Schema) {
+ this.version = version;
+ }
+
/**
* 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
@@ -141,11 +176,15 @@ public abstract class JsonSchema
*/
private JsonSchema[] extendsextends;
- /**
- * This attribute indicates if the instance must have a value, and not be
- * undefined. This is false by default, making the instance optional.
- */
- @JsonProperty
+ /**
+ * This attribute indicates if the instance must have a value, and not be
+ * undefined. This is false by default, making the instance optional.
+ * Available in Draft V3 spec ONLY.
+ *
+ * @deprecated Since 2.9 - Use setRequired on ObjectSchema from Draft V4 onwards.
+ */
+ @Deprecated
+ @JsonProperty
private Boolean required = null;
/**
@@ -161,7 +200,10 @@ public abstract class JsonSchema
*/
private String description;
- protected JsonSchema() { }
+ /**
+ * Map to hold items that are not part of the official spec but may want to be added.
+ */
+ private Map nonStandardProperties = new LinkedHashMap<>();
/**
* Attempt to return this JsonSchema as an {@link AnySchema}
@@ -279,7 +321,11 @@ public ValueTypeSchema asValueTypeSchema() {
return null;
}
- public String getId() {
+ public JsonSchemaVersion getVersion() {
+ return version;
+ }
+
+ public String getId() {
return id;
}
@@ -311,6 +357,15 @@ public String getDescription() {
return description;
}
+ @JsonAnyGetter
+ public Map getNonStandardProperties() {
+ return nonStandardProperties;
+ }
+
+ public String getNonStandardProperty(String propertyName) {
+ return nonStandardProperties.get(propertyName);
+ }
+
@JsonIgnore
public abstract JsonFormatTypes getType();
@@ -441,6 +496,9 @@ public boolean isValueTypeSchema() {
public void set$schema(String $schema) {
this.$schema = $schema;
+ if (version == null) {
+ this.version = JsonSchemaVersion.fromSchemaString($schema).orElse(null);
+ }
}
public void setDisallow(JsonSchema[] disallow) {
@@ -456,6 +514,9 @@ public void setId(String id) {
}
public void setRequired(Boolean required) {
+ if (!JsonSchemaVersion.DRAFT_V3.equals(version)) {
+ throw new RuntimeException("You can only set the required boolean on Draft V3. You have: " + version);
+ }
this.required = required;
}
@@ -467,6 +528,11 @@ public void setDescription(String description) {
this.description = description;
}
+ @JsonAnySetter
+ public void addNonStandardProperty(String key, String value) {
+ nonStandardProperties.put(key, value);
+ }
+
/**
* Override this to add information specific to the property of bean
* For example, bean validation annotations could be used to specify
@@ -478,33 +544,34 @@ public void enrichWithBeanProperty(BeanProperty beanProperty) {
}
/**
- * Create a schema which verifies only that an object is of the given format.
- * @param format the format to expect
- * @return the schema verifying the given format
- */
- public static JsonSchema minimalForFormat(JsonFormatTypes format)
+ * Create a schema which verifies only that an object is of the given format.
+ * @param jsonVersion
+ * @param format the format to expect
+ * @return the schema verifying the given format
+ */
+ public static JsonSchema minimalForFormat(JsonSchemaVersion jsonVersion, JsonFormatTypes format)
{
if (format != null) {
switch (format) {
case ARRAY:
- return new ArraySchema();
+ return new ArraySchema(jsonVersion);
case OBJECT:
- return new ObjectSchema();
+ return new ObjectSchema(jsonVersion);
case BOOLEAN:
- return new BooleanSchema();
+ return new BooleanSchema(jsonVersion);
case INTEGER:
- return new IntegerSchema();
+ return new IntegerSchema(jsonVersion);
case NUMBER:
- return new NumberSchema();
+ return new NumberSchema(jsonVersion);
case STRING:
- return new StringSchema();
+ return new StringSchema(jsonVersion);
case NULL:
- return new NullSchema();
+ return new NullSchema(jsonVersion);
case ANY:
default:
}
}
- return new AnySchema();
+ return new AnySchema(jsonVersion);
}
@Override
@@ -522,7 +589,7 @@ protected boolean _equals(JsonSchema that)
// 27-Apr-2015, tatu: Should not need to check type explicitly
// && equals(getType(), getType())
- && equals(getRequired(), that.getRequired())
+ && ((JsonSchemaVersion.DRAFT_V3.equals(version)) ? equals(getRequired(), that.getRequired()) : true)
&& equals(getReadonly(), that.getReadonly())
&& equals(get$ref(), that.get$ref())
&& equals(get$schema(), that.get$schema())
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/annotation/JsonSchemaTitle.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/annotation/JsonSchemaTitle.java
new file mode 100755
index 00000000..86c6df90
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/annotation/JsonSchemaTitle.java
@@ -0,0 +1,13 @@
+package com.fasterxml.jackson.module.jsonSchema.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Target({ METHOD, FIELD, PARAMETER, TYPE })
+@Retention(RUNTIME)
+public @interface JsonSchemaTitle {
+ String value();
+}
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/annotation/NonStandardProperties.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/annotation/NonStandardProperties.java
new file mode 100644
index 00000000..7622e49d
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/annotation/NonStandardProperties.java
@@ -0,0 +1,21 @@
+package com.fasterxml.jackson.module.jsonSchema.annotation;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Meant to add items to the schema that are not currently part of the schema.
+ *
+ * @author amerritt
+ */
+@Target({ METHOD, FIELD, PARAMETER, TYPE })
+@Retention(RUNTIME)
+public @interface NonStandardProperties {
+ NonStandardProperty[] value();
+}
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/annotation/NonStandardProperty.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/annotation/NonStandardProperty.java
new file mode 100644
index 00000000..5799ccb9
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/annotation/NonStandardProperty.java
@@ -0,0 +1,24 @@
+package com.fasterxml.jackson.module.jsonSchema.annotation;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Meant to add items to the schema that are not currently part of the schema.
+ *
+ * @author amerritt
+ */
+@Target({ METHOD, FIELD, PARAMETER, TYPE })
+@Retention(RUNTIME)
+@Repeatable(NonStandardProperties.class)
+public @interface NonStandardProperty {
+ String name();
+ String value();
+}
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/HyperSchemaFactoryWrapper.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/HyperSchemaFactoryWrapper.java
index 86863871..3cd96fdf 100644
--- a/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/HyperSchemaFactoryWrapper.java
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/HyperSchemaFactoryWrapper.java
@@ -9,7 +9,12 @@
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.annotation.JsonHyperSchema;
import com.fasterxml.jackson.module.jsonSchema.annotation.Link;
-import com.fasterxml.jackson.module.jsonSchema.factories.*;
+import com.fasterxml.jackson.module.jsonSchema.factories.ArrayVisitor;
+import com.fasterxml.jackson.module.jsonSchema.factories.ObjectVisitor;
+import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
+import com.fasterxml.jackson.module.jsonSchema.factories.VisitorContext;
+import com.fasterxml.jackson.module.jsonSchema.factories.WrapperFactory;
+import com.fasterxml.jackson.module.jsonSchema.factories.WrapperFactory.JsonSchemaVersion;
import com.fasterxml.jackson.module.jsonSchema.types.LinkDescriptionObject;
import com.fasterxml.jackson.module.jsonSchema.types.ReferenceSchema;
import com.fasterxml.jackson.module.jsonSchema.types.SimpleTypeSchema;
@@ -23,27 +28,37 @@
public class HyperSchemaFactoryWrapper extends SchemaFactoryWrapper {
private boolean ignoreDefaults = true;
+ private JsonSchemaVersion version;
private static class HyperSchemaFactoryWrapperFactory extends WrapperFactory {
+ public HyperSchemaFactoryWrapperFactory(JsonSchemaVersion version) {
+ super(version);
+ }
+
@Override
public SchemaFactoryWrapper getWrapper(SerializerProvider p) {
- return new HyperSchemaFactoryWrapper(p);
+ HyperSchemaFactoryWrapper hsfw = new HyperSchemaFactoryWrapper();
+ hsfw.setProvider(p);
+ return hsfw;
};
@Override
public SchemaFactoryWrapper getWrapper(SerializerProvider p, VisitorContext rvc)
{
- return new HyperSchemaFactoryWrapper(p)
- .setVisitorContext(rvc);
+ HyperSchemaFactoryWrapper hsfw = new HyperSchemaFactoryWrapper();
+ hsfw.setVisitorContext(rvc);
+ hsfw.setProvider(p);
+ return hsfw;
}
};
public HyperSchemaFactoryWrapper() {
- super(new HyperSchemaFactoryWrapperFactory());
+ this(JsonSchemaVersion.DRAFT_V3);
}
- public HyperSchemaFactoryWrapper(SerializerProvider p) {
- super(p, new HyperSchemaFactoryWrapperFactory());
+ public HyperSchemaFactoryWrapper(JsonSchemaVersion version) {
+ super(new HyperSchemaFactoryWrapperFactory(version));
+ this.version = version;
}
@Override
@@ -112,7 +127,7 @@ private JsonSchema fetchSchema(Class> targetSchema) {
if (visitorContext != null) {
String seenSchemaUri = visitorContext.getSeenSchemaUri(targetType);
if (seenSchemaUri != null) {
- return new ReferenceSchema(seenSchemaUri);
+ return new ReferenceSchema(version, seenSchemaUri);
}
}
HyperSchemaFactoryWrapper targetVisitor = new HyperSchemaFactoryWrapper();
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/SchemaPropertyProcessorManagerFactoryWrapper.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/SchemaPropertyProcessorManagerFactoryWrapper.java
new file mode 100644
index 00000000..accbcc3b
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/SchemaPropertyProcessorManagerFactoryWrapper.java
@@ -0,0 +1,93 @@
+package com.fasterxml.jackson.module.jsonSchema.customProperties;
+
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
+import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
+import com.fasterxml.jackson.module.jsonSchema.factories.ObjectVisitor;
+import com.fasterxml.jackson.module.jsonSchema.factories.ObjectVisitorDecorator;
+import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
+import com.fasterxml.jackson.module.jsonSchema.factories.VisitorContext;
+import com.fasterxml.jackson.module.jsonSchema.factories.WrapperFactory;
+import com.fasterxml.jackson.module.jsonSchema.factories.WrapperFactory.JsonSchemaVersion;
+import com.fasterxml.jackson.module.jsonSchema.property.manager.SchemaPropertyProcessorManagerApi;
+import com.fasterxml.jackson.module.jsonSchema.types.ObjectSchema;
+
+/**
+ * This class provides a wrapper around the SchemaFactoryWrapper that delegates
+ * to the provided implementation of SchemaPropertyProcessorManagerApi to process
+ * each property of type object elements.
+ *
+ * @author amerritt
+ */
+public class SchemaPropertyProcessorManagerFactoryWrapper extends SchemaFactoryWrapper {
+
+ private SchemaPropertyProcessorManagerApi schemaPropertyProcessorManager;
+
+ public SchemaPropertyProcessorManagerFactoryWrapper(SchemaPropertyProcessorManagerApi schemaPropertyProcessorManager) {
+ this(schemaPropertyProcessorManager, JsonSchemaVersion.DRAFT_V4);
+ }
+
+ public SchemaPropertyProcessorManagerFactoryWrapper(SchemaPropertyProcessorManagerApi schemaPropertyProcessorManager, JsonSchemaVersion version) {
+ super(new SchemaPropertyProcessorManagerFactory(schemaPropertyProcessorManager, version));
+ this.schemaPropertyProcessorManager = schemaPropertyProcessorManager;
+ }
+
+ @Override
+ public JsonObjectFormatVisitor expectObjectFormat(JavaType convertedType) {
+ ObjectVisitor objectVisitor = (ObjectVisitor) super.expectObjectFormat(convertedType);
+ schemaPropertyProcessorManager.process(objectVisitor.getSchema(), convertedType);
+ return new ObjectVisitorDecorator(objectVisitor) {
+ private JsonSchema getPropertySchema(BeanProperty writer) {
+ return ((ObjectSchema) getSchema()).getProperties().get(writer.getName());
+ }
+
+ @Override
+ public void optionalProperty(BeanProperty writer) throws JsonMappingException {
+ super.optionalProperty(writer);
+ schemaPropertyProcessorManager.process(getPropertySchema(writer), writer);
+ }
+
+ @Override
+ public void property(BeanProperty writer) throws JsonMappingException {
+ super.property(writer);
+ schemaPropertyProcessorManager.process(getPropertySchema(writer), writer);
+ }
+ };
+ }
+
+ private static class SchemaPropertyProcessorManagerFactory extends WrapperFactory {
+ SchemaPropertyProcessorManagerApi schemaPropertyProcessorManager;
+
+ SchemaPropertyProcessorManagerFactory(SchemaPropertyProcessorManagerApi schemaPropertyProcessorManager, JsonSchemaVersion version) {
+ super(version);
+ this.schemaPropertyProcessorManager = schemaPropertyProcessorManager;
+ }
+
+ @Override
+ public SchemaFactoryWrapper getWrapper(SerializerProvider p) {
+ SchemaFactoryWrapper wrapper = new SchemaPropertyProcessorManagerFactoryWrapper(schemaPropertyProcessorManager, getVersion());
+ wrapper.setProvider(p);
+ return wrapper;
+ }
+
+ @Override
+ public SchemaFactoryWrapper getWrapper(SerializerProvider p, VisitorContext rvc) {
+ SchemaFactoryWrapper wrapper = new SchemaPropertyProcessorManagerFactoryWrapper(schemaPropertyProcessorManager, getVersion());
+ wrapper.setProvider(p);
+ wrapper.setVisitorContext(rvc);
+ return wrapper;
+ }
+
+ @Override
+ public SchemaFactoryWrapper getWrapper(SerializerProvider p, VisitorContext rvc, ObjectSchema parent, Class> type) {
+ SchemaFactoryWrapper wrapper = new SchemaPropertyProcessorManagerFactoryWrapper(schemaPropertyProcessorManager.createCopyForType(type), getVersion());
+ wrapper.setProvider(p);
+ wrapper.setVisitorContext(rvc);
+ wrapper.setParent(parent);
+ return wrapper;
+ }
+ }
+}
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/TitleSchemaFactoryWrapper.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/TitleSchemaFactoryWrapper.java
deleted file mode 100644
index 37847080..00000000
--- a/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/TitleSchemaFactoryWrapper.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.fasterxml.jackson.module.jsonSchema.customProperties;
-
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor;
-import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
-import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
-import com.fasterxml.jackson.module.jsonSchema.factories.*;
-
-/**
- * Adds a title to every object schema, either root level or nested. Generally
- * useful for writing additional properties to a schema.
- *
- * @author jphelan
- */
-public class TitleSchemaFactoryWrapper extends SchemaFactoryWrapper
-{
- private static class TitleSchemaFactoryWrapperFactory extends WrapperFactory {
- @Override
- public SchemaFactoryWrapper getWrapper(SerializerProvider p) {
- SchemaFactoryWrapper wrapper = new TitleSchemaFactoryWrapper();
- if (p != null) {
- wrapper.setProvider(p);
- }
- return wrapper;
- };
-
- @Override
- public SchemaFactoryWrapper getWrapper(SerializerProvider p, VisitorContext rvc) {
- SchemaFactoryWrapper wrapper = new TitleSchemaFactoryWrapper();
- if (p != null) {
- wrapper.setProvider(p);
- }
- wrapper.setVisitorContext(rvc);
- return wrapper;
- }
- };
-
- public TitleSchemaFactoryWrapper() {
- super(new TitleSchemaFactoryWrapperFactory());
- }
-
- @Override
- public JsonObjectFormatVisitor expectObjectFormat(JavaType convertedType) {
- ObjectVisitor visitor = ((ObjectVisitor)super.expectObjectFormat(convertedType));
-
- // could add other properties here
- addTitle(visitor.getSchema(), convertedType);
-
- return visitor;
- }
-
- @Override
- public JsonArrayFormatVisitor expectArrayFormat(JavaType convertedType) {
- ArrayVisitor visitor = ((ArrayVisitor)super.expectArrayFormat(convertedType));
-
- // could add other properties here
- addTitle(visitor.getSchema(), convertedType);
-
- return visitor;
- }
-
- /**
- * Adds writes the type as the title of the schema.
- *
- * @param schema The schema who's title to set.
- * @param type The type of the object represented by the schema.
- */
- private void addTitle(JsonSchema schema, JavaType type)
- {
- if (!schema.isSimpleTypeSchema()) {
- throw new RuntimeException("given non simple type schema: " + schema.getType());
- }
- schema.asSimpleTypeSchema().setTitle(type.getGenericSignature());
- }
-}
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/TitleSchemaPropertyProcessorManagerFactoryWrapper.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/TitleSchemaPropertyProcessorManagerFactoryWrapper.java
new file mode 100644
index 00000000..4ef7e820
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/TitleSchemaPropertyProcessorManagerFactoryWrapper.java
@@ -0,0 +1,23 @@
+package com.fasterxml.jackson.module.jsonSchema.customProperties;
+
+import java.util.Arrays;
+
+import com.fasterxml.jackson.module.jsonSchema.factories.WrapperFactory.JsonSchemaVersion;
+import com.fasterxml.jackson.module.jsonSchema.property.SchemaPropertyProcessorTitle;
+import com.fasterxml.jackson.module.jsonSchema.property.manager.SchemaPropertyProcessorManager;
+
+/**
+ * Adds a title to any object annotated with JsonSchemaTitle, either root level or nested.
+ *
+ * @author amerritt
+ */
+public class TitleSchemaPropertyProcessorManagerFactoryWrapper extends SchemaPropertyProcessorManagerFactoryWrapper
+{
+ public TitleSchemaPropertyProcessorManagerFactoryWrapper() {
+ this(JsonSchemaVersion.DRAFT_V3);
+ }
+
+ public TitleSchemaPropertyProcessorManagerFactoryWrapper(JsonSchemaVersion version) {
+ super(new SchemaPropertyProcessorManager(Arrays.asList(new SchemaPropertyProcessorTitle())), version);
+ }
+}
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/ValidationSchemaFactoryWrapper.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/ValidationSchemaFactoryWrapper.java
deleted file mode 100644
index 02f2882a..00000000
--- a/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/ValidationSchemaFactoryWrapper.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.fasterxml.jackson.module.jsonSchema.customProperties;
-
-import com.fasterxml.jackson.databind.BeanProperty;
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
-import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
-import com.fasterxml.jackson.module.jsonSchema.factories.*;
-import com.fasterxml.jackson.module.jsonSchema.types.ArraySchema;
-import com.fasterxml.jackson.module.jsonSchema.types.NumberSchema;
-import com.fasterxml.jackson.module.jsonSchema.types.ObjectSchema;
-import com.fasterxml.jackson.module.jsonSchema.types.StringSchema;
-import com.fasterxml.jackson.module.jsonSchema.validation.AnnotationConstraintResolver;
-import com.fasterxml.jackson.module.jsonSchema.validation.ValidationConstraintResolver;
-
-/**
- * @author cponomaryov
- */
-public class ValidationSchemaFactoryWrapper extends SchemaFactoryWrapper {
-
- private ValidationConstraintResolver constraintResolver;
-
- private static class ValidationSchemaFactoryWrapperFactory extends WrapperFactory {
- @Override
- public SchemaFactoryWrapper getWrapper(SerializerProvider p) {
- SchemaFactoryWrapper wrapper = new ValidationSchemaFactoryWrapper();
- wrapper.setProvider(p);
- return wrapper;
- }
-
- @Override
- public SchemaFactoryWrapper getWrapper(SerializerProvider p, VisitorContext rvc) {
- SchemaFactoryWrapper wrapper = new ValidationSchemaFactoryWrapper();
- wrapper.setProvider(p);
- wrapper.setVisitorContext(rvc);
- return wrapper;
- }
- }
-
- public ValidationSchemaFactoryWrapper() {
- this(new AnnotationConstraintResolver());
- }
-
- public ValidationSchemaFactoryWrapper(ValidationConstraintResolver constraintResolver) {
- super(new ValidationSchemaFactoryWrapperFactory());
- this.constraintResolver = constraintResolver;
- }
-
- @Override
- public JsonObjectFormatVisitor expectObjectFormat(JavaType convertedType) {
- return new ObjectVisitorDecorator((ObjectVisitor) super.expectObjectFormat(convertedType)) {
- private JsonSchema getPropertySchema(BeanProperty writer) {
- return ((ObjectSchema) getSchema()).getProperties().get(writer.getName());
- }
-
- @Override
- public void optionalProperty(BeanProperty writer) throws JsonMappingException {
- super.optionalProperty(writer);
- addValidationConstraints(getPropertySchema(writer), writer);
- }
-
- @Override
- public void property(BeanProperty writer) throws JsonMappingException {
- super.property(writer);
- addValidationConstraints(getPropertySchema(writer), writer);
- }
- };
- }
-
- protected JsonSchema addValidationConstraints(JsonSchema schema, BeanProperty prop) {
- {
- Boolean required = constraintResolver.getRequired(prop);
- if (required != null) {
- schema.setRequired(required);
- }
- }
- if (schema.isArraySchema()) {
- ArraySchema arraySchema = schema.asArraySchema();
- arraySchema.setMaxItems(constraintResolver.getArrayMaxItems(prop));
- arraySchema.setMinItems(constraintResolver.getArrayMinItems(prop));
- } else if (schema.isNumberSchema()) {
- NumberSchema numberSchema = schema.asNumberSchema();
- numberSchema.setMaximum(constraintResolver.getNumberMaximum(prop));
- numberSchema.setMinimum(constraintResolver.getNumberMinimum(prop));
- } else if (schema.isStringSchema()) {
- StringSchema stringSchema = schema.asStringSchema();
- stringSchema.setMaxLength(constraintResolver.getStringMaxLength(prop));
- stringSchema.setMinLength(constraintResolver.getStringMinLength(prop));
- stringSchema.setPattern(constraintResolver.getStringPattern(prop));
- }
- return schema;
- }
-
-}
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/ValidationSchemaPropertyProcessorManagerFactoryWrapper.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/ValidationSchemaPropertyProcessorManagerFactoryWrapper.java
new file mode 100644
index 00000000..89e47b44
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/customProperties/ValidationSchemaPropertyProcessorManagerFactoryWrapper.java
@@ -0,0 +1,17 @@
+package com.fasterxml.jackson.module.jsonSchema.customProperties;
+
+import com.fasterxml.jackson.module.jsonSchema.factories.WrapperFactory.JsonSchemaVersion;
+import com.fasterxml.jackson.module.jsonSchema.property.manager.SchemaPropertyProcessorManagerConstraint;
+
+/**
+ * @author amerritt
+ */
+public class ValidationSchemaPropertyProcessorManagerFactoryWrapper extends SchemaPropertyProcessorManagerFactoryWrapper {
+ public ValidationSchemaPropertyProcessorManagerFactoryWrapper(Class> type, Class>... groups) {
+ super(new SchemaPropertyProcessorManagerConstraint(type, groups));
+ }
+
+ public ValidationSchemaPropertyProcessorManagerFactoryWrapper(JsonSchemaVersion version, Class> type, Class>... groups) {
+ super(new SchemaPropertyProcessorManagerConstraint(type, groups), version);
+ }
+}
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/ArrayVisitor.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/ArrayVisitor.java
index f5b427c5..6eec6d83 100644
--- a/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/ArrayVisitor.java
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/ArrayVisitor.java
@@ -1,6 +1,8 @@
package com.fasterxml.jackson.module.jsonSchema.factories;
-import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitable;
@@ -19,10 +21,6 @@ public class ArrayVisitor extends JsonArrayFormatVisitor.Base
private VisitorContext visitorContext;
- public ArrayVisitor(SerializerProvider provider, ArraySchema schema) {
- this(provider, schema, new WrapperFactory());
- }
-
public ArrayVisitor(SerializerProvider provider, ArraySchema schema, WrapperFactory wrapperFactory) {
this.provider = provider;
this.schema = schema;
@@ -75,7 +73,7 @@ public void itemsFormat(JsonFormatVisitable handler, JavaType contentType)
if (visitorContext != null) {
String seenSchemaUri = visitorContext.getSeenSchemaUri(contentType);
if (seenSchemaUri != null) {
- schema.setItemsSchema(new ReferenceSchema(seenSchemaUri));
+ schema.setItemsSchema(new ReferenceSchema(schema.getVersion(), seenSchemaUri));
return;
}
}
@@ -89,7 +87,7 @@ public void itemsFormat(JsonFormatVisitable handler, JavaType contentType)
@Override
public void itemsFormat(JsonFormatTypes format) throws JsonMappingException
{
- schema.setItemsSchema(JsonSchema.minimalForFormat(format));
+ schema.setItemsSchema(JsonSchema.minimalForFormat(schema.getVersion(), format));
}
@Override
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/FormatVisitorFactory.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/FormatVisitorFactory.java
index 6a3a410d..f7b258c3 100644
--- a/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/FormatVisitorFactory.java
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/FormatVisitorFactory.java
@@ -1,9 +1,23 @@
package com.fasterxml.jackson.module.jsonSchema.factories;
import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.jsonFormatVisitors.*;
-
-import com.fasterxml.jackson.module.jsonSchema.types.*;
+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.JsonIntegerFormatVisitor;
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonMapFormatVisitor;
+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.module.jsonSchema.types.AnySchema;
+import com.fasterxml.jackson.module.jsonSchema.types.ArraySchema;
+import com.fasterxml.jackson.module.jsonSchema.types.BooleanSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.IntegerSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.NullSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.NumberSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.ObjectSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.StringSchema;
/**
* Factory class used for constructing visitors for building various
@@ -13,10 +27,6 @@ public class FormatVisitorFactory {
private final WrapperFactory wrapperFactory;
- public FormatVisitorFactory() {
- this(new WrapperFactory());
- }
-
public FormatVisitorFactory(WrapperFactory wrapperFactory) {
this.wrapperFactory = wrapperFactory;
}
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/JsonSchemaFactory.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/JsonSchemaFactory.java
index 4f550b48..df3c607b 100644
--- a/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/JsonSchemaFactory.java
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/JsonSchemaFactory.java
@@ -1,5 +1,6 @@
package com.fasterxml.jackson.module.jsonSchema.factories;
+import com.fasterxml.jackson.module.jsonSchema.factories.WrapperFactory.JsonSchemaVersion;
import com.fasterxml.jackson.module.jsonSchema.types.AnySchema;
import com.fasterxml.jackson.module.jsonSchema.types.ArraySchema;
import com.fasterxml.jackson.module.jsonSchema.types.BooleanSchema;
@@ -7,39 +8,57 @@
import com.fasterxml.jackson.module.jsonSchema.types.NullSchema;
import com.fasterxml.jackson.module.jsonSchema.types.NumberSchema;
import com.fasterxml.jackson.module.jsonSchema.types.ObjectSchema;
+import com.fasterxml.jackson.module.jsonSchema.types.SimpleTypeSchema;
import com.fasterxml.jackson.module.jsonSchema.types.StringSchema;
public class JsonSchemaFactory
{
- public AnySchema anySchema() {
- return new AnySchema();
+ private JsonSchemaVersion version;
+
+ //NOTE: you could use the version to return different version but since Required went from a boolean to a List
+ // it would require maintaining to complete sets of classes. Not worth the time and effort at this point.
+ public JsonSchemaFactory(JsonSchemaVersion version) {
+ this.version = version;
+ }
+
+ public AnySchema anySchema(ObjectSchema parent) {
+ return setParent(new AnySchema(version), parent);
+ }
+
+ public ArraySchema arraySchema(ObjectSchema parent) {
+ return setParent(new ArraySchema(version), parent);
+ }
+
+ public BooleanSchema booleanSchema(ObjectSchema parent) {
+ return setParent(new BooleanSchema(version), parent);
}
- public ArraySchema arraySchema() {
- return new ArraySchema();
+ public IntegerSchema integerSchema(ObjectSchema parent) {
+ return setParent(new IntegerSchema(version), parent);
}
- public BooleanSchema booleanSchema() {
- return new BooleanSchema();
+ public NullSchema nullSchema(ObjectSchema parent) {
+ return setParent(new NullSchema(version), parent);
}
- public IntegerSchema integerSchema() {
- return new IntegerSchema();
+ public NumberSchema numberSchema(ObjectSchema parent) {
+ return setParent(new NumberSchema(version), parent);
}
- public NullSchema nullSchema() {
- return new NullSchema();
+ public ObjectSchema objectSchema(ObjectSchema parent) {
+ return setParent(new ObjectSchema(version), parent);
}
- public NumberSchema numberSchema() {
- return new NumberSchema();
+ public StringSchema stringSchema(ObjectSchema parent) {
+ return setParent(new StringSchema(version), parent);
}
- public ObjectSchema objectSchema() {
- return new ObjectSchema();
+ public String getSchemaString() {
+ return version.getSchemaString();
}
- public StringSchema stringSchema() {
- return new StringSchema();
+ private T setParent(T schema, ObjectSchema parent) {
+ schema.setParent(parent);
+ return schema;
}
}
\ No newline at end of file
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/MapVisitor.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/MapVisitor.java
index 05cee9a8..2be38058 100644
--- a/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/MapVisitor.java
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/MapVisitor.java
@@ -25,10 +25,6 @@ public class MapVisitor extends JsonMapFormatVisitor.Base
private VisitorContext visitorContext;
- public MapVisitor(SerializerProvider provider, ObjectSchema schema) {
- this(provider, schema, new WrapperFactory());
- }
-
public MapVisitor(SerializerProvider provider, ObjectSchema schema, WrapperFactory wrapperFactory) {
this.provider = provider;
this.schema = schema;
@@ -86,7 +82,7 @@ protected JsonSchema propertySchema(JsonFormatVisitable handler, JavaType proper
if (visitorContext != null) {
String seenSchemaUri = visitorContext.getSeenSchemaUri(propertyTypeHint);
if (seenSchemaUri != null) {
- return new ReferenceSchema(seenSchemaUri);
+ return new ReferenceSchema(wrapperFactory.getVersion(), seenSchemaUri);
}
}
diff --git a/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/ObjectVisitor.java b/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/ObjectVisitor.java
index ad7d67f4..5481f2a5 100644
--- a/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/ObjectVisitor.java
+++ b/src/main/java/com/fasterxml/jackson/module/jsonSchema/factories/ObjectVisitor.java
@@ -1,6 +1,10 @@
package com.fasterxml.jackson.module.jsonSchema.factories;
-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.SerializerProvider;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitable;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
@@ -16,14 +20,6 @@ public class ObjectVisitor extends JsonObjectFormatVisitor.Base
private WrapperFactory wrapperFactory;
private VisitorContext visitorContext;
- /**
- * @deprecated Since 2.4; call constructor that takes {@link WrapperFactory}
- */
- @Deprecated
- public ObjectVisitor(SerializerProvider provider, ObjectSchema schema) {
- this(provider, schema, new WrapperFactory());
- }
-
public ObjectVisitor(SerializerProvider provider, ObjectSchema schema, WrapperFactory wrapperFactory) {
this.provider = provider;
this.schema = schema;
@@ -105,10 +101,10 @@ protected JsonSchema propertySchema(BeanProperty prop)
// check if we've seen this argument's sub-schema already and return a reference-schema if we have
String seenSchemaUri = visitorContext.getSeenSchemaUri(prop.getType());
if (seenSchemaUri != null) {
- return new ReferenceSchema(seenSchemaUri);
+ return new ReferenceSchema(wrapperFactory.getVersion(), seenSchemaUri, schema);
}
- SchemaFactoryWrapper visitor = wrapperFactory.getWrapper(getProvider(), visitorContext);
+ SchemaFactoryWrapper visitor = wrapperFactory.getWrapper(getProvider(), visitorContext, schema, prop.getType().getRawClass());
JsonSerializer