All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.jackson.map.MapperConfig Maven / Gradle / Ivy

Go to download

Data Mapper package is a high-performance data binding package built on Jackson JSON processor

There is a newer version: 1.9.13
Show newest version
package org.codehaus.jackson.map;

import java.text.DateFormat;
import java.util.HashMap;
import java.util.Map;

import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.introspect.Annotated;
import org.codehaus.jackson.map.introspect.VisibilityChecker;
import org.codehaus.jackson.map.jsontype.SubtypeResolver;
import org.codehaus.jackson.map.jsontype.TypeIdResolver;
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.type.TypeBindings;
import org.codehaus.jackson.map.type.TypeFactory;
import org.codehaus.jackson.map.util.ClassUtil;
import org.codehaus.jackson.map.util.StdDateFormat;
import org.codehaus.jackson.type.JavaType;
import org.codehaus.jackson.type.TypeReference;

/**
 * Interface that defines functionality accessible through both
 * serialization and deserialization configuration objects;
 * accessors to mode-independent configuration settings
 * and such.
 *

* 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"). * One major remaining issue is that of handling mix-in annotations, which * still represent bit of mutable state. * * @since 1.2 -- major change in 1.8, changed from interface to * abstract class */ public abstract class MapperConfig> implements ClassIntrospector.MixInResolver { /* /********************************************************** /* Constants, default values /********************************************************** */ /** * This is the default {@link DateFormat} used unless overridden by * custom implementation. */ protected final static DateFormat DEFAULT_DATE_FORMAT = StdDateFormat.instance; /* /********************************************************** /* Simple immutable basic settings /********************************************************** */ /** * Immutable container object for simple configuration settings. *

* Note: ideally this would be final, but until we can eliminate * mutators, must keep it mutable. */ protected Base _base; /* /********************************************************** /* Mix-in annotations /********************************************************** */ /** * 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". *

* 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> _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; /* /********************************************************** /* "Late bound" settings /********************************************************** */ /** * Registered concrete subtypes that can be used instead of (or * in addition to) ones declared using annotations. * Unlike most other settings, it is not configured as early * as it is set, but rather only when a non-shared instance * is constructed by ObjectMapper (or -Reader * or -Writer) *

* Note: this is the only property left as non-final, to allow * lazy construction of the instance as necessary. * * @since 1.6 */ protected SubtypeResolver _subtypeResolver; /* /********************************************************** /* Life-cycle: constructors /********************************************************** */ protected MapperConfig(ClassIntrospector ci, AnnotationIntrospector ai, VisibilityChecker vc, SubtypeResolver str, PropertyNamingStrategy pns, TypeFactory tf, HandlerInstantiator hi) { _base = new Base(ci, ai, vc, pns, tf, null, DEFAULT_DATE_FORMAT, hi); _subtypeResolver = str; // by default, assumed to be shared; only cleared when explicit copy is made _mixInAnnotationsShared = true; } /** * Simple copy constructor * * @since 1.8 */ protected MapperConfig(MapperConfig src) { this(src, src._base, src._subtypeResolver); } /** * @since 1.8 */ protected MapperConfig(MapperConfig src, MapperConfig.Base base, SubtypeResolver str) { _base = base; _subtypeResolver = str; // by default, assumed to be shared; only cleared when explicit copy is made _mixInAnnotationsShared = true; _mixInAnnotations = src._mixInAnnotations; } /* /********************************************************** /* Life-cycle: factory methods /********************************************************** */ /** * 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. * * @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 public abstract void fromAnnotations(Class cls); /** * Method to use for constructing an instance that is not shared * between multiple operations but only used for a single one * (which may be this instance, if it is immutable; if not, a copy * is constructed with same settings) * * @since 1.8 */ public abstract T createUnshared(SubtypeResolver subtypeResolver); /** * Method for constructing and returning a new instance with different * {@link ClassIntrospector} * to use. *

* NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. * * @since 1.8 */ public abstract T withClassIntrospector(ClassIntrospector ci); /** * Method for constructing and returning a new instance with different * {@link AnnotationIntrospector} to use (replacing old one). *

* NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. * * @since 1.8 */ public abstract T withAnnotationIntrospector(AnnotationIntrospector ai); /** * Method for constructing and returning a new instance with different * {@link VisibilityChecker} * to use. *

* NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. * * @since 1.8 */ public abstract T withVisibilityChecker(VisibilityChecker vc); /** * Method for constructing and returning a new instance with different * minimal visibility level for specified property type *

* NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. * * @since 1.9 */ public abstract T withVisibility(JsonMethod forMethod, JsonAutoDetect.Visibility visibility); /** * Method for constructing and returning a new instance with different * {@link TypeResolverBuilder} * to use. *

* NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. * * @since 1.8 */ public abstract T withTypeResolverBuilder(TypeResolverBuilder trb); /** * Method for constructing and returning a new instance with different * {@link SubtypeResolver} * to use. *

* NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. * * @since 1.8 */ public abstract T withSubtypeResolver(SubtypeResolver str); /** * Method for constructing and returning a new instance with different * {@link PropertyNamingStrategy} * to use. *

* NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. * * @since 1.8 */ public abstract T withPropertyNamingStrategy(PropertyNamingStrategy strategy); /** * Method for constructing and returning a new instance with different * {@link TypeFactory} * to use. *

* NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. * * @since 1.8 */ public abstract T withTypeFactory(TypeFactory typeFactory); /** * Method for constructing and returning a new instance with different * {@link DateFormat} * to use. *

* NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. * * @since 1.8 */ public abstract T withDateFormat(DateFormat df); /** * Method for constructing and returning a new instance with different * {@link HandlerInstantiator} * to use. *

* NOTE: make sure to register new instance with ObjectMapper * if directly calling this method. * * @since 1.8 */ public abstract T withHandlerInstantiator(HandlerInstantiator hi); /** * Method for constructing and returning a new instance with additional * {@link AnnotationIntrospector} inserted (as the highest priority one) * * @since 1.9 */ public abstract T withInsertedAnnotationIntrospector(AnnotationIntrospector introspector); /** * Method for constructing and returning a new instance with additional * {@link AnnotationIntrospector} appended (as the lowest priority one) * * @since 1.9 */ public abstract T withAppendedAnnotationIntrospector(AnnotationIntrospector introspector); /* /********************************************************** /* Configuration: simple features /********************************************************** */ /** * Method for checking whether given feature is enabled or not */ public abstract boolean isEnabled(ConfigFeature f); /** * Method for determining whether annotation processing is enabled or not * (default settings are typically that it is enabled; must explicitly disable). * * @return True if annotation processing is enabled; false if not * * @since 1.8 */ public abstract boolean isAnnotationProcessingEnabled(); /** * Accessor for determining whether it is ok to try to force override of access * modifiers to be able to get or set values of non-public Methods, Fields; * to invoke non-public Constructors, Methods; or to instantiate non-public * Classes. By default this is enabled, but on some platforms it needs to be * prevented since if this would violate security constraints and cause failures. * * @return True if access modifier overriding is allowed (and may be done for * any Field, Method, Constructor or Class); false to prevent any attempts * to override. * * @since 1.8 */ public abstract boolean canOverrideAccessModifiers(); /** * Accessor for checking whether default settings for property handling * indicate that properties should be alphabetically ordered or not. * * @since 1.9 */ public abstract boolean shouldSortPropertiesAlphabetically(); /* /********************************************************** /* Configuration: introspectors, mix-ins /********************************************************** */ public ClassIntrospector getClassIntrospector() { return _base.getClassIntrospector(); } /** * Method for getting {@link AnnotationIntrospector} configured * to introspect annotation values used for configuration. *

* Non-final since it is actually overridden by sub-classes (for now?) */ public AnnotationIntrospector getAnnotationIntrospector() { return _base.getAnnotationIntrospector(); } /** * Method for registering specified {@link AnnotationIntrospector} as the highest * priority introspector (will be chained with existing introspector(s) which * will be used as fallbacks for cases this introspector does not handle) * * @param introspector Annotation introspector to register. * * @since 1.7 * * @deprecated Since 1.9 use {@link #withInsertedAnnotationIntrospector(AnnotationIntrospector)} instead; * this method is deprecated as it changes state, preventing immutability of instances */ @Deprecated public final void insertAnnotationIntrospector(AnnotationIntrospector introspector) { _base = _base.withAnnotationIntrospector(AnnotationIntrospector.Pair.create(introspector, getAnnotationIntrospector())); } /** * Method for registering specified {@link AnnotationIntrospector} as the lowest * priority introspector, chained with existing introspector(s) and called * as fallback for cases not otherwise handled. * * @param introspector Annotation introspector to register. * * @since 1.7 * * @deprecated Since 1.9 use {@link #withAppendedAnnotationIntrospector(AnnotationIntrospector)} instead; * this method is deprecated as it changes state, preventing immutability of instances */ @Deprecated public final void appendAnnotationIntrospector(AnnotationIntrospector introspector) { _base = _base.withAnnotationIntrospector(AnnotationIntrospector.Pair.create(getAnnotationIntrospector(), introspector)); } /** * Accessor for 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 */ public VisibilityChecker getDefaultVisibilityChecker() { return _base.getVisibilityChecker(); } /** * @since 1.8 */ public final PropertyNamingStrategy getPropertyNamingStrategy() { return _base.getPropertyNamingStrategy(); } /** * @since 1.8 */ public final HandlerInstantiator getHandlerInstantiator() { return _base.getHandlerInstantiator(); } /* /********************************************************** /* Configuration: mix-in annotations /********************************************************** */ /** * Method to use for defining mix-in annotations to use for augmenting * annotations that processable (serializable / 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 override * annotations that target classes (and their super-types) have. * * @since 1.2 */ public final void setMixInAnnotations(Map, Class> sourceMixins) { HashMap> mixins = null; if (sourceMixins != null && sourceMixins.size() > 0) { mixins = new HashMap>(sourceMixins.size()); for (Map.Entry,Class> en : sourceMixins.entrySet()) { mixins.put(new ClassKey(en.getKey()), en.getValue()); } } _mixInAnnotationsShared = false; _mixInAnnotations = mixins; } /** * Method to use for adding mix-in annotations to use for augmenting * specified class or interface. All annotations from * mixinSource are taken to override annotations * that target (or its supertypes) has. * * @since 1.2 * * @param target Class (or interface) whose annotations to effectively override * @param mixinSource Class (or interface) whose annotations are to * be "added" to target's annotations, overriding as necessary */ public final void addMixInAnnotations(Class target, Class mixinSource) { if (_mixInAnnotations == null) { _mixInAnnotationsShared = false; _mixInAnnotations = new HashMap>(); } else if (_mixInAnnotationsShared) { _mixInAnnotationsShared = false; _mixInAnnotations = new HashMap>(_mixInAnnotations); } _mixInAnnotations.put(new ClassKey(target), mixinSource); } // ClassIntrospector.MixInResolver impl: /** * Method that will check if there are "mix-in" classes (with mix-in * annotations) for given class * * @since 1.2 */ @Override public final Class findMixInClassFor(Class cls) { return (_mixInAnnotations == null) ? null : _mixInAnnotations.get(new ClassKey(cls)); } /** * @since 1.8.1 */ public final int mixInCount() { return (_mixInAnnotations == null) ? 0 : _mixInAnnotations.size(); } /* /********************************************************** /* Configuration: type and subtype handling /********************************************************** */ /** * Method called to locate a type info handler for types that do not have * one explicitly declared via annotations (or other configuration). * If such default handler is configured, it is returned; otherwise * null is returned. * * @since 1.5 */ public final TypeResolverBuilder getDefaultTyper(JavaType baseType) { return _base.getTypeResolverBuilder(); } /** * Accessor for object used for finding out all reachable subtypes * for supertypes; needed when a logical type name is used instead * of class name (or custom scheme). * * @since 1.6 */ public final SubtypeResolver getSubtypeResolver() { if (_subtypeResolver == null) { _subtypeResolver = new StdSubtypeResolver(); } return _subtypeResolver; } /** * @since 1.8 */ public final TypeFactory getTypeFactory() { return _base.getTypeFactory(); } /** * Helper method that will construct {@link JavaType} for given * raw class. * This is a simple short-cut for: *

     *    getTypeFactory().constructType(cls);
     *
* * @since 1.8 */ public final JavaType constructType(Class cls) { return getTypeFactory().constructType(cls, (TypeBindings) null); } /** * Helper method that will construct {@link JavaType} for given * type reference * This is a simple short-cut for: *
     *    getTypeFactory().constructType(valueTypeRef);
     *
* * @since 1.9 */ public final JavaType constructType(TypeReference valueTypeRef) { return getTypeFactory().constructType(valueTypeRef.getType(), (TypeBindings) null); } /* /********************************************************** /* Configuration: other /********************************************************** */ /** * Method for accessing currently configured (textual) date format * that will be used for reading or writing date values (in case * of writing, only if textual output is configured; not if dates * are to be serialized as time stamps). *

* Note that typically {@link DateFormat} instances are not thread-safe * (at least ones provided by JDK): * this means that calling code should clone format instance before * using it. *

* This method is usually only called by framework itself, since there * are convenience methods available via * {@link DeserializationContext} and {@link SerializerProvider} that * take care of cloning and thread-safe reuse. */ public final DateFormat getDateFormat() { return _base.getDateFormat(); } /** * Accessor for getting bean description that only contains class * annotations: useful if no getter/setter/creator information is needed. * * @since 1.7 */ @SuppressWarnings("unchecked") public DESC introspectClassAnnotations(Class cls) { return (DESC) introspectClassAnnotations(constructType(cls)); } /** * Accessor for getting bean description that only contains class * annotations: useful if no getter/setter/creator information is needed. * * @since 1.9 */ public abstract DESC introspectClassAnnotations(JavaType type); /** * 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. * * @since 1.7 */ @SuppressWarnings("unchecked") public DESC introspectDirectClassAnnotations(Class cls) { return (DESC) introspectDirectClassAnnotations(constructType(cls)); } /** * 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. */ public abstract DESC introspectDirectClassAnnotations(JavaType type); /* /********************************************************** /* Methods for instantiating handlers /********************************************************** */ /** * Method that can be called to obtain an instance of TypeIdResolver of * specified type. * * @since 1.8 */ public TypeResolverBuilder typeResolverBuilderInstance(Annotated annotated, Class> builderClass) { HandlerInstantiator hi = getHandlerInstantiator(); if (hi != null) { TypeResolverBuilder builder = hi.typeResolverBuilderInstance(this, annotated, builderClass); if (builder != null) { return builder; } } return (TypeResolverBuilder) ClassUtil.createInstance(builderClass, canOverrideAccessModifiers()); } /** * Method that can be called to obtain an instance of TypeIdResolver of * specified type. * * @since 1.8 */ public TypeIdResolver typeIdResolverInstance(Annotated annotated, Class resolverClass) { HandlerInstantiator hi = getHandlerInstantiator(); if (hi != null) { TypeIdResolver builder = hi.typeIdResolverInstance(this, annotated, resolverClass); if (builder != null) { return builder; } } return (TypeIdResolver) ClassUtil.createInstance(resolverClass, canOverrideAccessModifiers()); } /* /********************************************************** /* Deprecated methods /********************************************************** */ /** * Method for replacing existing annotation introspector(s) with specified * introspector. * Since this method modifies state of configuration object directly, its use * is not recommended. * * @deprecated Since 1.8, use either * {@link #withAnnotationIntrospector(AnnotationIntrospector)} or * Module API instead */ @Deprecated public final void setAnnotationIntrospector(AnnotationIntrospector ai) { _base = _base.withAnnotationIntrospector(ai); } /** * Method that will define specific date format to use for reading/writing * Date and Calendar values. * If null is passed, will use {@link StdDateFormat}. * Instance is used as is, without creating a clone. * Format object in use can be accessed using {@link #getDateFormat}. * * @deprecated As of version 1.8, it is preferable to call method in * {@link ObjectMapper} instead; or construct new instance with * {@link #withDateFormat(DateFormat)} */ @Deprecated public void setDateFormat(DateFormat df) { if (df == null) { df = StdDateFormat.instance; } _base = _base.withDateFormat(df); } /* /********************************************************** /* Helper interface used with simple on/off features /********************************************************** */ /** * Interface that actual Feature enumerations used by * {@link MapperConfig} implementations must implement. * Necessary since enums can not be extended using normal * inheritance, but can implement interfaces * * @since 1.9 */ public interface ConfigFeature { /** * Accessor for checking whether this feature is enabled by default. */ public boolean enabledByDefault(); /** * Returns bit mask for this feature instance */ public int getMask(); } /* /********************************************************** /* Helper class to contain basic state needed to implement /* MapperConfig. /********************************************************** */ /** * Immutable container class used to store simple configuration * settings. Since instances are fully immutable, instances can * be freely shared and used without synchronization. */ public static class Base { /* /********************************************************** /* Configuration settings; introspection, related /********************************************************** */ /** * 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 final ClassIntrospector _classIntrospector; /** * Introspector used for accessing annotation value based configuration. */ protected final AnnotationIntrospector _annotationIntrospector; /** * 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 final VisibilityChecker _visibilityChecker; /** * Custom property naming strategy in use, if any. * * @since 1.8 */ protected final PropertyNamingStrategy _propertyNamingStrategy; /** * Specific factory used for creating {@link JavaType} instances; * needed to allow modules to add more custom type handling * (mostly to support types of non-Java JVM languages) */ protected final TypeFactory _typeFactory; /* /********************************************************** /* Configuration settings; type resolution /********************************************************** */ /** * Type information handler used for "untyped" values (ones declared * to have type Object.class) * * @since 1.5 */ protected final TypeResolverBuilder _typeResolverBuilder; /* /********************************************************** /* Configuration settings; other /********************************************************** */ /** * Custom date format to use for de-serialization. If specified, will be * used instead of {@link org.codehaus.jackson.map.util.StdDateFormat}. *

* Note that the configured format object will be cloned once per * deserialization process (first time it is needed) */ protected final DateFormat _dateFormat; /** * Object used for creating instances of handlers (serializers, deserializers, * type and type id resolvers), given class to instantiate. This is typically * used to do additional configuration (with dependency injection, for example) * beyond simply construction of instances; or to use alternative constructors. */ protected final HandlerInstantiator _handlerInstantiator; /* /********************************************************** /* Construction /********************************************************** */ public Base(ClassIntrospector ci, AnnotationIntrospector ai, VisibilityChecker vc, PropertyNamingStrategy pns, TypeFactory tf, TypeResolverBuilder typer, DateFormat dateFormat, HandlerInstantiator hi) { _classIntrospector = ci; _annotationIntrospector = ai; _visibilityChecker = vc; _propertyNamingStrategy = pns; _typeFactory = tf; _typeResolverBuilder = typer; _dateFormat = dateFormat; _handlerInstantiator = hi; } /* /********************************************************** /* Factory methods /********************************************************** */ public Base withClassIntrospector(ClassIntrospector ci) { return new Base(ci, _annotationIntrospector, _visibilityChecker, _propertyNamingStrategy, _typeFactory, _typeResolverBuilder, _dateFormat, _handlerInstantiator); } public Base withAnnotationIntrospector(AnnotationIntrospector ai) { return new Base(_classIntrospector, ai, _visibilityChecker, _propertyNamingStrategy, _typeFactory, _typeResolverBuilder, _dateFormat, _handlerInstantiator); } public Base withInsertedAnnotationIntrospector(AnnotationIntrospector ai) { return withAnnotationIntrospector(AnnotationIntrospector.Pair.create(ai, _annotationIntrospector)); } public Base withAppendedAnnotationIntrospector(AnnotationIntrospector ai) { return withAnnotationIntrospector(AnnotationIntrospector.Pair.create(_annotationIntrospector, ai)); } public Base withVisibilityChecker(VisibilityChecker vc) { return new Base(_classIntrospector, _annotationIntrospector, vc, _propertyNamingStrategy, _typeFactory, _typeResolverBuilder, _dateFormat, _handlerInstantiator); } public Base withVisibility(JsonMethod forMethod, JsonAutoDetect.Visibility visibility) { return new Base(_classIntrospector, _annotationIntrospector, _visibilityChecker.withVisibility(forMethod, visibility), _propertyNamingStrategy, _typeFactory, _typeResolverBuilder, _dateFormat, _handlerInstantiator); } public Base withPropertyNamingStrategy(PropertyNamingStrategy pns) { return new Base(_classIntrospector, _annotationIntrospector, _visibilityChecker, pns, _typeFactory, _typeResolverBuilder, _dateFormat, _handlerInstantiator); } public Base withTypeFactory(TypeFactory tf) { return new Base(_classIntrospector, _annotationIntrospector, _visibilityChecker, _propertyNamingStrategy, tf, _typeResolverBuilder, _dateFormat, _handlerInstantiator); } public Base withTypeResolverBuilder(TypeResolverBuilder typer) { return new Base(_classIntrospector, _annotationIntrospector, _visibilityChecker, _propertyNamingStrategy, _typeFactory, typer, _dateFormat, _handlerInstantiator); } public Base withDateFormat(DateFormat df) { return new Base(_classIntrospector, _annotationIntrospector, _visibilityChecker, _propertyNamingStrategy, _typeFactory, _typeResolverBuilder, df, _handlerInstantiator); } public Base withHandlerInstantiator(HandlerInstantiator hi) { return new Base(_classIntrospector, _annotationIntrospector, _visibilityChecker, _propertyNamingStrategy, _typeFactory, _typeResolverBuilder, _dateFormat, hi); } /* /********************************************************** /* API /********************************************************** */ public ClassIntrospector getClassIntrospector() { return _classIntrospector; } public AnnotationIntrospector getAnnotationIntrospector() { return _annotationIntrospector; } public VisibilityChecker getVisibilityChecker() { return _visibilityChecker; } public PropertyNamingStrategy getPropertyNamingStrategy() { return _propertyNamingStrategy; } public TypeFactory getTypeFactory() { return _typeFactory; } public TypeResolverBuilder getTypeResolverBuilder() { return _typeResolverBuilder; } public DateFormat getDateFormat() { return _dateFormat; } public HandlerInstantiator getHandlerInstantiator() { return _handlerInstantiator; } } /* /********************************************************** /* Basic extension; added to avoid having to change generic /* signature of MapperConfig /* /* NOTE: May be merge in MapperConfig for 2.0, depending /* on how much we value backwards compatibility /********************************************************** */ static abstract class Impl> extends MapperConfig { /** *

* Note: moved to base class in 1.9; was stored by sub-class earlier */ protected int _featureFlags; /* /********************************************************** /* Construction /********************************************************** */ protected Impl(ClassIntrospector ci, AnnotationIntrospector ai, VisibilityChecker vc, SubtypeResolver str, PropertyNamingStrategy pns, TypeFactory tf, HandlerInstantiator hi, int defaultFeatures) { super(ci, ai, vc, str, pns, tf, hi); _featureFlags = defaultFeatures; } protected Impl(Impl src) { super(src); _featureFlags = src._featureFlags; } protected Impl(Impl src, int features) { super(src); _featureFlags = features; } /** * @since 1.8 */ protected Impl(Impl src, MapperConfig.Base base, SubtypeResolver str) { super(src, base, str); _featureFlags = src._featureFlags; } /** * Method that calculates bit set (flags) of all features that * are enabled by default. */ static & MapperConfig.ConfigFeature> int collectFeatureDefaults(Class enumClass) { int flags = 0; for (F value : enumClass.getEnumConstants()) { if (value.enabledByDefault()) { flags |= value.getMask(); } } return flags; } /* /********************************************************** /* Additional fluent-factory methods /********************************************************** */ /** * Fluent factory method that will construct and return a new configuration * object instance with specified features enabled. * * @since 1.9 */ public abstract T with(CFG... features); /** * Fluent factory method that will construct and return a new configuration * object instance with specified features disabled. * * @since 1.9 */ public abstract T without(CFG... features); /* /********************************************************** /* Configuration: simple features /********************************************************** */ @Override public boolean isEnabled(MapperConfig.ConfigFeature f) { return (_featureFlags & f.getMask()) != 0; } /* /********************************************************** /* Configuration: deprecated methods /********************************************************** */ /** * Method for enabling specified feature. * * @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 public final void enable(CFG f) { _featureFlags |= f.getMask(); } /** * Method for disabling specified feature. * * @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 public final void disable(CFG f) { _featureFlags &= ~f.getMask(); } /** * Method for enabling or disabling specified feature. * * @deprecated Since 1.9, it is preferable to use {@link #with} and * {@link #without} methods 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) */ @SuppressWarnings("deprecation") @Deprecated public final void set(CFG f, boolean state) { if (state) { enable(f); } else { disable(f); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy