diff --git a/gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java b/gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java index 344590e7..8a694af1 100644 --- a/gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java +++ b/gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java @@ -16,15 +16,13 @@ package com.google.gson.internal; -import com.google.gson.InstanceCreator; -import com.google.gson.reflect.TypeToken; - import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; +import java.util.EnumSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; @@ -36,6 +34,10 @@ import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; +import com.google.gson.InstanceCreator; +import com.google.gson.JsonIOException; +import com.google.gson.reflect.TypeToken; + /** * Returns a function that can construct an instance of a requested type. */ @@ -124,7 +126,7 @@ public final class ConstructorConstructor { */ @SuppressWarnings("unchecked") // use runtime checks to guarantee that 'T' is what it is private ObjectConstructor newDefaultImplementationConstructor( - Type type, Class rawType) { + final Type type, Class rawType) { if (Collection.class.isAssignableFrom(rawType)) { if (SortedSet.class.isAssignableFrom(rawType)) { return new ObjectConstructor() { @@ -132,6 +134,22 @@ public final class ConstructorConstructor { return (T) new TreeSet(); } }; + } else if (EnumSet.class.isAssignableFrom(rawType)) { + return new ObjectConstructor() { + @SuppressWarnings("rawtypes") + public T construct() { + if (type instanceof ParameterizedType) { + Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0]; + if (elementType instanceof Class) { + return (T) EnumSet.noneOf((Class)elementType); + } else { + throw new JsonIOException("Invalid EnumSet type: " + type.toString()); + } + } else { + throw new JsonIOException("Invalid EnumSet type: " + type.toString()); + } + } + }; } else if (Set.class.isAssignableFrom(rawType)) { return new ObjectConstructor() { public T construct() { 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 60136523..38897a75 100644 --- a/gson/src/test/java/com/google/gson/functional/EnumTest.java +++ b/gson/src/test/java/com/google/gson/functional/EnumTest.java @@ -16,6 +16,14 @@ package com.google.gson.functional; +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; + import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializationContext; @@ -28,12 +36,6 @@ import com.google.gson.JsonSerializer; import com.google.gson.annotations.SerializedName; import com.google.gson.common.MoreAsserts; import com.google.gson.reflect.TypeToken; -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. @@ -147,6 +149,17 @@ public class EnumTest extends TestCase { assertEquals(Gender.MALE, gson.fromJson("\"boy\"", Gender.class)); assertEquals("\"boy\"", gson.toJson(Gender.MALE, Gender.class)); } + enum Color { red, blue, green, yellow, thistle } + + public void testEnumSet() { + EnumSet foo = EnumSet.of(Roshambo.ROCK, Roshambo.PAPER); + String json = gson.toJson(foo); + Type type = new TypeToken>() {}.getType(); + EnumSet bar = gson.fromJson(json, type); + assertTrue(bar.contains(Roshambo.ROCK)); + assertTrue(bar.contains(Roshambo.PAPER)); + assertFalse(bar.contains(Roshambo.SCISSORS)); + } public enum Roshambo { ROCK {