diff options
author | Tatu Saloranta <tatu.saloranta@iki.fi> | 2020-07-10 21:12:50 -0700 |
---|---|---|
committer | Tatu Saloranta <tatu.saloranta@iki.fi> | 2020-07-10 21:12:50 -0700 |
commit | ef628ca32f107c6e6dd774f64d8a255ef02fe347 (patch) | |
tree | d268e9080a897e1936f411f545cf912cca8844b0 | |
parent | 5299c1aca5df819f8421bb20f2c7808ce894f023 (diff) | |
download | jackson-databind-ef628ca32f107c6e6dd774f64d8a255ef02fe347.tar.gz |
Backport #2761 in 2.12
4 files changed, 64 insertions, 67 deletions
diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index 139acc73e..d4b27b098 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -1174,3 +1174,7 @@ David Bidorff (bidorffOL@github) Jendrik Johannes (jjohannes@github) * Contributed #2726: Add Gradle Module Metadata for version alignment with Gradle 6 (2.12.0) + +Swayam Raina (swayamraina@github) + * Contributed #2761: Support multiple names in `JsonSubType.Type` + (2.12.0) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 6394d9d72..18c288b3c 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -39,6 +39,8 @@ Project: jackson-databind #2732: Allow `JsonNode` auto-convert into `ArrayNode` if duplicates found (for XML) #2733: Allow values of "untyped" auto-convert into `List` if duplicates found (for XML) #2751: Add `ValueInstantiator.createContextual(...) +#2761: Support multiple names in `JsonSubType.Type` + (contributed by Swayam R) #2776: Explicitly fail (de)serialization of `org.joda.time.*` types in absence of registered custom (de)serializers #2784: Trailing zeros are stripped when deserializing BigDecimal values inside a diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java b/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java index 6bd2c66c5..731102df8 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java @@ -592,6 +592,7 @@ public class JacksonAnnotationIntrospector ArrayList<NamedType> result = new ArrayList<NamedType>(types.length); for (JsonSubTypes.Type type : types) { result.add(new NamedType(type.value(), type.name())); + // [databind#2761]: alternative set of names to use for (String name : type.names()) { result.add(new NamedType(type.value(), name)); } diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/TestMultipleTypeNames.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/TestMultipleTypeNames.java index b44784bc4..021dd1cb2 100644 --- a/src/test/java/com/fasterxml/jackson/databind/jsontype/TestMultipleTypeNames.java +++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/TestMultipleTypeNames.java @@ -2,29 +2,17 @@ package com.fasterxml.jackson.databind.jsontype; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; + import com.fasterxml.jackson.databind.BaseMapTest; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; -import org.junit.Assert; import java.util.List; - -/** - * Tests for sub-types id user uses, - * 1. only names in all sub-types - * 2. 'names' for multi-keys while 'name' for singular keys - * - * [ annotations#171 ] - * As per this feature, keys holding similar java object types can be incorporated - * within the same annotation. - * See this <a href="https://github.com/FasterXML/jackson-annotations/issues/171">issue/improvement</a> - */ -public class TestMultipleTypeNames extends BaseMapTest { - - // serializer-deserializer - private final ObjectMapper MAPPER = objectMapper(); - +// Tests for [databind#2761] (and [annotations#171] +public class TestMultipleTypeNames extends BaseMapTest +{ + private final ObjectMapper MAPPER = newJsonMapper(); // common classes static class MultiTypeName { } @@ -39,10 +27,6 @@ public class TestMultipleTypeNames extends BaseMapTest { public float getY() { return y; } } - - - - // data for test 1 static class WrapperForNamesTest { private List<BaseForNamesTest> base; @@ -53,12 +37,12 @@ public class TestMultipleTypeNames extends BaseMapTest { private String type; public String getType() { return type; } - @JsonTypeInfo ( + @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type" ) - @JsonSubTypes (value = { + @JsonSubTypes(value = { @JsonSubTypes.Type(value = A.class, names = "a"), @JsonSubTypes.Type(value = B.class, names = {"b","c"}), }) @@ -66,36 +50,6 @@ public class TestMultipleTypeNames extends BaseMapTest { public MultiTypeName getData() { return data; } } - public void testOnlyNames () throws Exception { - String json; - WrapperForNamesTest w; - - // TC 1 : all KV serialisation - json = "{\"base\": [{\"type\":\"a\", \"data\": {\"x\": 5}}, {\"type\":\"b\", \"data\": {\"y\": 3.1}}, {\"type\":\"c\", \"data\": {\"y\": 33.8}}]}"; - w = MAPPER.readValue(json, WrapperForNamesTest.class); - Assert.assertNotNull(w); - Assert.assertEquals(3, w.base.size()); - Assert.assertTrue(w.base.get(0).data instanceof A); - Assert.assertEquals(5l, ((A) w.base.get(0).data).x); - Assert.assertTrue(w.base.get(1).data instanceof B); - Assert.assertEquals(3.1f, ((B) w.base.get(1).data).y, 0); - Assert.assertTrue(w.base.get(2).data instanceof B); - Assert.assertEquals(33.8f, ((B) w.base.get(2).data).y, 0); - - - // TC 2 : incorrect serialisation - json = "{\"data\": [{\"type\":\"a\", \"data\": {\"x\": 2.2}}, {\"type\":\"b\", \"data\": {\"y\": 5.3}}, {\"type\":\"c\", \"data\": {\"y\": 9.8}}]}"; - try { - MAPPER.readValue(json, WrapperForNamesTest.class); - Assert.fail("This serialisation should fail 'coz of x being float"); - } catch (UnrecognizedPropertyException e) {} - } - - - - - - // data for test 2 static class WrapperForNameAndNamesTest { private List<BaseForNameAndNamesTest> base; public List<BaseForNameAndNamesTest> getBase() { return base; } @@ -105,12 +59,12 @@ public class TestMultipleTypeNames extends BaseMapTest { private String type; public String getType() { return type; } - @JsonTypeInfo ( + @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type" ) - @JsonSubTypes (value = { + @JsonSubTypes(value = { @JsonSubTypes.Type(value = A.class, name = "a"), @JsonSubTypes.Type(value = B.class, names = {"b","c"}), }) @@ -118,29 +72,65 @@ public class TestMultipleTypeNames extends BaseMapTest { public MultiTypeName getData() { return data; } } - public void testNameAndNames () throws Exception { + /* + /********************************************************** + /* Test methods + /********************************************************** + */ + + public void testOnlyNames() throws Exception + { + String json; + WrapperForNamesTest w; + + // TC 1 : all KV serialisation + json = "{\"base\": [{\"type\":\"a\", \"data\": {\"x\": 5}}, {\"type\":\"b\", \"data\": {\"y\": 3.1}}, {\"type\":\"c\", \"data\": {\"y\": 33.8}}]}"; + w = MAPPER.readValue(json, WrapperForNamesTest.class); + assertNotNull(w); + assertEquals(3, w.base.size()); + assertTrue(w.base.get(0).data instanceof A); + assertEquals(5l, ((A) w.base.get(0).data).x); + assertTrue(w.base.get(1).data instanceof B); + assertEquals(3.1f, ((B) w.base.get(1).data).y, 0); + assertTrue(w.base.get(2).data instanceof B); + assertEquals(33.8f, ((B) w.base.get(2).data).y, 0); + + + // TC 2 : incorrect serialisation + json = "{\"data\": [{\"type\":\"a\", \"data\": {\"x\": 2.2}}, {\"type\":\"b\", \"data\": {\"y\": 5.3}}, {\"type\":\"c\", \"data\": {\"y\": 9.8}}]}"; + try { + MAPPER.readValue(json, WrapperForNamesTest.class); + fail("This serialisation should fail 'coz of x being float"); + } catch (UnrecognizedPropertyException e) { + verifyException(e, "Unrecognized field \"data\""); + } + } + + public void testNameAndNames() throws Exception + { String json; WrapperForNameAndNamesTest w; // TC 1 : all KV serialisation json = "{\"base\": [{\"type\":\"a\", \"data\": {\"x\": 5}}, {\"type\":\"b\", \"data\": {\"y\": 3.1}}, {\"type\":\"c\", \"data\": {\"y\": 33.8}}]}"; w = MAPPER.readValue(json, WrapperForNameAndNamesTest.class); - Assert.assertNotNull(w); - Assert.assertEquals(3, w.base.size()); - Assert.assertTrue(w.base.get(0).data instanceof A); - Assert.assertEquals(5l, ((A) w.base.get(0).data).x); - Assert.assertTrue(w.base.get(1).data instanceof B); - Assert.assertEquals(3.1f, ((B) w.base.get(1).data).y, 0); - Assert.assertTrue(w.base.get(2).data instanceof B); - Assert.assertEquals(33.8f, ((B) w.base.get(2).data).y, 0); + assertNotNull(w); + assertEquals(3, w.base.size()); + assertTrue(w.base.get(0).data instanceof A); + assertEquals(5l, ((A) w.base.get(0).data).x); + assertTrue(w.base.get(1).data instanceof B); + assertEquals(3.1f, ((B) w.base.get(1).data).y, 0); + assertTrue(w.base.get(2).data instanceof B); + assertEquals(33.8f, ((B) w.base.get(2).data).y, 0); // TC 2 : incorrect serialisation json = "{\"data\": [{\"type\":\"a\", \"data\": {\"x\": 2.2}}, {\"type\":\"b\", \"data\": {\"y\": 5.3}}, {\"type\":\"c\", \"data\": {\"y\": 9.8}}]}"; try { MAPPER.readValue(json, WrapperForNameAndNamesTest.class); - Assert.fail("This serialisation should fail 'coz of x being float"); - } catch (UnrecognizedPropertyException e) {} + fail("This serialisation should fail 'coz of x being float"); + } catch (UnrecognizedPropertyException e) { + verifyException(e, "Unrecognized field \"data\""); + } } - } |