Skip to content

Commit

Permalink
Improvement for #523, wrt EnumMapDeserializer, but only for 2.5 (due …
Browse files Browse the repository at this point in the history
…to minor refactorings).
  • Loading branch information
cowtowncoder committed Aug 20, 2014
1 parent b900afb commit 1f06e8f
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package com.fasterxml.jackson.databind.deser.std;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;

/**
Expand Down Expand Up @@ -57,4 +61,30 @@ public SettableBeanProperty findBackReference(String refName) {
* Accesor for deserializer use for deserializing content values.
*/
public abstract JsonDeserializer<Object> getContentDeserializer();

/*
/**********************************************************
/* Shared methods for sub-classes
/**********************************************************
*/

/**
* Helper method called by various Map(-like) deserializers.
*/
protected void wrapAndThrow(Throwable t, Object ref, String key) throws IOException
{
// to handle StackOverflow:
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors and "plain" IOExceptions to be passed as is
if (t instanceof Error) {
throw (Error) t;
}
// ... except for mapping exceptions
if (t instanceof IOException && !(t instanceof JsonMappingException)) {
throw (IOException) t;
}
throw JsonMappingException.wrapWithPath(t, ref, key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,19 @@
import java.util.*;

import com.fasterxml.jackson.core.*;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;

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

public EnumMapDeserializer(JavaType mapType, JsonDeserializer<?> keyDeserializer, JsonDeserializer<?> valueDeser, TypeDeserializer valueTypeDeser)
{
super(EnumMap.class);
super(mapType);
_mapType = mapType;
_enumClass = mapType.getKeyType().getRawClass();
_keyDeserializer = (JsonDeserializer<Enum<?>>) keyDeserializer;
Expand Down Expand Up @@ -96,7 +92,23 @@ public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanPro
*/
@Override
public boolean isCachable() { return true; }


/*
/**********************************************************
/* ContainerDeserializerBase API
/**********************************************************
*/

@Override
public JavaType getContentType() {
return _mapType.getContentType();
}

@Override
public JsonDeserializer<Object> getContentDeserializer() {
return _valueDeserializer;
}

/*
/**********************************************************
/* Actual deserialization
Expand All @@ -115,6 +127,8 @@ public EnumMap<?,?> deserialize(JsonParser jp, DeserializationContext ctxt) thro
final TypeDeserializer typeDeser = _valueTypeDeserializer;

while ((jp.nextToken()) != JsonToken.END_OBJECT) {
String keyName = jp.getCurrentName(); // just for error message
// but we need to let key deserializer handle it separately, nonetheless
Enum<?> key = _keyDeserializer.deserialize(jp, ctxt);
if (key == null) {
if (!ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) {
Expand All @@ -127,7 +141,7 @@ public EnumMap<?,?> deserialize(JsonParser jp, DeserializationContext ctxt) thro
throw ctxt.weirdStringException(value, _enumClass, "value not one of declared Enum instance names");
}
/* 24-Mar-2012, tatu: Null won't work as a key anyway, so let's
* just skip the entry then. But we must skip the value then.
* just skip the entry then. But we must skip the value as well, if so.
*/
jp.nextToken();
jp.skipChildren();
Expand All @@ -139,13 +153,18 @@ public EnumMap<?,?> deserialize(JsonParser jp, DeserializationContext ctxt) thro
* not handle them (and maybe fail or return bogus data)
*/
Object value;

if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue();
} else if (typeDeser == null) {
value = valueDes.deserialize(jp, ctxt);
} else {
value = valueDes.deserializeWithType(jp, ctxt, typeDeser);

try {
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue();
} else if (typeDeser == null) {
value = valueDes.deserialize(jp, ctxt);
} else {
value = valueDes.deserializeWithType(jp, ctxt, typeDeser);
}
} catch (Exception e) {
wrapAndThrow(e, result, keyName);
return null;
}
result.put(key, value);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.fasterxml.jackson.databind.deser.std;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

import com.fasterxml.jackson.core.*;
Expand Down Expand Up @@ -259,7 +258,7 @@ public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
}
return withResolved(kd, vtd, vd, ignored);
}

/*
/**********************************************************
/* ContainerDeserializerBase API
Expand Down Expand Up @@ -538,24 +537,6 @@ public Map<Object,Object> _deserializeUsingCreator(JsonParser jp, Deserializatio
protected void wrapAndThrow(Throwable t, Object ref) throws IOException {
wrapAndThrow(t, ref, null);
}

// note: copied from BeanDeserializer; should try to share somehow...
protected void wrapAndThrow(Throwable t, Object ref, String key) throws IOException
{
// to handle StackOverflow:
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors and "plain" IOExceptions to be passed as is
if (t instanceof Error) {
throw (Error) t;
}
// ... except for mapping exceptions
if (t instanceof IOException && !(t instanceof JsonMappingException)) {
throw (IOException) t;
}
throw JsonMappingException.wrapWithPath(t, ref, key);
}

private void handleUnresolvedReference(JsonParser jp, MapReferringAccumulator accumulator, Object key,
UnresolvedForwardReference reference)
Expand Down

0 comments on commit 1f06e8f

Please sign in to comment.