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
15 import com.fasterxml.jackson.databind.cfg.ContextAttributes;
16 import com.fasterxml.jackson.databind.deser.*;
17 import com.fasterxml.jackson.databind.deser.impl.ObjectIdReader;
18 import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId;
19 import com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer;
20 import com.fasterxml.jackson.databind.exc.MismatchedInputException;
21 import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
22 import com.fasterxml.jackson.databind.exc.InvalidFormatException;
23 import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
24 import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
25 import com.fasterxml.jackson.databind.exc.ValueInstantiationException;
26 import com.fasterxml.jackson.databind.introspect.Annotated;
27 import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
28 import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
29 import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
30 import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
31 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
32 import com.fasterxml.jackson.databind.type.TypeFactory;
33 import com.fasterxml.jackson.databind.util.*;
34
35 /**
36  * Context for the process of deserialization a single root-level value.
37  * Used to allow passing in configuration settings and reusable temporary
38  * objects (scrap arrays, containers).
39  *<p>
40  * Instance life-cycle is such that a partially configured "blueprint" object
41  * is registered with {@link ObjectMapper} (and {@link ObjectReader},
42  * and when actual instance is needed for deserialization,
43  * a fully configured instance will be created using a method in extended internal
44  *  API of sub-class
45  * ({@link com.fasterxml.jackson.databind.deser.DefaultDeserializationContext#createInstance}).
46  * Each instance is guaranteed to only be used from single-threaded context;
47  * instances may be reused if (and only if) no configuration has changed.
48  *<p>
49  * Defined as abstract class so that implementations must define methods
50  * for reconfiguring blueprints and creating instances.
51  */

52 public abstract class DeserializationContext
53     extends DatabindContext
54     implements java.io.Serializable
55 {
56     private static final long serialVersionUID = 1L; // 2.6
57
58     /*
59     /**********************************************************
60     /* Configuration, immutable
61     /**********************************************************
62      */

63
64     /**
65      * Object that handle details of {@link JsonDeserializer} caching.
66      */

67     protected final DeserializerCache _cache;
68
69     /*
70     /**********************************************************
71     /* Configuration, changeable via fluent factories
72     /**********************************************************
73      */

74
75     /**
76      * Read-only factory instance; exposed to let
77      * owners (<code>ObjectMapper</code>, <code>ObjectReader</code>)
78      * access it.
79      */

80     protected final DeserializerFactory _factory;
81
82     /*
83     /**********************************************************
84     /* Configuration that gets set for instances (not blueprints)
85     /* (partly denormalized for performance)
86     /**********************************************************
87      */

88
89     /**
90      * Generic deserialization processing configuration
91      */

92     protected final DeserializationConfig _config;
93
94     /**
95      * Bitmap of {@link DeserializationFeature}s that are enabled
96      */

97     protected final int _featureFlags;
98
99     /**
100      * Currently active view, if any.
101      */

102     protected final Class<?> _view;
103
104     /**
105      * Currently active parser used for deserialization.
106      * May be different from the outermost parser
107      * when content is buffered.
108      */

109     protected transient JsonParser _parser;
110     
111     /**
112      * Object used for resolving references to injectable
113      * values.
114      */

115     protected final InjectableValues _injectableValues;
116     
117     /*
118     /**********************************************************
119     /* Per-operation reusable helper objects (not for blueprints)
120     /**********************************************************
121      */

122
123     protected transient ArrayBuilders _arrayBuilders;
124
125     protected transient ObjectBuffer _objectBuffer;
126
127     protected transient DateFormat _dateFormat;
128
129     /**
130      * Lazily-constructed holder for per-call attributes.
131      * 
132      * @since 2.3
133      */

134     protected transient ContextAttributes _attributes;
135
136     /**
137      * Type of {@link JsonDeserializer} (or, more specifically,
138      *   {@link ContextualDeserializer}) that is being
139      *   contextualized currently.
140      *
141      * @since 2.5
142      */

143     protected LinkedNode<JavaType> _currentType;
144     
145     /*
146     /**********************************************************
147     /* Life-cycle
148     /**********************************************************
149      */

150
151     protected DeserializationContext(DeserializerFactory df) {
152         this(df, null);
153     }
154     
155     protected DeserializationContext(DeserializerFactory df,
156             DeserializerCache cache)
157     {
158         if (df == null) {
159             throw new NullPointerException("Cannot pass null DeserializerFactory");
160         }
161         _factory = df;
162         if (cache == null) {
163             cache = new DeserializerCache();
164         }
165         _cache = cache;
166         _featureFlags = 0;
167         _config = null;
168         _injectableValues = null;
169         _view = null;
170         _attributes = null;
171     }
172
173     protected DeserializationContext(DeserializationContext src,
174             DeserializerFactory factory)
175     {
176         _cache = src._cache;
177         _factory = factory;
178         
179         _config = src._config;
180         _featureFlags = src._featureFlags;
181         _view = src._view;
182         _parser = src._parser;
183         _injectableValues = src._injectableValues;
184         _attributes = src._attributes;
185     }
186
187     /**
188      * Constructor used for creating actual per-call instances.
189      */

190     protected DeserializationContext(DeserializationContext src,
191             DeserializationConfig config, JsonParser p,
192             InjectableValues injectableValues)
193     {
194         _cache = src._cache;
195         _factory = src._factory;
196         
197         _config = config;
198         _featureFlags = config.getDeserializationFeatures();
199         _view = config.getActiveView();
200         _parser = p;
201         _injectableValues = injectableValues;
202         _attributes = config.getAttributes();
203     }
204
205     /**
206      * Copy-constructor for use with <code>copy()</code> by {@link ObjectMapper#copy()}
207      */

208     protected DeserializationContext(DeserializationContext src) {
209         _cache = new DeserializerCache();
210         _factory = src._factory;
211
212         _config = src._config;
213         _featureFlags = src._featureFlags;
214         _view = src._view;
215         _injectableValues = null;
216     }
217     
218     /*
219     /**********************************************************
220     /* DatabindContext implementation
221     /**********************************************************
222      */

223
224     @Override
225     public DeserializationConfig getConfig() { return _config; }
226
227     @Override
228     public final Class<?> getActiveView() { return _view; }
229
230     @Override
231     public final boolean canOverrideAccessModifiers() {
232         return _config.canOverrideAccessModifiers();
233     }
234
235     @Override
236     public final boolean isEnabled(MapperFeature feature) {
237         return _config.isEnabled(feature);
238     }
239
240     @Override
241     public final JsonFormat.Value getDefaultPropertyFormat(Class<?> baseType) {
242         return _config.getDefaultPropertyFormat(baseType);
243     }
244
245     @Override
246     public final AnnotationIntrospector getAnnotationIntrospector() {
247         return _config.getAnnotationIntrospector();
248     }
249
250     @Override
251     public final TypeFactory getTypeFactory() {
252         return _config.getTypeFactory();
253     }
254
255     @Override // since 2.11
256     public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass)
257         throws IllegalArgumentException
258     {
259         if (baseType.hasRawClass(subclass)) {
260             return baseType;
261         }
262         // On deserialization side, still uses "strict" type-compatibility checking;
263         // see [databind#2632] about serialization side
264         return getConfig().getTypeFactory().constructSpecializedType(baseType, subclass, false);
265     }
266
267     /**
268      * Method for accessing default Locale to use: convenience method for
269      *<pre>
270      *   getConfig().getLocale();
271      *</pre>
272      */

273     @Override
274     public Locale getLocale() {
275         return _config.getLocale();
276     }
277
278     /**
279      * Method for accessing default TimeZone to use: convenience method for
280      *<pre>
281      *   getConfig().getTimeZone();
282      *</pre>
283      */

284     @Override
285     public TimeZone getTimeZone() {
286         return _config.getTimeZone();
287     }
288
289     /*
290     /**********************************************************
291     /* Access to per-call state, like generic attributes (2.3+)
292     /**********************************************************
293      */

294
295     @Override
296     public Object getAttribute(Object key) {
297         return _attributes.getAttribute(key);
298     }
299
300     @Override
301     public DeserializationContext setAttribute(Object key, Object value)
302     {
303         _attributes = _attributes.withPerCallAttribute(key, value);
304         return this;
305     }
306
307     /**
308      * Accessor to {@link JavaType} of currently contextualized
309      * {@link ContextualDeserializer}, if any.
310      * This is sometimes useful for generic {@link JsonDeserializer}s that
311      * do not get passed (or do not retain) type information when being
312      * constructed: happens for example for deserializers constructed
313      * from annotations.
314      * 
315      * @since 2.5
316      *
317      * @return Type of {@link ContextualDeserializer} being contextualized,
318      *   if process is on-going; null if not.
319      */

320     public JavaType getContextualType() {
321         return (_currentType == null) ? null : _currentType.value();
322     }
323
324     /*
325     /**********************************************************
326     /* Public API, config setting accessors
327     /**********************************************************
328      */

329
330     /**
331      * Method for getting current {@link DeserializerFactory}.
332      */

333     public DeserializerFactory getFactory() {
334         return _factory;
335     }
336     
337     /**
338      * Convenience method for checking whether specified on/off
339      * feature is enabled
340      */

341     public final boolean isEnabled(DeserializationFeature feat) {
342         /* 03-Dec-2010, tatu: minor shortcut; since this is called quite often,
343          *   let's use a local copy of feature settings:
344          */

345         return (_featureFlags & feat.getMask()) != 0;
346     }
347
348     /**
349      * Bulk access method for getting the bit mask of all {@link DeserializationFeature}s
350      * that are enabled.
351      *
352      * @since 2.6
353      */

354     public final int getDeserializationFeatures() {
355         return _featureFlags;
356     }
357     
358     /**
359      * Bulk access method for checking that all features specified by
360      * mask are enabled.
361      * 
362      * @since 2.3
363      */

364     public final boolean hasDeserializationFeatures(int featureMask) {
365         return (_featureFlags & featureMask) == featureMask;
366     }
367
368     /**
369      * Bulk access method for checking that at least one of features specified by
370      * mask is enabled.
371      * 
372      * @since 2.6
373      */

374     public final boolean hasSomeOfFeatures(int featureMask) {
375         return (_featureFlags & featureMask) != 0;
376     }
377     
378     /**
379      * Method for accessing the currently active parser.
380      * May be different from the outermost parser
381      * when content is buffered.
382      *<p>
383      * Use of this method is discouraged: if code has direct access
384      * to the active parser, that should be used instead.
385      */

386     public final JsonParser getParser() { return _parser; }
387
388     public final Object findInjectableValue(Object valueId,
389             BeanProperty forProperty, Object beanInstance)
390         throws JsonMappingException
391     {
392         if (_injectableValues == null) {
393             reportBadDefinition(ClassUtil.classOf(valueId), String.format(
394 "No 'injectableValues' configured, cannot inject value with id [%s]", valueId));
395         }
396         return _injectableValues.findInjectableValue(valueId, this, forProperty, beanInstance);
397     }
398
399     /**
400      * Convenience method for accessing the default Base64 encoding
401      * used for decoding base64 encoded binary content.
402      * Same as calling:
403      *<pre>
404      *  getConfig().getBase64Variant();
405      *</pre>
406      */

407     public final Base64Variant getBase64Variant() {
408         return _config.getBase64Variant();
409     }
410
411     /**
412      * Convenience method, functionally equivalent to:
413      *<pre>
414      *  getConfig().getNodeFactory();
415      * </pre>
416      */

417     public final JsonNodeFactory getNodeFactory() {
418         return _config.getNodeFactory();
419     }
420
421     /*
422     /**********************************************************
423     /* Public API, pass-through to DeserializerCache
424     /**********************************************************
425      */

426
427     /**
428      * Method for checking whether we could find a deserializer
429      * for given type.
430      *
431      * @param type
432      * @since 2.3
433      */

434     public boolean hasValueDeserializerFor(JavaType type, AtomicReference<Throwable> cause) {
435         try {
436             return _cache.hasValueDeserializerFor(this, _factory, type);
437         } catch (JsonMappingException e) {
438             if (cause != null) {
439                 cause.set(e);
440             }
441         } catch (RuntimeException e) {
442             if (cause == null) { // earlier behavior
443                 throw e;
444             }
445             cause.set(e);
446         }
447         return false;
448     }
449     
450     /**
451      * Method for finding a value deserializer, and creating a contextual
452      * version if necessary, for value reached via specified property.
453      */

454     @SuppressWarnings("unchecked")
455     public final JsonDeserializer<Object> findContextualValueDeserializer(JavaType type,
456             BeanProperty prop) throws JsonMappingException
457     {
458         JsonDeserializer<Object> deser = _cache.findValueDeserializer(this, _factory, type);
459         if (deser != null) {
460             deser = (JsonDeserializer<Object>) handleSecondaryContextualization(deser, prop, type);
461         }
462         return deser;
463     }
464
465     /**
466      * Variant that will try to locate deserializer for current type, but without
467      * performing any contextualization (unlike {@link #findContextualValueDeserializer})
468      * or checking for need to create a {@link TypeDeserializer} (unlike
469      * {@link #findRootValueDeserializer(JavaType)}.
470      * This method is usually called from within {@link ResolvableDeserializer#resolve},
471      * and expectation is that caller then calls either
472      * {@link #handlePrimaryContextualization(JsonDeserializer, BeanProperty, JavaType)} or
473      * {@link #handleSecondaryContextualization(JsonDeserializer, BeanProperty, JavaType)} at a
474      * later point, as necessary.
475      *
476      * @since 2.5
477      */

478     public final JsonDeserializer<Object> findNonContextualValueDeserializer(JavaType type)
479         throws JsonMappingException
480     {
481         return _cache.findValueDeserializer(this, _factory, type);
482     }
483     
484     /**
485      * Method for finding a deserializer for root-level value.
486      */

487     @SuppressWarnings("unchecked")
488     public final JsonDeserializer<Object> findRootValueDeserializer(JavaType type)
489         throws JsonMappingException
490     {
491         JsonDeserializer<Object> deser = _cache.findValueDeserializer(this,
492                 _factory, type);
493         if (deser == null) { // can this occur?
494             return null;
495         }
496         deser = (JsonDeserializer<Object>) handleSecondaryContextualization(deser, null, type);
497         TypeDeserializer typeDeser = _factory.findTypeDeserializer(_config, type);
498         if (typeDeser != null) {
499             // important: contextualize to indicate this is for root value
500             typeDeser = typeDeser.forProperty(null);
501             return new TypeWrappedDeserializer(typeDeser, deser);
502         }
503         return deser;
504     }
505
506     /**
507      * Convenience method, functionally same as:
508      *<pre>
509      *  getDeserializerProvider().findKeyDeserializer(getConfig(), prop.getType(), prop);
510      *</pre>
511      */

512     public final KeyDeserializer findKeyDeserializer(JavaType keyType,
513             BeanProperty prop) throws JsonMappingException {
514         KeyDeserializer kd = _cache.findKeyDeserializer(this,
515                 _factory, keyType);
516         // Second: contextualize?
517         if (kd instanceof ContextualKeyDeserializer) {
518             kd = ((ContextualKeyDeserializer) kd).createContextual(this, prop);
519         }
520         return kd;
521     }
522     
523     /*
524     /**********************************************************
525     /* Public API, ObjectId handling
526     /**********************************************************
527      */

528
529     /**
530      * Method called to find and return entry corresponding to given
531      * Object Id: will add an entry if necessary, and never returns null
532      */

533     public abstract ReadableObjectId findObjectId(Object id, ObjectIdGenerator<?> generator, ObjectIdResolver resolver);
534
535     /**
536      * Method called to ensure that every object id encounter during processing
537      * are resolved.
538      * 
539      * @throws UnresolvedForwardReference
540      */

541     public abstract void checkUnresolvedObjectId()
542         throws UnresolvedForwardReference;
543
544     /*
545     /**********************************************************
546     /* Public API, type handling
547     /**********************************************************
548      */

549     
550     /**
551      * Convenience method, functionally equivalent to:
552      *<pre>
553      *  getConfig().constructType(cls);
554      * </pre>
555      */

556     public final JavaType constructType(Class<?> cls) {
557         return (cls == null) ? null : _config.constructType(cls);
558     }
559
560     /**
561      * Helper method that is to be used when resolving basic class name into
562      * Class instance, the reason being that it may be necessary to work around
563      * various ClassLoader limitations, as well as to handle primitive type
564      * signatures.
565      *
566      * @since 2.6
567      */

568     public Class<?> findClass(String className) throws ClassNotFoundException
569     {
570         // By default, delegate to ClassUtil: can be overridden with custom handling
571         return getTypeFactory().findClass(className);
572     }
573
574     /*
575     /**********************************************************
576     /* Public API, helper object recycling
577     /**********************************************************
578      */

579
580     /**
581      * Method that can be used to get access to a reusable ObjectBuffer,
582      * useful for efficiently constructing Object arrays and Lists.
583      * Note that leased buffers should be returned once deserializer
584      * is done, to allow for reuse during same round of deserialization.
585      */

586     public final ObjectBuffer leaseObjectBuffer()
587     {
588         ObjectBuffer buf = _objectBuffer;
589         if (buf == null) {
590             buf = new ObjectBuffer();
591         } else {
592             _objectBuffer = null;
593         }
594         return buf;
595     }
596
597     /**
598      * Method to call to return object buffer previously leased with
599      * {@link #leaseObjectBuffer}.
600      * 
601      * @param buf Returned object buffer
602      */

603     public final void returnObjectBuffer(ObjectBuffer buf)
604     {
605         /* Already have a reusable buffer? Let's retain bigger one
606          * (or if equal, favor newer one, shorter life-cycle)
607          */

608         if (_objectBuffer == null
609             || buf.initialCapacity() >= _objectBuffer.initialCapacity()) {
610             _objectBuffer = buf;
611         }
612     }
613
614     /**
615      * Method for accessing object useful for building arrays of
616      * primitive types (such as int[]).
617      */

618     public final ArrayBuilders getArrayBuilders()
619     {
620         if (_arrayBuilders == null) {
621             _arrayBuilders = new ArrayBuilders();
622         }
623         return _arrayBuilders;
624     }
625
626     /*
627     /**********************************************************
628     /* Extended API: handler instantiation
629     /**********************************************************
630      */

631
632     public abstract JsonDeserializer<Object> deserializerInstance(Annotated annotated,
633             Object deserDef)
634         throws JsonMappingException;
635
636     public abstract KeyDeserializer keyDeserializerInstance(Annotated annotated,
637             Object deserDef)
638         throws JsonMappingException;
639
640     /*
641     /**********************************************************
642     /* Extended API: resolving contextual deserializers; called
643     /* by structured deserializers for their value/component
644     /* deserializers
645     /**********************************************************
646      */

647
648     /**
649      * Method called for primary property deserializers (ones
650      * directly created to deserialize values of a POJO property),
651      * to handle details of resolving
652      * {@link ContextualDeserializer} with given property context.
653      * 
654      * @param prop Property for which the given primary deserializer is used; never null.
655      * 
656      * @since 2.5
657      */

658     public JsonDeserializer<?> handlePrimaryContextualization(JsonDeserializer<?> deser,
659             BeanProperty prop, JavaType type)
660         throws JsonMappingException
661     {
662         if (deser instanceof ContextualDeserializer) {
663             _currentType = new LinkedNode<JavaType>(type, _currentType);
664             try {
665                 deser = ((ContextualDeserializer) deser).createContextual(this, prop);
666             } finally {
667                 _currentType = _currentType.next();
668             }
669         }
670         return deser;
671     }
672
673     /**
674      * Method called for secondary property deserializers (ones
675      * NOT directly created to deal with an annotatable POJO property,
676      * but instead created as a component -- such as value deserializers
677      * for structured types, or deserializers for root values)
678      * to handle details of resolving
679      * {@link ContextualDeserializer} with given property context.
680      * Given that these deserializers are not directly related to given property
681      * (or, in case of root value property, to any property), annotations
682      * accessible may or may not be relevant.
683      * 
684      * @param prop Property for which deserializer is used, if any; null
685      *    when deserializing root values
686      * 
687      * @since 2.5
688      */

689     public JsonDeserializer<?> handleSecondaryContextualization(JsonDeserializer<?> deser,
690             BeanProperty prop, JavaType type)
691         throws JsonMappingException
692     {
693         if (deser instanceof ContextualDeserializer) {
694             _currentType = new LinkedNode<JavaType>(type, _currentType);
695             try {
696                 deser = ((ContextualDeserializer) deser).createContextual(this, prop);
697             } finally {
698                 _currentType = _currentType.next();
699             }
700         }
701         return deser;
702     }
703
704     /*
705     /**********************************************************
706     /* Parsing methods that may use reusable/-cyclable objects
707     /**********************************************************
708      */

709
710     /**
711      * Convenience method for parsing a Date from given String, using
712      * currently configured date format (accessed using
713      * {@link DeserializationConfig#getDateFormat()}).
714      *<p>
715      * Implementation will handle thread-safety issues related to
716      * date formats such that first time this method is called,
717      * date format is cloned, and cloned instance will be retained
718      * for use during this deserialization round.
719      */

720     public Date parseDate(String dateStr) throws IllegalArgumentException
721     {
722         try {
723             DateFormat df = getDateFormat();
724             return df.parse(dateStr);
725         } catch (ParseException e) {
726             throw new IllegalArgumentException(String.format(
727                     "Failed to parse Date value '%s': %s", dateStr,
728                     ClassUtil.exceptionMessage(e)));
729         }
730     }
731
732     /**
733      * Convenience method for constructing Calendar instance set
734      * to specified time, to be modified and used by caller.
735      */

736     public Calendar constructCalendar(Date d) {
737         // 08-Jan-2008, tatu: not optimal, but should work for the most part; let's revise as needed.
738         Calendar c = Calendar.getInstance(getTimeZone());
739         c.setTime(d);
740         return c;
741     }
742
743     /*
744     /**********************************************************
745     /* Convenience methods for reading parsed values
746     /**********************************************************
747      */

748
749     /**
750      * Convenience method that may be used by composite or container deserializers,
751      * for reading one-off values contained (for sequences, it is more efficient
752      * to actually fetch deserializer once for the whole collection).
753      *<p>
754      * NOTE: when deserializing values of properties contained in composite types,
755      * rather use {@link #readPropertyValue(JsonParser, BeanProperty, Class)};
756      * this method does not allow use of contextual annotations.
757      * 
758      * @since 2.4
759      */

760     public <T> T readValue(JsonParser p, Class<T> type) throws IOException {
761         return readValue(p, getTypeFactory().constructType(type));
762     }
763
764     /**
765      * @since 2.4
766      */

767     @SuppressWarnings("unchecked")
768     public <T> T readValue(JsonParser p, JavaType type) throws IOException {
769         JsonDeserializer<Object> deser = findRootValueDeserializer(type);
770         if (deser == null) {
771             reportBadDefinition(type,
772                     "Could not find JsonDeserializer for type "+ClassUtil.getTypeDescription(type));
773         }
774         return (T) deser.deserialize(p, this);
775     }
776
777     /**
778      * Convenience method that may be used by composite or container deserializers,
779      * for reading one-off values for the composite type, taking into account
780      * annotations that the property (passed to this method -- usually property that
781      * has custom serializer that called this method) has.
782      * 
783      * @since 2.4
784      */

785     public <T> T readPropertyValue(JsonParser p, BeanProperty prop, Class<T> type) throws IOException {
786         return readPropertyValue(p, prop, getTypeFactory().constructType(type));
787     }
788
789     /**
790      * @since 2.4
791      */

792     @SuppressWarnings("unchecked")
793     public <T> T readPropertyValue(JsonParser p, BeanProperty prop, JavaType type) throws IOException {
794         JsonDeserializer<Object> deser = findContextualValueDeserializer(type, prop);
795         if (deser == null) {
796             return reportBadDefinition(type, String.format(
797                     "Could not find JsonDeserializer for type %s (via property %s)",
798                     ClassUtil.getTypeDescription(type), ClassUtil.nameOf(prop)));
799         }
800         return (T) deser.deserialize(p, this);
801     }
802
803     /**
804      * @since 2.10
805      */

806     public JsonNode readTree(JsonParser p) throws IOException {
807         JsonToken t = p.currentToken();
808         if (t == null) {
809             t = p.nextToken();
810             if (t == null) {
811                 return getNodeFactory().missingNode();
812             }
813         }
814         if (t == JsonToken.VALUE_NULL) {
815             return getNodeFactory().nullNode();
816         }
817         return (JsonNode) findRootValueDeserializer(_config.constructType(JsonNode.class))
818                 .deserialize(p, this);
819     }
820
821     /*
822     /**********************************************************
823     /* Methods for problem handling
824     /**********************************************************
825      */

826
827     /**
828      * Method that deserializers should call if they encounter an unrecognized
829      * property (and once that is not explicitly designed as ignorable), to
830      * inform possibly configured {@link DeserializationProblemHandler}s and
831      * let it handle the problem.
832      * 
833      * @return True if there was a configured problem handler that was able to handle the
834      *   problem
835      */

836     public boolean handleUnknownProperty(JsonParser p, JsonDeserializer<?> deser,
837             Object instanceOrClass, String propName)
838         throws IOException
839     {
840         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
841         while (h != null) {
842             // Can bail out if it's handled
843             if (h.value().handleUnknownProperty(this, p, deser, instanceOrClass, propName)) {
844                 return true;
845             }
846             h = h.next();
847         }
848         // Nope, not handled. Potentially that's a problem...
849         if (!isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) {
850             p.skipChildren();
851             return true;
852         }
853         // Do we know properties that are expected instead?
854         Collection<Object> propIds = (deser == null) ? null : deser.getKnownPropertyNames();
855         throw UnrecognizedPropertyException.from(_parser,
856                 instanceOrClass, propName, propIds);
857     }
858
859     /**
860      * Method that deserializers should call if they encounter a String value
861      * that cannot be converted to expected key of a {@link java.util.Map}
862      * valued property.
863      * Default implementation will try to call {@link DeserializationProblemHandler#handleWeirdNumberValue}
864      * on configured handlers, if any, to allow for recovery; if recovery does not
865      * succeed, will throw {@link InvalidFormatException} with given message.
866      *
867      * @param keyClass Expected type for key
868      * @param keyValue String value from which to deserialize key
869      * @param msg Error message template caller wants to use if exception is to be thrown
870      * @param msgArgs Optional arguments to use for message, if any
871      *
872      * @return Key value to use
873      *
874      * @throws IOException To indicate unrecoverable problem, usually based on <code>msg</code>
875      * 
876      * @since 2.8
877      */

878     public Object handleWeirdKey(Class<?> keyClass, String keyValue,
879             String msg, Object... msgArgs)
880         throws IOException
881     {
882         // but if not handled, just throw exception
883         msg = _format(msg, msgArgs);
884         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
885         while (h != null) {
886             // Can bail out if it's handled
887             Object key = h.value().handleWeirdKey(this, keyClass, keyValue, msg);
888             if (key != DeserializationProblemHandler.NOT_HANDLED) {
889                 // Sanity check for broken handlers, otherwise nasty to debug:
890                 if ((key == null) || keyClass.isInstance(key)) {
891                     return key;
892                 }
893                 throw weirdStringException(keyValue, keyClass, String.format(
894                         "DeserializationProblemHandler.handleWeirdStringValue() for type %s returned value of type %s",
895                         ClassUtil.getClassDescription(keyClass),
896                         ClassUtil.getClassDescription(key)
897                 ));
898             }
899             h = h.next();
900         }
901         throw weirdKeyException(keyClass, keyValue, msg);
902     }
903
904     /**
905      * Method that deserializers should call if they encounter a String value
906      * that cannot be converted to target property type, in cases where some
907      * String values could be acceptable (either with different settings,
908      * or different value).
909      * Default implementation will try to call {@link DeserializationProblemHandler#handleWeirdStringValue}
910      * on configured handlers, if any, to allow for recovery; if recovery does not
911      * succeed, will throw {@link InvalidFormatException} with given message.
912      *
913      * @param targetClass Type of property into which incoming number should be converted
914      * @param value String value from which to deserialize property value
915      * @param msg Error message template caller wants to use if exception is to be thrown
916      * @param msgArgs Optional arguments to use for message, if any
917      *
918      * @return Property value to use
919      *
920      * @throws IOException To indicate unrecoverable problem, usually based on <code>msg</code>
921      * 
922      * @since 2.8
923      */

924     public Object handleWeirdStringValue(Class<?> targetClass, String value,
925             String msg, Object... msgArgs)
926         throws IOException
927     {
928         // but if not handled, just throw exception
929         msg = _format(msg, msgArgs);
930         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
931         while (h != null) {
932             // Can bail out if it's handled
933             Object instance = h.value().handleWeirdStringValue(this, targetClass, value, msg);
934             if (instance != DeserializationProblemHandler.NOT_HANDLED) {
935                 // Sanity check for broken handlers, otherwise nasty to debug:
936                 if (_isCompatible(targetClass, instance)) {
937                     return instance;
938                 }
939                 throw weirdStringException(value, targetClass, String.format(
940                         "DeserializationProblemHandler.handleWeirdStringValue() for type %s returned value of type %s",
941                         ClassUtil.getClassDescription(targetClass),
942                         ClassUtil.getClassDescription(instance)
943                 ));
944             }
945             h = h.next();
946         }
947         throw weirdStringException(value, targetClass, msg);
948     }
949
950     /**
951      * Method that deserializers should call if they encounter a numeric value
952      * that cannot be converted to target property type, in cases where some
953      * numeric values could be acceptable (either with different settings,
954      * or different numeric value).
955      * Default implementation will try to call {@link DeserializationProblemHandler#handleWeirdNumberValue}
956      * on configured handlers, if any, to allow for recovery; if recovery does not
957      * succeed, will throw {@link InvalidFormatException} with given message.
958      *
959      * @param targetClass Type of property into which incoming number should be converted
960      * @param value Number value from which to deserialize property value
961      * @param msg Error message template caller wants to use if exception is to be thrown
962      * @param msgArgs Optional arguments to use for message, if any
963      *
964      * @return Property value to use
965      *
966      * @throws IOException To indicate unrecoverable problem, usually based on <code>msg</code>
967      * 
968      * @since 2.8
969      */

970     public Object handleWeirdNumberValue(Class<?> targetClass, Number value,
971             String msg, Object... msgArgs)
972         throws IOException
973     {
974         msg = _format(msg, msgArgs);
975         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
976         while (h != null) {
977             // Can bail out if it's handled
978             Object key = h.value().handleWeirdNumberValue(this, targetClass, value, msg);
979             if (key != DeserializationProblemHandler.NOT_HANDLED) {
980                 // Sanity check for broken handlers, otherwise nasty to debug:
981                 if (_isCompatible(targetClass, key)) {
982                     return key;
983                 }
984                 throw weirdNumberException(value, targetClass, _format(
985                         "DeserializationProblemHandler.handleWeirdNumberValue() for type %s returned value of type %s",
986                         ClassUtil.getClassDescription(targetClass),
987                         ClassUtil.getClassDescription(key)
988                 ));
989             }
990             h = h.next();
991         }
992         throw weirdNumberException(value, targetClass, msg);
993     }
994
995     public Object handleWeirdNativeValue(JavaType targetType, Object badValue,
996             JsonParser p)
997         throws IOException
998     {
999         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1000         final Class<?> raw = targetType.getRawClass();
1001         for (; h != null; h = h.next()) {
1002             // Can bail out if it's handled
1003             Object goodValue = h.value().handleWeirdNativeValue(this, targetType, badValue, p);
1004             if (goodValue != DeserializationProblemHandler.NOT_HANDLED) {
1005                 // Sanity check for broken handlers, otherwise nasty to debug:
1006                 if ((goodValue == null) || raw.isInstance(goodValue)) {
1007                     return goodValue;
1008                 }
1009                 throw JsonMappingException.from(p, _format(
1010 "DeserializationProblemHandler.handleWeirdNativeValue() for type %s returned value of type %s",
1011                     ClassUtil.getClassDescription(targetType),
1012                     ClassUtil.getClassDescription(goodValue)
1013                 ));
1014             }
1015         }
1016         throw weirdNativeValueException(badValue, raw);
1017     }
1018
1019     /**
1020      * Method that deserializers should call if they fail to instantiate value
1021      * due to lack of viable instantiator (usually creator, that is, constructor
1022      * or static factory method). Method should be called at point where value
1023      * has not been decoded, so that handler has a chance to handle decoding
1024      * using alternate mechanism, and handle underlying content (possibly by
1025      * just skipping it) to keep input state valid
1026      *
1027      * @param instClass Type that was to be instantiated
1028      * @param valueInst (optional) Value instantiator to be used, if any; null if type does not
1029      *    use one for instantiation (custom deserialiers don't; standard POJO deserializer does)
1030      * @param p Parser that points to the JSON value to decode
1031      *
1032      * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
1033      *
1034      * @since 2.9 (2.8 had alternate that did not take <code>ValueInstantiator</code>)
1035      */

1036     @SuppressWarnings("resource")
1037     public Object handleMissingInstantiator(Class<?> instClass, ValueInstantiator valueInst,
1038             JsonParser p, String msg, Object... msgArgs)
1039         throws IOException
1040     {
1041         if (p == null) {
1042             p = getParser();
1043         }
1044         msg = _format(msg, msgArgs);
1045         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1046         while (h != null) {
1047             // Can bail out if it's handled
1048             Object instance = h.value().handleMissingInstantiator(this,
1049                     instClass, valueInst, p, msg);
1050             if (instance != DeserializationProblemHandler.NOT_HANDLED) {
1051                 // Sanity check for broken handlers, otherwise nasty to debug:
1052                 if (_isCompatible(instClass, instance)) {
1053                     return instance;
1054                 }
1055                 reportBadDefinition(constructType(instClass), String.format(
1056 "DeserializationProblemHandler.handleMissingInstantiator() for type %s returned value of type %s",
1057                     ClassUtil.getClassDescription(instClass),
1058                     ClassUtil.getClassDescription((instance)
1059                 )));
1060             }
1061             h = h.next();
1062         }
1063
1064         // 16-Oct-2016, tatu: This is either a definition problem (if no applicable creator
1065         //   exists), or input mismatch problem (otherwise) since none of existing creators
1066         //   match with token.
1067         // 24-Oct-2019, tatu: Further, as per [databind#2522], passing `null` ValueInstantiator
1068         //   should simply trigger definition problem
1069         if (valueInst == null ) {
1070             msg = String.format("Cannot construct instance of %s: %s",
1071                     ClassUtil.nameOf(instClass), msg);
1072             return reportBadDefinition(instClass, msg);
1073         }
1074         if (!valueInst.canInstantiate()) {
1075             msg = String.format("Cannot construct instance of %s (no Creators, like default constructor, exist): %s",
1076                     ClassUtil.nameOf(instClass), msg);
1077             return reportBadDefinition(instClass, msg);
1078         }
1079         msg = String.format("Cannot construct instance of %s (although at least one Creator exists): %s",
1080                 ClassUtil.nameOf(instClass), msg);
1081         return reportInputMismatch(instClass, msg);
1082     }
1083
1084     /**
1085      * Method that deserializers should call if they fail to instantiate value
1086      * due to an exception that was thrown by constructor (or other mechanism used
1087      * to create instances).
1088      * Default implementation will try to call {@link DeserializationProblemHandler#handleInstantiationProblem}
1089      * on configured handlers, if any, to allow for recovery; if recovery does not
1090      * succeed, will throw exception constructed with {@link #instantiationException}.
1091      *
1092      * @param instClass Type that was to be instantiated
1093      * @param argument (optional) Argument that was passed to constructor or equivalent
1094      *    instantiator; often a {@link java.lang.String}.
1095      * @param t Exception that caused failure
1096      *
1097      * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
1098      *
1099      * @since 2.8
1100      */

1101     public Object handleInstantiationProblem(Class<?> instClass, Object argument,
1102             Throwable t)
1103         throws IOException
1104     {
1105         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1106         while (h != null) {
1107             // Can bail out if it's handled
1108             Object instance = h.value().handleInstantiationProblem(this, instClass, argument, t);
1109             if (instance != DeserializationProblemHandler.NOT_HANDLED) {
1110                 // Sanity check for broken handlers, otherwise nasty to debug:
1111                 if (_isCompatible(instClass, instance)) {
1112                     return instance;
1113                 }
1114                 reportBadDefinition(constructType(instClass), String.format(
1115 "DeserializationProblemHandler.handleInstantiationProblem() for type %s returned value of type %s",
1116                     ClassUtil.getClassDescription(instClass),
1117                     ClassUtil.classNameOf(instance)
1118                 ));
1119             }
1120             h = h.next();
1121         }
1122         // 18-May-2016, tatu: Only wrap if not already a valid type to throw
1123         ClassUtil.throwIfIOE(t);
1124         // [databind#2164]: but see if wrapping is desired
1125         if (!isEnabled(DeserializationFeature.WRAP_EXCEPTIONS)) {
1126             ClassUtil.throwIfRTE(t);
1127         }
1128         throw instantiationException(instClass, t);
1129     }
1130
1131     /**
1132      * Method that deserializers should call if the first token of the value to
1133      * deserialize is of unexpected type (that is, type of token that deserializer
1134      * cannot handle). This could occur, for example, if a Number deserializer
1135      * encounter {@link JsonToken#START_ARRAY} instead of
1136      * {@link JsonToken#VALUE_NUMBER_INT} or {@link JsonToken#VALUE_NUMBER_FLOAT}.
1137      * 
1138      * @param instClass Type that was to be instantiated
1139      * @param p Parser that points to the JSON value to decode
1140      *
1141      * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
1142      *
1143      * @since 2.8
1144      */

1145     public Object handleUnexpectedToken(Class<?> instClass, JsonParser p)
1146         throws IOException
1147     {
1148         return handleUnexpectedToken(constructType(instClass), p.getCurrentToken(), p, null);
1149     }
1150
1151     /**
1152      * Method that deserializers should call if the first token of the value to
1153      * deserialize is of unexpected type (that is, type of token that deserializer
1154      * cannot handle). This could occur, for example, if a Number deserializer
1155      * encounter {@link JsonToken#START_ARRAY} instead of
1156      * {@link JsonToken#VALUE_NUMBER_INT} or {@link JsonToken#VALUE_NUMBER_FLOAT}.
1157      * 
1158      * @param instClass Type that was to be instantiated
1159      * @param t Token encountered that does match expected
1160      * @param p Parser that points to the JSON value to decode
1161      *
1162      * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
1163      *
1164      * @since 2.8
1165      */

1166     public Object handleUnexpectedToken(Class<?> instClass, JsonToken t,
1167             JsonParser p, String msg, Object... msgArgs)
1168         throws IOException
1169     {
1170         return handleUnexpectedToken(constructType(instClass), t, p, msg, msgArgs);
1171     }
1172
1173     /**
1174      * Method that deserializers should call if the first token of the value to
1175      * deserialize is of unexpected type (that is, type of token that deserializer
1176      * cannot handle). This could occur, for example, if a Number deserializer
1177      * encounter {@link JsonToken#START_ARRAY} instead of
1178      * {@link JsonToken#VALUE_NUMBER_INT} or {@link JsonToken#VALUE_NUMBER_FLOAT}.
1179      *
1180      * @param targetType Type that was to be instantiated
1181      * @param p Parser that points to the JSON value to decode
1182      *
1183      * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
1184      *
1185      * @since 2.10
1186      */

1187     public Object handleUnexpectedToken(JavaType targetType, JsonParser p)
1188         throws IOException
1189     {
1190         return handleUnexpectedToken(targetType, p.getCurrentToken(), p, null);
1191     }
1192
1193     /**
1194      * Method that deserializers should call if the first token of the value to
1195      * deserialize is of unexpected type (that is, type of token that deserializer
1196      * cannot handle). This could occur, for example, if a Number deserializer
1197      * encounter {@link JsonToken#START_ARRAY} instead of
1198      * {@link JsonToken#VALUE_NUMBER_INT} or {@link JsonToken#VALUE_NUMBER_FLOAT}.
1199      *
1200      * @param targetType Type that was to be instantiated
1201      * @param t Token encountered that does not match expected
1202      * @param p Parser that points to the JSON value to decode
1203      *
1204      * @return Object that should be constructed, if any; has to be of type <code>instClass</code>
1205      *
1206      * @since 2.10
1207      */

1208     public Object handleUnexpectedToken(JavaType targetType, JsonToken t,
1209             JsonParser p, String msg, Object... msgArgs)
1210         throws IOException
1211     {
1212         msg = _format(msg, msgArgs);
1213         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1214         while (h != null) {
1215             Object instance = h.value().handleUnexpectedToken(this,
1216                     targetType, t, p, msg);
1217             if (instance != DeserializationProblemHandler.NOT_HANDLED) {
1218                 if (_isCompatible(targetType.getRawClass(), instance)) {
1219                     return instance;
1220                 }
1221                 reportBadDefinition(targetType, String.format(
1222                         "DeserializationProblemHandler.handleUnexpectedToken() for type %s returned value of type %s",
1223                         ClassUtil.getClassDescription(targetType),
1224                         ClassUtil.classNameOf(instance)
1225                 ));
1226             }
1227             h = h.next();
1228         }
1229         if (msg == null) {
1230             if (t == null) {
1231                 msg = String.format("Unexpected end-of-input when binding data into %s",
1232                         ClassUtil.getTypeDescription(targetType));
1233             } else {
1234                 msg = String.format("Cannot deserialize instance of %s out of %s token",
1235                         ClassUtil.getTypeDescription(targetType), t);
1236             }
1237         }
1238         // 18-Jun-2020, tatu: to resolve [databind#2770], force access to `getText()` for scalars
1239         if ((t != null) && t.isScalarValue()) {
1240             p.getText();
1241         }
1242         reportInputMismatch(targetType, msg);
1243         return null// never gets here
1244     }
1245
1246     /**
1247      * Method that deserializers should call if they encounter a type id
1248      * (for polymorphic deserialization) that cannot be resolved to an
1249      * actual type; usually since there is no mapping defined.
1250      * Default implementation will try to call {@link DeserializationProblemHandler#handleUnknownTypeId}
1251      * on configured handlers, if any, to allow for recovery; if recovery does not
1252      * succeed, will throw exception constructed with {@link #invalidTypeIdException}.
1253      *
1254      * @param baseType Base type from which resolution starts
1255      * @param id Type id that could not be converted
1256      * @param extraDesc Additional problem description to add to default exception message,
1257      *    if resolution fails.
1258      *
1259      * @return {@link JavaType} that id resolves to
1260      *
1261      * @throws IOException To indicate unrecoverable problem, if resolution cannot
1262      *    be made to work
1263      *
1264      * @since 2.8
1265      */

1266     public JavaType handleUnknownTypeId(JavaType baseType, String id,
1267             TypeIdResolver idResolver, String extraDesc) throws IOException
1268     {
1269         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1270         while (h != null) {
1271             // Can bail out if it's handled
1272             JavaType type = h.value().handleUnknownTypeId(this, baseType, id, idResolver, extraDesc);
1273             if (type != null) {
1274                 if (type.hasRawClass(Void.class)) {
1275                     return null;
1276                 }
1277                 // But ensure there's type compatibility
1278                 if (type.isTypeOrSubTypeOf(baseType.getRawClass())) {
1279                     return type;
1280                 }
1281                 throw invalidTypeIdException(baseType, id,
1282                         "problem handler tried to resolve into non-subtype: "+
1283                                 ClassUtil.getTypeDescription(type));
1284             }
1285             h = h.next();
1286         }
1287         // 24-May-2016, tatu: Actually we may still not want to fail quite yet
1288         if (!isEnabled(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE)) {
1289             return null;
1290         }
1291         throw invalidTypeIdException(baseType, id, extraDesc);
1292     }
1293
1294     /**
1295      * @since 2.9
1296      */

1297     public JavaType handleMissingTypeId(JavaType baseType,
1298             TypeIdResolver idResolver, String extraDesc) throws IOException
1299     {
1300         LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
1301         while (h != null) {
1302             // Can bail out if it's handled
1303             JavaType type = h.value().handleMissingTypeId(this, baseType, idResolver, extraDesc);
1304             if (type != null) {
1305                 if (type.hasRawClass(Void.class)) {
1306                     return null;
1307                 }
1308                 // But ensure there's type compatibility
1309                 if (type.isTypeOrSubTypeOf(baseType.getRawClass())) {
1310                     return type;
1311                 }
1312                 throw invalidTypeIdException(baseType, null,
1313                         "problem handler tried to resolve into non-subtype: "+
1314                                 ClassUtil.getTypeDescription(type));
1315             }
1316             h = h.next();
1317         }
1318         // 09-Mar-2017, tatu: We may want to consider yet another feature at some
1319         //    point to allow returning `null`... but that seems bit risky for now
1320 //        if (!isEnabled(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE)) {
1321 //            return null;
1322 //        }
1323         throw missingTypeIdException(baseType, extraDesc);
1324     }
1325
1326     /**
1327      * Method that deserializer may call if it is called to do an update ("merge")
1328      * but deserializer operates on a non-mergeable type. Although this should
1329      * usually be caught earlier, sometimes it may only be caught during operation
1330      * and if so this is the method to call.
1331      * Note that if {@link MapperFeature#IGNORE_MERGE_FOR_UNMERGEABLE} is enabled,
1332      * this method will simply return null; otherwise {@link InvalidDefinitionException}
1333      * will be thrown.
1334      *
1335      * @since 2.10
1336      */

1337     public void handleBadMerge(JsonDeserializer<?> deser) throws JsonMappingException
1338     {
1339         if (!isEnabled(MapperFeature.IGNORE_MERGE_FOR_UNMERGEABLE)) {
1340             JavaType type = constructType(deser.handledType());
1341             String msg = String.format("Invalid configuration: values of type %s cannot be merged",
1342                     ClassUtil.getTypeDescription(type));
1343             throw InvalidDefinitionException.from(getParser(), msg, type);
1344         }
1345     }
1346
1347     /**
1348      * @since 2.9.2
1349      */

1350     protected boolean _isCompatible(Class<?> target, Object value)
1351     {
1352         if ((value == null) || target.isInstance(value)) {
1353             return true;
1354         }
1355         // [databind#1767]: Make sure to allow wrappers for primitive fields
1356         return target.isPrimitive()
1357                 && ClassUtil.wrapperType(target).isInstance(value);
1358     }
1359
1360     /*
1361     /**********************************************************
1362     /* Methods for problem reporting, in cases where recovery
1363     /* is not considered possible: input problem
1364     /**********************************************************
1365      */

1366
1367     /**
1368      * Method for deserializers to call 
1369      * when the token encountered was of type different than what <b>should</b>
1370      * be seen at that position, usually within a sequence of expected tokens.
1371      * Note that this method will throw a {@link JsonMappingException} and no
1372      * recovery is attempted (via {@link DeserializationProblemHandler}, as
1373      * problem is considered to be difficult to recover from, in general.
1374      * 
1375      * @since 2.9
1376      */

1377     public void reportWrongTokenException(JsonDeserializer<?> deser,
1378             JsonToken expToken, String msg, Object... msgArgs)
1379         throws JsonMappingException
1380     {
1381         msg = _format(msg, msgArgs);
1382         throw wrongTokenException(getParser(), deser.handledType(), expToken, msg);
1383     }
1384     
1385     /**
1386      * Method for deserializers to call 
1387      * when the token encountered was of type different than what <b>should</b>
1388      * be seen at that position, usually within a sequence of expected tokens.
1389      * Note that this method will throw a {@link JsonMappingException} and no
1390      * recovery is attempted (via {@link DeserializationProblemHandler}, as
1391      * problem is considered to be difficult to recover from, in general.
1392      * 
1393      * @since 2.9
1394      */

1395     public void reportWrongTokenException(JavaType targetType,
1396             JsonToken expToken, String msg, Object... msgArgs)
1397         throws JsonMappingException
1398     {
1399         msg = _format(msg, msgArgs);
1400         throw wrongTokenException(getParser(), targetType, expToken, msg);
1401     }
1402
1403     /**
1404      * Method for deserializers to call 
1405      * when the token encountered was of type different than what <b>should</b>
1406      * be seen at that position, usually within a sequence of expected tokens.
1407      * Note that this method will throw a {@link JsonMappingException} and no
1408      * recovery is attempted (via {@link DeserializationProblemHandler}, as
1409      * problem is considered to be difficult to recover from, in general.
1410      * 
1411      * @since 2.9
1412      */

1413     public void reportWrongTokenException(Class<?> targetType,
1414             JsonToken expToken, String msg, Object... msgArgs)
1415         throws JsonMappingException
1416     {
1417         msg = _format(msg, msgArgs);
1418         throw wrongTokenException(getParser(), targetType, expToken, msg);
1419     }
1420
1421     /**
1422      * @since 2.8
1423      */

1424     public <T> T reportUnresolvedObjectId(ObjectIdReader oidReader, Object bean)
1425         throws JsonMappingException
1426     {
1427         String msg = String.format("No Object Id found for an instance of %s, to assign to property '%s'",
1428                 ClassUtil.classNameOf(bean), oidReader.propertyName);
1429         return reportInputMismatch(oidReader.idProperty, msg);
1430     }
1431
1432     /**
1433      * Helper method used to indicate a problem with input in cases where more
1434      * specific <code>reportXxx()</code> method was not available.
1435      *
1436      * @since 2.9
1437      */

1438     public <T> T reportInputMismatch(JsonDeserializer<?> src,
1439             String msg, Object... msgArgs) throws JsonMappingException
1440     {
1441         msg = _format(msg, msgArgs);
1442         throw MismatchedInputException.from(getParser(), src.handledType(), msg);
1443     }
1444
1445     /**
1446      * Helper method used to indicate a problem with input in cases where more
1447      * specific <code>reportXxx()</code> method was not available.
1448      *
1449      * @since 2.9
1450      */

1451     public <T> T reportInputMismatch(Class<?> targetType,
1452             String msg, Object... msgArgs) throws JsonMappingException
1453     {
1454         msg = _format(msg, msgArgs);
1455         throw MismatchedInputException.from(getParser(), targetType, msg);
1456     }
1457
1458     /**
1459      * Helper method used to indicate a problem with input in cases where more
1460      * specific <code>reportXxx()</code> method was not available.
1461      *
1462      * @since 2.9
1463      */

1464     public <T> T reportInputMismatch(JavaType targetType,
1465             String msg, Object... msgArgs) throws JsonMappingException
1466     {
1467         msg = _format(msg, msgArgs);
1468         throw MismatchedInputException.from(getParser(), targetType, msg);
1469     }
1470
1471     /**
1472      * Helper method used to indicate a problem with input in cases where more
1473      * specific <code>reportXxx()</code> method was not available.
1474      *
1475      * @since 2.9
1476      */

1477     public <T> T reportInputMismatch(BeanProperty prop,
1478             String msg, Object... msgArgs) throws JsonMappingException
1479     {
1480         msg = _format(msg, msgArgs);
1481         JavaType type = (prop == null) ? null : prop.getType();
1482         final MismatchedInputException e = MismatchedInputException.from(getParser(), type, msg);
1483         // [databind#2357]: Include property name, if we have it
1484         if (prop != null) {
1485             AnnotatedMember member = prop.getMember();
1486             if (member != null) {
1487                 e.prependPath(member.getDeclaringClass(), prop.getName());
1488             }
1489         }
1490         throw e;
1491     }
1492
1493     /**
1494      * Helper method used to indicate a problem with input in cases where more
1495      * specific <code>reportXxx()</code> method was not available.
1496      *
1497      * @since 2.10
1498      */

1499     public <T> T reportPropertyInputMismatch(Class<?> targetType, String propertyName,
1500             String msg, Object... msgArgs) throws JsonMappingException
1501     {
1502         msg = _format(msg, msgArgs);
1503         MismatchedInputException e = MismatchedInputException.from(getParser(), targetType, msg);
1504         if (propertyName != null) {
1505             e.prependPath(targetType, propertyName);
1506         }
1507         throw e;
1508     }
1509
1510     /**
1511      * Helper method used to indicate a problem with input in cases where more
1512      * specific <code>reportXxx()</code> method was not available.
1513      *
1514      * @since 2.10
1515      */

1516     public <T> T reportPropertyInputMismatch(JavaType targetType, String propertyName,
1517             String msg, Object... msgArgs) throws JsonMappingException
1518     {
1519         return reportPropertyInputMismatch(targetType.getRawClass(), propertyName, msg, msgArgs);
1520     }    
1521
1522     public <T> T reportTrailingTokens(Class<?> targetType,
1523             JsonParser p, JsonToken trailingToken) throws JsonMappingException
1524     {
1525         throw MismatchedInputException.from(p, targetType, String.format(
1526 "Trailing token (of type %s) found after value (bound as %s): not allowed as per `DeserializationFeature.FAIL_ON_TRAILING_TOKENS`",
1527 trailingToken, ClassUtil.nameOf(targetType)
1528                 ));
1529     }
1530
1531     @Deprecated // since 2.9
1532     public void reportWrongTokenException(JsonParser p,
1533             JsonToken expToken, String msg, Object... msgArgs)
1534         throws JsonMappingException
1535     {
1536         msg = _format(msg, msgArgs);
1537         throw wrongTokenException(p, expToken, msg);
1538     }
1539     
1540     /**
1541      * Helper method for reporting a problem with unhandled unknown property.
1542      * 
1543      * @param instanceOrClass Either value being populated (if one has been
1544      *   instantiated), or Class that indicates type that would be (or
1545      *   have been) instantiated
1546      * @param deser Deserializer that had the problem, if called by deserializer
1547      *   (or on behalf of one)
1548      *
1549      * @deprecated Since 2.8 call {@link #handleUnknownProperty} instead
1550      */

1551     @Deprecated
1552     public void reportUnknownProperty(Object instanceOrClass, String fieldName,
1553             JsonDeserializer<?> deser)
1554         throws JsonMappingException
1555     {
1556         if (isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) {
1557             // Do we know properties that are expected instead?
1558             Collection<Object> propIds = (deser == null) ? null : deser.getKnownPropertyNames();
1559             throw UnrecognizedPropertyException.from(_parser,
1560                     instanceOrClass, fieldName, propIds);
1561         }
1562     }
1563
1564     /**
1565      * @since 2.8
1566      *
1567      * @deprecated Since 2.9: not clear this ever occurs
1568      */

1569     @Deprecated // since 2.9
1570     public void reportMissingContent(String msg, Object... msgArgs) throws JsonMappingException {
1571         throw MismatchedInputException.from(getParser(), (JavaType) null"No content to map due to end-of-input");
1572     }
1573
1574     /*
1575     /**********************************************************
1576     /* Methods for problem reporting, in cases where recovery
1577     /* is not considered possible: POJO definition problems
1578     /**********************************************************
1579      */

1580     
1581     /**
1582      * Helper method called to indicate problem in POJO (serialization) definitions or settings
1583      * regarding specific Java type, unrelated to actual JSON content to map.
1584      * Default behavior is to construct and throw a {@link JsonMappingException}.
1585      *
1586      * @since 2.9
1587      */

1588     public <T> T reportBadTypeDefinition(BeanDescription bean,
1589             String msg, Object... msgArgs) throws JsonMappingException {
1590         msg = _format(msg, msgArgs);
1591         String beanDesc = ClassUtil.nameOf(bean.getBeanClass());
1592         msg = String.format("Invalid type definition for type %s: %s", beanDesc, msg);
1593         throw InvalidDefinitionException.from(_parser, msg, bean, null);
1594     }
1595
1596     /**
1597      * Helper method called to indicate problem in POJO (serialization) definitions or settings
1598      * regarding specific property (of a type), unrelated to actual JSON content to map.
1599      * Default behavior is to construct and throw a {@link JsonMappingException}.
1600      *
1601      * @since 2.9
1602      */

1603     public <T> T reportBadPropertyDefinition(BeanDescription bean, BeanPropertyDefinition prop,
1604             String msg, Object... msgArgs) throws JsonMappingException {
1605         msg = _format(msg, msgArgs);
1606         String propName = ClassUtil.nameOf(prop);
1607         String beanDesc = ClassUtil.nameOf(bean.getBeanClass());
1608         msg = String.format("Invalid definition for property %s (of type %s): %s",
1609                 propName, beanDesc, msg);
1610         throw InvalidDefinitionException.from(_parser, msg, bean, prop);
1611     }
1612
1613     @Override
1614     public <T> T reportBadDefinition(JavaType type, String msg) throws JsonMappingException {
1615         throw InvalidDefinitionException.from(_parser, msg, type);
1616     }
1617
1618     /**
1619      * @deprecated Since 2.10 use {@link #handleBadMerge} instead
1620      */

1621     @Deprecated // since 2.10
1622     public <T> T reportBadMerge(JsonDeserializer<?> deser) throws JsonMappingException {
1623         handleBadMerge(deser);
1624         return null;
1625     }
1626
1627     /*
1628     /**********************************************************
1629     /* Methods for constructing semantic exceptions; usually not
1630     /* to be called directly, call `handleXxx()` instead
1631     /**********************************************************
1632      */

1633
1634     /**
1635      * Helper method for constructing {@link JsonMappingException} to indicate
1636      * that the token encountered was of type different than what <b>should</b>
1637      * be seen at that position, usually within a sequence of expected tokens.
1638      * Note that most of the time this method should NOT be directly called;
1639      * instead, {@link #reportWrongTokenException} should be called and will
1640      * call this method as necessary.
1641      *
1642      * @since 2.9
1643      */

1644     public JsonMappingException wrongTokenException(JsonParser p, JavaType targetType,
1645             JsonToken expToken, String extra)
1646     {
1647         String msg = String.format("Unexpected token (%s), expected %s",
1648                 p.getCurrentToken(), expToken);
1649         msg = _colonConcat(msg, extra);
1650         return MismatchedInputException.from(p, targetType, msg);
1651     }
1652
1653     public JsonMappingException wrongTokenException(JsonParser p, Class<?> targetType,
1654             JsonToken expToken, String extra)
1655     {
1656         String msg = String.format("Unexpected token (%s), expected %s",
1657                 p.getCurrentToken(), expToken);
1658         msg = _colonConcat(msg, extra);
1659         return MismatchedInputException.from(p, targetType, msg);
1660     }
1661     
1662     @Deprecated // since 2.9
1663     public JsonMappingException wrongTokenException(JsonParser p, JsonToken expToken,
1664             String msg)
1665     {
1666         return wrongTokenException(p, (JavaType) null, expToken, msg);
1667     }
1668
1669     /**
1670      * Helper method for constructing exception to indicate that given JSON
1671      * Object field name was not in format to be able to deserialize specified
1672      * key type.
1673      * Note that most of the time this method should NOT be called; instead,
1674      * {@link #handleWeirdKey} should be called which will call this method
1675      * if necessary.
1676      */

1677     public JsonMappingException weirdKeyException(Class<?> keyClass, String keyValue,
1678             String msg) {
1679         return InvalidFormatException.from(_parser,
1680                 String.format("Cannot deserialize Map key of type %s from String %s: %s",
1681                         ClassUtil.nameOf(keyClass), _quotedString(keyValue), msg),
1682                 keyValue, keyClass);
1683     }
1684
1685     /**
1686      * Helper method for constructing exception to indicate that input JSON
1687      * String was not suitable for deserializing into given target type.
1688      * Note that most of the time this method should NOT be called; instead,
1689      * {@link #handleWeirdStringValue} should be called which will call this method
1690      * if necessary.
1691      * 
1692      * @param value String value from input being deserialized
1693      * @param instClass Type that String should be deserialized into
1694      * @param msgBase Message that describes specific problem
1695      * 
1696      * @since 2.1
1697      */

1698     public JsonMappingException weirdStringException(String value, Class<?> instClass,
1699             String msgBase) {
1700         final String msg = String.format("Cannot deserialize value of type %s from String %s: %s",
1701                 ClassUtil.nameOf(instClass), _quotedString(value), msgBase);
1702         return InvalidFormatException.from(_parser, msg, value, instClass);
1703     }
1704
1705     /**
1706      * Helper method for constructing exception to indicate that input JSON
1707      * Number was not suitable for deserializing into given target type.
1708      * Note that most of the time this method should NOT be called; instead,
1709      * {@link #handleWeirdNumberValue} should be called which will call this method
1710      * if necessary.
1711      */

1712     public JsonMappingException weirdNumberException(Number value, Class<?> instClass,
1713             String msg) {
1714         return InvalidFormatException.from(_parser,
1715                 String.format("Cannot deserialize value of type %s from number %s: %s",
1716                         ClassUtil.nameOf(instClass), String.valueOf(value), msg),
1717                 value, instClass);
1718     }
1719
1720     /**
1721      * Helper method for constructing exception to indicate that input JSON
1722      * token of type "native value" (see {@link JsonToken#VALUE_EMBEDDED_OBJECT})
1723      * is of incompatible type (and there is no delegating creator or such to use)
1724      * and can not be used to construct value of specified type (usually POJO).
1725      * Note that most of the time this method should NOT be called; instead,
1726      * {@link #handleWeirdNativeValue} should be called which will call this method
1727      *
1728      * @since 2.9
1729      */

1730     public JsonMappingException weirdNativeValueException(Object value, Class<?> instClass)
1731     {
1732         return InvalidFormatException.from(_parser, String.format(
1733 "Cannot deserialize value of type %s from native value (`JsonToken.VALUE_EMBEDDED_OBJECT`) of type %s: incompatible types",
1734             ClassUtil.nameOf(instClass), ClassUtil.classNameOf(value)),
1735                 value, instClass);
1736     }
1737
1738     /**
1739      * Helper method for constructing instantiation exception for specified type,
1740      * to indicate problem with physically constructing instance of
1741      * specified class (missing constructor, exception from constructor)
1742      *<p>
1743      * Note that most of the time this method should NOT be called directly; instead,
1744      * {@link #handleInstantiationProblem} should be called which will call this method
1745      * if necessary.
1746      */

1747     public JsonMappingException instantiationException(Class<?> instClass, Throwable cause) {
1748         String excMsg;
1749         if (cause == null) {
1750             excMsg = "N/A";
1751         } else if ((excMsg = ClassUtil.exceptionMessage(cause)) == null) {
1752             excMsg = ClassUtil.nameOf(cause.getClass());
1753         }
1754         String msg = String.format("Cannot construct instance of %s, problem: %s",
1755                 ClassUtil.nameOf(instClass), excMsg);
1756         // [databind#2162]: use specific exception type as we don't know if it's
1757         // due to type definition, input, or neither
1758         return ValueInstantiationException.from(_parser, msg, constructType(instClass), cause);
1759     }
1760
1761     /**
1762      * Helper method for constructing instantiation exception for specified type,
1763      * to indicate that instantiation failed due to missing instantiator
1764      * (creator; constructor or factory method).
1765      *<p>
1766      * Note that most of the time this method should NOT be called; instead,
1767      * {@link #handleMissingInstantiator} should be called which will call this method
1768      * if necessary.
1769      */

1770     public JsonMappingException instantiationException(Class<?> instClass, String msg0) {
1771         // [databind#2162]: use specific exception type as we don't know if it's
1772         // due to type definition, input, or neither
1773         return ValueInstantiationException.from(_parser,
1774                 String.format("Cannot construct instance of %s: %s",
1775                         ClassUtil.nameOf(instClass), msg0),
1776                 constructType(instClass));
1777     }
1778
1779     @Override
1780     public JsonMappingException invalidTypeIdException(JavaType baseType, String typeId,
1781             String extraDesc) {
1782         String msg = String.format("Could not resolve type id '%s' as a subtype of %s",
1783                 typeId, ClassUtil.getTypeDescription(baseType));
1784         return InvalidTypeIdException.from(_parser, _colonConcat(msg, extraDesc), baseType, typeId);
1785     }
1786
1787     /**
1788      * @since 2.9
1789      */

1790     public JsonMappingException missingTypeIdException(JavaType baseType,
1791             String extraDesc) {
1792         String msg = String.format("Missing type id when trying to resolve subtype of %s",
1793                 baseType);
1794         return InvalidTypeIdException.from(_parser, _colonConcat(msg, extraDesc), baseType, null);
1795     }
1796
1797     /*
1798     /**********************************************************
1799     /* Deprecated exception factory methods
1800     /**********************************************************
1801      */

1802
1803     /**
1804      * @since 2.5
1805      *
1806      * @deprecated Since 2.8 use {@link #handleUnknownTypeId} instead
1807      */

1808     @Deprecated
1809     public JsonMappingException unknownTypeException(JavaType type, String id,
1810             String extraDesc)
1811     {
1812         String msg = String.format("Could not resolve type id '%s' into a subtype of %s",
1813                 id, ClassUtil.getTypeDescription(type));
1814         msg = _colonConcat(msg, extraDesc);
1815         return MismatchedInputException.from(_parser, type, msg);
1816     }
1817
1818     /**
1819      * Helper method for constructing exception to indicate that end-of-input was
1820      * reached while still expecting more tokens to deserialize value of specified type.
1821      *
1822      * @deprecated Since 2.8; currently no way to catch EOF at databind level
1823      */

1824     @Deprecated
1825     public JsonMappingException endOfInputException(Class<?> instClass) {
1826         return MismatchedInputException.from(_parser, instClass,
1827                 "Unexpected end-of-input when trying to deserialize a "+instClass.getName());
1828     }
1829
1830     /*
1831     /**********************************************************
1832     /* Deprecated methods for constructing, throwing non-specific
1833     /* JsonMappingExceptions: as of 2.9, should use more specific
1834     /* ones.
1835     /**********************************************************
1836      */

1837     
1838     /**
1839      * Fallback method that may be called if no other <code>reportXxx</code>
1840      * is applicable -- but only in that case.
1841      *
1842      * @since 2.8
1843      * 
1844      * @deprecated Since 2.9: use a more specific method, or {@link #reportBadDefinition(JavaType, String)},
1845      *    or {@link #reportInputMismatch} instead
1846      */

1847     @Deprecated // since 2.9
1848     public void reportMappingException(String msg, Object... msgArgs)
1849         throws JsonMappingException
1850     {
1851         throw JsonMappingException.from(getParser(), _format(msg, msgArgs));
1852     }
1853
1854     /**
1855      * Helper method for constructing generic mapping exception with specified
1856      * message and current location information.
1857      * Note that application code should almost always call
1858      * one of <code>handleXxx</code> methods, or {@link #reportMappingException(String, Object...)}
1859      * instead.
1860      * 
1861      * @since 2.6
1862      * 
1863      * @deprecated Since 2.9 use more specific error reporting methods instead
1864      */

1865     @Deprecated
1866     public JsonMappingException mappingException(String message) {
1867         return JsonMappingException.from(getParser(), message);
1868     }
1869
1870     /**
1871      * Helper method for constructing generic mapping exception with specified
1872      * message and current location information
1873      * Note that application code should almost always call
1874      * one of <code>handleXxx</code> methods, or {@link #reportMappingException(String, Object...)}
1875      * instead.
1876      * 
1877      * @since 2.6
1878      *
1879      * @deprecated Since 2.9 use more specific error reporting methods instead
1880      */

1881     @Deprecated
1882     public JsonMappingException mappingException(String msg, Object... msgArgs) {
1883         return JsonMappingException.from(getParser(), _format(msg, msgArgs));
1884     }
1885
1886     /**
1887      * Helper method for constructing generic mapping exception for specified type
1888      * 
1889      * @deprecated Since 2.8 use {@link #handleUnexpectedToken(Class, JsonParser)} instead
1890      */

1891     @Deprecated
1892     public JsonMappingException mappingException(Class<?> targetClass) {
1893         return mappingException(targetClass, _parser.getCurrentToken());
1894     }
1895
1896     /**
1897      * @deprecated Since 2.8 use {@link #handleUnexpectedToken(Class, JsonParser)} instead
1898      */

1899     @Deprecated
1900     public JsonMappingException mappingException(Class<?> targetClass, JsonToken token) {
1901         return JsonMappingException.from(_parser,
1902                 String.format("Cannot deserialize instance of %s out of %s token",
1903                         ClassUtil.nameOf(targetClass), token));
1904     }
1905
1906     /*
1907     /**********************************************************
1908     /* Other internal methods
1909     /**********************************************************
1910      */

1911
1912     protected DateFormat getDateFormat()
1913     {
1914         if (_dateFormat != null) {
1915             return _dateFormat;
1916         }
1917         /* 24-Feb-2012, tatu: At this point, all timezone configuration
1918          *    should have occurred, with respect to default dateformat
1919          *    and timezone configuration. But we still better clone
1920          *    an instance as formatters may be stateful.
1921          */

1922         DateFormat df = _config.getDateFormat();
1923         _dateFormat = df = (DateFormat) df.clone();
1924         return df;
1925     }
1926 }
1927