From fede584b9811f35432a936af0c9441f4e05df80a Mon Sep 17 00:00:00 2001 From: Inderjeet Singh Date: Fri, 9 Sep 2011 06:23:17 +0000 Subject: [PATCH] Gson 2.0 converts JSON with type Object.class into something meaningful such as a Collection of primitives or Maps. Updated tests for the new behavior. Changed $Gson$Types.getCollectionElementType to handle wild-card sub-classes of collections and raw collections. --- .../com/google/gson/internal/$Gson$Types.java | 10 +++- .../gson/functional/CollectionTest.java | 51 +++++++++---------- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/gson/src/main/java/com/google/gson/internal/$Gson$Types.java b/gson/src/main/java/com/google/gson/internal/$Gson$Types.java index f03dc77f..9fc70ed6 100644 --- a/gson/src/main/java/com/google/gson/internal/$Gson$Types.java +++ b/gson/src/main/java/com/google/gson/internal/$Gson$Types.java @@ -18,6 +18,7 @@ package com.google.gson.internal; import static com.google.gson.internal.$Gson$Preconditions.checkArgument; import static com.google.gson.internal.$Gson$Preconditions.checkNotNull; + import java.io.Serializable; import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; @@ -297,7 +298,14 @@ public final class $Gson$Types { */ public static Type getCollectionElementType(Type context, Class contextRawType) { Type collectionType = getSupertype(context, contextRawType, Collection.class); - return ((ParameterizedType) collectionType).getActualTypeArguments()[0]; + + if (collectionType instanceof WildcardType) { + collectionType = ((WildcardType)collectionType).getUpperBounds()[0]; + } + if (collectionType instanceof ParameterizedType) { + return ((ParameterizedType) collectionType).getActualTypeArguments()[0]; + } + return Object.class; } /** diff --git a/gson/src/test/java/com/google/gson/functional/CollectionTest.java b/gson/src/test/java/com/google/gson/functional/CollectionTest.java index 2a068735..97fdf5ee 100644 --- a/gson/src/test/java/com/google/gson/functional/CollectionTest.java +++ b/gson/src/test/java/com/google/gson/functional/CollectionTest.java @@ -16,14 +16,6 @@ package com.google.gson.functional; -import com.google.gson.Gson; -import com.google.gson.JsonParseException; -import com.google.gson.common.MoreAsserts; -import com.google.gson.common.TestTypes.BagOfPrimitives; -import com.google.gson.reflect.TypeToken; - -import junit.framework.TestCase; - import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; @@ -32,9 +24,18 @@ import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Queue; import java.util.Set; +import junit.framework.TestCase; + +import com.google.gson.Gson; +import com.google.gson.JsonParseException; +import com.google.gson.common.MoreAsserts; +import com.google.gson.common.TestTypes.BagOfPrimitives; +import com.google.gson.reflect.TypeToken; + /** * Functional tests for Json serialization and deserialization of collections. * @@ -210,30 +211,28 @@ public class CollectionTest extends TestCase { public void testRawCollectionDeserializationNotAlllowed() { String json = "[0,1,2,3,4,5,6,7,8,9]"; - try { - gson.fromJson(json, Collection.class); - fail("Can not deserialize a non-genericized collection."); - } catch (JsonParseException expected) { } + Collection integers = gson.fromJson(json, Collection.class); + // JsonReader converts numbers to double by default so we need a floating point comparison + assertEquals(Arrays.asList(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0), integers); json = "[\"Hello\", \"World\"]"; - try { - gson.fromJson(json, Collection.class); - fail("Can not deserialize a non-genericized collection."); - } catch (JsonParseException expected) { } + Collection strings = gson.fromJson(json, Collection.class); + assertTrue(strings.contains("Hello")); + assertTrue(strings.contains("World")); } @SuppressWarnings("unchecked") public void testRawCollectionOfBagOfPrimitivesNotAllowed() { - try { - BagOfPrimitives bag = new BagOfPrimitives(10, 20, false, "stringValue"); - String json = '[' + bag.getExpectedJson() + ',' + bag.getExpectedJson() + ']'; - Collection target = gson.fromJson(json, Collection.class); - assertEquals(2, target.size()); - for (BagOfPrimitives bag1 : (Collection) target) { - assertEquals(bag.getExpectedJson(), bag1.getExpectedJson()); - } - fail("Raw collection of objects should not work"); - } catch (JsonParseException expected) { + BagOfPrimitives bag = new BagOfPrimitives(10, 20, false, "stringValue"); + String json = '[' + bag.getExpectedJson() + ',' + bag.getExpectedJson() + ']'; + Collection target = gson.fromJson(json, Collection.class); + assertEquals(2, target.size()); + for (Object bag1 : target) { + // Gson 2.0 converts raw objects into maps + Map values = (Map) bag1; + assertTrue(values.containsValue(10.0)); + assertTrue(values.containsValue(20.0)); + assertTrue(values.containsValue("stringValue")); } }