• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.introspect;
2 
3 import java.util.*;
4 
5 import com.fasterxml.jackson.annotation.JsonInclude;
6 import com.fasterxml.jackson.annotation.JsonProperty;
7 import com.fasterxml.jackson.annotation.JsonSetter;
8 import com.fasterxml.jackson.annotation.Nulls;
9 
10 import com.fasterxml.jackson.databind.*;
11 import com.fasterxml.jackson.databind.cfg.ConfigOverride;
12 import com.fasterxml.jackson.databind.cfg.MapperConfig;
13 import com.fasterxml.jackson.databind.type.TypeFactory;
14 import com.fasterxml.jackson.databind.util.ClassUtil;
15 
16 /**
17  * Helper class used for aggregating information about a single
18  * potential POJO property.
19  */
20 public class POJOPropertyBuilder
21     extends BeanPropertyDefinition
22     implements Comparable<POJOPropertyBuilder>
23 {
24     /**
25      * Marker value used to denote that no reference-property information found for
26      * this property
27      *
28      * @since 2.9
29      */
30     private final static AnnotationIntrospector.ReferenceProperty NOT_REFEFERENCE_PROP =
31             AnnotationIntrospector.ReferenceProperty.managed("");
32 
33     /**
34      * Whether property is being composed for serialization
35      * (true) or deserialization (false)
36      */
37     protected final boolean _forSerialization;
38 
39     protected final MapperConfig<?> _config;
40 
41     protected final AnnotationIntrospector _annotationIntrospector;
42 
43     /**
44      * External name of logical property; may change with
45      * renaming (by new instance being constructed using
46      * a new name)
47      */
48     protected final PropertyName _name;
49 
50     /**
51      * Original internal name, derived from accessor, of this
52      * property. Will not be changed by renaming.
53      */
54     protected final PropertyName _internalName;
55 
56     protected Linked<AnnotatedField> _fields;
57 
58     protected Linked<AnnotatedParameter> _ctorParameters;
59 
60     protected Linked<AnnotatedMethod> _getters;
61 
62     protected Linked<AnnotatedMethod> _setters;
63 
64     protected transient PropertyMetadata _metadata;
65 
66     /**
67      * Lazily accessed information about this property iff it is a forward or
68      * back reference.
69      *
70      * @since 2.9
71      */
72     protected transient AnnotationIntrospector.ReferenceProperty _referenceInfo;
73 
POJOPropertyBuilder(MapperConfig<?> config, AnnotationIntrospector ai, boolean forSerialization, PropertyName internalName)74     public POJOPropertyBuilder(MapperConfig<?> config, AnnotationIntrospector ai,
75             boolean forSerialization, PropertyName internalName) {
76         this(config, ai, forSerialization, internalName, internalName);
77     }
78 
POJOPropertyBuilder(MapperConfig<?> config, AnnotationIntrospector ai, boolean forSerialization, PropertyName internalName, PropertyName name)79     protected POJOPropertyBuilder(MapperConfig<?> config, AnnotationIntrospector ai,
80             boolean forSerialization, PropertyName internalName, PropertyName name)
81     {
82         _config = config;
83         _annotationIntrospector = ai;
84         _internalName = internalName;
85         _name = name;
86         _forSerialization = forSerialization;
87     }
88 
89     // protected since 2.9 (was public before)
POJOPropertyBuilder(POJOPropertyBuilder src, PropertyName newName)90     protected POJOPropertyBuilder(POJOPropertyBuilder src, PropertyName newName)
91     {
92         _config = src._config;
93         _annotationIntrospector = src._annotationIntrospector;
94         _internalName = src._internalName;
95         _name = newName;
96         _fields = src._fields;
97         _ctorParameters = src._ctorParameters;
98         _getters = src._getters;
99         _setters = src._setters;
100         _forSerialization = src._forSerialization;
101     }
102 
103     /*
104     /**********************************************************
105     /* Mutant factory methods
106     /**********************************************************
107      */
108 
109     @Override
withName(PropertyName newName)110     public POJOPropertyBuilder withName(PropertyName newName) {
111         return new POJOPropertyBuilder(this, newName);
112     }
113 
114     @Override
withSimpleName(String newSimpleName)115     public POJOPropertyBuilder withSimpleName(String newSimpleName)
116     {
117         PropertyName newName = _name.withSimpleName(newSimpleName);
118         return (newName == _name) ? this : new POJOPropertyBuilder(this, newName);
119     }
120 
121     /*
122     /**********************************************************
123     /* Comparable implementation: sort alphabetically, except
124     /* that properties with constructor parameters sorted
125     /* before other properties
126     /**********************************************************
127      */
128 
129     @Override
compareTo(POJOPropertyBuilder other)130     public int compareTo(POJOPropertyBuilder other)
131     {
132         // first, if one has ctor params, that should come first:
133         if (_ctorParameters != null) {
134             if (other._ctorParameters == null) {
135                 return -1;
136             }
137         } else if (other._ctorParameters != null) {
138             return 1;
139         }
140         /* otherwise sort by external name (including sorting of
141          * ctor parameters)
142          */
143         return getName().compareTo(other.getName());
144     }
145 
146     /*
147     /**********************************************************
148     /* BeanPropertyDefinition implementation, name/type
149     /**********************************************************
150      */
151 
152     @Override
getName()153     public String getName() {
154         return (_name == null) ? null : _name.getSimpleName();
155     }
156 
157     @Override
getFullName()158     public PropertyName getFullName() {
159         return _name;
160     }
161 
162     @Override
hasName(PropertyName name)163     public boolean hasName(PropertyName name) {
164         return _name.equals(name);
165     }
166 
167     @Override
getInternalName()168     public String getInternalName() { return _internalName.getSimpleName(); }
169 
170     @Override
getWrapperName()171     public PropertyName getWrapperName() {
172         /* 13-Mar-2013, tatu: Accessing via primary member SHOULD work,
173          *   due to annotation merging. However, I have seen some problems
174          *   with this access (for other annotations)... so if this should
175          *   occur, try commenting out full traversal code
176          */
177         AnnotatedMember member = getPrimaryMember();
178         return (member == null || _annotationIntrospector == null) ? null
179                 : _annotationIntrospector.findWrapperName(member);
180     	/*
181         return fromMemberAnnotations(new WithMember<PropertyName>() {
182             @Override
183             public PropertyName withMember(AnnotatedMember member) {
184                 return _annotationIntrospector.findWrapperName(member);
185             }
186         });
187         */
188     }
189 
190     @Override
isExplicitlyIncluded()191     public boolean isExplicitlyIncluded() {
192         return _anyExplicits(_fields)
193                 || _anyExplicits(_getters)
194                 || _anyExplicits(_setters)
195                 // 16-Jan-2016, tatu: Creator names are special, in that name should exist too;
196                 //   reason for this is [databind#1317]. Let's hope this works well, may need
197                 //   to tweak further if this lowers visibility
198 //                || _anyExplicits(_ctorParameters)
199                 || _anyExplicitNames(_ctorParameters)
200                 ;
201     }
202 
203     @Override
isExplicitlyNamed()204     public boolean isExplicitlyNamed() {
205         return _anyExplicitNames(_fields)
206                 || _anyExplicitNames(_getters)
207                 || _anyExplicitNames(_setters)
208                 || _anyExplicitNames(_ctorParameters)
209                 ;
210     }
211 
212     /*
213     /**********************************************************
214     /* Simple metadata
215     /**********************************************************
216      */
217 
218     @Override
getMetadata()219     public PropertyMetadata getMetadata()
220     {
221         if (_metadata == null) {
222             // 20-Jun-2020, tatu: Unfortunately strict checks lead to [databind#2757]
223             //   so we will need to try to avoid them at this point
224             final AnnotatedMember prim = getPrimaryMemberUnchecked();
225 
226             if (prim == null) {
227                 _metadata = PropertyMetadata.STD_REQUIRED_OR_OPTIONAL;
228             } else {
229                 final Boolean b = _annotationIntrospector.hasRequiredMarker(prim);
230                 final String desc = _annotationIntrospector.findPropertyDescription(prim);
231                 final Integer idx = _annotationIntrospector.findPropertyIndex(prim);
232                 final String def = _annotationIntrospector.findPropertyDefaultValue(prim);
233 
234                 if (b == null && idx == null && def == null) {
235                     _metadata = (desc == null) ? PropertyMetadata.STD_REQUIRED_OR_OPTIONAL
236                             : PropertyMetadata.STD_REQUIRED_OR_OPTIONAL.withDescription(desc);
237                 } else {
238                     _metadata = PropertyMetadata.construct(b, desc, idx, def);
239                 }
240                 if (!_forSerialization) {
241                     _metadata = _getSetterInfo(_metadata, prim);
242                 }
243             }
244         }
245         return _metadata;
246     }
247 
248     /**
249      * Helper method that contains logic for accessing and merging all setter
250      * information that we needed, regarding things like possible merging
251      * of property value, and handling of incoming nulls.
252      * Only called for deserialization purposes.
253      */
_getSetterInfo(PropertyMetadata metadata, AnnotatedMember primary)254     protected PropertyMetadata _getSetterInfo(PropertyMetadata metadata,
255             AnnotatedMember primary)
256     {
257         boolean needMerge = true;
258         Nulls valueNulls = null;
259         Nulls contentNulls = null;
260 
261         // Slightly confusing: first, annotations should be accessed via primary member
262         // (mutator); but accessor is needed for actual merge operation. So
263 
264         AnnotatedMember acc = getAccessor();
265 
266         if (primary != null) {
267             // Ok, first: does property itself have something to say?
268             if (_annotationIntrospector != null) {
269                 if (acc != null) {
270                     Boolean b = _annotationIntrospector.findMergeInfo(primary);
271                     if (b != null) {
272                         needMerge = false;
273                         if (b.booleanValue()) {
274                             metadata = metadata.withMergeInfo(PropertyMetadata.MergeInfo.createForPropertyOverride(acc));
275                         }
276                     }
277                 }
278                 JsonSetter.Value setterInfo = _annotationIntrospector.findSetterInfo(primary);
279                 if (setterInfo != null) {
280                     valueNulls = setterInfo.nonDefaultValueNulls();
281                     contentNulls = setterInfo.nonDefaultContentNulls();
282                 }
283             }
284             // If not, config override?
285             // 25-Oct-2016, tatu: Either this, or type of accessor...
286             if (needMerge || (valueNulls == null) || (contentNulls == null)) {
287                 // 20-Jun-2020, tatu: Related to [databind#2757], need to find type
288                 //   but keeping mind that type for setters is trickier; and that
289                 //   generic typing gets tricky as well.
290                 Class<?> rawType = _rawTypeOf(primary);
291                 ConfigOverride co = _config.getConfigOverride(rawType);
292                 JsonSetter.Value setterInfo = co.getSetterInfo();
293                 if (setterInfo != null) {
294                     if (valueNulls == null) {
295                         valueNulls = setterInfo.nonDefaultValueNulls();
296                     }
297                     if (contentNulls == null) {
298                         contentNulls = setterInfo.nonDefaultContentNulls();
299                     }
300                 }
301                 if (needMerge && (acc != null)) {
302                     Boolean b = co.getMergeable();
303                     if (b != null) {
304                         needMerge = false;
305                         if (b.booleanValue()) {
306                             metadata = metadata.withMergeInfo(PropertyMetadata.MergeInfo.createForTypeOverride(acc));
307                         }
308                     }
309                 }
310             }
311         }
312         if (needMerge || (valueNulls == null) || (contentNulls == null)) {
313             JsonSetter.Value setterInfo = _config.getDefaultSetterInfo();
314             if (valueNulls == null) {
315                 valueNulls = setterInfo.nonDefaultValueNulls();
316             }
317             if (contentNulls == null) {
318                 contentNulls = setterInfo.nonDefaultContentNulls();
319             }
320             if (needMerge) {
321                 Boolean b = _config.getDefaultMergeable();
322                 if (Boolean.TRUE.equals(b) && (acc != null)) {
323                     metadata = metadata.withMergeInfo(PropertyMetadata.MergeInfo.createForDefaults(acc));
324                 }
325             }
326         }
327         if ((valueNulls != null) || (contentNulls != null)) {
328             metadata = metadata.withNulls(valueNulls, contentNulls);
329         }
330         return metadata;
331     }
332 
333     /**
334      * Type determined from the primary member for the property being built,
335      * considering precedence according to whether we are processing serialization
336      * or deserialization.
337      */
338     @Override
getPrimaryType()339     public JavaType getPrimaryType() {
340         if (_forSerialization) {
341             AnnotatedMember m = getGetter();
342             if (m == null) {
343                 m = getField();
344                 if (m == null) {
345                     // 09-Feb-2017, tatu: Not sure if this or `null` but...
346                     return TypeFactory.unknownType();
347                 }
348             }
349             return m.getType();
350         }
351         AnnotatedMember m = getConstructorParameter();
352         if (m == null) {
353             m = getSetter();
354             // Important: can't try direct type access for setter; what we need is
355             // type of the first parameter
356             if (m != null) {
357                 return ((AnnotatedMethod) m).getParameterType(0);
358             }
359             m = getField();
360         }
361         // for setterless properties, however, can further try getter
362         if (m == null) {
363             m = getGetter();
364             if (m == null) {
365                 return TypeFactory.unknownType();
366             }
367         }
368         return m.getType();
369     }
370 
371     @Override
getRawPrimaryType()372     public Class<?> getRawPrimaryType() {
373         return getPrimaryType().getRawClass();
374     }
375 
376     /*
377     /**********************************************************
378     /* BeanPropertyDefinition implementation, accessor access
379     /**********************************************************
380      */
381 
382     @Override
hasGetter()383     public boolean hasGetter() { return _getters != null; }
384 
385     @Override
hasSetter()386     public boolean hasSetter() { return _setters != null; }
387 
388     @Override
hasField()389     public boolean hasField() { return _fields != null; }
390 
391     @Override
hasConstructorParameter()392     public boolean hasConstructorParameter() { return _ctorParameters != null; }
393 
394     @Override
couldDeserialize()395     public boolean couldDeserialize() {
396         return (_ctorParameters != null) || (_setters != null) || (_fields != null);
397     }
398 
399     @Override
couldSerialize()400     public boolean couldSerialize() {
401         return (_getters != null) || (_fields != null);
402     }
403 
404     @Override
getGetter()405     public AnnotatedMethod getGetter()
406     {
407         // Easy with zero or one getters...
408         Linked<AnnotatedMethod> curr = _getters;
409         if (curr == null) {
410             return null;
411         }
412         Linked<AnnotatedMethod> next = curr.next;
413         if (next == null) {
414             return curr.value;
415         }
416         // But if multiple, verify that they do not conflict...
417         for (; next != null; next = next.next) {
418             /* [JACKSON-255] Allow masking, i.e. do not report exception if one
419              *   is in super-class from the other
420              */
421             Class<?> currClass = curr.value.getDeclaringClass();
422             Class<?> nextClass = next.value.getDeclaringClass();
423             if (currClass != nextClass) {
424                 if (currClass.isAssignableFrom(nextClass)) { // next is more specific
425                     curr = next;
426                     continue;
427                 }
428                 if (nextClass.isAssignableFrom(currClass)) { // current more specific
429                     continue;
430                 }
431             }
432             /* 30-May-2014, tatu: Three levels of precedence:
433              *
434              * 1. Regular getters ("getX")
435              * 2. Is-getters ("isX")
436              * 3. Implicit, possible getters ("x")
437              */
438             int priNext = _getterPriority(next.value);
439             int priCurr = _getterPriority(curr.value);
440 
441             if (priNext != priCurr) {
442                 if (priNext < priCurr) {
443                     curr = next;
444                 }
445                 continue;
446             }
447             throw new IllegalArgumentException("Conflicting getter definitions for property \""+getName()+"\": "
448                     +curr.value.getFullName()+" vs "+next.value.getFullName());
449         }
450         // One more thing; to avoid having to do it again...
451         _getters = curr.withoutNext();
452         return curr.value;
453     }
454 
455     @Override
getSetter()456     public AnnotatedMethod getSetter()
457     {
458         // Easy with zero or one setters...
459         Linked<AnnotatedMethod> curr = _setters;
460         if (curr == null) {
461             return null;
462         }
463         Linked<AnnotatedMethod> next = curr.next;
464         if (next == null) {
465             return curr.value;
466         }
467         // But if multiple, verify that they do not conflict...
468         for (; next != null; next = next.next) {
469             // Allow masking, i.e. do not fail if one is in super-class from the other
470             Class<?> currClass = curr.value.getDeclaringClass();
471             Class<?> nextClass = next.value.getDeclaringClass();
472             if (currClass != nextClass) {
473                 if (currClass.isAssignableFrom(nextClass)) { // next is more specific
474                     curr = next;
475                     continue;
476                 }
477                 if (nextClass.isAssignableFrom(currClass)) { // current more specific
478                     continue;
479                 }
480             }
481             AnnotatedMethod nextM = next.value;
482             AnnotatedMethod currM = curr.value;
483 
484             /* 30-May-2014, tatu: Two levels of precedence:
485              *
486              * 1. Regular setters ("setX(...)")
487              * 2. Implicit, possible setters ("x(...)")
488              */
489             int priNext = _setterPriority(nextM);
490             int priCurr = _setterPriority(currM);
491 
492             if (priNext != priCurr) {
493                 if (priNext < priCurr) {
494                     curr = next;
495                 }
496                 continue;
497             }
498             // 11-Dec-2015, tatu: As per [databind#1033] allow pluggable conflict resolution
499             if (_annotationIntrospector != null) {
500                 AnnotatedMethod pref = _annotationIntrospector.resolveSetterConflict(_config,
501                         currM, nextM);
502 
503                 // note: should be one of nextM/currM; but no need to check
504                 if (pref == currM) {
505                     continue;
506                 }
507                 if (pref == nextM) {
508                     curr = next;
509                     continue;
510                 }
511             }
512             throw new IllegalArgumentException(String.format(
513  "Conflicting setter definitions for property \"%s\": %s vs %s",
514  getName(), curr.value.getFullName(), next.value.getFullName()));
515         }
516         // One more thing; to avoid having to do it again...
517         _setters = curr.withoutNext();
518         return curr.value;
519     }
520 
521     @Override
getField()522     public AnnotatedField getField()
523     {
524         if (_fields == null) {
525             return null;
526         }
527         // If multiple, verify that they do not conflict...
528         AnnotatedField field = _fields.value;
529         Linked<AnnotatedField> next = _fields.next;
530         for (; next != null; next = next.next) {
531             AnnotatedField nextField = next.value;
532             Class<?> fieldClass = field.getDeclaringClass();
533             Class<?> nextClass = nextField.getDeclaringClass();
534             if (fieldClass != nextClass) {
535                 if (fieldClass.isAssignableFrom(nextClass)) { // next is more specific
536                     field = nextField;
537                     continue;
538                 }
539                 if (nextClass.isAssignableFrom(fieldClass)) { // getter more specific
540                     continue;
541                 }
542             }
543             throw new IllegalArgumentException("Multiple fields representing property \""+getName()+"\": "
544                     +field.getFullName()+" vs "+nextField.getFullName());
545         }
546         return field;
547     }
548 
549     @Override
getConstructorParameter()550     public AnnotatedParameter getConstructorParameter()
551     {
552         if (_ctorParameters == null) {
553             return null;
554         }
555         /* Hmmh. Checking for constructor parameters is trickier; for one,
556          * we must allow creator and factory method annotations.
557          * If this is the case, constructor parameter has the precedence.
558          *
559          * So, for now, just try finding the first constructor parameter;
560          * if none, first factory method. And don't check for dups, if we must,
561          * can start checking for them later on.
562          */
563         Linked<AnnotatedParameter> curr = _ctorParameters;
564         do {
565             if (curr.value.getOwner() instanceof AnnotatedConstructor) {
566                 return curr.value;
567             }
568             curr = curr.next;
569         } while (curr != null);
570         return _ctorParameters.value;
571     }
572 
573     @Override
getConstructorParameters()574     public Iterator<AnnotatedParameter> getConstructorParameters() {
575         if (_ctorParameters == null) {
576             return ClassUtil.emptyIterator();
577         }
578         return new MemberIterator<AnnotatedParameter>(_ctorParameters);
579     }
580 
581     @Override
getPrimaryMember()582     public AnnotatedMember getPrimaryMember() {
583         if (_forSerialization) {
584             return getAccessor();
585         }
586         AnnotatedMember m = getMutator();
587         // for setterless properties, however...
588         if (m == null) {
589             m = getAccessor();
590         }
591         return m;
592     }
593 
594     // Sometimes we need to actually by-pass failures related to conflicting
595     // getters or setters (see [databind#2757] for specific example); if so,
596     // this method is to be used instead of `getPrimaryMember()`
597     // @since 2.11.1
getPrimaryMemberUnchecked()598     protected AnnotatedMember getPrimaryMemberUnchecked() {
599         if (_forSerialization) { // Inlined `getAccessor()` logic:
600             // Inlined `getGetter()`:
601             if (_getters != null) {
602                 return _getters.value;
603             }
604             // Inlined `getField()`:
605             if (_fields != null) {
606                 return _fields.value;
607             }
608             return null;
609         }
610 
611         // Otherwise, inlined `getMutator()` logic:
612 
613         // Inlined `getConstructorParameter()`:
614         if (_ctorParameters != null) {
615             return _ctorParameters.value;
616         }
617         // Inlined `getSetter()`:
618         if (_setters != null) {
619             return _setters.value;
620         }
621         // Inlined `getField()`:
622         if (_fields != null) {
623             return _fields.value;
624         }
625         // but to support setterless-properties, also include part of
626         // `getAccessor()` not yet covered, `getGetter()`:
627         if (_getters != null) {
628             return _getters.value;
629         }
630         return null;
631     }
632 
_getterPriority(AnnotatedMethod m)633     protected int _getterPriority(AnnotatedMethod m)
634     {
635         final String name = m.getName();
636         // [databind#238]: Also, regular getters have precedence over "is-getters"
637         if (name.startsWith("get") && name.length() > 3) {
638             // should we check capitalization?
639             return 1;
640         }
641         if (name.startsWith("is") && name.length() > 2) {
642             return 2;
643         }
644         return 3;
645     }
646 
_setterPriority(AnnotatedMethod m)647     protected int _setterPriority(AnnotatedMethod m)
648     {
649         final String name = m.getName();
650         if (name.startsWith("set") && name.length() > 3) {
651             // should we check capitalization?
652             return 1;
653         }
654         return 2;
655     }
656 
657     /*
658     /**********************************************************
659     /* Implementations of refinement accessors
660     /**********************************************************
661      */
662 
663     @Override
findViews()664     public Class<?>[] findViews() {
665         return fromMemberAnnotations(new WithMember<Class<?>[]>() {
666             @Override
667             public Class<?>[] withMember(AnnotatedMember member) {
668                 return _annotationIntrospector.findViews(member);
669             }
670         });
671     }
672 
673     @Override
674     public AnnotationIntrospector.ReferenceProperty findReferenceType() {
675         // 30-Mar-2017, tatu: Access lazily but retain information since it needs
676         //   to be accessed multiple times during processing.
677         AnnotationIntrospector.ReferenceProperty result = _referenceInfo;
678         if (result != null) {
679             if (result == NOT_REFEFERENCE_PROP) {
680                 return null;
681             }
682             return result;
683         }
684         result = fromMemberAnnotations(new WithMember<AnnotationIntrospector.ReferenceProperty>() {
685             @Override
686             public AnnotationIntrospector.ReferenceProperty withMember(AnnotatedMember member) {
687                 return _annotationIntrospector.findReferenceType(member);
688             }
689         });
690         _referenceInfo = (result == null) ? NOT_REFEFERENCE_PROP : result;
691         return result;
692     }
693 
694     @Override
695     public boolean isTypeId() {
696         Boolean b = fromMemberAnnotations(new WithMember<Boolean>() {
697             @Override
698             public Boolean withMember(AnnotatedMember member) {
699                 return _annotationIntrospector.isTypeId(member);
700             }
701         });
702         return (b != null) && b.booleanValue();
703     }
704 
705     @Override
706     public ObjectIdInfo findObjectIdInfo() {
707         return fromMemberAnnotations(new WithMember<ObjectIdInfo>() {
708             @Override
709             public ObjectIdInfo withMember(AnnotatedMember member) {
710                 ObjectIdInfo info = _annotationIntrospector.findObjectIdInfo(member);
711                 if (info != null) {
712                     info = _annotationIntrospector.findObjectReferenceInfo(member, info);
713                 }
714                 return info;
715             }
716         });
717     }
718 
719     @Override
720     public JsonInclude.Value findInclusion() {
721         AnnotatedMember a = getAccessor();
722         // 16-Apr-2106, tatu: Let's include per-type default inclusion too
723         // 17-Aug-2016, tatu: Do NOT include global, or per-type defaults, because
724         //    not all of this information (specifically, enclosing type's settings)
725         //    is available here
726         JsonInclude.Value v = (_annotationIntrospector == null) ?
727                 null : _annotationIntrospector.findPropertyInclusion(a);
728         return (v == null) ? JsonInclude.Value.empty() : v;
729     }
730 
731     public JsonProperty.Access findAccess() {
732         return fromMemberAnnotationsExcept(new WithMember<JsonProperty.Access>() {
733             @Override
734             public JsonProperty.Access withMember(AnnotatedMember member) {
735                 return _annotationIntrospector.findPropertyAccess(member);
736             }
737         }, JsonProperty.Access.AUTO);
738     }
739 
740     /*
741     /**********************************************************
742     /* Data aggregation
743     /**********************************************************
744      */
745 
746     public void addField(AnnotatedField a, PropertyName name, boolean explName, boolean visible, boolean ignored) {
747         _fields = new Linked<AnnotatedField>(a, _fields, name, explName, visible, ignored);
748     }
749 
750     public void addCtor(AnnotatedParameter a, PropertyName name, boolean explName, boolean visible, boolean ignored) {
751         _ctorParameters = new Linked<AnnotatedParameter>(a, _ctorParameters, name, explName, visible, ignored);
752     }
753 
754     public void addGetter(AnnotatedMethod a, PropertyName name, boolean explName, boolean visible, boolean ignored) {
755         _getters = new Linked<AnnotatedMethod>(a, _getters, name, explName, visible, ignored);
756     }
757 
758     public void addSetter(AnnotatedMethod a, PropertyName name, boolean explName, boolean visible, boolean ignored) {
759         _setters = new Linked<AnnotatedMethod>(a, _setters, name, explName, visible, ignored);
760     }
761 
762     /**
763      * Method for adding all property members from specified collector into
764      * this collector.
765      */
766     public void addAll(POJOPropertyBuilder src)
767     {
768         _fields = merge(_fields, src._fields);
769         _ctorParameters = merge(_ctorParameters, src._ctorParameters);
770         _getters= merge(_getters, src._getters);
771         _setters = merge(_setters, src._setters);
772     }
773 
774     private static <T> Linked<T> merge(Linked<T> chain1, Linked<T> chain2)
775     {
776         if (chain1 == null) {
777             return chain2;
778         }
779         if (chain2 == null) {
780             return chain1;
781         }
782         return chain1.append(chain2);
783     }
784 
785     /*
786     /**********************************************************
787     /* Modifications
788     /**********************************************************
789      */
790 
791     /**
792      * Method called to remove all entries that are marked as
793      * ignored.
794      */
795     public void removeIgnored()
796     {
797         _fields = _removeIgnored(_fields);
798         _getters = _removeIgnored(_getters);
799         _setters = _removeIgnored(_setters);
800         _ctorParameters = _removeIgnored(_ctorParameters);
801     }
802 
803     @Deprecated // since 2.12
804     public JsonProperty.Access removeNonVisible(boolean inferMutators) {
805         return removeNonVisible(inferMutators, null);
806     }
807 
808     /**
809      * @param inferMutators Whether mutators can be "pulled in" by visible
810      *    accessors or not.
811      *
812      * @since 2.12 (earlier had different signature)
813      */
814     public JsonProperty.Access removeNonVisible(boolean inferMutators,
815             POJOPropertiesCollector parent)
816     {
817         /* 07-Jun-2015, tatu: With 2.6, we will allow optional definition
818          *  of explicit access type for property; if not "AUTO", it will
819          *  dictate how visibility checks are applied.
820          */
821         JsonProperty.Access acc = findAccess();
822         if (acc == null) {
823             acc = JsonProperty.Access.AUTO;
824         }
825         switch (acc) {
826         case READ_ONLY:
827             // [databind#2719]: Need to add ignorals, first, keeping in mind
828             // we have not yet resolved explicit names, so include implicit
829             // and possible explicit names
830             if (parent != null) {
831                 parent._collectIgnorals(getName());
832                 for (PropertyName pn : findExplicitNames()) {
833                     parent._collectIgnorals(pn.getSimpleName());
834                 }
835             }
836             // Remove setters, creators for sure, but fields too if deserializing
837             _setters = null;
838             _ctorParameters = null;
839             if (!_forSerialization) {
840                 _fields = null;
841             }
842             break;
843         case READ_WRITE:
844             // no trimming whatsoever?
845             break;
846         case WRITE_ONLY:
847             // remove getters, definitely, but also fields if serializing
848             _getters = null;
849             if (_forSerialization) {
850                 _fields = null;
851             }
852             break;
853         default:
854         case AUTO: // the default case: base it on visibility
855             _getters = _removeNonVisible(_getters);
856             _ctorParameters = _removeNonVisible(_ctorParameters);
857 
858             if (!inferMutators || (_getters == null)) {
859                 _fields = _removeNonVisible(_fields);
860                 _setters = _removeNonVisible(_setters);
861             }
862         }
863         return acc;
864     }
865 
866     /**
867      * Mutator that will simply drop any constructor parameters property may have.
868      *
869      * @since 2.5
870      */
871     public void removeConstructors() {
872         _ctorParameters = null;
873     }
874 
875     /**
876      * Method called to trim unnecessary entries, such as implicit
877      * getter if there is an explict one available. This is important
878      * for later stages, to avoid unnecessary conflicts.
879      */
880     public void trimByVisibility()
881     {
882         _fields = _trimByVisibility(_fields);
883         _getters = _trimByVisibility(_getters);
884         _setters = _trimByVisibility(_setters);
885         _ctorParameters = _trimByVisibility(_ctorParameters);
886     }
887 
888     @SuppressWarnings("unchecked")
889     public void mergeAnnotations(boolean forSerialization)
890     {
891         if (forSerialization) {
892             if (_getters != null) {
893                 AnnotationMap ann = _mergeAnnotations(0, _getters, _fields, _ctorParameters, _setters);
894                 _getters = _applyAnnotations(_getters, ann);
895             } else if (_fields != null) {
896                 AnnotationMap ann = _mergeAnnotations(0, _fields, _ctorParameters, _setters);
897                 _fields = _applyAnnotations(_fields, ann);
898             }
899         } else { // for deserialization
900             if (_ctorParameters != null) {
901                 AnnotationMap ann = _mergeAnnotations(0, _ctorParameters, _setters, _fields, _getters);
902                 _ctorParameters = _applyAnnotations(_ctorParameters, ann);
903             } else if (_setters != null) {
904                 AnnotationMap ann = _mergeAnnotations(0, _setters, _fields, _getters);
905                 _setters = _applyAnnotations(_setters, ann);
906             } else if (_fields != null) {
907                 AnnotationMap ann = _mergeAnnotations(0, _fields, _getters);
908                 _fields = _applyAnnotations(_fields, ann);
909             }
910         }
911     }
912 
913     private AnnotationMap _mergeAnnotations(int index,
914             Linked<? extends AnnotatedMember>... nodes)
915     {
916         AnnotationMap ann = _getAllAnnotations(nodes[index]);
917         while (++index < nodes.length) {
918             if (nodes[index] != null) {
919                 return AnnotationMap.merge(ann, _mergeAnnotations(index, nodes));
920             }
921         }
922         return ann;
923     }
924 
925     /**
926      * Replacement, as per [databind#868], of simple access to annotations, which
927      * does "deep merge" if an as necessary.
928      *<pre>
929      * nodes[index].value.getAllAnnotations()
930      *</pre>
931      *
932      * @since 2.6
933      */
934     private <T extends AnnotatedMember> AnnotationMap _getAllAnnotations(Linked<T> node) {
935         AnnotationMap ann = node.value.getAllAnnotations();
936         if (node.next != null) {
937             ann = AnnotationMap.merge(ann, _getAllAnnotations(node.next));
938         }
939         return ann;
940     }
941 
942     /**
943      * Helper method to handle recursive merging of annotations within accessor class,
944      * to ensure no annotations are accidentally dropped within chain when non-visible
945      * and secondary accessors are pruned later on.
946      *<p>
947      * See [databind#868] for more information.
948      *
949      * @since 2.6
950      */
951     private <T extends AnnotatedMember> Linked<T> _applyAnnotations(Linked<T> node, AnnotationMap ann) {
952         @SuppressWarnings("unchecked")
953         T value = (T) node.value.withAnnotations(ann);
954         if (node.next != null) {
955             node = node.withNext(_applyAnnotations(node.next, ann));
956         }
957         return node.withValue(value);
958     }
959 
960     private <T> Linked<T> _removeIgnored(Linked<T> node)
961     {
962         if (node == null) {
963             return node;
964         }
965         return node.withoutIgnored();
966     }
967 
968     private <T> Linked<T> _removeNonVisible(Linked<T> node)
969     {
970         if (node == null) {
971             return node;
972         }
973         return node.withoutNonVisible();
974     }
975 
976     private <T> Linked<T> _trimByVisibility(Linked<T> node)
977     {
978         if (node == null) {
979             return node;
980         }
981         return node.trimByVisibility();
982     }
983 
984     /*
985     /**********************************************************
986     /* Accessors for aggregate information
987     /**********************************************************
988      */
989 
990     private <T> boolean _anyExplicits(Linked<T> n)
991     {
992         for (; n != null; n = n.next) {
993             if (n.name != null && n.name.hasSimpleName()) {
994                 return true;
995             }
996         }
997         return false;
998     }
999 
1000     private <T> boolean _anyExplicitNames(Linked<T> n)
1001     {
1002         for (; n != null; n = n.next) {
1003             if (n.name != null && n.isNameExplicit) {
1004                 return true;
1005             }
1006         }
1007         return false;
1008     }
1009 
1010     public boolean anyVisible() {
1011         return _anyVisible(_fields)
1012             || _anyVisible(_getters)
1013             || _anyVisible(_setters)
1014             || _anyVisible(_ctorParameters)
1015         ;
1016     }
1017 
1018     private <T> boolean _anyVisible(Linked<T> n)
1019     {
1020         for (; n != null; n = n.next) {
1021             if (n.isVisible) {
1022                 return true;
1023             }
1024         }
1025         return false;
1026     }
1027 
1028     public boolean anyIgnorals() {
1029         return _anyIgnorals(_fields)
1030             || _anyIgnorals(_getters)
1031             || _anyIgnorals(_setters)
1032             || _anyIgnorals(_ctorParameters)
1033         ;
1034     }
1035 
1036     private <T> boolean _anyIgnorals(Linked<T> n)
1037     {
1038         for (; n != null; n = n.next) {
1039             if (n.isMarkedIgnored) {
1040                 return true;
1041             }
1042         }
1043         return false;
1044     }
1045 
1046     /**
1047      * Method called to find out set of explicit names for accessors
1048      * bound together due to implicit name.
1049      *
1050      * @since 2.4
1051      */
1052     public Set<PropertyName> findExplicitNames()
1053     {
1054         Set<PropertyName> renamed = null;
1055         renamed = _findExplicitNames(_fields, renamed);
1056         renamed = _findExplicitNames(_getters, renamed);
1057         renamed = _findExplicitNames(_setters, renamed);
1058         renamed = _findExplicitNames(_ctorParameters, renamed);
1059         if (renamed == null) {
1060             return Collections.emptySet();
1061         }
1062         return renamed;
1063     }
1064 
1065     /**
1066      * Method called when a previous call to {@link #findExplicitNames} found
1067      * multiple distinct explicit names, and the property this builder represents
1068      * basically needs to be broken apart and replaced by a set of more than
1069      * one properties.
1070      *
1071      * @since 2.4
1072      */
1073     public Collection<POJOPropertyBuilder> explode(Collection<PropertyName> newNames)
1074     {
1075         HashMap<PropertyName,POJOPropertyBuilder> props = new HashMap<PropertyName,POJOPropertyBuilder>();
1076         _explode(newNames, props, _fields);
1077         _explode(newNames, props, _getters);
1078         _explode(newNames, props, _setters);
1079         _explode(newNames, props, _ctorParameters);
1080         return props.values();
1081     }
1082 
1083     @SuppressWarnings("unchecked")
1084     private void _explode(Collection<PropertyName> newNames,
1085             Map<PropertyName,POJOPropertyBuilder> props,
1086             Linked<?> accessors)
1087     {
1088         final Linked<?> firstAcc = accessors; // clumsy, part 1
1089         for (Linked<?> node = accessors; node != null; node = node.next) {
1090             PropertyName name = node.name;
1091             if (!node.isNameExplicit || name == null) { // no explicit name -- problem!
1092                 // [databind#541] ... but only as long as it's visible
1093                 if (!node.isVisible) {
1094                     continue;
1095                 }
1096 
1097                 throw new IllegalStateException("Conflicting/ambiguous property name definitions (implicit name '"
1098                         +_name+"'): found multiple explicit names: "
1099                         +newNames+", but also implicit accessor: "+node);
1100             }
1101             POJOPropertyBuilder prop = props.get(name);
1102             if (prop == null) {
1103                 prop = new POJOPropertyBuilder(_config, _annotationIntrospector, _forSerialization,
1104                         _internalName, name);
1105                 props.put(name, prop);
1106             }
1107             // ultra-clumsy, part 2 -- lambdas would be nice here
1108             if (firstAcc == _fields) {
1109                 Linked<AnnotatedField> n2 = (Linked<AnnotatedField>) node;
1110                 prop._fields = n2.withNext(prop._fields);
1111             } else if (firstAcc == _getters) {
1112                 Linked<AnnotatedMethod> n2 = (Linked<AnnotatedMethod>) node;
1113                 prop._getters = n2.withNext(prop._getters);
1114             } else if (firstAcc == _setters) {
1115                 Linked<AnnotatedMethod> n2 = (Linked<AnnotatedMethod>) node;
1116                 prop._setters = n2.withNext(prop._setters);
1117             } else if (firstAcc == _ctorParameters) {
1118                 Linked<AnnotatedParameter> n2 = (Linked<AnnotatedParameter>) node;
1119                 prop._ctorParameters = n2.withNext(prop._ctorParameters);
1120             } else {
1121                 throw new IllegalStateException("Internal error: mismatched accessors, property: "+this);
1122             }
1123         }
1124     }
1125 
1126     private Set<PropertyName> _findExplicitNames(Linked<? extends AnnotatedMember> node,
1127             Set<PropertyName> renamed)
1128     {
1129         for (; node != null; node = node.next) {
1130             /* 30-Mar-2014, tatu: Second check should not be needed, but seems like
1131              *   removing it can cause nasty exceptions with certain version
1132              *   combinations (2.4 databind, an older module).
1133              *   So leaving it in for now until this is resolved
1134              *   (or version beyond 2.4)
1135              */
1136             if (!node.isNameExplicit || node.name == null) {
1137                 continue;
1138             }
1139             if (renamed == null) {
1140                 renamed = new HashSet<PropertyName>();
1141             }
1142             renamed.add(node.name);
1143         }
1144         return renamed;
1145     }
1146 
1147     // For trouble-shooting
1148     @Override
1149     public String toString()
1150     {
1151         StringBuilder sb = new StringBuilder();
1152         sb.append("[Property '").append(_name)
1153           .append("'; ctors: ").append(_ctorParameters)
1154           .append(", field(s): ").append(_fields)
1155           .append(", getter(s): ").append(_getters)
1156           .append(", setter(s): ").append(_setters)
1157           ;
1158         sb.append("]");
1159         return sb.toString();
1160     }
1161 
1162     /*
1163     /**********************************************************
1164     /* Helper methods
1165     /**********************************************************
1166      */
1167 
1168     /**
1169      * Helper method used for finding annotation values, from accessors
1170      * relevant to current usage (deserialization, serialization)
1171      */
1172     protected <T> T fromMemberAnnotations(WithMember<T> func)
1173     {
1174         T result = null;
1175         if (_annotationIntrospector != null) {
1176             if (_forSerialization) {
1177                 if (_getters != null) {
1178                     result = func.withMember(_getters.value);
1179                 }
1180             } else {
1181                 if (_ctorParameters != null) {
1182                     result = func.withMember(_ctorParameters.value);
1183                 }
1184                 if (result == null && _setters != null) {
1185                     result = func.withMember(_setters.value);
1186                 }
1187             }
1188             if (result == null && _fields != null) {
1189                 result = func.withMember(_fields.value);
1190             }
1191         }
1192         return result;
1193     }
1194 
1195     protected <T> T fromMemberAnnotationsExcept(WithMember<T> func, T defaultValue)
1196     {
1197         if (_annotationIntrospector == null) {
1198             return null;
1199         }
1200 
1201         // NOTE: here we must ask ALL accessors, but the order varies between
1202         // serialization, deserialization
1203         if (_forSerialization) {
1204             if (_getters != null) {
1205                 T result = func.withMember(_getters.value);
1206                 if ((result != null) && (result != defaultValue)) {
1207                     return result;
1208                 }
1209             }
1210             if (_fields != null) {
1211                 T result = func.withMember(_fields.value);
1212                 if ((result != null) && (result != defaultValue)) {
1213                     return result;
1214                 }
1215             }
1216             if (_ctorParameters != null) {
1217                 T result = func.withMember(_ctorParameters.value);
1218                 if ((result != null) && (result != defaultValue)) {
1219                     return result;
1220                 }
1221             }
1222             if (_setters != null) {
1223                 T result = func.withMember(_setters.value);
1224                 if ((result != null) && (result != defaultValue)) {
1225                     return result;
1226                 }
1227             }
1228             return null;
1229         }
1230         if (_ctorParameters != null) {
1231             T result = func.withMember(_ctorParameters.value);
1232             if ((result != null) && (result != defaultValue)) {
1233                 return result;
1234             }
1235         }
1236         if (_setters != null) {
1237             T result = func.withMember(_setters.value);
1238             if ((result != null) && (result != defaultValue)) {
1239                 return result;
1240             }
1241         }
1242         if (_fields != null) {
1243             T result = func.withMember(_fields.value);
1244             if ((result != null) && (result != defaultValue)) {
1245                 return result;
1246             }
1247         }
1248         if (_getters != null) {
1249             T result = func.withMember(_getters.value);
1250             if ((result != null) && (result != defaultValue)) {
1251                 return result;
1252             }
1253         }
1254         return null;
1255     }
1256 
1257     // Helper method needed to work around oddity in type access for
1258     // `AnnotatedMethod`.
1259     //
1260     // @since 2.11.1
1261     protected Class<?> _rawTypeOf(AnnotatedMember m) {
1262         // AnnotatedMethod always returns return type, but for setters we
1263         // actually need argument type
1264         if (m instanceof AnnotatedMethod) {
1265             AnnotatedMethod meh = (AnnotatedMethod) m;
1266             if (meh.getParameterCount() > 0) {
1267                 // note: get raw type FROM full type since only that resolves
1268                 // generic types
1269                 return meh.getParameterType(0).getRawClass();
1270             }
1271         }
1272         // same as above, must get fully resolved type to handled generic typing
1273         // of fields etc.
1274         return m.getType().getRawClass();
1275     }
1276 
1277     /*
1278     /**********************************************************
1279     /* Helper classes
1280     /**********************************************************
1281      */
1282 
1283     private interface WithMember<T> {
1284         public T withMember(AnnotatedMember member);
1285     }
1286 
1287     /**
1288      * @since 2.5
1289      */
1290     protected static class MemberIterator<T extends AnnotatedMember>
1291         implements Iterator<T>
1292     {
1293         private Linked<T> next;
1294 
1295         public MemberIterator(Linked<T> first) {
1296             next = first;
1297         }
1298 
1299         @Override
1300         public boolean hasNext() {
1301             return (next != null);
1302         }
1303 
1304         @Override
1305         public T next() {
1306             if (next == null) throw new NoSuchElementException();
1307             T result = next.value;
1308             next = next.next;
1309             return result;
1310         }
1311 
1312         @Override
1313         public void remove() {
1314             throw new UnsupportedOperationException();
1315         }
1316 
1317     }
1318 
1319     /**
1320      * Node used for creating simple linked lists to efficiently store small sets
1321      * of things.
1322      */
1323     protected final static class Linked<T>
1324     {
1325         public final T value;
1326         public final Linked<T> next;
1327 
1328         public final PropertyName name;
1329         public final boolean isNameExplicit;
1330         public final boolean isVisible;
1331         public final boolean isMarkedIgnored;
1332 
1333         public Linked(T v, Linked<T> n,
1334                 PropertyName name, boolean explName, boolean visible, boolean ignored)
1335         {
1336             value = v;
1337             next = n;
1338             // ensure that we'll never have missing names
1339             this.name = (name == null || name.isEmpty()) ? null : name;
1340 
1341             if (explName) {
1342                 if (this.name == null) { // sanity check to catch internal problems
1343                     throw new IllegalArgumentException("Cannot pass true for 'explName' if name is null/empty");
1344                 }
1345                 // 03-Apr-2014, tatu: But how about name-space only override?
1346                 //   Probably should not be explicit? Or, need to merge somehow?
1347                 if (!name.hasSimpleName()) {
1348                     explName = false;
1349                 }
1350             }
1351 
1352             isNameExplicit = explName;
1353             isVisible = visible;
1354             isMarkedIgnored = ignored;
1355         }
1356 
1357         public Linked<T> withoutNext() {
1358             if (next == null) {
1359                 return this;
1360             }
1361             return new Linked<T>(value, null, name, isNameExplicit, isVisible, isMarkedIgnored);
1362         }
1363 
1364         public Linked<T> withValue(T newValue) {
1365             if (newValue == value) {
1366                 return this;
1367             }
1368             return new Linked<T>(newValue, next, name, isNameExplicit, isVisible, isMarkedIgnored);
1369         }
1370 
1371         public Linked<T> withNext(Linked<T> newNext) {
1372             if (newNext == next) {
1373                 return this;
1374             }
1375             return new Linked<T>(value, newNext, name, isNameExplicit, isVisible, isMarkedIgnored);
1376         }
1377 
1378         public Linked<T> withoutIgnored() {
1379             if (isMarkedIgnored) {
1380                 return (next == null) ? null : next.withoutIgnored();
1381             }
1382             if (next != null) {
1383                 Linked<T> newNext = next.withoutIgnored();
1384                 if (newNext != next) {
1385                     return withNext(newNext);
1386                 }
1387             }
1388             return this;
1389         }
1390 
1391         public Linked<T> withoutNonVisible() {
1392             Linked<T> newNext = (next == null) ? null : next.withoutNonVisible();
1393             return isVisible ? withNext(newNext) : newNext;
1394         }
1395 
1396         /**
1397          * Method called to append given node(s) at the end of this
1398          * node chain.
1399          */
1400         protected Linked<T> append(Linked<T> appendable) {
1401             if (next == null) {
1402                 return withNext(appendable);
1403             }
1404             return withNext(next.append(appendable));
1405         }
1406 
1407         public Linked<T> trimByVisibility() {
1408             if (next == null) {
1409                 return this;
1410             }
1411             Linked<T> newNext = next.trimByVisibility();
1412             if (name != null) { // this already has highest; how about next one?
1413                 if (newNext.name == null) { // next one not, drop it
1414                     return withNext(null);
1415                 }
1416                 //  both have it, keep
1417                 return withNext(newNext);
1418             }
1419             if (newNext.name != null) { // next one has higher, return it...
1420                 return newNext;
1421             }
1422             // neither has explicit name; how about visibility?
1423             if (isVisible == newNext.isVisible) { // same; keep both in current order
1424                 return withNext(newNext);
1425             }
1426             return isVisible ? withNext(null) : newNext;
1427         }
1428 
1429         @Override
1430         public String toString() {
1431             String msg = String.format("%s[visible=%b,ignore=%b,explicitName=%b]",
1432                     value.toString(), isVisible, isMarkedIgnored, isNameExplicit);
1433             if (next != null) {
1434                 msg = msg + ", "+next.toString();
1435             }
1436             return msg;
1437         }
1438     }
1439 }
1440