@@ -65,14 +65,20 @@ public JsonNode getNullValue(DeserializationContext ctxt) {
65
65
@ Override
66
66
public JsonNode deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
67
67
{
68
+ final ContainerStack stack = new ContainerStack ();
69
+ final JsonNodeFactory nodeF = ctxt .getNodeFactory ();
68
70
switch (p .currentTokenId ()) {
69
71
case JsonTokenId .ID_START_OBJECT :
70
- return deserializeObject (p , ctxt , ctxt .getNodeFactory ());
72
+ return deserializeObject (p , ctxt , nodeF , stack );
73
+ case JsonTokenId .ID_END_OBJECT :
74
+ return nodeF .objectNode ();
71
75
case JsonTokenId .ID_START_ARRAY :
72
- return deserializeArray (p , ctxt , ctxt .getNodeFactory ());
76
+ return deserializeArray (p , ctxt , nodeF , stack );
77
+ case JsonTokenId .ID_FIELD_NAME :
78
+ return deserializeObjectAtName (p , ctxt , nodeF , stack );
73
79
default :
74
80
}
75
- return deserializeAny (p , ctxt , ctxt . getNodeFactory () );
81
+ return deserializeAnyScalar (p , ctxt );
76
82
}
77
83
78
84
/*
@@ -96,10 +102,10 @@ final static class ObjectDeserializer
96
102
public ObjectNode deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
97
103
{
98
104
if (p .isExpectedStartObjectToken ()) {
99
- return deserializeObject (p , ctxt , ctxt .getNodeFactory ());
105
+ return deserializeObject (p , ctxt , ctxt .getNodeFactory (), new ContainerStack () );
100
106
}
101
107
if (p .hasToken (JsonToken .FIELD_NAME )) {
102
- return deserializeObjectAtName (p , ctxt , ctxt .getNodeFactory ());
108
+ return deserializeObjectAtName (p , ctxt , ctxt .getNodeFactory (), new ContainerStack () );
103
109
}
104
110
// 23-Sep-2015, tatu: Ugh. We may also be given END_OBJECT (similar to FIELD_NAME),
105
111
// if caller has advanced to the first token of Object, but for empty Object
@@ -140,7 +146,8 @@ final static class ArrayDeserializer
140
146
public ArrayNode deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
141
147
{
142
148
if (p .isExpectedStartArrayToken ()) {
143
- return deserializeArray (p , ctxt , ctxt .getNodeFactory ());
149
+ return deserializeArray (p , ctxt , ctxt .getNodeFactory (),
150
+ new ContainerStack ());
144
151
}
145
152
return (ArrayNode ) ctxt .handleUnexpectedToken (ArrayNode .class , p );
146
153
}
@@ -263,7 +270,7 @@ protected void _handleDuplicateField(JsonParser p, DeserializationContext ctxt,
263
270
* node to modify.
264
271
*/
265
272
protected final ObjectNode deserializeObject (JsonParser p , DeserializationContext ctxt ,
266
- final JsonNodeFactory nodeFactory ) throws IOException
273
+ final JsonNodeFactory nodeFactory , final ContainerStack stack ) throws IOException
267
274
{
268
275
final ObjectNode node = nodeFactory .objectNode ();
269
276
String key = p .nextFieldName ();
@@ -277,14 +284,14 @@ protected final ObjectNode deserializeObject(JsonParser p, DeserializationContex
277
284
case JsonTokenId .ID_START_OBJECT :
278
285
// Need to avoid deep recursion, so:
279
286
value = deserializeContainerNonRecursive (p , ctxt , nodeFactory ,
280
- nodeFactory .objectNode ());
287
+ stack , nodeFactory .objectNode ());
281
288
break ;
282
289
case JsonTokenId .ID_START_ARRAY :
283
290
// Ok to do one level of recursion:
284
- value = deserializeArray (p , ctxt , nodeFactory );
291
+ value = deserializeArray (p , ctxt , nodeFactory , stack );
285
292
break ;
286
293
case JsonTokenId .ID_EMBEDDED_OBJECT :
287
- value = _fromEmbedded (p , ctxt , nodeFactory );
294
+ value = _fromEmbedded (p , ctxt );
288
295
break ;
289
296
case JsonTokenId .ID_STRING :
290
297
value = nodeFactory .textNode (p .getText ());
@@ -302,7 +309,7 @@ protected final ObjectNode deserializeObject(JsonParser p, DeserializationContex
302
309
value = nodeFactory .nullNode ();
303
310
break ;
304
311
default :
305
- value = deserializeAny (p , ctxt , nodeFactory );
312
+ value = deserializeRareScalar (p , ctxt );
306
313
}
307
314
JsonNode old = node .replace (key , value );
308
315
if (old != null ) {
@@ -320,7 +327,7 @@ protected final ObjectNode deserializeObject(JsonParser p, DeserializationContex
320
327
* @since 2.9
321
328
*/
322
329
protected final ObjectNode deserializeObjectAtName (JsonParser p , DeserializationContext ctxt ,
323
- final JsonNodeFactory nodeFactory ) throws IOException
330
+ final JsonNodeFactory nodeFactory , final ContainerStack stack ) throws IOException
324
331
{
325
332
final ObjectNode node = nodeFactory .objectNode ();
326
333
String key = p .currentName ();
@@ -334,14 +341,11 @@ protected final ObjectNode deserializeObjectAtName(JsonParser p, Deserialization
334
341
case JsonTokenId .ID_START_OBJECT :
335
342
// Need to avoid deep recursion, so:
336
343
value = deserializeContainerNonRecursive (p , ctxt , nodeFactory ,
337
- nodeFactory .objectNode ());
344
+ stack , nodeFactory .objectNode ());
338
345
break ;
339
346
case JsonTokenId .ID_START_ARRAY :
340
347
// Ok to do one level of recursion:
341
- value = deserializeArray (p , ctxt , nodeFactory );
342
- break ;
343
- case JsonTokenId .ID_EMBEDDED_OBJECT :
344
- value = _fromEmbedded (p , ctxt , nodeFactory );
348
+ value = deserializeArray (p , ctxt , nodeFactory , stack );
345
349
break ;
346
350
case JsonTokenId .ID_STRING :
347
351
value = nodeFactory .textNode (p .getText ());
@@ -359,7 +363,7 @@ protected final ObjectNode deserializeObjectAtName(JsonParser p, Deserialization
359
363
value = nodeFactory .nullNode ();
360
364
break ;
361
365
default :
362
- value = deserializeAny (p , ctxt , nodeFactory );
366
+ value = deserializeRareScalar (p , ctxt );
363
367
}
364
368
JsonNode old = node .replace (key , value );
365
369
if (old != null ) {
@@ -388,6 +392,7 @@ protected final JsonNode updateObject(JsonParser p, DeserializationContext ctxt,
388
392
}
389
393
key = p .currentName ();
390
394
}
395
+ final ContainerStack stack = new ContainerStack ();
391
396
for (; key != null ; key = p .nextFieldName ()) {
392
397
// If not, fall through to regular handling
393
398
JsonToken t = p .nextToken ();
@@ -424,13 +429,10 @@ protected final JsonNode updateObject(JsonParser p, DeserializationContext ctxt,
424
429
JsonNodeFactory nodeFactory = ctxt .getNodeFactory ();
425
430
switch (t .id ()) {
426
431
case JsonTokenId .ID_START_OBJECT :
427
- value = deserializeObject (p , ctxt , nodeFactory );
432
+ value = deserializeObject (p , ctxt , nodeFactory , stack );
428
433
break ;
429
434
case JsonTokenId .ID_START_ARRAY :
430
- value = deserializeArray (p , ctxt , nodeFactory );
431
- break ;
432
- case JsonTokenId .ID_EMBEDDED_OBJECT :
433
- value = _fromEmbedded (p , ctxt , nodeFactory );
435
+ value = deserializeArray (p , ctxt , nodeFactory , stack );
434
436
break ;
435
437
case JsonTokenId .ID_STRING :
436
438
value = nodeFactory .textNode (p .getText ());
@@ -448,7 +450,7 @@ protected final JsonNode updateObject(JsonParser p, DeserializationContext ctxt,
448
450
value = nodeFactory .nullNode ();
449
451
break ;
450
452
default :
451
- value = deserializeAny (p , ctxt , nodeFactory );
453
+ value = deserializeRareScalar (p , ctxt );
452
454
}
453
455
// 15-Feb-2021, tatu: I don't think this should have been called
454
456
// on update case (was until 2.12.2) and was simply result of
@@ -465,7 +467,7 @@ protected final JsonNode updateObject(JsonParser p, DeserializationContext ctxt,
465
467
}
466
468
467
469
protected final ArrayNode deserializeArray (JsonParser p , DeserializationContext ctxt ,
468
- final JsonNodeFactory nodeFactory ) throws IOException
470
+ final JsonNodeFactory nodeFactory , final ContainerStack stack ) throws IOException
469
471
{
470
472
ArrayNode node = nodeFactory .arrayNode ();
471
473
JsonToken t ;
@@ -475,18 +477,15 @@ protected final ArrayNode deserializeArray(JsonParser p, DeserializationContext
475
477
case JsonTokenId .ID_START_OBJECT :
476
478
// Need to avoid deep recursion, so:
477
479
node .add (deserializeContainerNonRecursive (p , ctxt , nodeFactory ,
478
- nodeFactory .objectNode ()));
480
+ stack , nodeFactory .objectNode ()));
479
481
break ;
480
482
case JsonTokenId .ID_START_ARRAY :
481
483
// Need to avoid deep recursion, so:
482
484
node .add (deserializeContainerNonRecursive (p , ctxt , nodeFactory ,
483
- nodeFactory .arrayNode ()));
485
+ stack , nodeFactory .arrayNode ()));
484
486
break ;
485
487
case JsonTokenId .ID_END_ARRAY :
486
488
return node ;
487
- case JsonTokenId .ID_EMBEDDED_OBJECT :
488
- node .add (_fromEmbedded (p , ctxt , nodeFactory ));
489
- break ;
490
489
case JsonTokenId .ID_STRING :
491
490
node .add (nodeFactory .textNode (p .getText ()));
492
491
break ;
@@ -503,7 +502,7 @@ protected final ArrayNode deserializeArray(JsonParser p, DeserializationContext
503
502
node .add (nodeFactory .nullNode ());
504
503
break ;
505
504
default :
506
- node .add (deserializeAny (p , ctxt , nodeFactory ));
505
+ node .add (deserializeRareScalar (p , ctxt ));
507
506
break ;
508
507
}
509
508
}
@@ -519,20 +518,18 @@ protected final JsonNode updateArray(JsonParser p, DeserializationContext ctxt,
519
518
final ArrayNode node ) throws IOException
520
519
{
521
520
final JsonNodeFactory nodeFactory = ctxt .getNodeFactory ();
521
+ final ContainerStack stack = new ContainerStack ();
522
522
while (true ) {
523
523
JsonToken t = p .nextToken ();
524
524
switch (t .id ()) {
525
525
case JsonTokenId .ID_START_OBJECT :
526
- node .add (deserializeObject (p , ctxt , nodeFactory ));
526
+ node .add (deserializeObject (p , ctxt , nodeFactory , stack ));
527
527
break ;
528
528
case JsonTokenId .ID_START_ARRAY :
529
- node .add (deserializeArray (p , ctxt , nodeFactory ));
529
+ node .add (deserializeArray (p , ctxt , nodeFactory , stack ));
530
530
break ;
531
531
case JsonTokenId .ID_END_ARRAY :
532
532
return node ;
533
- case JsonTokenId .ID_EMBEDDED_OBJECT :
534
- node .add (_fromEmbedded (p , ctxt , nodeFactory ));
535
- break ;
536
533
case JsonTokenId .ID_STRING :
537
534
node .add (nodeFactory .textNode (p .getText ()));
538
535
break ;
@@ -549,48 +546,54 @@ protected final JsonNode updateArray(JsonParser p, DeserializationContext ctxt,
549
546
node .add (nodeFactory .nullNode ());
550
547
break ;
551
548
default :
552
- node .add (deserializeAny (p , ctxt , nodeFactory ));
549
+ node .add (deserializeRareScalar (p , ctxt ));
553
550
break ;
554
551
}
555
552
}
556
553
}
557
554
558
- protected final JsonNode deserializeAny (JsonParser p , DeserializationContext ctxt ,
559
- final JsonNodeFactory nodeFactory ) throws IOException
555
+ // Was called "deserializeAny()" in 2.12 and prior
556
+ protected final JsonNode deserializeAnyScalar (JsonParser p , DeserializationContext ctxt )
557
+ throws IOException
560
558
{
559
+ final JsonNodeFactory nodeF = ctxt .getNodeFactory ();
561
560
switch (p .currentTokenId ()) {
562
- case JsonTokenId .ID_END_OBJECT : // for empty JSON Objects we may point to this?
563
- return nodeFactory .objectNode ();
564
- case JsonTokenId .ID_FIELD_NAME :
565
- return deserializeObjectAtName (p , ctxt , nodeFactory );
566
- case JsonTokenId .ID_EMBEDDED_OBJECT :
567
- return _fromEmbedded (p , ctxt , nodeFactory );
561
+ case JsonTokenId .ID_END_OBJECT :
562
+ return nodeF .objectNode ();
568
563
case JsonTokenId .ID_STRING :
569
- return nodeFactory .textNode (p .getText ());
564
+ return nodeF .textNode (p .getText ());
570
565
case JsonTokenId .ID_NUMBER_INT :
571
- return _fromInt (p , ctxt , nodeFactory );
566
+ return _fromInt (p , ctxt , nodeF );
572
567
case JsonTokenId .ID_NUMBER_FLOAT :
573
- return _fromFloat (p , ctxt , nodeFactory );
568
+ return _fromFloat (p , ctxt );
574
569
case JsonTokenId .ID_TRUE :
575
- return nodeFactory .booleanNode (true );
570
+ return nodeF .booleanNode (true );
576
571
case JsonTokenId .ID_FALSE :
577
- return nodeFactory .booleanNode (false );
572
+ return nodeF .booleanNode (false );
578
573
case JsonTokenId .ID_NULL :
579
- return nodeFactory .nullNode ();
574
+ return nodeF .nullNode ();
575
+ case JsonTokenId .ID_EMBEDDED_OBJECT :
576
+ return _fromEmbedded (p , ctxt );
580
577
581
- /* Caller checks for these, should not get here ever
582
- case JsonTokenId.ID_START_OBJECT:
583
- return deserializeObject(p, ctxt, nodeFactory);
584
- case JsonTokenId.ID_START_ARRAY:
585
- return deserializeArray(p, ctxt, nodeFactory);
586
- */
578
+ // Caller should check for anything else
579
+ default :
580
+ }
581
+ return (JsonNode ) ctxt .handleUnexpectedToken (handledType (), p );
582
+ }
587
583
588
-
589
- // These states cannot be mapped; input stream is
590
- // off by an event or two
584
+ protected final JsonNode deserializeRareScalar (JsonParser p , DeserializationContext ctxt )
585
+ throws IOException
586
+ {
587
+ // 28-Mar-2021, tatu: Only things that caller does not check
588
+ switch (p .currentTokenId ()) {
589
+ case JsonTokenId .ID_END_OBJECT : // for empty JSON Objects we may point to this?
590
+ return ctxt .getNodeFactory ().objectNode ();
591
+ case JsonTokenId .ID_NUMBER_FLOAT :
592
+ return _fromFloat (p , ctxt );
593
+ case JsonTokenId .ID_EMBEDDED_OBJECT :
594
+ return _fromEmbedded (p , ctxt );
591
595
592
- //case END_OBJECT:
593
- //case END_ARRAY:
596
+ // Caller should check for anything else
594
597
default :
595
598
}
596
599
return (JsonNode ) ctxt .handleUnexpectedToken (handledType (), p );
@@ -599,11 +602,10 @@ protected final JsonNode deserializeAny(JsonParser p, DeserializationContext ctx
599
602
// Non-recursive alternative, used beyond certain nesting level
600
603
// @since 2.13.0
601
604
protected final ContainerNode <?> deserializeContainerNonRecursive (JsonParser p , DeserializationContext ctxt ,
602
- JsonNodeFactory nodeFactory , ContainerNode <?> root ) throws IOException
605
+ JsonNodeFactory nodeFactory , ContainerStack stack , ContainerNode <?> root )
606
+ throws IOException
603
607
{
604
608
ContainerNode <?> curr = root ;
605
- // Explicit stack of scopes to avoid recursive calls
606
- final ContainerStack stack = new ContainerStack ();
607
609
608
610
outer_loop :
609
611
while (true ) {
@@ -625,9 +627,6 @@ protected final ContainerNode<?> deserializeContainerNonRecursive(JsonParser p,
625
627
case JsonTokenId .ID_START_ARRAY :
626
628
value = newContainer = nodeFactory .arrayNode ();
627
629
break ;
628
- case JsonTokenId .ID_EMBEDDED_OBJECT :
629
- value = _fromEmbedded (p , ctxt , nodeFactory );
630
- break ;
631
630
case JsonTokenId .ID_STRING :
632
631
value = nodeFactory .textNode (p .getText ());
633
632
break ;
@@ -644,7 +643,7 @@ protected final ContainerNode<?> deserializeContainerNonRecursive(JsonParser p,
644
643
value = nodeFactory .nullNode ();
645
644
break ;
646
645
default :
647
- value = deserializeAny (p , ctxt , nodeFactory );
646
+ value = deserializeRareScalar (p , ctxt );
648
647
}
649
648
JsonNode old = currObject .replace (propName , value );
650
649
if (old != null ) {
@@ -678,9 +677,6 @@ protected final ContainerNode<?> deserializeContainerNonRecursive(JsonParser p,
678
677
continue outer_loop ;
679
678
case JsonTokenId .ID_END_ARRAY :
680
679
break arrayLoop ;
681
- case JsonTokenId .ID_EMBEDDED_OBJECT :
682
- currArray .add (_fromEmbedded (p , ctxt , nodeFactory ));
683
- break ;
684
680
case JsonTokenId .ID_STRING :
685
681
currArray .add (nodeFactory .textNode (p .getText ()));
686
682
break ;
@@ -697,7 +693,7 @@ protected final ContainerNode<?> deserializeContainerNonRecursive(JsonParser p,
697
693
currArray .add (nodeFactory .nullNode ());
698
694
break ;
699
695
default :
700
- currArray .add (deserializeAny (p , ctxt , nodeFactory ));
696
+ currArray .add (deserializeRareScalar (p , ctxt ));
701
697
break ;
702
698
}
703
699
}
@@ -735,9 +731,10 @@ protected final JsonNode _fromInt(JsonParser p, DeserializationContext ctxt,
735
731
return nodeFactory .numberNode (p .getBigIntegerValue ());
736
732
}
737
733
738
- protected final JsonNode _fromFloat (JsonParser p , DeserializationContext ctxt ,
739
- final JsonNodeFactory nodeFactory ) throws IOException
734
+ protected final JsonNode _fromFloat (JsonParser p , DeserializationContext ctxt )
735
+ throws IOException
740
736
{
737
+ final JsonNodeFactory nodeFactory = ctxt .getNodeFactory ();
741
738
JsonParser .NumberType nt = p .getNumberType ();
742
739
if (nt == JsonParser .NumberType .BIG_DECIMAL ) {
743
740
return nodeFactory .numberNode (p .getDecimalValue ());
@@ -756,27 +753,29 @@ protected final JsonNode _fromFloat(JsonParser p, DeserializationContext ctxt,
756
753
return nodeFactory .numberNode (p .getDoubleValue ());
757
754
}
758
755
759
- protected final JsonNode _fromEmbedded (JsonParser p , DeserializationContext ctxt ,
760
- JsonNodeFactory nodeFactory ) throws IOException
756
+ protected final JsonNode _fromEmbedded (JsonParser p , DeserializationContext ctxt )
757
+ throws IOException
761
758
{
762
- Object ob = p .getEmbeddedObject ();
759
+ final JsonNodeFactory nodeF = ctxt .getNodeFactory ();
760
+ final Object ob = p .getEmbeddedObject ();
761
+
763
762
if (ob == null ) { // should this occur?
764
- return nodeFactory .nullNode ();
763
+ return nodeF .nullNode ();
765
764
}
766
765
Class <?> type = ob .getClass ();
767
766
if (type == byte [].class ) { // most common special case
768
- return nodeFactory .binaryNode ((byte []) ob );
767
+ return nodeF .binaryNode ((byte []) ob );
769
768
}
770
769
// [databind#743]: Don't forget RawValue
771
770
if (ob instanceof RawValue ) {
772
- return nodeFactory .rawValueNode ((RawValue ) ob );
771
+ return nodeF .rawValueNode ((RawValue ) ob );
773
772
}
774
773
if (ob instanceof JsonNode ) {
775
774
// [databind#433]: but could also be a JsonNode hiding in there!
776
775
return (JsonNode ) ob ;
777
776
}
778
777
// any other special handling needed?
779
- return nodeFactory .pojoNode (ob );
778
+ return nodeF .pojoNode (ob );
780
779
}
781
780
782
781
/*
0 commit comments