7
7
8
8
import com .fasterxml .jackson .databind .*;
9
9
import com .fasterxml .jackson .databind .cfg .JsonNodeFeature ;
10
+ import com .fasterxml .jackson .databind .deser .ContextualDeserializer ;
10
11
import com .fasterxml .jackson .databind .jsontype .TypeDeserializer ;
11
12
import com .fasterxml .jackson .databind .node .*;
12
13
import com .fasterxml .jackson .databind .type .LogicalType ;
@@ -36,6 +37,17 @@ protected JsonNodeDeserializer() {
36
37
super (JsonNode .class , null );
37
38
}
38
39
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
+
39
51
/**
40
52
* Factory method for accessing deserializer for specific node type
41
53
*/
@@ -95,6 +107,11 @@ public JsonNode deserialize(JsonParser p, DeserializationContext ctxt) throws IO
95
107
return _deserializeAnyScalar (p , ctxt );
96
108
}
97
109
110
+ @ Override
111
+ public Boolean supportsUpdate (DeserializationConfig config ) {
112
+ return _supportsUpdates ;
113
+ }
114
+
98
115
/*
99
116
/**********************************************************************
100
117
/* Specific instances for more accurate types
@@ -115,6 +132,17 @@ final static class ObjectDeserializer
115
132
116
133
public static ObjectDeserializer getInstance () { return _instance ; }
117
134
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
+
118
146
@ Override
119
147
public ObjectNode deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
120
148
{
@@ -166,6 +194,17 @@ final static class ArrayDeserializer
166
194
167
195
public static ArrayDeserializer getInstance () { return _instance ; }
168
196
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
+
169
208
@ Override
170
209
public ArrayNode deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
171
210
{
@@ -205,12 +244,27 @@ public ArrayNode deserialize(JsonParser p, DeserializationContext ctxt,
205
244
@ SuppressWarnings ("serial" )
206
245
abstract class BaseNodeDeserializer <T extends JsonNode >
207
246
extends StdDeserializer <T >
247
+ implements ContextualDeserializer
208
248
{
209
249
protected final Boolean _supportsUpdates ;
210
250
251
+ protected final boolean _mergeArrays ;
252
+ protected final boolean _mergeObjects ;
253
+
211
254
public BaseNodeDeserializer (Class <T > vc , Boolean supportsUpdates ) {
212
255
super (vc );
213
256
_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 ;
214
268
}
215
269
216
270
@ Override
@@ -238,6 +292,43 @@ public Boolean supportsUpdate(DeserializationConfig config) {
238
292
return _supportsUpdates ;
239
293
}
240
294
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
+
241
332
/*
242
333
/**********************************************************************
243
334
/* Duplicate handling
@@ -359,7 +450,7 @@ protected final JsonNode updateObject(JsonParser p, DeserializationContext ctxt,
359
450
if (old instanceof ObjectNode ) {
360
451
// [databind#3056]: merging only if had Object and
361
452
// getting an Object
362
- if (t == JsonToken .START_OBJECT ) {
453
+ if (( t == JsonToken .START_OBJECT ) && _mergeObjects ) {
363
454
JsonNode newValue = updateObject (p , ctxt , (ObjectNode ) old , stack );
364
455
if (newValue != old ) {
365
456
node .set (key , newValue );
@@ -369,7 +460,7 @@ protected final JsonNode updateObject(JsonParser p, DeserializationContext ctxt,
369
460
} else if (old instanceof ArrayNode ) {
370
461
// [databind#3056]: related to Object handling, ensure
371
462
// Array values also match for mergeability
372
- if (t == JsonToken .START_ARRAY ) {
463
+ if (( t == JsonToken .START_ARRAY ) && _mergeArrays ) {
373
464
// 28-Mar-2021, tatu: We'll only append entries so not very different
374
465
// from "regular" deserializeArray...
375
466
_deserializeContainerNoRecursion (p , ctxt , nodeFactory ,
0 commit comments