• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind;
2 
3 import java.io.IOException;
4 import java.text.DateFormat;
5 import java.text.ParseException;
6 import java.util.*;
7 import java.util.concurrent.atomic.AtomicReference;
8 
9 import com.fasterxml.jackson.annotation.JsonFormat;
10 import com.fasterxml.jackson.annotation.ObjectIdGenerator;
11 import com.fasterxml.jackson.annotation.ObjectIdResolver;
12 
13 import com.fasterxml.jackson.core.*;
14 import com.fasterxml.jackson.core.util.JacksonFeatureSet;
15 import com.fasterxml.jackson.databind.cfg.CoercionAction;
16 import com.fasterxml.jackson.databind.cfg.CoercionInputShape;
17 import com.fasterxml.jackson.databind.cfg.ContextAttributes;
18 import com.fasterxml.jackson.databind.deser.*;
19 import com.fasterxml.jackson.databind.deser.impl.ObjectIdReader;
20 import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId;
21 import com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer;
22 import com.fasterxml.jackson.databind.exc.MismatchedInputException;
23 import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
24 import com.fasterxml.jackson.databind.exc.InvalidFormatException;
25 import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
26 import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
27 import com.fasterxml.jackson.databind.exc.ValueInstantiationException;
28 import com.fasterxml.jackson.databind.introspect.Annotated;
29 import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
30 import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
31 import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
32 import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
33 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
34 import com.fasterxml.jackson.databind.type.LogicalType;
35 import com.fasterxml.jackson.databind.type.TypeFactory;
36 import com.fasterxml.jackson.databind.util.*;
37 
38 /**
39  * Context for the process of deserialization a single root-level value.
40  * Used to allow passing in configuration settings and reusable temporary
41  * objects (scrap arrays, containers).
42  *<p>
43  * Instance life-cycle is such that a partially configured "blueprint" object
44  * is registered with {@link ObjectMapper} (and {@link ObjectReader},
45  * and when actual instance is needed for deserialization,
46  * a fully configured instance will be created using a method in extended internal
47  *  API of sub-class
48  * ({@link com.fasterxml.jackson.databind.deser.DefaultDeserializationContext#createInstance}).
49  * Each instance is guaranteed to only be used from single-threaded context;
50  * instances may be reused if (and only if) no configuration has changed.
51  *<p>
52  * Defined as abstract class so that implementations must define methods
53  * for reconfiguring blueprints and creating instances.
54  */
55 public abstract class DeserializationContext
56     extends DatabindContext
57     implements java.io.Serializable
58 {
59     private static final long serialVersionUID = 1L; // 2.6
60 
61     /*
62     /**********************************************************
63     /* Configuration, immutable
64     /**********************************************************
65      */
66 
67     /**
68      * Object that handle details of {@link JsonDeserializer} caching.
69      */
70     protected final DeserializerCache _cache;
71 
72     /*
73     /**********************************************************
74     /* Configuration, changeable via fluent factories
75     /**********************************************************
76      */
77 
78     /**
79      * Read-only factory instance; exposed to let
80      * owners (<code>ObjectMapper</code>, <code>ObjectReader</code>)
81      * access it.
82      */
83     protected final DeserializerFactory _factory;
84 
85     /*
86     /**********************************************************
87     /* Configuration that gets set for instances (not blueprints)
88     /* (partly denormalized for performance)
89     /**********************************************************
90      */
91 
92     /**
93      * Generic deserialization processing configuration
94      */
95     protected final DeserializationConfig _config;
96 
97     /**
98      * Bitmap of {@link DeserializationFeature}s that are enabled
99      */
100     protected final int _featureFlags;
101 
102     /**
103      * Capabilities of the input format.
104      *
105      * @since 2.12
106      */
107     protected final JacksonFeatureSet<StreamReadCapability> _readCapabilities;
108 
109     /**
110      * Currently active view, if any.
111      */
112     protected final Class<?> _view;
113 
114     /**
115      * Currently active parser used for deserialization.
116      * May be different from the outermost parser
117      * when content is buffered.
118      */
119     protected transient JsonParser _parser;
120 
121     /**
122      * Object used for resolving references to injectable
123      * values.
124      */
125     protected final InjectableValues _injectableValues;
126 
127     /*
128     /**********************************************************
129     /* Per-operation reusable helper objects (not for blueprints)
130     /**********************************************************
131      */
132 
133     protected transient ArrayBuilders _arrayBuilders;
134 
135     protected transient ObjectBuffer _objectBuffer;
136 
137     protected transient DateFormat _dateFormat;
138 
139     /**
140      * Lazily-constructed holder for per-call attributes.
141      *
142      * @since 2.3
143      */
144     protected transient ContextAttributes _attributes;
145 
146     /**
147      * Type of {@link JsonDeserializer} (or, more specifically,
148      *   {@link ContextualDeserializer}) that is being
149      *   contextualized currently.
150      *
151      * @since 2.5
152      */
153     protected LinkedNode<JavaType> _currentType;
154 
155     /*
156     /**********************************************************
157     /* Life-cycle
158     /**********************************************************
159      */
160 
DeserializationContext(DeserializerFactory df)161     protected DeserializationContext(DeserializerFactory df) {
162         this(df, null);
163     }
164 
DeserializationContext(DeserializerFactory df, DeserializerCache cache)165     protected DeserializationContext(DeserializerFactory df,
166             DeserializerCache cache)
167     {
168         if (df == null) {
169             throw new NullPointerException("Cannot pass null DeserializerFactory");
170         }
171         _factory = df;
172         if (cache == null) {
173             cache = new DeserializerCache();
174         }
175         _cache = cache;
176         _featureFlags = 0;
177         _readCapabilities = null;
178         _config = null;
179         _injectableValues = null;
180         _view = null;
181         _attributes = null;
182     }
183 
DeserializationContext(DeserializationContext src, DeserializerFactory factory)184     protected DeserializationContext(DeserializationContext src,
185             DeserializerFactory factory)
186     {
187         _cache = src._cache;
188         _factory = factory;
189 
190         _config = src._config;
191         _featureFlags = src._featureFlags;
192         _readCapabilities = src._readCapabilities;
193         _view = src._view;
194         _parser = src._parser;
195         _injectableValues = src._injectableValues;
196         _attributes = src._attributes;
197     }
198 
199     /**
200      * Constructor used for creating actual per-call instances.
201      */
DeserializationContext(DeserializationContext src, DeserializationConfig config, JsonParser p, InjectableValues injectableValues)202     protected DeserializationContext(DeserializationContext src,
203             DeserializationConfig config, JsonParser p,
204             InjectableValues injectableValues)
205     {
206         _cache = src._cache;
207         _factory = src._factory;
208         // 08-Jun-2020. tatu: Called only for `ObjectMapper.canDeserialize()`
209         //    (see [databind#2749]), not sure what's the best work-around but
210         //    start with this:
211         _readCapabilities = (p == null) ? null : p.getReadCapabilities();
212 
213         _config = config;
214         _featureFlags = config.getDeserializationFeatures();
215         _view = config.getActiveView();
216         _parser = p;
217         _injectableValues = injectableValues;
218         _attributes = config.getAttributes();
219     }
220 
221     /**
222      * Constructor used for creating bogus per-call style instance, but
223      * without underlying parser: needed for deserializer pre-fetching
224      *
225      * @since 2.12
226      */
DeserializationContext(DeserializationContext src, DeserializationConfig config)227     protected DeserializationContext(DeserializationContext src,
228             DeserializationConfig config)
229     {
230         _cache = src._cache;
231         _factory = src._factory;
232         _readCapabilities = null;
233 
234         _config = config;
235         _featureFlags = config.getDeserializationFeatures();
236         _view = null;
237         _parser = null;
238         _injectableValues = null;
239         _attributes = null;
240     }
241 
242     /**
243      * Copy-constructor for use with <code>copy()</code> by {@link ObjectMapper#copy()}
244      */
DeserializationContext(DeserializationContext src)245     protected DeserializationContext(DeserializationContext src) {
246         _cache = new DeserializerCache();
247         _factory = src._factory;
248 
249         _config = src._config;
250         _featureFlags = src._featureFlags;
251         _readCapabilities = src._readCapabilities;
252         _view = src._view;
253         _injectableValues = null;
254     }
255 
256     /*
257     /**********************************************************
258     /* DatabindContext implementation
259     /**********************************************************
260      */
261 
262     @Override
getConfig()263     public DeserializationConfig getConfig() { return _config; }
264 
265     @Override
getActiveView()266     public final Class<?> getActiveView() { return _view; }
267 
268     @Override
canOverrideAccessModifiers()269     public final boolean canOverrideAccessModifiers() {
270         return _config.canOverrideAccessModifiers();
271     }
272 
273     @Override
isEnabled(MapperFeature feature)274     public final boolean isEnabled(MapperFeature feature) {
275         return _config.isEnabled(feature);
276     }
277 
278     @Override
getDefaultPropertyFormat(Class<?> baseType)279     public final JsonFormat.Value getDefaultPropertyFormat(Class<?> baseType) {
280         return _config.getDefaultPropertyFormat(baseType);
281     }
282 
283     @Override
getAnnotationIntrospector()284     public final AnnotationIntrospector getAnnotationIntrospector() {
285         return _config.getAnnotationIntrospector();
286     }
287 
288     @Override
getTypeFactory()289     public final TypeFactory getTypeFactory() {
290         return _config.getTypeFactory();
291     }
292 
293     @Override // since 2.11
constructSpecializedType(JavaType baseType, Class<?> subclass)294     public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass)
295         throws IllegalArgumentException
296     {
297         if (baseType.hasRawClass(subclass)) {
298             return baseType;
299         }
300         // On deserialization side, still uses "strict" type-compatibility checking;
301         // see [databind#2632] about serialization side
302         return getConfig().getTypeFactory().constructSpecializedType(baseType, subclass, false);
303     }
304 
305     /**
306      * Method for accessing default Locale to use: convenience method for
307      *<pre>
308      *   getConfig().getLocale();
309      *</pre>
310      */
311     @Override
getLocale()312     public Locale getLocale() {
313         return _config.getLocale();
314     }
315 
316     /**
317      * Method for accessing default TimeZone to use: convenience method for
318      *<pre>
319      *   getConfig().getTimeZone();
320      *</pre>
321      */
322     @Override
getTimeZone()323     public TimeZone getTimeZone() {
324         return _config.getTimeZone();
325     }
326 
327     /*
328     /**********************************************************
329     /* Access to per-call state, like generic attributes (2.3+)
330     /**********************************************************
331      */
332 
333     @Override
getAttribute(Object key)334     public Object getAttribute(Object key) {
335         return _attributes.getAttribute(key);
336     }
337 
338     @Override
setAttribute(Object key, Object value)339     public DeserializationContext setAttribute(Object key, Object value)
340     {
341         _attributes = _attributes.withPerCallAttribute(key, value);
342         return this;
343     }
344 
345     /**
346      * Accessor to {@link JavaType} of currently contextualized
347      * {@link ContextualDeserializer}, if any.
348      * This is sometimes useful for generic {@link JsonDeserializer}s that
349      * do not get passed (or do not retain) type information when being
350      * constructed: happens for example for deserializers constructed
351      * from annotations.
352      *
353      * @since 2.5
354      *
355      * @return Type of {@link ContextualDeserializer} being contextualized,
356      *   if process is on-going; null if not.
357      */
getContextualType()358     public JavaType getContextualType() {
359         return (_currentType == null) ? null : _currentType.value();
360     }
361 
362     /*
363     /**********************************************************
364     /* Public API, config accessors
365     /**********************************************************
366      */
367 
368     /**
369      * Method for getting current {@link DeserializerFactory}.
370      */
getFactory()371     public DeserializerFactory getFactory() {
372         return _factory;
373     }
374 
375     /**
376      * Convenience method for checking whether specified on/off
377      * feature is enabled
378      */
isEnabled(DeserializationFeature feat)379     public final boolean isEnabled(DeserializationFeature feat) {
380         /* 03-Dec-2010, tatu: minor shortcut; since this is called quite often,
381          *   let's use a local copy of feature settings:
382          */
383         return (_featureFlags & feat.getMask()) != 0;
384     }
385 
386     /**
387      * Accessor for checking whether input format has specified capability
388      * or not.
389      *
390      * @return True if input format has specified capability; false if not
391      *
392      * @since 2.12
393      */
isEnabled(StreamReadCapability cap)394     public final boolean isEnabled(StreamReadCapability cap) {
395         return _readCapabilities.isEnabled(cap);
396     }
397 
398     /**
399      * Bulk access method for getting the bit mask of all {@link DeserializationFeature}s
400      * that are enabled.
401      *
402      * @since 2.6
403      */
getDeserializationFeatures()404     public final int getDeserializationFeatures() {
405         return _featureFlags;
406     }
407 
408     /**
409      * Bulk access method for checking that all features specified by
410      * mask are enabled.
411      *
412      * @since 2.3
413      */
hasDeserializationFeatures(int featureMask)414     public final boolean hasDeserializationFeatures(int featureMask) {
415         return (_featureFlags & featureMask) == featureMask;
416     }
417 
418     /**
419      * Bulk access method for checking that at least one of features specified by
420      * mask is enabled.
421      *
422      * @since 2.6
423      */
hasSomeOfFeatures(int featureMask)424     public final boolean hasSomeOfFeatures(int featureMask) {
425         return (_featureFlags & featureMask) != 0;
426     }
427 
428     /**
429      * Method for accessing the currently active parser.
430      * May be different from the outermost parser
431      * when content is buffered.
432      *<p>
433      * Use of this method is discouraged: if code has direct access
434      * to the active parser, that should be used instead.
435      */
getParser()436     public final JsonParser getParser() { return _parser; }
437 
findInjectableValue(Object valueId, BeanProperty forProperty, Object beanInstance)438     public final Object findInjectableValue(Object valueId,
439             BeanProperty forProperty, Object beanInstance)
440         throws JsonMappingException
441     {
442         if (_injectableValues == null) {
443             reportBadDefinition(ClassUtil.classOf(valueId), String.format(
444 "No 'injectableValues' configured, cannot inject value with id [%s]", valueId));
445         }
446         return _injectableValues.findInjectableValue(valueId, this, forProperty, beanInstance);
447     }
448 
449     /**
450      * Convenience method for accessing the default Base64 encoding
451      * used for decoding base64 encoded binary content.
452      * Same as calling:
453      *<pre>
454      *  getConfig().getBase64Variant();
455      *</pre>
456      */
getBase64Variant()457     public final Base64Variant getBase64Variant() {
458         return _config.getBase64Variant();
459     }
460 
461     /**
462      * Convenience method, functionally equivalent to:
463      *<pre>
464      *  getConfig().getNodeFactory();
465      * </pre>
466      */
getNodeFactory()467     public final JsonNodeFactory getNodeFactory() {
468         return _config.getNodeFactory();
469     }
470 
471     /*
472     /**********************************************************************
473     /* Public API, CoercionConfig access (2.12+)
474     /**********************************************************************
475      */
476 
477     /**
478      * General-purpose accessor for finding what to do when specified coercion
479      * from shape that is now always allowed to be coerced from is requested.
480      *
481      * @param targetType Logical target type of coercion
482      * @param targetClass Physical target type of coercion
483      * @param inputShape Input shape to coerce from
484      *
485      * @return CoercionAction configured for specific coercion
486      *
487      * @since 2.12
488      */
findCoercionAction(LogicalType targetType, Class<?> targetClass, CoercionInputShape inputShape)489     public CoercionAction findCoercionAction(LogicalType targetType,
490             Class<?> targetClass, CoercionInputShape inputShape)
491     {
492         return _config.findCoercionAction(targetType, targetClass, inputShape);
493     }
494 
495     /**
496      * More specialized accessor called in case of input being a blank
497      * String (one consisting of only white space characters with length of at least one).
498      * Will basically first determine if "blank as empty" is allowed: if not,
499      * returns {@code actionIfBlankNotAllowed}, otherwise returns action for
500      * {@link CoercionInputShape#EmptyString}.
501      *
502      * @param targetType Logical target type of coercion
503      * @param targetClass Physical target type of coercion
504      * @param actionIfBlankNotAllowed Return value to use in case "blanks as empty"
505      *    is not allowed
506      *
507      * @return CoercionAction configured for specified coercion from blank string
508      *
509      * @since 2.12
510      */
findCoercionFromBlankString(LogicalType targetType, Class<?> targetClass, CoercionAction actionIfBlankNotAllowed)511     public CoercionAction findCoercionFromBlankString(LogicalType targetType,
512             Class<?> targetClass,
513             CoercionAction actionIfBlankNotAllowed)
514     {
515         return _config.findCoercionFromBlankString(targetType, targetClass, actionIfBlankNotAllowed);
516     }
517 
518     /*
519     /**********************************************************
520     /* Public API, pass-through to DeserializerCache
521     /**********************************************************
522      */
523 
524     /**
525      * Method for checking whether we could find a deserializer
526      * for given type.
527      *
528      * @param type Type to check
529      * @param cause (optional) Reference set to root cause if no deserializer
530      *    could be found due to exception (to find the reason for failure)
531      *
532      * @since 2.3
533      */
hasValueDeserializerFor(JavaType type, AtomicReference<Throwable> cause)534     public boolean hasValueDeserializerFor(JavaType type, AtomicReference<Throwable> cause) {
535         try {
536             return _cache.hasValueDeserializerFor(this, _factory, type);
537         } catch (JsonMappingException e) {
538             if (cause != null) {
539                 cause.set(e);
540             }
541         } catch (RuntimeException e) {
542             if (cause == null) { // earlier behavior
543                 throw e;
544             }
545             cause.set(e);
546         }
547         return false;
548     }
549 
550     /**
551      * Method for finding a value deserializer, and creating a contextual
552      * version if necessary, for value reached via specified property.
553      */
554     @SuppressWarnings("unchecked")
findContextualValueDeserializer(JavaType type, BeanProperty prop)555     public final JsonDeserializer<Object> findContextualValueDeserializer(JavaType type,
556             BeanProperty prop) throws JsonMappingException
557     {
558         JsonDeserializer<Object> deser = _cache.findValueDeserializer(this, _factory, type);
559         if (deser != null) {
560             deser = (JsonDeserializer<Object>) handleSecondaryContextualization(deser, prop, type);
561         }
562         return deser;
563     }
564 
565     /**
566      * Variant that will try to locate deserializer for current type, but without
567      * performing any contextualization (unlike {@link #findContextualValueDeserializer})
568      * or checking for need to create a {@link TypeDeserializer} (unlike
569      * {@link #findRootValueDeserializer(JavaType)}.
570      * This method is usually called from within {@link ResolvableDeserializer#resolve},
571      * and expectation is that caller then calls either
572      * {@link #handlePrimaryContextualization(JsonDeserializer, BeanProperty, JavaType)} or
573      * {@link #handleSecondaryContextualization(JsonDeserializer, BeanProperty, JavaType)} at a
574      * later point, as necessary.
575      *
576      * @since 2.5
577      */
findNonContextualValueDeserializer(JavaType type)578     public final JsonDeserializer<Object> findNonContextualValueDeserializer(JavaType type)
579         throws JsonMappingException
580     {
581         return _cache.findValueDeserializer(this, _factory, type);
582     }
583 
584     /**
585      * Method for finding a deserializer for root-level value.
586      */
587     @SuppressWarnings("unchecked")
findRootValueDeserializer(JavaType type)588     public final JsonDeserializer<Object> findRootValueDeserializer(JavaType type)
589         throws JsonMappingException
590     {
591         JsonDeserializer<Object> deser = _cache.findValueDeserializer(this,
592                 _factory, type);
593         if (deser == null) { // can this occur?
594             return null;
595         }
596         deser = (JsonDeserializer<Object>) handleSecondaryContextualization(deser, null, type);
597         TypeDeserializer typeDeser = _factory.findTypeDeserializer(_config, type);
598         if (typeDeser != null) {
599             // important: contextualize to indicate this is for root value
600             typeDeser = typeDeser.forProperty(null);
601             return new TypeWrappedDeserializer(typeDeser, deser);
602         }
603         return deser;
604     }
605 
606     /**
607      * Convenience method, functionally same as:
608      *<pre>
609      *  getDeserializerProvider().findKeyDeserializer(getConfig(), prop.getType(), prop);
610      *</pre>
611      */
findKeyDeserializer(JavaType keyType, BeanProperty prop)612     public final KeyDeserializer findKeyDeserializer(JavaType keyType,
613             BeanProperty prop) throws JsonMappingException {
614         KeyDeserializer kd = _cache.findKeyDeserializer(this,
615                 _factory, keyType);
616         // Second: contextualize?
617         if (kd instanceof ContextualKeyDeserializer) {
618             kd = ((ContextualKeyDeserializer) kd).createContextual(this, prop);
619         }
620         return kd;
621     }
622 
623     /*
624     /**********************************************************
625     /* Public API, ObjectId handling
626     /**********************************************************
627      */
628 
629     /**
630      * Method called to find and return entry corresponding to given
631      * Object Id: will add an entry if necessary, and never returns null
632      */
findObjectId(Object id, ObjectIdGenerator<?> generator, ObjectIdResolver resolver)633     public abstract ReadableObjectId findObjectId(Object id, ObjectIdGenerator<?> generator, ObjectIdResolver resolver);
634 
635     /**
636      * Method called to ensure that every object id encounter during processing
637      * are resolved.
638      *
639      * @throws UnresolvedForwardReference
640      */
checkUnresolvedObjectId()641     public abstract void checkUnresolvedObjectId()
642         throws UnresolvedForwardReference;
643 
644     /*
645     /**********************************************************
646     /* Public API, type handling
647     /**********************************************************
648      */
649 
650     /**
651      * Convenience method, functionally equivalent to:
652      *<pre>
653      *  getConfig().constructType(cls);
654      * </pre>
655      */
constructType(Class<?> cls)656     public final JavaType constructType(Class<?> cls) {
657         return (cls == null) ? null : _config.constructType(cls);
658     }
659 
660     /**
661      * Helper method that is to be used when resolving basic class name into
662      * Class instance, the reason being that it may be necessary to work around
663      * various ClassLoader limitations, as well as to handle primitive type
664      * signatures.
665      *
666      * @since 2.6
667      */
findClass(String className)668     public Class<?> findClass(String className) throws ClassNotFoundException
669     {
670         // By default, delegate to ClassUtil: can be overridden with custom handling
671         return getTypeFactory().findClass(className);
672     }
673 
674     /*
675     /**********************************************************
676     /* Public API, helper object recycling
677     /**********************************************************
678      */
679 
680     /**
681      * Method that can be used to get access to a reusable ObjectBuffer,
682      * useful for efficiently constructing Object arrays and Lists.
683      * Note that leased buffers should be returned once deserializer
684      * is done, to allow for reuse during same round of deserialization.
685      */
leaseObjectBuffer()686     public final ObjectBuffer leaseObjectBuffer()
687     {
688         ObjectBuffer buf = _objectBuffer;
689         if (buf == null) {
690             buf = new ObjectBuffer();
691         } else {
692             _objectBuffer = null;
693         }
694         return buf;
695     }
696 
697     /**
698      * Method to call to return object buffer previously leased with
699      * {@link #leaseObjectBuffer}.
700      *
701      * @param buf Returned object buffer
702      */
returnObjectBuffer(ObjectBuffer buf)703     public final void returnObjectBuffer(ObjectBuffer buf)
704     {
705         /* Already have a reusable buffer? Let's retain bigger one
706          * (or if equal, favor newer one, shorter life-cycle)
707          */
708         if (_objectBuffer == null
709             || buf.initialCapacity() >= _objectBuffer.initialCapacity()) {
710             _objectBuffer = buf;
711         }
712     }
713 
714     /**
715      * Method for accessing object useful for building arrays of
716      * primitive types (such as int[]).
717      */
getArrayBuilders()718     public final ArrayBuilders getArrayBuilders()
719     {
720         if (_arrayBuilders == null) {
721             _arrayBuilders = new ArrayBuilders();
722         }
723         return _arrayBuilders;
724     }
725 
726     /*
727     /**********************************************************
728     /* Extended API: handler instantiation
729     /**********************************************************
730      */
731 
deserializerInstance(Annotated annotated, Object deserDef)732     public abstract JsonDeserializer<Object> deserializerInstance(Annotated annotated,
733             Object deserDef)
734         throws JsonMappingException;
735 
keyDeserializerInstance(Annotated annotated, Object deserDef)736     public abstract KeyDeserializer keyDeserializerInstance(Annotated annotated,
737             Object deserDef)
738         throws JsonMappingException;
739 
740     /*
741     /**********************************************************
742     /* Extended API: resolving contextual deserializers; called
743     /* by structured deserializers for their value/component
744     /* deserializers
745     /**********************************************************
746      */
747 
748     /**
749      * Method called for primary property deserializers (ones
750      * directly created to deserialize values of a POJO property),
751      * to handle details of resolving
752      * {@link ContextualDeserializer} with given property context.
753      *
754      * @param prop Property for which the given primary deserializer is used; never null.
755      *
756      * @since 2.5
757      */
handlePrimaryContextualization(JsonDeserializer<?> deser, BeanProperty prop, JavaType type)758     public JsonDeserializer<?> handlePrimaryContextualization(JsonDeserializer<?> deser,
759             BeanProperty prop, JavaType type)
760         throws JsonMappingException
761     {
762         if (deser instanceof ContextualDeserializer) {
763             _currentType = new LinkedNode<JavaType>(type, _currentType);
764             try {
765                 deser = ((ContextualDeserializer) deser).createContextual(this, prop);
766             } finally {
767                 _currentType = _currentType.next();
768             }
769         }
770         return deser;
771     }
772 
773     /**
774      * Method called for secondary property deserializers (ones
775      * NOT directly created to deal with an annotatable POJO property,
776      * but instead created as a component -- such as value deserializers
777      * for structured types, or deserializers for root values)
778      * to handle details of resolving
779      * {@link ContextualDeserializer} with given property context.
780      * Given that these deserializers are not directly related to given property
781      * (or, in case of root value property, to any property), annotations
782      * accessible may or may not be relevant.
783      *
784      * @param prop Property for which deserializer is used, if any; null
785      *    when deserializing root values
786      *
787      * @since 2.5
788      */
handleSecondaryContextualization(JsonDeserializer<?> deser, BeanProperty prop, JavaType type)789     public JsonDeserializer<?> handleSecondaryContextualization(JsonDeserializer<?> deser,
790             BeanProperty prop, JavaType type)
791         throws JsonMappingException
792     {
793         if (deser instanceof ContextualDeserializer) {
794             _currentType = new LinkedNode<JavaType>(type, _currentType);
795             try {
796                 deser = ((ContextualDeserializer) deser).createContextual(this, prop);
797             } finally {
798                 _currentType = _currentType.next();
799             }
800         }
801         return deser;
802     }
803 
804     /*
805     /**********************************************************
806     /* Parsing methods that may use reusable/-cyclable objects
807     /**********************************************************
808      */
809 
810     /**
811      * Convenience method for parsing a Date from given String, using
812      * currently configured date format (accessed using
813      * {@link DeserializationConfig#getDateFormat()}).
814      *<p>
815      * Implementation will handle thread-safety issues related to
816      * date formats such that first time this method is called,
817      * date format is cloned, and cloned instance will be retained
818      * for use during this deserialization round.
819      */
parseDate(String dateStr)820     public Date parseDate(String dateStr) throws IllegalArgumentException
821     {
822         try {
823             DateFormat df = _getDateFormat();
824             return df.parse(dateStr);
825         } catch (ParseException e) {
826             throw new IllegalArgumentException(String.format(
827                     "Failed to parse Date value '%s': %s", dateStr,
828                     ClassUtil.exceptionMessage(e)));
829         }
830     }
831 
832     /**
833      * Convenience method for constructing Calendar instance set
834      * to specified time, to be modified and used by caller.
835      */
constructCalendar(Date d)836     public Calendar constructCalendar(Date d) {
837         // 08-Jan-2008, tatu: not optimal, but should work for the most part; let's revise as needed.
838         Calendar c = Calendar.getInstance(getTimeZone());
839         c.setTime(d);
840         return c;
841     }
842 
843     /*
844     /**********************************************************
845     /* Extension points for more esoteric data coercion (2.12)
846     /**********************************************************
847      */
848 
849     /**
850      * Method to call in case incoming shape is Object Value (and parser thereby
851      * points to {@link com.fasterxml.jackson.core.JsonToken#START_OBJECT} token),
852      * but a Scalar value (potentially coercible from String value) is expected.
853      * This would typically be used to deserializer a Number, Boolean value or some other
854      * "simple" unstructured value type.
855      *
856      * @param p Actual parser to read content from
857      * @param deser Deserializer that needs extracted String value
858      * @param scalarType Immediate type of scalar to extract; usually type deserializer
859      *    handles but not always (for example, deserializer for {@code int[]} would pass
860      *    scalar type of {@code int})
861      *
862      * @return String value found; not {@code null} (exception should be thrown if no suitable
863      *     value found)
864      *
865      * @throws IOException If there are problems either reading content (underlying parser
866      *    problem) or finding expected scalar value
867      */
extractScalarFromObject(JsonParser p, JsonDeserializer<?> deser, Class<?> scalarType)868     public String extractScalarFromObject(JsonParser p, JsonDeserializer<?> deser,
869             Class<?> scalarType)
870         throws IOException
871     {
872         return reportInputMismatch(scalarType, String.format(
873 "Cannot deserialize value of type %s from %s (token `JsonToken.START_OBJECT`)",
874 ClassUtil.getClassDescription(scalarType), _shapeForToken(JsonToken.START_OBJECT)));
875     }
876 
877     /*
878     /**********************************************************
879     /* Convenience methods for reading parsed values
880     /**********************************************************
881      */
882 
883     /**
884      * Convenience method that may be used by composite or container deserializers,
885      * for reading one-off values contained (for sequences, it is more efficient
886      * to actually fetch deserializer once for the whole collection).
887      *<p>
888      * NOTE: when deserializing values of properties contained in composite types,
889      * rather use {@link #readPropertyValue(JsonParser, BeanProperty, Class)};
890      * this method does not allow use of contextual annotations.
891      *
892      * @since 2.4
893      */
readValue(JsonParser p, Class<T> type)894     public <T> T readValue(JsonParser p, Class<T> type) throws IOException {
895         return readValue(p, getTypeFactory().constructType(type));
896     }
897 
898     /**
899      * @since 2.4
900      */
901     @SuppressWarnings("unchecked")
readValue(JsonParser p, JavaType type)902     public <T> T readValue(JsonParser p, JavaType type) throws IOException {
903         JsonDeserializer<Object> deser = findRootValueDeserializer(type);
904         if (deser == null) {
905             reportBadDefinition(type,
906                     "Could not find JsonDeserializer for type "+ClassUtil.getTypeDescription(type));
907         }
908         return (T) deser.deserialize(p, this);
909     }
910 
911     /**
912      * Convenience method that may be used by composite or container deserializers,
913      * for reading one-off values for the composite type, taking into account
914      * annotations that the property (passed to this method -- usually property that
915      * has custom serializer that called this method) has.
916      *
917      * @since 2.4
918      */
readPropertyValue(JsonParser p, BeanProperty prop, Class<T> type)919     public <T> T readPropertyValue(JsonParser p, BeanProperty prop, Class<T> type) throws IOException {
920         return readPropertyValue(p, prop, getTypeFactory().constructType(type));
921     }
922 
923     /**
924      * @since 2.4
925      */
926     @SuppressWarnings("unchecked")
readPropertyValue(JsonParser p, BeanProperty prop, JavaType type)927     public <T> T readPropertyValue(JsonParser p, BeanProperty prop, JavaType type) throws IOException {
928         JsonDeserializer<Object> deser = findContextualValueDeserializer(type, prop);
929         if (deser == null) {
930             return reportBadDefinition(type, String.format(
931                     "Could not find JsonDeserializer for type %s (via property %s)",
932                     ClassUtil.getTypeDescription(type), ClassUtil.nameOf(prop)));
933         }
934         return (T) deser.deserialize(p, this);
935     }
936 
937     /**
938      * @since 2.10
939      */
readTree(JsonParser p)940     public JsonNode readTree(JsonParser p) throws IOException {
941         JsonToken t = p.currentToken();
942         if (t == null) {
943             t = p.nextToken();
944             if (t == null) {
945                 return getNodeFactory().missingNode();
946             }
947         }
948         if (t == JsonToken.VALUE_NULL) {
949             return getNodeFactory().nullNode();
950         }
951         return (JsonNode) findRootValueDeserializer(_config.constructType(JsonNode.class))
952                 .deserialize(p, this);
953     }
954 
955     /*
956     /**********************************************************
957     /* Methods for problem handling
958     /**********************************************************
959      */
960 
961     /**
962      * Method that deserializers should call if they encounter an unrecognized
963      * property (and once that is not explicitly designed as ignorable), to
964      * inform possibly configured {@link DeserializationProblemHandler}s and
965      * let it handle the problem.
966      *
967      * @return True if there was a configured problem handler that was able to handle the
968      *   problem
969      */
handleUnknownProperty(JsonParser p, JsonDeserializer<?> deser, Object instanceOrClass, String propName)970     public boolean handleUnknownProperty(JsonParser p, JsonDeserializer<?> deser,
971             Object instanceOrClass, String propName)
972         throws IOException
973     {
974         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
975         while (h != null) {
976             // Can bail out if it's handled
977             if (h.value().handleUnknownProperty(this, p, deser, instanceOrClass, propName)) {
978                 return true;
979             }
980             h = h.next();
981         }
982         // Nope, not handled. Potentially that's a problem...
983         if (!isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) {
984             p.skipChildren();
985             return true;
986         }
987         // Do we know properties that are expected instead?
988         Collection<Object> propIds = (deser == null) ? null : deser.getKnownPropertyNames();
989         throw UnrecognizedPropertyException.from(_parser,
990                 instanceOrClass, propName, propIds);
991     }
992 
993     /**
994      * Method that deserializers should call if they encounter a String value
995      * that cannot be converted to expected key of a {@link java.util.Map}
996      * valued property.
997      * Default implementation will try to call {@link DeserializationProblemHandler#handleWeirdNumberValue}
998      * on configured handlers, if any, to allow for recovery; if recovery does not
999      * succeed, will throw {@link InvalidFormatException} with given message.
1000      *
1001      * @param keyClass Expected type for key
1002      * @param keyValue String value from which to deserialize key
1003      * @param msg Error message template caller wants to use if exception is to be thrown
1004      * @param msgArgs Optional arguments to use for message, if any
1005      *
1006      * @return Key value to use
1007      *
1008      * @throws IOException To indicate unrecoverable problem, usually based on <code>msg</code>
1009      *
1010      * @since 2.8
1011      */
handleWeirdKey(Class<?> keyClass, String keyValue, String msg, Object... msgArgs)1012     public Object handleWeirdKey(Class<?> keyClass, String keyValue,
1013             String msg, Object... msgArgs)
1014         throws IOException
1015     {
1016         // but if not handled, just throw exception
1017         msg = _format(msg, msgArgs);
1018         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1019         while (h != null) {
1020             // Can bail out if it's handled
1021             Object key = h.value().handleWeirdKey(this, keyClass, keyValue, msg);
1022             if (key != DeserializationProblemHandler.NOT_HANDLED) {
1023                 // Sanity check for broken handlers, otherwise nasty to debug:
1024                 if ((key == null) || keyClass.isInstance(key)) {
1025                     return key;
1026                 }
1027                 throw weirdStringException(keyValue, keyClass, String.format(
1028                         "DeserializationProblemHandler.handleWeirdStringValue() for type %s returned value of type %s",
1029                         ClassUtil.getClassDescription(keyClass),
1030                         ClassUtil.getClassDescription(key)
1031                 ));
1032             }
1033             h = h.next();
1034         }
1035         throw weirdKeyException(keyClass, keyValue, msg);
1036     }
1037 
1038     /**
1039      * Method that deserializers should call if they encounter a String value
1040      * that cannot be converted to target property type, in cases where some
1041      * String values could be acceptable (either with different settings,
1042      * or different value).
1043      * Default implementation will try to call {@link DeserializationProblemHandler#handleWeirdStringValue}
1044      * on configured handlers, if any, to allow for recovery; if recovery does not
1045      * succeed, will throw {@link InvalidFormatException} with given message.
1046      *
1047      * @param targetClass Type of property into which incoming number should be converted
1048      * @param value String value from which to deserialize property value
1049      * @param msg Error message template caller wants to use if exception is to be thrown
1050      * @param msgArgs Optional arguments to use for message, if any
1051      *
1052      * @return Property value to use
1053      *
1054      * @throws IOException To indicate unrecoverable problem, usually based on <code>msg</code>
1055      *
1056      * @since 2.8
1057      */
handleWeirdStringValue(Class<?> targetClass, String value, String msg, Object... msgArgs)1058     public Object handleWeirdStringValue(Class<?> targetClass, String value,
1059             String msg, Object... msgArgs)
1060         throws IOException
1061     {
1062         // but if not handled, just throw exception
1063         msg = _format(msg, msgArgs);
1064         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1065         while (h != null) {
1066             // Can bail out if it's handled
1067             Object instance = h.value().handleWeirdStringValue(this, targetClass, value, msg);
1068             if (instance != DeserializationProblemHandler.NOT_HANDLED) {
1069                 // Sanity check for broken handlers, otherwise nasty to debug:
1070                 if (_isCompatible(targetClass, instance)) {
1071                     return instance;
1072                 }
1073                 throw weirdStringException(value, targetClass, String.format(
1074                         "DeserializationProblemHandler.handleWeirdStringValue() for type %s returned value of type %s",
1075                         ClassUtil.getClassDescription(targetClass),
1076                         ClassUtil.getClassDescription(instance)
1077                 ));
1078             }
1079             h = h.next();
1080         }
1081         throw weirdStringException(value, targetClass, msg);
1082     }
1083 
1084     /**
1085      * Method that deserializers should call if they encounter a numeric value
1086      * that cannot be converted to target property type, in cases where some
1087      * numeric values could be acceptable (either with different settings,
1088      * or different numeric value).
1089      * Default implementation will try to call {@link DeserializationProblemHandler#handleWeirdNumberValue}
1090      * on configured handlers, if any, to allow for recovery; if recovery does not
1091      * succeed, will throw {@link InvalidFormatException} with given message.
1092      *
1093      * @param targetClass Type of property into which incoming number should be converted
1094      * @param value Number value from which to deserialize property value
1095      * @param msg Error message template caller wants to use if exception is to be thrown
1096      * @param msgArgs Optional arguments to use for message, if any
1097      *
1098      * @return Property value to use
1099      *
1100      * @throws IOException To indicate unrecoverable problem, usually based on <code>msg</code>
1101      *
1102      * @since 2.8
1103      */
handleWeirdNumberValue(Class<?> targetClass, Number value, String msg, Object... msgArgs)1104     public Object handleWeirdNumberValue(Class<?> targetClass, Number value,
1105             String msg, Object... msgArgs)
1106         throws IOException
1107     {
1108         msg = _format(msg, msgArgs);
1109         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1110         while (h != null) {
1111             // Can bail out if it's handled
1112             Object key = h.value().handleWeirdNumberValue(this, targetClass, value, msg);
1113             if (key != DeserializationProblemHandler.NOT_HANDLED) {
1114                 // Sanity check for broken handlers, otherwise nasty to debug:
1115                 if (_isCompatible(targetClass, key)) {
1116                     return key;
1117                 }
1118                 throw weirdNumberException(value, targetClass, _format(
1119                         "DeserializationProblemHandler.handleWeirdNumberValue() for type %s returned value of type %s",
1120                         ClassUtil.getClassDescription(targetClass),
1121                         ClassUtil.getClassDescription(key)
1122                 ));
1123             }
1124             h = h.next();
1125         }
1126         throw weirdNumberException(value, targetClass, msg);
1127     }
1128 
handleWeirdNativeValue(JavaType targetType, Object badValue, JsonParser p)1129     public Object handleWeirdNativeValue(JavaType targetType, Object badValue,
1130             JsonParser p)
1131         throws IOException
1132     {
1133         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1134         final Class<?> raw = targetType.getRawClass();
1135         for (; h != null; h = h.next()) {
1136             // Can bail out if it's handled
1137             Object goodValue = h.value().handleWeirdNativeValue(this, targetType, badValue, p);
1138             if (goodValue != DeserializationProblemHandler.NOT_HANDLED) {
1139                 // Sanity check for broken handlers, otherwise nasty to debug:
1140                 if ((goodValue == null) || raw.isInstance(goodValue)) {
1141                     return goodValue;
1142                 }
1143                 throw JsonMappingException.from(p, _format(
1144 "DeserializationProblemHandler.handleWeirdNativeValue() for type %s returned value of type %s",
1145                     ClassUtil.getClassDescription(targetType),
1146                     ClassUtil.getClassDescription(goodValue)
1147                 ));
1148             }
1149         }
1150         throw weirdNativeValueException(badValue, raw);
1151     }
1152 
1153     /**
1154      * Method that deserializers should call if they fail to instantiate value
1155      * due to lack of viable instantiator (usually creator, that is, constructor
1156      * or static factory method). Method should be called at point where value
1157      * has not been decoded, so that handler has a chance to handle decoding
1158      * using alternate mechanism, and handle underlying content (possibly by
1159      * just skipping it) to keep input state valid
1160      *
1161      * @param instClass Type that was to be instantiated
1162      * @param valueInst (optional) Value instantiator to be used, if any; null if type does not
1163      *    use one for instantiation (custom deserialiers don't; standard POJO deserializer does)
1164      * @param p Parser that points to the JSON value to decode
1165      *
1166      * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
1167      *
1168      * @since 2.9 (2.8 had alternate that did not take <code>ValueInstantiator</code>)
1169      */
1170     @SuppressWarnings("resource")
handleMissingInstantiator(Class<?> instClass, ValueInstantiator valueInst, JsonParser p, String msg, Object... msgArgs)1171     public Object handleMissingInstantiator(Class<?> instClass, ValueInstantiator valueInst,
1172             JsonParser p, String msg, Object... msgArgs)
1173         throws IOException
1174     {
1175         if (p == null) {
1176             p = getParser();
1177         }
1178         msg = _format(msg, msgArgs);
1179         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1180         while (h != null) {
1181             // Can bail out if it's handled
1182             Object instance = h.value().handleMissingInstantiator(this,
1183                     instClass, valueInst, p, msg);
1184             if (instance != DeserializationProblemHandler.NOT_HANDLED) {
1185                 // Sanity check for broken handlers, otherwise nasty to debug:
1186                 if (_isCompatible(instClass, instance)) {
1187                     return instance;
1188                 }
1189                 reportBadDefinition(constructType(instClass), String.format(
1190 "DeserializationProblemHandler.handleMissingInstantiator() for type %s returned value of type %s",
1191                     ClassUtil.getClassDescription(instClass),
1192                     ClassUtil.getClassDescription((instance)
1193                 )));
1194             }
1195             h = h.next();
1196         }
1197 
1198         // 16-Oct-2016, tatu: This is either a definition problem (if no applicable creator
1199         //   exists), or input mismatch problem (otherwise) since none of existing creators
1200         //   match with token.
1201         // 24-Oct-2019, tatu: Further, as per [databind#2522], passing `null` ValueInstantiator
1202         //   should simply trigger definition problem
1203         if (valueInst == null ) {
1204             msg = String.format("Cannot construct instance of %s: %s",
1205                     ClassUtil.nameOf(instClass), msg);
1206             return reportBadDefinition(instClass, msg);
1207         }
1208         if (!valueInst.canInstantiate()) {
1209             msg = String.format("Cannot construct instance of %s (no Creators, like default constructor, exist): %s",
1210                     ClassUtil.nameOf(instClass), msg);
1211             return reportBadDefinition(instClass, msg);
1212         }
1213         msg = String.format("Cannot construct instance of %s (although at least one Creator exists): %s",
1214                 ClassUtil.nameOf(instClass), msg);
1215         return reportInputMismatch(instClass, msg);
1216     }
1217 
1218     /**
1219      * Method that deserializers should call if they fail to instantiate value
1220      * due to an exception that was thrown by constructor (or other mechanism used
1221      * to create instances).
1222      * Default implementation will try to call {@link DeserializationProblemHandler#handleInstantiationProblem}
1223      * on configured handlers, if any, to allow for recovery; if recovery does not
1224      * succeed, will throw exception constructed with {@link #instantiationException}.
1225      *
1226      * @param instClass Type that was to be instantiated
1227      * @param argument (optional) Argument that was passed to constructor or equivalent
1228      *    instantiator; often a {@link java.lang.String}.
1229      * @param t Exception that caused failure
1230      *
1231      * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
1232      *
1233      * @since 2.8
1234      */
handleInstantiationProblem(Class<?> instClass, Object argument, Throwable t)1235     public Object handleInstantiationProblem(Class<?> instClass, Object argument,
1236             Throwable t)
1237         throws IOException
1238     {
1239         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1240         while (h != null) {
1241             // Can bail out if it's handled
1242             Object instance = h.value().handleInstantiationProblem(this, instClass, argument, t);
1243             if (instance != DeserializationProblemHandler.NOT_HANDLED) {
1244                 // Sanity check for broken handlers, otherwise nasty to debug:
1245                 if (_isCompatible(instClass, instance)) {
1246                     return instance;
1247                 }
1248                 reportBadDefinition(constructType(instClass), String.format(
1249 "DeserializationProblemHandler.handleInstantiationProblem() for type %s returned value of type %s",
1250                     ClassUtil.getClassDescription(instClass),
1251                     ClassUtil.classNameOf(instance)
1252                 ));
1253             }
1254             h = h.next();
1255         }
1256         // 18-May-2016, tatu: Only wrap if not already a valid type to throw
1257         ClassUtil.throwIfIOE(t);
1258         // [databind#2164]: but see if wrapping is desired
1259         if (!isEnabled(DeserializationFeature.WRAP_EXCEPTIONS)) {
1260             ClassUtil.throwIfRTE(t);
1261         }
1262         throw instantiationException(instClass, t);
1263     }
1264 
1265     /**
1266      * Method that deserializers should call if the first token of the value to
1267      * deserialize is of unexpected type (that is, type of token that deserializer
1268      * cannot handle). This could occur, for example, if a Number deserializer
1269      * encounter {@link JsonToken#START_ARRAY} instead of
1270      * {@link JsonToken#VALUE_NUMBER_INT} or {@link JsonToken#VALUE_NUMBER_FLOAT}.
1271      *
1272      * @param instClass Type that was to be instantiated
1273      * @param p Parser that points to the JSON value to decode
1274      *
1275      * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
1276      *
1277      * @since 2.8
1278      */
handleUnexpectedToken(Class<?> instClass, JsonParser p)1279     public Object handleUnexpectedToken(Class<?> instClass, JsonParser p)
1280         throws IOException
1281     {
1282         return handleUnexpectedToken(constructType(instClass), p.currentToken(), p, null);
1283     }
1284 
1285     /**
1286      * Method that deserializers should call if the first token of the value to
1287      * deserialize is of unexpected type (that is, type of token that deserializer
1288      * cannot handle). This could occur, for example, if a Number deserializer
1289      * encounter {@link JsonToken#START_ARRAY} instead of
1290      * {@link JsonToken#VALUE_NUMBER_INT} or {@link JsonToken#VALUE_NUMBER_FLOAT}.
1291      *
1292      * @param instClass Type that was to be instantiated
1293      * @param t Token encountered that does match expected
1294      * @param p Parser that points to the JSON value to decode
1295      *
1296      * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
1297      *
1298      * @since 2.8
1299      */
handleUnexpectedToken(Class<?> instClass, JsonToken t, JsonParser p, String msg, Object... msgArgs)1300     public Object handleUnexpectedToken(Class<?> instClass, JsonToken t,
1301             JsonParser p, String msg, Object... msgArgs)
1302         throws IOException
1303     {
1304         return handleUnexpectedToken(constructType(instClass), t, p, msg, msgArgs);
1305     }
1306 
1307     /**
1308      * Method that deserializers should call if the first token of the value to
1309      * deserialize is of unexpected type (that is, type of token that deserializer
1310      * cannot handle). This could occur, for example, if a Number deserializer
1311      * encounter {@link JsonToken#START_ARRAY} instead of
1312      * {@link JsonToken#VALUE_NUMBER_INT} or {@link JsonToken#VALUE_NUMBER_FLOAT}.
1313      *
1314      * @param targetType Type that was to be instantiated
1315      * @param p Parser that points to the JSON value to decode
1316      *
1317      * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
1318      *
1319      * @since 2.10
1320      */
handleUnexpectedToken(JavaType targetType, JsonParser p)1321     public Object handleUnexpectedToken(JavaType targetType, JsonParser p)
1322         throws IOException
1323     {
1324         return handleUnexpectedToken(targetType, p.currentToken(), p, null);
1325     }
1326 
1327     /**
1328      * Method that deserializers should call if the first token of the value to
1329      * deserialize is of unexpected type (that is, type of token that deserializer
1330      * cannot handle). This could occur, for example, if a Number deserializer
1331      * encounter {@link JsonToken#START_ARRAY} instead of
1332      * {@link JsonToken#VALUE_NUMBER_INT} or {@link JsonToken#VALUE_NUMBER_FLOAT}.
1333      *
1334      * @param targetType Type that was to be instantiated
1335      * @param t Token encountered that does not match expected
1336      * @param p Parser that points to the JSON value to decode
1337      *
1338      * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
1339      *
1340      * @since 2.10
1341      */
handleUnexpectedToken(JavaType targetType, JsonToken t, JsonParser p, String msg, Object... msgArgs)1342     public Object handleUnexpectedToken(JavaType targetType, JsonToken t,
1343             JsonParser p, String msg, Object... msgArgs)
1344         throws IOException
1345     {
1346         msg = _format(msg, msgArgs);
1347         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1348         while (h != null) {
1349             Object instance = h.value().handleUnexpectedToken(this,
1350                     targetType, t, p, msg);
1351             if (instance != DeserializationProblemHandler.NOT_HANDLED) {
1352                 if (_isCompatible(targetType.getRawClass(), instance)) {
1353                     return instance;
1354                 }
1355                 reportBadDefinition(targetType, String.format(
1356                         "DeserializationProblemHandler.handleUnexpectedToken() for type %s returned value of type %s",
1357                         ClassUtil.getTypeDescription(targetType),
1358                         ClassUtil.classNameOf(instance)
1359                 ));
1360             }
1361             h = h.next();
1362         }
1363         if (msg == null) {
1364             final String targetDesc = ClassUtil.getTypeDescription(targetType);
1365             if (t == null) {
1366                 msg = String.format("Unexpected end-of-input when trying read value of type %s",
1367                         targetDesc);
1368             } else {
1369                 msg = String.format("Cannot deserialize value of type %s from %s (token `JsonToken.%s`)",
1370                         targetDesc, _shapeForToken(t), t);
1371             }
1372         }
1373         // 18-Jun-2020, tatu: to resolve [databind#2770], force access to `getText()` for scalars
1374         if ((t != null) && t.isScalarValue()) {
1375             p.getText();
1376         }
1377         reportInputMismatch(targetType, msg);
1378         return null; // never gets here
1379     }
1380 
1381     /**
1382      * Method that deserializers should call if they encounter a type id
1383      * (for polymorphic deserialization) that cannot be resolved to an
1384      * actual type; usually since there is no mapping defined.
1385      * Default implementation will try to call {@link DeserializationProblemHandler#handleUnknownTypeId}
1386      * on configured handlers, if any, to allow for recovery; if recovery does not
1387      * succeed, will throw exception constructed with {@link #invalidTypeIdException}.
1388      *
1389      * @param baseType Base type from which resolution starts
1390      * @param id Type id that could not be converted
1391      * @param extraDesc Additional problem description to add to default exception message,
1392      *    if resolution fails.
1393      *
1394      * @return {@link JavaType} that id resolves to
1395      *
1396      * @throws IOException To indicate unrecoverable problem, if resolution cannot
1397      *    be made to work
1398      *
1399      * @since 2.8
1400      */
handleUnknownTypeId(JavaType baseType, String id, TypeIdResolver idResolver, String extraDesc)1401     public JavaType handleUnknownTypeId(JavaType baseType, String id,
1402             TypeIdResolver idResolver, String extraDesc) throws IOException
1403     {
1404         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1405         while (h != null) {
1406             // Can bail out if it's handled
1407             JavaType type = h.value().handleUnknownTypeId(this, baseType, id, idResolver, extraDesc);
1408             if (type != null) {
1409                 if (type.hasRawClass(Void.class)) {
1410                     return null;
1411                 }
1412                 // But ensure there's type compatibility
1413                 if (type.isTypeOrSubTypeOf(baseType.getRawClass())) {
1414                     return type;
1415                 }
1416                 throw invalidTypeIdException(baseType, id,
1417                         "problem handler tried to resolve into non-subtype: "+
1418                                 ClassUtil.getTypeDescription(type));
1419             }
1420             h = h.next();
1421         }
1422         // 24-May-2016, tatu: Actually we may still not want to fail quite yet
1423         if (!isEnabled(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE)) {
1424             return null;
1425         }
1426         throw invalidTypeIdException(baseType, id, extraDesc);
1427     }
1428 
1429     /**
1430      * @since 2.9
1431      */
handleMissingTypeId(JavaType baseType, TypeIdResolver idResolver, String extraDesc)1432     public JavaType handleMissingTypeId(JavaType baseType,
1433             TypeIdResolver idResolver, String extraDesc) throws IOException
1434     {
1435         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1436         while (h != null) {
1437             // Can bail out if it's handled
1438             JavaType type = h.value().handleMissingTypeId(this, baseType, idResolver, extraDesc);
1439             if (type != null) {
1440                 if (type.hasRawClass(Void.class)) {
1441                     return null;
1442                 }
1443                 // But ensure there's type compatibility
1444                 if (type.isTypeOrSubTypeOf(baseType.getRawClass())) {
1445                     return type;
1446                 }
1447                 throw invalidTypeIdException(baseType, null,
1448                         "problem handler tried to resolve into non-subtype: "+
1449                                 ClassUtil.getTypeDescription(type));
1450             }
1451             h = h.next();
1452         }
1453         // 09-Mar-2017, tatu: We may want to consider yet another feature at some
1454         //    point to allow returning `null`... but that seems bit risky for now
1455 //        if (!isEnabled(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE)) {
1456 //            return null;
1457 //        }
1458         throw missingTypeIdException(baseType, extraDesc);
1459     }
1460 
1461     /**
1462      * Method that deserializer may call if it is called to do an update ("merge")
1463      * but deserializer operates on a non-mergeable type. Although this should
1464      * usually be caught earlier, sometimes it may only be caught during operation
1465      * and if so this is the method to call.
1466      * Note that if {@link MapperFeature#IGNORE_MERGE_FOR_UNMERGEABLE} is enabled,
1467      * this method will simply return null; otherwise {@link InvalidDefinitionException}
1468      * will be thrown.
1469      *
1470      * @since 2.10
1471      */
handleBadMerge(JsonDeserializer<?> deser)1472     public void handleBadMerge(JsonDeserializer<?> deser) throws JsonMappingException
1473     {
1474         if (!isEnabled(MapperFeature.IGNORE_MERGE_FOR_UNMERGEABLE)) {
1475             JavaType type = constructType(deser.handledType());
1476             String msg = String.format("Invalid configuration: values of type %s cannot be merged",
1477                     ClassUtil.getTypeDescription(type));
1478             throw InvalidDefinitionException.from(getParser(), msg, type);
1479         }
1480     }
1481 
1482     /**
1483      * @since 2.9.2
1484      */
_isCompatible(Class<?> target, Object value)1485     protected boolean _isCompatible(Class<?> target, Object value)
1486     {
1487         if ((value == null) || target.isInstance(value)) {
1488             return true;
1489         }
1490         // [databind#1767]: Make sure to allow wrappers for primitive fields
1491         return target.isPrimitive()
1492                 && ClassUtil.wrapperType(target).isInstance(value);
1493     }
1494 
1495     /*
1496     /**********************************************************
1497     /* Methods for problem reporting, in cases where recovery
1498     /* is not considered possible: input problem
1499     /**********************************************************
1500      */
1501 
1502     /**
1503      * Method for deserializers to call
1504      * when the token encountered was of type different than what <b>should</b>
1505      * be seen at that position, usually within a sequence of expected tokens.
1506      * Note that this method will throw a {@link JsonMappingException} and no
1507      * recovery is attempted (via {@link DeserializationProblemHandler}, as
1508      * problem is considered to be difficult to recover from, in general.
1509      *
1510      * @since 2.9
1511      */
reportWrongTokenException(JsonDeserializer<?> deser, JsonToken expToken, String msg, Object... msgArgs)1512     public void reportWrongTokenException(JsonDeserializer<?> deser,
1513             JsonToken expToken, String msg, Object... msgArgs)
1514         throws JsonMappingException
1515     {
1516         msg = _format(msg, msgArgs);
1517         throw wrongTokenException(getParser(), deser.handledType(), expToken, msg);
1518     }
1519 
1520     /**
1521      * Method for deserializers to call
1522      * when the token encountered was of type different than what <b>should</b>
1523      * be seen at that position, usually within a sequence of expected tokens.
1524      * Note that this method will throw a {@link JsonMappingException} and no
1525      * recovery is attempted (via {@link DeserializationProblemHandler}, as
1526      * problem is considered to be difficult to recover from, in general.
1527      *
1528      * @since 2.9
1529      */
reportWrongTokenException(JavaType targetType, JsonToken expToken, String msg, Object... msgArgs)1530     public void reportWrongTokenException(JavaType targetType,
1531             JsonToken expToken, String msg, Object... msgArgs)
1532         throws JsonMappingException
1533     {
1534         msg = _format(msg, msgArgs);
1535         throw wrongTokenException(getParser(), targetType, expToken, msg);
1536     }
1537 
1538     /**
1539      * Method for deserializers to call
1540      * when the token encountered was of type different than what <b>should</b>
1541      * be seen at that position, usually within a sequence of expected tokens.
1542      * Note that this method will throw a {@link JsonMappingException} and no
1543      * recovery is attempted (via {@link DeserializationProblemHandler}, as
1544      * problem is considered to be difficult to recover from, in general.
1545      *
1546      * @since 2.9
1547      */
reportWrongTokenException(Class<?> targetType, JsonToken expToken, String msg, Object... msgArgs)1548     public void reportWrongTokenException(Class<?> targetType,
1549             JsonToken expToken, String msg, Object... msgArgs)
1550         throws JsonMappingException
1551     {
1552         msg = _format(msg, msgArgs);
1553         throw wrongTokenException(getParser(), targetType, expToken, msg);
1554     }
1555 
1556     /**
1557      * @since 2.8
1558      */
reportUnresolvedObjectId(ObjectIdReader oidReader, Object bean)1559     public <T> T reportUnresolvedObjectId(ObjectIdReader oidReader, Object bean)
1560         throws JsonMappingException
1561     {
1562         String msg = String.format("No Object Id found for an instance of %s, to assign to property '%s'",
1563                 ClassUtil.classNameOf(bean), oidReader.propertyName);
1564         return reportInputMismatch(oidReader.idProperty, msg);
1565     }
1566 
1567     /**
1568      * Helper method used to indicate a problem with input in cases where more
1569      * specific <code>reportXxx()</code> method was not available.
1570      *
1571      * @since 2.9
1572      */
reportInputMismatch(JsonDeserializer<?> src, String msg, Object... msgArgs)1573     public <T> T reportInputMismatch(JsonDeserializer<?> src,
1574             String msg, Object... msgArgs) throws JsonMappingException
1575     {
1576         msg = _format(msg, msgArgs);
1577         throw MismatchedInputException.from(getParser(), src.handledType(), msg);
1578     }
1579 
1580     /**
1581      * Helper method used to indicate a problem with input in cases where more
1582      * specific <code>reportXxx()</code> method was not available.
1583      *
1584      * @since 2.9
1585      */
reportInputMismatch(Class<?> targetType, String msg, Object... msgArgs)1586     public <T> T reportInputMismatch(Class<?> targetType,
1587             String msg, Object... msgArgs) throws JsonMappingException
1588     {
1589         msg = _format(msg, msgArgs);
1590         throw MismatchedInputException.from(getParser(), targetType, msg);
1591     }
1592 
1593     /**
1594      * Helper method used to indicate a problem with input in cases where more
1595      * specific <code>reportXxx()</code> method was not available.
1596      *
1597      * @since 2.9
1598      */
reportInputMismatch(JavaType targetType, String msg, Object... msgArgs)1599     public <T> T reportInputMismatch(JavaType targetType,
1600             String msg, Object... msgArgs) throws JsonMappingException
1601     {
1602         msg = _format(msg, msgArgs);
1603         throw MismatchedInputException.from(getParser(), targetType, msg);
1604     }
1605 
1606     /**
1607      * Helper method used to indicate a problem with input in cases where more
1608      * specific <code>reportXxx()</code> method was not available.
1609      *
1610      * @since 2.9
1611      */
reportInputMismatch(BeanProperty prop, String msg, Object... msgArgs)1612     public <T> T reportInputMismatch(BeanProperty prop,
1613             String msg, Object... msgArgs) throws JsonMappingException
1614     {
1615         msg = _format(msg, msgArgs);
1616         JavaType type = (prop == null) ? null : prop.getType();
1617         final MismatchedInputException e = MismatchedInputException.from(getParser(), type, msg);
1618         // [databind#2357]: Include property name, if we have it
1619         if (prop != null) {
1620             AnnotatedMember member = prop.getMember();
1621             if (member != null) {
1622                 e.prependPath(member.getDeclaringClass(), prop.getName());
1623             }
1624         }
1625         throw e;
1626     }
1627 
1628     /**
1629      * Helper method used to indicate a problem with input in cases where more
1630      * specific <code>reportXxx()</code> method was not available.
1631      *
1632      * @since 2.10
1633      */
reportPropertyInputMismatch(Class<?> targetType, String propertyName, String msg, Object... msgArgs)1634     public <T> T reportPropertyInputMismatch(Class<?> targetType, String propertyName,
1635             String msg, Object... msgArgs) throws JsonMappingException
1636     {
1637         msg = _format(msg, msgArgs);
1638         MismatchedInputException e = MismatchedInputException.from(getParser(), targetType, msg);
1639         if (propertyName != null) {
1640             e.prependPath(targetType, propertyName);
1641         }
1642         throw e;
1643     }
1644 
1645     /**
1646      * Helper method used to indicate a problem with input in cases where more
1647      * specific <code>reportXxx()</code> method was not available.
1648      *
1649      * @since 2.10
1650      */
reportPropertyInputMismatch(JavaType targetType, String propertyName, String msg, Object... msgArgs)1651     public <T> T reportPropertyInputMismatch(JavaType targetType, String propertyName,
1652             String msg, Object... msgArgs) throws JsonMappingException
1653     {
1654         return reportPropertyInputMismatch(targetType.getRawClass(), propertyName, msg, msgArgs);
1655     }
1656 
reportTrailingTokens(Class<?> targetType, JsonParser p, JsonToken trailingToken)1657     public <T> T reportTrailingTokens(Class<?> targetType,
1658             JsonParser p, JsonToken trailingToken) throws JsonMappingException
1659     {
1660         throw MismatchedInputException.from(p, targetType, String.format(
1661 "Trailing token (of type %s) found after value (bound as %s): not allowed as per `DeserializationFeature.FAIL_ON_TRAILING_TOKENS`",
1662 trailingToken, ClassUtil.nameOf(targetType)
1663                 ));
1664     }
1665 
1666     @Deprecated // since 2.9
reportWrongTokenException(JsonParser p, JsonToken expToken, String msg, Object... msgArgs)1667     public void reportWrongTokenException(JsonParser p,
1668             JsonToken expToken, String msg, Object... msgArgs)
1669         throws JsonMappingException
1670     {
1671         msg = _format(msg, msgArgs);
1672         throw wrongTokenException(p, expToken, msg);
1673     }
1674 
1675     /**
1676      * Helper method for reporting a problem with unhandled unknown property.
1677      *
1678      * @param instanceOrClass Either value being populated (if one has been
1679      *   instantiated), or Class that indicates type that would be (or
1680      *   have been) instantiated
1681      * @param deser Deserializer that had the problem, if called by deserializer
1682      *   (or on behalf of one)
1683      *
1684      * @deprecated Since 2.8 call {@link #handleUnknownProperty} instead
1685      */
1686     @Deprecated
reportUnknownProperty(Object instanceOrClass, String fieldName, JsonDeserializer<?> deser)1687     public void reportUnknownProperty(Object instanceOrClass, String fieldName,
1688             JsonDeserializer<?> deser)
1689         throws JsonMappingException
1690     {
1691         if (isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) {
1692             // Do we know properties that are expected instead?
1693             Collection<Object> propIds = (deser == null) ? null : deser.getKnownPropertyNames();
1694             throw UnrecognizedPropertyException.from(_parser,
1695                     instanceOrClass, fieldName, propIds);
1696         }
1697     }
1698 
1699     /**
1700      * @since 2.8
1701      *
1702      * @deprecated Since 2.9: not clear this ever occurs
1703      */
1704     @Deprecated // since 2.9
reportMissingContent(String msg, Object... msgArgs)1705     public void reportMissingContent(String msg, Object... msgArgs) throws JsonMappingException {
1706         throw MismatchedInputException.from(getParser(), (JavaType) null, "No content to map due to end-of-input");
1707     }
1708 
1709     /*
1710     /**********************************************************
1711     /* Methods for problem reporting, in cases where recovery
1712     /* is not considered possible: POJO definition problems
1713     /**********************************************************
1714      */
1715 
1716     /**
1717      * Helper method called to indicate problem in POJO (serialization) definitions or settings
1718      * regarding specific Java type, unrelated to actual JSON content to map.
1719      * Default behavior is to construct and throw a {@link JsonMappingException}.
1720      *
1721      * @since 2.9
1722      */
reportBadTypeDefinition(BeanDescription bean, String msg, Object... msgArgs)1723     public <T> T reportBadTypeDefinition(BeanDescription bean,
1724             String msg, Object... msgArgs) throws JsonMappingException {
1725         msg = _format(msg, msgArgs);
1726         String beanDesc = ClassUtil.nameOf(bean.getBeanClass());
1727         msg = String.format("Invalid type definition for type %s: %s", beanDesc, msg);
1728         throw InvalidDefinitionException.from(_parser, msg, bean, null);
1729     }
1730 
1731     /**
1732      * Helper method called to indicate problem in POJO (serialization) definitions or settings
1733      * regarding specific property (of a type), unrelated to actual JSON content to map.
1734      * Default behavior is to construct and throw a {@link JsonMappingException}.
1735      *
1736      * @since 2.9
1737      */
reportBadPropertyDefinition(BeanDescription bean, BeanPropertyDefinition prop, String msg, Object... msgArgs)1738     public <T> T reportBadPropertyDefinition(BeanDescription bean, BeanPropertyDefinition prop,
1739             String msg, Object... msgArgs) throws JsonMappingException {
1740         msg = _format(msg, msgArgs);
1741         String propName = ClassUtil.nameOf(prop);
1742         String beanDesc = ClassUtil.nameOf(bean.getBeanClass());
1743         msg = String.format("Invalid definition for property %s (of type %s): %s",
1744                 propName, beanDesc, msg);
1745         throw InvalidDefinitionException.from(_parser, msg, bean, prop);
1746     }
1747 
1748     @Override
reportBadDefinition(JavaType type, String msg)1749     public <T> T reportBadDefinition(JavaType type, String msg) throws JsonMappingException {
1750         throw InvalidDefinitionException.from(_parser, msg, type);
1751     }
1752 
1753     /**
1754      * @deprecated Since 2.10 use {@link #handleBadMerge} instead
1755      */
1756     @Deprecated // since 2.10
reportBadMerge(JsonDeserializer<?> deser)1757     public <T> T reportBadMerge(JsonDeserializer<?> deser) throws JsonMappingException {
1758         handleBadMerge(deser);
1759         return null;
1760     }
1761 
1762     /*
1763     /**********************************************************
1764     /* Methods for constructing semantic exceptions; usually not
1765     /* to be called directly, call `handleXxx()` instead
1766     /**********************************************************
1767      */
1768 
1769     /**
1770      * Helper method for constructing {@link JsonMappingException} to indicate
1771      * that the token encountered was of type different than what <b>should</b>
1772      * be seen at that position, usually within a sequence of expected tokens.
1773      * Note that most of the time this method should NOT be directly called;
1774      * instead, {@link #reportWrongTokenException} should be called and will
1775      * call this method as necessary.
1776      *
1777      * @since 2.9
1778      */
wrongTokenException(JsonParser p, JavaType targetType, JsonToken expToken, String extra)1779     public JsonMappingException wrongTokenException(JsonParser p, JavaType targetType,
1780             JsonToken expToken, String extra)
1781     {
1782         String msg = String.format("Unexpected token (%s), expected %s",
1783                 p.currentToken(), expToken);
1784         msg = _colonConcat(msg, extra);
1785         return MismatchedInputException.from(p, targetType, msg);
1786     }
1787 
wrongTokenException(JsonParser p, Class<?> targetType, JsonToken expToken, String extra)1788     public JsonMappingException wrongTokenException(JsonParser p, Class<?> targetType,
1789             JsonToken expToken, String extra)
1790     {
1791         String msg = String.format("Unexpected token (%s), expected %s",
1792                 p.currentToken(), expToken);
1793         msg = _colonConcat(msg, extra);
1794         return MismatchedInputException.from(p, targetType, msg);
1795     }
1796 
1797     @Deprecated // since 2.9
wrongTokenException(JsonParser p, JsonToken expToken, String msg)1798     public JsonMappingException wrongTokenException(JsonParser p, JsonToken expToken,
1799             String msg)
1800     {
1801         return wrongTokenException(p, (JavaType) null, expToken, msg);
1802     }
1803 
1804     /**
1805      * Helper method for constructing exception to indicate that given JSON
1806      * Object field name was not in format to be able to deserialize specified
1807      * key type.
1808      * Note that most of the time this method should NOT be called; instead,
1809      * {@link #handleWeirdKey} should be called which will call this method
1810      * if necessary.
1811      */
weirdKeyException(Class<?> keyClass, String keyValue, String msg)1812     public JsonMappingException weirdKeyException(Class<?> keyClass, String keyValue,
1813             String msg) {
1814         return InvalidFormatException.from(_parser,
1815                 String.format("Cannot deserialize Map key of type %s from String %s: %s",
1816                         ClassUtil.nameOf(keyClass), _quotedString(keyValue), msg),
1817                 keyValue, keyClass);
1818     }
1819 
1820     /**
1821      * Helper method for constructing exception to indicate that input JSON
1822      * String was not suitable for deserializing into given target type.
1823      * Note that most of the time this method should NOT be called; instead,
1824      * {@link #handleWeirdStringValue} should be called which will call this method
1825      * if necessary.
1826      *
1827      * @param value String value from input being deserialized
1828      * @param instClass Type that String should be deserialized into
1829      * @param msgBase Message that describes specific problem
1830      *
1831      * @since 2.1
1832      */
weirdStringException(String value, Class<?> instClass, String msgBase)1833     public JsonMappingException weirdStringException(String value, Class<?> instClass,
1834             String msgBase) {
1835         final String msg = String.format("Cannot deserialize value of type %s from String %s: %s",
1836                 ClassUtil.nameOf(instClass), _quotedString(value), msgBase);
1837         return InvalidFormatException.from(_parser, msg, value, instClass);
1838     }
1839 
1840     /**
1841      * Helper method for constructing exception to indicate that input JSON
1842      * Number was not suitable for deserializing into given target type.
1843      * Note that most of the time this method should NOT be called; instead,
1844      * {@link #handleWeirdNumberValue} should be called which will call this method
1845      * if necessary.
1846      */
weirdNumberException(Number value, Class<?> instClass, String msg)1847     public JsonMappingException weirdNumberException(Number value, Class<?> instClass,
1848             String msg) {
1849         return InvalidFormatException.from(_parser,
1850                 String.format("Cannot deserialize value of type %s from number %s: %s",
1851                         ClassUtil.nameOf(instClass), String.valueOf(value), msg),
1852                 value, instClass);
1853     }
1854 
1855     /**
1856      * Helper method for constructing exception to indicate that input JSON
1857      * token of type "native value" (see {@link JsonToken#VALUE_EMBEDDED_OBJECT})
1858      * is of incompatible type (and there is no delegating creator or such to use)
1859      * and can not be used to construct value of specified type (usually POJO).
1860      * Note that most of the time this method should NOT be called; instead,
1861      * {@link #handleWeirdNativeValue} should be called which will call this method
1862      *
1863      * @since 2.9
1864      */
weirdNativeValueException(Object value, Class<?> instClass)1865     public JsonMappingException weirdNativeValueException(Object value, Class<?> instClass)
1866     {
1867         return InvalidFormatException.from(_parser, String.format(
1868 "Cannot deserialize value of type %s from native value (`JsonToken.VALUE_EMBEDDED_OBJECT`) of type %s: incompatible types",
1869             ClassUtil.nameOf(instClass), ClassUtil.classNameOf(value)),
1870                 value, instClass);
1871     }
1872 
1873     /**
1874      * Helper method for constructing instantiation exception for specified type,
1875      * to indicate problem with physically constructing instance of
1876      * specified class (missing constructor, exception from constructor)
1877      *<p>
1878      * Note that most of the time this method should NOT be called directly; instead,
1879      * {@link #handleInstantiationProblem} should be called which will call this method
1880      * if necessary.
1881      */
instantiationException(Class<?> instClass, Throwable cause)1882     public JsonMappingException instantiationException(Class<?> instClass, Throwable cause) {
1883         String excMsg;
1884         if (cause == null) {
1885             excMsg = "N/A";
1886         } else if ((excMsg = ClassUtil.exceptionMessage(cause)) == null) {
1887             excMsg = ClassUtil.nameOf(cause.getClass());
1888         }
1889         String msg = String.format("Cannot construct instance of %s, problem: %s",
1890                 ClassUtil.nameOf(instClass), excMsg);
1891         // [databind#2162]: use specific exception type as we don't know if it's
1892         // due to type definition, input, or neither
1893         return ValueInstantiationException.from(_parser, msg, constructType(instClass), cause);
1894     }
1895 
1896     /**
1897      * Helper method for constructing instantiation exception for specified type,
1898      * to indicate that instantiation failed due to missing instantiator
1899      * (creator; constructor or factory method).
1900      *<p>
1901      * Note that most of the time this method should NOT be called; instead,
1902      * {@link #handleMissingInstantiator} should be called which will call this method
1903      * if necessary.
1904      */
instantiationException(Class<?> instClass, String msg0)1905     public JsonMappingException instantiationException(Class<?> instClass, String msg0) {
1906         // [databind#2162]: use specific exception type as we don't know if it's
1907         // due to type definition, input, or neither
1908         return ValueInstantiationException.from(_parser,
1909                 String.format("Cannot construct instance of %s: %s",
1910                         ClassUtil.nameOf(instClass), msg0),
1911                 constructType(instClass));
1912     }
1913 
1914     @Override
invalidTypeIdException(JavaType baseType, String typeId, String extraDesc)1915     public JsonMappingException invalidTypeIdException(JavaType baseType, String typeId,
1916             String extraDesc) {
1917         String msg = String.format("Could not resolve type id '%s' as a subtype of %s",
1918                 typeId, ClassUtil.getTypeDescription(baseType));
1919         return InvalidTypeIdException.from(_parser, _colonConcat(msg, extraDesc), baseType, typeId);
1920     }
1921 
1922     /**
1923      * @since 2.9
1924      */
missingTypeIdException(JavaType baseType, String extraDesc)1925     public JsonMappingException missingTypeIdException(JavaType baseType,
1926             String extraDesc) {
1927         String msg = String.format("Missing type id when trying to resolve subtype of %s",
1928                 baseType);
1929         return InvalidTypeIdException.from(_parser, _colonConcat(msg, extraDesc), baseType, null);
1930     }
1931 
1932     /*
1933     /**********************************************************
1934     /* Deprecated exception factory methods
1935     /**********************************************************
1936      */
1937 
1938     /**
1939      * @since 2.5
1940      *
1941      * @deprecated Since 2.8 use {@link #handleUnknownTypeId} instead
1942      */
1943     @Deprecated
unknownTypeException(JavaType type, String id, String extraDesc)1944     public JsonMappingException unknownTypeException(JavaType type, String id,
1945             String extraDesc)
1946     {
1947         String msg = String.format("Could not resolve type id '%s' into a subtype of %s",
1948                 id, ClassUtil.getTypeDescription(type));
1949         msg = _colonConcat(msg, extraDesc);
1950         return MismatchedInputException.from(_parser, type, msg);
1951     }
1952 
1953     /**
1954      * Helper method for constructing exception to indicate that end-of-input was
1955      * reached while still expecting more tokens to deserialize value of specified type.
1956      *
1957      * @deprecated Since 2.8; currently no way to catch EOF at databind level
1958      */
1959     @Deprecated
endOfInputException(Class<?> instClass)1960     public JsonMappingException endOfInputException(Class<?> instClass) {
1961         return MismatchedInputException.from(_parser, instClass,
1962                 "Unexpected end-of-input when trying to deserialize a "+instClass.getName());
1963     }
1964 
1965     /*
1966     /**********************************************************
1967     /* Deprecated methods for constructing, throwing non-specific
1968     /* JsonMappingExceptions: as of 2.9, should use more specific
1969     /* ones.
1970     /**********************************************************
1971      */
1972 
1973     /**
1974      * Fallback method that may be called if no other <code>reportXxx</code>
1975      * is applicable -- but only in that case.
1976      *
1977      * @since 2.8
1978      *
1979      * @deprecated Since 2.9: use a more specific method, or {@link #reportBadDefinition(JavaType, String)},
1980      *    or {@link #reportInputMismatch} instead
1981      */
1982     @Deprecated // since 2.9
reportMappingException(String msg, Object... msgArgs)1983     public void reportMappingException(String msg, Object... msgArgs)
1984         throws JsonMappingException
1985     {
1986         throw JsonMappingException.from(getParser(), _format(msg, msgArgs));
1987     }
1988 
1989     /**
1990      * Helper method for constructing generic mapping exception with specified
1991      * message and current location information.
1992      * Note that application code should almost always call
1993      * one of <code>handleXxx</code> methods, or {@link #reportMappingException(String, Object...)}
1994      * instead.
1995      *
1996      * @since 2.6
1997      *
1998      * @deprecated Since 2.9 use more specific error reporting methods instead
1999      */
2000     @Deprecated
mappingException(String message)2001     public JsonMappingException mappingException(String message) {
2002         return JsonMappingException.from(getParser(), message);
2003     }
2004 
2005     /**
2006      * Helper method for constructing generic mapping exception with specified
2007      * message and current location information
2008      * Note that application code should almost always call
2009      * one of <code>handleXxx</code> methods, or {@link #reportMappingException(String, Object...)}
2010      * instead.
2011      *
2012      * @since 2.6
2013      *
2014      * @deprecated Since 2.9 use more specific error reporting methods instead
2015      */
2016     @Deprecated
mappingException(String msg, Object... msgArgs)2017     public JsonMappingException mappingException(String msg, Object... msgArgs) {
2018         return JsonMappingException.from(getParser(), _format(msg, msgArgs));
2019     }
2020 
2021     /**
2022      * Helper method for constructing generic mapping exception for specified type
2023      *
2024      * @deprecated Since 2.8 use {@link #handleUnexpectedToken(Class, JsonParser)} instead
2025      */
2026     @Deprecated
mappingException(Class<?> targetClass)2027     public JsonMappingException mappingException(Class<?> targetClass) {
2028         return mappingException(targetClass, _parser.currentToken());
2029     }
2030 
2031     /**
2032      * @deprecated Since 2.8 use {@link #handleUnexpectedToken(Class, JsonParser)} instead
2033      */
2034     @Deprecated
mappingException(Class<?> targetClass, JsonToken token)2035     public JsonMappingException mappingException(Class<?> targetClass, JsonToken token) {
2036         return JsonMappingException.from(_parser,
2037                 String.format("Cannot deserialize instance of %s out of %s token",
2038                         ClassUtil.nameOf(targetClass), token));
2039     }
2040 
2041     /*
2042     /**********************************************************
2043     /* Other internal methods
2044     /**********************************************************
2045      */
2046 
2047     @Deprecated // since 2.12, remove from 2.13 or later
getDateFormat()2048     protected DateFormat getDateFormat() {
2049         return _getDateFormat();
2050     }
2051 
_getDateFormat()2052     protected DateFormat _getDateFormat() {
2053         if (_dateFormat != null) {
2054             return _dateFormat;
2055         }
2056         /* 24-Feb-2012, tatu: At this point, all timezone configuration
2057          *    should have occurred, with respect to default dateformat
2058          *    and timezone configuration. But we still better clone
2059          *    an instance as formatters may be stateful.
2060          */
2061         DateFormat df = _config.getDateFormat();
2062         _dateFormat = df = (DateFormat) df.clone();
2063         return df;
2064     }
2065 
2066     // @since 2.12
2067     /**
2068      * Helper method for constructing description like "Object value" given
2069      * {@link JsonToken} encountered.
2070      */
_shapeForToken(JsonToken t)2071     protected String _shapeForToken(JsonToken t) {
2072         if (t != null) {
2073             switch (t) {
2074             // Likely Object values
2075             case START_OBJECT:
2076             case END_OBJECT:
2077             case FIELD_NAME:
2078                 return "Object value";
2079 
2080             // Likely Array values
2081             case START_ARRAY:
2082             case END_ARRAY:
2083                 return "Array value";
2084 
2085             case VALUE_FALSE:
2086             case VALUE_TRUE:
2087                 return "Boolean value";
2088 
2089             case VALUE_EMBEDDED_OBJECT:
2090                 return "Embedded Object";
2091 
2092             case VALUE_NUMBER_FLOAT:
2093                 return "Floating-point value";
2094             case VALUE_NUMBER_INT:
2095                 return "Integer value";
2096             case VALUE_STRING:
2097                 return "String value";
2098 
2099             case VALUE_NULL:
2100                 return "Null value";
2101 
2102             case NOT_AVAILABLE:
2103             default:
2104                 return "[Unavailable value]";
2105             }
2106         }
2107         return "<end of input>";
2108     }
2109 }
2110