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.core.*;
7
8 import com.fasterxml.jackson.databind.*;
9 import com.fasterxml.jackson.databind.deser.impl.FailingDeserializer;
10 import com.fasterxml.jackson.databind.deser.impl.NullsConstantProvider;
11 import com.fasterxml.jackson.databind.introspect.*;
12 import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
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 import com.fasterxml.jackson.databind.util.ViewMatcher;
17
18 /**
19 * Base class for deserializable properties of a bean: contains
20 * both type and name definitions, and reflection-based set functionality.
21 * Concrete sub-classes implement details, so that field- and
22 * setter-backed properties, as well as a few more esoteric variations,
23 * can be handled.
24 */
25 @SuppressWarnings("serial")
26 public abstract class SettableBeanProperty
27 extends ConcreteBeanPropertyBase
28 implements java.io.Serializable
29 {
30 /**
31 * To avoid nasty NPEs, let's use a placeholder for _valueDeserializer,
32 * if real deserializer is not (yet) available.
33 *
34 * @since 2.2
35 */
36 protected static final JsonDeserializer<Object> MISSING_VALUE_DESERIALIZER = new FailingDeserializer(
37 "No _valueDeserializer assigned");
38
39 /**
40 * Logical name of the property (often but not always derived
41 * from the setter method name)
42 */
43 protected final PropertyName _propName;
44
45 /**
46 * Base type for property; may be a supertype of actual value.
47 */
48 protected final JavaType _type;
49
50 /**
51 * @since 2.2
52 */
53 protected final PropertyName _wrapperName;
54
55 /**
56 * Class that contains this property (either class that declares
57 * the property or one of its subclasses), class that is
58 * deserialized using deserializer that contains this property.
59 */
60 protected final transient Annotations _contextAnnotations;
61
62 /**
63 * Deserializer used for handling property value.
64 *<p>
65 * NOTE: has been immutable since 2.3
66 */
67 protected final JsonDeserializer<Object> _valueDeserializer;
68
69 /**
70 * If value will contain type information (to support
71 * polymorphic handling), this is the type deserializer
72 * used to handle type resolution.
73 */
74 protected final TypeDeserializer _valueTypeDeserializer;
75
76 /**
77 * Entity used for possible translation from `null` into non-null
78 * value of type of this property.
79 * Often same as <code>_valueDeserializer</code>, but not always.
80 *
81 * @since 2.9
82 */
83 protected final NullValueProvider _nullProvider;
84
85 /*
86 /**********************************************************
87 /* Configuration that is not yet immutable; generally assigned
88 /* during initialization process but cannot be passed to
89 /* constructor.
90 /**********************************************************
91 */
92
93 /**
94 * If property represents a managed (forward) reference, we will need
95 * the name of reference for later linking.
96 *<p>
97 * TODO: should try to make immutable.
98 */
99 protected String _managedReferenceName;
100
101 /**
102 * This is the information for object identity associated with the property.
103 * <p>
104 * TODO: should try to make immutable.
105 */
106 protected ObjectIdInfo _objectIdInfo;
107
108 /**
109 * Helper object used for checking whether this property is to
110 * be included in the active view, if property is view-specific;
111 * null otherwise.
112 *<p>
113 * TODO: should try to make immutable.
114 */
115 protected ViewMatcher _viewMatcher;
116
117 /**
118 * Index of property (within all property of a bean); assigned
119 * when all properties have been collected. Order of entries
120 * is arbitrary, but once indexes are assigned they are not
121 * changed.
122 *<p>
123 * TODO: should try to make immutable if at all possible
124 */
125 protected int _propertyIndex = -1;
126
127 /*
128 /**********************************************************
129 /* Life-cycle (construct & configure)
130 /**********************************************************
131 */
132
133 protected SettableBeanProperty(BeanPropertyDefinition propDef,
134 JavaType type, TypeDeserializer typeDeser, Annotations contextAnnotations)
135 {
136 this(propDef.getFullName(), type, propDef.getWrapperName(), typeDeser,
137 contextAnnotations, propDef.getMetadata());
138 }
139
140 protected SettableBeanProperty(PropertyName propName, JavaType type, PropertyName wrapper,
141 TypeDeserializer typeDeser, Annotations contextAnnotations,
142 PropertyMetadata metadata)
143 {
144 super(metadata);
145 // 09-Jan-2009, tatu: Intern()ing makes sense since Jackson parsed
146 // field names are (usually) interned too, hence lookups will be faster.
147 // 23-Oct-2009, tatu: should this be disabled wrt [JACKSON-180]?
148 // Probably need not, given that namespace of field/method names
149 // is not unbounded, unlike potential JSON names.
150 if (propName == null) {
151 _propName = PropertyName.NO_NAME;
152 } else {
153 _propName = propName.internSimpleName();
154 }
155 _type = type;
156 _wrapperName = wrapper;
157 _contextAnnotations = contextAnnotations;
158 _viewMatcher = null;
159
160 // 30-Jan-2012, tatu: Important: contextualize TypeDeserializer now...
161 if (typeDeser != null) {
162 typeDeser = typeDeser.forProperty(this);
163 }
164 _valueTypeDeserializer = typeDeser;
165 _valueDeserializer = MISSING_VALUE_DESERIALIZER;
166 _nullProvider = MISSING_VALUE_DESERIALIZER;
167 }
168
169 /**
170 * Constructor only used by {@link com.fasterxml.jackson.databind.deser.impl.ObjectIdValueProperty}.
171 *
172 * @since 2.3
173 */
174 protected SettableBeanProperty(PropertyName propName, JavaType type,
175 PropertyMetadata metadata, JsonDeserializer<Object> valueDeser)
176 {
177 super(metadata);
178 // as with above ctor, intern()ing probably fine
179 if (propName == null) {
180 _propName = PropertyName.NO_NAME;
181 } else {
182 _propName = propName.internSimpleName();
183 }
184 _type = type;
185 _wrapperName = null;
186 _contextAnnotations = null;
187 _viewMatcher = null;
188 _valueTypeDeserializer = null;
189 _valueDeserializer = valueDeser;
190 // 29-Jan-2017, tatu: Presumed to be irrelevant for ObjectId values...
191 _nullProvider = valueDeser;
192 }
193
194 /**
195 * Basic copy-constructor for sub-classes to use.
196 */
197 protected SettableBeanProperty(SettableBeanProperty src)
198 {
199 super(src);
200 _propName = src._propName;
201 _type = src._type;
202 _wrapperName = src._wrapperName;
203 _contextAnnotations = src._contextAnnotations;
204 _valueDeserializer = src._valueDeserializer;
205 _valueTypeDeserializer = src._valueTypeDeserializer;
206 _managedReferenceName = src._managedReferenceName;
207 _propertyIndex = src._propertyIndex;
208 _viewMatcher = src._viewMatcher;
209 _nullProvider = src._nullProvider;
210 }
211
212 /**
213 * Copy-with-deserializer-change constructor for sub-classes to use.
214 */
215 @SuppressWarnings("unchecked")
216 protected SettableBeanProperty(SettableBeanProperty src,
217 JsonDeserializer<?> deser, NullValueProvider nuller)
218 {
219 super(src);
220 _propName = src._propName;
221 _type = src._type;
222 _wrapperName = src._wrapperName;
223 _contextAnnotations = src._contextAnnotations;
224 _valueTypeDeserializer = src._valueTypeDeserializer;
225 _managedReferenceName = src._managedReferenceName;
226 _propertyIndex = src._propertyIndex;
227
228 if (deser == null) {
229 _valueDeserializer = MISSING_VALUE_DESERIALIZER;
230 } else {
231 _valueDeserializer = (JsonDeserializer<Object>) deser;
232 }
233 _viewMatcher = src._viewMatcher;
234 // 29-Jan-2017, tatu: Bit messy, but for now has to do...
235 if (nuller == MISSING_VALUE_DESERIALIZER) {
236 nuller = _valueDeserializer;
237 }
238 _nullProvider = nuller;
239 }
240
241 /**
242 * Copy-with-deserializer-change constructor for sub-classes to use.
243 */
244 protected SettableBeanProperty(SettableBeanProperty src, PropertyName newName)
245 {
246 super(src);
247 _propName = newName;
248 _type = src._type;
249 _wrapperName = src._wrapperName;
250 _contextAnnotations = src._contextAnnotations;
251 _valueDeserializer = src._valueDeserializer;
252 _valueTypeDeserializer = src._valueTypeDeserializer;
253 _managedReferenceName = src._managedReferenceName;
254 _propertyIndex = src._propertyIndex;
255 _viewMatcher = src._viewMatcher;
256 _nullProvider = src._nullProvider;
257 }
258
259 /**
260 * Fluent factory method for constructing and returning a new instance
261 * with specified value deserializer.
262 * Note that this method should NOT change configuration of this instance.
263 *
264 * @param deser Deserializer to assign to the new property instance
265 *
266 * @return Newly constructed instance, if value deserializer differs from the
267 * one used for this instance; or 'this' if not.
268 */
269 public abstract SettableBeanProperty withValueDeserializer(JsonDeserializer<?> deser);
270
271 /**
272 * Fluent factory method for constructing and returning a new instance
273 * with specified property name.
274 * Note that this method should NOT change configuration of this instance.
275 *
276 * @param newName Name to use for the new instance.
277 *
278 * @return Newly constructed instance, if property name differs from the
279 * one used for this instance; or 'this' if not.
280 */
281 public abstract SettableBeanProperty withName(PropertyName newName);
282
283 /**
284 * @since 2.3
285 */
286 public SettableBeanProperty withSimpleName(String simpleName) {
287 PropertyName n = (_propName == null)
288 ? new PropertyName(simpleName) : _propName.withSimpleName(simpleName);
289 return (n == _propName) ? this : withName(n);
290 }
291
292 /**
293 * @since 2.9
294 */
295 public abstract SettableBeanProperty withNullProvider(NullValueProvider nva);
296
297 public void setManagedReferenceName(String n) {
298 _managedReferenceName = n;
299 }
300
301 public void setObjectIdInfo(ObjectIdInfo objectIdInfo) {
302 _objectIdInfo = objectIdInfo;
303 }
304
305 public void setViews(Class<?>[] views) {
306 if (views == null) {
307 _viewMatcher = null;
308 } else {
309 _viewMatcher = ViewMatcher.construct(views);
310 }
311 }
312
313 /**
314 * Method used to assign index for property.
315 */
316 public void assignIndex(int index) {
317 if (_propertyIndex != -1) {
318 throw new IllegalStateException("Property '"+getName()+"' already had index ("+_propertyIndex+"), trying to assign "+index);
319 }
320 _propertyIndex = index;
321 }
322
323 /**
324 * Method called to ensure that the mutator has proper access rights to
325 * be called, as per configuration. Overridden by implementations that
326 * have mutators that require access, fields and setters.
327 *
328 * @since 2.8.3
329 */
330 public void fixAccess(DeserializationConfig config) {
331 ;
332 }
333
334 /**
335 * @since 2.9.4
336 */
337 public void markAsIgnorable() { }
338
339 /**
340 * @since 2.9.4
341 */
342 public boolean isIgnorable() { return false; }
343
344 /*
345 /**********************************************************
346 /* BeanProperty impl
347 /**********************************************************
348 */
349
350 @Override
351 public final String getName() {
352 return _propName.getSimpleName();
353 }
354
355 @Override
356 public PropertyName getFullName() {
357 return _propName;
358 }
359
360 @Override
361 public JavaType getType() { return _type; }
362
363 @Override
364 public PropertyName getWrapperName() {
365 return _wrapperName;
366 }
367
368 @Override
369 public abstract AnnotatedMember getMember();
370
371 @Override
372 public abstract <A extends Annotation> A getAnnotation(Class<A> acls);
373
374 @Override
375 public <A extends Annotation> A getContextAnnotation(Class<A> acls) {
376 return _contextAnnotations.get(acls);
377 }
378
379 @Override
380 public void depositSchemaProperty(JsonObjectFormatVisitor objectVisitor,
381 SerializerProvider provider)
382 throws JsonMappingException
383 {
384 if (isRequired()) {
385 objectVisitor.property(this);
386 } else {
387 objectVisitor.optionalProperty(this);
388 }
389 }
390
391 /*
392 /**********************************************************
393 /* Accessors
394 /**********************************************************
395 */
396
397 protected Class<?> getDeclaringClass() {
398 return getMember().getDeclaringClass();
399 }
400
401 public String getManagedReferenceName() { return _managedReferenceName; }
402
403 public ObjectIdInfo getObjectIdInfo() { return _objectIdInfo; }
404
405 public boolean hasValueDeserializer() {
406 return (_valueDeserializer != null) && (_valueDeserializer != MISSING_VALUE_DESERIALIZER);
407 }
408
409 public boolean hasValueTypeDeserializer() { return (_valueTypeDeserializer != null); }
410
411 public JsonDeserializer<Object> getValueDeserializer() {
412 JsonDeserializer<Object> deser = _valueDeserializer;
413 if (deser == MISSING_VALUE_DESERIALIZER) {
414 return null;
415 }
416 return deser;
417 }
418
419 public TypeDeserializer getValueTypeDeserializer() { return _valueTypeDeserializer; }
420
421 /**
422 * @since 2.9
423 */
424 public NullValueProvider getNullValueProvider() { return _nullProvider; }
425
426 public boolean visibleInView(Class<?> activeView) {
427 return (_viewMatcher == null) || _viewMatcher.isVisibleForView(activeView);
428 }
429
430 public boolean hasViews() { return _viewMatcher != null; }
431
432 /**
433 * Method for accessing unique index of this property; indexes are
434 * assigned once all properties of a {@link BeanDeserializer} have
435 * been collected.
436 *
437 * @return Index of this property
438 */
439 public int getPropertyIndex() { return _propertyIndex; }
440
441 /**
442 * Method for accessing index of the creator property: for other
443 * types of properties will simply return -1.
444 *
445 * @since 2.1
446 */
447 public int getCreatorIndex() {
448 // changed from 'return -1' in 2.7.9 / 2.8.7
449 throw new IllegalStateException(String.format(
450 "Internal error: no creator index for property '%s' (of type %s)",
451 this.getName(), getClass().getName()));
452 }
453
454 /**
455 * Accessor for id of injectable value, if this bean property supports
456 * value injection.
457 */
458 public Object getInjectableValueId() { return null; }
459
460 /**
461 * Accessor for checking whether this property is injectable, and if so,
462 * ONLY injectable (will not bind from input).
463 * Currently (2.11) can only return {@code true} for Creator-backed properties.
464 *
465 * @return True if (and only if) property has injector that is also defined NOT
466 * to bind from input.
467 *
468 * @since 2.11
469 */
470 public boolean isInjectionOnly() { return false; } // overridden by CreatorProperty
471
472 /*
473 /**********************************************************
474 /* Public API
475 /**********************************************************
476 */
477
478 /**
479 * Method called to deserialize appropriate value, given parser (and
480 * context), and set it using appropriate mechanism.
481 * Pre-condition is that passed parser must point to the first token
482 * that should be consumed to produce the value (the only value for
483 * scalars, multiple for Objects and Arrays).
484 */
485 public abstract void deserializeAndSet(JsonParser p,
486 DeserializationContext ctxt, Object instance) throws IOException;
487
488 /**
489 * Alternative to {@link #deserializeAndSet} that returns
490 * either return value of setter method called (if one is),
491 * or null to indicate that no return value is available.
492 * Mostly used to support Builder style deserialization.
493 *
494 * @since 2.0
495 */
496 public abstract Object deserializeSetAndReturn(JsonParser p,
497 DeserializationContext ctxt, Object instance) throws IOException;
498
499 /**
500 * Method called to assign given value to this property, on
501 * specified Object.
502 *<p>
503 * Note: this is an optional operation, not supported by all
504 * implementations, creator-backed properties for example do not
505 * support this method.
506 */
507 public abstract void set(Object instance, Object value) throws IOException;
508
509 /**
510 * Method called to assign given value to this property, on
511 * specified Object, and return whatever delegating accessor
512 * returned (if anything)
513 *<p>
514 * Note: this is an optional operation, not supported by all
515 * implementations, creator-backed properties for example do not
516 * support this method.
517 */
518 public abstract Object setAndReturn(Object instance, Object value) throws IOException;
519
520 /**
521 * This method is needed by some specialized bean deserializers,
522 * and also called by some {@link #deserializeAndSet} implementations.
523 *<p>
524 * Pre-condition is that passed parser must point to the first token
525 * that should be consumed to produce the value (the only value for
526 * scalars, multiple for Objects and Arrays).
527 *<p>
528 * Note that this method is final for performance reasons: to override
529 * functionality you must override other methods that call this method;
530 * this method should also not be called directly unless you really know
531 * what you are doing (and probably not even then).
532 */
533 public final Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
534 {
535 if (p.hasToken(JsonToken.VALUE_NULL)) {
536 return _nullProvider.getNullValue(ctxt);
537 }
538 if (_valueTypeDeserializer != null) {
539 return _valueDeserializer.deserializeWithType(p, ctxt, _valueTypeDeserializer);
540 }
541 // 04-May-2018, tatu: [databind#2023] Coercion from String (mostly) can give null
542 Object value = _valueDeserializer.deserialize(p, ctxt);
543 if (value == null) {
544 value = _nullProvider.getNullValue(ctxt);
545 }
546 return value;
547 }
548
549 /**
550 * @since 2.9
551 */
552 public final Object deserializeWith(JsonParser p, DeserializationContext ctxt,
553 Object toUpdate) throws IOException
554 {
555 // 20-Oct-2016, tatu: Not 100% sure what to do; probably best to simply return
556 // null value and let caller decide what to do.
557 if (p.hasToken(JsonToken.VALUE_NULL)) {
558 // ... except for "skip nulls" case which should just do that:
559 if (NullsConstantProvider.isSkipper(_nullProvider)) {
560 return toUpdate;
561 }
562 return _nullProvider.getNullValue(ctxt);
563 }
564 // 20-Oct-2016, tatu: Also tricky -- for now, report an error
565 if (_valueTypeDeserializer != null) {
566 ctxt.reportBadDefinition(getType(),
567 String.format("Cannot merge polymorphic property '%s'",
568 getName()));
569 // return _valueDeserializer.deserializeWithType(p, ctxt, _valueTypeDeserializer);
570 }
571 // 04-May-2018, tatu: [databind#2023] Coercion from String (mostly) can give null
572 Object value = _valueDeserializer.deserialize(p, ctxt, toUpdate);
573 if (value == null) {
574 if (NullsConstantProvider.isSkipper(_nullProvider)) {
575 return toUpdate;
576 }
577 value = _nullProvider.getNullValue(ctxt);
578 }
579 return value;
580 }
581
582 /*
583 /**********************************************************
584 /* Helper methods
585 /**********************************************************
586 */
587
588 /**
589 * Method that takes in exception of any type, and casts or wraps it
590 * to an IOException or its subclass.
591 */
592 protected void _throwAsIOE(JsonParser p, Exception e, Object value) throws IOException
593 {
594 if (e instanceof IllegalArgumentException) {
595 String actType = ClassUtil.classNameOf(value);
596 StringBuilder msg = new StringBuilder("Problem deserializing property '")
597 .append(getName())
598 .append("' (expected type: ")
599 .append(getType())
600 .append("; actual type: ")
601 .append(actType).append(")");
602 String origMsg = ClassUtil.exceptionMessage(e);
603 if (origMsg != null) {
604 msg.append(", problem: ")
605 .append(origMsg);
606 } else {
607 msg.append(" (no error message provided)");
608 }
609 throw JsonMappingException.from(p, msg.toString(), e);
610 }
611 _throwAsIOE(p, e);
612 }
613
614 /**
615 * @since 2.7
616 */
617 protected IOException _throwAsIOE(JsonParser p, Exception e) throws IOException
618 {
619 ClassUtil.throwIfIOE(e);
620 ClassUtil.throwIfRTE(e);
621 // let's wrap the innermost problem
622 Throwable th = ClassUtil.getRootCause(e);
623 throw JsonMappingException.from(p, ClassUtil.exceptionMessage(th), th);
624 }
625
626 @Deprecated // since 2.7
627 protected IOException _throwAsIOE(Exception e) throws IOException {
628 return _throwAsIOE((JsonParser) null, e);
629 }
630
631 // 10-Oct-2015, tatu: _Should_ be deprecated, too, but its remaining
632 // callers cannot actually provide a JsonParser
633 protected void _throwAsIOE(Exception e, Object value) throws IOException {
634 _throwAsIOE((JsonParser) null, e, value);
635 }
636
637 @Override public String toString() { return "[property '"+getName()+"']"; }
638
639 /*
640 /**********************************************************
641 /* Helper classes
642 /**********************************************************
643 */
644
645 /**
646 * Helper class that is designed to both make it easier to sub-class
647 * delegating subtypes and to reduce likelihood of breakage when
648 * new methods are added.
649 *<p>
650 * Class was specifically added to help with {@code Afterburner}
651 * module, but its use is not limited to only support it.
652 *
653 * @since 2.9
654 */
655 public static abstract class Delegating
656 extends SettableBeanProperty
657 {
658 protected final SettableBeanProperty delegate;
659
660 protected Delegating(SettableBeanProperty d) {
661 super(d);
662 delegate = d;
663 }
664
665 /**
666 * Method sub-classes must implement, to construct a new instance
667 * with given delegate.
668 */
669 protected abstract SettableBeanProperty withDelegate(SettableBeanProperty d);
670
671 protected SettableBeanProperty _with(SettableBeanProperty newDelegate) {
672 if (newDelegate == delegate) {
673 return this;
674 }
675 return withDelegate(newDelegate);
676 }
677
678 @Override
679 public SettableBeanProperty withValueDeserializer(JsonDeserializer<?> deser) {
680 return _with(delegate.withValueDeserializer(deser));
681 }
682
683 @Override
684 public SettableBeanProperty withName(PropertyName newName) {
685 return _with(delegate.withName(newName));
686 }
687
688 @Override
689 public SettableBeanProperty withNullProvider(NullValueProvider nva) {
690 return _with(delegate.withNullProvider(nva));
691 }
692
693 @Override
694 public void assignIndex(int index) {
695 delegate.assignIndex(index);
696 }
697
698 @Override
699 public void fixAccess(DeserializationConfig config) {
700 delegate.fixAccess(config);
701 }
702
703 /*
704 /**********************************************************
705 /* Accessors
706 /**********************************************************
707 */
708
709 @Override
710 protected Class<?> getDeclaringClass() { return delegate.getDeclaringClass(); }
711
712 @Override
713 public String getManagedReferenceName() { return delegate.getManagedReferenceName(); }
714
715 @Override
716 public ObjectIdInfo getObjectIdInfo() { return delegate.getObjectIdInfo(); }
717
718 @Override
719 public boolean hasValueDeserializer() { return delegate.hasValueDeserializer(); }
720
721 @Override
722 public boolean hasValueTypeDeserializer() { return delegate.hasValueTypeDeserializer(); }
723
724 @Override
725 public JsonDeserializer<Object> getValueDeserializer() { return delegate.getValueDeserializer(); }
726
727 @Override
728 public TypeDeserializer getValueTypeDeserializer() { return delegate.getValueTypeDeserializer(); }
729
730 @Override
731 public boolean visibleInView(Class<?> activeView) { return delegate.visibleInView(activeView); }
732
733 @Override
734 public boolean hasViews() { return delegate.hasViews(); }
735
736 @Override
737 public int getPropertyIndex() { return delegate.getPropertyIndex(); }
738
739 @Override
740 public int getCreatorIndex() { return delegate.getCreatorIndex(); }
741
742 @Override
743 public Object getInjectableValueId() { return delegate.getInjectableValueId(); }
744
745 @Override
746 public boolean isInjectionOnly() { return delegate.isInjectionOnly(); }
747
748 @Override
749 public AnnotatedMember getMember() {
750 return delegate.getMember();
751 }
752
753 @Override
754 public <A extends Annotation> A getAnnotation(Class<A> acls) {
755 return delegate.getAnnotation(acls);
756 }
757
758 /*
759 /**********************************************************
760 /* Extended API
761 /**********************************************************
762 */
763
764 public SettableBeanProperty getDelegate() {
765 return delegate;
766 }
767
768 /*
769 /**********************************************************
770 /* Actual mutators
771 /**********************************************************
772 */
773
774 @Override
775 public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
776 Object instance) throws IOException {
777 delegate.deserializeAndSet(p, ctxt, instance);
778 }
779
780 @Override
781 public Object deserializeSetAndReturn(JsonParser p,
782 DeserializationContext ctxt, Object instance) throws IOException
783 {
784 return delegate.deserializeSetAndReturn(p, ctxt, instance);
785 }
786
787 @Override
788 public void set(Object instance, Object value) throws IOException {
789 delegate.set(instance, value);
790 }
791
792 @Override
793 public Object setAndReturn(Object instance, Object value) throws IOException {
794 return delegate.setAndReturn(instance, value);
795 }
796 }
797 }
798