Yet more refactoring, trying to be able to pass DeserializationContext to ContextualDeserializer
diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java
index 54050e6..b6b78d1 100644
--- a/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java
+++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java
@@ -11,8 +11,6 @@
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.cfg.MapperConfigBase;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
-import com.fasterxml.jackson.databind.deser.ValueInstantiator;
-import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.ClassIntrospector;
import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
@@ -21,7 +19,6 @@
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.type.ClassKey;
import com.fasterxml.jackson.databind.type.TypeFactory;
-import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.LinkedNode;
/**
@@ -667,55 +664,4 @@
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<?> deserClass)
- {
- HandlerInstantiator hi = getHandlerInstantiator();
- if (hi != null) {
- JsonDeserializer<?> deser = hi.deserializerInstance(this, annotated,
- (Class<JsonDeserializer<?>>)deserClass);
- if (deser != null) {
- return (JsonDeserializer<Object>) deser;
- }
- }
- return (JsonDeserializer<Object>) ClassUtil.createInstance(deserClass, canOverrideAccessModifiers());
- }
-
- public KeyDeserializer keyDeserializerInstance(Annotated annotated,
- Class<?> keyDeserClass)
- {
- HandlerInstantiator hi = getHandlerInstantiator();
- if (hi != null) {
- @SuppressWarnings("unchecked")
- KeyDeserializer keyDeser = hi.keyDeserializerInstance(this, annotated,
- (Class<KeyDeserializer>)keyDeserClass);
- if (keyDeser != null) {
- return (KeyDeserializer) keyDeser;
- }
- }
- return (KeyDeserializer) ClassUtil.createInstance(keyDeserClass, canOverrideAccessModifiers());
- }
-
- public ValueInstantiator valueInstantiatorInstance(Annotated annotated,
- Class<?> instClass)
- {
- HandlerInstantiator hi = getHandlerInstantiator();
- if (hi != null) {
- @SuppressWarnings("unchecked")
- ValueInstantiator inst = hi.valueInstantiatorInstance(this, annotated,
- (Class<ValueInstantiator>)instClass);
- if (inst != null) {
- return (ValueInstantiator) inst;
- }
- }
- return (ValueInstantiator) ClassUtil.createInstance(instClass, canOverrideAccessModifiers());
- }
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
index 9370ef4..397bb8e 100644
--- a/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
+++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
@@ -4,8 +4,10 @@
import java.util.*;
import com.fasterxml.jackson.core.*;
+
+import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
-import com.fasterxml.jackson.databind.deser.DeserializerCache;
+import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.ArrayBuilders;
@@ -45,12 +47,6 @@
*/
public DeserializationConfig getConfig() { return _config; }
- /**
- * Returns provider that can be used for dynamically locating
- * other deserializers during runtime.
- */
- public abstract DeserializerCache getDeserializerProvider();
-
public final AnnotationIntrospector getAnnotationIntrospector() {
return _config.getAnnotationIntrospector();
}
@@ -66,6 +62,14 @@
return (_featureFlags & feat.getMask()) != 0;
}
+ public final boolean isEnabled(MapperConfig.Feature feat) {
+ return _config.isEnabled(feat);
+ }
+
+ public final boolean canOverrideAccessModifiers() {
+ return _config.canOverrideAccessModifiers();
+ }
+
/**
* Convenience method for accessing the default Base64 encoding
* used for decoding base64 encoded binary content.
@@ -134,6 +138,20 @@
public abstract KeyDeserializer findKeyDeserializer(JavaType keyType,
BeanProperty property)
throws JsonMappingException;
+
+ /*
+ /**********************************************************
+ /* Extended API: handler instantiation
+ /**********************************************************
+ */
+
+ public abstract JsonDeserializer<Object> deserializerInstance(Annotated annotated,
+ BeanProperty property, Object deserDef)
+ throws JsonMappingException;
+
+ public abstract KeyDeserializer keyDeserializerInstance(Annotated annotated,
+ BeanProperty property, Object keyDeserClass)
+ throws JsonMappingException;
/*
/**********************************************************
diff --git a/src/main/java/com/fasterxml/jackson/databind/HandlerInstantiator.java b/src/main/java/com/fasterxml/jackson/databind/HandlerInstantiator.java
index b93fcb8..c83feaf 100644
--- a/src/main/java/com/fasterxml/jackson/databind/HandlerInstantiator.java
+++ b/src/main/java/com/fasterxml/jackson/databind/HandlerInstantiator.java
@@ -42,7 +42,7 @@
* @return Deserializer instance to use
*/
public abstract JsonDeserializer<?> deserializerInstance(DeserializationConfig config,
- Annotated annotated, Class<? extends JsonDeserializer<?>> deserClass);
+ Annotated annotated, Class<?> deserClass);
/**
* Method called to get an instance of key deserializer of specified type.
@@ -56,7 +56,7 @@
* @return Key deserializer instance to use
*/
public abstract KeyDeserializer keyDeserializerInstance(DeserializationConfig config,
- Annotated annotated, Class<? extends KeyDeserializer> keyDeserClass);
+ Annotated annotated, Class<?> keyDeserClass);
/**
* Method called to get an instance of serializer of specified type.
@@ -85,7 +85,7 @@
* @return TypeResolverBuilder instance to use
*/
public abstract TypeResolverBuilder<?> typeResolverBuilderInstance(MapperConfig<?> config,
- Annotated annotated, Class<? extends TypeResolverBuilder<?>> builderClass);
+ Annotated annotated, Class<?> builderClass);
/**
* Method called to get an instance of TypeIdResolver of specified type.
@@ -100,13 +100,13 @@
* @return TypeResolverBuilder instance to use
*/
public abstract TypeIdResolver typeIdResolverInstance(MapperConfig<?> config,
- Annotated annotated, Class<? extends TypeIdResolver> resolverClass);
+ Annotated annotated, Class<?> resolverClass);
/**
* Method called to construct an instance of ValueInstantiator of specified type.
*/
public ValueInstantiator valueInstantiatorInstance(MapperConfig<?> config,
- Annotated annotated, Class<? extends ValueInstantiator> resolverClass) {
+ Annotated annotated, Class<?> resolverClass) {
return null;
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java
index 57f3e5b..9ebb8de 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java
@@ -225,7 +225,7 @@
*/
@Override
- public abstract ValueInstantiator findValueInstantiator(DeserializationConfig config,
+ public abstract ValueInstantiator findValueInstantiator(DeserializationContext ctxt,
BeanDescription beanDesc)
throws JsonMappingException;
@@ -234,7 +234,7 @@
throws JsonMappingException;
@Override
- public JsonDeserializer<?> createArrayDeserializer(DeserializationConfig config,
+ public JsonDeserializer<?> createArrayDeserializer(DeserializationContext ctxt,
ArrayType type, final BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException
{
@@ -250,7 +250,8 @@
* deserializers for all types (including primitive arrays) is useful
* so let's allow this
*/
- JsonDeserializer<?> custom = _findCustomArrayDeserializer(type, config, property, null, null);
+ JsonDeserializer<?> custom = _findCustomArrayDeserializer(type,
+ ctxt.getConfig(), property, null, null);
if (custom != null) {
return custom;
}
@@ -265,10 +266,11 @@
TypeDeserializer elemTypeDeser = elemType.getTypeHandler();
// but if not, may still be possible to find:
if (elemTypeDeser == null) {
- elemTypeDeser = findTypeDeserializer(config, elemType, property);
+ elemTypeDeser = findTypeDeserializer(ctxt.getConfig(), elemType, property);
}
// 23-Nov-2010, tatu: Custom array deserializer?
- JsonDeserializer<?> custom = _findCustomArrayDeserializer(type, config, property, elemTypeDeser, contentDeser);
+ JsonDeserializer<?> custom = _findCustomArrayDeserializer(type,
+ ctxt.getConfig(), property, elemTypeDeser, contentDeser);
if (custom != null) {
return custom;
}
@@ -276,7 +278,7 @@
}
@Override
- public JsonDeserializer<?> createCollectionDeserializer(DeserializationConfig config,
+ public JsonDeserializer<?> createCollectionDeserializer(DeserializationContext ctxt,
CollectionType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException
{
@@ -288,11 +290,12 @@
TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
// but if not, may still be possible to find:
if (contentTypeDeser == null) {
- contentTypeDeser = findTypeDeserializer(config, contentType, property);
+ contentTypeDeser = findTypeDeserializer(ctxt.getConfig(), contentType, property);
}
// 23-Nov-2010, tatu: Custom deserializer?
- JsonDeserializer<?> custom = _findCustomCollectionDeserializer(type, config, beanDesc, property,
+ JsonDeserializer<?> custom = _findCustomCollectionDeserializer(type,
+ ctxt.getConfig(), beanDesc, property,
contentTypeDeser, contentDeser);
if (custom != null) {
return custom;
@@ -322,11 +325,11 @@
throw new IllegalArgumentException("Can not find a deserializer for non-concrete Collection type "+type);
}
collectionClass = fallback;
- type = (CollectionType) config.constructSpecializedType(type, collectionClass);
+ type = (CollectionType) ctxt.getConfig().constructSpecializedType(type, collectionClass);
// But if so, also need to re-check creators...
- beanDesc = config.introspectForCreation(type);
+ beanDesc = ctxt.getConfig().introspectForCreation(type);
}
- ValueInstantiator inst = findValueInstantiator(config, beanDesc);
+ ValueInstantiator inst = findValueInstantiator(ctxt, beanDesc);
// 13-Dec-2010, tatu: Can use more optimal deserializer if content type is String, so:
if (contentType.getRawClass() == String.class) {
// no value type deserializer because Strings are one of natural/native types:
@@ -337,7 +340,7 @@
// Copied almost verbatim from "createCollectionDeserializer" -- should try to share more code
@Override
- public JsonDeserializer<?> createCollectionLikeDeserializer(DeserializationConfig config,
+ public JsonDeserializer<?> createCollectionLikeDeserializer(DeserializationContext ctxt,
CollectionLikeType type, final BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException
{
@@ -349,17 +352,18 @@
TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
// but if not, may still be possible to find:
if (contentTypeDeser == null) {
- contentTypeDeser = findTypeDeserializer(config, contentType, property);
+ contentTypeDeser = findTypeDeserializer(ctxt.getConfig(), contentType, property);
}
- return _findCustomCollectionLikeDeserializer(type, config, beanDesc, property,
+ return _findCustomCollectionLikeDeserializer(type, ctxt.getConfig(), beanDesc, property,
contentTypeDeser, contentDeser);
}
@Override
- public JsonDeserializer<?> createMapDeserializer(DeserializationConfig config,
+ public JsonDeserializer<?> createMapDeserializer(DeserializationContext ctxt,
MapType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException
{
+ final DeserializationConfig config = ctxt.getConfig();
JavaType keyType = type.getKeyType();
JavaType contentType = type.getContentType();
@@ -415,7 +419,7 @@
// But if so, also need to re-check creators...
beanDesc = config.introspectForCreation(type);
}
- ValueInstantiator inst = findValueInstantiator(config, beanDesc);
+ ValueInstantiator inst = findValueInstantiator(ctxt, beanDesc);
MapDeserializer md = new MapDeserializer(type, property, inst, keyDes, contentDeser, contentTypeDeser);
md.setIgnorableProperties(config.getAnnotationIntrospector().findPropertiesToIgnore(beanDesc.getClassInfo()));
return md;
@@ -423,7 +427,7 @@
// Copied almost verbatim from "createMapDeserializer" -- should try to share more code
@Override
- public JsonDeserializer<?> createMapLikeDeserializer(DeserializationConfig config,
+ public JsonDeserializer<?> createMapLikeDeserializer(DeserializationContext ctxt,
MapLikeType type, final BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException
{
@@ -445,36 +449,37 @@
TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
// but if not, may still be possible to find:
if (contentTypeDeser == null) {
- contentTypeDeser = findTypeDeserializer(config, contentType, property);
+ contentTypeDeser = findTypeDeserializer(ctxt.getConfig(), contentType, property);
}
- return _findCustomMapLikeDeserializer(type, config, beanDesc, property,
- keyDes, contentTypeDeser, contentDeser);
+ return _findCustomMapLikeDeserializer(type, ctxt.getConfig(),
+ beanDesc, property, keyDes, contentTypeDeser, contentDeser);
}
/**
* Factory method for constructing serializers of {@link Enum} types.
*/
@Override
- public JsonDeserializer<?> createEnumDeserializer(DeserializationConfig config,
+ public JsonDeserializer<?> createEnumDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException
{
Class<?> enumClass = type.getRawClass();
// 23-Nov-2010, tatu: Custom deserializer?
- JsonDeserializer<?> custom = _findCustomEnumDeserializer(enumClass, config, beanDesc, property);
+ JsonDeserializer<?> custom = _findCustomEnumDeserializer(enumClass,
+ ctxt.getConfig(), beanDesc, property);
if (custom != null) {
return custom;
}
// [JACKSON-193] May have @JsonCreator for static factory method:
for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) {
- if (config.getAnnotationIntrospector().hasCreatorAnnotation(factory)) {
+ if (ctxt.getAnnotationIntrospector().hasCreatorAnnotation(factory)) {
int argCount = factory.getParameterCount();
if (argCount == 1) {
Class<?> returnType = factory.getRawType();
// usually should be class, but may be just plain Enum<?> (for Enum.valueOf()?)
if (returnType.isAssignableFrom(enumClass)) {
- return EnumDeserializer.deserializerForCreator(config, enumClass, factory);
+ return EnumDeserializer.deserializerForCreator(ctxt.getConfig(), enumClass, factory);
}
}
throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type "
@@ -482,7 +487,7 @@
}
}
// [JACKSON-749] Also, need to consider @JsonValue, if one found
- return new EnumDeserializer(constructEnumResolver(enumClass, config, beanDesc.findJsonValueMethod()));
+ return new EnumDeserializer(constructEnumResolver(enumClass, ctxt.getConfig(), beanDesc.findJsonValueMethod()));
}
@Override
@@ -574,10 +579,11 @@
}
@Override
- public KeyDeserializer createKeyDeserializer(DeserializationConfig config, JavaType type,
- BeanProperty property)
+ public KeyDeserializer createKeyDeserializer(DeserializationContext ctxt,
+ JavaType type, BeanProperty property)
throws JsonMappingException
{
+ final DeserializationConfig config = ctxt.getConfig();
if (_factoryConfig.hasKeyDeserializers()) {
BeanDescription beanDesc = config.introspectClassAnnotations(type.getRawClass());
for (KeyDeserializers d : _factoryConfig.keyDeserializers()) {
@@ -588,31 +594,31 @@
}
}
// and if none found, standard ones:
- // No serializer needed if it's plain old String, or Object/untyped
Class<?> raw = type.getRawClass();
if (raw == String.class || raw == Object.class) {
return StdKeyDeserializers.constructStringKeyDeserializer(config, type);
}
- // Most other keys are of limited number of static types
+ // Most other keys are for limited number of static types
KeyDeserializer kdes = _keyDeserializers.get(type);
if (kdes != null) {
return kdes;
}
// And then other one-offs; first, Enum:
if (type.isEnumType()) {
- return _createEnumKeyDeserializer(config, type, property);
+ return _createEnumKeyDeserializer(ctxt, type, property);
}
// One more thing: can we find ctor(String) or valueOf(String)?
kdes = StdKeyDeserializers.findStringBasedKeyDeserializer(config, type);
return kdes;
}
- private KeyDeserializer _createEnumKeyDeserializer(DeserializationConfig config,
+ private KeyDeserializer _createEnumKeyDeserializer(DeserializationContext ctxt,
JavaType type, BeanProperty property)
throws JsonMappingException
{
+ final DeserializationConfig config = ctxt.getConfig();
BeanDescription beanDesc = config.introspect(type);
- JsonDeserializer<?> des = findDeserializerFromAnnotation(config, beanDesc.getClassInfo(), property);
+ JsonDeserializer<?> des = findDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo(), property);
if (des != null) {
return StdKeyDeserializers.constructDelegatingKeyDeserializer(config, type, des);
}
@@ -722,39 +728,15 @@
* has annotation that tells which class to use for deserialization.
* Returns null if no such annotation found.
*/
- @SuppressWarnings("unchecked")
- protected JsonDeserializer<Object> findDeserializerFromAnnotation(DeserializationConfig config,
+ protected JsonDeserializer<Object> findDeserializerFromAnnotation(DeserializationContext ctxt,
Annotated ann, BeanProperty property)
throws JsonMappingException
{
- Object deserDef = config.getAnnotationIntrospector().findDeserializer(ann);
+ Object deserDef = ctxt.getAnnotationIntrospector().findDeserializer(ann);
if (deserDef == null) {
return null;
}
- if (deserDef instanceof JsonDeserializer) {
- JsonDeserializer<Object> deser = (JsonDeserializer<Object>) deserDef;
- // related to [JACKSON-569], need contextualization:
- if (deser instanceof ContextualDeserializer<?>) {
- deser = (JsonDeserializer<Object>)((ContextualDeserializer<?>) deser).createContextual(config, property);
- }
- return deser;
- }
- /* Alas, there's no way to force return type of "either class
- * X or Y" -- need to throw an exception after the fact
- */
- if (!(deserDef instanceof Class)) {
- throw new IllegalStateException("AnnotationIntrospector returned deserializer definition of type "+deserDef.getClass().getName()+"; expected type JsonDeserializer or Class<JsonDeserializer> instead");
- }
- Class<? extends JsonDeserializer<?>> deserClass = (Class<? extends JsonDeserializer<?>>) deserDef;
- if (!JsonDeserializer.class.isAssignableFrom(deserClass)) {
- throw new IllegalStateException("AnnotationIntrospector returned Class "+deserClass.getName()+"; expected Class<JsonDeserializer>");
- }
- JsonDeserializer<Object> deser = config.deserializerInstance(ann, deserClass);
- // related to [JACKSON-569], need contextualization:
- if (deser instanceof ContextualDeserializer<?>) {
- deser = (JsonDeserializer<Object>)((ContextualDeserializer<?>) deser).createContextual(config, property);
- }
- return deser;
+ return ctxt.deserializerInstance(ann, property, deserDef);
}
/**
@@ -764,48 +746,28 @@
* using generic type passed as type reference), which is
* needed in some cases.
*/
- protected JavaType resolveType(DeserializationConfig config,
+ protected JavaType resolveType(DeserializationContext ctxt,
BeanDescription beanDesc, JavaType type, AnnotatedMember member,
BeanProperty property)
throws JsonMappingException
{
// [JACKSON-154]: Also need to handle keyUsing, contentUsing
if (type.isContainerType()) {
- AnnotationIntrospector intr = config.getAnnotationIntrospector();
+ AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
JavaType keyType = type.getKeyType();
if (keyType != null) {
Object kdDef = intr.findKeyDeserializer(member);
- if (kdDef != null) {
- KeyDeserializer kd = null;
- if (kdDef instanceof KeyDeserializer) {
- kd = (KeyDeserializer) kdDef;
- } else {
- Class<?> kdClass = _verifyAsClass(kdDef, "findKeyDeserializer", KeyDeserializer.None.class);
- if (kdClass != null) {
- kd = config.keyDeserializerInstance(member, kdClass);
- }
- }
- if (kd != null) {
- type = ((MapLikeType) type).withKeyValueHandler(kd);
- keyType = type.getKeyType(); // just in case it's used below
- }
+ KeyDeserializer kd = ctxt.keyDeserializerInstance(member, property, kdDef);
+ if (kd != null) {
+ type = ((MapLikeType) type).withKeyValueHandler(kd);
+ keyType = type.getKeyType(); // just in case it's used below
}
}
// and all container types have content types...
Object cdDef = intr.findContentDeserializer(member);
- if (cdDef != null) {
- JsonDeserializer<?> cd = null;
- if (cdDef instanceof JsonDeserializer<?>) {
- cd = (JsonDeserializer<?>) cdDef;
- } else {
- Class<?> cdClass = _verifyAsClass(cdDef, "findContentDeserializer", JsonDeserializer.None.class);
- if (cdClass != null) {
- cd = config.deserializerInstance(member, cdClass);
- }
- }
- if (cd != null) {
- type = type.withContentValueHandler(cd);
- }
+ JsonDeserializer<?> cd = ctxt.deserializerInstance(member, property, cdDef);
+ if (cd != null) {
+ type = type.withContentValueHandler(cd);
}
/* 04-Feb-2010, tatu: Need to figure out JAXB annotations that indicate type
* information to use for polymorphic members; and specifically types for
@@ -813,8 +775,8 @@
* ... but only applies to members (fields, methods), not classes
*/
if (member instanceof AnnotatedMember) {
- TypeDeserializer contentTypeDeser = findPropertyContentTypeDeserializer(config, type,
- (AnnotatedMember) member, property);
+ TypeDeserializer contentTypeDeser = findPropertyContentTypeDeserializer(
+ ctxt.getConfig(), type, (AnnotatedMember) member, property);
if (contentTypeDeser != null) {
type = type.withContentTypeHandler(contentTypeDeser);
}
@@ -823,10 +785,11 @@
TypeDeserializer valueTypeDeser;
if (member instanceof AnnotatedMember) { // JAXB allows per-property annotations
- valueTypeDeser = findPropertyTypeDeserializer(config, type, (AnnotatedMember) member, property);
+ valueTypeDeser = findPropertyTypeDeserializer(ctxt.getConfig(),
+ type, (AnnotatedMember) member, property);
} else { // classes just have Jackson annotations
// probably only occurs if 'property' is null anyway
- valueTypeDeser = findTypeDeserializer(config, type, null);
+ valueTypeDeser = findTypeDeserializer(ctxt.getConfig(), type, null);
}
if (valueTypeDeser != null) {
type = type.withTypeHandler(valueTypeDeser);
@@ -834,6 +797,44 @@
return type;
}
+ public ValueInstantiator valueInstantiatorInstance(DeserializationConfig config,
+ Annotated annotated, Object instDef)
+ throws JsonMappingException
+ {
+ if (instDef == null) {
+ return null;
+ }
+
+ ValueInstantiator inst;
+
+ if (instDef instanceof ValueInstantiator) {
+ inst = (ValueInstantiator) instDef;
+ } else {
+ if (!(instDef instanceof Class)) {
+ throw new IllegalStateException("AnnotationIntrospector returned key deserializer definition of type "
+ +instDef.getClass().getName()
+ +"; expected type KeyDeserializer or Class<KeyDeserializer> instead");
+ }
+ Class<?> instClass = (Class<?>)instDef;
+ if (instClass == NoClass.class) {
+ return null;
+ }
+ if (!ValueInstantiator.class.isAssignableFrom(instClass)) {
+ throw new IllegalStateException("AnnotationIntrospector returned Class "+instClass.getName()
+ +"; expected Class<ValueInstantiator>");
+ }
+ HandlerInstantiator hi = config.getHandlerInstantiator();
+ if (hi != null) {
+ inst = hi.valueInstantiatorInstance(config, annotated, instClass);
+ } else {
+ inst = (ValueInstantiator) ClassUtil.createInstance(instClass,
+ config.canOverrideAccessModifiers());
+ }
+ }
+ // not resolvable or contextual, just return:
+ return inst;
+ }
+
protected EnumResolver<?> constructEnumResolver(Class<?> enumClass, DeserializationConfig config,
AnnotatedMethod jsonValueMethod)
{
@@ -859,19 +860,4 @@
BeanDescription beanDesc = config.introspect(enumType);
return beanDesc.findJsonValueMethod();
}
-
- protected Class<?> _verifyAsClass(Object src, String methodName, Class<?> noneClass)
- {
- if (src == null) {
- return null;
- }
- if (!(src instanceof Class)) {
- throw new IllegalStateException("AnnotationIntrospector."+methodName+"() returned value of type "+src.getClass().getName()+": expected type JsonSerializer or Class<JsonSerializer> instead");
- }
- Class<?> cls = (Class<?>) src;
- if (cls == noneClass || cls == NoClass.class) {
- return null;
- }
- return cls;
- }
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java
index b21704c..bd1b405 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java
@@ -1367,22 +1367,19 @@
return subDeser;
}
// If not, maybe we can locate one. First, need provider
- DeserializerCache deserProv = ctxt.getDeserializerProvider();
- if (deserProv != null) {
- JavaType type = ctxt.constructType(bean.getClass());
- /* 09-Dec-2010, tatu: Would be nice to know which property pointed to this
- * bean... but, alas, no such information is retained, so:
- */
- subDeser = ctxt.findValueDeserializer(type, _property);
- // Also, need to cache it
- if (subDeser != null) {
- synchronized (this) {
- if (_subDeserializers == null) {
- _subDeserializers = new HashMap<ClassKey,JsonDeserializer<Object>>();;
- }
- _subDeserializers.put(new ClassKey(bean.getClass()), subDeser);
- }
- }
+ JavaType type = ctxt.constructType(bean.getClass());
+ /* 09-Dec-2010, tatu: Would be nice to know which property pointed to this
+ * bean... but, alas, no such information is retained, so:
+ */
+ subDeser = ctxt.findValueDeserializer(type, _property);
+ // Also, need to cache it
+ if (subDeser != null) {
+ synchronized (this) {
+ if (_subDeserializers == null) {
+ _subDeserializers = new HashMap<ClassKey,JsonDeserializer<Object>>();;
+ }
+ _subDeserializers.put(new ClassKey(bean.getClass()), subDeser);
+ }
}
return subDeser;
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java
index dea7683..b07d22a 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java
@@ -422,37 +422,26 @@
* module interface).
*/
@Override
- public ValueInstantiator findValueInstantiator(DeserializationConfig config,
+ public ValueInstantiator findValueInstantiator(DeserializationContext ctxt,
BeanDescription beanDesc)
throws JsonMappingException
{
- ValueInstantiator instantiator;
+ final DeserializationConfig config = ctxt.getConfig();
+
+ ValueInstantiator instantiator = null;
// [JACKSON-633] Check @JsonValueInstantiator before anything else
AnnotatedClass ac = beanDesc.getClassInfo();
- Object instDef = config.getAnnotationIntrospector().findValueInstantiator(ac);
+ Object instDef = ctxt.getAnnotationIntrospector().findValueInstantiator(ac);
if (instDef != null) {
- if (instDef instanceof ValueInstantiator) {
- instantiator = (ValueInstantiator) instDef;
- } else {
- if (!(instDef instanceof Class<?>)) { // sanity check
- throw new IllegalStateException("Invalid value instantiator returned for type "+beanDesc+": neither a Class nor ValueInstantiator");
- }
- Class<?> cls = (Class<?>) instDef;
- if (!ValueInstantiator.class.isAssignableFrom(cls)) {
- throw new IllegalStateException("Invalid instantiator Class<?> returned for type "+beanDesc+": "
- +cls.getName()+" not a ValueInstantiator");
- }
- @SuppressWarnings("unchecked")
- Class<? extends ValueInstantiator> instClass = (Class<? extends ValueInstantiator>) cls;
- instantiator = config.valueInstantiatorInstance(ac, (Class<? extends ValueInstantiator>)instClass);
- }
- } else {
+ instantiator = valueInstantiatorInstance(config, ac, instDef);
+ }
+ if (instantiator == null) {
/* Second: see if some of standard Jackson/JDK types might provide value
* instantiators.
*/
instantiator = findStdValueInstantiator(config, beanDesc);
if (instantiator == null) {
- instantiator = constructDefaultValueInstantiator(config, beanDesc);
+ instantiator = constructDefaultValueInstantiator(ctxt, beanDesc);
}
}
@@ -477,10 +466,11 @@
* enums.
*/
@Override
- public JsonDeserializer<Object> createBeanDeserializer(DeserializationConfig config,
+ public JsonDeserializer<Object> createBeanDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException
{
+ final DeserializationConfig config = ctxt.getConfig();
// We may also have custom overrides:
JsonDeserializer<Object> custom = _findCustomBeanDeserializer(type, config, beanDesc, property);
if (custom != null) {
@@ -491,7 +481,7 @@
* different handling.
*/
if (type.isThrowable()) {
- return buildThrowableDeserializer(config, type, beanDesc, property);
+ return buildThrowableDeserializer(ctxt, type, beanDesc, property);
}
/* Or, for abstract types, may have alternate means for resolution
* (defaulting, materialization)
@@ -504,7 +494,7 @@
* interface doesn't have constructors, for one)
*/
beanDesc = config.introspect(concreteType);
- return buildBeanDeserializer(config, concreteType, beanDesc, property);
+ return buildBeanDeserializer(ctxt, concreteType, beanDesc, property);
}
}
@@ -519,7 +509,7 @@
return null;
}
// Use generic bean introspection to build deserializer
- return buildBeanDeserializer(config, type, beanDesc, property);
+ return buildBeanDeserializer(ctxt, type, beanDesc, property);
}
/**
@@ -574,12 +564,13 @@
* deserializers.
*/
@SuppressWarnings("unchecked")
- public JsonDeserializer<Object> buildBeanDeserializer(DeserializationConfig config,
+ public JsonDeserializer<Object> buildBeanDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException
{
// First: check what creators we can use, if any
- ValueInstantiator valueInstantiator = findValueInstantiator(config, beanDesc);
+ ValueInstantiator valueInstantiator = findValueInstantiator(ctxt, beanDesc);
+ final DeserializationConfig config = ctxt.getConfig();
// ... since often we have nothing to go on, if we have abstract type:
if (type.isAbstract()) {
if (!valueInstantiator.canInstantiate()) {
@@ -590,10 +581,10 @@
BeanDeserializerBuilder builder = constructBeanDeserializerBuilder(beanDesc);
builder.setValueInstantiator(valueInstantiator);
// And then setters for deserializing from JSON Object
- addBeanProps(config, beanDesc, builder);
+ addBeanProps(ctxt, beanDesc, builder);
// managed/back reference fields/setters need special handling... first part
- addReferenceProperties(config, beanDesc, builder);
- addInjectables(config, beanDesc, builder);
+ addReferenceProperties(ctxt, beanDesc, builder);
+ addInjectables(ctxt, beanDesc, builder);
// [JACKSON-440]: update builder now that all information is in?
if (_factoryConfig.hasDeserializerModifiers()) {
@@ -614,15 +605,16 @@
}
@SuppressWarnings("unchecked")
- public JsonDeserializer<Object> buildThrowableDeserializer(DeserializationConfig config,
+ public JsonDeserializer<Object> buildThrowableDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException
{
+ final DeserializationConfig config = ctxt.getConfig();
// first: construct like a regular bean deserializer...
BeanDeserializerBuilder builder = constructBeanDeserializerBuilder(beanDesc);
- builder.setValueInstantiator(findValueInstantiator(config, beanDesc));
+ builder.setValueInstantiator(findValueInstantiator(ctxt, beanDesc));
- addBeanProps(config, beanDesc, builder);
+ addBeanProps(ctxt, beanDesc, builder);
// (and assume there won't be any back references)
// But then let's decorate things a bit
@@ -631,7 +623,7 @@
*/
AnnotatedMethod am = beanDesc.findMethod("initCause", INIT_CAUSE_PARAMS);
if (am != null) { // should never be null
- SettableBeanProperty prop = constructSettableProperty(config, beanDesc, "cause", am);
+ SettableBeanProperty prop = constructSettableProperty(ctxt, beanDesc, "cause", am);
if (prop != null) {
/* 21-Aug-2011, tatus: We may actually have found 'cause' property
* to set (with new 1.9 code)... but let's replace it just in case,
@@ -699,13 +691,13 @@
* Method that will construct standard default {@link ValueInstantiator}
* using annotations (like @JsonCreator) and visibility rules
*/
- protected ValueInstantiator constructDefaultValueInstantiator(DeserializationConfig config,
+ protected ValueInstantiator constructDefaultValueInstantiator(DeserializationContext ctxt,
BeanDescription beanDesc)
throws JsonMappingException
{
- boolean fixAccess = config.canOverrideAccessModifiers();
+ boolean fixAccess = ctxt.canOverrideAccessModifiers();
CreatorCollector creators = new CreatorCollector(beanDesc, fixAccess);
- AnnotationIntrospector intr = config.getAnnotationIntrospector();
+ AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
// First, let's figure out constructor/factory-based instantiation
// 23-Jan-2010, tatus: but only for concrete types
@@ -720,20 +712,21 @@
}
// need to construct suitable visibility checker:
+ final DeserializationConfig config = ctxt.getConfig();
VisibilityChecker<?> vchecker = config.getDefaultVisibilityChecker();
vchecker = config.getAnnotationIntrospector().findAutoDetectVisibility(beanDesc.getClassInfo(), vchecker);
/* Important: first add factory methods; then constructors, so
* latter can override former!
*/
- _addDeserializerFactoryMethods(config, beanDesc, vchecker, intr, creators);
- _addDeserializerConstructors(config, beanDesc, vchecker, intr, creators);
+ _addDeserializerFactoryMethods(ctxt, beanDesc, vchecker, intr, creators);
+ _addDeserializerConstructors(ctxt, beanDesc, vchecker, intr, creators);
return creators.constructValueInstantiator(config);
}
protected void _addDeserializerConstructors
- (DeserializationConfig config, BeanDescription beanDesc, VisibilityChecker<?> vchecker,
+ (DeserializationContext ctxt, BeanDescription beanDesc, VisibilityChecker<?> vchecker,
AnnotationIntrospector intr, CreatorCollector creators)
throws JsonMappingException
{
@@ -746,7 +739,7 @@
boolean isVisible = vchecker.isCreatorVisible(ctor);
// some single-arg constructors (String, number) are auto-detected
if (argCount == 1) {
- _handleSingleArgumentConstructor(config, beanDesc, vchecker, intr, creators,
+ _handleSingleArgumentConstructor(ctxt, beanDesc, vchecker, intr, creators,
ctor, isCreator, isVisible);
continue;
}
@@ -769,10 +762,10 @@
Object injectId = intr.findInjectableValueId(param);
if (name != null && name.length() > 0) {
++namedCount;
- properties[i] = constructCreatorProperty(config, beanDesc, name, i, param, injectId);
+ properties[i] = constructCreatorProperty(ctxt, beanDesc, name, i, param, injectId);
} else if (injectId != null) {
++injectCount;
- properties[i] = constructCreatorProperty(config, beanDesc, name, i, param, injectId);
+ properties[i] = constructCreatorProperty(ctxt, beanDesc, name, i, param, injectId);
} else if (nonAnnotatedParam == null) {
nonAnnotatedParam = param;
}
@@ -793,7 +786,7 @@
}
}
- protected boolean _handleSingleArgumentConstructor(DeserializationConfig config,
+ protected boolean _handleSingleArgumentConstructor(DeserializationContext ctxt,
BeanDescription beanDesc, VisibilityChecker<?> vchecker,
AnnotationIntrospector intr, CreatorCollector creators,
AnnotatedConstructor ctor, boolean isCreator, boolean isVisible)
@@ -807,7 +800,7 @@
if ((injectId != null) || (name != null && name.length() > 0)) { // property-based
// We know there's a name and it's only 1 parameter.
CreatorProperty[] properties = new CreatorProperty[1];
- properties[0] = constructCreatorProperty(config, beanDesc, name, 0, param, injectId);
+ properties[0] = constructCreatorProperty(ctxt, beanDesc, name, 0, param, injectId);
creators.addPropertyCreator(ctor, properties);
return true;
}
@@ -848,11 +841,11 @@
}
protected void _addDeserializerFactoryMethods
- (DeserializationConfig config, BeanDescription beanDesc, VisibilityChecker<?> vchecker,
+ (DeserializationContext ctxt, BeanDescription beanDesc, VisibilityChecker<?> vchecker,
AnnotationIntrospector intr, CreatorCollector creators)
throws JsonMappingException
{
-
+ final DeserializationConfig config = ctxt.getConfig();
for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) {
int argCount = factory.getParameterCount();
if (argCount < 1) {
@@ -889,10 +882,10 @@
Object injectId = intr.findInjectableValueId(param);
if (name != null && name.length() > 0) {
++namedCount;
- properties[i] = constructCreatorProperty(config, beanDesc, name, i, param, injectId);
+ properties[i] = constructCreatorProperty(ctxt, beanDesc, name, i, param, injectId);
} else if (injectId != null) {
++injectCount;
- properties[i] = constructCreatorProperty(config, beanDesc, name, i, param, injectId);
+ properties[i] = constructCreatorProperty(ctxt, beanDesc, name, i, param, injectId);
} else if (nonAnnotatedParam == null) {
nonAnnotatedParam = param;
}
@@ -964,22 +957,23 @@
* a logical property passed via Creator (constructor or static
* factory method)
*/
- protected CreatorProperty constructCreatorProperty(DeserializationConfig config,
+ protected CreatorProperty constructCreatorProperty(DeserializationContext ctxt,
BeanDescription beanDesc, String name, int index,
AnnotatedParameter param,
Object injectableValueId)
throws JsonMappingException
{
+ final DeserializationConfig config = ctxt.getConfig();
JavaType t0 = config.getTypeFactory().constructType(param.getParameterType(), beanDesc.bindingsForBeanType());
BeanProperty.Std property = new BeanProperty.Std(name, t0, beanDesc.getClassAnnotations(), param);
- JavaType type = resolveType(config, beanDesc, t0, param, property);
+ JavaType type = resolveType(ctxt, beanDesc, t0, param, property);
if (type != t0) {
property = property.withType(type);
}
// Is there an annotation that specifies exact deserializer?
- JsonDeserializer<Object> deser = findDeserializerFromAnnotation(config, param, property);
+ JsonDeserializer<Object> deser = findDeserializerFromAnnotation(ctxt, param, property);
// If yes, we are mostly done:
- type = modifyTypeByAnnotation(config, param, type, name);
+ type = modifyTypeByAnnotation(ctxt, param, type, property);
// Type deserializer: either comes from property (and already resolved)
TypeDeserializer typeDeser = (TypeDeserializer) type.getTypeHandler();
@@ -1002,13 +996,13 @@
* Note: designed to be overridable, and effort is made to keep interface
* similar between versions.
*/
- protected void addBeanProps(DeserializationConfig config,
+ protected void addBeanProps(DeserializationContext ctxt,
BeanDescription beanDesc, BeanDeserializerBuilder builder)
throws JsonMappingException
{
List<BeanPropertyDefinition> props = beanDesc.findProperties();
// Things specified as "ok to ignore"? [JACKSON-77]
- AnnotationIntrospector intr = config.getAnnotationIntrospector();
+ AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
boolean ignoreAny = false;
{
Boolean B = intr.findIgnoreUnknownProperties(beanDesc.getClassInfo());
@@ -1025,7 +1019,7 @@
// Also, do we have a fallback "any" setter?
AnnotatedMethod anySetter = beanDesc.findAnySetter();
if (anySetter != null) {
- builder.setAnySetter(constructAnySetter(config, beanDesc, anySetter));
+ builder.setAnySetter(constructAnySetter(ctxt, beanDesc, anySetter));
}
// NOTE: we do NOT add @JsonIgnore'd properties into blocked ones if there's any setter
// Implicit ones via @JsonIgnore and equivalent?
@@ -1061,12 +1055,12 @@
AnnotatedMethod setter = property.getSetter();
// [JACKSON-429] Some types are declared as ignorable as well
Class<?> type = setter.getParameterClass(0);
- if (isIgnorableType(config, beanDesc, type, ignoredTypes)) {
+ if (isIgnorableType(ctxt.getConfig(), beanDesc, type, ignoredTypes)) {
// important: make ignorable, to avoid errors if value is actually seen
builder.addIgnorable(name);
continue;
}
- SettableBeanProperty prop = constructSettableProperty(config, beanDesc, name, setter);
+ SettableBeanProperty prop = constructSettableProperty(ctxt, beanDesc, name, setter);
if (prop != null) {
builder.addProperty(prop);
}
@@ -1076,12 +1070,12 @@
AnnotatedField field = property.getField();
// [JACKSON-429] Some types are declared as ignorable as well
Class<?> type = field.getRawType();
- if (isIgnorableType(config, beanDesc, type, ignoredTypes)) {
+ if (isIgnorableType(ctxt.getConfig(), beanDesc, type, ignoredTypes)) {
// important: make ignorable, to avoid errors if value is actually seen
builder.addIgnorable(name);
continue;
}
- SettableBeanProperty prop = constructSettableProperty(config, beanDesc, name, field);
+ SettableBeanProperty prop = constructSettableProperty(ctxt, beanDesc, name, field);
if (prop != null) {
builder.addProperty(prop);
}
@@ -1094,7 +1088,7 @@
/* also, as per [JACKSON-328], should not override fields (or actual setters),
* thus these are added AFTER adding fields
*/
- if (config.isEnabled(MapperConfig.Feature.USE_GETTERS_AS_SETTERS)) {
+ if (ctxt.isEnabled(MapperConfig.Feature.USE_GETTERS_AS_SETTERS)) {
/* Hmmh. We have to assume that 'use getters as setters' also
* implies 'yes, do auto-detect these getters'? (if not, we'd
* need to add AUTO_DETECT_GETTERS to deser config too, not
@@ -1111,7 +1105,7 @@
Class<?> rt = getter.getRawType();
if (Collection.class.isAssignableFrom(rt) || Map.class.isAssignableFrom(rt)) {
if (!ignored.contains(name) && !builder.hasProperty(name)) {
- builder.addProperty(constructSetterlessProperty(config, beanDesc, name, getter));
+ builder.addProperty(constructSetterlessProperty(ctxt, beanDesc, name, getter));
}
}
}
@@ -1123,7 +1117,7 @@
* Method that will find if bean has any managed- or back-reference properties,
* and if so add them to bean, to be linked during resolution phase.
*/
- protected void addReferenceProperties(DeserializationConfig config,
+ protected void addReferenceProperties(DeserializationContext ctxt,
BeanDescription beanDesc, BeanDeserializerBuilder builder)
throws JsonMappingException
{
@@ -1135,10 +1129,10 @@
AnnotatedMember m = en.getValue();
if (m instanceof AnnotatedMethod) {
builder.addBackReferenceProperty(name, constructSettableProperty(
- config, beanDesc, m.getName(), (AnnotatedMethod) m));
+ ctxt, beanDesc, m.getName(), (AnnotatedMethod) m));
} else {
builder.addBackReferenceProperty(name, constructSettableProperty(
- config, beanDesc, m.getName(), (AnnotatedField) m));
+ ctxt, beanDesc, m.getName(), (AnnotatedField) m));
}
}
}
@@ -1148,13 +1142,13 @@
* Method called locate all members used for value injection (if any),
* constructor {@link com.fasterxml.jackson.databind.deser.impl.ValueInjector} instances, and add them to builder.
*/
- protected void addInjectables(DeserializationConfig config,
+ protected void addInjectables(DeserializationContext ctxt,
BeanDescription beanDesc, BeanDeserializerBuilder builder)
throws JsonMappingException
{
Map<Object, AnnotatedMember> raw = beanDesc.findInjectables();
if (raw != null) {
- boolean fixAccess = config.canOverrideAccessModifiers();
+ boolean fixAccess = ctxt.canOverrideAccessModifiers();
for (Map.Entry<Object, AnnotatedMember> entry : raw.entrySet()) {
AnnotatedMember m = entry.getValue();
if (fixAccess) {
@@ -1171,31 +1165,31 @@
* for handling unknown bean properties, given a method that
* has been designated as such setter.
*/
- protected SettableAnyProperty constructAnySetter(DeserializationConfig config,
+ protected SettableAnyProperty constructAnySetter(DeserializationContext ctxt,
BeanDescription beanDesc, AnnotatedMethod setter)
throws JsonMappingException
{
- if (config.canOverrideAccessModifiers()) {
+ if (ctxt.canOverrideAccessModifiers()) {
setter.fixAccess(); // to ensure we can call it
}
// we know it's a 2-arg method, second arg is the value
JavaType type = beanDesc.bindingsForBeanType().resolveType(setter.getParameterType(1));
BeanProperty.Std property = new BeanProperty.Std(setter.getName(), type, beanDesc.getClassAnnotations(), setter);
- type = resolveType(config, beanDesc, type, setter, property);
+ type = resolveType(ctxt, beanDesc, type, setter, property);
/* AnySetter can be annotated with @JsonClass (etc) just like a
* regular setter... so let's see if those are used.
* Returns null if no annotations, in which case binding will
* be done at a later point.
*/
- JsonDeserializer<Object> deser = findDeserializerFromAnnotation(config, setter, property);
+ JsonDeserializer<Object> deser = findDeserializerFromAnnotation(ctxt, setter, property);
if (deser != null) {
return new SettableAnyProperty(property, setter, type, deser);
}
/* Otherwise, method may specify more specific (sub-)class for
* value (no need to check if explicit deser was specified):
*/
- type = modifyTypeByAnnotation(config, setter, type, property.getName());
+ type = modifyTypeByAnnotation(ctxt, setter, type, property);
return new SettableAnyProperty(property, setter, type, null);
}
@@ -1209,20 +1203,20 @@
* @return Property constructed, if any; or null to indicate that
* there should be no property based on given definitions.
*/
- protected SettableBeanProperty constructSettableProperty(DeserializationConfig config,
+ protected SettableBeanProperty constructSettableProperty(DeserializationContext ctxt,
BeanDescription beanDesc, String name,
AnnotatedMethod setter)
throws JsonMappingException
{
// need to ensure method is callable (for non-public)
- if (config.canOverrideAccessModifiers()) {
+ if (ctxt.canOverrideAccessModifiers()) {
setter.fixAccess();
}
// note: this works since we know there's exactly one argument for methods
JavaType t0 = beanDesc.bindingsForBeanType().resolveType(setter.getParameterType(0));
BeanProperty.Std property = new BeanProperty.Std(name, t0, beanDesc.getClassAnnotations(), setter);
- JavaType type = resolveType(config, beanDesc, t0, setter, property);
+ JavaType type = resolveType(ctxt, beanDesc, t0, setter, property);
// did type change?
if (type != t0) {
property = property.withType(type);
@@ -1231,8 +1225,8 @@
/* First: does the Method specify the deserializer to use?
* If so, let's use it.
*/
- JsonDeserializer<Object> propDeser = findDeserializerFromAnnotation(config, setter, property);
- type = modifyTypeByAnnotation(config, setter, type, name);
+ JsonDeserializer<Object> propDeser = findDeserializerFromAnnotation(ctxt, setter, property);
+ type = modifyTypeByAnnotation(ctxt, setter, type, property);
TypeDeserializer typeDeser = type.getTypeHandler();
SettableBeanProperty prop = new SettableBeanProperty.MethodProperty(name, type, typeDeser,
beanDesc.getClassAnnotations(), setter);
@@ -1240,24 +1234,24 @@
prop = prop.withValueDeserializer(propDeser);
}
// [JACKSON-235]: need to retain name of managed forward references:
- AnnotationIntrospector.ReferenceProperty ref = config.getAnnotationIntrospector().findReferenceType(setter);
+ AnnotationIntrospector.ReferenceProperty ref = ctxt.getAnnotationIntrospector().findReferenceType(setter);
if (ref != null && ref.isManagedReference()) {
prop.setManagedReferenceName(ref.getName());
}
return prop;
}
- protected SettableBeanProperty constructSettableProperty(DeserializationConfig config,
+ protected SettableBeanProperty constructSettableProperty(DeserializationContext ctxt,
BeanDescription beanDesc, String name, AnnotatedField field)
throws JsonMappingException
{
// need to ensure method is callable (for non-public)
- if (config.canOverrideAccessModifiers()) {
+ if (ctxt.canOverrideAccessModifiers()) {
field.fixAccess();
}
JavaType t0 = beanDesc.bindingsForBeanType().resolveType(field.getGenericType());
BeanProperty.Std property = new BeanProperty.Std(name, t0, beanDesc.getClassAnnotations(), field);
- JavaType type = resolveType(config, beanDesc, t0, field, property);
+ JavaType type = resolveType(ctxt, beanDesc, t0, field, property);
// did type change?
if (type != t0) {
property = property.withType(type);
@@ -1265,8 +1259,8 @@
/* First: does the Method specify the deserializer to use?
* If so, let's use it.
*/
- JsonDeserializer<Object> propDeser = findDeserializerFromAnnotation(config, field, property);
- type = modifyTypeByAnnotation(config, field, type, name);
+ JsonDeserializer<Object> propDeser = findDeserializerFromAnnotation(ctxt, field, property);
+ type = modifyTypeByAnnotation(ctxt, field, type, property);
TypeDeserializer typeDeser = type.getTypeHandler();
SettableBeanProperty prop = new SettableBeanProperty.FieldProperty(name, type, typeDeser,
beanDesc.getClassAnnotations(), field);
@@ -1274,7 +1268,7 @@
prop = prop.withValueDeserializer(propDeser);
}
// [JACKSON-235]: need to retain name of managed forward references:
- AnnotationIntrospector.ReferenceProperty ref = config.getAnnotationIntrospector().findReferenceType(field);
+ AnnotationIntrospector.ReferenceProperty ref = ctxt.getAnnotationIntrospector().findReferenceType(field);
if (ref != null && ref.isManagedReference()) {
prop.setManagedReferenceName(ref.getName());
}
@@ -1288,12 +1282,12 @@
* @param getter Method to use to get property value to modify, null if
* none. Non-null for "setterless" properties.
*/
- protected SettableBeanProperty constructSetterlessProperty(DeserializationConfig config,
+ protected SettableBeanProperty constructSetterlessProperty(DeserializationContext ctxt,
BeanDescription beanDesc, String name, AnnotatedMethod getter)
throws JsonMappingException
{
// need to ensure it is callable now:
- if (config.canOverrideAccessModifiers()) {
+ if (ctxt.canOverrideAccessModifiers()) {
getter.fixAccess();
}
@@ -1303,8 +1297,8 @@
*/
BeanProperty.Std property = new BeanProperty.Std(name, type, beanDesc.getClassAnnotations(), getter);
// @TODO: create BeanProperty to pass?
- JsonDeserializer<Object> propDeser = findDeserializerFromAnnotation(config, getter, property);
- type = modifyTypeByAnnotation(config, getter, type, name);
+ JsonDeserializer<Object> propDeser = findDeserializerFromAnnotation(ctxt, getter, property);
+ type = modifyTypeByAnnotation(ctxt, getter, type, property);
TypeDeserializer typeDeser = type.getTypeHandler();
SettableBeanProperty prop = new SettableBeanProperty.SetterlessProperty(name, type, typeDeser,
beanDesc.getClassAnnotations(), getter);
@@ -1376,7 +1370,7 @@
*
* @param a Method or field that the type is associated with
* @param type Type derived from the setter argument
- * @param propName Name of property that refers to type, if any; null
+ * @param prop property that refers to type, if any; null
* if no property information available (when modify type declaration
* of a class, for example)
*
@@ -1386,13 +1380,14 @@
* @throws JsonMappingException if invalid annotation is found
*/
@SuppressWarnings({ "unchecked" })
- protected <T extends JavaType> T modifyTypeByAnnotation(DeserializationConfig config,
- Annotated a, T type, String propName)
+ protected <T extends JavaType> T modifyTypeByAnnotation(DeserializationContext ctxt,
+ Annotated a, T type, BeanProperty prop)
throws JsonMappingException
{
// first: let's check class for the instance itself:
- AnnotationIntrospector intr = config.getAnnotationIntrospector();
- Class<?> subclass = intr.findDeserializationType(a, type, propName);
+ AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
+ Class<?> subclass = intr.findDeserializationType(a, type,
+ (prop == null) ? null : prop.getName());
if (subclass != null) {
try {
type = (T) type.narrowBy(subclass);
@@ -1403,7 +1398,8 @@
// then key class
if (type.isContainerType()) {
- Class<?> keyClass = intr.findDeserializationKeyType(a, type.getKeyType(), propName);
+ Class<?> keyClass = intr.findDeserializationKeyType(a, type.getKeyType(),
+ (prop == null) ? null : prop.getName());
if (keyClass != null) {
// illegal to use on non-Maps
if (!(type instanceof MapLikeType)) {
@@ -1422,25 +1418,16 @@
*/
if (keyType != null && keyType.getValueHandler() == null) {
Object kdDef = intr.findKeyDeserializer(a);
- if (kdDef != null) {
- KeyDeserializer kd = null;
- if (kdDef instanceof KeyDeserializer) {
- kd = (KeyDeserializer) kdDef;
- } else {
- Class<?> kdClass = _verifyAsClass(kdDef, "findKeyDeserializer", KeyDeserializer.None.class);
- if (kdClass != null) {
- kd = config.keyDeserializerInstance(a, kdClass);
- }
- }
- if (kd != null) {
- type = (T) ((MapLikeType) type).withKeyValueHandler(kd);
- keyType = type.getKeyType(); // just in case it's used below
- }
+ KeyDeserializer kd = ctxt.keyDeserializerInstance(a, prop, kdDef);
+ if (kd != null) {
+ type = (T) ((MapLikeType) type).withKeyValueHandler(kd);
+ keyType = type.getKeyType(); // just in case it's used below
}
}
// and finally content class; only applicable to structured types
- Class<?> cc = intr.findDeserializationContentType(a, type.getContentType(), propName);
+ Class<?> cc = intr.findDeserializationContentType(a, type.getContentType(),
+ (prop == null) ? null : prop.getName());
if (cc != null) {
try {
type = (T) type.narrowContentsBy(cc);
@@ -1452,19 +1439,9 @@
JavaType contentType = type.getContentType();
if (contentType.getValueHandler() == null) { // as with above, avoid resetting (which would trigger exception)
Object cdDef = intr.findContentDeserializer(a);
- if (cdDef != null) {
- JsonDeserializer<?> cd = null;
- if (cdDef instanceof JsonDeserializer<?>) {
- cdDef = (JsonDeserializer<?>) cdDef;
- } else {
- Class<?> cdClass = _verifyAsClass(cdDef, "findContentDeserializer", JsonDeserializer.None.class);
- if (cdClass != null) {
- cd = config.deserializerInstance(a, cdClass);
- }
- }
- if (cd != null) {
- type = (T) type.withContentValueHandler(cd);
- }
+ JsonDeserializer<?> cd = ctxt.deserializerInstance(a, prop, cdDef);
+ if (cd != null) {
+ type = (T) type.withContentValueHandler(cd);
}
}
}
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java
index 8129379..1c32281 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerCache.java
@@ -236,18 +236,22 @@
* accessing suitable key deserializer; including that of not
* finding any serializer
*/
- public KeyDeserializer findKeyDeserializer(DeserializationConfig config,
+ public KeyDeserializer findKeyDeserializer(DeserializationContext ctxt,
JavaType type, BeanProperty property)
throws JsonMappingException
{
- KeyDeserializer kd = _factory.createKeyDeserializer(config, type, property);
- // One more thing: contextuality
- if (kd instanceof ContextualKeyDeserializer) {
- kd = ((ContextualKeyDeserializer) kd).createContextual(config, property);
- }
+ KeyDeserializer kd = _factory.createKeyDeserializer(ctxt, type, property);
if (kd == null) { // if none found, need to use a placeholder that'll fail
return _handleUnknownKeyDeserializer(type);
}
+ // First: need to resolve?
+ if (kd instanceof ResolvableDeserializer) {
+ ((ResolvableDeserializer) kd).resolve(ctxt);
+ }
+ // Second: contextualize?
+ if (kd instanceof ContextualKeyDeserializer) {
+ kd = ((ContextualKeyDeserializer) kd).createContextual(ctxt.getConfig(), property);
+ }
return kd;
}
@@ -409,7 +413,7 @@
}
// If not, may have further type-modification annotations to check:
- JavaType newType = modifyTypeByAnnotation(config, beanDesc.getClassInfo(), type, property);
+ JavaType newType = modifyTypeByAnnotation(ctxt, beanDesc.getClassInfo(), type, property);
if (newType != type) {
type = newType;
beanDesc = config.introspect(newType);
@@ -417,30 +421,30 @@
// If not, let's see which factory method to use:
if (type.isEnumType()) {
- return (JsonDeserializer<Object>) _factory.createEnumDeserializer(config, type,
+ return (JsonDeserializer<Object>) _factory.createEnumDeserializer(ctxt, type,
beanDesc, property);
}
if (type.isContainerType()) {
if (type.isArrayType()) {
- return (JsonDeserializer<Object>)_factory.createArrayDeserializer(config,
+ return (JsonDeserializer<Object>)_factory.createArrayDeserializer(ctxt,
(ArrayType) type, beanDesc, property);
}
if (type.isMapLikeType()) {
MapLikeType mlt = (MapLikeType) type;
if (mlt.isTrueMapType()) {
- return (JsonDeserializer<Object>)_factory.createMapDeserializer(config,
+ return (JsonDeserializer<Object>)_factory.createMapDeserializer(ctxt,
(MapType) mlt, beanDesc, property);
}
- return (JsonDeserializer<Object>)_factory.createMapLikeDeserializer(config,
+ return (JsonDeserializer<Object>)_factory.createMapLikeDeserializer(ctxt,
mlt, beanDesc, property);
}
if (type.isCollectionLikeType()) {
CollectionLikeType clt = (CollectionLikeType) type;
if (clt.isTrueCollectionType()) {
- return (JsonDeserializer<Object>)_factory.createCollectionDeserializer(config,
+ return (JsonDeserializer<Object>)_factory.createCollectionDeserializer(ctxt,
(CollectionType) clt, beanDesc, property);
}
- return (JsonDeserializer<Object>)_factory.createCollectionLikeDeserializer(config,
+ return (JsonDeserializer<Object>)_factory.createCollectionLikeDeserializer(ctxt,
clt, beanDesc, property);
}
}
@@ -449,7 +453,7 @@
if (JsonNode.class.isAssignableFrom(type.getRawClass())) {
return (JsonDeserializer<Object>)_factory.createTreeDeserializer(config, type, beanDesc, property);
}
- return (JsonDeserializer<Object>)_factory.createBeanDeserializer(config, type, beanDesc, property);
+ return (JsonDeserializer<Object>)_factory.createBeanDeserializer(ctxt, type, beanDesc, property);
}
/**
@@ -457,7 +461,6 @@
* has annotation that tells which class to use for deserialization.
* Returns null if no such annotation found.
*/
- @SuppressWarnings("unchecked")
protected JsonDeserializer<Object> findDeserializerFromAnnotation(DeserializationContext ctxt,
Annotated ann, BeanProperty property)
throws JsonMappingException
@@ -466,38 +469,7 @@
if (deserDef == null) {
return null;
}
- if (deserDef instanceof JsonDeserializer) {
- JsonDeserializer<Object> deser = (JsonDeserializer<Object>) deserDef;
- // related to [JACKSON-569], need contextualization:
- if (deser instanceof ContextualDeserializer<?>) {
- deser = (JsonDeserializer<Object>)((ContextualDeserializer<?>) deser).createContextual(ctxt.getConfig(), property);
- }
- return deser;
- }
- /* Alas, there's no way to force return type of "either class
- * X or Y" -- need to throw an exception after the fact
- */
- if (!(deserDef instanceof Class)) {
- throw new IllegalStateException("AnnotationIntrospector returned deserializer definition of type "+deserDef.getClass().getName()+"; expected type JsonDeserializer or Class<JsonDeserializer> instead");
- }
- Class<? extends JsonDeserializer<?>> deserClass = (Class<? extends JsonDeserializer<?>>) deserDef;
- if (!JsonDeserializer.class.isAssignableFrom(deserClass)) {
- throw new IllegalStateException("AnnotationIntrospector returned Class "+deserClass.getName()+"; expected Class<JsonDeserializer>");
- }
- JsonDeserializer<Object> deser = ctxt.getConfig().deserializerInstance(ann, deserClass);
- // related to [JACKSON-569], need contextualization:
- if (deser instanceof ContextualDeserializer<?>) {
- deser = (JsonDeserializer<Object>)((ContextualDeserializer<?>) deser).createContextual(ctxt.getConfig(), property);
- }
- return deser;
- }
-
- private JavaType modifyTypeByAnnotation(DeserializationConfig config,
- Annotated a, JavaType type, BeanProperty prop)
- throws JsonMappingException
- {
- return modifyTypeByAnnotation(config, a, type,
- (prop == null) ? null : prop.getName());
+ return ctxt.deserializerInstance(ann, property, deserDef);
}
/**
@@ -510,22 +482,21 @@
*
* @param a Method or field that the type is associated with
* @param type Type derived from the setter argument
- * @param propName Name of property that refers to type, if any; null
- * if no property information available (when modify type declaration
- * of a class, for example)
+ * @param prop Property that lead to this annotation, if any.
*
* @return Original type if no annotations are present; or a more
* specific type derived from it if type annotation(s) was found
*
* @throws JsonMappingException if invalid annotation is found
*/
- private JavaType modifyTypeByAnnotation(DeserializationConfig config,
- Annotated a, JavaType type, String propName)
+ private JavaType modifyTypeByAnnotation(DeserializationContext ctxt,
+ Annotated a, JavaType type, BeanProperty prop)
throws JsonMappingException
{
// first: let's check class for the instance itself:
- AnnotationIntrospector intr = config.getAnnotationIntrospector();
- Class<?> subclass = intr.findDeserializationType(a, type, propName);
+ AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
+ Class<?> subclass = intr.findDeserializationType(a, type,
+ (prop == null)? null : prop.getName());
if (subclass != null) {
try {
type = type.narrowBy(subclass);
@@ -536,7 +507,8 @@
// then key class
if (type.isContainerType()) {
- Class<?> keyClass = intr.findDeserializationKeyType(a, type.getKeyType(), propName);
+ Class<?> keyClass = intr.findDeserializationKeyType(a, type.getKeyType(),
+ (prop == null)? null : prop.getName());
if (keyClass != null) {
// illegal to use on non-Maps
if (!(type instanceof MapLikeType)) {
@@ -556,15 +528,7 @@
if (keyType != null && keyType.getValueHandler() == null) {
Object kdDef = intr.findKeyDeserializer(a);
if (kdDef != null) {
- KeyDeserializer kd = null;
- if (kdDef instanceof KeyDeserializer) {
- kd = (KeyDeserializer) kdDef;
- } else {
- Class<?> kdClass = _verifyAsClass(kdDef, "findKeyDeserializer", KeyDeserializer.None.class);
- if (kdClass != null) {
- kd = config.keyDeserializerInstance(a, kdClass);
- }
- }
+ KeyDeserializer kd = ctxt.keyDeserializerInstance(a, prop, kdDef);
if (kd != null) {
type = ((MapLikeType) type).withKeyValueHandler(kd);
keyType = type.getKeyType(); // just in case it's used below
@@ -573,7 +537,8 @@
}
// and finally content class; only applicable to structured types
- Class<?> cc = intr.findDeserializationContentType(a, type.getContentType(), propName);
+ Class<?> cc = intr.findDeserializationContentType(a, type.getContentType(),
+ (prop == null) ? null : prop.getName());
if (cc != null) {
try {
type = type.narrowContentsBy(cc);
@@ -592,7 +557,7 @@
} else {
Class<?> cdClass = _verifyAsClass(cdDef, "findContentDeserializer", JsonDeserializer.None.class);
if (cdClass != null) {
- cd = config.deserializerInstance(a, cdClass);
+ cd = ctxt.deserializerInstance(a, prop, cdClass);
}
}
if (cd != null) {
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerFactory.java
index b28d095..d3ed96f 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerFactory.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/DeserializerFactory.java
@@ -198,7 +198,7 @@
* Method that is to find all creators (constructors, factory methods)
* for the bean type to deserialize.
*/
- public abstract ValueInstantiator findValueInstantiator(DeserializationConfig config,
+ public abstract ValueInstantiator findValueInstantiator(DeserializationContext ctxt,
BeanDescription beanDesc)
throws JsonMappingException;
@@ -214,7 +214,7 @@
*
* @param type Type to be deserialized
*/
- public abstract JsonDeserializer<Object> createBeanDeserializer(DeserializationConfig config,
+ public abstract JsonDeserializer<Object> createBeanDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException;
@@ -225,27 +225,27 @@
*
* @param type Type to be deserialized
*/
- public abstract JsonDeserializer<?> createArrayDeserializer(DeserializationConfig config,
+ public abstract JsonDeserializer<?> createArrayDeserializer(DeserializationContext ctxt,
ArrayType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException;
- public abstract JsonDeserializer<?> createCollectionDeserializer(DeserializationConfig config,
+ public abstract JsonDeserializer<?> createCollectionDeserializer(DeserializationContext ctxt,
CollectionType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException;
- public abstract JsonDeserializer<?> createCollectionLikeDeserializer(DeserializationConfig config,
+ public abstract JsonDeserializer<?> createCollectionLikeDeserializer(DeserializationContext ctxt,
CollectionLikeType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException;
- public abstract JsonDeserializer<?> createEnumDeserializer(DeserializationConfig config,
+ public abstract JsonDeserializer<?> createEnumDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException;
- public abstract JsonDeserializer<?> createMapDeserializer(DeserializationConfig config,
+ public abstract JsonDeserializer<?> createMapDeserializer(DeserializationContext ctxt,
MapType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException;
- public abstract JsonDeserializer<?> createMapLikeDeserializer(DeserializationConfig config,
+ public abstract JsonDeserializer<?> createMapLikeDeserializer(DeserializationContext ctxt,
MapLikeType type, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException;
@@ -265,7 +265,7 @@
* @return Key deserializer to use for specified type, if one found; null if not
* (and default key deserializer should be used)
*/
- public abstract KeyDeserializer createKeyDeserializer(DeserializationConfig config,
+ public abstract KeyDeserializer createKeyDeserializer(DeserializationContext ctxt,
JavaType type, BeanProperty property)
throws JsonMappingException;
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/StdDeserializationContext.java b/src/main/java/com/fasterxml/jackson/databind/deser/StdDeserializationContext.java
index 866f1fb..8c29676 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/StdDeserializationContext.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/StdDeserializationContext.java
@@ -7,7 +7,9 @@
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.NoClass;
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
+import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.util.ArrayBuilders;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.LinkedNode;
@@ -35,7 +37,7 @@
*/
protected JsonParser _parser;
- protected final DeserializerCache _deserProvider;
+ protected final DeserializerCache _deserCache;
protected final InjectableValues _injectableValues;
@@ -54,11 +56,11 @@
*/
public StdDeserializationContext(DeserializationConfig config, JsonParser jp,
- DeserializerCache prov, InjectableValues injectableValues)
+ DeserializerCache cache, InjectableValues injectableValues)
{
super(config);
_parser = jp;
- _deserProvider = prov;
+ _deserCache = cache;
_injectableValues = injectableValues;
}
@@ -68,9 +70,8 @@
/**********************************************************
*/
- @Override
- public DeserializerCache getDeserializerProvider() {
- return _deserProvider;
+ public DeserializerCache getDeserializerCache() {
+ return _deserCache;
}
/**
@@ -103,21 +104,115 @@
@Override
public JsonDeserializer<Object> findValueDeserializer(JavaType type,
BeanProperty property) throws JsonMappingException {
- return _deserProvider.findValueDeserializer(this, type, property);
+ return _deserCache.findValueDeserializer(this, type, property);
}
@Override
public JsonDeserializer<Object> findTypedValueDeserializer(JavaType type,
BeanProperty property) throws JsonMappingException {
- return _deserProvider.findTypedValueDeserializer(this, type, property);
+ return _deserCache.findTypedValueDeserializer(this, type, property);
}
@Override
public KeyDeserializer findKeyDeserializer(JavaType keyType,
BeanProperty property) throws JsonMappingException {
- return _deserProvider.findKeyDeserializer(_config, keyType, property);
+ return _deserCache.findKeyDeserializer(this, keyType, property);
}
+ @SuppressWarnings("unchecked")
+ @Override
+ public JsonDeserializer<Object> deserializerInstance(Annotated annotated,
+ BeanProperty property, Object deserDef)
+ throws JsonMappingException
+ {
+ if (deserDef == null) {
+ return null;
+ }
+ JsonDeserializer<?> deser;
+
+ if (deserDef instanceof JsonDeserializer) {
+ deser = (JsonDeserializer<?>) deserDef;
+ } else {
+ /* Alas, there's no way to force return type of "either class
+ * X or Y" -- need to throw an exception after the fact
+ */
+ if (!(deserDef instanceof Class)) {
+ throw new IllegalStateException("AnnotationIntrospector returned deserializer definition of type "+deserDef.getClass().getName()+"; expected type JsonDeserializer or Class<JsonDeserializer> instead");
+ }
+ Class<?> deserClass = (Class<?>)deserDef;
+ // there are some known "no class" markers to consider too:
+ if (deserClass == JsonDeserializer.None.class || deserClass == NoClass.class) {
+ return null;
+ }
+ if (!JsonDeserializer.class.isAssignableFrom(deserClass)) {
+ throw new IllegalStateException("AnnotationIntrospector returned Class "+deserClass.getName()+"; expected Class<JsonDeserializer>");
+ }
+ HandlerInstantiator hi = _config.getHandlerInstantiator();
+ if (hi != null) {
+ deser = hi.deserializerInstance(_config, annotated, deserClass);
+ } else {
+ deser = (JsonDeserializer<?>) ClassUtil.createInstance(deserClass,
+ _config.canOverrideAccessModifiers());
+ }
+ }
+ // First: need to resolve
+ if (deser instanceof ResolvableDeserializer) {
+ ((ResolvableDeserializer) deser).resolve(this);
+ }
+ // Second: contextualize:
+ if (deser instanceof ContextualDeserializer<?>) {
+ deser = ((ContextualDeserializer<?>) deser).createContextual(_config, property);
+ }
+ return (JsonDeserializer<Object>) deser;
+ }
+
+ @Override
+ public KeyDeserializer keyDeserializerInstance(Annotated annotated,
+ BeanProperty property, Object deserDef)
+ throws JsonMappingException
+ {
+ if (deserDef == null) {
+ return null;
+ }
+
+ KeyDeserializer deser;
+
+ if (deserDef instanceof KeyDeserializer) {
+ deser = (KeyDeserializer) deserDef;
+ } else {
+ if (!(deserDef instanceof Class)) {
+ throw new IllegalStateException("AnnotationIntrospector returned key deserializer definition of type "
+ +deserDef.getClass().getName()
+ +"; expected type KeyDeserializer or Class<KeyDeserializer> instead");
+ }
+ Class<?> deserClass = (Class<?>)deserDef;
+ // there are some known "no class" markers to consider too:
+ if (deserClass == KeyDeserializer.None.class || deserClass == NoClass.class) {
+ return null;
+ }
+ if (!KeyDeserializer.class.isAssignableFrom(deserClass)) {
+ throw new IllegalStateException("AnnotationIntrospector returned Class "+deserClass.getName()
+ +"; expected Class<KeyDeserializer>");
+ }
+ HandlerInstantiator hi = _config.getHandlerInstantiator();
+ if (hi != null) {
+ deser = hi.keyDeserializerInstance(_config, annotated, deserClass);
+ } else {
+ deser = (KeyDeserializer) ClassUtil.createInstance(deserClass,
+ _config.canOverrideAccessModifiers());
+ }
+ }
+ // First: need to resolve
+ if (deser instanceof ResolvableDeserializer) {
+ ((ResolvableDeserializer) deser).resolve(this);
+ }
+ // Second: contextualize:
+ if (deser instanceof ContextualKeyDeserializer) {
+ deser = ((ContextualKeyDeserializer) deser).createContextual(_config, property);
+ }
+ return deser;
+ }
+
/*
/**********************************************************
/* Public API, helper object recycling
diff --git a/src/test/java/com/fasterxml/jackson/databind/TestHandlerInstantiation.java b/src/test/java/com/fasterxml/jackson/databind/TestHandlerInstantiation.java
index 26aebe6..6d1dd78 100644
--- a/src/test/java/com/fasterxml/jackson/databind/TestHandlerInstantiation.java
+++ b/src/test/java/com/fasterxml/jackson/databind/TestHandlerInstantiation.java
@@ -179,8 +179,9 @@
}
@Override
- public JsonDeserializer<?> deserializerInstance(DeserializationConfig config, Annotated annotated,
- Class<? extends JsonDeserializer<?>> deserClass)
+ public JsonDeserializer<?> deserializerInstance(DeserializationConfig config,
+ Annotated annotated,
+ Class<?> deserClass)
{
if (deserClass == MyBeanDeserializer.class) {
return new MyBeanDeserializer(_prefix);
@@ -190,7 +191,7 @@
@Override
public KeyDeserializer keyDeserializerInstance(DeserializationConfig config,
- Annotated annotated, Class<? extends KeyDeserializer> keyDeserClass)
+ Annotated annotated, Class<?> keyDeserClass)
{
if (keyDeserClass == MyKeyDeserializer.class) {
return new MyKeyDeserializer();
@@ -211,7 +212,7 @@
@Override
public TypeIdResolver typeIdResolverInstance(MapperConfig<?> config,
- Annotated annotated, Class<? extends TypeIdResolver> resolverClass)
+ Annotated annotated, Class<?> resolverClass)
{
if (resolverClass == CustomIdResolver.class) {
return new CustomIdResolver("!!!");
@@ -221,7 +222,7 @@
@Override
public TypeResolverBuilder<?> typeResolverBuilderInstance(MapperConfig<?> config, Annotated annotated,
- Class<? extends TypeResolverBuilder<?>> builderClass)
+ Class<?> builderClass)
{
return null;
}