Skip to content

Commit 1f06e8f

Browse files
committed
Improvement for #523, wrt EnumMapDeserializer, but only for 2.5 (due to minor refactorings).
1 parent b900afb commit 1f06e8f

File tree

3 files changed

+65
-35
lines changed

3 files changed

+65
-35
lines changed

src/main/java/com/fasterxml/jackson/databind/deser/std/ContainerDeserializerBase.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package com.fasterxml.jackson.databind.deser.std;
22

3+
import java.io.IOException;
4+
import java.lang.reflect.InvocationTargetException;
5+
36
import com.fasterxml.jackson.databind.JavaType;
47
import com.fasterxml.jackson.databind.JsonDeserializer;
8+
import com.fasterxml.jackson.databind.JsonMappingException;
59
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
610

711
/**
@@ -57,4 +61,30 @@ public SettableBeanProperty findBackReference(String refName) {
5761
* Accesor for deserializer use for deserializing content values.
5862
*/
5963
public abstract JsonDeserializer<Object> getContentDeserializer();
64+
65+
/*
66+
/**********************************************************
67+
/* Shared methods for sub-classes
68+
/**********************************************************
69+
*/
70+
71+
/**
72+
* Helper method called by various Map(-like) deserializers.
73+
*/
74+
protected void wrapAndThrow(Throwable t, Object ref, String key) throws IOException
75+
{
76+
// to handle StackOverflow:
77+
while (t instanceof InvocationTargetException && t.getCause() != null) {
78+
t = t.getCause();
79+
}
80+
// Errors and "plain" IOExceptions to be passed as is
81+
if (t instanceof Error) {
82+
throw (Error) t;
83+
}
84+
// ... except for mapping exceptions
85+
if (t instanceof IOException && !(t instanceof JsonMappingException)) {
86+
throw (IOException) t;
87+
}
88+
throw JsonMappingException.wrapWithPath(t, ref, key);
89+
}
6090
}

src/main/java/com/fasterxml/jackson/databind/deser/std/EnumMapDeserializer.java

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,19 @@
44
import java.util.*;
55

66
import com.fasterxml.jackson.core.*;
7-
87
import com.fasterxml.jackson.databind.*;
98
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
10-
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
119
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
1210

1311
/**
1412
* Deserializer for {@link EnumMap} values.
1513
* <p>
1614
* Note: casting within this class is all messed up -- just could not figure out a way
1715
* to properly deal with recursive definition of "EnumMap<K extends Enum<K>, V>
18-
*
19-
* @author tsaloranta
2016
*/
2117
@SuppressWarnings({ "unchecked", "rawtypes" })
2218
public class EnumMapDeserializer
23-
extends StdDeserializer<EnumMap<?,?>>
19+
extends ContainerDeserializerBase<EnumMap<?,?>>
2420
implements ContextualDeserializer
2521
{
2622
private static final long serialVersionUID = 4564890642370311174L;
@@ -47,7 +43,7 @@ public class EnumMapDeserializer
4743

4844
public EnumMapDeserializer(JavaType mapType, JsonDeserializer<?> keyDeserializer, JsonDeserializer<?> valueDeser, TypeDeserializer valueTypeDeser)
4945
{
50-
super(EnumMap.class);
46+
super(mapType);
5147
_mapType = mapType;
5248
_enumClass = mapType.getKeyType().getRawClass();
5349
_keyDeserializer = (JsonDeserializer<Enum<?>>) keyDeserializer;
@@ -96,7 +92,23 @@ public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanPro
9692
*/
9793
@Override
9894
public boolean isCachable() { return true; }
99-
95+
96+
/*
97+
/**********************************************************
98+
/* ContainerDeserializerBase API
99+
/**********************************************************
100+
*/
101+
102+
@Override
103+
public JavaType getContentType() {
104+
return _mapType.getContentType();
105+
}
106+
107+
@Override
108+
public JsonDeserializer<Object> getContentDeserializer() {
109+
return _valueDeserializer;
110+
}
111+
100112
/*
101113
/**********************************************************
102114
/* Actual deserialization
@@ -115,6 +127,8 @@ public EnumMap<?,?> deserialize(JsonParser jp, DeserializationContext ctxt) thro
115127
final TypeDeserializer typeDeser = _valueTypeDeserializer;
116128

117129
while ((jp.nextToken()) != JsonToken.END_OBJECT) {
130+
String keyName = jp.getCurrentName(); // just for error message
131+
// but we need to let key deserializer handle it separately, nonetheless
118132
Enum<?> key = _keyDeserializer.deserialize(jp, ctxt);
119133
if (key == null) {
120134
if (!ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) {
@@ -127,7 +141,7 @@ public EnumMap<?,?> deserialize(JsonParser jp, DeserializationContext ctxt) thro
127141
throw ctxt.weirdStringException(value, _enumClass, "value not one of declared Enum instance names");
128142
}
129143
/* 24-Mar-2012, tatu: Null won't work as a key anyway, so let's
130-
* just skip the entry then. But we must skip the value then.
144+
* just skip the entry then. But we must skip the value as well, if so.
131145
*/
132146
jp.nextToken();
133147
jp.skipChildren();
@@ -139,13 +153,18 @@ public EnumMap<?,?> deserialize(JsonParser jp, DeserializationContext ctxt) thro
139153
* not handle them (and maybe fail or return bogus data)
140154
*/
141155
Object value;
142-
143-
if (t == JsonToken.VALUE_NULL) {
144-
value = valueDes.getNullValue();
145-
} else if (typeDeser == null) {
146-
value = valueDes.deserialize(jp, ctxt);
147-
} else {
148-
value = valueDes.deserializeWithType(jp, ctxt, typeDeser);
156+
157+
try {
158+
if (t == JsonToken.VALUE_NULL) {
159+
value = valueDes.getNullValue();
160+
} else if (typeDeser == null) {
161+
value = valueDes.deserialize(jp, ctxt);
162+
} else {
163+
value = valueDes.deserializeWithType(jp, ctxt, typeDeser);
164+
}
165+
} catch (Exception e) {
166+
wrapAndThrow(e, result, keyName);
167+
return null;
149168
}
150169
result.put(key, value);
151170
}

src/main/java/com/fasterxml/jackson/databind/deser/std/MapDeserializer.java

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.fasterxml.jackson.databind.deser.std;
22

33
import java.io.IOException;
4-
import java.lang.reflect.InvocationTargetException;
54
import java.util.*;
65

76
import com.fasterxml.jackson.core.*;
@@ -259,7 +258,7 @@ public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
259258
}
260259
return withResolved(kd, vtd, vd, ignored);
261260
}
262-
261+
263262
/*
264263
/**********************************************************
265264
/* ContainerDeserializerBase API
@@ -538,24 +537,6 @@ public Map<Object,Object> _deserializeUsingCreator(JsonParser jp, Deserializatio
538537
protected void wrapAndThrow(Throwable t, Object ref) throws IOException {
539538
wrapAndThrow(t, ref, null);
540539
}
541-
542-
// note: copied from BeanDeserializer; should try to share somehow...
543-
protected void wrapAndThrow(Throwable t, Object ref, String key) throws IOException
544-
{
545-
// to handle StackOverflow:
546-
while (t instanceof InvocationTargetException && t.getCause() != null) {
547-
t = t.getCause();
548-
}
549-
// Errors and "plain" IOExceptions to be passed as is
550-
if (t instanceof Error) {
551-
throw (Error) t;
552-
}
553-
// ... except for mapping exceptions
554-
if (t instanceof IOException && !(t instanceof JsonMappingException)) {
555-
throw (IOException) t;
556-
}
557-
throw JsonMappingException.wrapWithPath(t, ref, key);
558-
}
559540

560541
private void handleUnresolvedReference(JsonParser jp, MapReferringAccumulator accumulator, Object key,
561542
UnresolvedForwardReference reference)

0 commit comments

Comments
 (0)