77
88import com .fasterxml .jackson .databind .*;
99import com .fasterxml .jackson .databind .cfg .JsonNodeFeature ;
10+ import com .fasterxml .jackson .databind .deser .ContextualDeserializer ;
1011import com .fasterxml .jackson .databind .jsontype .TypeDeserializer ;
1112import com .fasterxml .jackson .databind .node .*;
1213import com .fasterxml .jackson .databind .type .LogicalType ;
@@ -36,6 +37,17 @@ protected JsonNodeDeserializer() {
3637 super (JsonNode .class , null );
3738 }
3839
40+ protected JsonNodeDeserializer (JsonNodeDeserializer base ,
41+ boolean mergeArrays , boolean mergeObjects ) {
42+ super (base , mergeArrays , mergeObjects );
43+ }
44+
45+ @ Override
46+ protected JsonDeserializer <?> _createWithMerge (boolean mergeArrays ,
47+ boolean mergeObjects ) {
48+ return new JsonNodeDeserializer (this , mergeArrays , mergeObjects );
49+ }
50+
3951 /**
4052 * Factory method for accessing deserializer for specific node type
4153 */
@@ -95,6 +107,11 @@ public JsonNode deserialize(JsonParser p, DeserializationContext ctxt) throws IO
95107 return _deserializeAnyScalar (p , ctxt );
96108 }
97109
110+ @ Override
111+ public Boolean supportsUpdate (DeserializationConfig config ) {
112+ return _supportsUpdates ;
113+ }
114+
98115 /*
99116 /**********************************************************************
100117 /* Specific instances for more accurate types
@@ -115,6 +132,17 @@ final static class ObjectDeserializer
115132
116133 public static ObjectDeserializer getInstance () { return _instance ; }
117134
135+ protected ObjectDeserializer (ObjectDeserializer base ,
136+ boolean mergeArrays , boolean mergeObjects ) {
137+ super (base , mergeArrays , mergeObjects );
138+ }
139+
140+ @ Override
141+ protected JsonDeserializer <?> _createWithMerge (boolean mergeArrays ,
142+ boolean mergeObjects ) {
143+ return new ObjectDeserializer (this , mergeArrays , mergeObjects );
144+ }
145+
118146 @ Override
119147 public ObjectNode deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
120148 {
@@ -166,6 +194,17 @@ final static class ArrayDeserializer
166194
167195 public static ArrayDeserializer getInstance () { return _instance ; }
168196
197+ protected ArrayDeserializer (ArrayDeserializer base ,
198+ boolean mergeArrays , boolean mergeObjects ) {
199+ super (base , mergeArrays , mergeObjects );
200+ }
201+
202+ @ Override
203+ protected JsonDeserializer <?> _createWithMerge (boolean mergeArrays ,
204+ boolean mergeObjects ) {
205+ return new ArrayDeserializer (this , mergeArrays , mergeObjects );
206+ }
207+
169208 @ Override
170209 public ArrayNode deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
171210 {
@@ -205,12 +244,27 @@ public ArrayNode deserialize(JsonParser p, DeserializationContext ctxt,
205244@ SuppressWarnings ("serial" )
206245abstract class BaseNodeDeserializer <T extends JsonNode >
207246 extends StdDeserializer <T >
247+ implements ContextualDeserializer
208248{
209249 protected final Boolean _supportsUpdates ;
210250
251+ protected final boolean _mergeArrays ;
252+ protected final boolean _mergeObjects ;
253+
211254 public BaseNodeDeserializer (Class <T > vc , Boolean supportsUpdates ) {
212255 super (vc );
213256 _supportsUpdates = supportsUpdates ;
257+ _mergeArrays = true ;
258+ _mergeObjects = true ;
259+ }
260+
261+ protected BaseNodeDeserializer (BaseNodeDeserializer <?> base ,
262+ boolean mergeArrays , boolean mergeObjects )
263+ {
264+ super (base );
265+ _supportsUpdates = base ._supportsUpdates ;
266+ _mergeArrays = mergeArrays ;
267+ _mergeObjects = mergeObjects ;
214268 }
215269
216270 @ Override
@@ -238,6 +292,43 @@ public Boolean supportsUpdate(DeserializationConfig config) {
238292 return _supportsUpdates ;
239293 }
240294
295+ @ Override // @since 2.14
296+ public JsonDeserializer <?> createContextual (DeserializationContext ctxt ,
297+ BeanProperty property )
298+ throws JsonMappingException
299+ {
300+ // 13-Jun-2022, tatu: Should we care about property? For now, let's not yet.
301+ // (merge info there accessible via "property.getMetadata().getMergeInfo()")
302+ final DeserializationConfig cfg = ctxt .getConfig ();
303+ Boolean mergeArr = cfg .getDefaultMergeable (ArrayNode .class );
304+ Boolean mergeObj = cfg .getDefaultMergeable (ObjectNode .class );
305+ Boolean mergeNode = cfg .getDefaultMergeable (JsonNode .class );
306+
307+ final boolean mergeArrays = _shouldMerge (mergeArr , mergeNode );
308+ final boolean mergeObjects = _shouldMerge (mergeObj , mergeNode );
309+
310+ if ((mergeArrays != _mergeArrays )
311+ || (mergeObjects != _mergeObjects )) {
312+ return _createWithMerge (mergeArrays , mergeObjects );
313+ }
314+
315+ return this ;
316+ }
317+
318+ private static boolean _shouldMerge (Boolean specificMerge , Boolean generalMerge ) {
319+ if (specificMerge != null ) {
320+ return specificMerge .booleanValue ();
321+ }
322+ if (generalMerge != null ) {
323+ return generalMerge .booleanValue ();
324+ }
325+ return true ;
326+ }
327+
328+ // @since 2.14
329+ protected abstract JsonDeserializer <?> _createWithMerge (boolean mergeArrays ,
330+ boolean mergeObjects );
331+
241332 /*
242333 /**********************************************************************
243334 /* Duplicate handling
@@ -359,7 +450,7 @@ protected final JsonNode updateObject(JsonParser p, DeserializationContext ctxt,
359450 if (old instanceof ObjectNode ) {
360451 // [databind#3056]: merging only if had Object and
361452 // getting an Object
362- if (t == JsonToken .START_OBJECT ) {
453+ if (( t == JsonToken .START_OBJECT ) && _mergeObjects ) {
363454 JsonNode newValue = updateObject (p , ctxt , (ObjectNode ) old , stack );
364455 if (newValue != old ) {
365456 node .set (key , newValue );
@@ -369,7 +460,7 @@ protected final JsonNode updateObject(JsonParser p, DeserializationContext ctxt,
369460 } else if (old instanceof ArrayNode ) {
370461 // [databind#3056]: related to Object handling, ensure
371462 // Array values also match for mergeability
372- if (t == JsonToken .START_ARRAY ) {
463+ if (( t == JsonToken .START_ARRAY ) && _mergeArrays ) {
373464 // 28-Mar-2021, tatu: We'll only append entries so not very different
374465 // from "regular" deserializeArray...
375466 _deserializeContainerNoRecursion (p , ctxt , nodeFactory ,
0 commit comments