Skip to content

Commit fe8c599

Browse files
committed
Merge pull request #713 from lunaticare/issue676
Add a test for #676
2 parents 935ccaf + 612f6fc commit fe8c599

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package com.fasterxml.jackson.failing;
2+
3+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
4+
import com.fasterxml.jackson.databind.BaseMapTest;
5+
import com.fasterxml.jackson.databind.ObjectMapper;
6+
import com.fasterxml.jackson.databind.SerializationFeature;
7+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
8+
9+
import java.io.IOException;
10+
import java.util.Arrays;
11+
import java.util.Date;
12+
import java.util.HashMap;
13+
import java.util.List;
14+
import java.util.Map;
15+
16+
/**
17+
* Reproduction of [https://github.com/FasterXML/jackson-databind/issues/676]
18+
* <p/>
19+
* Deserialization of class with generic collection inside
20+
* depends on how is was deserialized first time.
21+
*/
22+
public class TestPolymorphicDeserialization676 extends BaseMapTest {
23+
private static final int TIMESTAMP = 123456;
24+
private final MapContainer originMap;
25+
26+
public TestPolymorphicDeserialization676() {
27+
Map<String, Object> localMap = new HashMap<String, Object>();
28+
localMap.put("DateValue", new Date(TIMESTAMP));
29+
originMap = new MapContainer(localMap);
30+
}
31+
32+
/**
33+
* If the class was first deserialized as polymorphic field,
34+
* deserialization will fail at complex type.
35+
*/
36+
public void testDeSerFail() throws IOException {
37+
ObjectMapper mapper = new ObjectMapper();
38+
39+
MapContainer deserMapBad = createDeSerMapContainer(originMap, mapper);
40+
41+
// map is deserialized as list
42+
List<Object> list = Arrays.asList(new Object[] {"java.util.Date", TIMESTAMP});
43+
assertFalse(list.equals(deserMapBad.getMap().get("DateValue")));
44+
assertTrue(originMap.equals(deserMapBad));
45+
assertTrue(originMap.equals(mapper.readValue(mapper.writeValueAsString(originMap),
46+
MapContainer.class)));
47+
}
48+
49+
/**
50+
* If the class was first deserialized as is,
51+
* deserialization will work correctly.
52+
*/
53+
public void testDeSerCorrect() throws IOException {
54+
ObjectMapper mapper = new ObjectMapper();
55+
mapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
56+
Map<String, Object> map = new HashMap<String, Object>();
57+
map.put("1", 1);
58+
// commenting out the following statement will fail the test
59+
assertEquals(new MapContainer(map),
60+
mapper.readValue(
61+
mapper.writeValueAsString(new MapContainer(map)),
62+
MapContainer.class));
63+
64+
MapContainer deserMapGood = createDeSerMapContainer(originMap, mapper);
65+
66+
assertEquals(originMap, deserMapGood);
67+
assertEquals(new Date(TIMESTAMP), deserMapGood.getMap().get("DateValue"));
68+
69+
assertEquals(originMap, mapper.readValue(mapper.writeValueAsString(originMap), MapContainer.class));
70+
}
71+
72+
private static MapContainer createDeSerMapContainer(MapContainer originMap, ObjectMapper mapper) throws IOException {
73+
PolymorphicValueWrapper result = new PolymorphicValueWrapper();
74+
result.setValue(originMap);
75+
String json = mapper.writeValueAsString(result);
76+
assertEquals("{\"value\":{\"@class\":"
77+
+ "\"com.fasterxml.jackson.failing.TestPolymorphicDeserialization676$MapContainer\","
78+
+ "\"map\":{\"DateValue\":[\"java.util.Date\",123456]}}}",
79+
json);
80+
PolymorphicValueWrapper deserializedResult = mapper.readValue(json, PolymorphicValueWrapper.class);
81+
return (MapContainer) deserializedResult.getValue();
82+
}
83+
84+
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
85+
public static class MapContainer {
86+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,
87+
include = JsonTypeInfo.As.PROPERTY,
88+
property = "@class")
89+
private Map<String, Object> map;
90+
91+
@SuppressWarnings("unused")
92+
public MapContainer() {
93+
}
94+
95+
public MapContainer(Map<String, Object> map) {
96+
this.map = map;
97+
}
98+
99+
public Map<String, Object> getMap() {
100+
return map;
101+
}
102+
103+
public void setMap(Map<String, Object> map) {
104+
this.map = map;
105+
}
106+
107+
@Override
108+
public boolean equals(Object o) {
109+
if (this == o) {
110+
return true;
111+
}
112+
if (o == null || getClass() != o.getClass()) {
113+
return false;
114+
}
115+
116+
MapContainer that = (MapContainer) o;
117+
118+
return !(map != null ? !map.equals(that.map) : that.map != null);
119+
}
120+
121+
@Override
122+
public int hashCode() {
123+
return map != null ? map.hashCode() : 0;
124+
}
125+
126+
@Override
127+
public String toString() {
128+
return "MapContainer{" +
129+
"map=" + map +
130+
'}';
131+
}
132+
}
133+
134+
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
135+
public static class PolymorphicValueWrapper {
136+
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,
137+
include = JsonTypeInfo.As.PROPERTY,
138+
property = "@class")
139+
private Object value;
140+
141+
public Object getValue() {
142+
return value;
143+
}
144+
145+
public void setValue(Object value) {
146+
this.value = value;
147+
}
148+
}
149+
}

0 commit comments

Comments
 (0)