Skip to content

Commit 6f54812

Browse files
committed
Incremental work
1 parent 229ddd0 commit 6f54812

File tree

4 files changed

+68
-36
lines changed

4 files changed

+68
-36
lines changed

src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java

+24-7
Original file line numberDiff line numberDiff line change
@@ -820,15 +820,32 @@ protected SettableAnyProperty constructAnySetter(DeserializationContext ctxt,
820820
} else if (mutator instanceof AnnotatedField) {
821821
AnnotatedField af = (AnnotatedField) mutator;
822822
// get the type from the content type of the map object
823-
JavaType mapType = af.getType();
824-
mapType = resolveMemberAndTypeAnnotations(ctxt, mutator, mapType);
825-
keyType = mapType.getKeyType();
826-
valueType = mapType.getContentType();
827-
prop = new BeanProperty.Std(PropertyName.construct(mutator.getName()),
828-
mapType, null, mutator, PropertyMetadata.STD_OPTIONAL);
823+
JavaType fieldType = af.getType();
824+
// 31-Jul-2022, tatu: Not just Maps any more but also JsonNode, so:
825+
if (fieldType.isMapLikeType()) {
826+
fieldType = resolveMemberAndTypeAnnotations(ctxt, mutator, fieldType);
827+
keyType = fieldType.getKeyType();
828+
valueType = fieldType.getContentType();
829+
prop = new BeanProperty.Std(PropertyName.construct(mutator.getName()),
830+
fieldType, null, mutator, PropertyMetadata.STD_OPTIONAL);
831+
} else if (fieldType.isTypeOrSubTypeOf(JsonNode.class)) {
832+
fieldType = resolveMemberAndTypeAnnotations(ctxt, mutator, fieldType);
833+
keyType = null; // so it's plain old `String`
834+
valueType = ctxt.constructType(JsonNode.class);
835+
prop = new BeanProperty.Std(PropertyName.construct(mutator.getName()),
836+
fieldType, null, mutator, PropertyMetadata.STD_OPTIONAL);
837+
838+
// Unlike with more complicated types, here we do not allow any annotation
839+
// overrides etc but instead short-cut handling:
840+
return new SettableAnyProperty(prop, mutator, valueType,
841+
null, null, null);
842+
} else {
843+
return ctxt.reportBadDefinition(beanDesc.getType(), String.format(
844+
"Unsupported type for any-setter: %s", ClassUtil.getTypeDescription(fieldType)));
845+
}
829846
} else {
830847
return ctxt.reportBadDefinition(beanDesc.getType(), String.format(
831-
"Unrecognized mutator type for any setter: %s", mutator.getClass()));
848+
"Unrecognized mutator type for any-setter: %s", ClassUtil.nameOf(mutator.getClass())));
832849
}
833850
// First: see if there are explicitly specified
834851
// and then possible direct deserializer override on accessor

src/main/java/com/fasterxml/jackson/databind/deser/SettableAnyProperty.java

+5-12
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
/**
1616
* Class that represents a "wildcard" set method which can be used
1717
* to generically set values of otherwise unmapped (aka "unknown")
18-
* properties read from Json content.
18+
* properties read from JSON content.
1919
*<p>
2020
* !!! Note: might make sense to refactor to share some code
2121
* with {@link SettableBeanProperty}?
@@ -34,10 +34,10 @@ public class SettableAnyProperty
3434
/**
3535
* Annotated variant is needed for JDK serialization only
3636
*/
37-
final protected AnnotatedMember _setter;
37+
protected final AnnotatedMember _setter;
38+
39+
protected final boolean _setterIsField;
3840

39-
final boolean _setterIsField;
40-
4141
protected final JavaType _type;
4242

4343
protected JsonDeserializer<Object> _valueDeserializer;
@@ -68,13 +68,6 @@ public SettableAnyProperty(BeanProperty property, AnnotatedMember setter, JavaTy
6868
_setterIsField = setter instanceof AnnotatedField;
6969
}
7070

71-
@Deprecated // since 2.9
72-
public SettableAnyProperty(BeanProperty property, AnnotatedMember setter, JavaType type,
73-
JsonDeserializer<Object> valueDeser, TypeDeserializer typeDeser)
74-
{
75-
this(property, setter, type, null, valueDeser, typeDeser);
76-
}
77-
7871
public SettableAnyProperty withValueDeserializer(JsonDeserializer<Object> deser) {
7972
return new SettableAnyProperty(_property, _setter, _type,
8073
_keyDeserializer, deser, _valueTypeDeserializer);
@@ -97,7 +90,7 @@ public void fixAccess(DeserializationConfig config) {
9790
Object readResolve() {
9891
// sanity check...
9992
if (_setter == null || _setter.getAnnotated() == null) {
100-
throw new IllegalArgumentException("Missing method (broken JDK (de)serialization?)");
93+
throw new IllegalArgumentException("Missing method/field (broken JDK (de)serialization?)");
10194
}
10295
return this;
10396
}

src/test/java/com/fasterxml/jackson/databind/deser/AnySetter3394Test.java

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
package com.fasterxml.jackson.databind.deser;
22

3+
import java.util.HashMap;
4+
import java.util.Map;
5+
36
import com.fasterxml.jackson.annotation.JsonAnySetter;
47

58
import com.fasterxml.jackson.databind.*;
9+
import com.fasterxml.jackson.databind.node.ObjectNode;
610

711
// for [databind#3394]
812
public class AnySetter3394Test extends BaseMapTest
913
{
1014
static class AnySetter3394Bean {
1115
@JsonAnySetter
12-
public JsonNode extraData;
16+
public JsonNode extraData = new ObjectNode(null);
17+
}
18+
19+
private static class JsonAnySetterOnMapXXX {
20+
public int id;
21+
22+
@JsonAnySetter
23+
public Map<String, String> other;
1324
}
1425

1526
/*
@@ -22,8 +33,19 @@ static class AnySetter3394Bean {
2233

2334
public void testAnySetterWithJsonNode() throws Exception
2435
{
25-
final String DOC = a2q("{'test': 3}");
36+
final String DOC = a2q("{'test':3,'value':true}");
2637
AnySetter3394Bean bean = MAPPER.readValue(DOC, AnySetter3394Bean.class);
2738
assertEquals(DOC, ""+bean.extraData);
2839
}
40+
41+
/*
42+
public void testJsonAnySetterOnMap() throws Exception {
43+
JsonAnySetterOnMapXXX result = MAPPER.readValue("{\"id\":2,\"name\":\"Joe\", \"city\":\"New Jersey\"}",
44+
JsonAnySetterOnMapXXX.class);
45+
assertEquals(2, result.id);
46+
assertNotNull(result.other);
47+
assertEquals("Joe", result.other.get("name"));
48+
assertEquals("New Jersey", result.other.get("city"));
49+
}
50+
*/
2951
}

src/test/java/com/fasterxml/jackson/databind/deser/AnySetterTest.java

+15-15
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public void prop(String name, Base value) {
146146
props.put(name, value);
147147
}
148148
}
149-
149+
150150
static class JsonAnySetterOnMap {
151151
public int id;
152152

@@ -344,20 +344,20 @@ public void testPolymorphic() throws Exception
344344
assertTrue(ob instanceof Impl);
345345
assertEquals("xyz", ((Impl) ob).value);
346346
}
347-
348-
public void testJsonAnySetterOnMap() throws Exception {
349-
JsonAnySetterOnMap result = MAPPER.readValue("{\"id\":2,\"name\":\"Joe\", \"city\":\"New Jersey\"}",
350-
JsonAnySetterOnMap.class);
351-
assertEquals(2, result.id);
352-
assertEquals("Joe", result.other.get("name"));
353-
assertEquals("New Jersey", result.other.get("city"));
354-
}
355-
356-
public void testJsonAnySetterOnNullMap() throws Exception {
357-
JsonAnySetterOnNullMap result = MAPPER.readValue("{\"id\":2,\"name\":\"Joe\", \"city\":\"New Jersey\"}",
358-
JsonAnySetterOnNullMap.class);
359-
assertEquals(2, result.id);
360-
assertNull(result.other);
347+
348+
public void testJsonAnySetterOnMap() throws Exception {
349+
JsonAnySetterOnMap result = MAPPER.readValue("{\"id\":2,\"name\":\"Joe\", \"city\":\"New Jersey\"}",
350+
JsonAnySetterOnMap.class);
351+
assertEquals(2, result.id);
352+
assertEquals("Joe", result.other.get("name"));
353+
assertEquals("New Jersey", result.other.get("city"));
354+
}
355+
356+
public void testJsonAnySetterOnNullMap() throws Exception {
357+
JsonAnySetterOnNullMap result = MAPPER.readValue("{\"id\":2,\"name\":\"Joe\", \"city\":\"New Jersey\"}",
358+
JsonAnySetterOnNullMap.class);
359+
assertEquals(2, result.id);
360+
assertNull(result.other);
361361
}
362362

363363
final static String UNWRAPPED_JSON_349 = a2q(

0 commit comments

Comments
 (0)