From 612f6fc050628f091a0d678aa37892e81cee17b5 Mon Sep 17 00:00:00 2001 From: lunaticare Date: Sat, 28 Feb 2015 02:31:48 +0300 Subject: [PATCH] Add a test for #676 --- .../TestPolymorphicDeserialization676.java | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 src/test/java/com/fasterxml/jackson/failing/TestPolymorphicDeserialization676.java diff --git a/src/test/java/com/fasterxml/jackson/failing/TestPolymorphicDeserialization676.java b/src/test/java/com/fasterxml/jackson/failing/TestPolymorphicDeserialization676.java new file mode 100644 index 0000000000..46c2a62975 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/failing/TestPolymorphicDeserialization676.java @@ -0,0 +1,149 @@ +package com.fasterxml.jackson.failing; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.BaseMapTest; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Reproduction of [https://github.com/FasterXML/jackson-databind/issues/676] + *

+ * Deserialization of class with generic collection inside + * depends on how is was deserialized first time. + */ +public class TestPolymorphicDeserialization676 extends BaseMapTest { + private static final int TIMESTAMP = 123456; + private final MapContainer originMap; + + public TestPolymorphicDeserialization676() { + Map localMap = new HashMap(); + localMap.put("DateValue", new Date(TIMESTAMP)); + originMap = new MapContainer(localMap); + } + + /** + * If the class was first deserialized as polymorphic field, + * deserialization will fail at complex type. + */ + public void testDeSerFail() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + MapContainer deserMapBad = createDeSerMapContainer(originMap, mapper); + + // map is deserialized as list + List list = Arrays.asList(new Object[] {"java.util.Date", TIMESTAMP}); + assertFalse(list.equals(deserMapBad.getMap().get("DateValue"))); + assertTrue(originMap.equals(deserMapBad)); + assertTrue(originMap.equals(mapper.readValue(mapper.writeValueAsString(originMap), + MapContainer.class))); + } + + /** + * If the class was first deserialized as is, + * deserialization will work correctly. + */ + public void testDeSerCorrect() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + mapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS); + Map map = new HashMap(); + map.put("1", 1); + // commenting out the following statement will fail the test + assertEquals(new MapContainer(map), + mapper.readValue( + mapper.writeValueAsString(new MapContainer(map)), + MapContainer.class)); + + MapContainer deserMapGood = createDeSerMapContainer(originMap, mapper); + + assertEquals(originMap, deserMapGood); + assertEquals(new Date(TIMESTAMP), deserMapGood.getMap().get("DateValue")); + + assertEquals(originMap, mapper.readValue(mapper.writeValueAsString(originMap), MapContainer.class)); + } + + private static MapContainer createDeSerMapContainer(MapContainer originMap, ObjectMapper mapper) throws IOException { + PolymorphicValueWrapper result = new PolymorphicValueWrapper(); + result.setValue(originMap); + String json = mapper.writeValueAsString(result); + assertEquals("{\"value\":{\"@class\":" + + "\"com.fasterxml.jackson.failing.TestPolymorphicDeserialization676$MapContainer\"," + + "\"map\":{\"DateValue\":[\"java.util.Date\",123456]}}}", + json); + PolymorphicValueWrapper deserializedResult = mapper.readValue(json, PolymorphicValueWrapper.class); + return (MapContainer) deserializedResult.getValue(); + } + + @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) + public static class MapContainer { + @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, + include = JsonTypeInfo.As.PROPERTY, + property = "@class") + private Map map; + + @SuppressWarnings("unused") + public MapContainer() { + } + + public MapContainer(Map map) { + this.map = map; + } + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + MapContainer that = (MapContainer) o; + + return !(map != null ? !map.equals(that.map) : that.map != null); + } + + @Override + public int hashCode() { + return map != null ? map.hashCode() : 0; + } + + @Override + public String toString() { + return "MapContainer{" + + "map=" + map + + '}'; + } + } + + @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) + public static class PolymorphicValueWrapper { + @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, + include = JsonTypeInfo.As.PROPERTY, + property = "@class") + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + } +}