diff --git a/src/main/java/com/fasterxml/jackson/databind/BeanDescription.java b/src/main/java/com/fasterxml/jackson/databind/BeanDescription.java index 84802965e9..b48e8a127e 100644 --- a/src/main/java/com/fasterxml/jackson/databind/BeanDescription.java +++ b/src/main/java/com/fasterxml/jackson/databind/BeanDescription.java @@ -109,7 +109,7 @@ public boolean isNonStaticInnerClass() { /* /********************************************************** - /* Basic API for finding creator members + /* Basic API for finding Creators, related information /********************************************************** */ @@ -166,6 +166,15 @@ public boolean isNonStaticInnerClass() { */ public abstract AnnotatedConstructor findDefaultConstructor(); + /** + * Method that is replacing earlier Creator introspection access methods. + * + * @since 2.18 + * + * @return Container for introspected Creator candidates, if any + */ + public abstract PotentialCreators getPotentialCreators(); + /* /********************************************************** /* Basic API for finding property accessors diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/BasicBeanDescription.java b/src/main/java/com/fasterxml/jackson/databind/introspect/BasicBeanDescription.java index 63f54879b2..b1021be1e5 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/BasicBeanDescription.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/BasicBeanDescription.java @@ -340,6 +340,11 @@ public List> getCon return result; } + @Override + public PotentialCreators getPotentialCreators() { + return _propCollector.getPotentialCreators(); + } + @Override public Object instantiateBean(boolean fixAccess) { AnnotatedConstructor ac = _classInfo.getDefaultConstructor(); @@ -363,7 +368,7 @@ public Object instantiateBean(boolean fixAccess) { +ClassUtil.exceptionMessage(t), t); } } - + /* /********************************************************** /* Simple accessors, extended diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java index c11e360a33..019cddafb6 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java @@ -91,6 +91,11 @@ public class POJOPropertiesCollector protected List _creatorProperties; + /** + * @since 2.18 + */ + protected PotentialCreators _potentialCreators; + /** * A set of "field renamings" that have been discovered, indicating * intended renaming of other accessors: key is the implicit original @@ -218,6 +223,14 @@ public List getProperties() { return new ArrayList<>(props.values()); } + // @since 2.18 + public PotentialCreators getPotentialCreators() { + if (!_collected) { + collectAll(); + } + return _potentialCreators; + } + public Map getInjectables() { if (!_collected) { collectAll(); @@ -626,6 +639,8 @@ protected void _addFields(Map props) // Completely rewritten in 2.18 protected void _addCreators(Map props) { + final PotentialCreators creators = new PotentialCreators(); + _potentialCreators = creators; _creatorProperties = new ArrayList<>(); // First, resolve explicit annotations for all potential Creators @@ -648,35 +663,35 @@ protected void _addCreators(Map props) _removeDisabledCreators(constructors); _removeDisabledCreators(factories); - final PotentialCreators collector = new PotentialCreators(); // and use annotations to find explicitly chosen Creators if (_useAnnotations) { // can't have explicit ones without Annotation introspection // Start with Constructors as they have higher precedence: - _addExplicitlyAnnotatedCreators(collector, constructors, props, false); + _addExplicitlyAnnotatedCreators(creators, constructors, props, false); // followed by Factory methods (lower precedence) - _addExplicitlyAnnotatedCreators(collector, factories, props, - collector.hasPropertiesBased()); + _addExplicitlyAnnotatedCreators(creators, factories, props, + creators.hasPropertiesBased()); } // If no Explicitly annotated creators found, look // for ones with explicitly-named ({@code @JsonProperty}) parameters - if (!collector.hasPropertiesBased()) { + if (!creators.hasPropertiesBased()) { // only discover constructor Creators? - _addCreatorsWithAnnotatedNames(collector, constructors); + _addCreatorsWithAnnotatedNames(creators, constructors); } // But if no annotation-based Creators found, find/use canonical Creator // (JDK 17 Record/Scala/Kotlin) - if (!collector.hasPropertiesBased()) { + if (!creators.hasPropertiesBased()) { // for Records: if ((canonical != null) && constructors.contains(canonical)) { constructors.remove(canonical); - collector.addPropertiesBased(_config, canonical, "canonical"); + creators.addPropertiesBased(_config, canonical, "canonical"); } } - // And finally add logical properties: - PotentialCreator primary = collector.propertiesBased; + // And finally add logical properties for the One Properties-based + // creator selected (if any): + PotentialCreator primary = creators.propertiesBased; if (primary != null) { _addCreatorParams(props, primary); } diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/PotentialCreators.java b/src/main/java/com/fasterxml/jackson/databind/introspect/PotentialCreators.java index 5a3ad070a4..ab4e1c4623 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/PotentialCreators.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/PotentialCreators.java @@ -11,7 +11,7 @@ public class PotentialCreators */ public PotentialCreator propertiesBased; - public final List delegating = new ArrayList<>(); + private List delegating; public PotentialCreators() { @@ -36,6 +36,9 @@ public void addPropertiesBased(MapperConfig config, PotentialCreator ctor, St public void addDelegating(PotentialCreator ctor) { + if (delegating == null) { + delegating = new ArrayList<>(); + } delegating.add(ctor); } @@ -50,6 +53,10 @@ public boolean hasPropertiesBased() { } public boolean hasPropertiesBasedOrDelegating() { - return (propertiesBased != null) || !delegating.isEmpty(); + return (propertiesBased != null) || (delegating != null && !delegating.isEmpty()); + } + + public List getDelegating() { + return (delegating == null) ? Collections.emptyList() : delegating; } }