0

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"
        }
     }
  },
Niranjan
  • 2,601
  • 8
  • 43
  • 54

2 Answers2

0

I'm not sure there is any support or Joda in that module. What you can do is replace the generated Joda schema by your own. Something like this:

    private void replaceDateTime(JsonSchema schema, Class<?> clazz) {
        Field[] fields = ClazzFieldFinder.getAllFields(clazz);
        for (Field field : fields) {
            String fieldName = field.getName();
            if (field.getType().equals(DateTime.class)) {
                schema.asObjectSchema().getProperties().remove(fieldName);

                StringSchema stringSchemaDateTime = new StringSchema();
                stringSchemaDateTime.setFormat(JsonValueFormat.DATE_TIME);
                schema.asObjectSchema().getProperties().put(fieldName, stringSchemaDateTime);
            }
        }
    }

It removes the generated schema for Joda and adds the string/date_time format.

Franjavi
  • 647
  • 4
  • 14
0

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"}
Niranjan
  • 2,601
  • 8
  • 43
  • 54