Skip to content

Commit de844c5

Browse files
committed
Renaming, javadoc changes
1 parent 96e5c8b commit de844c5

File tree

4 files changed

+135
-44
lines changed

4 files changed

+135
-44
lines changed

src/main/java/com/fasterxml/jackson/databind/AnnotationIntrospector.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,19 +1398,20 @@ public JsonCreator.Mode findCreatorAnnotation(MapperConfig<?> config, Annotated
13981398
}
13991399

14001400
/**
1401-
* Method called to check if introspector is able to detect so-called Canonical
1402-
* creator: primary Creator to use when no explicit annotation found
1401+
* Method called to check if introspector is able to detect so-called Primary
1402+
* Creator: Creator to select for use when no explicit annotation is found
14031403
* (via {@link #findCreatorAnnotation}).
1404-
* This is the case for example for Java Record types (but for which handling
1405-
* is in-built); but is specifically true for various "Data" classes by frameworks like
1406-
* Lombok and JVM languages like Kotlin and Scala (case classes).
1404+
* This is the case for example for Java Record types which have so-called
1405+
* canonical constructor; but it is also true for various "Data" classes by frameworks
1406+
* like Lombok and JVM languages like Kotlin and Scala (case classes).
14071407
* If introspector can determine that one of given {@link PotentialCreator}s should
14081408
* be considered canonical, it should return it; if not, should return {@code null}.
14091409
*<p>
14101410
* NOTE: when returning chosen Creator, it may be necessary to mark its "mode"
14111411
* with {@link PotentialCreator#overrideMode} (especially for "delegating" creators).
14121412
*<p>
1413-
* NOTE: method is NOT called for Java Record types.
1413+
* NOTE: method is NOT called for Java Record types; selection of canonical constructor
1414+
* as the Primary creator is handled by {@link POJOPropertiesCollector}
14141415
*
14151416
* @param config Configuration settings in effect (for deserialization)
14161417
* @param valueClass Class being instantiated and defines Creators passed
@@ -1422,7 +1423,7 @@ public JsonCreator.Mode findCreatorAnnotation(MapperConfig<?> config, Annotated
14221423
*
14231424
* @since 2.18
14241425
*/
1425-
public PotentialCreator findCanonicalCreator(MapperConfig<?> config,
1426+
public PotentialCreator findPrimaryCreator(MapperConfig<?> config,
14261427
AnnotatedClass valueClass,
14271428
List<PotentialCreator> declaredConstructors,
14281429
List<PotentialCreator> declaredFactories) {

src/main/java/com/fasterxml/jackson/databind/introspect/AnnotationIntrospectorPair.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -736,14 +736,14 @@ public JsonCreator.Mode findCreatorAnnotation(MapperConfig<?> config, Annotated
736736
}
737737

738738
@Override
739-
public PotentialCreator findCanonicalCreator(MapperConfig<?> config,
739+
public PotentialCreator findPrimaryCreator(MapperConfig<?> config,
740740
AnnotatedClass valueClass,
741741
List<PotentialCreator> declaredConstructors,
742742
List<PotentialCreator> declaredFactories) {
743-
PotentialCreator canonical = _primary.findCanonicalCreator(config,
743+
PotentialCreator canonical = _primary.findPrimaryCreator(config,
744744
valueClass, declaredConstructors, declaredFactories);
745745
if (canonical == null) {
746-
canonical = _secondary.findCanonicalCreator(config,
746+
canonical = _secondary.findPrimaryCreator(config,
747747
valueClass, declaredConstructors, declaredFactories);
748748
}
749749
return canonical;

src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertiesCollector.java

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -648,14 +648,14 @@ protected void _addCreators(Map<String, POJOPropertyBuilder> props)
648648
List<PotentialCreator> constructors = _collectCreators(_classDef.getConstructors());
649649
List<PotentialCreator> factories = _collectCreators(_classDef.getFactoryMethods());
650650

651-
// Then find and mark the "canonical" constructor (if one exists):
652-
// for Java Records and potentially other types too ("data classes":
651+
// Then find what is the Primary Constructor (if one exists for type):
652+
// for Java Records and potentially other types too ("data classes"):
653653
// Needs to be done early to get implicit names populated
654654
final PotentialCreator canonical;
655655
if (_isRecordType) {
656656
canonical = JDK14Util.findCanonicalRecordConstructor(_config, _classDef, constructors);
657657
} else {
658-
canonical = _annotationIntrospector.findCanonicalCreator(_config, _classDef,
658+
canonical = _annotationIntrospector.findPrimaryCreator(_config, _classDef,
659659
constructors, factories);
660660
}
661661

@@ -678,18 +678,18 @@ protected void _addCreators(Map<String, POJOPropertyBuilder> props)
678678
_addCreatorsWithAnnotatedNames(creators, constructors);
679679
}
680680

681-
// But if no annotation-based Creators found, find/use canonical Creator
682-
// (Scala/Kotlin/Lombok?)
683-
if (!creators.hasPropertiesBased()) {
684-
if (canonical != null) {
681+
// But if no annotation-based Creators found, find/use Primary Creator
682+
// detected earlier, if any
683+
if (canonical != null) {
684+
if (!creators.hasPropertiesBased()) {
685685
// ... but only process if still included as a candidate
686686
if (constructors.remove(canonical)
687687
|| factories.remove(canonical)) {
688688
// But wait! Could be delegating
689689
if (_isDelegatingConstructor(canonical)) {
690690
creators.addExplicitDelegating(canonical);
691691
} else {
692-
creators.setPropertiesBased(_config, canonical, "canonical");
692+
creators.setPropertiesBased(_config, canonical, "Primary");
693693
}
694694
}
695695
}
@@ -767,17 +767,6 @@ private List<PotentialCreator> _collectCreators(List<? extends AnnotatedWithPara
767767
return (result == null) ? Collections.emptyList() : result;
768768
}
769769

770-
private void _removeDisabledCreators(List<PotentialCreator> ctors)
771-
{
772-
Iterator<PotentialCreator> it = ctors.iterator();
773-
while (it.hasNext()) {
774-
// explicitly prevented? Remove
775-
if (it.next().creatorMode() == JsonCreator.Mode.DISABLED) {
776-
it.remove();
777-
}
778-
}
779-
}
780-
781770
private void _removeNonVisibleCreators(List<PotentialCreator> ctors)
782771
{
783772
Iterator<PotentialCreator> it = ctors.iterator();
Lines changed: 116 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
package com.fasterxml.jackson.databind.introspect;
22

3+
import java.util.ArrayList;
34
import java.util.List;
5+
import java.util.Objects;
46

57
import org.junit.jupiter.api.Test;
68

9+
import com.fasterxml.jackson.annotation.JsonCreator;
710
import com.fasterxml.jackson.databind.*;
11+
import com.fasterxml.jackson.databind.cfg.MapperConfig;
12+
import com.fasterxml.jackson.databind.json.JsonMapper;
813
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
914

15+
import static org.junit.Assert.assertEquals;
16+
1017
// Tests for [databind#4584]: extension point for discovering "Canonical"
1118
// Creator (primary Creator, usually constructor, used in case no creator
1219
// explicitly annotated)
@@ -15,40 +22,134 @@
1522
public class CanonicalCreator4584Test extends DatabindTestUtil
1623
{
1724
static class POJO4584 {
18-
String value;
25+
final String value;
1926

20-
// actually fundamentally canonical constructor...
21-
private POJO4584(String v, int bogus) {
27+
POJO4584(@ImplicitName("v") String v, @ImplicitName("bogus") int bogus) {
2228
value = v;
2329
}
24-
25-
public POJO4584(List<Object> bogus) {
26-
value = "List["+((bogus == null) ? -1 : bogus.size())+"]";
30+
31+
public POJO4584(@ImplicitName("list") List<Object> list) {
32+
value = "List["+((list == null) ? -1 : list.size())+"]";
2733
}
2834

29-
public POJO4584(Object[] bogus) {
30-
value = "Array["+((bogus == null) ? -1 : bogus.length)+"]";
35+
public POJO4584(@ImplicitName("array") Object[] array) {
36+
value = "Array["+((array == null) ? -1 : array.length)+"]";
3137
}
3238

33-
public static POJO4584 factoryInt(int i) {
39+
public static POJO4584 factoryInt(@ImplicitName("i") int i) {
3440
return new POJO4584("int["+i+"]", 0);
3541
}
3642

37-
public static POJO4584 factoryLong(long l) {
38-
return new POJO4584("long["+l+"]", 0);
43+
public static POJO4584 factoryString(@ImplicitName("v") String v) {
44+
return new POJO4584(v, 0);
45+
}
46+
47+
@Override
48+
public boolean equals(Object o) {
49+
return (o instanceof POJO4584) && Objects.equals(((POJO4584) o).value, value);
50+
}
51+
52+
@Override
53+
public String toString() {
54+
return "'"+value+"'";
55+
}
56+
}
57+
58+
static class DelegatingCanonicalFindingIntrospector extends ImplicitNameIntrospector
59+
{
60+
private static final long serialVersionUID = 1L;
61+
62+
private final Class<?> _argType;
63+
64+
public DelegatingCanonicalFindingIntrospector(Class<?> argType) {
65+
_argType = argType;
66+
}
67+
68+
@Override
69+
public PotentialCreator findPrimaryCreator(MapperConfig<?> config,
70+
AnnotatedClass valueClass,
71+
List<PotentialCreator> declaredConstructors,
72+
List<PotentialCreator> declaredFactories)
73+
{
74+
if (valueClass.getRawType() != POJO4584.class) {
75+
System.err.println("findCanonicalCreator SKIPPED for: "+valueClass.getRawType());
76+
return null;
77+
}
78+
System.err.println("findCanonicalCreator DONE for: "+valueClass.getRawType());
79+
List<PotentialCreator> combo = new ArrayList<>(declaredConstructors);
80+
combo.addAll(declaredFactories);
81+
for (PotentialCreator ctor : combo) {
82+
if (ctor.paramCount() == 1
83+
&& _argType == ctor.param(0).getRawType()) {
84+
System.err.println("MATCH! "+ctor);
85+
ctor.overrideMode(JsonCreator.Mode.DELEGATING);
86+
return ctor;
87+
}
88+
}
89+
System.err.println("No MATCH! ");
90+
return null;
3991
}
4092
}
4193

42-
private final ObjectMapper MAPPER = newJsonMapper();
94+
/*
95+
/**********************************************************************
96+
/* Test methods; properties-based Creators
97+
/**********************************************************************
98+
*/
99+
100+
/*
101+
@Test
102+
public void testCanonicalConstructorPropertiesCreator() throws Exception
103+
{
104+
assertEquals(POJO4584.factoryString("List[0]"),
105+
readerWith(new DelegatingCanonicalFindingIntrospector(List.class))
106+
.readValue(a2q("{'x':[ ]}")));
107+
}
108+
*/
43109

44110
/*
45111
/**********************************************************************
46-
/* Test methods
112+
/* Test methods; delegation-based Creators
47113
/**********************************************************************
48114
*/
115+
116+
@Test
117+
public void testCanonicalConstructorDelegatingIntCreator() throws Exception
118+
{
119+
assertEquals(POJO4584.factoryString("List[3]"),
120+
readerWith(new DelegatingCanonicalFindingIntrospector(List.class))
121+
.readValue(a2q("[1, 2, 3]")));
122+
}
49123

50124
@Test
51-
public void testCanonicalConstructorPropertiesCreator() throws Exception {
52-
// TODO
125+
public void testCanonicalConstructorDelegatingListCreator() throws Exception
126+
{
127+
assertEquals(POJO4584.factoryString("List[3]"),
128+
readerWith(new DelegatingCanonicalFindingIntrospector(List.class))
129+
.readValue(a2q("[1, 2, 3]")));
130+
}
131+
132+
@Test
133+
public void testCanonicalConstructorDelegatingArrayCreator() throws Exception
134+
{
135+
assertEquals(POJO4584.factoryString("Array[1]"),
136+
readerWith(new DelegatingCanonicalFindingIntrospector(Object[].class))
137+
.readValue(a2q("[true]")));
138+
}
139+
140+
/*
141+
/**********************************************************************
142+
/* Helper methods
143+
/**********************************************************************
144+
*/
145+
146+
private ObjectReader readerWith(AnnotationIntrospector intr) {
147+
return mapperWith(intr).readerFor(POJO4584.class);
148+
}
149+
150+
private ObjectMapper mapperWith(AnnotationIntrospector intr) {
151+
return JsonMapper.builder()
152+
.annotationIntrospector(intr)
153+
.build();
53154
}
54155
}

0 commit comments

Comments
 (0)