1 package com.fasterxml.jackson.databind.util;
2 
3 import java.util.Collections;
4 import java.util.Iterator;
5 
6 import com.fasterxml.jackson.annotation.JsonInclude;
7 
8 import com.fasterxml.jackson.databind.*;
9 import com.fasterxml.jackson.databind.cfg.MapperConfig;
10 import com.fasterxml.jackson.databind.introspect.*;
11 import com.fasterxml.jackson.databind.type.TypeFactory;
12 
13 /**
14  * Simple immutable {@link BeanPropertyDefinition} implementation that can
15  * be wrapped around a {@link AnnotatedMember} that is a simple
16  * accessor (getter) or mutator (setter, constructor parameter)
17  * (or both, for fields).
18  */
19 public class SimpleBeanPropertyDefinition
20     extends BeanPropertyDefinition
21 {
22     protected final AnnotationIntrospector _annotationIntrospector;
23 
24     /**
25      * Member that defines logical property. Assumption is that it
26      * should be a 'simple' accessor; meaning a zero-argument getter,
27      * single-argument setter or constructor parameter.
28      *<p>
29      * NOTE: for "virtual" properties, this is null.
30      */
31     protected final AnnotatedMember _member;
32 
33     /**
34      * @since 2.5
35      */
36     protected final PropertyMetadata _metadata;
37 
38     /**
39      * @since 2.5
40      */
41     protected final PropertyName _fullName;
42 
43     /**
44      * @since 2.5
45      */
46     protected final JsonInclude.Value _inclusion;
47 
48     /*
49     /**********************************************************
50     /* Construction
51     /**********************************************************
52      */
53 
54     /**
55      * @since 2.9
56      */
SimpleBeanPropertyDefinition(AnnotationIntrospector intr, AnnotatedMember member, PropertyName fullName, PropertyMetadata metadata, JsonInclude.Value inclusion)57     protected SimpleBeanPropertyDefinition(AnnotationIntrospector intr,
58             AnnotatedMember member, PropertyName fullName, PropertyMetadata metadata,
59             JsonInclude.Value inclusion)
60     {
61         _annotationIntrospector = intr;
62         _member = member;
63         _fullName = fullName;
64         _metadata = (metadata == null) ? PropertyMetadata.STD_OPTIONAL: metadata;
65         _inclusion = inclusion;
66     }
67 
68     /**
69      * @since 2.2
70      */
construct(MapperConfig<?> config, AnnotatedMember member)71     public static SimpleBeanPropertyDefinition construct(MapperConfig<?> config,
72     		AnnotatedMember member)
73     {
74         return new SimpleBeanPropertyDefinition(config.getAnnotationIntrospector(),
75                 member, PropertyName.construct(member.getName()), null, EMPTY_INCLUDE);
76     }
77 
78     /**
79      * @since 2.5
80      */
construct(MapperConfig<?> config, AnnotatedMember member, PropertyName name)81     public static SimpleBeanPropertyDefinition construct(MapperConfig<?> config,
82             AnnotatedMember member, PropertyName name) {
83         return construct(config, member, name, null, EMPTY_INCLUDE);
84     }
85 
86     /**
87      * Method called to create instance for virtual properties.
88      *
89      * @since 2.5
90      */
construct(MapperConfig<?> config, AnnotatedMember member, PropertyName name, PropertyMetadata metadata, JsonInclude.Include inclusion)91     public static SimpleBeanPropertyDefinition construct(MapperConfig<?> config,
92             AnnotatedMember member, PropertyName name, PropertyMetadata metadata,
93             JsonInclude.Include inclusion)
94     {
95         JsonInclude.Value inclValue
96              = ((inclusion == null) || (inclusion == JsonInclude.Include.USE_DEFAULTS))
97              ? EMPTY_INCLUDE : JsonInclude.Value.construct(inclusion, null);
98         return new SimpleBeanPropertyDefinition(config.getAnnotationIntrospector(),
99                 member, name, metadata, inclValue);
100     }
101 
102     /**
103      * @since 2.7
104      */
construct(MapperConfig<?> config, AnnotatedMember member, PropertyName name, PropertyMetadata metadata, JsonInclude.Value inclusion)105     public static SimpleBeanPropertyDefinition construct(MapperConfig<?> config,
106             AnnotatedMember member, PropertyName name, PropertyMetadata metadata,
107             JsonInclude.Value inclusion) {
108           return new SimpleBeanPropertyDefinition(config.getAnnotationIntrospector(),
109                   member, name, metadata, inclusion);
110     }
111 
112     /*
113     /**********************************************************
114     /* Fluent factories
115     /**********************************************************
116      */
117 
118     @Override
withSimpleName(String newName)119     public BeanPropertyDefinition withSimpleName(String newName) {
120         if (_fullName.hasSimpleName(newName) && !_fullName.hasNamespace()) {
121             return this;
122         }
123         return new SimpleBeanPropertyDefinition(_annotationIntrospector,
124                 _member, new PropertyName(newName), _metadata, _inclusion);
125     }
126 
127     @Override
withName(PropertyName newName)128     public BeanPropertyDefinition withName(PropertyName newName) {
129         if (_fullName.equals(newName)) {
130             return this;
131         }
132         return new SimpleBeanPropertyDefinition(_annotationIntrospector,
133                 _member, newName, _metadata, _inclusion);
134     }
135 
136     /**
137      * @since 2.5
138      */
withMetadata(PropertyMetadata metadata)139     public BeanPropertyDefinition withMetadata(PropertyMetadata metadata) {
140         if (metadata.equals(_metadata)) {
141             return this;
142         }
143         return new SimpleBeanPropertyDefinition(_annotationIntrospector,
144                 _member, _fullName, metadata, _inclusion);
145     }
146 
147     /**
148      * @since 2.5
149      */
withInclusion(JsonInclude.Value inclusion)150     public BeanPropertyDefinition withInclusion(JsonInclude.Value inclusion) {
151         if (_inclusion == inclusion) {
152             return this;
153         }
154         return new SimpleBeanPropertyDefinition(_annotationIntrospector,
155                 _member, _fullName, _metadata, inclusion);
156     }
157 
158     /*
159     /**********************************************************
160     /* Basic property information, name, type
161     /**********************************************************
162      */
163 
164     @Override
getName()165     public String getName() { return _fullName.getSimpleName(); }
166 
167     @Override
getFullName()168     public PropertyName getFullName() { return _fullName; }
169 
170     @Override
hasName(PropertyName name)171     public boolean hasName(PropertyName name) {
172         return _fullName.equals(name);
173     }
174 
175     @Override
getInternalName()176     public String getInternalName() { return getName(); }
177 
178     @Override
getWrapperName()179     public PropertyName getWrapperName() {
180         if ((_annotationIntrospector == null) || (_member == null)) {
181             return null;
182         }
183         return _annotationIntrospector.findWrapperName(_member);
184     }
185 
186     // hmmh. what should we claim here?
187 
isExplicitlyIncluded()188     @Override public boolean isExplicitlyIncluded() { return false; }
isExplicitlyNamed()189     @Override public boolean isExplicitlyNamed() { return false; }
190 
191     /**
192      * We will indicate that property is optional, since there is nothing
193      * to indicate whether it might be required.
194      */
195     @Override
getMetadata()196     public PropertyMetadata getMetadata() {
197         return _metadata;
198     }
199 
200     @Override
getPrimaryType()201     public JavaType getPrimaryType() {
202         if (_member == null) {
203             return TypeFactory.unknownType();
204         }
205         return _member.getType();
206     }
207 
208     @Override
getRawPrimaryType()209     public Class<?> getRawPrimaryType() {
210         if (_member == null) {
211             return Object.class;
212         }
213         return _member.getRawType();
214     }
215 
216     @Override
findInclusion()217     public JsonInclude.Value findInclusion() {
218         return _inclusion;
219     }
220 
221     /*
222     /**********************************************************
223     /* Access to accessors (fields, methods etc)
224     /**********************************************************
225      */
226 
227     @Override
hasGetter()228     public boolean hasGetter() { return (getGetter() != null); }
229 
230     @Override
hasSetter()231     public boolean hasSetter() { return (getSetter() != null); }
232 
233     @Override
hasField()234     public boolean hasField() { return (_member instanceof AnnotatedField); }
235 
236     @Override
hasConstructorParameter()237     public boolean hasConstructorParameter() { return (_member instanceof AnnotatedParameter); }
238 
239     @Override
getGetter()240     public AnnotatedMethod getGetter() {
241         if ((_member instanceof AnnotatedMethod)
242                 && ((AnnotatedMethod) _member).getParameterCount() == 0) {
243             return (AnnotatedMethod) _member;
244         }
245         return null;
246     }
247 
248     @Override
getSetter()249     public AnnotatedMethod getSetter() {
250         if ((_member instanceof AnnotatedMethod)
251                 && ((AnnotatedMethod) _member).getParameterCount() == 1) {
252             return (AnnotatedMethod) _member;
253         }
254         return null;
255     }
256 
257     @Override
getField()258     public AnnotatedField getField() {
259         return (_member instanceof AnnotatedField) ? (AnnotatedField) _member : null;
260     }
261 
262     @Override
getConstructorParameter()263     public AnnotatedParameter getConstructorParameter() {
264         return (_member instanceof AnnotatedParameter) ? (AnnotatedParameter) _member : null;
265     }
266 
267     @Override
getConstructorParameters()268     public Iterator<AnnotatedParameter> getConstructorParameters() {
269         AnnotatedParameter param = getConstructorParameter();
270         if (param == null) {
271             return ClassUtil.emptyIterator();
272         }
273         return Collections.singleton(param).iterator();
274     }
275 
276     @Override
getPrimaryMember()277     public AnnotatedMember getPrimaryMember() { return _member; }
278 }
279