34
34
import org .springframework .data .mapping .MappingException ;
35
35
import org .springframework .data .util .DirectFieldAccessFallbackBeanWrapper ;
36
36
import org .springframework .util .Assert ;
37
+ import org .springframework .util .ClassUtils ;
37
38
import org .springframework .util .NumberUtils ;
39
+ import org .springframework .util .ObjectUtils ;
38
40
import org .springframework .util .StringUtils ;
39
41
40
42
import com .fasterxml .jackson .annotation .JsonInclude .Include ;
153
155
*/
154
156
public class Jackson2HashMapper implements HashMapper <Object , String , Object >, HashObjectReader <String , Object > {
155
157
158
+ private static final boolean SOURCE_VERSION_PRESENT = ClassUtils .isPresent ("javax.lang.model.SourceVersion" , Jackson2HashMapper .class .getClassLoader ());
159
+
156
160
private final HashMapperModule HASH_MAPPER_MODULE = new HashMapperModule ();
157
161
158
162
private final ObjectMapper typingMapper ;
@@ -287,8 +291,7 @@ public <R> R fromHash(Class<R> type, Map<String, Object> hash) {
287
291
288
292
if (flatten ) {
289
293
290
- return typingMapper .reader ().forType (type )
291
- .readValue (untypedMapper .writeValueAsBytes (doUnflatten (hash )));
294
+ return typingMapper .reader ().forType (type ).readValue (untypedMapper .writeValueAsBytes (doUnflatten (hash )));
292
295
}
293
296
294
297
return typingMapper .treeToValue (untypedMapper .valueToTree (hash ), type );
@@ -394,10 +397,42 @@ private void flattenElement(String propertyPrefix, Object source, Map<String, Ob
394
397
if (cur .isArray ()) {
395
398
this .flattenCollection (propertyPrefix , cur .elements (), resultMap );
396
399
} else {
400
+ if (nodes .hasNext () && mightBeJavaType (cur )) {
401
+
402
+ JsonNode next = nodes .next ();
403
+
404
+ if (next .isArray ()) {
405
+ this .flattenCollection (propertyPrefix , next .elements (), resultMap );
406
+ }
407
+
408
+ if (cur .asText ().equals ("java.util.Date" )) {
409
+ resultMap .put (propertyPrefix , next .asText ());
410
+ break ;
411
+ }
412
+ if (next .isNumber ()) {
413
+ resultMap .put (propertyPrefix , next .numberValue ());
414
+ break ;
415
+ }
416
+ if (next .isTextual ()) {
417
+
418
+ resultMap .put (propertyPrefix , next .textValue ());
419
+ break ;
420
+ }
421
+ if (next .isBoolean ()) {
422
+
423
+ resultMap .put (propertyPrefix , next .booleanValue ());
424
+ break ;
425
+ }
426
+ if (next .isBinary ()) {
427
+
428
+ try {
429
+ resultMap .put (propertyPrefix , next .binaryValue ());
430
+ } catch (IOException e ) {
431
+ throw new IllegalStateException (String .format ("Cannot read binary value of '%s'" , propertyPrefix ), e );
432
+ }
433
+ break ;
434
+ }
397
435
398
- if (cur .asText ().equals ("java.util.Date" )) {
399
- resultMap .put (propertyPrefix , nodes .next ().asText ());
400
- break ;
401
436
}
402
437
}
403
438
}
@@ -409,6 +444,27 @@ private void flattenElement(String propertyPrefix, Object source, Map<String, Ob
409
444
}
410
445
}
411
446
447
+ private boolean mightBeJavaType (JsonNode node ) {
448
+
449
+ String textValue = node .asText ();
450
+ if (!SOURCE_VERSION_PRESENT ) {
451
+
452
+ if (ObjectUtils .nullSafeEquals (textValue , "java.util.Date" )) {
453
+ return true ;
454
+ }
455
+ if (ObjectUtils .nullSafeEquals (textValue , "java.math.BigInteger" )) {
456
+ return true ;
457
+ }
458
+ if (ObjectUtils .nullSafeEquals (textValue , "java.math.BigDecimal" )) {
459
+ return true ;
460
+ }
461
+
462
+ return false ;
463
+ }
464
+ return javax .lang .model .SourceVersion .isName (textValue );
465
+
466
+ }
467
+
412
468
private void flattenCollection (String propertyPrefix , Iterator <JsonNode > list , Map <String , Object > resultMap ) {
413
469
414
470
int counter = 0 ;
0 commit comments