Loading build.sbt +2 −1 Original line number Diff line number Diff line Loading @@ -42,7 +42,8 @@ lazy val deps = Seq( "com.fasterxml.jackson.core" % "jackson-databind" % jacksonVersion, "org.slf4j" % "slf4j-api" % slf4jVersion, "org.scalatest" % "scalatest_2.11" % "2.2.4" % "test", "ch.qos.logback" % "logback-classic" % "1.1.3" % "test" "ch.qos.logback" % "logback-classic" % "1.1.3" % "test", "com.github.fge" % "json-schema-validator" % "2.2.6" % "test" ) lazy val root = (project in file(".")) Loading src/main/scala/com/kjetland/jackson/jsonSchema/JsonSchemaGenerator.scala +84 −40 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ class JsonSchemaGenerator(rootObjectMapper:ObjectMapper) { trait MySerializerProvider { var provider: SerializerProvider = null def getProvider: SerializerProvider = provider def setProvider(provider: SerializerProvider): Unit = this.provider = provider Loading @@ -33,41 +34,96 @@ class JsonSchemaGenerator(rootObjectMapper:ObjectMapper) { def createChild(childNode: ObjectNode): MyJsonFormatVisitorWrapper = new MyJsonFormatVisitorWrapper(objectMapper, indent + " ", childNode) override def expectStringFormat(_type: JavaType) = new JsonStringFormatVisitor { override def enumTypes(enums: util.Set[String]): Unit = l(s"enums: $enums") override def expectStringFormat(_type: JavaType) = { l("expectStringFormat") node.put("type", "string") new JsonStringFormatVisitor { override def enumTypes(enums: util.Set[String]): Unit = l(s"expectStringFormat - enums: $enums") override def format(format: JsonValueFormat): Unit = l(s"format: $format") override def format(format: JsonValueFormat): Unit = l(s"expectStringFormat - format: $format") } } override def expectArrayFormat(_type: JavaType) = { l("expectArrayFormat") node.put("type", "array") override def expectArrayFormat(_type: JavaType) = new JsonArrayFormatVisitor with MySerializerProvider { new JsonArrayFormatVisitor with MySerializerProvider { override def itemsFormat(handler: JsonFormatVisitable, elementType: JavaType): Unit = l(s"expectArrayFormat - handler: $handler - elementType: $elementType") override def itemsFormat(format: JsonFormatTypes): Unit = l(s"itemsFormat - format: $format") } } override def expectNumberFormat(_type: JavaType) = { l("expectNumberFormat") node.put("type", "number") override def expectNumberFormat(_type: JavaType) = new JsonNumberFormatVisitor { new JsonNumberFormatVisitor { override def numberType(_type: NumberType): Unit = ??? override def enumTypes(enums: util.Set[String]): Unit = ??? override def format(format: JsonValueFormat): Unit = ??? } } override def expectAnyFormat(_type: JavaType) = new JsonAnyFormatVisitor { override def expectAnyFormat(_type: JavaType) = { l("expectAnyFormat") ??? new JsonAnyFormatVisitor { } } override def expectIntegerFormat(_type: JavaType) = new JsonIntegerFormatVisitor { override def expectIntegerFormat(_type: JavaType) = { l("expectIntegerFormat") node.put("type", "integer") new JsonIntegerFormatVisitor { override def numberType(_type: NumberType): Unit = l(s"expectIntegerFormat - type = ${_type}") override def enumTypes(enums: util.Set[String]): Unit = ??? override def format(format: JsonValueFormat): Unit = ??? } } override def expectNullFormat(_type: JavaType) = new JsonNullFormatVisitor { l("expectNullFormat") ??? } override def expectBooleanFormat(_type: JavaType) = { l("expectBooleanFormat") node.put("type", "boolean") new JsonBooleanFormatVisitor { override def enumTypes(enums: util.Set[String]): Unit = ??? override def format(format: JsonValueFormat): Unit = ??? } } override def expectMapFormat(_type: JavaType) = { l("expectMapFormat") ??? new JsonMapFormatVisitor with MySerializerProvider { override def keyFormat(handler: JsonFormatVisitable, keyType: JavaType): Unit = ??? override def valueFormat(handler: JsonFormatVisitable, valueType: JavaType): Unit = ??? } } override def expectObjectFormat(_type: JavaType) = { Loading Loading @@ -120,7 +176,7 @@ class JsonSchemaGenerator(rootObjectMapper:ObjectMapper) { override def optionalProperty(writer: BeanProperty): Unit = { val propertyName = writer.getName val propertyType = writer.getType l(s"${propertyName}: ${propertyType}") l(s"JsonObjectFormatVisitor - ${propertyName}: ${propertyType}") val thisPropertyNode = JsonNodeFactory.instance.objectNode() propertiesNode.set(propertyName, thisPropertyNode) Loading @@ -142,18 +198,6 @@ class JsonSchemaGenerator(rootObjectMapper:ObjectMapper) { } override def expectBooleanFormat(_type: JavaType) = new JsonBooleanFormatVisitor { override def enumTypes(enums: util.Set[String]): Unit = ??? override def format(format: JsonValueFormat): Unit = ??? } override def expectMapFormat(_type: JavaType) = new JsonMapFormatVisitor with MySerializerProvider { override def keyFormat(handler: JsonFormatVisitable, keyType: JavaType): Unit = ??? override def valueFormat(handler: JsonFormatVisitable, valueType: JavaType): Unit = ??? } } Loading src/test/scala/com/kjetland/jackson/jsonSchema/JsonSchemaGeneratorTest.scala +29 −11 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ package com.kjetland.jackson.jsonSchema import com.fasterxml.jackson.annotation.JsonValue import com.fasterxml.jackson.databind.{JsonNode, ObjectMapper} import com.github.fge.jsonschema.main.JsonSchemaFactory import com.kjetland.jackson.jsonSchema.testData.{Child1, Parent, PojoWithParent} import org.scalatest.{FunSuite, Matchers} Loading @@ -16,35 +17,52 @@ class JsonSchemaGeneratorTest extends FunSuite with Matchers with TestData { } def assertToFromJson(o:Any): Unit = { def assertToFromJson(o:Any): JsonNode = { assertToFromJson(o, o.getClass) } def assertToFromJson(o:Any, deserType:Class[_]): Unit = { def assertToFromJson(o:Any, deserType:Class[_]): JsonNode = { val json = objectMapper.writeValueAsString(o) println(s"json: $json") val r = objectMapper.readValue(json, deserType) val jsonNode = objectMapper.readTree(json) val r = objectMapper.treeToValue(jsonNode, deserType) assert( o == r) jsonNode } test("polymorphism") { assertToFromJson(pojoWithParent) def useSchema(jsonSchema:JsonNode, jsonToTestAgainstSchema:Option[JsonNode] = None): Unit = { val schemaValidator = JsonSchemaFactory.byDefault().getJsonSchema(jsonSchema) jsonToTestAgainstSchema.foreach { node => val r = schemaValidator.validate(node) if ( !r.isSuccess ) { throw new Exception("json does not validate agains schema: " + r) } } } val schema = jsonSchemaGenerator.generateJsonSchema(pojoWithParent.getClass) def generateAndValidateSchema(clazz:Class[_], jsonToTestAgainstSchema:Option[JsonNode] = None):String = { val schema = jsonSchemaGenerator.generateJsonSchema(clazz) useSchema(schema, jsonToTestAgainstSchema) val schemaAsJson = asPrettyJson(schema) asPrettyJson(schema) } test("polymorphism") { val jsonNode = assertToFromJson(pojoWithParent) val schemaAsJson = generateAndValidateSchema(pojoWithParent.getClass, Some(jsonNode)) println("--------------------------------------------") println(schemaAsJson) } test("polymorphism - first Level") { assertToFromJson(child1) val jsonNode = assertToFromJson(child1) assertToFromJson(child1, classOf[Parent]) val schema = jsonSchemaGenerator.generateJsonSchema(classOf[Parent]) val schemaAsJson = asPrettyJson(schema) val schemaAsJson = generateAndValidateSchema(classOf[Parent], Some(jsonNode)) println("--------------------------------------------") println(schemaAsJson) } Loading Loading
build.sbt +2 −1 Original line number Diff line number Diff line Loading @@ -42,7 +42,8 @@ lazy val deps = Seq( "com.fasterxml.jackson.core" % "jackson-databind" % jacksonVersion, "org.slf4j" % "slf4j-api" % slf4jVersion, "org.scalatest" % "scalatest_2.11" % "2.2.4" % "test", "ch.qos.logback" % "logback-classic" % "1.1.3" % "test" "ch.qos.logback" % "logback-classic" % "1.1.3" % "test", "com.github.fge" % "json-schema-validator" % "2.2.6" % "test" ) lazy val root = (project in file(".")) Loading
src/main/scala/com/kjetland/jackson/jsonSchema/JsonSchemaGenerator.scala +84 −40 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ class JsonSchemaGenerator(rootObjectMapper:ObjectMapper) { trait MySerializerProvider { var provider: SerializerProvider = null def getProvider: SerializerProvider = provider def setProvider(provider: SerializerProvider): Unit = this.provider = provider Loading @@ -33,41 +34,96 @@ class JsonSchemaGenerator(rootObjectMapper:ObjectMapper) { def createChild(childNode: ObjectNode): MyJsonFormatVisitorWrapper = new MyJsonFormatVisitorWrapper(objectMapper, indent + " ", childNode) override def expectStringFormat(_type: JavaType) = new JsonStringFormatVisitor { override def enumTypes(enums: util.Set[String]): Unit = l(s"enums: $enums") override def expectStringFormat(_type: JavaType) = { l("expectStringFormat") node.put("type", "string") new JsonStringFormatVisitor { override def enumTypes(enums: util.Set[String]): Unit = l(s"expectStringFormat - enums: $enums") override def format(format: JsonValueFormat): Unit = l(s"format: $format") override def format(format: JsonValueFormat): Unit = l(s"expectStringFormat - format: $format") } } override def expectArrayFormat(_type: JavaType) = { l("expectArrayFormat") node.put("type", "array") override def expectArrayFormat(_type: JavaType) = new JsonArrayFormatVisitor with MySerializerProvider { new JsonArrayFormatVisitor with MySerializerProvider { override def itemsFormat(handler: JsonFormatVisitable, elementType: JavaType): Unit = l(s"expectArrayFormat - handler: $handler - elementType: $elementType") override def itemsFormat(format: JsonFormatTypes): Unit = l(s"itemsFormat - format: $format") } } override def expectNumberFormat(_type: JavaType) = { l("expectNumberFormat") node.put("type", "number") override def expectNumberFormat(_type: JavaType) = new JsonNumberFormatVisitor { new JsonNumberFormatVisitor { override def numberType(_type: NumberType): Unit = ??? override def enumTypes(enums: util.Set[String]): Unit = ??? override def format(format: JsonValueFormat): Unit = ??? } } override def expectAnyFormat(_type: JavaType) = new JsonAnyFormatVisitor { override def expectAnyFormat(_type: JavaType) = { l("expectAnyFormat") ??? new JsonAnyFormatVisitor { } } override def expectIntegerFormat(_type: JavaType) = new JsonIntegerFormatVisitor { override def expectIntegerFormat(_type: JavaType) = { l("expectIntegerFormat") node.put("type", "integer") new JsonIntegerFormatVisitor { override def numberType(_type: NumberType): Unit = l(s"expectIntegerFormat - type = ${_type}") override def enumTypes(enums: util.Set[String]): Unit = ??? override def format(format: JsonValueFormat): Unit = ??? } } override def expectNullFormat(_type: JavaType) = new JsonNullFormatVisitor { l("expectNullFormat") ??? } override def expectBooleanFormat(_type: JavaType) = { l("expectBooleanFormat") node.put("type", "boolean") new JsonBooleanFormatVisitor { override def enumTypes(enums: util.Set[String]): Unit = ??? override def format(format: JsonValueFormat): Unit = ??? } } override def expectMapFormat(_type: JavaType) = { l("expectMapFormat") ??? new JsonMapFormatVisitor with MySerializerProvider { override def keyFormat(handler: JsonFormatVisitable, keyType: JavaType): Unit = ??? override def valueFormat(handler: JsonFormatVisitable, valueType: JavaType): Unit = ??? } } override def expectObjectFormat(_type: JavaType) = { Loading Loading @@ -120,7 +176,7 @@ class JsonSchemaGenerator(rootObjectMapper:ObjectMapper) { override def optionalProperty(writer: BeanProperty): Unit = { val propertyName = writer.getName val propertyType = writer.getType l(s"${propertyName}: ${propertyType}") l(s"JsonObjectFormatVisitor - ${propertyName}: ${propertyType}") val thisPropertyNode = JsonNodeFactory.instance.objectNode() propertiesNode.set(propertyName, thisPropertyNode) Loading @@ -142,18 +198,6 @@ class JsonSchemaGenerator(rootObjectMapper:ObjectMapper) { } override def expectBooleanFormat(_type: JavaType) = new JsonBooleanFormatVisitor { override def enumTypes(enums: util.Set[String]): Unit = ??? override def format(format: JsonValueFormat): Unit = ??? } override def expectMapFormat(_type: JavaType) = new JsonMapFormatVisitor with MySerializerProvider { override def keyFormat(handler: JsonFormatVisitable, keyType: JavaType): Unit = ??? override def valueFormat(handler: JsonFormatVisitable, valueType: JavaType): Unit = ??? } } Loading
src/test/scala/com/kjetland/jackson/jsonSchema/JsonSchemaGeneratorTest.scala +29 −11 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ package com.kjetland.jackson.jsonSchema import com.fasterxml.jackson.annotation.JsonValue import com.fasterxml.jackson.databind.{JsonNode, ObjectMapper} import com.github.fge.jsonschema.main.JsonSchemaFactory import com.kjetland.jackson.jsonSchema.testData.{Child1, Parent, PojoWithParent} import org.scalatest.{FunSuite, Matchers} Loading @@ -16,35 +17,52 @@ class JsonSchemaGeneratorTest extends FunSuite with Matchers with TestData { } def assertToFromJson(o:Any): Unit = { def assertToFromJson(o:Any): JsonNode = { assertToFromJson(o, o.getClass) } def assertToFromJson(o:Any, deserType:Class[_]): Unit = { def assertToFromJson(o:Any, deserType:Class[_]): JsonNode = { val json = objectMapper.writeValueAsString(o) println(s"json: $json") val r = objectMapper.readValue(json, deserType) val jsonNode = objectMapper.readTree(json) val r = objectMapper.treeToValue(jsonNode, deserType) assert( o == r) jsonNode } test("polymorphism") { assertToFromJson(pojoWithParent) def useSchema(jsonSchema:JsonNode, jsonToTestAgainstSchema:Option[JsonNode] = None): Unit = { val schemaValidator = JsonSchemaFactory.byDefault().getJsonSchema(jsonSchema) jsonToTestAgainstSchema.foreach { node => val r = schemaValidator.validate(node) if ( !r.isSuccess ) { throw new Exception("json does not validate agains schema: " + r) } } } val schema = jsonSchemaGenerator.generateJsonSchema(pojoWithParent.getClass) def generateAndValidateSchema(clazz:Class[_], jsonToTestAgainstSchema:Option[JsonNode] = None):String = { val schema = jsonSchemaGenerator.generateJsonSchema(clazz) useSchema(schema, jsonToTestAgainstSchema) val schemaAsJson = asPrettyJson(schema) asPrettyJson(schema) } test("polymorphism") { val jsonNode = assertToFromJson(pojoWithParent) val schemaAsJson = generateAndValidateSchema(pojoWithParent.getClass, Some(jsonNode)) println("--------------------------------------------") println(schemaAsJson) } test("polymorphism - first Level") { assertToFromJson(child1) val jsonNode = assertToFromJson(child1) assertToFromJson(child1, classOf[Parent]) val schema = jsonSchemaGenerator.generateJsonSchema(classOf[Parent]) val schemaAsJson = asPrettyJson(schema) val schemaAsJson = generateAndValidateSchema(classOf[Parent], Some(jsonNode)) println("--------------------------------------------") println(schemaAsJson) } Loading