Loading src/main/scala/com/kjetland/jackson/jsonSchema/JsonSchemaGenerator.scala +6 −15 Original line number Diff line number Diff line Loading @@ -287,14 +287,15 @@ class JsonSchemaGenerator val itemsNode = JsonNodeFactory.instance.objectNode() node.set("items", itemsNode) // When processing scala modules we sometimes get a better elementType here than later in itemsFormat val preferredElementType:Option[JavaType] = if ( _type.containedTypeCount() >= 1) Some(_type.containedType(0)) else None // We get improved result while processing scala-collections by getting elementType this way // instead of using the one which we receive in JsonArrayFormatVisitor.itemsFormat // This approach also works for Java val preferredElementType:JavaType = _type.getContentType new JsonArrayFormatVisitor with MySerializerProvider { override def itemsFormat(handler: JsonFormatVisitable, _elementType: JavaType): Unit = { l(s"expectArrayFormat - handler: $handler - elementType: ${_elementType} - preferredElementType: $preferredElementType") val elementType = preferredElementType.getOrElse(_elementType) objectMapper.acceptJsonFormatVisitor(elementType, createChild(itemsNode, currentProperty = None)) objectMapper.acceptJsonFormatVisitor(preferredElementType, createChild(itemsNode, currentProperty = None)) } override def itemsFormat(format: JsonFormatTypes): Unit = { Loading Loading @@ -604,17 +605,7 @@ class JsonSchemaGenerator val childVisitor = createChild(thisPropertyNode.main, currentProperty = prop) // Workaround for scala lists and so on if ( (propertyType.isArrayType || propertyType.isCollectionLikeType) && !classOf[Option[_]].isAssignableFrom(propertyType.getRawClass) && propertyType.containedTypeCount() >= 1) { // If visiting a scala list and using default acceptJsonFormatVisitor-approach, // we get java.lang.Object instead of actual type. // By doing it manually like this it works. l(s"JsonObjectFormatVisitor - forcing array for propertyName:$propertyName, propertyType: $propertyType") val itemType:JavaType = resolveType(propertyType, prop, objectMapper) childVisitor.expectArrayFormat(itemType).itemsFormat(null, itemType) } else if( (classOf[Option[_]].isAssignableFrom(propertyType.getRawClass) || classOf[Optional[_]].isAssignableFrom(propertyType.getRawClass) ) && propertyType.containedTypeCount() >= 1) { if( (classOf[Option[_]].isAssignableFrom(propertyType.getRawClass) || classOf[Optional[_]].isAssignableFrom(propertyType.getRawClass) ) && propertyType.containedTypeCount() >= 1) { // Property is scala Option or Java Optional. // Loading src/test/scala/com/kjetland/jackson/jsonSchema/JsonSchemaGeneratorTest.scala +6 −3 Original line number Diff line number Diff line Loading @@ -738,7 +738,8 @@ trait TestData { List("l1", "l2", "l3"), List(child1, child2), List(child1, child2).toArray, List(classNotExtendingAnything, classNotExtendingAnything) List(classNotExtendingAnything, classNotExtendingAnything), PojoWithArrays._listOfListOfStringsValues // It was difficult to construct this from scala :) ) val pojoWithArraysScala = PojoWithArraysScala( Loading @@ -747,7 +748,8 @@ trait TestData { List("l1", "l2", "l3"), List(child1, child2), List(child1, child2), List(classNotExtendingAnything, classNotExtendingAnything) List(classNotExtendingAnything, classNotExtendingAnything), List(List("l11","l12"), List("l21")) ) val recursivePojo = new RecursivePojo("t1", List(new RecursivePojo("c1", null))) Loading Loading @@ -784,7 +786,8 @@ case class PojoWithArraysScala stringList:List[String], polymorphismList:List[Parent], polymorphismArray:List[Parent], // We never use array in scala - use list instead to make it compatible with PojoWithArrays (java) regularObjectList:List[ClassNotExtendingAnything] regularObjectList:List[ClassNotExtendingAnything], listOfListOfStrings:List[List[String]] ) case class ClassNotExtendingAnythingScala(someString:String, myEnum: MyEnum, myEnumO: Option[MyEnum]) Loading src/test/scala/com/kjetland/jackson/jsonSchema/testData/PojoWithArrays.java +10 −1 Original line number Diff line number Diff line Loading @@ -5,6 +5,9 @@ import java.util.List; public class PojoWithArrays { // It was difficult to construct this from scala :) public static List<List<String>> _listOfListOfStringsValues = Arrays.asList(Arrays.asList("1","2"), Arrays.asList("3")); public int[] intArray1; public String[] stringArray; Loading @@ -14,16 +17,19 @@ public class PojoWithArrays { public Parent[] polymorphismArray; public List<ClassNotExtendingAnything> regularObjectList; public List<List<String>> listOfListOfStrings; public PojoWithArrays() { } public PojoWithArrays(int[] intArray1, String[] stringArray, List<String> stringList, List<Parent> polymorphismList, Parent[] polymorphismArray, List<ClassNotExtendingAnything> regularObjectList) { public PojoWithArrays(int[] intArray1, String[] stringArray, List<String> stringList, List<Parent> polymorphismList, Parent[] polymorphismArray, List<ClassNotExtendingAnything> regularObjectList, List<List<String>> listOfListOfStrings) { this.intArray1 = intArray1; this.stringArray = stringArray; this.stringList = stringList; this.polymorphismList = polymorphismList; this.polymorphismArray = polymorphismArray; this.regularObjectList = regularObjectList; this.listOfListOfStrings = listOfListOfStrings; } @Override Loading @@ -40,6 +46,8 @@ public class PojoWithArrays { if (polymorphismList != null ? !polymorphismList.equals(that.polymorphismList) : that.polymorphismList != null) if (regularObjectList != null ? !regularObjectList.equals(that.regularObjectList) : that.regularObjectList != null) return false; if (listOfListOfStrings != null ? !listOfListOfStrings.equals(that.listOfListOfStrings) : that.listOfListOfStrings != null) return false; // Probably incorrect - comparing Object[] arrays with Arrays.equals return Arrays.equals(polymorphismArray, that.polymorphismArray); Loading @@ -52,6 +60,7 @@ public class PojoWithArrays { result = 31 * result + (stringList != null ? stringList.hashCode() : 0); result = 31 * result + (polymorphismList != null ? polymorphismList.hashCode() : 0); result = 31 * result + (regularObjectList != null ? regularObjectList.hashCode() : 0); result = 31 * result + (listOfListOfStrings != null ? listOfListOfStrings.hashCode() : 0); result = 31 * result + Arrays.hashCode(polymorphismArray); return result; } Loading Loading
src/main/scala/com/kjetland/jackson/jsonSchema/JsonSchemaGenerator.scala +6 −15 Original line number Diff line number Diff line Loading @@ -287,14 +287,15 @@ class JsonSchemaGenerator val itemsNode = JsonNodeFactory.instance.objectNode() node.set("items", itemsNode) // When processing scala modules we sometimes get a better elementType here than later in itemsFormat val preferredElementType:Option[JavaType] = if ( _type.containedTypeCount() >= 1) Some(_type.containedType(0)) else None // We get improved result while processing scala-collections by getting elementType this way // instead of using the one which we receive in JsonArrayFormatVisitor.itemsFormat // This approach also works for Java val preferredElementType:JavaType = _type.getContentType new JsonArrayFormatVisitor with MySerializerProvider { override def itemsFormat(handler: JsonFormatVisitable, _elementType: JavaType): Unit = { l(s"expectArrayFormat - handler: $handler - elementType: ${_elementType} - preferredElementType: $preferredElementType") val elementType = preferredElementType.getOrElse(_elementType) objectMapper.acceptJsonFormatVisitor(elementType, createChild(itemsNode, currentProperty = None)) objectMapper.acceptJsonFormatVisitor(preferredElementType, createChild(itemsNode, currentProperty = None)) } override def itemsFormat(format: JsonFormatTypes): Unit = { Loading Loading @@ -604,17 +605,7 @@ class JsonSchemaGenerator val childVisitor = createChild(thisPropertyNode.main, currentProperty = prop) // Workaround for scala lists and so on if ( (propertyType.isArrayType || propertyType.isCollectionLikeType) && !classOf[Option[_]].isAssignableFrom(propertyType.getRawClass) && propertyType.containedTypeCount() >= 1) { // If visiting a scala list and using default acceptJsonFormatVisitor-approach, // we get java.lang.Object instead of actual type. // By doing it manually like this it works. l(s"JsonObjectFormatVisitor - forcing array for propertyName:$propertyName, propertyType: $propertyType") val itemType:JavaType = resolveType(propertyType, prop, objectMapper) childVisitor.expectArrayFormat(itemType).itemsFormat(null, itemType) } else if( (classOf[Option[_]].isAssignableFrom(propertyType.getRawClass) || classOf[Optional[_]].isAssignableFrom(propertyType.getRawClass) ) && propertyType.containedTypeCount() >= 1) { if( (classOf[Option[_]].isAssignableFrom(propertyType.getRawClass) || classOf[Optional[_]].isAssignableFrom(propertyType.getRawClass) ) && propertyType.containedTypeCount() >= 1) { // Property is scala Option or Java Optional. // Loading
src/test/scala/com/kjetland/jackson/jsonSchema/JsonSchemaGeneratorTest.scala +6 −3 Original line number Diff line number Diff line Loading @@ -738,7 +738,8 @@ trait TestData { List("l1", "l2", "l3"), List(child1, child2), List(child1, child2).toArray, List(classNotExtendingAnything, classNotExtendingAnything) List(classNotExtendingAnything, classNotExtendingAnything), PojoWithArrays._listOfListOfStringsValues // It was difficult to construct this from scala :) ) val pojoWithArraysScala = PojoWithArraysScala( Loading @@ -747,7 +748,8 @@ trait TestData { List("l1", "l2", "l3"), List(child1, child2), List(child1, child2), List(classNotExtendingAnything, classNotExtendingAnything) List(classNotExtendingAnything, classNotExtendingAnything), List(List("l11","l12"), List("l21")) ) val recursivePojo = new RecursivePojo("t1", List(new RecursivePojo("c1", null))) Loading Loading @@ -784,7 +786,8 @@ case class PojoWithArraysScala stringList:List[String], polymorphismList:List[Parent], polymorphismArray:List[Parent], // We never use array in scala - use list instead to make it compatible with PojoWithArrays (java) regularObjectList:List[ClassNotExtendingAnything] regularObjectList:List[ClassNotExtendingAnything], listOfListOfStrings:List[List[String]] ) case class ClassNotExtendingAnythingScala(someString:String, myEnum: MyEnum, myEnumO: Option[MyEnum]) Loading
src/test/scala/com/kjetland/jackson/jsonSchema/testData/PojoWithArrays.java +10 −1 Original line number Diff line number Diff line Loading @@ -5,6 +5,9 @@ import java.util.List; public class PojoWithArrays { // It was difficult to construct this from scala :) public static List<List<String>> _listOfListOfStringsValues = Arrays.asList(Arrays.asList("1","2"), Arrays.asList("3")); public int[] intArray1; public String[] stringArray; Loading @@ -14,16 +17,19 @@ public class PojoWithArrays { public Parent[] polymorphismArray; public List<ClassNotExtendingAnything> regularObjectList; public List<List<String>> listOfListOfStrings; public PojoWithArrays() { } public PojoWithArrays(int[] intArray1, String[] stringArray, List<String> stringList, List<Parent> polymorphismList, Parent[] polymorphismArray, List<ClassNotExtendingAnything> regularObjectList) { public PojoWithArrays(int[] intArray1, String[] stringArray, List<String> stringList, List<Parent> polymorphismList, Parent[] polymorphismArray, List<ClassNotExtendingAnything> regularObjectList, List<List<String>> listOfListOfStrings) { this.intArray1 = intArray1; this.stringArray = stringArray; this.stringList = stringList; this.polymorphismList = polymorphismList; this.polymorphismArray = polymorphismArray; this.regularObjectList = regularObjectList; this.listOfListOfStrings = listOfListOfStrings; } @Override Loading @@ -40,6 +46,8 @@ public class PojoWithArrays { if (polymorphismList != null ? !polymorphismList.equals(that.polymorphismList) : that.polymorphismList != null) if (regularObjectList != null ? !regularObjectList.equals(that.regularObjectList) : that.regularObjectList != null) return false; if (listOfListOfStrings != null ? !listOfListOfStrings.equals(that.listOfListOfStrings) : that.listOfListOfStrings != null) return false; // Probably incorrect - comparing Object[] arrays with Arrays.equals return Arrays.equals(polymorphismArray, that.polymorphismArray); Loading @@ -52,6 +60,7 @@ public class PojoWithArrays { result = 31 * result + (stringList != null ? stringList.hashCode() : 0); result = 31 * result + (polymorphismList != null ? polymorphismList.hashCode() : 0); result = 31 * result + (regularObjectList != null ? regularObjectList.hashCode() : 0); result = 31 * result + (listOfListOfStrings != null ? listOfListOfStrings.hashCode() : 0); result = 31 * result + Arrays.hashCode(polymorphismArray); return result; } Loading