Package org.codehaus.jackson.map

Source Code of org.codehaus.jackson.map.DeserializationConfig

package org.codehaus.jackson.map;

import java.text.DateFormat;
import java.util.*;

import org.codehaus.jackson.Base64Variant;
import org.codehaus.jackson.Base64Variants;
import org.codehaus.jackson.annotate.*;
import org.codehaus.jackson.map.introspect.AnnotatedClass;
import org.codehaus.jackson.map.introspect.NopAnnotationIntrospector;
import org.codehaus.jackson.map.introspect.VisibilityChecker;
import org.codehaus.jackson.map.jsontype.SubtypeResolver;
import org.codehaus.jackson.map.jsontype.TypeResolverBuilder;
import org.codehaus.jackson.map.jsontype.impl.StdSubtypeResolver;
import org.codehaus.jackson.map.type.ClassKey;
import org.codehaus.jackson.map.util.LinkedNode;
import org.codehaus.jackson.map.util.StdDateFormat;
import org.codehaus.jackson.node.JsonNodeFactory;
import org.codehaus.jackson.type.JavaType;

/**
* Object that contains baseline configuration for deserialization
* process. An instance is owned by {@link ObjectMapper}, which makes
* a copy that is passed during serialization process to
* {@link DeserializerProvider} and {@link DeserializerFactory}.
*<p>
* Note: although configuration settings can be changed at any time
* (for factories and instances), they are not guaranteed to have
* effect if called after constructing relevant mapper or deserializer
* instance. This because some objects may be configured, constructed and
* cached first time they are needed.
*/
public class DeserializationConfig
    implements MapperConfig<DeserializationConfig>
{
    /**
     * Enumeration that defines togglable features that guide
     * the serialization feature.
     */
    public enum Feature {
        // // // Introspection configuration

        /**
         * Feature that determines whether annotation introspection
         * is used for configuration; if enabled, configured
         * {@link AnnotationIntrospector} will be used: if disabled,
         * no annotations are considered.
         *<P>
         * Feature is enabled by default.
         *
         * @since 1.2
         */
        USE_ANNOTATIONS(true),

        /**
         * Feature that determines whether "setter" methods are
         * automatically detected based on standard Bean naming convention
         * or not. If yes, then all public one-argument methods that
         * start with prefix "set"
         * are considered setters. If disabled, only methods explicitly
         * annotated are considered setters.
         *<p>
         * Note that this feature has lower precedence than per-class
         * annotations, and is only used if there isn't more granular
         * configuration available.
         *<P>
         * Feature is enabled by default.
         */
        AUTO_DETECT_SETTERS(true),

        /**
         * Feature that determines whether "creator" methods are
         * automatically detected by consider public constructors,
         * and static single argument methods with name "valueOf".
         * If disabled, only methods explicitly annotated are considered
         * creator methods (except for the no-arg default constructor which
         * is always considered a factory method).
         *<p>
         * Note that this feature has lower precedence than per-class
         * annotations, and is only used if there isn't more granular
         * configuration available.
         *<P>
         * Feature is enabled by default.
         */
        AUTO_DETECT_CREATORS(true),

        /**
         * Feature that determines whether non-static fields are recognized as
         * properties.
         * If yes, then all public member fields
         * are considered as properties. If disabled, only fields explicitly
         * annotated are considered property fields.
         *<p>
         * Note that this feature has lower precedence than per-class
         * annotations, and is only used if there isn't more granular
         * configuration available.
         *<P>
         * Feature is enabled by default.
         *
         * @since 1.1
         */
        AUTO_DETECT_FIELDS(true),

        /**
         * Feature that determines whether otherwise regular "getter"
         * methods (but only ones that handle Collections and Maps,
         * not getters of other type)
         * can be used for purpose of getting a reference to a Collection
         * and Map to modify the property, without requiring a setter
         * method.
         * This is similar to how JAXB framework sets Collections and
         * Maps: no setter is involved, just setter.
         *<p>
         * Note that such getters-as-setters methods have lower
         * precedence than setters, so they are only used if no
         * setter is found for the Map/Collection property.
         *<p>
         * Feature is enabled by default.
         */
        USE_GETTERS_AS_SETTERS(true),

        /**
         * Feature that determines whether method and field access
         * modifier settings can be overridden when accessing
         * properties. If enabled, method
         * {@link java.lang.reflect.AccessibleObject#setAccessible}
         * may be called to enable access to otherwise unaccessible
         * objects.
         */
        CAN_OVERRIDE_ACCESS_MODIFIERS(true),

        // // // Type conversion configuration

        /**
         * 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>
         * 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" floating
         * point 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 standard deserialization mechanism used for
         * Enum values: if enabled, Enums are assumed to have been serialized  using
         * return value of <code>Enum.toString()</code>;
         * if disabled, return value of <code>Enum.name()</code> is assumed to have been used.
         * Since pre-1.6 method was to use Enum name, this is the default.
         *<p>
         * Note: this feature should usually have same value
         * as {@link SerializationConfig.Feature#WRITE_ENUMS_USING_TO_STRING}.
         *<p>
         * For further details, check out [JACKSON-212]
         *
         * @since 1.6
         */
        READ_ENUMS_USING_TO_STRING(false),
       
        // // // Problem handling

        /**
         * 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 JsonMappingException}) or not.
         * This setting only takes effect after all other handling
         * methods for unknown properties have been tried, and
         * property remains unhandled.
         *<p>
         * Feature is enabled by default, meaning that
         * {@link JsonMappingException} is thrown if an unknown property
         * is encountered. This is the implicit default prior to
         * introduction of the feature.
         *
         * @since 1.2
         */
        FAIL_ON_UNKNOWN_PROPERTIES(true),

        // // // Structural changes

        /**
         * Feature that can be enabled to handle "wrapped" values
         * (see {@link SerializationConfig.Feature#WRAP_ROOT_VALUE}
         * for details).
         * If enabled, value being deserialized must be a single-property
         * JSON Object where the key name matches expected "root name"
         * (determined using annotation, or if none, fallback which is
         * the unqualified class name of the expected value)
         *<p>
         * Default setting is false, meaning root value is not wrapped.
         *
         * @since 1.3
         */
        WRAP_ROOT_VALUE(false)
        ;

        final boolean _defaultState;

        /**
         * Method that calculates bit set (flags) of all features that
         * are enabled by default.
         */
        public static int collectDefaults()
        {
            int flags = 0;
            for (Feature f : values()) {
                if (f.enabledByDefault()) {
                    flags |= f.getMask();
                }
            }
            return flags;
        }
         
        private Feature(boolean defaultState) {
            _defaultState = defaultState;
        }
         
        public boolean enabledByDefault() { return _defaultState; }
   
        public int getMask() { return (1 << ordinal()); }
    }

    /**
     * Bitfield (set of flags) of all Features that are enabled
     * by default.
     */
    protected final static int DEFAULT_FEATURE_FLAGS = Feature.collectDefaults();

    protected final static DateFormat DEFAULT_DATE_FORMAT = StdDateFormat.instance;

    /*
    /**********************************************************
    /* Configuration settings
    /**********************************************************
     */

    /**
     * Introspector used to figure out Bean properties needed for bean serialization
     * and deserialization. Overridable so that it is possible to change low-level
     * details of introspection, like adding new annotation types.
     */
    protected ClassIntrospector<? extends BeanDescription> _classIntrospector;

    /**
     * Introspector used for accessing annotation value based configuration.
     */
    protected AnnotationIntrospector _annotationIntrospector;

    /**
     * Bit set that contains all enabled features
     */
    protected int _featureFlags = DEFAULT_FEATURE_FLAGS;

    /**
     * Linked list that contains all registered problem handlers.
     * Implementation as front-added linked list allows for sharing
     * of the list (tail) without copying the list.
     */
    protected LinkedNode<DeserializationProblemHandler> _problemHandlers;

    /**
     * Custom date format to use for de-serialization. If specified, will be
     * used instead of {@link org.codehaus.jackson.map.util.StdDateFormat}.
     *<p>
     * Note that the configured format object will be cloned once per
     * deserialization process (first time it is needed)
     */
    protected DateFormat _dateFormat = DEFAULT_DATE_FORMAT;

    /**
     * Mapping that defines how to apply mix-in annotations: key is
     * the type to received additional annotations, and value is the
     * type that has annotations to "mix in".
     *<p>
     * Annotations associated with the value classes will be used to
     * override annotations of the key class, associated with the
     * same field or method. They can be further masked by sub-classes:
     * you can think of it as injecting annotations between the target
     * class and its sub-classes (or interfaces)
     *
     * @since 1.2
     */
    protected HashMap<ClassKey,Class<?>> _mixInAnnotations;


    /**
     * Flag used to detect when a copy if mix-in annotations is
     * needed: set when current copy is shared, cleared when a
     * fresh copy is made
     *
     * @since 1.2
     */
    protected boolean _mixInAnnotationsShared;

    /**
     * Type information handler used for "untyped" values (ones declared
     * to have type <code>Object.class</code>)
     *
     * @since 1.5
     */
    protected final TypeResolverBuilder<?> _typer;

    /**
     * Object used for determining whether specific property elements
     * (method, constructors, fields) can be auto-detected based on
     * their visibility (access modifiers). Can be changed to allow
     * different minimum visibility levels for auto-detection. Note
     * that this is the global handler; individual types (classes)
     * can further override active checker used (using
     * {@link JsonAutoDetect} annotation)
     *
     * @since 1.5
     */
    protected VisibilityChecker<?> _visibilityChecker;

    /**
     * Registered concrete subtypes that can be used instead of (or
     * in addition to) ones declared using annotations.
     *
     * @since 1.6
     */
    protected SubtypeResolver _subtypeResolver;

    /**
     * To support on-the-fly class generation for interface and abstract classes
     * it is possible to register "abstract type resolver".
     *
     * @since 1.6
     */
    protected AbstractTypeResolver _abstractTypeResolver;
   
    /**
     * Factory used for constructing {@link org.codehaus.jackson.JsonNode} instances.
     *
     * @since 1.6
     */
    protected JsonNodeFactory _nodeFactory;
   
    /*
    /**********************************************************
    /* Life-cycle
    /**********************************************************
     */

    public DeserializationConfig(ClassIntrospector<? extends BeanDescription> intr,
                               AnnotationIntrospector annIntr, VisibilityChecker<?> vc,
                               SubtypeResolver subtypeResolver)
    {
        _classIntrospector = intr;
        _annotationIntrospector = annIntr;
        _typer = null;
        _visibilityChecker = vc;
        _subtypeResolver = subtypeResolver;
        _nodeFactory = JsonNodeFactory.instance;
    }

    protected DeserializationConfig(DeserializationConfig src,
                                    HashMap<ClassKey,Class<?>> mixins,
                                    TypeResolverBuilder<?> typer,
                                    VisibilityChecker<?> vc,
                                    SubtypeResolver subtypeResolver)
    {
        _classIntrospector = src._classIntrospector;
        _annotationIntrospector = src._annotationIntrospector;
        _abstractTypeResolver = src._abstractTypeResolver;
        _featureFlags = src._featureFlags;
        _problemHandlers = src._problemHandlers;
        _dateFormat = src._dateFormat;
        _nodeFactory = src._nodeFactory;
        _mixInAnnotations = mixins;
        _typer = typer;
        _visibilityChecker = vc;
        _subtypeResolver = subtypeResolver;
    }

    /*
    /**********************************************************
    /* Configuration: on/off features
    /**********************************************************
     */

    /**
     * Method for enabling specified  feature.
     */
    public void enable(Feature f) {
        _featureFlags |= f.getMask();
    }

    /**
     * Method for disabling specified feature.
     */
    public void disable(Feature f) {
        _featureFlags &= ~f.getMask();
    }

    /**
     * Method for enabling or disabling specified feature.
     */
    public void set(Feature f, boolean state)
    {
        if (state) {
            enable(f);
        } else {
            disable(f);
        }
    }

    /**
     * Method for checking whether given feature is enabled or not
     */
    public final boolean isEnabled(Feature f) {
        return (_featureFlags & f.getMask()) != 0;
    }

    //protected int getFeatures() { return _generatorFeatures; }
   
    /*
    /**********************************************************
    /* MapperConfig implementation
    /**********************************************************
     */

    /**
     * Method that checks class annotations that the argument Object has,
     * and modifies settings of this configuration object accordingly,
     * similar to how those annotations would affect actual value classes
     * annotated with them, but with global scope. Note that not all
     * annotations have global significance, and thus only subset of
     * Jackson annotations will have any effect.
     *<p>
     * Ones that are known to have effect are:
     *<ul>
     * <li>{@link JsonAutoDetect}</li>
     *</ul>
     *
     * @param cls Class of which class annotations to use
     *   for changing configuration settings
     */
    //@Override
    public void fromAnnotations(Class<?> cls)
    {
      /* no class annotation for:
         *
         * - CAN_OVERRIDE_ACCESS_MODIFIERS
         * - USE_BIG_DECIMAL_FOR_FLOATS
         * - USE_BIG_INTEGER_FOR_INTS
         * - USE_GETTERS_AS_SETTERS
         */

        /* 10-Jul-2009, tatu: Should be able to just pass null as
         *    'MixInResolver'; no mix-ins set at this point
         */
        AnnotatedClass ac = AnnotatedClass.construct(cls, _annotationIntrospector, null);
        // visibility checks handled via separate checker object...
        _visibilityChecker = _annotationIntrospector.findAutoDetectVisibility(ac, _visibilityChecker);
    }

    /**
     * Method that is called to create a non-shared copy of the configuration
     * to be used for a deserialization operation.
     * Note that if sub-classing
     * and sub-class has additional instance methods,
     * this method <b>must</b> be overridden to produce proper sub-class
     * instance.
     */
    //@Override
    public DeserializationConfig createUnshared(TypeResolverBuilder<?> typer,
        VisibilityChecker<?> vc, SubtypeResolver subtypeResolver)
    {
        HashMap<ClassKey,Class<?>> mixins = _mixInAnnotations;
        _mixInAnnotationsShared = true;
      return new DeserializationConfig(this, mixins, typer, vc, subtypeResolver);
    }

    /**
     * Alternative "copy factory" that creates an unshared copy that uses
     * different node factory than this instance.
     *
     * @since 1.6
     */
    public DeserializationConfig createUnshared(JsonNodeFactory nf)
    {
        DeserializationConfig config = createUnshared(_typer, _visibilityChecker, _subtypeResolver);
        config.setNodeFactory(nf);
        return config;
    }

    //@Override
    public void setIntrospector(ClassIntrospector<? extends BeanDescription> i) {
        _classIntrospector = i;
    }

    /**
     * Method for getting {@link AnnotationIntrospector} configured
     * to introspect annotation values used for configuration.
     */
    //@Override
    public AnnotationIntrospector getAnnotationIntrospector()
    {
        /* 29-Jul-2009, tatu: it's now possible to disable use of
         *   annotations; can be done using "no-op" introspector
         */
        if (isEnabled(Feature.USE_ANNOTATIONS)) {
            return _annotationIntrospector;
        }
        return NopAnnotationIntrospector.instance;
    }

    //@Override
    public void setAnnotationIntrospector(AnnotationIntrospector introspector)
    {
        _annotationIntrospector = introspector;
    }

    /**
     * Method to use for defining mix-in annotations to use for augmenting
     * annotations that deserializable classes have.
     * Mixing in is done when introspecting class annotations and properties.
     * Map passed contains keys that are target classes (ones to augment
     * with new annotation overrides), and values that are source classes
     * (have annotations to use for augmentation).
     * Annotations from source classes (and their supertypes)
     * will <b>override</b>
     * annotations that target classes (and their super-types) have.
     *<p>
     * Note: a copy of argument Map is created; the original Map is
     * not modified or retained by this config object.
     *
     * @since 1.2
     */
    //@Override
    public void setMixInAnnotations(Map<Class<?>, Class<?>> sourceMixins)
    {
        HashMap<ClassKey,Class<?>> mixins = null;
        if (sourceMixins != null && sourceMixins.size() > 0) {
            mixins = new HashMap<ClassKey,Class<?>>(sourceMixins.size());
            for (Map.Entry<Class<?>,Class<?>> en : sourceMixins.entrySet()) {
                mixins.put(new ClassKey(en.getKey()), en.getValue());
            }
        }
        _mixInAnnotationsShared = false;
        _mixInAnnotations = mixins;
    }

    //@Override
    public void addMixInAnnotations(Class<?> target, Class<?> mixinSource)
    {
        if (_mixInAnnotations == null || _mixInAnnotationsShared) {
            _mixInAnnotationsShared = false;
            _mixInAnnotations = new HashMap<ClassKey,Class<?>>();
        }
        _mixInAnnotations.put(new ClassKey(target), mixinSource);
    }

    /**
     * @since 1.2
     */
    //@Override
    public Class<?> findMixInClassFor(Class<?> cls) {
        return (_mixInAnnotations == null) ? null : _mixInAnnotations.get(new ClassKey(cls));
    }

    //@Override
    public DateFormat getDateFormat() { return _dateFormat; }

    /**
     * Method that will set the textual deserialization to use for
     * deserializing Dates (and Calendars). If null is passed, will
     * use {@link StdDateFormat}.
     */
    //@Override
    public void setDateFormat(DateFormat df) {
        _dateFormat = (df == null) ? StdDateFormat.instance : df;
    }

    //@Override
    public VisibilityChecker<?> getDefaultVisibilityChecker() {
        return _visibilityChecker;
    }

    //@Override
    public TypeResolverBuilder<?> getDefaultTyper(JavaType baseType) {
        return _typer;
    }

    /**
     * @since 1.6
     */
    public SubtypeResolver getSubtypeResolver() {
        if (_subtypeResolver == null) {
            _subtypeResolver = new StdSubtypeResolver();
        }
        return _subtypeResolver;
    }

    /**
     * @since 1.6
     */
    public void setSubtypeResolver(SubtypeResolver r) {
        _subtypeResolver = r;
    }
   
    /*
    /**********************************************************
    /* Problem handlers
    /**********************************************************
     */

    /**
     * Method for getting head of the problem handler chain. May be null,
     * if no handlers have been added.
     */
    public LinkedNode<DeserializationProblemHandler> getProblemHandlers()
    {
        return _problemHandlers;
    }
   
    /**
     * Method that can be used to add a handler that can (try to)
     * resolve non-fatal deserialization problems.
     */
    public void addHandler(DeserializationProblemHandler h)
    {
        /* Sanity check: let's prevent adding same handler multiple
         * times
         */
        if (!LinkedNode.contains(_problemHandlers, h)) {
            _problemHandlers = new LinkedNode<DeserializationProblemHandler>(h, _problemHandlers);
        }
    }

    /**
     * Method for removing all configuring problem handlers; usually done to replace
     * existing handler(s) with different one(s)
     *
     * @since 1.1
     */
    public void clearHandlers()
    {
        _problemHandlers = null;
    }

    /*
    /**********************************************************
    /* Introspection methods
    /**********************************************************
     */

    /**
     * Method that will introspect full bean properties for the purpose
     * of building a bean deserializer
     *
     * @param type Type of class to be introspected
     */
    @SuppressWarnings("unchecked")
    public <T extends BeanDescription> T introspect(JavaType type) {
        return (T) _classIntrospector.forDeserialization(this, type, this);
    }

    /**
     * Method that will introspect subset of bean properties needed to
     * construct bean instance.
     */
    @SuppressWarnings("unchecked")
    public <T extends BeanDescription> T introspectForCreation(JavaType type) {
        return (T) _classIntrospector.forCreation(this, type, this);
    }

    /**
     * Accessor for getting bean description that only contains class
     * annotations: useful if no getter/setter/creator information is needed.
     */
    @SuppressWarnings("unchecked")
    public <T extends BeanDescription> T introspectClassAnnotations(Class<?> cls) {
        return (T) _classIntrospector.forClassAnnotations(this, cls, this);
    }

    /**
     * Accessor for getting bean description that only contains immediate class
     * annotations: ones from the class, and its direct mix-in, if any, but
     * not from super types.
     */
    @SuppressWarnings("unchecked")
    public <T extends BeanDescription> T introspectDirectClassAnnotations(Class<?> cls) {
        return (T) _classIntrospector.forDirectClassAnnotations(this, cls, this);
    }
   
    /*
    /**********************************************************
    /* Polymorphic type handling configuration
    /**********************************************************
     */

    /**
     * Method for accessing {@link AbstractTypeResolver} configured, if any
     * (no default) used for resolving abstract types into concrete
     * types (either by mapping or materializing new classes).
     *
     * @since 1.6
     */
    public AbstractTypeResolver getAbstractTypeResolver() {
        return _abstractTypeResolver;
    }
   
    /**
     * @since 1.6
     */
    public void setAbstractTypeResolver(AbstractTypeResolver atr) {
        _abstractTypeResolver = atr;
    }
   
    /*
    /**********************************************************
    /* Other configuration
    /**********************************************************
     */

    /**
     * Method called during deserialization if Base64 encoded content
     * needs to be decoded. Default version just returns default Jackson
     * uses, which is modified-mime which does not add linefeeds (because
     * those would have to be escaped in Json strings).
     */
    public Base64Variant getBase64Variant() {
        return Base64Variants.getDefaultVariant();
    }
   
    /**
     * @since 1.6
     */
    public void setNodeFactory(JsonNodeFactory nf) {
        _nodeFactory = nf;
    }

    /**
     * @since 1.6
     */
    public final JsonNodeFactory getNodeFactory() {
        return _nodeFactory;
    }
}
TOP

Related Classes of org.codehaus.jackson.map.DeserializationConfig

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.