package com.fasterxml.jackson.databind; import java.io.*; import java.lang.reflect.Type; import java.net.URL; import java.text.DateFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.io.SegmentedStringWriter; import com.fasterxml.jackson.core.io.SerializedString; import com.fasterxml.jackson.core.type.ResolvedType; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.util.*; import com.fasterxml.jackson.databind.cfg.BaseSettings; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.deser.*; import com.fasterxml.jackson.databind.introspect.BasicClassIntrospector; import com.fasterxml.jackson.databind.introspect.ClassIntrospector; import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import com.fasterxml.jackson.databind.introspect.VisibilityChecker; import com.fasterxml.jackson.databind.jsonschema.JsonSchema; import com.fasterxml.jackson.databind.jsontype.*; import com.fasterxml.jackson.databind.jsontype.impl.StdSubtypeResolver; import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder; import com.fasterxml.jackson.databind.node.*; import com.fasterxml.jackson.databind.ser.*; import com.fasterxml.jackson.databind.type.ClassKey; import com.fasterxml.jackson.databind.type.SimpleType; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.type.TypeModifier; import com.fasterxml.jackson.databind.util.StdDateFormat; import com.fasterxml.jackson.databind.util.TokenBuffer; /** * This mapper (or, data binder, or codec) provides functionality for * converting between Java objects (instances of JDK provided core classes, * beans), and matching JSON constructs. * It will use instances of {@link JsonParser} and {@link JsonGenerator} * for implementing actual reading/writing of JSON. *
* The main conversion API is defined in {@link ObjectCodec}, so that * implementation details of this class need not be exposed to * streaming parser and generator classes. *
* Note on caching: root-level deserializers are always cached, and accessed * using full (generics-aware) type information. This is different from * caching of referenced types, which is more limited and is done only * for a subset of all deserializer types. The main reason for difference * is that at root-level there is no incoming reference (and hence no * referencing property, no referral information or annotations to * produce differing deserializers), and that the performance impact * greatest at root level (since it'll essentially cache the full * graph of deserializers involved). */ public class ObjectMapper extends ObjectCodec implements Versioned { /* /********************************************************** /* Helper classes, enums /********************************************************** */ /** * Enumeration used with {@link ObjectMapper#enableDefaultTyping()} * to specify what kind of types (classes) default typing should * be used for. It will only be used if no explicit type information * is found, but this enumeration further limits subset of those types. */ public enum DefaultTyping { /** * This value means that only properties that have * {@link java.lang.Object} as declared type (including * generic types without explicit type) will use default * typing. */ JAVA_LANG_OBJECT, /** * Value that means that default typing will be used for * properties with declared type of {@link java.lang.Object} * or an abstract type (abstract class or interface). * Note that this does not include array types. */ OBJECT_AND_NON_CONCRETE, /** * Value that means that default typing will be used for * all types covered by {@link #OBJECT_AND_NON_CONCRETE} * plus all array types for them. */ NON_CONCRETE_AND_ARRAYS, /** * Value that means that default typing will be used for * all non-final types, with exception of small number of * "natural" types (String, Boolean, Integer, Double), which * can be correctly inferred from JSON; as well as for * all arrays of non-final types. */ NON_FINAL } /** * Customized {@link TypeResolverBuilder} that provides type resolver builders * used with so-called "default typing" * (see {@link ObjectMapper#enableDefaultTyping()} for details). *
* Type resolver construction is based on configuration: implementation takes care
* of only providing builders in cases where type information should be applied.
* This is important since build calls may be sent for any and all types, and
* type information should NOT be applied to all of them.
*/
public static class DefaultTypeResolverBuilder
extends StdTypeResolverBuilder
{
/**
* Definition of what types is this default typer valid for.
*/
protected final DefaultTyping _appliesFor;
public DefaultTypeResolverBuilder(DefaultTyping t) {
_appliesFor = t;
}
@Override
public TypeDeserializer buildTypeDeserializer(DeserializationConfig config,
JavaType baseType, Collection
* 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)
*/
protected final HashMap
* Given that we don't expect much concurrency for additions
* (should very quickly converge to zero after startup), let's
* explicitly define a low concurrency setting.
*
* Since version 1.5, these may are either "raw" deserializers (when
* no type information is needed for base type), or type-wrapped
* deserializers (if it is needed)
*/
final protected ConcurrentHashMap
* Note: will also set {@link TypeFactory} that deserialization and
* serialization config objects use.
*/
public ObjectMapper setTypeFactory(TypeFactory f)
{
_typeFactory = f;
_deserializationConfig = _deserializationConfig.withTypeFactory(f);
_serializationConfig = _serializationConfig.withTypeFactory(f);
return this;
}
/**
* Convenience method for constructing {@link JavaType} out of given
* type (typically
* Note that usually it is better to use method {@link #writer(FilterProvider)};
* however, sometimes
* this method is more convenient. For example, some frameworks only allow configuring
* of ObjectMapper instances and not ObjectWriters.
*/
public void setFilters(FilterProvider filterProvider) {
_serializationConfig = _serializationConfig.withFilters(filterProvider);
}
/*
/**********************************************************
/* Configuration, other
/**********************************************************
*/
/**
* Method that can be used to get hold of {@link JsonFactory} that this
* mapper uses if it needs to construct {@link JsonParser}s
* and/or {@link JsonGenerator}s.
*
* @return {@link JsonFactory} that this mapper uses when it needs to
* construct Json parser and generators
*/
public JsonFactory getJsonFactory() { return _jsonFactory; }
/**
* Method for configuring the default {@link DateFormat} to use when serializing time
* values as Strings, and deserializing from JSON Strings.
* This is preferably to directly modifying {@link SerializationConfig} and
* {@link DeserializationConfig} instances.
* If you need per-request configuration, use {@link #writer(DateFormat)} to
* create properly configured {@link ObjectWriter} and use that; this because
* {@link ObjectWriter}s are thread-safe whereas ObjectMapper itself is only
* thread-safe when configuring methods (such as this one) are NOT called.
*/
public void setDateFormat(DateFormat dateFormat)
{
_deserializationConfig = _deserializationConfig.withDateFormat(dateFormat);
_serializationConfig = _serializationConfig.withDateFormat(dateFormat);
}
/**
* Method for configuring {@link HandlerInstantiator} to use for creating
* instances of handlers (such as serializers, deserializers, type and type
* id resolvers), given a class.
*
* @param hi Instantiator to use; if null, use the default implementation
*/
public void setHandlerInstantiator(HandlerInstantiator hi)
{
_deserializationConfig = _deserializationConfig.withHandlerInstantiator(hi);
_serializationConfig = _serializationConfig.withHandlerInstantiator(hi);
}
/**
* Method for configuring {@link InjectableValues} which used to find
* values to inject.
*/
public ObjectMapper setInjectableValues(InjectableValues injectableValues) {
_injectableValues = injectableValues;
return this;
}
/*
/**********************************************************
/* Configuration, simple features
/**********************************************************
*/
/**
* Method for changing state of an on/off mapper feature for
* this mapper instance.
*/
public ObjectMapper configure(MapperConfig.Feature f, boolean state) {
_serializationConfig = state ?
_serializationConfig.with(f) : _serializationConfig.without(f);
_deserializationConfig = state ?
_deserializationConfig.with(f) : _deserializationConfig.without(f);
return this;
}
/**
* Method for changing state of an on/off serialization feature for
* this object mapper.
*/
public ObjectMapper configure(SerializationConfig.Feature f, boolean state) {
_serializationConfig = state ?
_serializationConfig.with(f) : _serializationConfig.without(f);
return this;
}
/**
* Method for changing state of an on/off deserialization feature for
* this object mapper.
*/
public ObjectMapper configure(DeserializationConfig.Feature f, boolean state) {
_deserializationConfig = state ?
_deserializationConfig.with(f) : _deserializationConfig.without(f);
return this;
}
/**
* Method for changing state of an on/off {@link JsonParser} feature for
* {@link JsonFactory} instance this object mapper uses.
*
* This is method is basically a shortcut method for calling
* {@link JsonFactory#enable} on the shared
* {@link JsonFactory} this mapper uses (which is accessible
* using {@link #getJsonFactory}).
*/
public ObjectMapper configure(JsonParser.Feature f, boolean state) {
_jsonFactory.configure(f, state);
return this;
}
/**
* Method for changing state of an on/off {@link JsonGenerator} feature for
* {@link JsonFactory} instance this object mapper uses.
*
* This is method is basically a shortcut method for calling
* {@link JsonFactory#enable} on the shared
* {@link JsonFactory} this mapper uses (which is accessible
* using {@link #getJsonFactory}).
*/
public ObjectMapper configure(JsonGenerator.Feature f, boolean state) {
_jsonFactory.configure(f, state);
return this;
}
/**
* Method for enabling specified {@link MapperConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper enable(MapperConfig.Feature... f) {
_deserializationConfig = _deserializationConfig.with(f);
_serializationConfig = _serializationConfig.with(f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper disable(MapperConfig.Feature... f) {
_deserializationConfig = _deserializationConfig.without(f);
_serializationConfig = _serializationConfig.without(f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper enable(DeserializationConfig.Feature feature) {
_deserializationConfig = _deserializationConfig.with(feature);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper enable(DeserializationConfig.Feature first,
DeserializationConfig.Feature... f) {
_deserializationConfig = _deserializationConfig.with(first, f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper disable(DeserializationConfig.Feature feature) {
_deserializationConfig = _deserializationConfig.without(feature);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper disable(DeserializationConfig.Feature first,
DeserializationConfig.Feature... f) {
_deserializationConfig = _deserializationConfig.without(first, f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} feature.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper enable(SerializationConfig.Feature f) {
_serializationConfig = _serializationConfig.with(f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper enable(SerializationConfig.Feature first,
SerializationConfig.Feature... f) {
_serializationConfig = _serializationConfig.with(first, f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper disable(SerializationConfig.Feature f) {
_serializationConfig = _serializationConfig.without(f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper disable(SerializationConfig.Feature first,
SerializationConfig.Feature... f) {
_serializationConfig = _serializationConfig.without(first, f);
return this;
}
/**
* Method for checking whether given Mapper
* feature is enabled.
*/
public boolean isEnabled(MapperConfig.Feature f) {
// ok to use either one, should be kept in sync
return _serializationConfig.isEnabled(f);
}
/**
* Method for checking whether given serialization-specific
* feature is enabled.
*/
public boolean isEnabled(SerializationConfig.Feature f) {
return _serializationConfig.isEnabled(f);
}
/**
* Method for checking whether given deserialization-specific
* feature is enabled.
*/
public boolean isEnabled(DeserializationConfig.Feature f) {
return _deserializationConfig.isEnabled(f);
}
/**
* Convenience method, equivalent to:
*
* Note: this is just a shortcut for calling
*
* Note: this method should NOT be used if the result type is a
* container ({@link java.util.Collection} or {@link java.util.Map}.
* The reason is that due to type erasure, key and value types
* can not be introspected when using this method.
*/
@Override
@SuppressWarnings("unchecked")
public
* Note that {@link ObjectReader} has more complete set of variants.
*/
@Override
public
* Note: this method should NOT be used if the result type is a
* container ({@link java.util.Collection} or {@link java.util.Map}.
* The reason is that due to type erasure, key and value types
* can not be introspected when using this method.
*
* @param cfg Specific deserialization configuration to use for
* this operation. Note that not all config settings can
* be changed on per-operation basis: some changeds only take effect
* before calling the operation for the first time (for the mapper
* instance)
*/
@SuppressWarnings("unchecked")
public
* Note: return type is co-variant, as basic ObjectCodec
* abstraction can not refer to concrete node types (as it's
* part of core package, whereas impls are part of mapper
* package)
*/
@Override
public ObjectNode createObjectNode() {
return _deserializationConfig.getNodeFactory().objectNode();
}
/**
*
* Note: return type is co-variant, as basic ObjectCodec
* abstraction can not refer to concrete node types (as it's
* part of core package, whereas impls are part of mapper
* package)
*/
@Override
public ArrayNode createArrayNode() {
return _deserializationConfig.getNodeFactory().arrayNode();
}
/**
* Method for constructing a {@link JsonParser} out of JSON tree
* representation.
*
* @param n Root node of the tree that resulting parser will read from
*/
@Override
public JsonParser treeAsTokens(JsonNode n)
{
return new TreeTraversingParser(n, this);
}
/**
* Convenience conversion method that will bind data given JSON tree
* contains into specific value (usually bean) type.
*
* Equivalent to:
*
* Note: method does not close the underlying stream explicitly
* here; however, {@link JsonFactory} this mapper uses may choose
* to close the stream depending on its settings (by default,
* it will try to close it when {@link JsonGenerator} we construct
* is closed).
*/
public void writeValue(OutputStream out, Object value)
throws IOException, JsonGenerationException, JsonMappingException
{
_configAndWriteValue(_jsonFactory.createJsonGenerator(out, JsonEncoding.UTF8), value);
}
/**
* Method that can be used to serialize any Java value as
* JSON output, using Writer provided.
*
* Note: method does not close the underlying stream explicitly
* here; however, {@link JsonFactory} this mapper uses may choose
* to close the stream depending on its settings (by default,
* it will try to close it when {@link JsonGenerator} we construct
* is closed).
*/
public void writeValue(Writer w, Object value)
throws IOException, JsonGenerationException, JsonMappingException
{
_configAndWriteValue(_jsonFactory.createJsonGenerator(w), value);
}
/**
* Method that can be used to serialize any Java value as
* a String. Functionally equivalent to calling
* {@link #writeValue(Writer,Object)} with {@link java.io.StringWriter}
* and constructing String, but more efficient.
*/
public String writeValueAsString(Object value)
throws IOException, JsonGenerationException, JsonMappingException
{
// alas, we have to pull the recycler directly here...
SegmentedStringWriter sw = new SegmentedStringWriter(_jsonFactory._getBufferRecycler());
_configAndWriteValue(_jsonFactory.createJsonGenerator(sw), value);
return sw.getAndClear();
}
/**
* Method that can be used to serialize any Java value as
* a byte array. Functionally equivalent to calling
* {@link #writeValue(Writer,Object)} with {@link java.io.ByteArrayOutputStream}
* and getting bytes, but more efficient.
* Encoding used will be UTF-8.
*/
public byte[] writeValueAsBytes(Object value)
throws IOException, JsonGenerationException, JsonMappingException
{
ByteArrayBuilder bb = new ByteArrayBuilder(_jsonFactory._getBufferRecycler());
_configAndWriteValue(_jsonFactory.createJsonGenerator(bb, JsonEncoding.UTF8), value);
byte[] result = bb.toByteArray();
bb.release();
return result;
}
/*
/**********************************************************
/* Extended Public API: constructing ObjectWriters
/* for more advanced configuration
/**********************************************************
*/
/**
* Convenience method for constructing {@link ObjectWriter}
* with default settings.
*/
public ObjectWriter writer() {
return new ObjectWriter(this, getSerializationConfig());
}
/**
* Factory method for constructing {@link ObjectWriter} with
* specified feature enabled (compared to settings that this
* mapper instance has).
*/
public ObjectWriter writer(SerializationConfig.Feature feature) {
return new ObjectWriter(this, getSerializationConfig().with(feature));
}
/**
* Factory method for constructing {@link ObjectWriter} with
* specified features enabled (compared to settings that this
* mapper instance has).
*/
public ObjectWriter writer(SerializationConfig.Feature first,
SerializationConfig.Feature... other) {
return new ObjectWriter(this, getSerializationConfig().with(first, other));
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified {@link DateFormat}; or, if
* null passed, using timestamp (64-bit number.
*/
public ObjectWriter writer(DateFormat df) {
return new ObjectWriter(this,
getSerializationConfig().withDateFormat(df));
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified JSON View (filter).
*/
public ObjectWriter writerWithView(Class> serializationView) {
return new ObjectWriter(this, getSerializationConfig().withView(serializationView));
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified root type, instead of actual
* runtime type of value. Type must be a super-type of runtime
* type.
*/
public ObjectWriter writerWithType(Class> rootType) {
JavaType t = (rootType == null) ? null : _typeFactory.constructType(rootType);
return new ObjectWriter(this, getSerializationConfig(), t, /*PrettyPrinter*/null);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified root type, instead of actual
* runtime type of value. Type must be a super-type of runtime type.
*/
public ObjectWriter writerWithType(JavaType rootType) {
return new ObjectWriter(this, getSerializationConfig(), rootType, /*PrettyPrinter*/null);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified root type, instead of actual
* runtime type of value. Type must be a super-type of runtime type.
*/
public ObjectWriter writerWithType(TypeReference> rootType) {
JavaType t = (rootType == null) ? null : _typeFactory.constructType(rootType);
return new ObjectWriter(this, getSerializationConfig(), t, /*PrettyPrinter*/null);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified pretty printer for indentation
* (or if null, no pretty printer)
*/
public ObjectWriter writer(PrettyPrinter pp) {
if (pp == null) { // need to use a marker to indicate explicit disabling of pp
pp = ObjectWriter.NULL_PRETTY_PRINTER;
}
return new ObjectWriter(this, getSerializationConfig(), /*root type*/ null, pp);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using the default pretty printer for indentation
*/
public ObjectWriter writerWithDefaultPrettyPrinter() {
return new ObjectWriter(this, getSerializationConfig(),
/*root type*/ null, _defaultPrettyPrinter());
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified filter provider.
*/
public ObjectWriter writer(FilterProvider filterProvider) {
return new ObjectWriter(this,
getSerializationConfig().withFilters(filterProvider));
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* pass specific schema object to {@link JsonGenerator} used for
* writing content.
*
* @param schema Schema to pass to generator
*/
public ObjectWriter writer(FormatSchema schema) {
return new ObjectWriter(this, getSerializationConfig(), schema);
}
/*
/**********************************************************
/* Extended Public API: constructing ObjectReaders
/* for more advanced configuration
/**********************************************************
*/
/**
* Factory method for constructing {@link ObjectReader} with
* default settings. Note that the resulting instance is NOT usable as is,
* without defining expected value type.
*/
public ObjectReader reader() {
return new ObjectReader(this, getDeserializationConfig())
.withInjectableValues(_injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} with
* specified feature enabled (compared to settings that this
* mapper instance has).
* Note that the resulting instance is NOT usable as is,
* without defining expected value type.
*/
public ObjectReader reader(DeserializationConfig.Feature feature) {
return new ObjectReader(this, getDeserializationConfig().with(feature));
}
/**
* Factory method for constructing {@link ObjectReader} with
* specified features enabled (compared to settings that this
* mapper instance has).
* Note that the resulting instance is NOT usable as is,
* without defining expected value type.
*/
public ObjectReader reader(DeserializationConfig.Feature first,
DeserializationConfig.Feature... other) {
return new ObjectReader(this, getDeserializationConfig().with(first, other));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* update given Object (usually Bean, but can be a Collection or Map
* as well, but NOT an array) with JSON data. Deserialization occurs
* normally except that the root-level value in JSON is not used for
* instantiating a new object; instead give updateable object is used
* as root.
* Runtime type of value object is used for locating deserializer,
* unless overridden by other factory methods of {@link ObjectReader}
*/
public ObjectReader readerForUpdating(Object valueToUpdate)
{
JavaType t = _typeFactory.constructType(valueToUpdate.getClass());
return new ObjectReader(this, getDeserializationConfig(), t, valueToUpdate,
null, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of specified type
*/
public ObjectReader reader(JavaType type)
{
return new ObjectReader(this, getDeserializationConfig(), type, null,
null, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of specified type
*/
public ObjectReader reader(Class> type)
{
return reader(_typeFactory.constructType(type));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of specified type
*/
public ObjectReader reader(TypeReference> type)
{
return reader(_typeFactory.constructType(type));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified {@link JsonNodeFactory} for constructing JSON trees.
*/
public ObjectReader reader(JsonNodeFactory f)
{
return new ObjectReader(this, getDeserializationConfig()).withNodeFactory(f);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* pass specific schema object to {@link JsonParser} used for
* reading content.
*
* @param schema Schema to pass to parser
*/
public ObjectReader reader(FormatSchema schema) {
return new ObjectReader(this, getDeserializationConfig(), null, null,
schema, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified injectable values.
*
* @param injectableValues Injectable values to use
*/
public ObjectReader reader(InjectableValues injectableValues) {
return new ObjectReader(this, getDeserializationConfig(), null, null,
null, injectableValues);
}
/*
/**********************************************************
/* Extended Public API: convenience type conversion
/**********************************************************
*/
/**
* Convenience method for doing two-step conversion from given value, into
* instance of given value type. This is functionality equivalent to first
* serializing given value into JSON, then binding JSON data into value
* of given type, but may be executed without fully serializing into
* JSON. Same converters (serializers, deserializers) will be used as for
* data binding, meaning same object mapper configuration works.
*
* @throws IllegalArgumentException If conversion fails due to incompatible type;
* if so, root cause will contain underlying checked exception data binding
* functionality threw
*/
@SuppressWarnings("unchecked")
public mixinSource
are taken to override annotations
* that target
(or its supertypes) has.
*
* @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)
{
_mixInAnnotations.put(new ClassKey(target), mixinSource);
}
public final Class> findMixInClassFor(Class> cls) {
return (_mixInAnnotations == null) ? null : _mixInAnnotations.get(new ClassKey(cls));
}
public final int mixInCount() {
return (_mixInAnnotations == null) ? 0 : _mixInAnnotations.size();
}
/*
/**********************************************************
/* Configuration, introspection
/**********************************************************
*/
/**
* Method for accessing currently configured visibility checker;
* object used for determining whether given property element
* (method, field, constructor) can be auto-detected or not.
*/
public VisibilityChecker> getVisibilityChecker() {
return _serializationConfig.getDefaultVisibilityChecker();
}
/**
* Method for setting currently configured visibility checker;
* object used for determining whether given property element
* (method, field, constructor) can be auto-detected or not.
* This default checker is used if no per-class overrides
* are defined.
*/
public void setVisibilityChecker(VisibilityChecker> vc) {
_deserializationConfig = _deserializationConfig.withVisibilityChecker(vc);
_serializationConfig = _serializationConfig.withVisibilityChecker(vc);
}
/**
* Convenience method that allows changing configuration for
* underlying {@link VisibilityChecker}s, to change details of what kinds of
* properties are auto-detected.
* Basically short cut for doing:
*
* mapper.setVisibilityChecker(
* mapper.getVisibilityChecker().withVisibility(forMethod, visibility)
* );
*
* one common use case would be to do:
*
* mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);
*
* which would make all member fields serializable without further annotations,
* instead of just public fields (default setting).
*
* @param forMethod Type of property descriptor affected (field, getter/isGetter,
* setter, creator)
* @param visibility Minimum visibility to require for the property descriptors of type
*
* @return Modified mapper instance (that is, "this"), to allow chaining
* of configuration calls
*/
public ObjectMapper setVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility)
{
_deserializationConfig = _deserializationConfig.withVisibility(forMethod, visibility);
_serializationConfig = _serializationConfig.withVisibility(forMethod, visibility);
return this;
}
/**
* Method for accessing subtype resolver in use.
*/
public SubtypeResolver getSubtypeResolver() {
return _subtypeResolver;
}
/**
* Method for setting custom subtype resolver to use.
*/
public ObjectMapper setSubtypeResolver(SubtypeResolver str) {
_subtypeResolver = str;
_deserializationConfig = _deserializationConfig.withSubtypeResolver(str);
_serializationConfig = _serializationConfig.withSubtypeResolver(str);
return this;
}
/**
* Method for changing {@link AnnotationIntrospector} used by this
* mapper instance for both serialization and deserialization
*/
public ObjectMapper setAnnotationIntrospector(AnnotationIntrospector ai) {
_serializationConfig = _serializationConfig.withAnnotationIntrospector(ai);
_deserializationConfig = _deserializationConfig.withAnnotationIntrospector(ai);
return this;
}
/**
* Method for setting custom property naming strategy to use.
*/
public ObjectMapper setPropertyNamingStrategy(PropertyNamingStrategy s) {
_serializationConfig = _serializationConfig.withPropertyNamingStrategy(s);
_deserializationConfig = _deserializationConfig.withPropertyNamingStrategy(s);
return this;
}
/**
* Method for setting defalt POJO property inclusion strategy for serialization.
* Equivalent to:
*
* mapper.setSerializationConfig(mapper.getSerializationConfig().withSerializationInclusion(incl));
*
*/
public ObjectMapper setSerializationInclusion(JsonInclude.Include incl) {
_serializationConfig = _serializationConfig.withSerializationInclusion(incl);
return this;
}
/*
/**********************************************************
/* Type information configuration (1.5+)
/**********************************************************
*/
/**
* Convenience method that is equivalent to calling
*
* enableObjectTyping(DefaultTyping.OBJECT_AND_NON_CONCRETE);
*
*/
public ObjectMapper enableDefaultTyping() {
return enableDefaultTyping(DefaultTyping.OBJECT_AND_NON_CONCRETE);
}
/**
* Convenience method that is equivalent to calling
*
* enableObjectTyping(dti, JsonTypeInfo.As.WRAPPER_ARRAY);
*
*/
public ObjectMapper enableDefaultTyping(DefaultTyping dti) {
return enableDefaultTyping(dti, JsonTypeInfo.As.WRAPPER_ARRAY);
}
/**
* Method for enabling automatic inclusion of type information, needed
* for proper deserialization of polymorphic types (unless types
* have been annotated with {@link com.fasterxml.jackson.annotation.JsonTypeInfo}).
*
* @param applicability Defines kinds of types for which additional type information
* is added; see {@link DefaultTyping} for more information.
*/
public ObjectMapper enableDefaultTyping(DefaultTyping applicability, JsonTypeInfo.As includeAs)
{
TypeResolverBuilder> typer = new DefaultTypeResolverBuilder(applicability);
// we'll always use full class name, when using defaulting
typer = typer.init(JsonTypeInfo.Id.CLASS, null);
typer = typer.inclusion(includeAs);
return setDefaultTyping(typer);
}
/**
* Method for enabling automatic inclusion of type information -- needed
* for proper deserialization of polymorphic types (unless types
* have been annotated with {@link com.fasterxml.jackson.annotation.JsonTypeInfo}) --
* using "As.PROPERTY" inclusion mechanism and specified property name
* to use for inclusion (default being "@class" since default type information
* always uses class name as type identifier)
*/
public ObjectMapper enableDefaultTypingAsProperty(DefaultTyping applicability, String propertyName)
{
TypeResolverBuilder> typer = new DefaultTypeResolverBuilder(applicability);
// we'll always use full class name, when using defaulting
typer = typer.init(JsonTypeInfo.Id.CLASS, null);
typer = typer.inclusion(JsonTypeInfo.As.PROPERTY);
typer = typer.typeProperty(propertyName);
return setDefaultTyping(typer);
}
/**
* Method for disabling automatic inclusion of type information; if so, only
* explicitly annotated types (ones with
* {@link com.fasterxml.jackson.annotation.JsonTypeInfo}) will have
* additional embedded type information.
*/
public ObjectMapper disableDefaultTyping() {
return setDefaultTyping(null);
}
/**
* Method for enabling automatic inclusion of type information, using
* specified handler object for determining which types this affects,
* as well as details of how information is embedded.
*
* @param typer Type information inclusion handler
*/
public ObjectMapper setDefaultTyping(TypeResolverBuilder> typer) {
_deserializationConfig = _deserializationConfig.withTypeResolverBuilder(typer);
_serializationConfig = _serializationConfig.withTypeResolverBuilder(typer);
return this;
}
/**
* Method for registering specified class as a subtype, so that
* typename-based resolution can link supertypes to subtypes
* (as an alternative to using annotations).
* Type for given class is determined from appropriate annotation;
* or if missing, default name (unqualified class name)
*/
public void registerSubtypes(Class>... classes) {
getSubtypeResolver().registerSubtypes(classes);
}
/**
* Method for registering specified class as a subtype, so that
* typename-based resolution can link supertypes to subtypes
* (as an alternative to using annotations).
* Name may be provided as part of argument, but if not will
* be based on annotations or use default name (unqualified
* class name).
*/
public void registerSubtypes(NamedType... types) {
getSubtypeResolver().registerSubtypes(types);
}
/*
/**********************************************************
/* Configuration, basic type handling
/**********************************************************
*/
/**
* Accessor for getting currently configured {@link TypeFactory} instance.
*/
public TypeFactory getTypeFactory() {
return _typeFactory;
}
/**
* Method that can be used to override {@link TypeFactory} instance
* used by this mapper.
*java.lang.Class
), but without explicit
* context.
*/
public JavaType constructType(Type t) {
return _typeFactory.constructType(t);
}
/*
/**********************************************************
/* Configuration, deserialization
/**********************************************************
*/
/**
* Method for specifying {@link JsonNodeFactory} to use for
* constructing root level tree nodes (via method
* {@link #createObjectNode}
*/
public ObjectMapper setNodeFactory(JsonNodeFactory f) {
_deserializationConfig = _deserializationConfig.withNodeFactory(f);
return this;
}
/**
* Method for adding specified {@link DeserializationProblemHandler}
* to be used for handling specific problems during deserialization.
*/
public ObjectMapper addHandler(DeserializationProblemHandler h) {
_deserializationConfig = _deserializationConfig.withHandler(h);
return this;
}
/**
* Method for removing all registered {@link DeserializationProblemHandler}s
* instances from this mapper.
*/
public ObjectMapper clearProblemHandlers() {
_deserializationConfig = _deserializationConfig.withNoProblemHandlers();
return this;
}
/*
/**********************************************************
/* Configuration, serialization
/**********************************************************
*/
/**
* Convenience method that is equivalent to:
*
* mapper.setFilters(mapper.getSerializationConfig().withFilters(filterProvider));
*
*
* getJsonFactory().isEnabled(f);
*
*/
public boolean isEnabled(JsonFactory.Feature f) {
return _jsonFactory.isEnabled(f);
}
/**
* Convenience method, equivalent to:
*
* getJsonFactory().isEnabled(f);
*
*/
public boolean isEnabled(JsonParser.Feature f) {
return _jsonFactory.isEnabled(f);
}
/**
* Convenience method, equivalent to:
*
* getJsonFactory().isEnabled(f);
*
*/
public boolean isEnabled(JsonGenerator.Feature f) {
return _jsonFactory.isEnabled(f);
}
/**
* Method that can be used to get hold of {@link JsonNodeFactory}
* that this mapper will use when directly constructing
* root {@link JsonNode} instances for Trees.
*
* getDeserializationConfig().getNodeFactory()
*
*/
public JsonNodeFactory getNodeFactory() {
return _deserializationConfig.getNodeFactory();
}
/*
/**********************************************************
/* Public API (from ObjectCodec): deserialization
/* (mapping from JSON to Java types);
/* main methods
/**********************************************************
*/
/**
* Method to deserialize JSON content into a non-container
* type (it can be an array type, however): typically a bean, array
* or a wrapper type (like {@link java.lang.Boolean}).
*
* objectMapper.convertValue(n, valueClass);
*
*/
@Override
public
* mapper.readValue(mapper.treeAsTokens(root), valueType);
*
*/
@SuppressWarnings("unchecked")
public
* mapper.readValue(mapper.treeAsTokens(root), valueType);
*
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public
* mapper.readValue(mapper.treeAsTokens(root), valueType);
*
*/
@SuppressWarnings("unchecked")
public writeValue
and
* readValue
methods.
*/
protected Object _convert(Object fromValue, JavaType toValueType)
throws IllegalArgumentException
{
// sanity check for null first:
if (fromValue == null) return null;
/* Then use TokenBuffer, which is a JsonGenerator:
* (see [JACKSON-175])
*/
TokenBuffer buf = new TokenBuffer(this);
try {
// inlined 'writeValue' with minor changes:
// first: disable wrapping when writing
SerializationConfig config = getSerializationConfig().without(SerializationConfig.Feature.WRAP_ROOT_VALUE);
// no need to check for closing of TokenBuffer
_serializerProvider.serializeValue(config, buf, fromValue, _serializerFactory);
// then matching read, inlined 'readValue' with minor mods:
final JsonParser jp = buf.asParser();
Object result;
// ok to pass in existing feature flags; unwrapping handled by mapper
final DeserializationConfig deserConfig = getDeserializationConfig();
JsonToken t = _initForReading(jp);
if (t == JsonToken.VALUE_NULL) {
result = _findRootDeserializer(deserConfig, toValueType).getNullValue();
} else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = null;
} else { // pointing to event other than null
DeserializationContext ctxt = _createDeserializationContext(jp, deserConfig);
JsonDeserializer