Support EnumMap deserialization (#2071)
This commit is contained in:
parent
e2e851c9bc
commit
565b7a198e
@ -23,6 +23,7 @@ import java.lang.reflect.Type;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
@ -199,7 +200,26 @@ public final class ConstructorConstructor {
|
||||
}
|
||||
|
||||
if (Map.class.isAssignableFrom(rawType)) {
|
||||
if (ConcurrentNavigableMap.class.isAssignableFrom(rawType)) {
|
||||
// Only support creation of EnumMap, but not of custom subtypes; for them type parameters
|
||||
// and constructor parameter might have completely different meaning
|
||||
if (rawType == EnumMap.class) {
|
||||
return new ObjectConstructor<T>() {
|
||||
@Override public T construct() {
|
||||
if (type instanceof ParameterizedType) {
|
||||
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
if (elementType instanceof Class) {
|
||||
@SuppressWarnings("rawtypes")
|
||||
T map = (T) new EnumMap((Class) elementType);
|
||||
return map;
|
||||
} else {
|
||||
throw new JsonIOException("Invalid EnumMap type: " + type.toString());
|
||||
}
|
||||
} else {
|
||||
throw new JsonIOException("Invalid EnumMap type: " + type.toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
} else if (ConcurrentNavigableMap.class.isAssignableFrom(rawType)) {
|
||||
return new ObjectConstructor<T>() {
|
||||
@Override public T construct() {
|
||||
return (T) new ConcurrentSkipListMap<Object, Object>();
|
||||
|
@ -31,7 +31,10 @@ import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import junit.framework.TestCase;
|
||||
/**
|
||||
@ -150,6 +153,8 @@ public class EnumTest extends TestCase {
|
||||
public void testEnumSet() {
|
||||
EnumSet<Roshambo> foo = EnumSet.of(Roshambo.ROCK, Roshambo.PAPER);
|
||||
String json = gson.toJson(foo);
|
||||
assertEquals("[\"ROCK\",\"PAPER\"]", json);
|
||||
|
||||
Type type = new TypeToken<EnumSet<Roshambo>>() {}.getType();
|
||||
EnumSet<Roshambo> bar = gson.fromJson(json, type);
|
||||
assertTrue(bar.contains(Roshambo.ROCK));
|
||||
@ -157,6 +162,18 @@ public class EnumTest extends TestCase {
|
||||
assertFalse(bar.contains(Roshambo.SCISSORS));
|
||||
}
|
||||
|
||||
public void testEnumMap() throws Exception {
|
||||
EnumMap<MyEnum, String> map = new EnumMap<MyEnum, String>(MyEnum.class);
|
||||
map.put(MyEnum.VALUE1, "test");
|
||||
String json = gson.toJson(map);
|
||||
assertEquals("{\"VALUE1\":\"test\"}", json);
|
||||
|
||||
Type type = new TypeToken<EnumMap<MyEnum, String>>() {}.getType();
|
||||
EnumMap<?, ?> actualMap = gson.fromJson("{\"VALUE1\":\"test\"}", type);
|
||||
Map<?, ?> expectedMap = Collections.singletonMap(MyEnum.VALUE1, "test");
|
||||
assertEquals(expectedMap, actualMap);
|
||||
}
|
||||
|
||||
public enum Roshambo {
|
||||
ROCK {
|
||||
@Override Roshambo defeats() {
|
||||
|
Loading…
Reference in New Issue
Block a user