Skip to content

Commit

Permalink
Fix #67
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Apr 27, 2015
1 parent 129565e commit 671188e
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 48 deletions.
11 changes: 11 additions & 0 deletions release-notes/CREDITS
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,14 @@ Izek Greenfield (igreenfield@github)
#64: Add support to oneOf
(2.6.0)

Sebastien Briquet (sebfz1@github)

#67: Unable to deserialize (extended/custom) Schema
(2.6.0)


David Semke (dsemke@github)

#69: Add support for @Pattern annotations in String schemas
(2.6.0)

4 changes: 4 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Project: jackson-module-jsonSchema
#60: Add `readonly` property to `JsonSchema`
#64: Add support to oneOf
(contributed by Izek K, igreenfield@github)
#67: Unable to deserialize (extended/custom) Schema
(reported by Sebastian B)
#69: Add support for @Pattern annotations in String schemas
(contributed by David S)
- Added `JsonSchemaGenerator(ObjectWriter)` to allow use of (re-)configured `ObjectWriter`
instead of `ObjectMapper` which can not be configured.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,27 +318,27 @@ public String getDescription() {
}

@JsonIgnore
public abstract JsonFormatTypes getType();
public abstract JsonFormatTypes getType();

/**
* determine if this JsonSchema is an {@link AnySchema}.
*
* @return true if this JsonSchema is an AnySchema, false otherwise
*/
@JsonIgnore
public boolean isAnySchema() {
return false;
}
/**
* determine if this JsonSchema is an {@link 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 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}.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,30 @@
package com.fasterxml.jackson.module.jsonSchema;

import java.util.Arrays;

import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;

import com.fasterxml.jackson.databind.DatabindContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes;
import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.module.jsonSchema.types.*;

/**
* Type id resolver needed to support polymorphic (de)serialization of all kinds of
* {@link JsonSchema} instances.
* Note that to support custom types, you will need to sub-lcass this resolver
* and override at least {@link #idFromValue(Object)}, {@link #idFromValueAndType(Object, Class)} and
* {@link #typeFromId(String)} methods; as well as associate this resolver using
* {@link JsonTypeInfo} annotation on all custom {@link JsonSchema} implementation classes.
*/
public class JsonSchemaIdResolver extends TypeIdResolverBase
{
/* This is Wrong: should not use defaultInstance() for anything.
* But has to work for now...
*/
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);

public JsonSchemaIdResolver() { }

@Override
public String idFromValue(Object value) {
if ( value instanceof JsonSchema) {
if (value instanceof JsonSchema) {
return ((JsonSchema)value).getType().value();
}
return null;
Expand All @@ -38,19 +36,33 @@ public String idFromValueAndType(Object value, Class<?> suggestedType) {
}

@Override
public JavaType typeFromId(DatabindContext context, String id) {
switch (JsonFormatTypes.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;
}
public JavaType typeFromId(DatabindContext ctxt, String id)
{
JsonFormatTypes stdType = JsonFormatTypes.forValue(id);
if (stdType != null) {
switch (stdType) {
case ARRAY:
return ctxt.constructType(ArraySchema.class);
case BOOLEAN:
return ctxt.constructType(BooleanSchema.class);
case INTEGER:
return ctxt.constructType(IntegerSchema.class);
case NULL:
return ctxt.constructType(NullSchema.class);
case NUMBER:
return ctxt.constructType(NumberSchema.class);
case OBJECT:
return ctxt.constructType(ObjectSchema.class);
case STRING:
return ctxt.constructType(StringSchema.class);
case ANY:
default:
return ctxt.constructType(AnySchema.class);
}
}
// Not a standard type; should use a custom sub-type impl
throw new IllegalArgumentException("Can not resolve JsonSchema 'type' id of \""+id
+"\", not recognized as one of standard values: "+Arrays.asList(JsonFormatTypes.values()));
}

@Override
Expand All @@ -65,4 +77,4 @@ public void init(JavaType baseType) { }
public String idFromBaseType() {
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.fasterxml.jackson.module.jsonSchema;

import com.fasterxml.jackson.databind.DatabindContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
import com.fasterxml.jackson.module.jsonSchema.types.ObjectSchema;

public class CustomSchemaReadTest extends SchemaTestBase
{
@JsonTypeIdResolver(MyResolver.class)
public static class MySchema extends ObjectSchema {
}

static class MyResolver extends JsonSchemaIdResolver
{
@Override
public String idFromValue(Object value) {
if (value instanceof MySchema) {
return "CUSTOM";
}
return super.idFromValue(value);
}

@Override
public String idFromValueAndType(Object value, Class<?> suggestedType) {
if (value instanceof MySchema) {
return "CUSTOM";
}
return super.idFromValueAndType(value, suggestedType);
}

@Override
public JavaType typeFromId(DatabindContext ctxt, String id) {
if ("CUSTOM".equals(id)) {
return ctxt.constructType(MySchema.class);
}
return super.typeFromId(ctxt, id);
}
}

// [module-jsonSchema#67]
public void testSchema() throws Exception
{
String input = "{ \"type\" : \"CUSTOM\" , \"id\" : \"7a2e8538-196b-423e-b714-13515848ec0c\" , \"description\" : \"My Schema\" , \"title\" : \"my-json-schema\" , \"properties\" : { \"myarray\" : { \"type\" : \"array\" , \"required\" : true , \"title\" : \"my property #2\" , \"items\" : { \"type\" : \"string\"} , \"maxItems\" : 5} , \"mystring\" : { \"type\" : \"string\" , \"required\" : true , \"title\" : \"my property #1\" , \"format\" : \"REGEX\" , \"pattern\" : \"\\\\w+\"} , \"myobject\" : { \"type\" : \"object\" , \"required\" : true , \"title\" : \"my property #3\" , \"properties\" : { \"subprop\" : { \"type\" : \"string\" , \"required\" : true , \"title\" : \"sub property #1\" , \"format\" : \"REGEX\" , \"pattern\" : \"\\\\w{3}\"}}}}}";

ObjectMapper mapper = new ObjectMapper();

// ObjectSchema schema = mapper.readValue(json, ObjectSchema.class); // works
MySchema schema = mapper.readValue(input, MySchema.class); // fails

String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema);
assertNotNull(json);
}
}

0 comments on commit 671188e

Please sign in to comment.