Fix a bunch of preserve-type issues:

- Issue 205
- Issue 294
- Issue 318
This commit is contained in:
Joel Leitch 2011-04-20 22:27:51 +00:00
parent cf3615e38c
commit f291c4d33e
7 changed files with 38 additions and 8 deletions

View File

@ -677,7 +677,8 @@ final class DefaultTypeAdapters {
} else { } else {
Type childType = (childGenericType == null || childGenericType == Object.class) Type childType = (childGenericType == null || childGenericType == Object.class)
? child.getClass() : childGenericType; ? child.getClass() : childGenericType;
JsonElement element = context.serialize(child, childType); JsonSerializationContextDefault contextImpl = (JsonSerializationContextDefault) context;
JsonElement element = contextImpl.serialize(child, childType, false);
array.add(element); array.add(element);
} }
} }

View File

@ -16,7 +16,6 @@
package com.google.gson; package com.google.gson;
import java.lang.reflect.Type; import java.lang.reflect.Type;
/** /**
@ -59,7 +58,8 @@ final class JsonSerializationContextDefault implements JsonSerializationContext
} }
JsonSerializationVisitor visitor = new JsonSerializationVisitor( JsonSerializationVisitor visitor = new JsonSerializationVisitor(
objectNavigator, fieldNamingPolicy, serializeNulls, serializers, this, ancestors); objectNavigator, fieldNamingPolicy, serializeNulls, serializers, this, ancestors);
objectNavigator.accept(new ObjectTypePair(src, typeOfSrc, preserveType), visitor); ObjectTypePair objTypePair = new ObjectTypePair(src, typeOfSrc, preserveType);
objectNavigator.accept(objTypePair, visitor);
return visitor.getJsonElement(); return visitor.getJsonElement();
} }
} }

View File

@ -100,6 +100,7 @@ final class ObjectNavigator {
} }
boolean visitedWithCustomHandler = visitor.visitUsingCustomHandler(objTypePair); boolean visitedWithCustomHandler = visitor.visitUsingCustomHandler(objTypePair);
if (!visitedWithCustomHandler) { if (!visitedWithCustomHandler) {
objTypePair = objTypePair.toMoreSpecificType();
Object obj = objTypePair.getObject(); Object obj = objTypePair.getObject();
Object objectToVisit = (obj == null) ? visitor.getTarget() : obj; Object objectToVisit = (obj == null) ? visitor.getTarget() : obj;
if (objectToVisit == null) { if (objectToVisit == null) {
@ -108,7 +109,7 @@ final class ObjectNavigator {
objTypePair.setObject(objectToVisit); objTypePair.setObject(objectToVisit);
visitor.start(objTypePair); visitor.start(objTypePair);
try { try {
if ($Gson$Types.isArray(objTypePair.type)) { if ($Gson$Types.isArray(objTypePair.getMoreSpecificType())) {
visitor.visitArray(objectToVisit, objTypePair.type); visitor.visitArray(objectToVisit, objTypePair.type);
} else if (objTypePair.type == Object.class && isPrimitiveOrString(objectToVisit)) { } else if (objTypePair.type == Object.class && isPrimitiveOrString(objectToVisit)) {
// TODO(Joel): this is only used for deserialization of "primitives" // TODO(Joel): this is only used for deserialization of "primitives"

View File

@ -75,7 +75,7 @@ final class ObjectTypePair {
if (actualType == type) { if (actualType == type) {
return this; return this;
} }
return new ObjectTypePair(obj, actualType, preserveType); return new ObjectTypePair(obj, actualType, true);
} }
Type getMoreSpecificType() { Type getMoreSpecificType() {

View File

@ -274,6 +274,14 @@ public class ArrayTest extends TestCase {
assertEquals("[[1,2]]", gson.toJson(array)); assertEquals("[[1,2]]", gson.toJson(array));
} }
/**
* Regression test for Issue 205
*/
public void testMixingTypesInObjectArraySerialization() {
Object[] array = new Object[] { 1, 2, new Object[] { "one", "two" } };
assertEquals("[1,2,[\"one\",\"two\"]]", gson.toJson(array));
}
/** /**
* Regression tests for Issue 272 * Regression tests for Issue 272
*/ */

View File

@ -421,6 +421,22 @@ public class MapTest extends TestCase {
assertEquals(expected, json); assertEquals(expected, json);
} }
public void testGeneralMapField() throws Exception {
MapWithGeneralMapParameters map = new MapWithGeneralMapParameters();
map.map.put("string", "testString");
map.map.put("stringArray", new String[] { "one", "two" });
map.map.put("objectArray", new Object[] { 1, 2L, "three" });
String expected = "{\"map\":{\"string\":\"testString\",\"stringArray\":"
+ "[\"one\",\"two\"],\"objectArray\":[1,2,\"three\"]}}";
assertEquals(expected, gson.toJson(map));
gson = new GsonBuilder()
.enableComplexMapKeySerialization()
.create();
assertEquals(expected, gson.toJson(map));
}
static final class MapClass { static final class MapClass {
private final Map<String, TestTypes.Base> bases = new HashMap<String, TestTypes.Base>(); private final Map<String, TestTypes.Base> bases = new HashMap<String, TestTypes.Base>();
private final Map<String, TestTypes.Sub> subs = new HashMap<String, TestTypes.Sub>(); private final Map<String, TestTypes.Sub> subs = new HashMap<String, TestTypes.Sub>();
@ -433,4 +449,8 @@ public class MapTest extends TestCase {
subs.put(name, value); subs.put(name, value);
} }
} }
static final class MapWithGeneralMapParameters {
final Map<String, Object> map = new LinkedHashMap();
}
} }

View File

@ -48,14 +48,14 @@ public class MoreSpecificTypeSerializationTest extends TestCase {
assertTrue(json.contains("\"s\":2")); assertTrue(json.contains("\"s\":2"));
} }
public void disabled_testListOfSubclassFields() { public void testListOfSubclassFields() {
Collection<Base> list = new ArrayList<Base>(); Collection<Base> list = new ArrayList<Base>();
list.add(new Base(1)); list.add(new Base(1));
list.add(new Sub(2, 3)); list.add(new Sub(2, 3));
ClassWithContainersOfBaseFields target = new ClassWithContainersOfBaseFields(list, null); ClassWithContainersOfBaseFields target = new ClassWithContainersOfBaseFields(list, null);
String json = gson.toJson(target); String json = gson.toJson(target);
assertTrue(json, json.contains("{\"b\":1}")); assertTrue(json, json.contains("{\"b\":1}"));
assertTrue(json, json.contains("{\"b\":2,\"s\":3}")); assertTrue(json, json.contains("{\"s\":3,\"b\":2}"));
} }
public void testMapOfSubclassFields() { public void testMapOfSubclassFields() {