aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/com/fasterxml/jackson/databind/jsontype/TestPolymorphicDeserialization676.java
blob: d6b1bcc55775c5664f9828383708add15e8f2290 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package com.fasterxml.jackson.databind.jsontype;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.*;

import java.io.IOException;
import java.util.*;

/**
 * Reproduction of [https://github.com/FasterXML/jackson-databind/issues/676]
 * <p/>
 * 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;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class MapContainer {
        @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,
                include = JsonTypeInfo.As.PROPERTY,
                property = "@class")
        public Map<String, Object> map;

        public MapContainer() { }

        public MapContainer(Map<String, Object> map) {
            this.map = map;
        }

        @Override
        public boolean equals(Object o) {
            if (o == this) return true;
            if (!(o instanceof MapContainer)) return false;
            return map.equals(((MapContainer) o).map);
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("[MapContainer:");
            for (Map.Entry<String,Object> entry : map.entrySet()) {
                sb.append(" '").append(entry.getKey()).append("' : ");
                Object value = entry.getValue();
                if (value == null) {
                    sb.append("null");
                } else {
                    sb.append("(").append(value.getClass().getName()).append(") ");
                    sb.append(String.valueOf(value));
                }
            }
            return sb.append(']').toString();
        }
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class PolymorphicValueWrapper {
        @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,
                include = JsonTypeInfo.As.PROPERTY,
                property = "@class")
        public Object value;
    }

    private final MapContainer originMap;

    public TestPolymorphicDeserialization676() {
        Map<String, Object> localMap = new LinkedHashMap<String, Object>();
        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);
        assertEquals(originMap, deserMapBad);
        assertEquals(originMap,
                mapper.readValue(mapper.writeValueAsString(originMap), MapContainer.class));
    }

    public void testDeSerCorrect() throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
        Map<String, Object> map = new HashMap<String, Object>();
        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.map.get("DateValue"));

        assertEquals(originMap, mapper.readValue(mapper.writeValueAsString(originMap), MapContainer.class));
    }

    private MapContainer createDeSerMapContainer(MapContainer src, ObjectMapper mapper) throws IOException {
        PolymorphicValueWrapper result = new PolymorphicValueWrapper();
        result.value = src;
        String json = mapper.writeValueAsString(result);
        assertEquals("{\"value\":{\"@class\":"
                + "\""+getClass().getName()+"$MapContainer\","
                + "\"map\":{\"DateValue\":[\"java.util.Date\",123456]}}}",
                json);
        PolymorphicValueWrapper deserializedResult = mapper.readValue(json, PolymorphicValueWrapper.class);
        return (MapContainer) deserializedResult.value;
    }
}