diff --git a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java index 4347534c..c90aaa7d 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java +++ b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java @@ -25,6 +25,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSyntaxException; import com.google.gson.TypeAdapter; +import com.google.gson.annotations.SerializedName; import com.google.gson.internal.LazilyParsedNumber; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; @@ -40,6 +41,7 @@ import java.util.BitSet; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; +import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.StringTokenizer; @@ -644,21 +646,34 @@ public final class TypeAdapters { = newFactory(JsonElement.class, JSON_ELEMENT); private static final class EnumTypeAdapter> extends TypeAdapter { - private final Class classOfT; + private final Map nameToConstant = new HashMap(); + private final Map constantToName = new HashMap(); public EnumTypeAdapter(Class classOfT) { - this.classOfT = classOfT; + try { + for (T constant : classOfT.getEnumConstants()) { + String name = constant.name(); + SerializedName annotation = classOfT.getField(name).getAnnotation(SerializedName.class); + if (annotation != null) { + name = annotation.value(); + } + nameToConstant.put(name, constant); + constantToName.put(constant, name); + } + } catch (NoSuchFieldException e) { + throw new AssertionError(); + } } public T read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } - return Enum.valueOf(classOfT, in.nextString()); + return nameToConstant.get(in.nextString()); } public void write(JsonWriter out, T value) throws IOException { - out.value(value == null ? null : value.name()); + out.value(value == null ? null : constantToName.get(value)); } } diff --git a/gson/src/test/java/com/google/gson/functional/EnumTest.java b/gson/src/test/java/com/google/gson/functional/EnumTest.java index f73665a0..60136523 100644 --- a/gson/src/test/java/com/google/gson/functional/EnumTest.java +++ b/gson/src/test/java/com/google/gson/functional/EnumTest.java @@ -25,16 +25,15 @@ import com.google.gson.JsonParseException; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; +import com.google.gson.annotations.SerializedName; import com.google.gson.common.MoreAsserts; import com.google.gson.reflect.TypeToken; - -import junit.framework.TestCase; - import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; import java.util.Set; +import junit.framework.TestCase; /** * Functional tests for Java 5.0 enums. @@ -144,6 +143,11 @@ public class EnumTest extends TestCase { MoreAsserts.assertContains(actualJsonList, Roshambo.PAPER); } + public void testEnumCaseMapping() { + assertEquals(Gender.MALE, gson.fromJson("\"boy\"", Gender.class)); + assertEquals("\"boy\"", gson.toJson(Gender.MALE, Gender.class)); + } + public enum Roshambo { ROCK { @Override Roshambo defeats() { @@ -175,4 +179,12 @@ public class EnumTest extends TestCase { return Roshambo.valueOf(json.getAsString().substring(3)); } } + + public enum Gender { + @SerializedName("boy") + MALE, + + @SerializedName("girl") + FEMALE + } }