Repository: johnzon Updated Branches: refs/heads/master 2b3d6d99e -> 7bbeb16fd
JOHNZON-138 add Collection support for @JsonbTypeSerializer and also for @JsonbTypeDeSerializer. They will now be applied to all their children Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/7bbeb16f Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/7bbeb16f Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/7bbeb16f Branch: refs/heads/master Commit: 7bbeb16fdb3a0d513049f79172378c5cc8d84466 Parents: 2b3d6d9 Author: Mark Struberg <[email protected]> Authored: Mon Oct 16 21:23:25 2017 +0200 Committer: Mark Struberg <[email protected]> Committed: Mon Oct 16 21:23:25 2017 +0200 ---------------------------------------------------------------------- .../apache/johnzon/jsonb/SerializerTest.java | 24 ++++++++-- .../johnzon/mapper/MappingGeneratorImpl.java | 16 ++++++- .../johnzon/mapper/MappingParserImpl.java | 19 +++++--- .../apache/johnzon/mapper/ObjectTypeTest.java | 47 +++++++++++++++++--- 4 files changed, 88 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/johnzon/blob/7bbeb16f/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/SerializerTest.java ---------------------------------------------------------------------- diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/SerializerTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/SerializerTest.java index 475fbcc..a6771ef 100644 --- a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/SerializerTest.java +++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/SerializerTest.java @@ -31,6 +31,8 @@ import javax.json.bind.serializer.SerializationContext; import javax.json.stream.JsonGenerator; import javax.json.stream.JsonParser; import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -41,19 +43,31 @@ public class SerializerTest { public void roundTrip() { final Jsonb jsonb = JsonbBuilder.create(); - final String json = "{\"foo\":{\"full\":true,\"name\":\"SerializerTest\"}}"; + final String expectedJson = "{\"foo\":{\"full\":true,\"name\":\"SerializerTest\"},\"moreFoos\":[{\"full\":true,\"name\":\"foo2\"},{\"full\":true,\"name\":\"foo3\"}]}"; final Foo foo = new Foo(); foo.name = "SerializerTest"; final Wrapper wrapper = new Wrapper(); wrapper.foo = foo; - assertEquals(json, jsonb.toJson(wrapper)); + Foo foo2 = new Foo(); + foo2.name = "foo2"; + Foo foo3 = new Foo(); + foo3.name = "foo3"; + wrapper.moreFoos.add(foo2); + wrapper.moreFoos.add(foo3); - final Wrapper deser = jsonb.fromJson(json, Wrapper.class); + assertEquals(expectedJson, jsonb.toJson(wrapper)); + + final Wrapper deser = jsonb.fromJson(expectedJson, Wrapper.class); assertEquals(foo.name, deser.foo.name); assertEquals(foo.name.length(), deser.foo.value); assertTrue(deser.foo.flag); + + assertEquals(2, deser.moreFoos.size()); + assertEquals("foo2", deser.moreFoos.get(0).name); + assertEquals(4, deser.moreFoos.get(0).value); + assertEquals(4, deser.moreFoos.get(1).value); } public static class Foo { @@ -66,6 +80,10 @@ public class SerializerTest { @JsonbTypeSerializer(FooSer.class) @JsonbTypeDeserializer(FooDeser.class) public Foo foo; + + @JsonbTypeSerializer(FooSer.class) + @JsonbTypeDeserializer(FooDeser.class) + public List<Foo> moreFoos = new ArrayList<>(); } public static class FooDeser implements JsonbDeserializer<Foo> { http://git-wip-us.apache.org/repos/asf/johnzon/blob/7bbeb16f/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java ---------------------------------------------------------------------- diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java index a76b447..7ecf2b3 100644 --- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java +++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java @@ -355,9 +355,22 @@ public class MappingGeneratorImpl implements MappingGenerator { for (final Object o : Collection.class.cast(value)) { String valJsonPointer = jsonPointers.get(o); if (valJsonPointer != null) { + // write JsonPointer instead of the original object writePrimitives(valJsonPointer); } else { - writeItem(itemConverter != null ? itemConverter.from(o) : o, ignoredProperties, config.isDeduplicateObjects() ? new JsonPointerTracker(jsonPointer, i) : null); + ObjectConverter.Writer objectConverterToUse = objectConverter; + if (objectConverterToUse == null) { + objectConverterToUse = config.findObjectConverterWriter(o.getClass()); + } + + if (objectConverterToUse != null) { + generator.writeStartObject(); + objectConverterToUse.writeJson(o, this); + generator.writeEnd(); + } else { + writeItem(itemConverter != null ? itemConverter.from(o) : o, ignoredProperties, + config.isDeduplicateObjects() ? new JsonPointerTracker(jsonPointer, i) : null); + } } i++; } @@ -381,7 +394,6 @@ public class MappingGeneratorImpl implements MappingGenerator { writeValue(String.class, true, false, false, false, null, key, adapted, null, ignoredProperties, jsonPointer); return; } else { - ObjectConverter.Writer objectConverterToUse = objectConverter; if (objectConverterToUse == null) { objectConverterToUse = config.findObjectConverterWriter(type); http://git-wip-us.apache.org/repos/asf/johnzon/blob/7bbeb16f/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java ---------------------------------------------------------------------- diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java index 5928b95..383b10c 100644 --- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java +++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java @@ -180,7 +180,7 @@ public class MappingParserImpl implements MappingParser { final Type arg = pt.getActualTypeArguments()[0]; return (T) mapCollection(mapping, jsonArray, Class.class.isInstance(arg) ? config.findAdapter(Class.class.cast(arg)) : null, - config.isDeduplicateObjects() ? new JsonPointerTracker(null, "/") : null); + null, config.isDeduplicateObjects() ? new JsonPointerTracker(null, "/") : null); } if (Object.class == targetType) { return (T) new ArrayList(asList(Object[].class.cast(buildArrayWithComponentType(jsonArray, Object.class, null, @@ -511,7 +511,7 @@ public class MappingParserImpl implements MappingParser { if (JsonArray.class == type || JsonStructure.class == type) { return jsonValue; } - return buildArray(type, JsonArray.class.cast(jsonValue), itemConverter, jsonPointer); + return buildArray(type, JsonArray.class.cast(jsonValue), itemConverter, null, jsonPointer); } else if (JsonNumber.class.isInstance(jsonValue)) { if (JsonNumber.class == type) { return jsonValue; @@ -573,7 +573,8 @@ public class MappingParserImpl implements MappingParser { throw new MapperException("Unable to parse " + jsonValue + " to " + type); } - private Object buildArray(final Type type, final JsonArray jsonArray, final Adapter itemConverter, final JsonPointerTracker jsonPointer) { + private Object buildArray(final Type type, final JsonArray jsonArray, final Adapter itemConverter, ObjectConverter.Reader objectConverter, + final JsonPointerTracker jsonPointer) { if (Class.class.isInstance(type)) { final Class clazz = Class.class.cast(type); if (clazz.isArray()) { @@ -585,12 +586,12 @@ public class MappingParserImpl implements MappingParser { if (ParameterizedType.class.isInstance(type)) { final Mappings.CollectionMapping mapping = mappings.findCollectionMapping(ParameterizedType.class.cast(type)); if (mapping != null) { - return mapCollection(mapping, jsonArray, itemConverter, jsonPointer); + return mapCollection(mapping, jsonArray, itemConverter, objectConverter, jsonPointer); } } if (Object.class == type) { - return buildArray(ANY_LIST, jsonArray, null, jsonPointer); + return buildArray(ANY_LIST, jsonArray, null, null, jsonPointer); } throw new UnsupportedOperationException("type " + type + " not supported"); @@ -608,7 +609,7 @@ public class MappingParserImpl implements MappingParser { } private <T> Collection<T> mapCollection(final Mappings.CollectionMapping mapping, final JsonArray jsonArray, - final Adapter itemConverter, JsonPointerTracker jsonPointer) { + final Adapter itemConverter, ObjectConverter.Reader objectConverter, JsonPointerTracker jsonPointer) { final Collection collection; if (SortedSet.class == mapping.raw || NavigableSet.class == mapping.raw || TreeSet.class == mapping.raw) { @@ -631,7 +632,9 @@ public class MappingParserImpl implements MappingParser { int i = 0; for (final JsonValue value : jsonArray) { - collection.add(JsonValue.NULL.equals(value) ? null : toObject(null, value, mapping.arg, itemConverter, + collection.add(JsonValue.NULL.equals(value) + ? null + : toValue(null, value, null, itemConverter, mapping.arg, objectConverter, config.isDeduplicateObjects() ? new JsonPointerTracker(jsonPointer, i) : null)); i++; } @@ -677,6 +680,8 @@ public class MappingParserImpl implements MappingParser { if (jsonValue instanceof JsonObject) { return objectConverter.fromJson((JsonObject) jsonValue, type, this); + } else if (jsonValue instanceof JsonArray) { + return buildArray(type, jsonValue.asJsonArray(), itemConverter, objectConverter, jsonPointer); } else { throw new UnsupportedOperationException("Array handling with ObjectConverter currently not implemented"); } http://git-wip-us.apache.org/repos/asf/johnzon/blob/7bbeb16f/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectTypeTest.java ---------------------------------------------------------------------- diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectTypeTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectTypeTest.java index 8ac0289..adfe0e5 100644 --- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectTypeTest.java +++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectTypeTest.java @@ -127,11 +127,15 @@ public class ObjectTypeTest { } @Test - public void multiple() { + public void testGenericList() { assumeFalse("field".equals(accessMode) /*we need setType*/); final Multiple multiple = new Multiple(); - multiple.dogs = asList(new Dog(), new Beagle()); + Poodle poodle = new Poodle(); + poodle.setHairCut(true); + Beagle beagle = new Beagle(); + beagle.setColor("brown"); + multiple.dogs = asList(poodle, beagle); final Mapper mapper = new MapperBuilder() .setAccessModeName(accessMode) .setReadAttributeBeforeWrite(true) @@ -142,18 +146,19 @@ public class ObjectTypeTest { } }).build(); final String json = "{\"dogs\":[" + - "{\"type\":\"org.apache.johnzon.mapper.ObjectTypeTest$Dog\",\"value\":{}}," + - "{\"type\":\"org.apache.johnzon.mapper.ObjectTypeTest$Beagle\",\"value\":{}}]}"; + "{\"type\":\"org.apache.johnzon.mapper.ObjectTypeTest$Poodle\",\"value\":{\"hairCut\":true}}," + + "{\"type\":\"org.apache.johnzon.mapper.ObjectTypeTest$Beagle\",\"value\":{\"color\":\"brown\"}}]}"; assertEquals(json, mapper.writeObjectAsString(multiple)); final Multiple deser = mapper.readObject(json, Multiple.class); assertEquals(2, deser.dogs.size()); - assertTrue(Dog.class.isInstance(deser.dogs.get(0))); + assertTrue(Poodle.class.isInstance(deser.dogs.get(0))); assertFalse(Beagle.class.isInstance(deser.dogs.get(0))); assertTrue(Beagle.class.isInstance(deser.dogs.get(1))); } + private Mutt getJavaObject() { Poodle mum = new Poodle(); mum.setName("Rosa"); @@ -306,7 +311,7 @@ public class ObjectTypeTest { } } - public static class Dog { + public static abstract class Dog { private String name; private Dog father; private Dog mother; @@ -366,6 +371,15 @@ public class ObjectTypeTest { } public static class Beagle extends Dog { + private String color; + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } } public static class Poodle extends Dog { @@ -414,4 +428,25 @@ public class ObjectTypeTest { return POODLES.get(jsonObject.getString("poodleName")); } } + + public static class DogOwner { + private String name; + private List<Dog> dogs; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List<Dog> getDogs() { + return dogs; + } + + public void setDogs(List<Dog> dogs) { + this.dogs = dogs; + } + } } \ No newline at end of file
