Skip to content

Commit c106f0c

Browse files
committed
bit more test coverage for MapDeserializer, merging
1 parent efb024e commit c106f0c

File tree

2 files changed

+62
-27
lines changed

2 files changed

+62
-27
lines changed

src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -205,30 +205,27 @@ public void setIgnorableProperties(Set<String> ignorable) {
205205
public void resolve(DeserializationContext ctxt) throws JsonMappingException
206206
{
207207
// May need to resolve types for delegate- and/or property-based creators:
208-
if (_valueInstantiator != null) {
209-
if (_valueInstantiator.canCreateUsingDelegate()) {
210-
JavaType delegateType = _valueInstantiator.getDelegateType(ctxt.getConfig());
211-
if (delegateType == null) {
212-
ctxt.reportBadDefinition(_containerType, String.format(
208+
if (_valueInstantiator.canCreateUsingDelegate()) {
209+
JavaType delegateType = _valueInstantiator.getDelegateType(ctxt.getConfig());
210+
if (delegateType == null) {
211+
ctxt.reportBadDefinition(_containerType, String.format(
213212
"Invalid delegate-creator definition for %s: value instantiator (%s) returned true for 'canCreateUsingDelegate()', but null for 'getDelegateType()'",
214-
_containerType,
215-
_valueInstantiator.getClass().getName()));
216-
}
217-
/* Theoretically should be able to get CreatorProperty for delegate
218-
* parameter to pass; but things get tricky because DelegateCreator
219-
* may contain injectable values. So, for now, let's pass nothing.
220-
*/
221-
_delegateDeserializer = findDeserializer(ctxt, delegateType, null);
222-
} else if (_valueInstantiator.canCreateUsingArrayDelegate()) {
223-
JavaType delegateType = _valueInstantiator.getArrayDelegateType(ctxt.getConfig());
224-
if (delegateType == null) {
225-
ctxt.reportBadDefinition(_containerType, String.format(
213+
_containerType,
214+
_valueInstantiator.getClass().getName()));
215+
}
216+
// Theoretically should be able to get CreatorProperty for delegate
217+
// parameter to pass; but things get tricky because DelegateCreator
218+
// may contain injectable values. So, for now, let's pass nothing.
219+
_delegateDeserializer = findDeserializer(ctxt, delegateType, null);
220+
} else if (_valueInstantiator.canCreateUsingArrayDelegate()) {
221+
JavaType delegateType = _valueInstantiator.getArrayDelegateType(ctxt.getConfig());
222+
if (delegateType == null) {
223+
ctxt.reportBadDefinition(_containerType, String.format(
226224
"Invalid delegate-creator definition for %s: value instantiator (%s) returned true for 'canCreateUsingArrayDelegate()', but null for 'getArrayDelegateType()'",
227-
_containerType,
228-
_valueInstantiator.getClass().getName()));
229-
}
230-
_delegateDeserializer = findDeserializer(ctxt, delegateType, null);
225+
_containerType,
226+
_valueInstantiator.getClass().getName()));
231227
}
228+
_delegateDeserializer = findDeserializer(ctxt, delegateType, null);
232229
}
233230
if (_valueInstantiator.canCreateFromObjectWith()) {
234231
SettableBeanProperty[] creatorProps = _valueInstantiator.getFromObjectArguments(ctxt.getConfig());
@@ -272,7 +269,7 @@ public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
272269
}
273270
Set<String> ignored = _ignorableProperties;
274271
AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
275-
if (intr != null && property != null) {
272+
if (_neitherNull(intr, property)) {
276273
AnnotatedMember member = property.getMember();
277274
if (member != null) {
278275
JsonIgnoreProperties.Value ignorals = intr.findPropertyIgnorals(member);
@@ -328,9 +325,8 @@ public ValueInstantiator getValueInstantiator() {
328325
*/
329326
@Override
330327
public boolean isCachable() {
331-
/* As per [databind#735], existence of value or key deserializer (only passed
332-
* if annotated to use non-standard one) should also prevent caching.
333-
*/
328+
// As per [databind#735], existence of value or key deserializer (only passed
329+
// if annotated to use non-standard one) should also prevent caching.
334330
return (_valueDeserializer == null)
335331
&& (_keyDeserializer == null)
336332
&& (_valueTypeDeserializer == null)

src/test/java/com/fasterxml/jackson/databind/deser/merge/MapMergeTest.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
import java.util.Map;
77

88
import com.fasterxml.jackson.annotation.JsonMerge;
9-
9+
import com.fasterxml.jackson.annotation.JsonSetter;
10+
import com.fasterxml.jackson.annotation.Nulls;
1011
import com.fasterxml.jackson.databind.*;
1112

1213
public class MapMergeTest extends BaseMapTest
@@ -31,6 +32,17 @@ public MergedMap(Map<String,Object> src) {
3132
}
3233
}
3334

35+
static class MergedIntMap
36+
{
37+
@JsonMerge
38+
public Map<Integer,Object> values;
39+
40+
protected MergedIntMap() {
41+
values = new LinkedHashMap<>();
42+
values.put(Integer.valueOf(13), "a");
43+
}
44+
}
45+
3446
/*
3547
/********************************************************
3648
/* Test methods, Map merging
@@ -42,14 +54,41 @@ public MergedMap(Map<String,Object> src) {
4254
.disable(MapperFeature.IGNORE_MERGE_FOR_UNMERGEABLE)
4355
;
4456

57+
private final ObjectMapper MAPPER_SKIP_NULLS = newObjectMapper()
58+
.setDefaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.SKIP));
59+
;
60+
4561
public void testShallowMapMerging() throws Exception
4662
{
47-
MergedMap v = MAPPER.readValue(aposToQuotes("{'values':{'c':'y'}}"), MergedMap.class);
63+
final String JSON = aposToQuotes("{'values':{'c':'y','d':null}}");
64+
MergedMap v = MAPPER.readValue(JSON, MergedMap.class);
65+
assertEquals(3, v.values.size());
66+
assertEquals("y", v.values.get("c"));
67+
assertEquals("x", v.values.get("a"));
68+
assertNull(v.values.get("d"));
69+
70+
// but also, skip nulls
71+
v = MAPPER_SKIP_NULLS.readValue(JSON, MergedMap.class);
4872
assertEquals(2, v.values.size());
4973
assertEquals("y", v.values.get("c"));
5074
assertEquals("x", v.values.get("a"));
5175
}
5276

77+
public void testShallowNonStringMerging() throws Exception
78+
{
79+
final String JSON = aposToQuotes("{'values':{'72':'b','666':null}}");
80+
MergedIntMap v = MAPPER.readValue(JSON , MergedIntMap.class);
81+
assertEquals(3, v.values.size());
82+
assertEquals("a", v.values.get(Integer.valueOf(13)));
83+
assertEquals("b", v.values.get(Integer.valueOf(72)));
84+
assertNull(v.values.get(Integer.valueOf(666)));
85+
86+
v = MAPPER_SKIP_NULLS.readValue(JSON , MergedIntMap.class);
87+
assertEquals(2, v.values.size());
88+
assertEquals("a", v.values.get(Integer.valueOf(13)));
89+
assertEquals("b", v.values.get(Integer.valueOf(72)));
90+
}
91+
5392
@SuppressWarnings("unchecked")
5493
public void testDeeperMapMerging() throws Exception
5594
{

0 commit comments

Comments
 (0)