9
9
import com .fasterxml .jackson .databind .*;
10
10
import com .fasterxml .jackson .databind .cfg .HandlerInstantiator ;
11
11
import com .fasterxml .jackson .databind .cfg .MapperConfig ;
12
+ import com .fasterxml .jackson .databind .jdk14 .JDK14Util ;
12
13
import com .fasterxml .jackson .databind .util .ClassUtil ;
13
14
14
15
/**
@@ -610,23 +611,53 @@ protected void _addFields(Map<String, POJOPropertyBuilder> props)
610
611
protected void _addCreators (Map <String , POJOPropertyBuilder > props )
611
612
{
612
613
// can be null if annotation processing is disabled...
613
- if (!_useAnnotations ) {
614
- return ;
615
- }
616
- for (AnnotatedConstructor ctor : _classDef .getConstructors ()) {
617
- if (_creatorProperties == null ) {
618
- _creatorProperties = new LinkedList <POJOPropertyBuilder >();
614
+ if (_useAnnotations ) {
615
+ for (AnnotatedConstructor ctor : _classDef .getConstructors ()) {
616
+ if (_creatorProperties == null ) {
617
+ _creatorProperties = new LinkedList <POJOPropertyBuilder >();
618
+ }
619
+ for (int i = 0 , len = ctor .getParameterCount (); i < len ; ++i ) {
620
+ _addCreatorParam (props , ctor .getParameter (i ));
621
+ }
619
622
}
620
- for (int i = 0 , len = ctor .getParameterCount (); i < len ; ++i ) {
621
- _addCreatorParam (props , ctor .getParameter (i ));
623
+ for (AnnotatedMethod factory : _classDef .getFactoryMethods ()) {
624
+ if (_creatorProperties == null ) {
625
+ _creatorProperties = new LinkedList <POJOPropertyBuilder >();
626
+ }
627
+ for (int i = 0 , len = factory .getParameterCount (); i < len ; ++i ) {
628
+ _addCreatorParam (props , factory .getParameter (i ));
629
+ }
622
630
}
623
631
}
624
- for (AnnotatedMethod factory : _classDef .getFactoryMethods ()) {
625
- if (_creatorProperties == null ) {
626
- _creatorProperties = new LinkedList <POJOPropertyBuilder >();
627
- }
628
- for (int i = 0 , len = factory .getParameterCount (); i < len ; ++i ) {
629
- _addCreatorParam (props , factory .getParameter (i ));
632
+ if (_classDef .getType ().isRecordType ()) {
633
+ List <String > recordComponentNames = new ArrayList <String >();
634
+ AnnotatedConstructor canonicalCtor = JDK14Util .findRecordConstructor (
635
+ _classDef , _annotationIntrospector , _config , recordComponentNames );
636
+
637
+ if (canonicalCtor != null ) {
638
+ if (_creatorProperties == null ) {
639
+ _creatorProperties = new LinkedList <POJOPropertyBuilder >();
640
+ }
641
+
642
+ Set <AnnotatedParameter > registeredParams = new HashSet <AnnotatedParameter >();
643
+ for (POJOPropertyBuilder creatorProperty : _creatorProperties ) {
644
+ Iterator <AnnotatedParameter > iter = creatorProperty .getConstructorParameters ();
645
+ while (iter .hasNext ()) {
646
+ AnnotatedParameter param = iter .next ();
647
+ if (param .getOwner ().equals (canonicalCtor )) {
648
+ registeredParams .add (param );
649
+ }
650
+ }
651
+ }
652
+
653
+ if (_creatorProperties .isEmpty () || !registeredParams .isEmpty ()) {
654
+ for (int i = 0 ; i < canonicalCtor .getParameterCount (); i ++) {
655
+ AnnotatedParameter param = canonicalCtor .getParameter (i );
656
+ if (!registeredParams .contains (param )) {
657
+ _addCreatorParam (props , param , recordComponentNames .get (i ));
658
+ }
659
+ }
660
+ }
630
661
}
631
662
}
632
663
}
@@ -637,11 +668,23 @@ protected void _addCreators(Map<String, POJOPropertyBuilder> props)
637
668
protected void _addCreatorParam (Map <String , POJOPropertyBuilder > props ,
638
669
AnnotatedParameter param )
639
670
{
640
- // JDK 8, paranamer, Scala can give implicit name
641
- String impl = _annotationIntrospector .findImplicitPropertyName (param );
642
- if (impl == null ) {
643
- impl = "" ;
671
+ _addCreatorParam (props , param , null );
672
+ }
673
+
674
+ private void _addCreatorParam (Map <String , POJOPropertyBuilder > props ,
675
+ AnnotatedParameter param , String recordComponentName )
676
+ {
677
+ String impl ;
678
+ if (recordComponentName != null ) {
679
+ impl = recordComponentName ;
680
+ } else {
681
+ // JDK 8, paranamer, Scala can give implicit name
682
+ impl = _annotationIntrospector .findImplicitPropertyName (param );
683
+ if (impl == null ) {
684
+ impl = "" ;
685
+ }
644
686
}
687
+
645
688
PropertyName pn = _annotationIntrospector .findNameForDeserialization (param );
646
689
boolean expl = (pn != null && !pn .isEmpty ());
647
690
if (!expl ) {
@@ -650,10 +693,13 @@ protected void _addCreatorParam(Map<String, POJOPropertyBuilder> props,
650
693
// this creator parameter -- may or may not be a problem, verified at a later point.
651
694
return ;
652
695
}
653
- // Also: if this occurs, there MUST be explicit annotation on creator itself
654
- JsonCreator .Mode creatorMode = _annotationIntrospector .findCreatorAnnotation (_config ,
655
- param .getOwner ());
656
- if ((creatorMode == null ) || (creatorMode == JsonCreator .Mode .DISABLED )) {
696
+
697
+ // Also: if this occurs, there MUST be explicit annotation on creator itself...
698
+ JsonCreator .Mode creatorMode = _annotationIntrospector .findCreatorAnnotation (_config , param .getOwner ());
699
+ // ...or is a Records canonical constructor
700
+ boolean isCanonicalConstructor = recordComponentName != null ;
701
+
702
+ if ((creatorMode == null || creatorMode == JsonCreator .Mode .DISABLED ) && !isCanonicalConstructor ) {
657
703
return ;
658
704
}
659
705
pn = PropertyName .construct (impl );
@@ -902,6 +948,17 @@ protected void _removeUnwantedProperties(Map<String, POJOPropertyBuilder> props)
902
948
}
903
949
// Otherwise, check ignorals
904
950
if (prop .anyIgnorals ()) {
951
+ // Special handling for Records, as they do not have mutators so relying on constructors with (mostly)
952
+ // implicitly-named parameters...
953
+ if (_classDef .getType ().isRecordType ()) {
954
+ // ...so can only remove ignored field and/or accessors, not constructor parameters that are needed
955
+ // for instantiation...
956
+ prop .removeIgnored ();
957
+ // ...which will then be ignored (the incoming property value) during deserialization
958
+ _collectIgnorals (prop .getName ());
959
+ continue ;
960
+ }
961
+
905
962
// first: if one or more ignorals, and no explicit markers, remove the whole thing
906
963
// 16-May-2022, tatu: NOTE! As per [databind#3357] need to consider
907
964
// only explicit inclusion by accessors OTHER than ones with ignoral marker
0 commit comments