@@ -339,4 +339,195 @@ public abstract static class None {}
339
339
* @since 2.16
340
340
*/
341
341
public OptBoolean requireTypeIdForSubtypes () default OptBoolean .DEFAULT ;
342
+
343
+ /*
344
+ /**********************************************************************
345
+ /* Value class used to enclose information, allow for
346
+ /* merging of layered configuration settings.
347
+ /**********************************************************************
348
+ */
349
+
350
+ public static class Value
351
+ implements JacksonAnnotationValue <JsonTypeInfo >,
352
+ java .io .Serializable
353
+ {
354
+ private static final long serialVersionUID = 1L ;
355
+
356
+ // should not really be needed usually but make sure defalts to `NONE`; other
357
+ // values of less interest
358
+ protected final static Value EMPTY = new Value (Id .NONE , As .PROPERTY , null , null , false , null );
359
+
360
+ protected final Id _idType ;
361
+ protected final As _inclusionType ;
362
+ protected final String _propertyName ;
363
+
364
+ protected final Class <?> _defaultImpl ;
365
+ protected final boolean _idVisible ;
366
+ protected final Boolean _requireTypeIdForSubtypes ;
367
+
368
+ /*
369
+ /**********************************************************************
370
+ /* Construction
371
+ /**********************************************************************
372
+ */
373
+
374
+ protected Value (Id idType , As inclusionType ,
375
+ String propertyName , Class <?> defaultImpl , boolean idVisible , Boolean requireTypeIdForSubtypes )
376
+ {
377
+ _defaultImpl = defaultImpl ;
378
+ _idType = idType ;
379
+ _inclusionType = inclusionType ;
380
+ _propertyName = propertyName ;
381
+ _idVisible = idVisible ;
382
+ _requireTypeIdForSubtypes = requireTypeIdForSubtypes ;
383
+ }
384
+
385
+ public static Value construct (Id idType , As inclusionType ,
386
+ String propertyName , Class <?> defaultImpl , boolean idVisible , Boolean requireTypeIdForSubtypes )
387
+ {
388
+ // couple of overrides we need to apply here. First: if no propertyName specified,
389
+ // use Id-specific property name
390
+ if ((propertyName == null ) || propertyName .isEmpty ()) {
391
+ if (idType != null ) {
392
+ propertyName = idType .getDefaultPropertyName ();
393
+ } else {
394
+ propertyName = "" ;
395
+ }
396
+ }
397
+ // Although we can not do much here for special handling of `Void`, we can convert
398
+ // annotation types as `null` (== no default implementation)
399
+ if ((defaultImpl == null ) || defaultImpl .isAnnotation ()) {
400
+ defaultImpl = null ;
401
+ }
402
+ return new Value (idType , inclusionType , propertyName , defaultImpl , idVisible , requireTypeIdForSubtypes );
403
+ }
404
+
405
+ public static Value from (JsonTypeInfo src ) {
406
+ if (src == null ) {
407
+ return null ;
408
+ }
409
+ return construct (src .use (), src .include (),
410
+ src .property (), src .defaultImpl (), src .visible (), src .requireTypeIdForSubtypes ().asBoolean ());
411
+ }
412
+
413
+ /*
414
+ /**********************************************************************
415
+ /* Mutators
416
+ /**********************************************************************
417
+ */
418
+
419
+ public Value withDefaultImpl (Class <?> impl ) {
420
+ return (impl == _defaultImpl ) ? this :
421
+ new Value (_idType , _inclusionType , _propertyName , impl , _idVisible , _requireTypeIdForSubtypes );
422
+ }
423
+
424
+ public Value withIdType (Id idType ) {
425
+ return (idType == _idType ) ? this :
426
+ new Value (idType , _inclusionType , _propertyName , _defaultImpl , _idVisible , _requireTypeIdForSubtypes );
427
+ }
428
+
429
+ public Value withInclusionType (As inclusionType ) {
430
+ return (inclusionType == _inclusionType ) ? this :
431
+ new Value (_idType , inclusionType , _propertyName , _defaultImpl , _idVisible , _requireTypeIdForSubtypes );
432
+ }
433
+
434
+ public Value withPropertyName (String propName ) {
435
+ return (propName == _propertyName ) ? this :
436
+ new Value (_idType , _inclusionType , propName , _defaultImpl , _idVisible , _requireTypeIdForSubtypes );
437
+ }
438
+
439
+ public Value withIdVisible (boolean visible ) {
440
+ return (visible == _idVisible ) ? this :
441
+ new Value (_idType , _inclusionType , _propertyName , _defaultImpl , visible , _requireTypeIdForSubtypes );
442
+ }
443
+
444
+ public Value withRequireTypeIdForSubtypes (Boolean requireTypeIdForSubtypes ) {
445
+ return (_requireTypeIdForSubtypes == requireTypeIdForSubtypes ) ? this :
446
+ new Value (_idType , _inclusionType , _propertyName , _defaultImpl , _idVisible , requireTypeIdForSubtypes );
447
+ }
448
+
449
+ /*
450
+ /**********************************************************************
451
+ /* Simple accessors
452
+ /**********************************************************************
453
+ */
454
+
455
+ @ Override
456
+ public Class <JsonTypeInfo > valueFor () {
457
+ return JsonTypeInfo .class ;
458
+ }
459
+
460
+ public Class <?> getDefaultImpl () { return _defaultImpl ; }
461
+ public Id getIdType () { return _idType ; }
462
+ public As getInclusionType () { return _inclusionType ; }
463
+ public String getPropertyName () { return _propertyName ; }
464
+ public boolean getIdVisible () { return _idVisible ; }
465
+ public Boolean getRequireTypeIdForSubtypes () { return _requireTypeIdForSubtypes ; }
466
+
467
+ /**
468
+ * Static helper method for simple(r) checking of whether there's a Value instance
469
+ * that indicates that polymorphic handling is (to be) enabled.
470
+ */
471
+ public static boolean isEnabled (JsonTypeInfo .Value v ) {
472
+ return (v != null ) &&
473
+ (v ._idType != null ) && (v ._idType != Id .NONE );
474
+ }
475
+
476
+ /*
477
+ /**********************************************************************
478
+ /* Standard methods
479
+ /**********************************************************************
480
+ */
481
+
482
+ @ Override
483
+ public String toString () {
484
+ return String .format ("JsonTypeInfo.Value(idType=%s,includeAs=%s,propertyName=%s,defaultImpl=%s,idVisible=%s"
485
+ + ",requireTypeIdForSubtypes=%s)" ,
486
+ _idType , _inclusionType , _propertyName ,
487
+ ((_defaultImpl == null ) ? "NULL" : _defaultImpl .getName ()),
488
+ _idVisible , _requireTypeIdForSubtypes );
489
+ }
490
+
491
+ @ Override
492
+ public int hashCode () {
493
+ int hashCode = 1 ;
494
+ hashCode = 31 * hashCode + (_idType != null ? _idType .hashCode () : 0 );
495
+ hashCode = 31 * hashCode + (_inclusionType != null ? _inclusionType .hashCode () : 0 );
496
+ hashCode = 31 * hashCode + (_propertyName != null ? _propertyName .hashCode () : 0 );
497
+ hashCode = 31 * hashCode + (_defaultImpl != null ? _defaultImpl .hashCode () : 0 );
498
+ hashCode = 31 * hashCode + (_requireTypeIdForSubtypes ? 11 : -17 );
499
+ hashCode = 31 * hashCode + (_idVisible ? 11 : -17 );
500
+ return hashCode ;
501
+ }
502
+
503
+ @ Override
504
+ public boolean equals (Object o ) {
505
+ if (o == this ) return true ;
506
+ if (o == null ) return false ;
507
+ return (o .getClass () == getClass ())
508
+ && _equals (this , (Value ) o );
509
+ }
510
+
511
+ private static boolean _equals (Value a , Value b )
512
+ {
513
+ return (a ._idType == b ._idType )
514
+ && (a ._inclusionType == b ._inclusionType )
515
+ && (a ._defaultImpl == b ._defaultImpl )
516
+ && (a ._idVisible == b ._idVisible )
517
+ && _equal (a ._propertyName , b ._propertyName )
518
+ && _equal (a ._requireTypeIdForSubtypes , b ._requireTypeIdForSubtypes )
519
+ ;
520
+ }
521
+
522
+ private static <T > boolean _equal (T value1 , T value2 )
523
+ {
524
+ if (value1 == null ) {
525
+ return (value2 == null );
526
+ }
527
+ if (value2 == null ) {
528
+ return false ;
529
+ }
530
+ return value1 .equals (value2 );
531
+ }
532
+ }
342
533
}
0 commit comments