aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/fasterxml/jackson/databind/introspect/BeanPropertyDefinition.java
blob: 85be2e9b647234d6ed2c2bf3274f12bf8cb25b2d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
package com.fasterxml.jackson.databind.introspect;

import java.util.Iterator;

import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonInclude;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.Named;

/**
 * Simple value classes that contain definitions of properties,
 * used during introspection of properties to use for
 * serialization and deserialization purposes.
 * These instances are created before actual {@link BeanProperty}
 * instances are created, i.e. they are used earlier in the process
 * flow, and are typically use to construct actual
 * {@link BeanProperty} instances.
 */
public abstract class BeanPropertyDefinition
    implements Named
{
    protected final static JsonInclude.Value EMPTY_INCLUDE = JsonInclude.Value.empty();

    /*
    /**********************************************************
    /* Fluent factory methods for creating modified copies
    /**********************************************************
     */

    /**
     * Method that can be used to create a definition with
     * same settings as this one, but with different
     * (external) name; that is, one for which
     * {@link #getName()} would return <code>newName</code>.
     * 
     * @since 2.3
     */
    public abstract BeanPropertyDefinition withName(PropertyName newName);

    /**
     * Alternate "mutant factory" that will only change simple name, but
     * leave other optional parts (like namespace) as is.
     * 
     * @since 2.3
     */
    public abstract BeanPropertyDefinition withSimpleName(String newSimpleName);

    /*
    /**********************************************************
    /* Property name information
    /**********************************************************
     */

    /**
     * Accessor for name used for external representation (in JSON).
     */
    @Override // from Named
    public abstract String getName();

    public abstract PropertyName getFullName();

    /**
     * @since 2.6
     */
    public boolean hasName(PropertyName name) {
        return getFullName().equals(name);
    }
    
    /**
     * Accessor that can be used to determine implicit name from underlying
     * element(s) before possible renaming. This is the "internal"
     * name derived from accessor ("x" from "getX"), and is not based on
     * annotations or naming strategy.
     */
    public abstract String getInternalName();
    
    /**
     * Accessor for finding wrapper name to use for property (if any).
     * 
     * @since 2.2
     */
    public abstract PropertyName getWrapperName();

    /**
     * Accessor that can be called to check whether property was included
     * due to an explicit marker (usually annotation), or just by naming
     * convention.
     * 
     * @return True if property was explicitly included (usually by having
     *   one of components being annotated); false if inclusion was purely
     *   due to naming or visibility definitions (that is, implicit)
     */
    public abstract boolean isExplicitlyIncluded();

    /**
     * Accessor that can be called to check whether property name was
     * due to an explicit marker (usually annotation), or just by naming
     * convention or use of "use-default-name" marker (annotation).
     *<p>
     * Note that entries that return true from this method will always
     * return true for {@link #isExplicitlyIncluded()}, but not necessarily
     * vice versa.
     *
     * @since 2.4
     */
    public boolean isExplicitlyNamed() {
        return isExplicitlyIncluded();
    }

    /*
    /**********************************************************
    /* Basic property metadata
    /**********************************************************
     */

    /**
     * @since 2.9
     */
    public abstract JavaType getPrimaryType();

    /**
     * @since 2.9
     */
    public abstract Class<?> getRawPrimaryType();
    
    /**
     * Method for accessing additional metadata.
     * NOTE: will never return null, so de-referencing return value
     * is safe.
     * 
     * @since 2.3
     */
    public abstract PropertyMetadata getMetadata();

    /**
     * Method used to check if this property is expected to have a value;
     * and if none found, should either be considered invalid (and most likely
     * fail deserialization), or handled by other means (by providing default
     * value)
     */
    public boolean isRequired() {
        return getMetadata().isRequired();
    }

    /*
    /**********************************************************
    /* Capabilities
    /**********************************************************
     */

    public boolean couldDeserialize() { return getMutator() != null; }
    public boolean couldSerialize() { return getAccessor() != null; }

    /*
    /**********************************************************
    /* Access to accessors (fields, methods etc)
    /**********************************************************
     */

    public abstract boolean hasGetter();
    public abstract boolean hasSetter();
    public abstract boolean hasField();
    public abstract boolean hasConstructorParameter();

    public abstract AnnotatedMethod getGetter();
    public abstract AnnotatedMethod getSetter();
    public abstract AnnotatedField getField();
    public abstract AnnotatedParameter getConstructorParameter();

    /**
     * Additional method that may be called instead of {@link #getConstructorParameter()}
     * to get access to all constructor parameters, not just the highest priority one.
     * 
     * @since 2.5
     */
    public Iterator<AnnotatedParameter> getConstructorParameters() {
        return ClassUtil.emptyIterator();
    }
    
    /**
     * Method used to find accessor (getter, field to access) to use for accessing
     * value of the property.
     * Null if no such member exists.
     */
    public AnnotatedMember getAccessor()
    {
        AnnotatedMember m = getGetter();
        if (m == null) {
            m = getField();
        }
        return m;
    }

    /**
     * Method used to find mutator (constructor parameter, setter, field) to use for
     * changing value of the property.
     * Null if no such member exists.
     */
    public AnnotatedMember getMutator() {
        AnnotatedMember acc = getConstructorParameter();
        if (acc == null) {
            acc = getSetter();
            if (acc == null) {
                acc = getField();
            }
        }
        return acc;
    }

    /**
     * @since 2.3
     */
    public AnnotatedMember getNonConstructorMutator() {
        AnnotatedMember m = getSetter();
        if (m == null) {
            m = getField();
        }
        return m;
    }

    /**
     * Method used to find the property member (getter, setter, field) that has
     * the highest precedence in current context (getter method when serializing,
     * if available, and so forth), if any.
     *<p>
     * Note: abstract since 2.5
     * 
     * @since 2.1
     */
    public abstract AnnotatedMember getPrimaryMember();
    
    /*
    /**********************************************************
    /* More refined access to configuration features
    /* (usually based on annotations and/or config overrides)
    /* Since most trivial implementations do not support
    /* these methods, they are implemented as no-ops.
    /**********************************************************
     */

    /**
     * Method used to find View-inclusion definitions for the property.
     */
    public Class<?>[] findViews() { return null; }

    /**
     * Method used to find whether property is part of a bi-directional
     * reference.
     */
    public AnnotationIntrospector.ReferenceProperty findReferenceType() { return null; }

    /**
     * @since 2.9
     */
    public String findReferenceName() {
        AnnotationIntrospector.ReferenceProperty ref = findReferenceType();
        return (ref == null) ? null : ref.getName();
    }

    /**
     * @since 2.11
     */
    public JacksonInject.Value findValueInjection() {
        return null;
    }

    /**
     * Method used to check whether this logical property has a marker
     * to indicate it should be used as the type id for polymorphic type
     * handling.
     */
    public boolean isTypeId() { return false; }

    /**
     * Method used to check whether this logical property indicates that
     * value POJOs should be written using additional Object Identifier
     * (or, when multiple references exist, all but first AS Object Identifier).
     */
    public ObjectIdInfo findObjectIdInfo() { return null; }

    /**
     * Method used to check if this property has specific inclusion override
     * associated with it or not.
     * It should NOT check for any default settings (global, per-type, or
     * containing POJO settings)
     * 
     * @since 2.5
     */
    public abstract JsonInclude.Value findInclusion();
}