Skip to content

Commit 2439bca

Browse files
committed
[685] Fix the issue when deserializing a Map which has a wildcard value. Added tests for wildcards on map keys and values, lists and optional.
Signed-off-by: James R. Perkins <jperkins@ibm.com>
1 parent 0804c14 commit 2439bca

File tree

3 files changed

+99
-26
lines changed

3 files changed

+99
-26
lines changed

src/main/java/org/eclipse/yasson/internal/deserializer/DeserializationModelCreator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ private ModelDeserializer<JsonParser> createMapDeserializer(CachedItem cachedIte
296296
ClassCustomization.empty(),
297297
JustReturn.instance(),
298298
MAP_KEY_EVENTS);
299-
ClassModel valueClassModel = jsonbContext.getMappingContext().getOrCreateClassModel(ReflectionUtils.getRawType(valueType));
299+
ClassModel valueClassModel = jsonbContext.getMappingContext().getOrCreateClassModel(ReflectionUtils.resolveRawType(chain, valueType));
300300
ModelDeserializer<JsonParser> valueProcessor = typeProcessor(chain,
301301
valueType,
302302
valueClassModel.getClassCustomization(),

src/test/java/org/eclipse/yasson/serializers/TypeDeserializerOnContainersTest.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,23 @@ public TestInterface deserialize(final JsonParser parser, final DeserializationC
7979
// Container classes for testing
8080
public static class MapContainer {
8181
public Map<String, TestInterface> map;
82+
public Map<?, ?> questionKeyMap;
83+
public Map<String, ?> questionValueMap;
8284
}
8385

8486
public static class ListContainer {
8587
public List<TestInterface> list;
88+
public List<?> questionList;
8689
}
8790

8891
public static class ArrayContainer {
8992
public TestInterface[] array;
9093
}
9194

95+
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
9296
public static class OptionalContainer {
93-
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
9497
public Optional<TestInterface> optional;
98+
public Optional<?> questionOptional;
9599
}
96100

97101
public static class ByteArrayContainer {
@@ -115,26 +119,41 @@ public void closeJsonb() throws Exception {
115119

116120
@Test
117121
public void testTypeDeserializerOnMapValues() {
118-
final String json = "{\"map\":{\"key1\":{\"value\":\"value1\"},\"key2\":{\"value\":\"value2\"}}}";
122+
final String json = "{\"map\":{\"key1\":{\"value\":\"value1\"},\"key2\":{\"value\":\"value2\"}}, \"questionKeyMap\":{\"qKey1\":\"value1\",\"qKey2\":\"value2\"},\"questionValueMap\":{\"key1\":\"qValue1\",\"key2\":\"qValue2\"}}";
119123

120124
final MapContainer result = jsonb.fromJson(json, MapContainer.class);
121125

122126
Assertions.assertNotNull(result.map);
123127
Assertions.assertEquals(2, result.map.size(), () -> String.format("Expected two entries got %s", result.map));
124128
Assertions.assertEquals("DESERIALIZED:value1", result.map.get("key1").getValue());
125129
Assertions.assertEquals("DESERIALIZED:value2", result.map.get("key2").getValue());
130+
131+
Assertions.assertNotNull(result.questionKeyMap);
132+
Assertions.assertEquals(2, result.questionKeyMap.size(), () -> String.format("Expected two entries got %s", result.questionKeyMap));
133+
Assertions.assertEquals("value1", result.questionKeyMap.get("qKey1"));
134+
Assertions.assertEquals("value2", result.questionKeyMap.get("qKey2"));
135+
136+
Assertions.assertNotNull(result.questionValueMap);
137+
Assertions.assertEquals(2, result.questionValueMap.size(), () -> String.format("Expected two entries got %s", result.questionValueMap));
138+
Assertions.assertEquals("qValue1", result.questionValueMap.get("key1"));
139+
Assertions.assertEquals("qValue2", result.questionValueMap.get("key2"));
126140
}
127141

128142
@Test
129143
public void testTypeDeserializerOnListElements() {
130-
final String json = "{\"list\":[{\"value\":\"value1\"},{\"value\":\"value2\"}]}";
144+
final String json = "{\"list\":[{\"value\":\"value1\"},{\"value\":\"value2\"}], \"questionList\": [\"value1\", \"value2\"]}";
131145

132146
final ListContainer result = jsonb.fromJson(json, ListContainer.class);
133147

134148
Assertions.assertNotNull(result.list);
135149
Assertions.assertEquals(2, result.list.size(), () -> String.format("Expected two entries got %s", result.list));
136150
Assertions.assertEquals("DESERIALIZED:value1", result.list.get(0).getValue());
137151
Assertions.assertEquals("DESERIALIZED:value2", result.list.get(1).getValue());
152+
153+
Assertions.assertNotNull(result.questionList);
154+
Assertions.assertEquals(2, result.questionList.size(), () -> String.format("Expected two entries got %s", result.questionList));
155+
Assertions.assertEquals("value1", result.questionList.get(0));
156+
Assertions.assertEquals("value2", result.questionList.get(1));
138157
}
139158

140159
@Test
@@ -151,13 +170,17 @@ public void testTypeDeserializerOnArrayElements() {
151170

152171
@Test
153172
public void testTypeDeserializerOnOptionalValue() {
154-
final String json = "{\"optional\":{\"value\":\"value1\"}}";
173+
final String json = "{\"optional\":{\"value\":\"value1\"},\"questionOptional\":\"value2\"}";
155174

156175
final OptionalContainer result = jsonb.fromJson(json, OptionalContainer.class);
157176

158177
Assertions.assertNotNull(result.optional);
159178
Assertions.assertTrue(result.optional.isPresent(), "Expected value to be present, but the optional was empty.");
160179
Assertions.assertEquals("DESERIALIZED:value1", result.optional.get().getValue());
180+
181+
Assertions.assertNotNull(result.questionOptional);
182+
Assertions.assertTrue(result.questionOptional.isPresent(), "Expected value to be present, but the optional was empty.");
183+
Assertions.assertEquals("value2", result.questionOptional.get());
161184
}
162185

163186
@Test

src/test/java/org/eclipse/yasson/serializers/TypeSerializerOnContainersTest.java

Lines changed: 71 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,19 @@
1212

1313
package org.eclipse.yasson.serializers;
1414

15+
import java.io.StringReader;
1516
import java.util.List;
1617
import java.util.Map;
1718
import java.util.Optional;
19+
import java.util.function.Supplier;
1820

21+
import jakarta.json.Json;
22+
import jakarta.json.JsonArray;
23+
import jakarta.json.JsonObject;
24+
import jakarta.json.JsonReader;
1925
import jakarta.json.bind.Jsonb;
2026
import jakarta.json.bind.JsonbBuilder;
27+
import jakarta.json.bind.JsonbException;
2128
import jakarta.json.bind.annotation.JsonbTypeSerializer;
2229
import jakarta.json.bind.serializer.JsonbSerializer;
2330
import jakarta.json.bind.serializer.SerializationContext;
@@ -66,35 +73,43 @@ public void serialize(final TestInterface obj, final JsonGenerator generator, fi
6673

6774
// Container classes for testing
6875
public static class MapContainer {
69-
public Map<String, TestInterface> map;
76+
public final Map<String, TestInterface> map;
77+
public final Map<?, ?> questionKeyMap;
78+
public final Map<String, ?> questionValueMap;
7079

71-
public MapContainer(Map<String, TestInterface> map) {
80+
public MapContainer(final Map<String, TestInterface> map, final Map<?, ?> questionKeyMap, final Map<String, ?> questionValueMap) {
7281
this.map = map;
82+
this.questionKeyMap = questionKeyMap;
83+
this.questionValueMap = questionValueMap;
7384
}
7485
}
7586

7687
public static class ListContainer {
77-
public List<TestInterface> list;
88+
public final List<TestInterface> list;
89+
public final List<?> questionList;
7890

79-
public ListContainer(List<TestInterface> list) {
91+
public ListContainer(final List<TestInterface> list, final List<?> questionList) {
8092
this.list = list;
93+
this.questionList = questionList;
8194
}
8295
}
8396

8497
public static class ArrayContainer {
85-
public TestInterface[] array;
98+
public final TestInterface[] array;
8699

87100
public ArrayContainer(TestInterface[] array) {
88101
this.array = array;
89102
}
90103
}
91104

105+
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
92106
public static class OptionalContainer {
93-
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
94-
public Optional<TestInterface> optional;
107+
public final Optional<TestInterface> optional;
108+
public final Optional<?> questionOptional;
95109

96-
public OptionalContainer(Optional<TestInterface> optional) {
110+
public OptionalContainer(final Optional<TestInterface> optional, final Optional<?> questionOptional) {
97111
this.optional = optional;
112+
this.questionOptional = questionOptional;
98113
}
99114
}
100115

@@ -118,31 +133,55 @@ public void testTypeSerializerOnMapValues() {
118133
final MapContainer container = new MapContainer(Map.of(
119134
"key1", new TestImpl("value1"),
120135
"key2", new TestImpl("value2")
121-
));
136+
), Map.of("qKey1", "value1", "qKey2", "value2"),
137+
Map.of("key1", "qValue1", "key2", "qValue2")
138+
);
139+
140+
final JsonObject json = toJsonObject(container);
141+
final JsonObject map = json.getJsonObject("map");
142+
final JsonObject questionKeyMap = json.getJsonObject("questionKeyMap");
143+
final JsonObject questionValueMap = json.getJsonObject("questionValueMap");
144+
145+
Supplier<String> errorMessage = () -> String.format("Expected value not found in %s", map);
146+
Assertions.assertEquals("SERIALIZED:value1", map.getString("key1"), errorMessage);
147+
Assertions.assertEquals("SERIALIZED:value2", map.getString("key2"), errorMessage);
122148

123-
final String json = jsonb.toJson(container);
124149

125-
Assertions.assertTrue(json.contains("\"key1\":\"SERIALIZED:value1\""),
126-
"Expected serialized value1 but got: " + json);
127-
Assertions.assertTrue(json.contains("\"key2\":\"SERIALIZED:value2\""),
128-
"Expected serialized value2 but got: " + json);
150+
errorMessage = () -> String.format("Expected value not found in %s", questionKeyMap);
151+
Assertions.assertEquals("value1", questionKeyMap.getString("qKey1"), errorMessage);
152+
Assertions.assertEquals("value2", questionKeyMap.getString("qKey2"), errorMessage);
153+
154+
155+
errorMessage = () -> String.format("Expected value not found in %s", questionValueMap);
156+
Assertions.assertEquals("qValue1", questionValueMap.getString("key1"), errorMessage);
157+
Assertions.assertEquals("qValue2", questionValueMap.getString("key2"), errorMessage);
129158
}
130159

131160
@Test
132161
public void testTypeSerializerOnListElements() {
133162
final ListContainer container = new ListContainer(List.of(
134163
new TestImpl("value1"),
135164
new TestImpl("value2")
136-
));
165+
), List.of("qValue1", "qValue2"));
137166

138-
final String json = jsonb.toJson(container);
167+
final JsonObject json = toJsonObject(container);
168+
final JsonArray list = json.getJsonArray("list");
169+
final JsonArray questionList = json.getJsonArray("questionList");
139170

140-
Assertions.assertEquals("{\"list\":[\"SERIALIZED:value1\",\"SERIALIZED:value2\"]}", json);
171+
Supplier<String> errorMessage = () -> String.format("Expected value not found in %s", list);
172+
Assertions.assertEquals(2, list.size(), () -> String.format("Expected a size of 2 in %s", list));
173+
Assertions.assertEquals("SERIALIZED:value1", list.getString(0), errorMessage);
174+
Assertions.assertEquals("SERIALIZED:value2", list.getString(1), errorMessage);
175+
176+
errorMessage = () -> String.format("Expected value not found in %s", questionList);
177+
Assertions.assertEquals(2, questionList.size(), () -> String.format("Expected a size of 2 in %s", questionList));
178+
Assertions.assertEquals("qValue1", questionList.getString(0), errorMessage);
179+
Assertions.assertEquals("qValue2", questionList.getString(1), errorMessage);
141180
}
142181

143182
@Test
144183
public void testTypeSerializerOnArrayElements() {
145-
final ArrayContainer container = new ArrayContainer(new TestInterface[]{
184+
final ArrayContainer container = new ArrayContainer(new TestInterface[] {
146185
new TestImpl("value1"),
147186
new TestImpl("value2")
148187
});
@@ -154,10 +193,21 @@ public void testTypeSerializerOnArrayElements() {
154193

155194
@Test
156195
public void testTypeSerializerOnOptionalValue() {
157-
final OptionalContainer container = new OptionalContainer(Optional.of(new TestImpl("value1")));
196+
final OptionalContainer container = new OptionalContainer(Optional.of(new TestImpl("value1")), Optional.of("value2"));
158197

159-
final String json = jsonb.toJson(container);
198+
final JsonObject json = toJsonObject(container);
160199

161-
Assertions.assertEquals("{\"optional\":\"SERIALIZED:value1\"}", json);
200+
Assertions.assertEquals("SERIALIZED:value1", json.getString("optional"));
201+
Assertions.assertEquals("value2", json.getString("questionOptional"));
202+
}
203+
204+
private JsonObject toJsonObject(final Object object) throws JsonbException {
205+
final String value = jsonb.toJson(object);
206+
try (
207+
StringReader reader = new StringReader(value);
208+
JsonReader jsonReader = Json.createReader(reader)
209+
) {
210+
return jsonReader.readObject();
211+
}
162212
}
163213
}

0 commit comments

Comments
 (0)