aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSwayam Raina <swayamraina@gmail.com>2020-07-11 09:28:55 +0530
committerTatu Saloranta <tatu.saloranta@iki.fi>2020-07-10 20:59:23 -0700
commit5299c1aca5df819f8421bb20f2c7808ce894f023 (patch)
tree6ac5b34ac5560c592ebc9e67508b3b79a1de033d /src
parent1369c51957f81470579272c962f1ca755e51470f (diff)
downloadjackson-databind-5299c1aca5df819f8421bb20f2c7808ce894f023.tar.gz
Issue 2761 (#2762)
Implement #2761 (support multiple type names for `@JsonSubtypes.Type`)
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java3
-rw-r--r--src/test/java/com/fasterxml/jackson/databind/jsontype/TestMultipleTypeNames.java146
2 files changed, 149 insertions, 0 deletions
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 747aeccb5..6bd2c66c5 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,9 @@ public class JacksonAnnotationIntrospector
ArrayList<NamedType> result = new ArrayList<NamedType>(types.length);
for (JsonSubTypes.Type type : types) {
result.add(new NamedType(type.value(), type.name()));
+ for (String name : type.names()) {
+ result.add(new NamedType(type.value(), name));
+ }
}
return result;
}
diff --git a/src/test/java/com/fasterxml/jackson/databind/jsontype/TestMultipleTypeNames.java b/src/test/java/com/fasterxml/jackson/databind/jsontype/TestMultipleTypeNames.java
new file mode 100644
index 000000000..b44784bc4
--- /dev/null
+++ b/src/test/java/com/fasterxml/jackson/databind/jsontype/TestMultipleTypeNames.java
@@ -0,0 +1,146 @@
+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();
+
+
+ // common classes
+ static class MultiTypeName { }
+
+ static class A extends MultiTypeName {
+ private long x;
+ public long getX() { return x; }
+ }
+
+ static class B extends MultiTypeName {
+ private float y;
+ public float getY() { return y; }
+ }
+
+
+
+
+
+ // data for test 1
+ static class WrapperForNamesTest {
+ private List<BaseForNamesTest> base;
+ public List<BaseForNamesTest> getBase() { return base; }
+ }
+
+ static class BaseForNamesTest {
+ private String type;
+ public String getType() { return type; }
+
+ @JsonTypeInfo (
+ use = JsonTypeInfo.Id.NAME,
+ include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
+ property = "type"
+ )
+ @JsonSubTypes (value = {
+ @JsonSubTypes.Type(value = A.class, names = "a"),
+ @JsonSubTypes.Type(value = B.class, names = {"b","c"}),
+ })
+ private MultiTypeName data;
+ 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; }
+ }
+
+ static class BaseForNameAndNamesTest {
+ private String type;
+ public String getType() { return type; }
+
+ @JsonTypeInfo (
+ use = JsonTypeInfo.Id.NAME,
+ include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
+ property = "type"
+ )
+ @JsonSubTypes (value = {
+ @JsonSubTypes.Type(value = A.class, name = "a"),
+ @JsonSubTypes.Type(value = B.class, names = {"b","c"}),
+ })
+ private MultiTypeName data;
+ public MultiTypeName getData() { return 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);
+
+
+ // 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) {}
+ }
+
+}