@@ -648,22 +648,22 @@ protected void _addCreators(Map<String, POJOPropertyBuilder> props)
648
648
List <PotentialCreator > constructors = _collectCreators (_classDef .getConstructors ());
649
649
List <PotentialCreator > factories = _collectCreators (_classDef .getFactoryMethods ());
650
650
651
- final PotentialCreator canonical ;
652
-
653
- // Find and mark "canonical" constructor for Records.
651
+ // Then find what is the Primary Constructor (if one exists for type):
652
+ // for Java Records and potentially other types too ("data classes"):
654
653
// Needs to be done early to get implicit names populated
654
+ final PotentialCreator primary ;
655
655
if (_isRecordType ) {
656
- canonical = JDK14Util .findCanonicalRecordConstructor (_config , _classDef , constructors );
656
+ primary = JDK14Util .findCanonicalRecordConstructor (_config , _classDef , constructors );
657
657
} else {
658
- // !!! TODO: fetch Canonical for Kotlin, Scala, via AnnotationIntrospector?
659
- canonical = null ;
658
+ primary = _annotationIntrospector . findPrimaryCreator ( _config , _classDef ,
659
+ constructors , factories ) ;
660
660
}
661
-
662
661
// Next: remove creators marked as explicitly disabled
663
662
_removeDisabledCreators (constructors );
664
663
_removeDisabledCreators (factories );
664
+
665
665
// And then remove non-annotated static methods that do not look like factories
666
- _removeNonFactoryStaticMethods (factories );
666
+ _removeNonFactoryStaticMethods (factories , primary );
667
667
668
668
// and use annotations to find explicitly chosen Creators
669
669
if (_useAnnotations ) { // can't have explicit ones without Annotation introspection
@@ -681,18 +681,18 @@ protected void _addCreators(Map<String, POJOPropertyBuilder> props)
681
681
_addCreatorsWithAnnotatedNames (creators , constructors );
682
682
}
683
683
684
- // But if no annotation-based Creators found, find/use canonical Creator
685
- // (JDK 17 Record/Scala/Kotlin)
686
- if (!creators .hasPropertiesBased ()) {
687
- // for Records:
688
- if (canonical != null ) {
684
+ // But if no annotation-based Creators found, find/use Primary Creator
685
+ // detected earlier, if any
686
+ if (primary != null ) {
687
+ if (!creators .hasPropertiesBased ()) {
689
688
// ... but only process if still included as a candidate
690
- if (constructors .remove (canonical )) {
689
+ if (constructors .remove (primary )
690
+ || factories .remove (primary )) {
691
691
// But wait! Could be delegating
692
- if (_isDelegatingConstructor (canonical )) {
693
- creators .addExplicitDelegating (canonical );
692
+ if (_isDelegatingConstructor (primary )) {
693
+ creators .addExplicitDelegating (primary );
694
694
} else {
695
- creators .setPropertiesBased (_config , canonical , "canonical " );
695
+ creators .setPropertiesBased (_config , primary , "Primary " );
696
696
}
697
697
}
698
698
}
@@ -720,19 +720,29 @@ protected void _addCreators(Map<String, POJOPropertyBuilder> props)
720
720
721
721
// And finally add logical properties for the One Properties-based
722
722
// creator selected (if any):
723
- PotentialCreator primary = creators .propertiesBased ;
724
- if (primary == null ) {
723
+ PotentialCreator propsCtor = creators .propertiesBased ;
724
+ if (propsCtor == null ) {
725
725
_creatorProperties = Collections .emptyList ();
726
726
} else {
727
727
_creatorProperties = new ArrayList <>();
728
- _addCreatorParams (props , primary , _creatorProperties );
728
+ _addCreatorParams (props , propsCtor , _creatorProperties );
729
729
}
730
730
}
731
731
732
732
// Method to determine if given non-explictly-annotated constructor
733
733
// looks like delegating one
734
734
private boolean _isDelegatingConstructor (PotentialCreator ctor )
735
735
{
736
+ // First things first: could be
737
+ switch (ctor .creatorModeOrDefault ()) {
738
+ case DELEGATING :
739
+ return true ;
740
+ case DISABLED :
741
+ case PROPERTIES :
742
+ return false ;
743
+ default : // case DEFAULT:
744
+ }
745
+
736
746
// Only consider single-arg case, for now
737
747
if (ctor .paramCount () == 1 ) {
738
748
// Main thing: @JsonValue makes it delegating:
@@ -752,6 +762,7 @@ private List<PotentialCreator> _collectCreators(List<? extends AnnotatedWithPara
752
762
for (AnnotatedWithParams ctor : ctors ) {
753
763
JsonCreator .Mode creatorMode = _useAnnotations
754
764
? _annotationIntrospector .findCreatorAnnotation (_config , ctor ) : null ;
765
+ // 06-Jul-2024, tatu: Can't yet drop DISABLED ones; add all (for now)
755
766
result .add (new PotentialCreator (ctor , creatorMode ));
756
767
}
757
768
return (result == null ) ? Collections .emptyList () : result ;
@@ -779,14 +790,19 @@ private void _removeNonVisibleCreators(List<PotentialCreator> ctors)
779
790
}
780
791
}
781
792
782
- private void _removeNonFactoryStaticMethods (List <PotentialCreator > ctors )
793
+ private void _removeNonFactoryStaticMethods (List <PotentialCreator > ctors ,
794
+ PotentialCreator canonical )
783
795
{
784
796
final Class <?> rawType = _type .getRawClass ();
785
797
Iterator <PotentialCreator > it = ctors .iterator ();
786
798
while (it .hasNext ()) {
787
799
// explicit mode? Retain (for now)
788
800
PotentialCreator ctor = it .next ();
789
- if (ctor .creatorMode () != null ) {
801
+ if (ctor .isAnnotated ()) {
802
+ continue ;
803
+ }
804
+ // Do not trim canonical either
805
+ if (canonical == ctor ) {
790
806
continue ;
791
807
}
792
808
// Copied from `BasicBeanDescription.isFactoryMethod()`
@@ -820,7 +836,7 @@ private void _addExplicitlyAnnotatedCreators(PotentialCreators collector,
820
836
821
837
// If no explicit annotation, skip for now (may be discovered
822
838
// at a later point)
823
- if (ctor .creatorMode () == null ) {
839
+ if (! ctor .isAnnotated () ) {
824
840
continue ;
825
841
}
826
842
0 commit comments