package org.codehaus.jackson.map.deser;
import java.io.IOException;
import java.util.*;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.map.DeserializationContext;
/**
*
* <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
*/
public final class EnumMapDeserializer
extends StdDeserializer<EnumMap<?,?>>
{
final EnumResolver _enumResolver;
final JsonDeserializer<Object> _valueDeserializer;
public EnumMapDeserializer(EnumResolver enumRes, JsonDeserializer<Object> valueDes)
{
super(EnumMap.class);
_enumResolver = enumRes;
_valueDeserializer = valueDes;
}
@SuppressWarnings("unchecked")
public EnumMap<?,?> deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// Ok: must point to START_OBJECT
if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
throw ctxt.mappingException(EnumMap.class);
}
EnumMap result = constructMap();
while ((jp.nextToken()) != JsonToken.END_OBJECT) {
String fieldName = jp.getCurrentName();
Enum<?> key = _enumResolver.findEnum(fieldName);
if (key == null) {
throw ctxt.weirdStringException(_enumResolver.getEnumClass(), "value not one of declared Enum instance names");
}
// And then the value...
JsonToken t = jp.nextToken();
/* note: MUST check for nulls separately: deserializers will
* not handle them (and maybe fail or return bogus data)
*/
Object value = (t == JsonToken.VALUE_NULL) ?
null : _valueDeserializer.deserialize(jp, ctxt);
result.put(key, value);
}
return result;
}
@SuppressWarnings("unchecked")
private EnumMap constructMap()
{
Class<Enum<?>> enumCls = _enumResolver.getEnumClass();
return new EnumMap(enumCls);
}
}