aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorTatu Saloranta <tatu.saloranta@iki.fi>2016-10-05 23:21:57 -0700
committerTatu Saloranta <tatu.saloranta@iki.fi>2016-10-05 23:21:57 -0700
commitd068a401140fb876757f37d694dfa271933752ac (patch)
tree08553eff537f3b0ebc5d1584d3dc213674753e56 /src/main/java
parent816bbed534c8541b2257d58688a0e43792047291 (diff)
downloadjackson-databind-d068a401140fb876757f37d694dfa271933752ac.tar.gz
Fix #1035
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java6
-rw-r--r--src/main/java/com/fasterxml/jackson/databind/KeyDeserializer.java4
-rw-r--r--src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java17
-rw-r--r--src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java58
-rw-r--r--src/main/java/com/fasterxml/jackson/databind/deser/SettableAnyProperty.java27
5 files changed, 84 insertions, 28 deletions
diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
index 7942eff5c..7bd6e3e70 100644
--- a/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
+++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java
@@ -3,11 +3,7 @@ package com.fasterxml.jackson.databind;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
+import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import com.fasterxml.jackson.annotation.JsonFormat;
diff --git a/src/main/java/com/fasterxml/jackson/databind/KeyDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/KeyDeserializer.java
index 90dd56da6..217527d41 100644
--- a/src/main/java/com/fasterxml/jackson/databind/KeyDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/KeyDeserializer.java
@@ -2,8 +2,6 @@ package com.fasterxml.jackson.databind;
import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-
/**
* Abstract class that defines API used for deserializing JSON content
* field names into Java Map keys. These deserializers are only used
@@ -15,7 +13,7 @@ public abstract class KeyDeserializer
* Method called to deserialize a {@link java.util.Map} key from JSON property name.
*/
public abstract Object deserializeKey(String key, DeserializationContext ctxt)
- throws IOException, JsonProcessingException;
+ throws IOException;
/**
* This marker class is only to be used with annotations, to
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 d80c23d03..750c3c26b 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java
@@ -1781,6 +1781,23 @@ public abstract class BasicDeserializerFactory
}
/**
+ * @since 2.9
+ */
+ protected JsonDeserializer<Object> findContentDeserializerFromAnnotation(DeserializationContext ctxt,
+ Annotated ann)
+ throws JsonMappingException
+ {
+ AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
+ if (intr != null) {
+ Object deserDef = intr.findContentDeserializer(ann);
+ if (deserDef != null) {
+ return ctxt.deserializerInstance(ann, deserDef);
+ }
+ }
+ return null;
+ }
+
+ /**
* Helper method used to resolve additional type-related annotation information
* like type overrides, or handler (serializer, deserializer) overrides,
* so that from declared field, property or constructor parameter type
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 06217d2a6..ad37f3ad7 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java
@@ -679,31 +679,59 @@ public class BeanDeserializerFactory
throws JsonMappingException
{
//find the java type based on the annotated setter method or setter field
- JavaType type = null;
+ BeanProperty prop;
+ JavaType keyType;
+ JavaType valueType;
+
if (mutator instanceof AnnotatedMethod) {
// we know it's a 2-arg method, second arg is the value
- type = ((AnnotatedMethod) mutator).getParameterType(1);
+ AnnotatedMethod am = (AnnotatedMethod) mutator;
+ keyType = am.getParameterType(0);
+ valueType = am.getParameterType(1);
+ valueType = resolveMemberAndTypeAnnotations(ctxt, mutator, valueType);
+ prop = new BeanProperty.Std(PropertyName.construct(mutator.getName()),
+ valueType, null, beanDesc.getClassAnnotations(), mutator,
+ PropertyMetadata.STD_OPTIONAL);
+
} else if (mutator instanceof AnnotatedField) {
+ AnnotatedField af = (AnnotatedField) mutator;
// get the type from the content type of the map object
- type = ((AnnotatedField) mutator).getType().getContentType();
- }
- // First: various annotations on type itself, as well as type-overrides
- // on accessor need to be resolved
- type = resolveMemberAndTypeAnnotations(ctxt, mutator, type);
- BeanProperty.Std prop = new BeanProperty.Std(PropertyName.construct(mutator.getName()),
- type, null, beanDesc.getClassAnnotations(), mutator,
- PropertyMetadata.STD_OPTIONAL);
+ JavaType mapType = af.getType();
+ mapType = resolveMemberAndTypeAnnotations(ctxt, mutator, mapType);
+ keyType = mapType.getKeyType();
+ valueType = mapType.getContentType();
+ prop = new BeanProperty.Std(PropertyName.construct(mutator.getName()),
+ mapType, null, beanDesc.getClassAnnotations(), mutator,
+ PropertyMetadata.STD_OPTIONAL);
+ } else {
+ return ctxt.reportBadDefinition(beanDesc.getType(), String.format(
+ "Unrecognized mutator type for any setter: %s", mutator.getClass()));
+ }
+ // First: see if there are explicitly specified
// and then possible direct deserializer override on accessor
- JsonDeserializer<Object> deser = findDeserializerFromAnnotation(ctxt, mutator);
+ KeyDeserializer keyDeser = findKeyDeserializerFromAnnotation(ctxt, mutator);
+ if (keyDeser == null) {
+ keyDeser = keyType.getValueHandler();
+ }
+ if (keyDeser == null) {
+ keyDeser = ctxt.findKeyDeserializer(keyType, prop);
+ } else {
+ if (keyDeser instanceof ContextualKeyDeserializer) {
+ keyDeser = ((ContextualKeyDeserializer) keyDeser)
+ .createContextual(ctxt, prop);
+ }
+ }
+ JsonDeserializer<Object> deser = findContentDeserializerFromAnnotation(ctxt, mutator);
if (deser == null) {
- deser = type.getValueHandler();
+ deser = valueType.getValueHandler();
}
if (deser != null) {
// As per [databind#462] need to ensure we contextualize deserializer before passing it on
- deser = (JsonDeserializer<Object>) ctxt.handlePrimaryContextualization(deser, prop, type);
+ deser = (JsonDeserializer<Object>) ctxt.handlePrimaryContextualization(deser, prop, valueType);
}
- TypeDeserializer typeDeser = type.getTypeHandler();
- return new SettableAnyProperty(prop, mutator, type, deser, typeDeser);
+ TypeDeserializer typeDeser = valueType.getTypeHandler();
+ return new SettableAnyProperty(prop, mutator, valueType,
+ keyDeser, deser, typeDeser);
}
/**
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/SettableAnyProperty.java b/src/main/java/com/fasterxml/jackson/databind/deser/SettableAnyProperty.java
index 8ee86d433..ead2f39b4 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/SettableAnyProperty.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/SettableAnyProperty.java
@@ -42,7 +42,12 @@ public class SettableAnyProperty
protected JsonDeserializer<Object> _valueDeserializer;
protected final TypeDeserializer _valueTypeDeserializer;
-
+
+ /**
+ * @since 2.9
+ */
+ protected final KeyDeserializer _keyDeserializer;
+
/*
/**********************************************************
/* Life-cycle
@@ -50,6 +55,7 @@ public class SettableAnyProperty
*/
public SettableAnyProperty(BeanProperty property, AnnotatedMember setter, JavaType type,
+ KeyDeserializer keyDeser,
JsonDeserializer<Object> valueDeser, TypeDeserializer typeDeser)
{
_property = property;
@@ -57,9 +63,17 @@ public class SettableAnyProperty
_type = type;
_valueDeserializer = valueDeser;
_valueTypeDeserializer = typeDeser;
+ _keyDeserializer = keyDeser;
_setterIsField = setter instanceof AnnotatedField;
}
+ @Deprecated // since 2.9
+ public SettableAnyProperty(BeanProperty property, AnnotatedMember setter, JavaType type,
+ JsonDeserializer<Object> valueDeser, TypeDeserializer typeDeser)
+ {
+ this(property, setter, type, null, valueDeser, typeDeser);
+ }
+
/**
* Constructor used for JDK Serialization when reading persisted object
*/
@@ -70,12 +84,13 @@ public class SettableAnyProperty
_type = src._type;
_valueDeserializer = src._valueDeserializer;
_valueTypeDeserializer = src._valueTypeDeserializer;
+ _keyDeserializer = src._keyDeserializer;
_setterIsField = src._setterIsField;
}
public SettableAnyProperty withValueDeserializer(JsonDeserializer<Object> deser) {
return new SettableAnyProperty(_property, _setter, _type,
- deser, _valueTypeDeserializer);
+ _keyDeserializer, deser, _valueTypeDeserializer);
}
public void fixAccess(DeserializationConfig config) {
@@ -127,7 +142,9 @@ public class SettableAnyProperty
throws IOException
{
try {
- set(instance, propName, deserialize(p, ctxt));
+ Object key = (_keyDeserializer == null) ? propName
+ : _keyDeserializer.deserializeKey(propName, ctxt);
+ set(instance, key, deserialize(p, ctxt));
} catch (UnresolvedForwardReference reference) {
if (!(_valueDeserializer.getObjectIdReader() != null)) {
throw JsonMappingException.from(p, "Unresolved forward reference but no identity info.", reference);
@@ -151,7 +168,7 @@ public class SettableAnyProperty
}
@SuppressWarnings("unchecked")
- public void set(Object instance, String propName, Object value) throws IOException
+ public void set(Object instance, Object propName, Object value) throws IOException
{
try {
// if annotation in the field (only map is supported now)
@@ -187,7 +204,7 @@ public class SettableAnyProperty
* @param propName Name of property (from Json input) to set
* @param value Value of the property
*/
- protected void _throwAsIOE(Exception e, String propName, Object value)
+ protected void _throwAsIOE(Exception e, Object propName, Object value)
throws IOException
{
if (e instanceof IllegalArgumentException) {