DeserializationFeature.java

package tools.jackson.databind;

import com.fasterxml.jackson.annotation.JacksonInject;

import tools.jackson.databind.cfg.ConfigFeature;
import tools.jackson.databind.cfg.MapperBuilder;

/**
 * Enumeration that defines simple on/off features that affect
 * the way Java objects are deserialized from JSON
 *<p>
 * Note that features can be set both through
 * {@link ObjectMapper} (as sort of defaults) and through
 * {@link ObjectReader}.
 * In first case these defaults must follow "config-then-use" patterns
 * (i.e. defined once, not changed afterwards); all per-call
 * changes must be done using {@link ObjectReader}.
 *<p>
 * Note that features that do not indicate version of inclusion
 * were available in Jackson 3.0 (or earlier); only later additions
 * indicate version of inclusion.
 */
public enum DeserializationFeature implements ConfigFeature
{
    /*
    /**********************************************************************
    /* Value (mostly scalar) mapping features
    /**********************************************************************
     */

    /**
     * Feature that determines whether JSON floating point numbers
     * are to be deserialized into {@link java.math.BigDecimal}s
     * if only generic type description (either {@link Object} or
     * {@link Number}, or within untyped {@link java.util.Map}
     * or {@link java.util.Collection} context) is available.
     * If enabled such values will be deserialized as {@link java.math.BigDecimal}s;
     * if disabled, will be deserialized as {@link Double}s.
     *<p>
     * NOTE: one related aspect of {@link java.math.BigDecimal} handling that may need
     * configuring is whether trailing zeroes are trimmed:
     * {@link tools.jackson.databind.cfg.JsonNodeFeature#STRIP_TRAILING_BIGDECIMAL_ZEROES}
     * is used for optionally enabling this for {@link tools.jackson.databind.JsonNode}
     * values.
     *<p>
     * Feature is disabled by default, meaning that "untyped" floating
     * point numbers will by default be deserialized as {@link Double}s
     * (choice is for performance reason -- BigDecimals are slower than
     * Doubles).
     */
    USE_BIG_DECIMAL_FOR_FLOATS(false),

    /**
     * Feature that determines whether JSON integral (non-floating-point)
     * numbers are to be deserialized into {@link java.math.BigInteger}s
     * if only generic type description (either {@link Object} or
     * {@link Number}, or within untyped {@link java.util.Map}
     * or {@link java.util.Collection} context) is available.
     * If enabled such values will be deserialized as
     * {@link java.math.BigInteger}s;
     * if disabled, will be deserialized as "smallest" available type,
     * which is either {@link Integer}, {@link Long} or
     * {@link java.math.BigInteger}, depending on number of digits.
     * <p>
     * Feature is disabled by default, meaning that "untyped" integral
     * numbers will by default be deserialized using whatever
     * is the most compact integral type, to optimize efficiency.
     */
    USE_BIG_INTEGER_FOR_INTS(false),

    /**
     * Feature that determines how "small" JSON integral (non-floating-point)
     * numbers -- ones that fit in 32-bit signed integer (`int`) -- are bound
     * when target type is loosely typed as {@link Object} or {@link Number}
     * (or within untyped {@link java.util.Map} or {@link java.util.Collection} context).
     * If enabled, such values will be deserialized as {@link java.lang.Long};
     * if disabled, they will be deserialized as "smallest" available type,
     * {@link Integer}.
     *<p>
     * Note: if {@link #USE_BIG_INTEGER_FOR_INTS} is enabled, it has precedence
     * over this setting, forcing use of {@link java.math.BigInteger} for all
     * integral values.
     *<p>
     * Feature is disabled by default, meaning that "untyped" integral
     * numbers will by default be deserialized using {@link java.lang.Integer}
     * if value fits.
     */
    USE_LONG_FOR_INTS(false),

    /**
     * Feature that determines whether JSON Array is mapped to
     * <code>Object[]</code> or {@code List<Object>} when binding
     * "untyped" objects (ones with nominal type of <code>java.lang.Object</code>).
     * If true, binds as <code>Object[]</code>; if false, as {@code List<Object>}.
     *<p>
     * Feature is disabled by default, meaning that JSON arrays are bound as
     * {@link java.util.List}s.
     */
    USE_JAVA_ARRAY_FOR_JSON_ARRAY(false),

    /**
     * Feature that determines whether deserialization of "Reference Types"
     * (such as {@link java.util.Optional}, {@link java.util.concurrent.atomic.AtomicReference},
     * and Kotlin/Scala equivalents) should return Java {@code null} in case
     * of value missing from incoming JSON. If disabled, reference type's
     * "absent" value is returned (for example, {@link java.util.Optional#empty()}.
     *<p>
     * NOTE: this feature only affects handling of missing values; not explicit
     * JSON {@code null}s.
     * Also note that this feature only affects deserialization when reference value
     * is passed via Creator (constructor or factory method) parameter; when
     * Setter methods or fields are used, the reference type is left un-assigned
     * (this is not specifically related to reference types, but general behavior).
     *
     * @since 3.1
     */
    USE_NULL_FOR_MISSING_REFERENCE_VALUES(false),

    /*
    /**********************************************************************
    /* Error handling features
    /**********************************************************************
     */

    /**
     * Feature that determines whether encountering of unknown
     * properties (ones that do not map to a property, and there is
     * no "any setter" or handler that can handle it)
     * should result in a failure (by throwing a
     * {@link DatabindException}) or not.
     * This setting only takes effect after all other handling
     * methods for unknown properties have been tried, and
     * property remains unhandled.
     * Enabling this feature means that a {@link DatabindException}
     * will be thrown if an unknown property is encountered.
     *<p>
     * Feature is disabled by default as of Jackson 3.0 (in 2.x it was enabled).
     */
    FAIL_ON_UNKNOWN_PROPERTIES(false),

    /**
     * Feature that determines whether encountering of JSON null
     * is an error when deserializing into Java primitive types
     * (like 'int' or 'double'). If it is, a {@link DatabindException}
     * is thrown to indicate this; if not, default value is used
     * (0 for 'int', 0.0 for double, same defaulting as what JVM uses).
     *<p>
     * Feature is enabled by default as of Jackson 3.0 (in 2.x it was disabled).
     */
    FAIL_ON_NULL_FOR_PRIMITIVES(true),

    /**
     * Feature that determines what happens when type of a polymorphic
     * value (indicated for example by {@link com.fasterxml.jackson.annotation.JsonTypeInfo})
     * cannot be found (missing) or resolved (invalid class name, non-mappable id);
     * if enabled, an exception is thrown; if false, null value is used instead.
     *<p>
     * Feature is enabled by default so that exception is thrown for missing or invalid
     * type information.
     */
    FAIL_ON_INVALID_SUBTYPE(true),

    /**
     * Feature that determines what happens when reading JSON content into tree
     * ({@link JsonNode} and a duplicate key
     * is encountered (property name that was already seen for the JSON Object).
     * If enabled, {@link DatabindException} will be thrown; if disabled, no exception
     * is thrown and the new (later) value overwrites the earlier value.
     *<p>
     * Note that this property does NOT affect other aspects of data-binding; that is,
     * no detection is done with respect to POJO properties or {@link java.util.Map}
     * keys. New features may be added to control additional cases.
     *<p>
     * Feature is disabled by default so that no exception is thrown.
     */
    FAIL_ON_READING_DUP_TREE_KEY(false),

    /**
     * Feature that determines what happens when a property that has been explicitly
     * marked as ignorable is encountered in input: if feature is enabled,
     * {@link DatabindException} is thrown; if false, property is quietly skipped.
     *<p>
     * Feature is disabled by default so that no exception is thrown.
     */
    FAIL_ON_IGNORED_PROPERTIES(false),

    /**
     * Feature that determines what happens if an Object Id reference is encountered
     * that does not refer to an actual Object with that id ("unresolved Object Id"):
     * either an exception {@link tools.jackson.databind.deser.UnresolvedForwardReference}
     * containing information about {@link tools.jackson.databind.deser.UnresolvedId}
     * is thrown (<code>true</code>), or a null object is used instead (<code>false</code>).
     * Note that if this is set to <code>false</code>, no further processing is done;
     * specifically, if reference is defined via setter method, that method will NOT
     * be called.
     *<p>
     * Feature is enabled by default, so that unknown Object Ids will result in an
     * exception being thrown, at the end of deserialization.
     */
    FAIL_ON_UNRESOLVED_OBJECT_IDS(true),

    /**
     * Feature that determines what happens if one or more Creator properties (properties
     * bound to parameters of Creator method (constructor or static factory method))
     * are missing value to bind to from content.
     * If enabled, such missing values result in a {@link DatabindException} being
     * thrown with information on the first one (by index) of missing properties.
     * If disabled, and if property is NOT marked as required,
     * missing Creator properties are filled
     * with <code>null values</code> provided by deserializer for the type of parameter
     * (usually null for Object types, and default value for primitives; but redefinable
     * via custom deserializers).
     *<p>
     * Note that having an injectable value counts as "not missing".
     *<p>
     * Feature is disabled by default, so that no exception is thrown for missing creator
     * property values, unless they are explicitly marked as `required`.
     */
    FAIL_ON_MISSING_CREATOR_PROPERTIES(false),

    /**
      * Feature that determines what happens if one or more Creator properties (properties
      * bound to parameters of Creator method (constructor or static factory method))
      * are bound to null values - either from the JSON or as a default value. This
      * is useful if you want to avoid nulls in your codebase, and particularly useful
      * if you are using Java or Scala {@code Optional}s for non-mandatory fields.
      * Feature is disabled by default, so that no exception is thrown for missing creator
      * property values, unless they are explicitly marked as `required`.
      */
    FAIL_ON_NULL_CREATOR_PROPERTIES(false),

    /**
     * Feature that determines what happens when a property annotated with
     * {@link com.fasterxml.jackson.annotation.JsonTypeInfo.As#EXTERNAL_PROPERTY} is missing,
     * but associated type id is available. If enabled, a {@link DatabindException} is always
     * thrown when property value is missing (if type id does exist);
     * if disabled, exception is only thrown if property is marked as {@code required}.
     *<p>
     * Feature is enabled by default, so that exception is thrown when a subtype property is
     * missing.
     */
    FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY(true),

    /**
     * Feature that determines behavior for data-binding after binding the root value.
     * If feature is enabled, one more call to
     * {@link tools.jackson.core.JsonParser#nextToken} is made to ensure that
     * no more tokens are found (and if any is found,
     * {@link tools.jackson.databind.exc.MismatchedInputException} is thrown); if
     * disabled, no further checks are made.
     *<p>
     * Feature could alternatively be called {@code READ_FULL_STREAM}, since it
     * effectively verifies that input stream contains only as much data as is needed
     * for binding the full value, and nothing more (except for possible ignorable
     * white space or comments, if supported by data format).
     *<p>
     * NOTE: this feature should usually be disabled when reading from
     * {@link java.io.DataInput}, since it cannot detect end-of-input efficiently
     * (but by throwing an {@link java.io.IOException}). Disabling is NOT done
     * automatically by Jackson: users are recommended to disable it.
     *<p>
     * Feature is enabled by default as of Jackson 3.0 (in 2.x it was disabled).
     */
    FAIL_ON_TRAILING_TOKENS(true),

    /**
     * Feature that determines behavior when deserializing polymorphic types that use
     * Class-based Type Id mechanism (either
     * {@code JsonTypeInfo.Id.CLASS} or {@code JsonTypeInfo.Id.MINIMAL_CLASS}):
     * If enabled, an exception will be
     * thrown if a subtype (Class) is encountered that has not been explicitly registered (by
     * calling {@link MapperBuilder#registerSubtypes} or using annotation
     * {@link com.fasterxml.jackson.annotation.JsonSubTypes}).
     *<p>
     * Note that for Type Name - based Type Id mechanism ({@code JsonTypeInfo.Id.NAME})
     * you already need to register the subtypes but with so this feature has no effect.
     *<p>
     * Feature is disabled by default.
     */
    FAIL_ON_SUBTYPE_CLASS_NOT_REGISTERED(false),

    /**
     * Feature that determines whether Jackson code should catch
     * and wrap non-Jackson {@link Exception}s (but never {@link Error}s!)
     * to add additional information about
     * location (within input) of problem or not. If enabled,
     * most exceptions will be caught and re-thrown; this can be
     * convenient both in that all exceptions will be checked and
     * declared, and so there is more contextual information.
     * However, sometimes calling application may just want "raw"
     * unchecked exceptions passed as is.
     *<p>
     * NOTE: most of the time exceptions that may or may not be wrapped are of
     * type {@link RuntimeException}: as mentioned earlier,
     * {@link tools.jackson.core.JacksonException}s) will
     * always be passed as-is.
     *<p>
     * Disabling this feature will mean that you will need to adjust your try/catch
     * blocks to properly handle {@link RuntimeException}s. Failing to do so,
     * may cause your application to crash due to unhandled exceptions.
     *<p>
     * Feature is enabled by default.
     */
    WRAP_EXCEPTIONS(true),

    /**
     * Feature that determines the handling of properties not included in the active JSON view
     * during deserialization.
     *<p>
     * When enabled, if a property is encountered during deserialization that is not part of the
     * active view (as defined by {@link com.fasterxml.jackson.annotation.JsonView}),
     * an exception is thrown. If disabled, the property is simply ignored.
     *<p>
     * This feature is particularly useful in scenarios where strict adherence to the specified
     * view is required and any deviation, such as the presence of properties not belonging to
     * the view, should be reported as an error. It can enhance the robustness of data binding
     * by ensuring that only the properties relevant to the active view are considered during
     * deserialization, thereby preventing unintended data from being processed.
     *<p>
     * Feature is disabled by default to maintain backward compatibility.
     */
    FAIL_ON_UNEXPECTED_VIEW_PROPERTIES(false),

    /**
     * Feature that determines the handling of injected properties during deserialization.
     *<p>
     * When enabled, if an injected property without matching value is encountered
     * during deserialization,  an exception is thrown.
     * When disabled, no exception is thrown.
     * See {@link JacksonInject#optional()} for per-property override
     * of this setting.
     *<p>
     * This feature is enabled by default to maintain backwards-compatibility.
     *
     * @see JacksonInject#optional()
     */
    FAIL_ON_UNKNOWN_INJECT_VALUE(true),

    /*
    /**********************************************************************
    /* Structural conversion features
    /**********************************************************************
     */

    /**
     * Feature that determines whether it is acceptable to coerce non-array
     * (in JSON) values to work with Java collection (arrays, java.util.Collection)
     * types. If enabled, collection deserializers will try to handle non-array
     * values as if they had "implicit" surrounding JSON array.
     * This feature is meant to be used for compatibility/interoperability reasons,
     * to work with packages (such as XML-to-JSON converters) that leave out JSON
     * array in cases where there is just a single element in array.
     *<p>
     * Feature is disabled by default.
     */
    ACCEPT_SINGLE_VALUE_AS_ARRAY(false),

    /**
     * Feature that determines whether it is acceptable to coerce single value array (in JSON)
     * values to the corresponding value type.  This is basically the opposite of the {@link #ACCEPT_SINGLE_VALUE_AS_ARRAY}
     * feature.  If more than one value is found in the array, a {@link DatabindException} is thrown.
     * <p>
     * NOTE: only <b>single</b> wrapper Array is allowed: if multiple attempted, exception
     * will be thrown.
     * <p>
     * Feature is disabled by default.
     */
    UNWRAP_SINGLE_VALUE_ARRAYS(false),

    /**
     * Feature to allow "unwrapping" root-level JSON value, to match setting of
     * {@link SerializationFeature#WRAP_ROOT_VALUE} used for serialization.
     * Will verify that the root JSON value is a JSON Object, and that it has
     * a single property with expected root name. If not, a
     * {@link DatabindException} is thrown; otherwise value of the wrapped property
     * will be deserialized as if it was the root value.
     * <p>
     * Feature is disabled by default.
     */
    UNWRAP_ROOT_VALUE(false),

    /*
    /**********************************************************************
    /* Value conversion/coercion features
    /**********************************************************************
     */

    /**
     * Feature that can be enabled to allow JSON empty String
     * value ({@code ""}) to be bound as {@code null} for POJOs and other structured
     * values ({@link java.util.Map}s, {@link java.util.Collection}s).
     * If disabled, standard POJOs can only be bound from JSON {@code null} or
     * JSON Object (standard meaning that no custom deserializers or
     * constructors are defined; both of which can add support for other
     * kinds of JSON values); if enabled, empty JSON String can be taken
     * to be equivalent of JSON null.
     *<p>
     * NOTE: this does NOT apply to scalar values such as Strings, booleans, numbers
     * and date/time types;
     * whether these can be coerced depends on
     * {@link MapperFeature#ALLOW_COERCION_OF_SCALARS}.
     *<p>
     * Feature is disabled by default.
     */
    ACCEPT_EMPTY_STRING_AS_NULL_OBJECT(false),

    /**
     * Feature that can be enabled to allow empty JSON Array
     * value (that is, {@code [ ]} to be bound to POJOs {@code null}.
     * If disabled, standard POJOs can only be bound from JSON {@code null} or
     * JSON Object (standard meaning that no custom deserializers or
     * constructors are defined; both of which can add support for other
     * kinds of JSON values); if enabled, empty JSON Array will be taken
     * to be equivalent of JSON {@code null}.
     *<p>
     * Feature is disabled by default.
     */
    ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT(false),

    /**
     * Feature that determines whether coercion from JSON floating point
     * number (anything with command (`.`) or exponent portion (`e` / `E'))
     * to an expected integral number (`int`, `long`, `java.lang.Integer`, `java.lang.Long`,
     * `java.math.BigDecimal`) is allowed or not.
     * If enabled, coercion truncates value; if disabled, a {@link DatabindException}
     * will be thrown.
     *<p>
     * Feature is enabled by default.
     */
    ACCEPT_FLOAT_AS_INT(true),

    /*
    /**********************************************************************
    /* Other
    /**********************************************************************
     */

    /**
     * Feature that determines whether {@link ObjectReader} should
     * try to eagerly fetch necessary {@link ValueDeserializer} when
     * possible. This improves performance in cases where similarly
     * configured {@link ObjectReader} instance is used multiple
     * times; and should not significantly affect single-use cases.
     *<p>
     * Note that there should not be any need to normally disable this
     * feature: only consider that if there are actual perceived problems.
     *<p>
     * Feature is enabled by default.
     */
    EAGER_DESERIALIZER_FETCH(true)

    ;

    private final boolean _defaultState;
    private final int _mask;

    private DeserializationFeature(boolean defaultState) {
        _defaultState = defaultState;
        _mask = (1 << ordinal());
    }

    @Override
    public boolean enabledByDefault() { return _defaultState; }

    @Override
    public int getMask() { return _mask; }

    @Override
    public boolean enabledIn(int flags) { return (flags & _mask) != 0; }
}