| 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.annotate.JsonAutoDetect.Visibility; |
| import org.codehaus.jackson.map.deser.ValueInstantiator; |
| import org.codehaus.jackson.map.introspect.Annotated; |
| 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.type.ClassKey; |
| import org.codehaus.jackson.map.type.TypeFactory; |
| import org.codehaus.jackson.map.util.ClassUtil; |
| import org.codehaus.jackson.map.util.LinkedNode; |
| 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. |
| *<p> |
| * As of version 1.9, the goal is to make this class eventually immutable. |
| * Because of this, existing methods that allow changing state of this |
| * instance are deprecated in favor of methods that create new instances |
| * with different configuration ("fluent factories") |
| */ |
| public class DeserializationConfig |
| extends MapperConfig.Impl<DeserializationConfig.Feature, DeserializationConfig> |
| { |
| /** |
| * Enumeration that defines togglable features that guide |
| * the serialization feature. |
| */ |
| public enum Feature implements MapperConfig.ConfigFeature |
| { |
| /* |
| /****************************************************** |
| * Introspection features |
| /****************************************************** |
| */ |
| |
| /** |
| * 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 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> |
| * 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), |
| |
| // [JACKSON-652] |
| /** |
| * Feature that determines whether JSON Array is mapped to |
| * <code>Object[]</code> or <code>List<Object></code> 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></code>. |
| *<p> |
| * Feature is disabled by default, meaning that JSON arrays are bound as |
| * {@link java.util.List}s. |
| * |
| * @since 1.9 |
| */ |
| USE_JAVA_ARRAY_FOR_JSON_ARRAY(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), |
| |
| /* |
| /****************************************************** |
| * 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 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), |
| |
| /** |
| * 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 JsonProcessingException |
| * 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 disabled by default (to be consistent with behavior |
| * of Jackson 1.6), |
| * i.e. to allow use of nulls for primitive properties. |
| * |
| * @since 1.7 |
| */ |
| FAIL_ON_NULL_FOR_PRIMITIVES(false), |
| |
| /** |
| * Feature that determines whether JSON integer numbers are valid |
| * values to be used for deserializing Java enum values. |
| * If set to 'false' numbers are acceptable and are used to map to |
| * ordinal() of matching enumeration value; if 'true', numbers are |
| * not allowed and a {@link JsonMappingException} will be thrown. |
| * Latter behavior makes sense if there is concern that accidental |
| * mapping from integer values to enums might happen (and when enums |
| * are always serialized as JSON Strings) |
| *<p> |
| * Feature is disabled by default (to be consistent with behavior |
| * of Jackson 1.6), |
| * i.e. to allow use of JSON integers for Java enums. |
| * |
| * @since 1.7 |
| */ |
| FAIL_ON_NUMBERS_FOR_ENUMS(false), |
| |
| /** |
| * Feature that determines whether Jackson code should catch |
| * and wrap {@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 (exception |
| * specifically being that {@link java.io.IOException}s may be passed |
| * as is, since they are declared as throwable); 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> |
| * Feature is enabled by default, and is similar in behavior |
| * to default prior to 1.7. |
| * |
| * @since 1.7 |
| */ |
| WRAP_EXCEPTIONS(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. |
| * |
| * @since 1.8 |
| */ |
| ACCEPT_SINGLE_VALUE_AS_ARRAY(false), |
| |
| /** |
| * Feature to allow "unwrapping" root-level JSON value, to match setting of |
| * {@link SerializationConfig.Feature#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 JsonMappingException} is thrown; otherwise value of the wrapped property |
| * will be deserialized as if it was the root value. |
| * |
| * @since 1.9 |
| */ |
| UNWRAP_ROOT_VALUE(false), |
| |
| /* |
| /****************************************************** |
| * Value conversion features |
| /****************************************************** |
| */ |
| |
| /** |
| * Feature that can be enabled to allow JSON empty String |
| * value ("") to be bound to POJOs as null. |
| * If disabled, standard POJOs can only be bound from JSON 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 enable, empty JSON String can be taken |
| * to be equivalent of JSON null. |
| * |
| * @since 1.8 |
| */ |
| ACCEPT_EMPTY_STRING_AS_NULL_OBJECT(false) |
| |
| ; |
| |
| final boolean _defaultState; |
| |
| private Feature(boolean defaultState) { |
| _defaultState = defaultState; |
| } |
| |
| @Override |
| public boolean enabledByDefault() { return _defaultState; } |
| |
| @Override |
| public int getMask() { return (1 << ordinal()); } |
| } |
| |
| /* |
| /********************************************************** |
| /* Configuration settings for deserialization |
| /********************************************************** |
| */ |
| |
| /** |
| * 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; |
| |
| /** |
| * Factory used for constructing {@link org.codehaus.jackson.JsonNode} instances. |
| * |
| * @since 1.6 |
| */ |
| protected final JsonNodeFactory _nodeFactory; |
| |
| /** |
| * Feature flag from {@link SerializationConfig} which is needed to |
| * know if serializer will by default sort properties in |
| * alphabetic order. |
| *<p> |
| * Note that although this property is not marked as final, |
| * it is handled like it was, except for the fact that it is |
| * assigned with a call to {@link #passSerializationFeatures} |
| * instead of constructor. |
| * |
| * @since 1.9 |
| */ |
| protected boolean _sortPropertiesAlphabetically; |
| |
| /* |
| /********************************************************** |
| /* Life-cycle, constructors |
| /********************************************************** |
| */ |
| |
| /** |
| * Constructor used by ObjectMapper to create default configuration object instance. |
| */ |
| public DeserializationConfig(ClassIntrospector<? extends BeanDescription> intr, |
| AnnotationIntrospector annIntr, VisibilityChecker<?> vc, |
| SubtypeResolver subtypeResolver, PropertyNamingStrategy propertyNamingStrategy, |
| TypeFactory typeFactory, HandlerInstantiator handlerInstantiator) |
| { |
| super(intr, annIntr, vc, subtypeResolver, propertyNamingStrategy, typeFactory, handlerInstantiator, |
| collectFeatureDefaults(DeserializationConfig.Feature.class)); |
| _nodeFactory = JsonNodeFactory.instance; |
| } |
| |
| /** |
| * @since 1.8 |
| */ |
| protected DeserializationConfig(DeserializationConfig src) { |
| this(src, src._base); |
| } |
| |
| /** |
| * Copy constructor used to create a non-shared instance with given mix-in |
| * annotation definitions and subtype resolver. |
| * |
| * @since 1.8 |
| */ |
| private DeserializationConfig(DeserializationConfig src, |
| HashMap<ClassKey,Class<?>> mixins, SubtypeResolver str) |
| { |
| this(src, src._base); |
| _mixInAnnotations = mixins; |
| _subtypeResolver = str; |
| } |
| |
| /** |
| * @since 1.8 |
| */ |
| protected DeserializationConfig(DeserializationConfig src, MapperConfig.Base base) |
| { |
| super(src, base, src._subtypeResolver); |
| _problemHandlers = src._problemHandlers; |
| _nodeFactory = src._nodeFactory; |
| _sortPropertiesAlphabetically = src._sortPropertiesAlphabetically; |
| } |
| |
| /** |
| * @since 1.8 |
| */ |
| protected DeserializationConfig(DeserializationConfig src, JsonNodeFactory f) |
| { |
| super(src); |
| _problemHandlers = src._problemHandlers; |
| _nodeFactory = f; |
| _sortPropertiesAlphabetically = src._sortPropertiesAlphabetically; |
| } |
| |
| /** |
| * @since 1.9 |
| */ |
| protected DeserializationConfig(DeserializationConfig src, int featureFlags) |
| { |
| super(src, featureFlags); |
| _problemHandlers = src._problemHandlers; |
| _nodeFactory = src._nodeFactory; |
| _sortPropertiesAlphabetically = src._sortPropertiesAlphabetically; |
| } |
| |
| /** |
| * Helper method to be called right after creating a non-shared |
| * instance, needed to pass state of feature(s) shared with |
| * SerializationConfig. |
| * |
| * Since 1.9 |
| */ |
| protected DeserializationConfig passSerializationFeatures(int serializationFeatureFlags) |
| { |
| _sortPropertiesAlphabetically = (serializationFeatureFlags |
| & SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY.getMask()) != 0; |
| return this; |
| } |
| |
| /* |
| /********************************************************** |
| /* Life-cycle, factory methods from MapperConfig |
| /********************************************************** |
| */ |
| |
| @Override |
| public DeserializationConfig withClassIntrospector(ClassIntrospector<? extends BeanDescription> ci) { |
| return new DeserializationConfig(this, _base.withClassIntrospector(ci)); |
| } |
| |
| @Override |
| public DeserializationConfig withAnnotationIntrospector(AnnotationIntrospector ai) { |
| return new DeserializationConfig(this, _base.withAnnotationIntrospector(ai)); |
| } |
| |
| @Override |
| public DeserializationConfig withVisibilityChecker(VisibilityChecker<?> vc) { |
| return new DeserializationConfig(this, _base.withVisibilityChecker(vc)); |
| } |
| |
| @Override |
| public DeserializationConfig withVisibility(JsonMethod forMethod, JsonAutoDetect.Visibility visibility) { |
| return new DeserializationConfig(this, _base.withVisibility(forMethod, visibility)); |
| } |
| |
| @Override |
| public DeserializationConfig withTypeResolverBuilder(TypeResolverBuilder<?> trb) { |
| return new DeserializationConfig(this, _base.withTypeResolverBuilder(trb)); |
| } |
| |
| @Override |
| public DeserializationConfig withSubtypeResolver(SubtypeResolver str) |
| { |
| DeserializationConfig cfg = new DeserializationConfig(this); |
| cfg._subtypeResolver = str; |
| return cfg; |
| } |
| |
| @Override |
| public DeserializationConfig withPropertyNamingStrategy(PropertyNamingStrategy pns) { |
| return new DeserializationConfig(this, _base.withPropertyNamingStrategy(pns)); |
| } |
| |
| @Override |
| public DeserializationConfig withTypeFactory(TypeFactory tf) { |
| return (tf == _base.getTypeFactory()) ? this : new DeserializationConfig(this, _base.withTypeFactory(tf)); |
| } |
| |
| @Override |
| public DeserializationConfig withDateFormat(DateFormat df) { |
| return (df == _base.getDateFormat()) ? this : new DeserializationConfig(this, _base.withDateFormat(df)); |
| } |
| |
| @Override |
| public DeserializationConfig withHandlerInstantiator(HandlerInstantiator hi) { |
| return (hi == _base.getHandlerInstantiator()) ? this : new DeserializationConfig(this, _base.withHandlerInstantiator(hi)); |
| } |
| |
| @Override |
| public DeserializationConfig withInsertedAnnotationIntrospector(AnnotationIntrospector ai) { |
| return new DeserializationConfig(this, _base.withInsertedAnnotationIntrospector(ai)); |
| } |
| |
| @Override |
| public DeserializationConfig withAppendedAnnotationIntrospector(AnnotationIntrospector ai) { |
| return new DeserializationConfig(this, _base.withAppendedAnnotationIntrospector(ai)); |
| } |
| |
| /* |
| /********************************************************** |
| /* Life-cycle, deserialization-specific factory methods |
| /********************************************************** |
| */ |
| |
| /** |
| * Fluent factory method that will construct a new instance with |
| * specified {@link JsonNodeFactory} |
| * |
| * @since 1.8 |
| */ |
| public DeserializationConfig withNodeFactory(JsonNodeFactory f) { |
| return new DeserializationConfig(this, f); |
| } |
| |
| /** |
| * Fluent factory method that will construct and return a new configuration |
| * object instance with specified features enabled. |
| * |
| * @since 1.9 |
| */ |
| @Override |
| public DeserializationConfig with(DeserializationConfig.Feature... features) |
| { |
| int flags = _featureFlags; |
| for (Feature f : features) { |
| flags |= f.getMask(); |
| } |
| return new DeserializationConfig(this, flags); |
| } |
| |
| /** |
| * Fluent factory method that will construct and return a new configuration |
| * object instance with specified features disabled. |
| * |
| * @since 1.9 |
| */ |
| @Override |
| public DeserializationConfig without(DeserializationConfig.Feature... features) |
| { |
| int flags = _featureFlags; |
| for (Feature f : features) { |
| flags &= ~f.getMask(); |
| } |
| return new DeserializationConfig(this, flags); |
| } |
| |
| /* |
| /********************************************************** |
| /* 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 |
| * |
| * @deprecated Since 1.9, it is preferably to explicitly configure |
| * instances; this method also modifies existing instance which is |
| * against immutable design goals of this class. |
| */ |
| @Deprecated |
| @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 |
| */ |
| AnnotationIntrospector ai = getAnnotationIntrospector(); |
| AnnotatedClass ac = AnnotatedClass.construct(cls, ai, null); |
| // visibility checks handled via separate checker object... |
| VisibilityChecker<?> prevVc = getDefaultVisibilityChecker(); |
| _base = _base.withVisibilityChecker(ai.findAutoDetectVisibility(ac, prevVc)); |
| } |
| |
| /** |
| * 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(SubtypeResolver subtypeResolver) |
| { |
| HashMap<ClassKey,Class<?>> mixins = _mixInAnnotations; |
| // ensure that we assume sharing at this point: |
| _mixInAnnotationsShared = true; |
| return new DeserializationConfig(this, mixins, subtypeResolver); |
| } |
| |
| /** |
| * 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 super.getAnnotationIntrospector(); |
| } |
| return NopAnnotationIntrospector.instance; |
| } |
| |
| /** |
| * Accessor for getting bean description that only contains class |
| * annotations: useful if no getter/setter/creator information is needed. |
| *<p> |
| * Note: part of {@link MapperConfig} since 1.7 |
| */ |
| @SuppressWarnings("unchecked") |
| @Override |
| public <T extends BeanDescription> T introspectClassAnnotations(JavaType type) { |
| return (T) getClassIntrospector().forClassAnnotations(this, type, 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. |
| *<p> |
| * Note: part of {@link MapperConfig} since 1.7 |
| */ |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T extends BeanDescription> T introspectDirectClassAnnotations(JavaType type) { |
| return (T) getClassIntrospector().forDirectClassAnnotations(this, type, this); |
| } |
| |
| @Override |
| public boolean isAnnotationProcessingEnabled() { |
| return isEnabled(Feature.USE_ANNOTATIONS); |
| } |
| |
| @Override |
| public boolean canOverrideAccessModifiers() { |
| return isEnabled(Feature.CAN_OVERRIDE_ACCESS_MODIFIERS); |
| } |
| |
| @Override |
| public boolean shouldSortPropertiesAlphabetically() { |
| return _sortPropertiesAlphabetically; |
| } |
| |
| @Override |
| public VisibilityChecker<?> getDefaultVisibilityChecker() |
| { |
| VisibilityChecker<?> vchecker = super.getDefaultVisibilityChecker(); |
| if (!isEnabled(DeserializationConfig.Feature.AUTO_DETECT_SETTERS)) { |
| vchecker = vchecker.withSetterVisibility(Visibility.NONE); |
| } |
| if (!isEnabled(DeserializationConfig.Feature.AUTO_DETECT_CREATORS)) { |
| vchecker = vchecker.withCreatorVisibility(Visibility.NONE); |
| } |
| if (!isEnabled(DeserializationConfig.Feature.AUTO_DETECT_FIELDS)) { |
| vchecker = vchecker.withFieldVisibility(Visibility.NONE); |
| } |
| return vchecker; |
| } |
| |
| /* |
| /********************************************************** |
| /* MapperConfig overrides for 1.8 backwards compatibility |
| /********************************************************** |
| */ |
| |
| /* NOTE: these are overloads we MUST have, but that were missing |
| * from 1.9.0 and 1.9.1. Type erasure can bite in the ass... |
| *<p> |
| * NOTE: will remove either these variants, or base class one, in 2.0. |
| */ |
| |
| /** |
| * An overload for {@link MapperConfig#isEnabled(MapperConfig.ConfigFeature)}, |
| * needed for backwards-compatibility. |
| *<p> |
| * NOTE: will remove either this variant, or base class one, in 2.0./ |
| * |
| * @since 1.0 However, note that version 1.9.0 and 1.9.1 accidentally missed |
| * this overloaded variant |
| */ |
| public boolean isEnabled(DeserializationConfig.Feature f) { |
| return (_featureFlags & f.getMask()) != 0; |
| } |
| |
| /** |
| * @deprecated Since 1.9, it is preferable to use {@link #with} instead; |
| * this method is deprecated as it modifies current instance instead of |
| * creating a new one (as the goal is to make this class immutable) |
| */ |
| @Deprecated |
| @Override |
| public void enable(DeserializationConfig.Feature f) { |
| super.enable(f); |
| } |
| |
| /** |
| * @deprecated Since 1.9, it is preferable to use {@link #without} instead; |
| * this method is deprecated as it modifies current instance instead of |
| * creating a new one (as the goal is to make this class immutable) |
| */ |
| @Deprecated |
| @Override |
| public void disable(DeserializationConfig.Feature f) { |
| super.disable(f); |
| } |
| |
| /** |
| * @deprecated Since 1.9, it is preferable to use {@link #without} and {@link #with} instead; |
| * this method is deprecated as it modifies current instance instead of |
| * creating a new one (as the goal is to make this class immutable) |
| */ |
| @Deprecated |
| @Override |
| public void set(DeserializationConfig.Feature f, boolean state) { |
| super.set(f, state); |
| } |
| |
| /* |
| /********************************************************** |
| /* 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 configured problem handlers; usually done to replace |
| * existing handler(s) with different one(s) |
| * |
| * @since 1.1 |
| */ |
| public void clearHandlers() |
| { |
| _problemHandlers = null; |
| } |
| |
| /* |
| /********************************************************** |
| /* 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 final JsonNodeFactory getNodeFactory() { |
| return _nodeFactory; |
| } |
| |
| /* |
| /********************************************************** |
| /* 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) getClassIntrospector().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) getClassIntrospector().forCreation(this, type, this); |
| } |
| |
| /* |
| /********************************************************** |
| /* Extended API: handler instantiation |
| /********************************************************** |
| */ |
| |
| @SuppressWarnings("unchecked") |
| public JsonDeserializer<Object> deserializerInstance(Annotated annotated, |
| Class<? extends JsonDeserializer<?>> deserClass) |
| { |
| HandlerInstantiator hi = getHandlerInstantiator(); |
| if (hi != null) { |
| JsonDeserializer<?> deser = hi.deserializerInstance(this, annotated, deserClass); |
| if (deser != null) { |
| return (JsonDeserializer<Object>) deser; |
| } |
| } |
| return (JsonDeserializer<Object>) ClassUtil.createInstance(deserClass, canOverrideAccessModifiers()); |
| } |
| |
| public KeyDeserializer keyDeserializerInstance(Annotated annotated, |
| Class<? extends KeyDeserializer> keyDeserClass) |
| { |
| HandlerInstantiator hi = getHandlerInstantiator(); |
| if (hi != null) { |
| KeyDeserializer keyDeser = hi.keyDeserializerInstance(this, annotated, keyDeserClass); |
| if (keyDeser != null) { |
| return (KeyDeserializer) keyDeser; |
| } |
| } |
| return (KeyDeserializer) ClassUtil.createInstance(keyDeserClass, canOverrideAccessModifiers()); |
| } |
| |
| public ValueInstantiator valueInstantiatorInstance(Annotated annotated, |
| Class<? extends ValueInstantiator> instClass) |
| { |
| HandlerInstantiator hi = getHandlerInstantiator(); |
| if (hi != null) { |
| ValueInstantiator inst = hi.valueInstantiatorInstance(this, annotated, instClass); |
| if (inst != null) { |
| return (ValueInstantiator) inst; |
| } |
| } |
| return (ValueInstantiator) ClassUtil.createInstance(instClass, canOverrideAccessModifiers()); |
| } |
| } |