package com.fasterxml.jackson.databind;
import java.lang.reflect.
Type;
import com.fasterxml.jackson.
annotation.
ObjectIdGenerator;
import com.fasterxml.jackson.databind.
annotation.
NoClass;
import com.fasterxml.jackson.databind.
cfg.
HandlerInstantiator;
import com.fasterxml.jackson.databind.
cfg.
MapperConfig;
import com.fasterxml.jackson.databind.
introspect.
Annotated;
import com.fasterxml.jackson.databind.
introspect.
ObjectIdInfo;
import com.fasterxml.jackson.databind.
type.
TypeFactory;
import com.fasterxml.jackson.databind.
util.
ClassUtil;
import com.fasterxml.jackson.databind.
util.
Converter;
/**
* Shared base class for {@link DeserializationContext} and
* {@link SerializerProvider}, context objects passed through data-binding
* process. Designed so that some of implementations can rely on shared
* aspects like access to secondary contextual objects like type factories
* or handler instantiators.
*
* @since 2.2
*/
public abstract class
DatabindContext
{
/*
/**********************************************************
/* Generic config access
/**********************************************************
*/
/**
* Accessor to currently active configuration (both per-request configs
* and per-mapper config).
*/
public abstract
MapperConfig<?> getConfig();
/**
* Convenience method for accessing serialization view in use (if any); equivalent to:
*<pre>
* getConfig().getAnnotationIntrospector();
*</pre>
*/
public abstract
AnnotationIntrospector getAnnotationIntrospector();
/*
/**********************************************************
/* Access to specific config settings
/**********************************************************
*/
/**
* Convenience method for checking whether specified serialization
* feature is enabled or not.
* Shortcut for:
*<pre>
* getConfig().isEnabled(feature);
*</pre>
*/
public final boolean isEnabled(
MapperFeature feature) {
return
getConfig().
isEnabled(
feature);
}
/**
* Convenience method for accessing serialization view in use (if any); equivalent to:
*<pre>
* getConfig().canOverrideAccessModifiers();
*</pre>
*/
public final boolean
canOverrideAccessModifiers() {
return
getConfig().
canOverrideAccessModifiers();
}
/**
* Accessor for locating currently active view, if any;
* returns null if no view has been set.
*/
public abstract
Class<?>
getActiveView();
/*
/**********************************************************
/* Generic attributes (2.3+)
/**********************************************************
*/
/**
* Method for accessing attributes available in this context.
* Per-call attributes have highest precedence; attributes set
* via {@link ObjectReader} or {@link ObjectWriter} have lower
* precedence.
*
* @param key Key of the attribute to get
* @return Value of the attribute, if any; null otherwise
*
* @since 2.3
*/
public abstract
Object getAttribute(
Object key);
/**
* Method for setting per-call value of given attribute.
* This will override any previously defined value for the
* attribute within this context.
*
* @param key Key of the attribute to set
* @param value Value to set attribute to
*
* @return This context object, to allow chaining
*
* @since 2.3
*/
public abstract
DatabindContext setAttribute(
Object key,
Object value);
/*
/**********************************************************
/* Type instantiation/resolution
/**********************************************************
*/
/**
* Convenience method for constructing {@link JavaType} for given JDK
* type (usually {@link java.lang.Class})
*/
public
JavaType constructType(
Type type) {
return
getTypeFactory().
constructType(
type);
}
/**
* Convenience method for constructing subtypes, retaining generic
* type parameter (if any)
*/
public
JavaType constructSpecializedType(
JavaType baseType,
Class<?>
subclass) {
// simple optimization to avoid costly introspection if type-erased type does NOT differ
if (
baseType.
getRawClass() ==
subclass) {
return
baseType;
}
return
getConfig().
constructSpecializedType(
baseType,
subclass);
}
public abstract
TypeFactory getTypeFactory();
/*
/**********************************************************
/* Helper object construction
/**********************************************************
*/
public
ObjectIdGenerator<?> objectIdGeneratorInstance(
Annotated annotated,
ObjectIdInfo objectIdInfo)
throws
JsonMappingException
{
Class<?>
implClass =
objectIdInfo.
getGeneratorType();
final
MapperConfig<?>
config =
getConfig();
HandlerInstantiator hi =
config.
getHandlerInstantiator();
ObjectIdGenerator<?>
gen = (
hi == null) ? null :
hi.
objectIdGeneratorInstance(
config,
annotated,
implClass);
if (
gen == null) {
gen = (
ObjectIdGenerator<?>)
ClassUtil.
createInstance(
implClass,
config.
canOverrideAccessModifiers());
}
return
gen.
forScope(
objectIdInfo.
getScope());
}
/**
* Helper method to use to construct a {@link Converter}, given a definition
* that may be either actual converter instance, or Class for instantiating one.
*
* @since 2.2
*/
@
SuppressWarnings("unchecked")
public
Converter<
Object,
Object> converterInstance(
Annotated annotated,
Object converterDef)
throws
JsonMappingException
{
if (
converterDef == null) {
return null;
}
if (
converterDef instanceof
Converter<?,?>) {
return (
Converter<
Object,
Object>)
converterDef;
}
if (!(
converterDef instanceof
Class)) {
throw new
IllegalStateException("AnnotationIntrospector returned Converter definition of type "
+
converterDef.
getClass().
getName()+"; expected type Converter or Class<Converter> instead");
}
Class<?>
converterClass = (
Class<?>)
converterDef;
// there are some known "no class" markers to consider too:
if (
converterClass ==
Converter.
None.class ||
converterClass ==
NoClass.class) {
return null;
}
if (!
Converter.class.
isAssignableFrom(
converterClass)) {
throw new
IllegalStateException("AnnotationIntrospector returned Class "
+
converterClass.
getName()+"; expected Class<Converter>");
}
final
MapperConfig<?>
config =
getConfig();
HandlerInstantiator hi =
config.
getHandlerInstantiator();
Converter<?,?>
conv = (
hi == null) ? null :
hi.
converterInstance(
config,
annotated,
converterClass);
if (
conv == null) {
conv = (
Converter<?,?>)
ClassUtil.
createInstance(
converterClass,
config.
canOverrideAccessModifiers());
}
return (
Converter<
Object,
Object>)
conv;
}
}