1 package com.fasterxml.jackson.databind.deser;
2
3 import java.io.IOException;
4 import java.lang.annotation.Annotation;
5
6 import com.fasterxml.jackson.annotation.JacksonInject;
7 import com.fasterxml.jackson.core.JsonParser;
8
9 import com.fasterxml.jackson.databind.*;
10 import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
11 import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
12 import com.fasterxml.jackson.databind.introspect.AnnotatedParameter;
13 import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
14 import com.fasterxml.jackson.databind.util.Annotations;
15 import com.fasterxml.jackson.databind.util.ClassUtil;
16
17
29 public class CreatorProperty
30 extends SettableBeanProperty
31 {
32 private static final long serialVersionUID = 1L;
33
34
39 protected final AnnotatedParameter _annotated;
40
41
47 protected final JacksonInject.Value _injectableValue;
48
49
60 protected SettableBeanProperty _fallbackSetter;
61
62
65 protected final int _creatorIndex;
66
67
76 protected boolean _ignorable;
77
78
81 protected CreatorProperty(PropertyName name, JavaType type, PropertyName wrapperName,
82 TypeDeserializer typeDeser,
83 Annotations contextAnnotations, AnnotatedParameter param,
84 int index, JacksonInject.Value injectable,
85 PropertyMetadata metadata)
86 {
87 super(name, type, wrapperName, typeDeser, contextAnnotations, metadata);
88 _annotated = param;
89 _creatorIndex = index;
90 _injectableValue = injectable;
91 _fallbackSetter = null;
92 }
93
94
97 @Deprecated
98 public CreatorProperty(PropertyName name, JavaType type, PropertyName wrapperName,
99 TypeDeserializer typeDeser,
100 Annotations contextAnnotations, AnnotatedParameter param,
101 int index, Object injectableValueId,
102 PropertyMetadata metadata)
103 {
104 this(name, type, wrapperName, typeDeser, contextAnnotations, param, index,
105 (injectableValueId == null) ? null
106 : JacksonInject.Value.construct(injectableValueId, null),
107 metadata);
108 }
109
110
128 public static CreatorProperty construct(PropertyName name, JavaType type, PropertyName wrapperName,
129 TypeDeserializer typeDeser,
130 Annotations contextAnnotations, AnnotatedParameter param,
131 int index, JacksonInject.Value injectable,
132 PropertyMetadata metadata)
133 {
134 return new CreatorProperty(name, type, wrapperName, typeDeser, contextAnnotations,
135 param, index, injectable, metadata);
136 }
137
138
141 protected CreatorProperty(CreatorProperty src, PropertyName newName) {
142 super(src, newName);
143 _annotated = src._annotated;
144 _injectableValue = src._injectableValue;
145 _fallbackSetter = src._fallbackSetter;
146 _creatorIndex = src._creatorIndex;
147 _ignorable = src._ignorable;
148 }
149
150 protected CreatorProperty(CreatorProperty src, JsonDeserializer<?> deser,
151 NullValueProvider nva) {
152 super(src, deser, nva);
153 _annotated = src._annotated;
154 _injectableValue = src._injectableValue;
155 _fallbackSetter = src._fallbackSetter;
156 _creatorIndex = src._creatorIndex;
157 _ignorable = src._ignorable;
158 }
159
160 @Override
161 public SettableBeanProperty withName(PropertyName newName) {
162 return new CreatorProperty(this, newName);
163 }
164
165 @Override
166 public SettableBeanProperty withValueDeserializer(JsonDeserializer<?> deser) {
167 if (_valueDeserializer == deser) {
168 return this;
169 }
170
171 NullValueProvider nvp = (_valueDeserializer == _nullProvider) ? deser : _nullProvider;
172 return new CreatorProperty(this, deser, nvp);
173 }
174
175 @Override
176 public SettableBeanProperty withNullProvider(NullValueProvider nva) {
177 return new CreatorProperty(this, _valueDeserializer, nva);
178 }
179
180 @Override
181 public void fixAccess(DeserializationConfig config) {
182 if (_fallbackSetter != null) {
183 _fallbackSetter.fixAccess(config);
184 }
185 }
186
187
193 public void setFallbackSetter(SettableBeanProperty fallbackSetter) {
194 _fallbackSetter = fallbackSetter;
195 }
196
197 @Override
198 public void markAsIgnorable() {
199 _ignorable = true;
200 }
201
202 @Override
203 public boolean isIgnorable() {
204 return _ignorable;
205 }
206
207
212
213
214
215
216
217
218 @Deprecated
219 public Object findInjectableValue(DeserializationContext context, Object beanInstance)
220 throws JsonMappingException
221 {
222 if (_injectableValue == null) {
223 context.reportBadDefinition(ClassUtil.classOf(beanInstance),
224 String.format("Property '%s' (type %s) has no injectable value id configured",
225 getName(), getClass().getName()));
226 }
227 return context.findInjectableValue(_injectableValue.getId(), this, beanInstance);
228 }
229
230
231
232
233
234 @Deprecated
235 public void inject(DeserializationContext context, Object beanInstance) throws IOException
236 {
237 set(beanInstance, findInjectableValue(context, beanInstance));
238 }
239
240
245
246 @Override
247 public <A extends Annotation> A getAnnotation(Class<A> acls) {
248 if (_annotated == null) {
249 return null;
250 }
251 return _annotated.getAnnotation(acls);
252 }
253
254 @Override public AnnotatedMember getMember() { return _annotated; }
255
256 @Override public int getCreatorIndex() {
257 return _creatorIndex;
258 }
259
260
265
266 @Override
267 public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
268 Object instance) throws IOException
269 {
270 _verifySetter();
271 _fallbackSetter.set(instance, deserialize(p, ctxt));
272 }
273
274 @Override
275 public Object deserializeSetAndReturn(JsonParser p,
276 DeserializationContext ctxt, Object instance) throws IOException
277 {
278 _verifySetter();
279 return _fallbackSetter.setAndReturn(instance, deserialize(p, ctxt));
280 }
281
282 @Override
283 public void set(Object instance, Object value) throws IOException
284 {
285 _verifySetter();
286 _fallbackSetter.set(instance, value);
287 }
288
289 @Override
290 public Object setAndReturn(Object instance, Object value) throws IOException
291 {
292 _verifySetter();
293 return _fallbackSetter.setAndReturn(instance, value);
294 }
295
296 @Override
297 public PropertyMetadata getMetadata() {
298
299
300
301
302
303 PropertyMetadata md = super.getMetadata();
304 if (_fallbackSetter != null) {
305 return md.withMergeInfo(_fallbackSetter.getMetadata().getMergeInfo());
306 }
307 return md;
308 }
309
310
311 @Override
312 public Object getInjectableValueId() {
313 return (_injectableValue == null) ? null : _injectableValue.getId();
314 }
315
316 @Override
317 public boolean isInjectionOnly() {
318 return (_injectableValue != null) && !_injectableValue.willUseInput(true);
319 }
320
321
322
323
328
329 @Override
330 public String toString() { return "[creator property, name '"+getName()+"'; inject id '"+getInjectableValueId()+"']"; }
331
332
337
338
339 private final void _verifySetter() throws IOException {
340 if (_fallbackSetter == null) {
341 _reportMissingSetter(null, null);
342 }
343 }
344
345
346 private void _reportMissingSetter(JsonParser p, DeserializationContext ctxt) throws IOException
347 {
348 final String msg = "No fallback setter/field defined for creator property '"+getName()+"'";
349
350
351 if (ctxt != null ) {
352 ctxt.reportBadDefinition(getType(), msg);
353 } else {
354 throw InvalidDefinitionException.from(p, msg, getType());
355 }
356 }
357 }
358