1 package com.fasterxml.jackson.databind.deser.std;
2
3 import java.io.IOException;
4 import java.util.*;
5
6 import com.fasterxml.jackson.annotation.JsonFormat;
7 import com.fasterxml.jackson.annotation.Nulls;
8 import com.fasterxml.jackson.core.*;
9 import com.fasterxml.jackson.core.exc.InputCoercionException;
10 import com.fasterxml.jackson.core.io.NumberInput;
11 import com.fasterxml.jackson.databind.*;
12 import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
13 import com.fasterxml.jackson.databind.deser.BeanDeserializerBase;
14 import com.fasterxml.jackson.databind.deser.NullValueProvider;
15 import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
16 import com.fasterxml.jackson.databind.deser.ValueInstantiator;
17 import com.fasterxml.jackson.databind.deser.impl.NullsAsEmptyProvider;
18 import com.fasterxml.jackson.databind.deser.impl.NullsConstantProvider;
19 import com.fasterxml.jackson.databind.deser.impl.NullsFailProvider;
20 import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
21 import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
22 import com.fasterxml.jackson.databind.util.AccessPattern;
23 import com.fasterxml.jackson.databind.util.ClassUtil;
24 import com.fasterxml.jackson.databind.util.Converter;
25
26 /**
27  * Base class for common deserializers. Contains shared
28  * base functionality for dealing with primitive values, such
29  * as (re)parsing from String.
30  */

31 public abstract class StdDeserializer<T>
32     extends JsonDeserializer<T>
33     implements java.io.Serializable
34 {
35     private static final long serialVersionUID = 1L;
36
37     /**
38      * Bitmask that covers {@link DeserializationFeature#USE_BIG_INTEGER_FOR_INTS}
39      * and {@link DeserializationFeature#USE_LONG_FOR_INTS}, used for more efficient
40      * cheks when coercing integral values for untyped deserialization.
41      *
42      * @since 2.6
43      */

44     protected final static int F_MASK_INT_COERCIONS =
45             DeserializationFeature.USE_BIG_INTEGER_FOR_INTS.getMask()
46             | DeserializationFeature.USE_LONG_FOR_INTS.getMask();
47
48     // @since 2.9
49     protected final static int F_MASK_ACCEPT_ARRAYS =
50             DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS.getMask() |
51             DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT.getMask();
52
53     /**
54      * Type of values this deserializer handles: sometimes
55      * exact types, other time most specific supertype of
56      * types deserializer handles (which may be as generic
57      * as {@link Object} in some case)
58      */

59     final protected Class<?> _valueClass;
60
61     final protected JavaType _valueType;
62
63     protected StdDeserializer(Class<?> vc) {
64         _valueClass = vc;
65         _valueType = null;
66     }
67
68     protected StdDeserializer(JavaType valueType) {
69         // 26-Sep-2017, tatu: [databind#1764] need to add null-check back until 3.x
70         _valueClass = (valueType == null) ? Object.class : valueType.getRawClass();
71         _valueType = valueType;
72     }
73
74     /**
75      * Copy-constructor for sub-classes to use, most often when creating
76      * new instances for {@link com.fasterxml.jackson.databind.deser.ContextualDeserializer}.
77      *
78      * @since 2.5
79      */

80     protected StdDeserializer(StdDeserializer<?> src) {
81         _valueClass = src._valueClass;
82         _valueType = src._valueType;
83     }
84
85     /*
86     /**********************************************************
87     /* Accessors
88     /**********************************************************
89      */

90
91     @Override
92     public Class<?> handledType() { return _valueClass; }
93     
94     /*
95     /**********************************************************
96     /* Extended API
97     /**********************************************************
98      */

99
100     /**
101      * @deprecated Since 2.3 use {@link #handledType} instead
102      */

103     @Deprecated
104     public final Class<?> getValueClass() { return _valueClass; }
105
106     /**
107      * Exact structured type this deserializer handles, if known.
108      */

109     public JavaType getValueType() { return _valueType; }
110
111     /**
112      * Convenience method for getting handled type as {@link JavaType}, regardless
113      * of whether deserializer has one already resolved (and accessible via
114      * {@link #getValueType()}) or not: equivalent to:
115      *<pre>
116      *   if (getValueType() != null) {
117      *        return getValueType();
118      *   }
119      *   return ctxt.constructType(handledType());
120      *</pre>
121      * 
122      * @since 2.10
123      */

124     public JavaType getValueType(DeserializationContext ctxt) {
125         if (_valueType != null) {
126             return _valueType;
127         }
128         return ctxt.constructType(_valueClass);
129     }
130
131     /**
132      * Method that can be called to determine if given deserializer is the default
133      * deserializer Jackson uses; as opposed to a custom deserializer installed by
134      * a module or calling application. Determination is done using
135      * {@link JacksonStdImpl} annotation on deserializer class.
136      */

137     protected boolean isDefaultDeserializer(JsonDeserializer<?> deserializer) {
138         return ClassUtil.isJacksonStdImpl(deserializer);
139     }
140
141     protected boolean isDefaultKeyDeserializer(KeyDeserializer keyDeser) {
142         return ClassUtil.isJacksonStdImpl(keyDeser);
143     }
144     
145     /*
146     /**********************************************************
147     /* Partial JsonDeserializer implementation 
148     /**********************************************************
149      */

150
151     /**
152      * Base implementation that does not assume specific type
153      * inclusion mechanism. Sub-classes are expected to override
154      * this method if they are to handle type information.
155      */

156     @Override
157     public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
158             TypeDeserializer typeDeserializer) throws IOException {
159         return typeDeserializer.deserializeTypedFromAny(p, ctxt);
160     }
161
162     /*
163     /**********************************************************
164     /* Helper methods for sub-classes, parsing: while mostly
165     /* useful for numeric types, can be also useful for dealing
166     /* with things serialized as numbers (such as Dates).
167     /**********************************************************
168      */

169
170     @Deprecated // since 2.11, use overloaded variant
171     protected final boolean _parseBooleanPrimitive(JsonParser p, DeserializationContext ctxt) throws IOException {
172         return _parseBooleanPrimitive(ctxt, p, Boolean.TYPE);
173     }
174
175     // @since 2.11
176     protected final boolean _parseBooleanPrimitive(DeserializationContext ctxt,
177             JsonParser p, Class<?> targetType) throws IOException
178     {
179         JsonToken t = p.getCurrentToken();
180         if (t == JsonToken.VALUE_TRUE) return true;
181         if (t == JsonToken.VALUE_FALSE) return false;
182         if (t == JsonToken.VALUE_NULL) {
183             _verifyNullForPrimitive(ctxt);
184             return false;
185         }
186
187         // should accept ints too, (0 == false, otherwise true)
188         if (t == JsonToken.VALUE_NUMBER_INT) {
189             return _parseBooleanFromInt(p, ctxt);
190         }
191         // And finally, let's allow Strings to be converted too
192         if (t == JsonToken.VALUE_STRING) {
193             String text = p.getText().trim();
194             // [databind#422]: Allow aliases
195             if ("true".equals(text) || "True".equals(text)) {
196                 return true;
197             }
198             if ("false".equals(text) || "False".equals(text)) {
199                 return false;
200             }
201             if (_isEmptyOrTextualNull(text)) {
202                 _verifyNullForPrimitiveCoercion(ctxt, text);
203                 return false;
204             }
205             Boolean b = (Boolean) ctxt.handleWeirdStringValue(targetType, text,
206                     "only \"true\" or \"false\" recognized");
207             return Boolean.TRUE.equals(b);
208         }
209         // [databind#381]
210         if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
211             p.nextToken();
212             final boolean parsed = _parseBooleanPrimitive(ctxt, p, targetType);
213             _verifyEndArrayForSingle(p, ctxt);
214             return parsed;
215         }
216         // Otherwise, no can do:
217         return ((Boolean) ctxt.handleUnexpectedToken(targetType, p)).booleanValue();
218     }
219
220     protected boolean _parseBooleanFromInt(JsonParser p, DeserializationContext ctxt)
221         throws IOException
222     {
223         // 13-Oct-2016, tatu: As per [databind#1324], need to be careful wrt
224         //    degenerate case of huge integers, legal in JSON.
225         //  ... this is, on the other hand, probably wrong/sub-optimal for non-JSON
226         //  input. For now, no rea
227         _verifyNumberForScalarCoercion(ctxt, p);
228         // Anyway, note that since we know it's valid (JSON) integer, it can't have
229         // extra whitespace to trim.
230         return !"0".equals(p.getText());
231     }
232
233     protected final byte _parseBytePrimitive(JsonParser p, DeserializationContext ctxt)
234         throws IOException
235     {
236         int value = _parseIntPrimitive(p, ctxt);
237         // So far so good: but does it fit?
238         if (_byteOverflow(value)) {
239             Number v = (Number) ctxt.handleWeirdStringValue(_valueClass, String.valueOf(value),
240                     "overflow, value cannot be represented as 8-bit value");
241             return _nonNullNumber(v).byteValue();
242         }
243         return (byte) value;
244     }
245
246     protected final short _parseShortPrimitive(JsonParser p, DeserializationContext ctxt)
247         throws IOException
248     {
249         int value = _parseIntPrimitive(p, ctxt);
250         // So far so good: but does it fit?
251         if (_shortOverflow(value)) {
252             Number v = (Number) ctxt.handleWeirdStringValue(_valueClass, String.valueOf(value),
253                     "overflow, value cannot be represented as 16-bit value");
254             return _nonNullNumber(v).shortValue();
255         }
256         return (short) value;
257     }
258
259     protected final int _parseIntPrimitive(JsonParser p, DeserializationContext ctxt)
260         throws IOException
261     {
262         if (p.hasToken(JsonToken.VALUE_NUMBER_INT)) {
263             return p.getIntValue();
264         }
265         switch (p.getCurrentTokenId()) {
266         case JsonTokenId.ID_STRING:
267             String text = p.getText().trim();
268             if (_isEmptyOrTextualNull(text)) {
269                 _verifyNullForPrimitiveCoercion(ctxt, text);
270                 return 0;
271             }
272             return _parseIntPrimitive(ctxt, text);
273         case JsonTokenId.ID_NUMBER_FLOAT:
274             if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_FLOAT_AS_INT)) {
275                 _failDoubleToIntCoercion(p, ctxt, "int");
276             }
277             return p.getValueAsInt();
278         case JsonTokenId.ID_NULL:
279             _verifyNullForPrimitive(ctxt);
280             return 0;
281         case JsonTokenId.ID_START_ARRAY:
282             if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
283                 p.nextToken();
284                 final int parsed = _parseIntPrimitive(p, ctxt);
285                 _verifyEndArrayForSingle(p, ctxt);
286                 return parsed;
287             }
288             break;
289         default:
290         }
291         // Otherwise, no can do:
292         return ((Number) ctxt.handleUnexpectedToken(_valueClass, p)).intValue();
293     }
294
295     /**
296      * @since 2.9
297      */

298     protected final int _parseIntPrimitive(DeserializationContext ctxt, String text) throws IOException
299     {
300         try {
301             if (text.length() > 9) {
302                 long l = Long.parseLong(text);
303                 if (_intOverflow(l)) {
304                     Number v = (Number) ctxt.handleWeirdStringValue(_valueClass, text,
305                         "Overflow: numeric value (%s) out of range of int (%d -%d)",
306                         text, Integer.MIN_VALUE, Integer.MAX_VALUE);
307                     return _nonNullNumber(v).intValue();
308                 }
309                 return (int) l;
310             }
311             return NumberInput.parseInt(text);
312         } catch (IllegalArgumentException iae) {
313             Number v = (Number) ctxt.handleWeirdStringValue(_valueClass, text,
314                     "not a valid int value");
315             return _nonNullNumber(v).intValue();
316         }
317     }
318
319     protected final long _parseLongPrimitive(JsonParser p, DeserializationContext ctxt)
320         throws IOException
321     {
322         if (p.hasToken(JsonToken.VALUE_NUMBER_INT)) {
323             return p.getLongValue();
324         }
325         switch (p.getCurrentTokenId()) {
326         case JsonTokenId.ID_STRING:
327             String text = p.getText().trim();
328             if (_isEmptyOrTextualNull(text)) {
329                 _verifyNullForPrimitiveCoercion(ctxt, text);
330                 return 0L;
331             }
332             return _parseLongPrimitive(ctxt, text);
333         case JsonTokenId.ID_NUMBER_FLOAT:
334             if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_FLOAT_AS_INT)) {
335                 _failDoubleToIntCoercion(p, ctxt, "long");
336             }
337             return p.getValueAsLong();
338         case JsonTokenId.ID_NULL:
339             _verifyNullForPrimitive(ctxt);
340             return 0L;
341         case JsonTokenId.ID_START_ARRAY:
342             if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
343                 p.nextToken();
344                 final long parsed = _parseLongPrimitive(p, ctxt);
345                 _verifyEndArrayForSingle(p, ctxt);
346                 return parsed;
347             }
348             break;
349         }
350         return ((Number) ctxt.handleUnexpectedToken(_valueClass, p)).longValue();
351     }
352
353     /**
354      * @since 2.9
355      */

356     protected final long _parseLongPrimitive(DeserializationContext ctxt, String text) throws IOException
357     {
358         try {
359             return NumberInput.parseLong(text);
360         } catch (IllegalArgumentException iae) { }
361         {
362             Number v = (Number) ctxt.handleWeirdStringValue(_valueClass, text,
363                     "not a valid long value");
364             return _nonNullNumber(v).longValue();
365         }
366     }
367
368     protected final float _parseFloatPrimitive(JsonParser p, DeserializationContext ctxt)
369         throws IOException
370     {
371         if (p.hasToken(JsonToken.VALUE_NUMBER_FLOAT)) {
372             return p.getFloatValue();
373         }
374         switch (p.getCurrentTokenId()) {
375         case JsonTokenId.ID_STRING:
376             String text = p.getText().trim();
377             if (_isEmptyOrTextualNull(text)) {
378                 _verifyNullForPrimitiveCoercion(ctxt, text);
379                 return 0.0f;
380             }
381             return _parseFloatPrimitive(ctxt, text);
382         case JsonTokenId.ID_NUMBER_INT:
383             return p.getFloatValue();
384         case JsonTokenId.ID_NULL:
385             _verifyNullForPrimitive(ctxt);
386             return 0.0f;
387         case JsonTokenId.ID_START_ARRAY:
388             if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
389                 p.nextToken();
390                 final float parsed = _parseFloatPrimitive(p, ctxt);
391                 _verifyEndArrayForSingle(p, ctxt);
392                 return parsed;
393             }
394             break;
395         }
396         // Otherwise, no can do:
397         return ((Number) ctxt.handleUnexpectedToken(_valueClass, p)).floatValue();
398     }
399
400     /**
401      * @since 2.9
402      */

403     protected final float _parseFloatPrimitive(DeserializationContext ctxt, String text)
404         throws IOException
405     {
406         switch (text.charAt(0)) {
407         case 'I':
408             if (_isPosInf(text)) {
409                 return Float.POSITIVE_INFINITY;
410             }
411             break;
412         case 'N':
413             if (_isNaN(text)) { return Float.NaN; }
414             break;
415         case '-':
416             if (_isNegInf(text)) {
417                 return Float.NEGATIVE_INFINITY;
418             }
419             break;
420         }
421         try {
422             return Float.parseFloat(text);
423         } catch (IllegalArgumentException iae) { }
424         Number v = (Number) ctxt.handleWeirdStringValue(_valueClass, text,
425                 "not a valid float value");
426         return _nonNullNumber(v).floatValue();
427     }
428
429     protected final double _parseDoublePrimitive(JsonParser p, DeserializationContext ctxt)
430         throws IOException
431     {
432         if (p.hasToken(JsonToken.VALUE_NUMBER_FLOAT)) {
433             return p.getDoubleValue();
434         }
435         switch (p.getCurrentTokenId()) {
436         case JsonTokenId.ID_STRING:
437             String text = p.getText().trim();
438             if (_isEmptyOrTextualNull(text)) {
439                 _verifyNullForPrimitiveCoercion(ctxt, text);
440                 return 0.0;
441             }
442             return _parseDoublePrimitive(ctxt, text);
443         case JsonTokenId.ID_NUMBER_INT:
444             return p.getDoubleValue();
445         case JsonTokenId.ID_NULL:
446             _verifyNullForPrimitive(ctxt);
447             return 0.0;
448         case JsonTokenId.ID_START_ARRAY:
449             if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
450                 p.nextToken();
451                 final double parsed = _parseDoublePrimitive(p, ctxt);
452                 _verifyEndArrayForSingle(p, ctxt);
453                 return parsed;
454             }
455             break;
456         }
457         // Otherwise, no can do:
458         return ((Number) ctxt.handleUnexpectedToken(_valueClass, p)).doubleValue();
459     }
460
461     /**
462      * @since 2.9
463      */

464     protected final double _parseDoublePrimitive(DeserializationContext ctxt, String text)
465         throws IOException
466     {
467         switch (text.charAt(0)) {
468         case 'I':
469             if (_isPosInf(text)) {
470                 return Double.POSITIVE_INFINITY;
471             }
472             break;
473         case 'N':
474             if (_isNaN(text)) {
475                 return Double.NaN;
476             }
477             break;
478         case '-':
479             if (_isNegInf(text)) {
480                 return Double.NEGATIVE_INFINITY;
481             }
482             break;
483         }
484         try {
485             return parseDouble(text);
486         } catch (IllegalArgumentException iae) { }
487         Number v = (Number) ctxt.handleWeirdStringValue(_valueClass, text,
488                 "not a valid double value (as String to convert)");
489         return _nonNullNumber(v).doubleValue();
490     }
491
492     protected java.util.Date _parseDate(JsonParser p, DeserializationContext ctxt)
493         throws IOException
494     {
495         switch (p.getCurrentTokenId()) {
496         case JsonTokenId.ID_STRING:
497             return _parseDate(p.getText().trim(), ctxt);
498         case JsonTokenId.ID_NUMBER_INT:
499             {
500                 long ts;
501                 try {
502                     ts = p.getLongValue();
503                 // 16-Jan-2019, tatu: 2.10 uses InputCoercionException, earlier JsonParseException
504                 //     (but leave both until 3.0)
505                 } catch (JsonParseException | InputCoercionException e) {
506                     Number v = (Number) ctxt.handleWeirdNumberValue(_valueClass, p.getNumberValue(),
507                             "not a valid 64-bit long for creating `java.util.Date`");
508                     ts = v.longValue();
509                 }
510                 return new java.util.Date(ts);
511             }
512         case JsonTokenId.ID_NULL:
513             return (java.util.Date) getNullValue(ctxt);
514         case JsonTokenId.ID_START_ARRAY:
515             return _parseDateFromArray(p, ctxt);
516         }
517         return (java.util.Date) ctxt.handleUnexpectedToken(_valueClass, p);
518     }
519
520     // @since 2.9
521     protected java.util.Date _parseDateFromArray(JsonParser p, DeserializationContext ctxt)
522             throws IOException
523     {
524         JsonToken t;
525         if (ctxt.hasSomeOfFeatures(F_MASK_ACCEPT_ARRAYS)) {
526             t = p.nextToken();
527             if (t == JsonToken.END_ARRAY) {
528                 if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT)) {
529                     return (java.util.Date) getNullValue(ctxt);
530                 }
531             }
532             if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
533                 final Date parsed = _parseDate(p, ctxt);
534                 _verifyEndArrayForSingle(p, ctxt);
535                 return parsed;
536             }
537         } else {
538             t = p.getCurrentToken();
539         }
540         return (java.util.Date) ctxt.handleUnexpectedToken(_valueClass, t, p, null);
541     }
542
543     /**
544      * @since 2.8
545      */

546     protected java.util.Date _parseDate(String value, DeserializationContext ctxt)
547         throws IOException
548     {
549         try {
550             // Take empty Strings to mean 'empty' Value, usually 'null':
551             if (_isEmptyOrTextualNull(value)) {
552                 return (java.util.Date) getNullValue(ctxt);
553             }
554             return ctxt.parseDate(value);
555         } catch (IllegalArgumentException iae) {
556             return (java.util.Date) ctxt.handleWeirdStringValue(_valueClass, value,
557                     "not a valid representation (error: %s)",
558                     ClassUtil.exceptionMessage(iae));
559         }
560     }
561
562     /**
563      * Helper method for encapsulating calls to low-level double value parsing; single place
564      * just because we need a work-around that must be applied to all calls.
565      */

566     protected final static double parseDouble(String numStr) throws NumberFormatException
567     {
568         // avoid some nasty float representations... but should it be MIN_NORMAL or MIN_VALUE?
569         if (NumberInput.NASTY_SMALL_DOUBLE.equals(numStr)) {
570             return Double.MIN_NORMAL; // since 2.7; was MIN_VALUE prior
571         }
572         return Double.parseDouble(numStr);
573     }
574
575     /**
576      * Helper method used for accessing String value, if possible, doing
577      * necessary conversion or throwing exception as necessary.
578      *
579      * @since 2.1
580      */

581     protected final String _parseString(JsonParser p, DeserializationContext ctxt) throws IOException
582     {
583         JsonToken t = p.getCurrentToken();
584         if (t == JsonToken.VALUE_STRING) {
585             return p.getText();
586         }
587         // 07-Nov-2019, tatu: [databind#2535] Need to support byte[]->Base64 same as `StringDeserializer`
588         if (t == JsonToken.VALUE_EMBEDDED_OBJECT) {
589             Object ob = p.getEmbeddedObject();
590             if (ob instanceof byte[]) {
591                 return ctxt.getBase64Variant().encode((byte[]) ob, false);
592             }
593             if (ob == null) {
594                 return null;
595             }
596             // otherwise, try conversion using toString()...
597             return ob.toString();
598         }
599
600         // 07-Nov-2016, tatu: Caller should take care of unwrapping and there shouldn't
601         //    be need for extra pass here...
602         /*
603         // [databind#381]
604         if ((t == JsonToken.START_ARRAY) && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
605             p.nextToken();
606             final String parsed = _parseString(p, ctxt);
607             _verifyEndArrayForSingle(p, ctxt);
608             return parsed;            
609         }
610         */

611         String value = p.getValueAsString();
612         if (value != null) {
613             return value;
614         }
615         return (String) ctxt.handleUnexpectedToken(String.class, p);
616     }
617
618     /**
619      * Helper method that may be used to support fallback for Empty String / Empty Array
620      * non-standard representations; usually for things serialized as JSON Objects.
621      *
622      * @since 2.5
623      */

624     @SuppressWarnings("unchecked")
625     protected T _deserializeFromEmpty(JsonParser p, DeserializationContext ctxt)
626         throws IOException
627     {
628         JsonToken t = p.getCurrentToken();
629         if (t == JsonToken.START_ARRAY) {
630             if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT)) {
631                 t = p.nextToken();
632                 if (t == JsonToken.END_ARRAY) {
633                     return null;
634                 }
635                 return (T) ctxt.handleUnexpectedToken(handledType(), p);
636             }
637         } else if (t == JsonToken.VALUE_STRING) {
638             if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) {
639                 String str = p.getText().trim();
640                 if (str.isEmpty()) {
641                     return null;
642                 }
643             }
644         }
645         return (T) ctxt.handleUnexpectedToken(handledType(), p);
646     }
647
648     /**
649      * Helper method called to determine if we are seeing String value of
650      * "null", and, further, that it should be coerced to null just like
651      * null token.
652      *
653      * @since 2.3
654      */

655     protected boolean _hasTextualNull(String value) {
656         return "null".equals(value);
657     }
658
659     /**
660      * @since 2.9
661      */

662     protected boolean _isEmptyOrTextualNull(String value) {
663         return value.isEmpty() || "null".equals(value);
664     }
665
666     protected final boolean _isNegInf(String text) {
667         return "-Infinity".equals(text) || "-INF".equals(text);
668     }
669
670     protected final boolean _isPosInf(String text) {
671         return "Infinity".equals(text) || "INF".equals(text);
672     }
673
674     protected final boolean _isNaN(String text) { return "NaN".equals(text); }
675
676     /*
677     /**********************************************************
678     /* Helper methods for sub-classes regarding decoding from
679     /* alternate representations
680     /**********************************************************
681      */

682
683     /**
684      * Helper method that allows easy support for array-related {@link DeserializationFeature}s
685      * `ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT` and `UNWRAP_SINGLE_VALUE_ARRAYS`: checks for either
686      * empty array, or single-value array-wrapped value (respectively), and either reports
687      * an exception (if no match, or feature(s) not enabled), or returns appropriate
688      * result value.
689      *<p>
690      * This method should NOT be called if Array representation is explicitly supported
691      * for type: it should only be called in case it is otherwise unrecognized.
692      *<p>
693      * NOTE: in case of unwrapped single element, will handle actual decoding
694      * by calling {@link #_deserializeWrappedValue}, which by default calls
695      * {@link #deserialize(JsonParser, DeserializationContext)}.
696      *
697      * @since 2.9
698      */

699     protected T _deserializeFromArray(JsonParser p, DeserializationContext ctxt) throws IOException
700     {
701         JsonToken t;
702         if (ctxt.hasSomeOfFeatures(F_MASK_ACCEPT_ARRAYS)) {
703             t = p.nextToken();
704             if (t == JsonToken.END_ARRAY) {
705                 if (ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT)) {
706                     return getNullValue(ctxt);
707                 }
708             }
709             if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
710                 final T parsed = deserialize(p, ctxt);
711                 if (p.nextToken() != JsonToken.END_ARRAY) {
712                     handleMissingEndArrayForSingle(p, ctxt);
713                 }
714                 return parsed;
715             }
716         } else {
717             t = p.getCurrentToken();
718         }
719         @SuppressWarnings("unchecked")
720         T result = (T) ctxt.handleUnexpectedToken(getValueType(ctxt), p.getCurrentToken(), p, null);
721         return result;
722     }
723
724     /**
725      * Helper called to support {@link DeserializationFeature#UNWRAP_SINGLE_VALUE_ARRAYS}:
726      * default implementation simply calls
727      * {@link #deserialize(JsonParser, DeserializationContext)},
728      * but handling may be overridden.
729      *
730      * @since 2.9
731      */

732     protected T _deserializeWrappedValue(JsonParser p, DeserializationContext ctxt) throws IOException
733     {
734         // 23-Mar-2017, tatu: Let's specifically block recursive resolution to avoid
735         //   either supporting nested arrays, or to cause infinite looping.
736         if (p.hasToken(JsonToken.START_ARRAY)) {
737             String msg = String.format(
738 "Cannot deserialize instance of %s out of %s token: nested Arrays not allowed with %s",
739                     ClassUtil.nameOf(_valueClass), JsonToken.START_ARRAY,
740                     "DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS");
741             @SuppressWarnings("unchecked")
742             T result = (T) ctxt.handleUnexpectedToken(getValueType(ctxt), p.getCurrentToken(), p, msg);
743             return result;
744         }
745         return (T) deserialize(p, ctxt);
746     }
747
748     /*
749     /****************************************************
750     /* Helper methods for sub-classes, coercions
751     /****************************************************
752      */

753
754     protected void _failDoubleToIntCoercion(JsonParser p, DeserializationContext ctxt,
755             String type) throws IOException
756     {
757         ctxt.reportInputMismatch(handledType(),
758 "Cannot coerce a floating-point value ('%s') into %s (enable `DeserializationFeature.ACCEPT_FLOAT_AS_INT` to allow)",
759                 p.getValueAsString(), type);
760     }
761
762     /**
763      * Helper method called in case where an integral number is encountered, but
764      * config settings suggest that a coercion may be needed to "upgrade"
765      * {@link java.lang.Number} into "bigger" type like {@link java.lang.Long} or
766      * {@link java.math.BigInteger}
767      *
768      * @see DeserializationFeature#USE_BIG_INTEGER_FOR_INTS
769      * @see DeserializationFeature#USE_LONG_FOR_INTS
770      *
771      * @since 2.6
772      */

773     protected Object _coerceIntegral(JsonParser p, DeserializationContext ctxt) throws IOException
774     {
775         int feats = ctxt.getDeserializationFeatures();
776         if (DeserializationFeature.USE_BIG_INTEGER_FOR_INTS.enabledIn(feats)) {
777             return p.getBigIntegerValue();
778         }
779         if (DeserializationFeature.USE_LONG_FOR_INTS.enabledIn(feats)) {
780             return p.getLongValue();
781         }
782         return p.getBigIntegerValue(); // should be optimal, whatever it is
783     }
784
785     /**
786      * Method to call when JSON `null` token is encountered. Note: only called when
787      * this deserializer encounters it but NOT when reached via property
788      *
789      * @since 2.9
790      */

791     protected Object _coerceNullToken(DeserializationContext ctxt, boolean isPrimitive) throws JsonMappingException
792     {
793         if (isPrimitive) {
794             _verifyNullForPrimitive(ctxt);
795         }
796         return getNullValue(ctxt);
797     }
798
799     /**
800      * Method called when JSON String with value "null" is encountered.
801      *
802      * @since 2.9
803      */

804     protected Object _coerceTextualNull(DeserializationContext ctxt, boolean isPrimitive) throws JsonMappingException
805     {
806         Enum<?> feat;
807         boolean enable;
808
809         if (!ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS)) {
810             feat = MapperFeature.ALLOW_COERCION_OF_SCALARS;
811             enable = true;
812         } else if (isPrimitive && ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) {
813             feat = DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES;
814             enable = false;
815         } else {
816             return getNullValue(ctxt);
817         }
818         _reportFailedNullCoerce(ctxt, enable, feat, "String \"null\"");
819         return null;
820     }
821
822     /**
823      * Method called when JSON String with value "" (that is, zero length) is encountered.
824      *
825      * @since 2.9
826      */

827     protected Object _coerceEmptyString(DeserializationContext ctxt, boolean isPrimitive) throws JsonMappingException
828     {
829         Enum<?> feat;
830         boolean enable;
831
832         if (!ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS)) {
833             feat = MapperFeature.ALLOW_COERCION_OF_SCALARS;
834             enable = true;
835         } else if (isPrimitive && ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) {
836             feat = DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES;
837             enable = false;
838         } else {
839             return getNullValue(ctxt);
840         }
841         _reportFailedNullCoerce(ctxt, enable, feat, "empty String (\"\")");
842         return null;
843     }
844
845     // @since 2.9
846     protected final void _verifyNullForPrimitive(DeserializationContext ctxt) throws JsonMappingException
847     {
848         if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) {
849             ctxt.reportInputMismatch(this,
850 "Cannot coerce `null` %s (disable `DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES` to allow)",
851                     _coercedTypeDesc());
852         }
853     }
854
855     // NOTE: only for primitive Scalars
856     // @since 2.9
857     protected final void _verifyNullForPrimitiveCoercion(DeserializationContext ctxt, String str) throws JsonMappingException
858     {
859         Enum<?> feat;
860         boolean enable;
861
862         if (!ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS)) {
863             feat = MapperFeature.ALLOW_COERCION_OF_SCALARS;
864             enable = true;
865         } else if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) {
866             feat = DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES;
867             enable = false;
868         } else {
869             return;
870         }
871         String strDesc = str.isEmpty() ? "empty String (\"\")" : String.format("String \"%s\"", str);
872         _reportFailedNullCoerce(ctxt, enable, feat, strDesc);
873     }
874
875     // NOTE: for non-primitive Scalars
876     // @since 2.9
877     protected final void _verifyNullForScalarCoercion(DeserializationContext ctxt, String str) throws JsonMappingException
878     {
879         if (!ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS)) {
880             String strDesc = str.isEmpty() ? "empty String (\"\")" : String.format("String \"%s\"", str);
881             _reportFailedNullCoerce(ctxt, true, MapperFeature.ALLOW_COERCION_OF_SCALARS, strDesc);
882         }
883     }
884
885     // @since 2.9
886     protected void _verifyStringForScalarCoercion(DeserializationContext ctxt, String str) throws JsonMappingException
887     {
888         MapperFeature feat = MapperFeature.ALLOW_COERCION_OF_SCALARS;
889         if (!ctxt.isEnabled(feat)) {
890             ctxt.reportInputMismatch(this"Cannot coerce String \"%s\" %s (enable `%s.%s` to allow)",
891                 str, _coercedTypeDesc(), feat.getClass().getSimpleName(), feat.name());
892         }
893     }
894
895     // @since 2.9
896     protected void _verifyNumberForScalarCoercion(DeserializationContext ctxt, JsonParser p) throws IOException
897     {
898         MapperFeature feat = MapperFeature.ALLOW_COERCION_OF_SCALARS;
899         if (!ctxt.isEnabled(feat)) {
900             // 31-Mar-2017, tatu: Since we don't know (or this deep, care) about exact type,
901             //   access as a String: may require re-encoding by parser which should be fine
902             String valueDesc = p.getText();
903             ctxt.reportInputMismatch(this"Cannot coerce Number (%s) %s (enable `%s.%s` to allow)",
904                 valueDesc, _coercedTypeDesc(), feat.getClass().getSimpleName(), feat.name());
905         }
906     }
907
908     protected void _reportFailedNullCoerce(DeserializationContext ctxt, boolean state, Enum<?> feature,
909             String inputDesc) throws JsonMappingException
910     {
911         String enableDesc = state ? "enable" : "disable";
912         ctxt.reportInputMismatch(this"Cannot coerce %s to Null value %s (%s `%s.%s` to allow)",
913             inputDesc, _coercedTypeDesc(), enableDesc, feature.getClass().getSimpleName(), feature.name());
914     }
915
916     /**
917      * Helper method called to get a description of type into which a scalar value coercion
918      * is (most likely) being applied, to be used for constructing exception messages
919      * on coerce failure.
920      *
921      * @return Message with backtick-enclosed name of type this deserializer supports
922      *
923      * @since 2.9
924      */

925     protected String _coercedTypeDesc() {
926         boolean structured;
927         String typeDesc;
928
929         JavaType t = getValueType();
930         if ((t != null) && !t.isPrimitive()) {
931             structured = (t.isContainerType() || t.isReferenceType());
932             // 21-Jul-2017, tatu: Probably want to change this (JavaType.toString() not very good) but...
933             typeDesc = "'"+t.toString()+"'";
934         } else {
935             Class<?> cls = handledType();
936             structured = cls.isArray() || Collection.class.isAssignableFrom(cls)
937                 || Map.class.isAssignableFrom(cls);
938             typeDesc = ClassUtil.nameOf(cls);
939         }
940         if (structured) {
941             return "as content of type "+typeDesc;
942         }
943         return "for type "+typeDesc;
944     }
945
946     /*
947     /****************************************************
948     /* Helper methods for sub-classes, resolving dependencies
949     /****************************************************
950      */

951
952     /**
953      * Helper method used to locate deserializers for properties the
954      * type this deserializer handles contains (usually for properties of
955      * bean types)
956      *
957      * @param type Type of property to deserialize
958      * @param property Actual property object (field, method, constuctor parameter) used
959      *     for passing deserialized values; provided so deserializer can be contextualized if necessary
960      */

961     protected JsonDeserializer<Object> findDeserializer(DeserializationContext ctxt,
962             JavaType type, BeanProperty property)
963         throws JsonMappingException
964     {
965         return ctxt.findContextualValueDeserializer(type, property);
966     }
967
968     /**
969      * Helper method to check whether given text refers to what looks like a clean simple
970      * integer number, consisting of optional sign followed by a sequence of digits.
971      */

972     protected final boolean _isIntNumber(String text)
973     {
974         final int len = text.length();
975         if (len > 0) {
976             char c = text.charAt(0);
977             // skip leading sign (plus not allowed for strict JSON numbers but...)
978             int i = (c == '-' || c == '+') ? 1 : 0;
979             for (; i < len; ++i) {
980                 int ch = text.charAt(i);
981                 if (ch > '9' || ch < '0') {
982                     return false;
983                 }
984             }
985             return true;
986         }
987         return false;
988     }
989
990     /*
991     /**********************************************************
992     /* Helper methods for: deserializer construction
993     /**********************************************************
994      */

995
996     /**
997      * Helper method that can be used to see if specified property has annotation
998      * indicating that a converter is to be used for contained values (contents
999      * of structured types; array/List/Map values)
1000      *
1001      * @param existingDeserializer (optional) configured content
1002      *    serializer if one already exists.
1003      *
1004      * @since 2.2
1005      */

1006     protected JsonDeserializer<?> findConvertingContentDeserializer(DeserializationContext ctxt,
1007             BeanProperty prop, JsonDeserializer<?> existingDeserializer)
1008         throws JsonMappingException
1009     {
1010         final AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
1011         if (_neitherNull(intr, prop)) {
1012             AnnotatedMember member = prop.getMember();
1013             if (member != null) {
1014                 Object convDef = intr.findDeserializationContentConverter(member);
1015                 if (convDef != null) {
1016                     Converter<Object,Object> conv = ctxt.converterInstance(prop.getMember(), convDef);
1017                     JavaType delegateType = conv.getInputType(ctxt.getTypeFactory());
1018                     if (existingDeserializer == null) {
1019                         existingDeserializer = ctxt.findContextualValueDeserializer(delegateType, prop);
1020                     }
1021                     return new StdDelegatingDeserializer<Object>(conv, delegateType, existingDeserializer);
1022                 }
1023             }
1024         }
1025         return existingDeserializer;
1026     }
1027
1028     /*
1029     /**********************************************************
1030     /* Helper methods for: accessing contextual config settings
1031     /**********************************************************
1032      */

1033
1034     /**
1035      * Helper method that may be used to find if this deserializer has specific
1036      * {@link JsonFormat} settings, either via property, or through type-specific
1037      * defaulting.
1038      *
1039      * @param typeForDefaults Type (erased) used for finding default format settings, if any
1040      *
1041      * @since 2.7
1042      */

1043     protected JsonFormat.Value findFormatOverrides(DeserializationContext ctxt,
1044             BeanProperty prop, Class<?> typeForDefaults)
1045     {
1046         if (prop != null) {
1047             return prop.findPropertyFormat(ctxt.getConfig(), typeForDefaults);
1048         }
1049         // even without property or AnnotationIntrospector, may have type-specific defaults
1050         return ctxt.getDefaultPropertyFormat(typeForDefaults);
1051     }
1052
1053     /**
1054      * Convenience method that uses {@link #findFormatOverrides} to find possible
1055      * defaults and/of overrides, and then calls
1056      * <code>JsonFormat.Value.getFeature(feat)</code>
1057      * to find whether that feature has been specifically marked as enabled or disabled.
1058      *
1059      * @param typeForDefaults Type (erased) used for finding default format settings, if any
1060      *
1061      * @since 2.7
1062      */

1063     protected Boolean findFormatFeature(DeserializationContext ctxt,
1064             BeanProperty prop, Class<?> typeForDefaults, JsonFormat.Feature feat)
1065     {
1066         JsonFormat.Value format = findFormatOverrides(ctxt, prop, typeForDefaults);
1067         if (format != null) {
1068             return format.getFeature(feat);
1069         }
1070         return null;
1071     }
1072
1073     /**
1074      * Method called to find {@link NullValueProvider} for a primary property, using
1075      * "value nulls" setting. If no provider found (not defined, or is "skip"),
1076      * will return `null`.
1077      *
1078      * @since 2.9
1079      */

1080     protected final NullValueProvider findValueNullProvider(DeserializationContext ctxt,
1081             SettableBeanProperty prop, PropertyMetadata propMetadata)
1082         throws JsonMappingException
1083     {
1084         if (prop != null) {
1085             return _findNullProvider(ctxt, prop, propMetadata.getValueNulls(),
1086                     prop.getValueDeserializer());
1087         }
1088         return null;
1089     }
1090
1091     /**
1092      * Method called to find {@link NullValueProvider} for a contents of a structured
1093      * primary property (Collection, Map, array), using
1094      * "content nulls" setting. If no provider found (not defined),
1095      * will return given value deserializer (which is a null value provider itself).
1096      *
1097      * @since 2.9
1098      */

1099     protected NullValueProvider findContentNullProvider(DeserializationContext ctxt,
1100             BeanProperty prop, JsonDeserializer<?> valueDeser)
1101         throws JsonMappingException
1102     {
1103         final Nulls nulls = findContentNullStyle(ctxt, prop);
1104         if (nulls == Nulls.SKIP) {
1105             return NullsConstantProvider.skipper();
1106         }
1107         // 09-Dec-2019, tatu: [databind#2567] need to ensure correct target type (element,
1108         //    not container), so inlined here before calling _findNullProvider
1109         if (nulls == Nulls.FAIL) {
1110             if (prop == null) {
1111                 JavaType type = ctxt.constructType(valueDeser.handledType());
1112                 // should always be container? But let's double-check just in case:
1113                 if (type.isContainerType()) {
1114                     type = type.getContentType();
1115                 }
1116                 return NullsFailProvider.constructForRootValue(type);
1117             }
1118             return NullsFailProvider.constructForProperty(prop, prop.getType().getContentType());
1119         }
1120
1121         NullValueProvider prov = _findNullProvider(ctxt, prop, nulls, valueDeser);
1122         if (prov != null) {
1123             return prov;
1124         }
1125         return valueDeser;
1126     }
1127
1128     protected Nulls findContentNullStyle(DeserializationContext ctxt, BeanProperty prop)
1129         throws JsonMappingException
1130     {
1131         if (prop != null) {
1132             return prop.getMetadata().getContentNulls();
1133         }
1134         return null;
1135     }
1136
1137     // @since 2.9
1138     protected final NullValueProvider _findNullProvider(DeserializationContext ctxt,
1139             BeanProperty prop, Nulls nulls, JsonDeserializer<?> valueDeser)
1140         throws JsonMappingException
1141     {
1142         if (nulls == Nulls.FAIL) {
1143             if (prop == null) {
1144                 return NullsFailProvider.constructForRootValue(ctxt.constructType(valueDeser.handledType()));
1145             }
1146             return NullsFailProvider.constructForProperty(prop);
1147         }
1148         if (nulls == Nulls.AS_EMPTY) {
1149             // cannot deal with empty values if there is no value deserializer that
1150             // can indicate what "empty value" is:
1151             if (valueDeser == null) {
1152                 return null;
1153             }
1154
1155             // Let's first do some sanity checking...
1156             // NOTE: although we could use `ValueInstantiator.Gettable` in general,
1157             // let's not since that would prevent being able to use custom impls:
1158             if (valueDeser instanceof BeanDeserializerBase) {
1159                 ValueInstantiator vi = ((BeanDeserializerBase) valueDeser).getValueInstantiator();
1160                 if (!vi.canCreateUsingDefault()) {
1161                     final JavaType type = prop.getType();
1162                     ctxt.reportBadDefinition(type,
1163                             String.format("Cannot create empty instance of %s, no default Creator", type));
1164                 }
1165             }
1166             // Second: can with pre-fetch value?
1167             {
1168                 AccessPattern access = valueDeser.getEmptyAccessPattern();
1169                 if (access == AccessPattern.ALWAYS_NULL) {
1170                     return NullsConstantProvider.nuller();
1171                 }
1172                 if (access == AccessPattern.CONSTANT) {
1173                     return NullsConstantProvider.forValue(valueDeser.getEmptyValue(ctxt));
1174                 }
1175             }
1176             return new NullsAsEmptyProvider(valueDeser);
1177         }
1178         if (nulls == Nulls.SKIP) {
1179             return NullsConstantProvider.skipper();
1180         }
1181         return null;
1182     }
1183
1184     /*
1185     /**********************************************************
1186     /* Helper methods for sub-classes, problem reporting
1187     /**********************************************************
1188      */

1189
1190     /**
1191      * Method called to deal with a property that did not map to a known
1192      * Bean property. Method can deal with the problem as it sees fit (ignore,
1193      * throw exception); but if it does return, it has to skip the matching
1194      * Json content parser has.
1195      *
1196      * @param p Parser that points to value of the unknown property
1197      * @param ctxt Context for deserialization; allows access to the parser,
1198      *    error reporting functionality
1199      * @param instanceOrClass Instance that is being populated by this
1200      *   deserializer, or if not known, Class that would be instantiated.
1201      *   If null, will assume type is what {@link #getValueClass} returns.
1202      * @param propName Name of the property that cannot be mapped
1203      */

1204     protected void handleUnknownProperty(JsonParser p, DeserializationContext ctxt,
1205             Object instanceOrClass, String propName)
1206         throws IOException
1207     {
1208         if (instanceOrClass == null) {
1209             instanceOrClass = handledType();
1210         }
1211         // Maybe we have configured handler(s) to take care of it?
1212         if (ctxt.handleUnknownProperty(p, this, instanceOrClass, propName)) {
1213             return;
1214         }
1215         /* But if we do get this far, need to skip whatever value we
1216          * are pointing to now (although handler is likely to have done that already)
1217          */

1218         p.skipChildren();
1219     }
1220
1221     protected void handleMissingEndArrayForSingle(JsonParser p, DeserializationContext ctxt)
1222         throws IOException
1223     {
1224         ctxt.reportWrongTokenException(this, JsonToken.END_ARRAY,
1225 "Attempted to unwrap '%s' value from an array (with `DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS`) but it contains more than one value",
1226 handledType().getName());
1227         // 05-May-2016, tatu: Should recover somehow (maybe skip until END_ARRAY);
1228         //     but for now just fall through
1229     }
1230
1231     protected void _verifyEndArrayForSingle(JsonParser p, DeserializationContext ctxt) throws IOException
1232     {
1233         JsonToken t = p.nextToken();
1234         if (t != JsonToken.END_ARRAY) {
1235             handleMissingEndArrayForSingle(p, ctxt);
1236         }
1237     }
1238
1239     /*
1240     /**********************************************************
1241     /* Helper methods, other
1242     /**********************************************************
1243      */

1244
1245     /**
1246      * @since 2.9
1247      */

1248     protected final static boolean _neitherNull(Object a, Object b) {
1249         return (a != null) && (b != null);
1250     }
1251
1252     /**
1253      * @since 2.9
1254      */

1255     protected final boolean _byteOverflow(int value) {
1256         // 07-nov-2016, tatu: We support "unsigned byte" as well
1257         //    as Java signed range since that's relatively common usage
1258         return (value < Byte.MIN_VALUE || value > 255);
1259     }
1260
1261     /**
1262      * @since 2.9
1263      */

1264     protected final boolean _shortOverflow(int value) {
1265         return (value < Short.MIN_VALUE || value > Short.MAX_VALUE);
1266     }
1267
1268     /**
1269      * @since 2.9
1270      */

1271     protected final boolean _intOverflow(long value) {
1272         return (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE);
1273     }
1274
1275     /**
1276      * @since 2.9
1277      */

1278     protected Number _nonNullNumber(Number n) {
1279         if (n == null) {
1280             n = Integer.valueOf(0);
1281         }
1282         return n;
1283     }
1284 }
1285