1 package com.fasterxml.jackson.databind.introspect;
2 
3 import java.util.Iterator;
4 
5 import com.fasterxml.jackson.annotation.JsonInclude;
6 
7 import com.fasterxml.jackson.databind.*;
8 import com.fasterxml.jackson.databind.util.ClassUtil;
9 import com.fasterxml.jackson.databind.util.Named;
10 
11 /**
12  * Simple value classes that contain definitions of properties,
13  * used during introspection of properties to use for
14  * serialization and deserialization purposes.
15  * These instances are created before actual {@link BeanProperty}
16  * instances are created, i.e. they are used earlier in the process
17  * flow, and are typically use to construct actual
18  * {@link BeanProperty} instances.
19  */
20 public abstract class BeanPropertyDefinition
21     implements Named
22 {
23     protected final static JsonInclude.Value EMPTY_INCLUDE = JsonInclude.Value.empty();
24 
25     /*
26     /**********************************************************
27     /* Fluent factory methods for creating modified copies
28     /**********************************************************
29      */
30 
31     /**
32      * Method that can be used to create a definition with
33      * same settings as this one, but with different
34      * (external) name; that is, one for which
35      * {@link #getName()} would return <code>newName</code>.
36      *
37      * @since 2.3
38      */
withName(PropertyName newName)39     public abstract BeanPropertyDefinition withName(PropertyName newName);
40 
41     /**
42      * Alternate "mutant factory" that will only change simple name, but
43      * leave other optional parts (like namespace) as is.
44      *
45      * @since 2.3
46      */
withSimpleName(String newSimpleName)47     public abstract BeanPropertyDefinition withSimpleName(String newSimpleName);
48 
49     /*
50     /**********************************************************
51     /* Property name information
52     /**********************************************************
53      */
54 
55     /**
56      * Accessor for name used for external representation (in JSON).
57      */
58     @Override // from Named
getName()59     public abstract String getName();
60 
getFullName()61     public abstract PropertyName getFullName();
62 
63     /**
64      * @since 2.6
65      */
hasName(PropertyName name)66     public boolean hasName(PropertyName name) {
67         return getFullName().equals(name);
68     }
69 
70     /**
71      * Accessor that can be used to determine implicit name from underlying
72      * element(s) before possible renaming. This is the "internal"
73      * name derived from accessor ("x" from "getX"), and is not based on
74      * annotations or naming strategy.
75      */
getInternalName()76     public abstract String getInternalName();
77 
78     /**
79      * Accessor for finding wrapper name to use for property (if any).
80      *
81      * @since 2.2
82      */
getWrapperName()83     public abstract PropertyName getWrapperName();
84 
85     /**
86      * Accessor that can be called to check whether property was included
87      * due to an explicit marker (usually annotation), or just by naming
88      * convention.
89      *
90      * @return True if property was explicitly included (usually by having
91      *   one of components being annotated); false if inclusion was purely
92      *   due to naming or visibility definitions (that is, implicit)
93      */
isExplicitlyIncluded()94     public abstract boolean isExplicitlyIncluded();
95 
96     /**
97      * Accessor that can be called to check whether property name was
98      * due to an explicit marker (usually annotation), or just by naming
99      * convention or use of "use-default-name" marker (annotation).
100      *<p>
101      * Note that entries that return true from this method will always
102      * return true for {@link #isExplicitlyIncluded()}, but not necessarily
103      * vice versa.
104      *
105      * @since 2.4
106      */
isExplicitlyNamed()107     public boolean isExplicitlyNamed() {
108         return isExplicitlyIncluded();
109     }
110 
111     /*
112     /**********************************************************
113     /* Basic property metadata
114     /**********************************************************
115      */
116 
117     /**
118      * @since 2.9
119      */
getPrimaryType()120     public abstract JavaType getPrimaryType();
121 
122     /**
123      * @since 2.9
124      */
getRawPrimaryType()125     public abstract Class<?> getRawPrimaryType();
126 
127     /**
128      * Method for accessing additional metadata.
129      * NOTE: will never return null, so de-referencing return value
130      * is safe.
131      *
132      * @since 2.3
133      */
getMetadata()134     public abstract PropertyMetadata getMetadata();
135 
136     /**
137      * Method used to check if this property is expected to have a value;
138      * and if none found, should either be considered invalid (and most likely
139      * fail deserialization), or handled by other means (by providing default
140      * value)
141      */
isRequired()142     public boolean isRequired() {
143         return getMetadata().isRequired();
144     }
145 
146     /*
147     /**********************************************************
148     /* Capabilities
149     /**********************************************************
150      */
151 
couldDeserialize()152     public boolean couldDeserialize() { return getMutator() != null; }
couldSerialize()153     public boolean couldSerialize() { return getAccessor() != null; }
154 
155     /*
156     /**********************************************************
157     /* Access to accessors (fields, methods etc)
158     /**********************************************************
159      */
160 
hasGetter()161     public abstract boolean hasGetter();
hasSetter()162     public abstract boolean hasSetter();
hasField()163     public abstract boolean hasField();
hasConstructorParameter()164     public abstract boolean hasConstructorParameter();
165 
getGetter()166     public abstract AnnotatedMethod getGetter();
getSetter()167     public abstract AnnotatedMethod getSetter();
getField()168     public abstract AnnotatedField getField();
getConstructorParameter()169     public abstract AnnotatedParameter getConstructorParameter();
170 
171     /**
172      * Additional method that may be called instead of {@link #getConstructorParameter()}
173      * to get access to all constructor parameters, not just the highest priority one.
174      *
175      * @since 2.5
176      */
getConstructorParameters()177     public Iterator<AnnotatedParameter> getConstructorParameters() {
178         return ClassUtil.emptyIterator();
179     }
180 
181     /**
182      * Method used to find accessor (getter, field to access) to use for accessing
183      * value of the property.
184      * Null if no such member exists.
185      */
getAccessor()186     public AnnotatedMember getAccessor()
187     {
188         AnnotatedMember m = getGetter();
189         if (m == null) {
190             m = getField();
191         }
192         return m;
193     }
194 
195     /**
196      * Method used to find mutator (constructor parameter, setter, field) to use for
197      * changing value of the property.
198      * Null if no such member exists.
199      */
getMutator()200     public AnnotatedMember getMutator() {
201         AnnotatedMember acc = getConstructorParameter();
202         if (acc == null) {
203             acc = getSetter();
204             if (acc == null) {
205                 acc = getField();
206             }
207         }
208         return acc;
209     }
210 
211     /**
212      * @since 2.3
213      */
getNonConstructorMutator()214     public AnnotatedMember getNonConstructorMutator() {
215         AnnotatedMember m = getSetter();
216         if (m == null) {
217             m = getField();
218         }
219         return m;
220     }
221 
222     /**
223      * Method used to find the property member (getter, setter, field) that has
224      * the highest precedence in current context (getter method when serializing,
225      * if available, and so forth), if any.
226      *<p>
227      * Note: may throw {@link IllegalArgumentException} in case problems are found
228      * trying to getter or setter info.
229      *<p>
230      * Note: abstract since 2.5
231      *
232      * @since 2.1
233      */
getPrimaryMember()234     public abstract AnnotatedMember getPrimaryMember();
235 
236     /*
237     /**********************************************************
238     /* More refined access to configuration features
239     /* (usually based on annotations and/or config overrides)
240     /* Since most trivial implementations do not support
241     /* these methods, they are implemented as no-ops.
242     /**********************************************************
243      */
244 
245     /**
246      * Method used to find View-inclusion definitions for the property.
247      */
findViews()248     public Class<?>[] findViews() { return null; }
249 
250     /**
251      * Method used to find whether property is part of a bi-directional
252      * reference.
253      */
findReferenceType()254     public AnnotationIntrospector.ReferenceProperty findReferenceType() { return null; }
255 
256     /**
257      * @since 2.9
258      */
findReferenceName()259     public String findReferenceName() {
260         AnnotationIntrospector.ReferenceProperty ref = findReferenceType();
261         return (ref == null) ? null : ref.getName();
262     }
263 
264     /**
265      * Method used to check whether this logical property has a marker
266      * to indicate it should be used as the type id for polymorphic type
267      * handling.
268      */
isTypeId()269     public boolean isTypeId() { return false; }
270 
271     /**
272      * Method used to check whether this logical property indicates that
273      * value POJOs should be written using additional Object Identifier
274      * (or, when multiple references exist, all but first AS Object Identifier).
275      */
findObjectIdInfo()276     public ObjectIdInfo findObjectIdInfo() { return null; }
277 
278     /**
279      * Method used to check if this property has specific inclusion override
280      * associated with it or not.
281      * It should NOT check for any default settings (global, per-type, or
282      * containing POJO settings)
283      *
284      * @since 2.5
285      */
findInclusion()286     public abstract JsonInclude.Value findInclusion();
287 }
288