I am using Jackson JSON schema module version 2.7.4
to generate JSON schema for some of my classes. In my classes, I have used Joda DateTime
object. The schema for this object is generated with all it's properties exploded (as shown below). Is it possible to convert this to something like DATE_TIME
?
"createdDate":{
"type":"object",
"id":"urn:jsonschema:org:joda:time:DateTime",
"properties":{
"weekOfWeekyear":{
"type":"integer"
},
"weekyear":{
"type":"integer"
},
"yearOfEra":{
"type":"integer"
},
"secondOfDay":{
"type":"integer"
},
"minuteOfDay":{
"type":"integer"
},
"yearOfCentury":{
"type":"integer"
},
"centuryOfEra":{
"type":"integer"
},
"millisOfDay":{
"type":"integer"
},
"monthOfYear":{
"type":"integer"
},
"hourOfDay":{
"type":"integer"
},
"minuteOfHour":{
"type":"integer"
},
"secondOfMinute":{
"type":"integer"
},
"millisOfSecond":{
"type":"integer"
},
"year":{
"type":"integer"
},
"dayOfMonth":{
"type":"integer"
},
"dayOfWeek":{
"type":"integer"
},
"era":{
"type":"integer"
},
"dayOfYear":{
"type":"integer"
},
"chronology":{
"type":"object",
"id":"urn:jsonschema:org:joda:time:Chronology",
"properties":{
"zone":{
"type":"object",
"id":"urn:jsonschema:org:joda:time:DateTimeZone",
"properties":{
"id":{
"type":"string"
},
"fixed":{
"type":"boolean"
}
}
}
}
},
"zone":{
"type":"object",
"$ref":"urn:jsonschema:org:joda:time:DateTimeZone"
},
"millis":{
"type":"integer"
},
"afterNow":{
"type":"boolean"
},
"beforeNow":{
"type":"boolean"
},
"equalNow":{
"type":"boolean"
}
}
},
I don't know if this is the right solution, but this is what was suggested in another web site and this worked for me; hence, I am posting this as an answer.
In Jackson schema module, there is a notion of VisitorContext
which can be registered with ObjectMapper
class for schema generation. As per the suggestion, I provided an implementation of this as:
public static class VisitorContextWithoutSchemaInlining extends VisitorContext {
@Override
public String addSeenSchemaUri(final JavaType aSeenSchema) {
return getSeenSchemaUri(aSeenSchema);
}
@Override
public String getSeenSchemaUri(final JavaType aSeenSchema) {
return isEligibleForInlineSchema(aSeenSchema) ? javaTypeToUrn(aSeenSchema) : null;
}
private boolean isEligibleForInlineSchema(final JavaType type) {
return type.getRawClass() != String.class
&& !isBoxedPrimitive(type)
&& !type.isPrimitive()
&& !type.isMapLikeType()
&& !type.isCollectionLikeType()
&& type.getRawClass() == DateTime.class
;
}
private boolean isBoxedPrimitive(final JavaType type) {
return type.getRawClass() == Boolean.class
|| type.getRawClass() == Byte.class
|| type.getRawClass() == Long.class
|| type.getRawClass() == Integer.class
|| type.getRawClass() == Short.class
|| type.getRawClass() == Float.class
|| type.getRawClass() == Double.class
;
}
}
To use this with ObjectMapper
, I did this:
final ObjectMapper mapper = new ObjectMapper();
final ObjectWriter objectWriter = mapper.writer();
final SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
visitor.setVisitorContext(new VisitorContextWithoutSchemaInlining());
objectWriter.acceptJsonFormatVisitor(candidateClass, visitor);
final JsonSchema jsonSchema = visitor.finalSchema();
final String schemaJsonString = objectWriter.forType(JsonSchema.class).writeValueAsString(jsonSchema);
With this I could see my schema has this for createdDate
"createdDate":{"type":"object","$ref":"urn:jsonschema:org:joda:time:DateTime"}