@@ -340,12 +340,7 @@ private boolean handleArray(JsonNode node, Object source, ObjectMapper mapper, T
340
340
return false ;
341
341
}
342
342
343
- Iterator <Object > iterator = collection .iterator ();
344
- TypeInformation <?> componentType = iterator .hasNext () ? //
345
- ClassTypeInformation .from (iterator .next ().getClass ()) : //
346
- collectionType .getComponentType ();
347
-
348
- return handleArrayNode ((ArrayNode ) node , collection , mapper , componentType );
343
+ return handleArrayNode ((ArrayNode ) node , collection , mapper , collectionType .getComponentType ());
349
344
}
350
345
351
346
/**
@@ -373,16 +368,15 @@ private boolean handleArrayNode(ArrayNode array, Collection<Object> collection,
373
368
374
369
if (!value .hasNext ()) {
375
370
376
- Class <?> type = componentType == null ? Object .class : componentType .getType ();
377
- collection .add (mapper .treeToValue (jsonNode , type ));
371
+ collection .add (mapper .treeToValue (jsonNode , getTypeToMap (null , componentType ).getType ()));
378
372
379
373
continue ;
380
374
}
381
375
382
376
Object next = value .next ();
383
377
384
378
if (ArrayNode .class .isInstance (jsonNode )) {
385
- return handleArray (jsonNode , next , mapper , componentType );
379
+ return handleArray (jsonNode , next , mapper , getTypeToMap ( value , componentType ) );
386
380
}
387
381
388
382
if (ObjectNode .class .isInstance (jsonNode )) {
@@ -417,7 +411,7 @@ private void doMergeNestedMap(Map<Object, Object> source, ObjectNode node, Objec
417
411
418
412
Iterator <Entry <String , JsonNode >> fields = node .fields ();
419
413
Class <?> keyType = typeOrObject (type .getComponentType ());
420
- Class <?> valueType = typeOrObject ( type .getMapValueType () );
414
+ TypeInformation <?> valueType = type .getMapValueType ();
421
415
422
416
while (fields .hasNext ()) {
423
417
@@ -427,19 +421,19 @@ private void doMergeNestedMap(Map<Object, Object> source, ObjectNode node, Objec
427
421
428
422
Object mappedKey = mapper .readValue (quote (key ), keyType );
429
423
Object sourceValue = source .get (mappedKey );
424
+ TypeInformation <?> typeToMap = getTypeToMap (sourceValue , valueType );
430
425
431
426
if (value instanceof ObjectNode && sourceValue != null ) {
432
427
433
428
doMerge ((ObjectNode ) value , sourceValue , mapper );
434
429
435
430
} else if (value instanceof ArrayNode && sourceValue != null ) {
436
431
437
- handleArray (value , sourceValue , mapper , type );
432
+ handleArray (value , sourceValue , mapper , getTypeToMap ( sourceValue , typeToMap ) );
438
433
439
434
} else {
440
435
441
- Class <?> typeToRead = sourceValue != null ? sourceValue .getClass () : valueType ;
442
- source .put (mappedKey , mapper .treeToValue (value , typeToRead ));
436
+ source .put (mappedKey , mapper .treeToValue (value , typeToMap .getType ()));
443
437
}
444
438
445
439
fields .remove ();
@@ -554,4 +548,30 @@ private static String quote(String source) {
554
548
private static Class <?> typeOrObject (TypeInformation <?> type ) {
555
549
return type == null ? Object .class : type .getType ();
556
550
}
551
+
552
+ /**
553
+ * Returns the type to read for the given value and default type. The type will be defaulted to {@link Object} if
554
+ * missing. If the given value's type is different from the given default (i.e. more concrete) the value's type will
555
+ * be used.
556
+ *
557
+ * @param value can be {@literal null}.
558
+ * @param type can be {@literal null}.
559
+ * @return
560
+ */
561
+ private static TypeInformation <?> getTypeToMap (Object value , TypeInformation <?> type ) {
562
+
563
+ if (type == null ) {
564
+ type = ClassTypeInformation .OBJECT ;
565
+ }
566
+
567
+ if (value == null ) {
568
+ return type ;
569
+ }
570
+
571
+ if (Enum .class .isInstance (value )) {
572
+ return ClassTypeInformation .from (((Enum <?>) value ).getDeclaringClass ());
573
+ }
574
+
575
+ return value .getClass ().equals (type .getType ()) ? type : ClassTypeInformation .from (value .getClass ());
576
+ }
557
577
}
0 commit comments