From 62675b7f46e805fe15a04a7b8b252da6dac00c15 Mon Sep 17 00:00:00 2001 From: Inderjeet Singh Date: Fri, 1 Jul 2011 21:29:20 +0000 Subject: [PATCH] Added serializeDefault and deserializeDefault methods in contexts that only invoke system type adapters on the top-level object. With this, the RuntimeTypeAdapterTest passes. --- .../gson/typeadapters/RuntimeTypeAdapter.java | 4 +- .../typeadapters/RuntimeTypeAdapterTest.java | 2 +- .../com/google/gson/BaseMapTypeAdapter.java | 2 +- .../com/google/gson/DefaultTypeAdapters.java | 2 +- .../gson/JsonDeserializationContext.java | 36 ++++++--- .../gson/JsonDeserializationVisitor.java | 2 +- .../JsonObjectDeserializationVisitor.java | 2 +- .../google/gson/JsonSerializationContext.java | 12 ++- .../google/gson/JsonSerializationVisitor.java | 12 +-- .../google/gson/MappedObjectConstructor.java | 2 +- .../java/com/google/gson/ObjectTypePair.java | 16 ++-- .../gson/ParameterizedTypeHandlerMap.java | 25 +++--- .../com/google/gson/MemoryRefStackTest.java | 10 +-- .../gson/ParameterizedTypeHandlerMapTest.java | 26 +++---- .../SystemOnlyTypeAdaptersTest.java | 77 +++++++++++++++++++ 15 files changed, 170 insertions(+), 60 deletions(-) create mode 100644 gson/src/test/java/com/google/gson/functional/SystemOnlyTypeAdaptersTest.java diff --git a/extras/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapter.java b/extras/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapter.java index 8f399cc2..2a3a8ebf 100644 --- a/extras/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapter.java +++ b/extras/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapter.java @@ -184,7 +184,7 @@ public final class RuntimeTypeAdapter implements JsonSerializer, JsonDeser throw new JsonParseException("cannot serialize " + srcType.getName() + "; did you forget to register a subtype?"); } - JsonElement serialized = context.serialize(src, srcType); + JsonElement serialized = context.serializeDefault(src, srcType); final JsonObject jsonObject = serialized.getAsJsonObject(); if (jsonObject.has(typeFieldName)) { throw new JsonParseException("cannot serialize " + srcType.getName() @@ -212,7 +212,7 @@ public final class RuntimeTypeAdapter implements JsonSerializer, JsonDeser + label + "; did you forget to register a subtype?"); } @SuppressWarnings("unchecked") // registration requires that subtype extends T - T result = (T) context.deserialize(json, subtype); + T result = (T) context.deserializeDefault(json, subtype); return result; } } diff --git a/extras/src/test/java/com/google/gson/typeadapters/RuntimeTypeAdapterTest.java b/extras/src/test/java/com/google/gson/typeadapters/RuntimeTypeAdapterTest.java index a842ec55..eda46de8 100644 --- a/extras/src/test/java/com/google/gson/typeadapters/RuntimeTypeAdapterTest.java +++ b/extras/src/test/java/com/google/gson/typeadapters/RuntimeTypeAdapterTest.java @@ -50,7 +50,7 @@ public final class RuntimeTypeAdapterTest extends TestCase { assertEquals("{\"type\":\"BillingInstrument\",\"ownerName\":\"Jesse\"}", gson.toJson(original, BillingInstrument.class)); BillingInstrument deserialized = gson.fromJson( - "{type:'CreditCard',ownerName:'Jesse'}", BillingInstrument.class); + "{type:'BillingInstrument',ownerName:'Jesse'}", BillingInstrument.class); assertEquals("Jesse", deserialized.ownerName); } diff --git a/gson/src/main/java/com/google/gson/BaseMapTypeAdapter.java b/gson/src/main/java/com/google/gson/BaseMapTypeAdapter.java index 36eb40f1..71c87cbf 100644 --- a/gson/src/main/java/com/google/gson/BaseMapTypeAdapter.java +++ b/gson/src/main/java/com/google/gson/BaseMapTypeAdapter.java @@ -30,7 +30,7 @@ abstract class BaseMapTypeAdapter protected static final JsonElement serialize(JsonSerializationContext context, Object src, Type srcType) { - return context.serialize(src, srcType, false); + return context.serialize(src, srcType, false, false); } protected static final Map constructMapType( diff --git a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java index 1294ebf2..64673021 100644 --- a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java +++ b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java @@ -677,7 +677,7 @@ final class DefaultTypeAdapters { } else { Type childType = (childGenericType == null || childGenericType == Object.class) ? child.getClass() : childGenericType; - JsonElement element = context.serialize(child, childType, false); + JsonElement element = context.serialize(child, childType, false, false); array.add(element); } } diff --git a/gson/src/main/java/com/google/gson/JsonDeserializationContext.java b/gson/src/main/java/com/google/gson/JsonDeserializationContext.java index 111bc1cb..d5a98b22 100644 --- a/gson/src/main/java/com/google/gson/JsonDeserializationContext.java +++ b/gson/src/main/java/com/google/gson/JsonDeserializationContext.java @@ -55,29 +55,29 @@ public final class JsonDeserializationContext { private T fromJsonArray(Type arrayType, JsonArray jsonArray, - JsonDeserializationContext context) throws JsonParseException { + JsonDeserializationContext context, boolean systemOnly) throws JsonParseException { JsonArrayDeserializationVisitor visitor = new JsonArrayDeserializationVisitor( jsonArray, arrayType, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context); - objectNavigator.accept(new ObjectTypePair(null, arrayType, true), visitor); + objectNavigator.accept(new ObjectTypePair(null, arrayType, true, systemOnly), visitor); return visitor.getTarget(); } private T fromJsonObject(Type typeOfT, JsonObject jsonObject, - JsonDeserializationContext context) throws JsonParseException { + JsonDeserializationContext context, boolean systemOnly) throws JsonParseException { JsonObjectDeserializationVisitor visitor = new JsonObjectDeserializationVisitor( jsonObject, typeOfT, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context); - objectNavigator.accept(new ObjectTypePair(null, typeOfT, true), visitor); + objectNavigator.accept(new ObjectTypePair(null, typeOfT, true, systemOnly), visitor); return visitor.getTarget(); } @SuppressWarnings("unchecked") private T fromJsonPrimitive(Type typeOfT, JsonPrimitive json, - JsonDeserializationContext context) throws JsonParseException { + JsonDeserializationContext context, boolean systemOnly) throws JsonParseException { JsonObjectDeserializationVisitor visitor = new JsonObjectDeserializationVisitor( json, typeOfT, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context); - objectNavigator.accept(new ObjectTypePair(json.getAsObject(), typeOfT, true), visitor); + objectNavigator.accept(new ObjectTypePair(json.getAsObject(), typeOfT, true, systemOnly), visitor); Object target = visitor.getTarget(); return (T) target; } @@ -99,13 +99,31 @@ public final class JsonDeserializationContext { if (json == null || json.isJsonNull()) { return null; } else if (json.isJsonArray()) { - Object array = fromJsonArray(typeOfT, json.getAsJsonArray(), this); + Object array = fromJsonArray(typeOfT, json.getAsJsonArray(), this, false); return (T) array; } else if (json.isJsonObject()) { - Object object = fromJsonObject(typeOfT, json.getAsJsonObject(), this); + Object object = fromJsonObject(typeOfT, json.getAsJsonObject(), this, false); return (T) object; } else if (json.isJsonPrimitive()) { - Object primitive = fromJsonPrimitive(typeOfT, json.getAsJsonPrimitive(), this); + Object primitive = fromJsonPrimitive(typeOfT, json.getAsJsonPrimitive(), this, false); + return (T) primitive; + } else { + throw new JsonParseException("Failed parsing JSON source: " + json + " to Json"); + } + } + + @SuppressWarnings("unchecked") + public T deserializeDefault(JsonElement json, Type typeOfT) throws JsonParseException { + if (json == null || json.isJsonNull()) { + return null; + } else if (json.isJsonArray()) { + Object array = fromJsonArray(typeOfT, json.getAsJsonArray(), this, true); + return (T) array; + } else if (json.isJsonObject()) { + Object object = fromJsonObject(typeOfT, json.getAsJsonObject(), this, true); + return (T) object; + } else if (json.isJsonPrimitive()) { + Object primitive = fromJsonPrimitive(typeOfT, json.getAsJsonPrimitive(), this, true); return (T) primitive; } else { throw new JsonParseException("Failed parsing JSON source: " + json + " to Json"); diff --git a/gson/src/main/java/com/google/gson/JsonDeserializationVisitor.java b/gson/src/main/java/com/google/gson/JsonDeserializationVisitor.java index a928fcba..033bf20d 100644 --- a/gson/src/main/java/com/google/gson/JsonDeserializationVisitor.java +++ b/gson/src/main/java/com/google/gson/JsonDeserializationVisitor.java @@ -107,7 +107,7 @@ abstract class JsonDeserializationVisitor implements ObjectNavigator.Visitor } private Object visitChild(Type type, JsonDeserializationVisitor childVisitor) { - objectNavigator.accept(new ObjectTypePair(null, type, false), childVisitor); + objectNavigator.accept(new ObjectTypePair(null, type, false, false), childVisitor); // the underlying object may have changed during the construction phase // This happens primarily because of custom deserializers return childVisitor.getTarget(); diff --git a/gson/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java b/gson/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java index f1bf51c8..173dd8a6 100644 --- a/gson/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java +++ b/gson/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java @@ -109,7 +109,7 @@ final class JsonObjectDeserializationVisitor extends JsonDeserializationVisit } return true; } - ObjectTypePair objTypePair = new ObjectTypePair(null, declaredTypeOfField, false); + ObjectTypePair objTypePair = new ObjectTypePair(null, declaredTypeOfField, false, false); Pair, ObjectTypePair> pair = objTypePair.getMatchingHandler(deserializers); if (pair == null) { return false; diff --git a/gson/src/main/java/com/google/gson/JsonSerializationContext.java b/gson/src/main/java/com/google/gson/JsonSerializationContext.java index f0473af3..317da418 100644 --- a/gson/src/main/java/com/google/gson/JsonSerializationContext.java +++ b/gson/src/main/java/com/google/gson/JsonSerializationContext.java @@ -53,7 +53,7 @@ public final class JsonSerializationContext { if (src == null) { return JsonNull.INSTANCE; } - return serialize(src, src.getClass(), false); + return serialize(src, src.getClass(), false, false); } /** @@ -67,16 +67,20 @@ public final class JsonSerializationContext { * @return a tree of {@link JsonElement}s corresponding to the serialized form of {@code src}. */ public JsonElement serialize(Object src, Type typeOfSrc) { - return serialize(src, typeOfSrc, true); + return serialize(src, typeOfSrc, true, false); } - JsonElement serialize(Object src, Type typeOfSrc, boolean preserveType) { + public JsonElement serializeDefault(Object src, Type typeOfSrc) { + return serialize(src, typeOfSrc, true, true); + } + + JsonElement serialize(Object src, Type typeOfSrc, boolean preserveType, boolean defaultOnly) { if (src == null) { return JsonNull.INSTANCE; } JsonSerializationVisitor visitor = new JsonSerializationVisitor( objectNavigator, fieldNamingPolicy, serializeNulls, serializers, this, ancestors); - ObjectTypePair objTypePair = new ObjectTypePair(src, typeOfSrc, preserveType); + ObjectTypePair objTypePair = new ObjectTypePair(src, typeOfSrc, preserveType, defaultOnly); objectNavigator.accept(objTypePair, visitor); return visitor.getJsonElement(); } diff --git a/gson/src/main/java/com/google/gson/JsonSerializationVisitor.java b/gson/src/main/java/com/google/gson/JsonSerializationVisitor.java index ef42c41d..d29e6904 100644 --- a/gson/src/main/java/com/google/gson/JsonSerializationVisitor.java +++ b/gson/src/main/java/com/google/gson/JsonSerializationVisitor.java @@ -54,7 +54,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor { } public void start(ObjectTypePair node) { - if (node == null) { + if (node == null || node.isSystemOnly()) { return; } if (ancestors.contains(node)) { @@ -64,7 +64,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor { } public void end(ObjectTypePair node) { - if (node != null) { + if (node != null && !node.isSystemOnly()) { ancestors.pop(); } } @@ -81,7 +81,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor { Object child = Array.get(array, i); // we should not get more specific component type yet since it is possible // that a custom serializer is registered for the componentType - addAsArrayElement(new ObjectTypePair(child, componentType, false)); + addAsArrayElement(new ObjectTypePair(child, componentType, false, false)); } } @@ -93,7 +93,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor { } } else { Object array = getFieldValue(f, obj); - addAsChildOfObject(f, new ObjectTypePair(array, typeOfF, false)); + addAsChildOfObject(f, new ObjectTypePair(array, typeOfF, false, false)); } } catch (CircularReferenceException e) { throw e.createDetailedException(f); @@ -111,7 +111,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor { // we should not get more specific component type yet since it is // possible that a custom // serializer is registered for the componentType - addAsChildOfObject(f, new ObjectTypePair(fieldValue, typeOfF, false)); + addAsChildOfObject(f, new ObjectTypePair(fieldValue, typeOfF, false, false)); } } catch (CircularReferenceException e) { throw e.createDetailedException(f); @@ -200,7 +200,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor { } return true; } - ObjectTypePair objTypePair = new ObjectTypePair(obj, declaredTypeOfField, false); + ObjectTypePair objTypePair = new ObjectTypePair(obj, declaredTypeOfField, false, false); JsonElement child = findAndInvokeCustomSerializer(objTypePair); if (child != null) { addChildAsElement(f, child); diff --git a/gson/src/main/java/com/google/gson/MappedObjectConstructor.java b/gson/src/main/java/com/google/gson/MappedObjectConstructor.java index 86fdfdd9..dbd8c3b0 100644 --- a/gson/src/main/java/com/google/gson/MappedObjectConstructor.java +++ b/gson/src/main/java/com/google/gson/MappedObjectConstructor.java @@ -45,7 +45,7 @@ final class MappedObjectConstructor implements ObjectConstructor { @SuppressWarnings("unchecked") public T construct(Type typeOfT) { - InstanceCreator creator = (InstanceCreator) instanceCreatorMap.getHandlerFor(typeOfT); + InstanceCreator creator = (InstanceCreator) instanceCreatorMap.getHandlerFor(typeOfT, false); if (creator != null) { return creator.createInstance(typeOfT); } diff --git a/gson/src/main/java/com/google/gson/ObjectTypePair.java b/gson/src/main/java/com/google/gson/ObjectTypePair.java index c777d809..3e85eae7 100644 --- a/gson/src/main/java/com/google/gson/ObjectTypePair.java +++ b/gson/src/main/java/com/google/gson/ObjectTypePair.java @@ -27,11 +27,13 @@ final class ObjectTypePair { private Object obj; final Type type; private final boolean preserveType; + private final boolean systemOnly; - ObjectTypePair(Object obj, Type type, boolean preserveType) { + ObjectTypePair(Object obj, Type type, boolean preserveType, boolean systemOnly) { this.obj = obj; this.type = type; this.preserveType = preserveType; + this.systemOnly = systemOnly; } Object getObject() { @@ -57,13 +59,13 @@ final class ObjectTypePair { if (!preserveType && obj != null) { // First try looking up the handler for the actual type ObjectTypePair moreSpecificType = toMoreSpecificType(); - handler = handlers.getHandlerFor(moreSpecificType.type); + handler = handlers.getHandlerFor(moreSpecificType.type, systemOnly); if (handler != null) { return new Pair(handler, moreSpecificType); } } // Try the specified type - handler = handlers.getHandlerFor(type); + handler = handlers.getHandlerFor(type, systemOnly); return handler == null ? null : new Pair(handler, this); } @@ -75,7 +77,7 @@ final class ObjectTypePair { if (actualType == type) { return this; } - return new ObjectTypePair(obj, actualType, true); + return new ObjectTypePair(obj, actualType, true, systemOnly); } Type getMoreSpecificType() { @@ -135,10 +137,14 @@ final class ObjectTypePair { } else if (!type.equals(other.type)) { return false; } - return preserveType == other.preserveType; + return preserveType == other.preserveType && systemOnly == other.systemOnly; } public boolean isPreserveType() { return preserveType; } + + public boolean isSystemOnly() { + return systemOnly; + } } diff --git a/gson/src/main/java/com/google/gson/ParameterizedTypeHandlerMap.java b/gson/src/main/java/com/google/gson/ParameterizedTypeHandlerMap.java index df05dd70..7add6ad4 100644 --- a/gson/src/main/java/com/google/gson/ParameterizedTypeHandlerMap.java +++ b/gson/src/main/java/com/google/gson/ParameterizedTypeHandlerMap.java @@ -164,10 +164,13 @@ final class ParameterizedTypeHandlerMap { modifiable = false; } - public synchronized T getHandlerFor(Type type) { - T handler = userMap.get(type); - if (handler != null) { - return handler; + public synchronized T getHandlerFor(Type type, boolean systemOnly) { + T handler; + if (!systemOnly) { + handler = userMap.get(type); + if (handler != null) { + return handler; + } } handler = systemMap.get(type); if (handler != null) { @@ -175,20 +178,22 @@ final class ParameterizedTypeHandlerMap { } Class rawClass = $Gson$Types.getRawType(type); if (rawClass != type) { - handler = getHandlerFor(rawClass); + handler = getHandlerFor(rawClass, systemOnly); if (handler != null) { return handler; } } // check if something registered for type hierarchy - handler = getHandlerForTypeHierarchy(rawClass); + handler = getHandlerForTypeHierarchy(rawClass, systemOnly); return handler; } - private T getHandlerForTypeHierarchy(Class type) { - for (Pair, T> entry : userTypeHierarchyList) { - if (entry.first.isAssignableFrom(type)) { - return entry.second; + private T getHandlerForTypeHierarchy(Class type, boolean systemOnly) { + if (!systemOnly) { + for (Pair, T> entry : userTypeHierarchyList) { + if (entry.first.isAssignableFrom(type)) { + return entry.second; + } } } for (Pair, T> entry : systemTypeHierarchyList) { diff --git a/gson/src/test/java/com/google/gson/MemoryRefStackTest.java b/gson/src/test/java/com/google/gson/MemoryRefStackTest.java index 35168c3f..788c03fe 100644 --- a/gson/src/test/java/com/google/gson/MemoryRefStackTest.java +++ b/gson/src/test/java/com/google/gson/MemoryRefStackTest.java @@ -42,7 +42,7 @@ public class MemoryRefStackTest extends TestCase { } public void testPushPeekAndPop() throws Exception { - ObjectTypePair obj = new ObjectTypePair(this, getClass(), true); + ObjectTypePair obj = new ObjectTypePair(this, getClass(), true, false); assertEquals(obj, stack.push(obj)); assertEquals(obj, stack.peek()); @@ -50,7 +50,7 @@ public class MemoryRefStackTest extends TestCase { } public void testPopTooMany() throws Exception { - ObjectTypePair obj = new ObjectTypePair(this, getClass(), true); + ObjectTypePair obj = new ObjectTypePair(this, getClass(), true, false); stack.push(obj); assertEquals(obj, stack.pop()); @@ -63,9 +63,9 @@ public class MemoryRefStackTest extends TestCase { MockObject objA = new MockObject(); MockObject objB = new MockObject(); assertEquals(objA, objB); - stack.push(new ObjectTypePair(objA, MockObject.class, true)); - assertTrue(stack.contains(new ObjectTypePair(objA, MockObject.class, true))); - assertFalse(stack.contains(new ObjectTypePair(objB, MockObject.class, true))); + stack.push(new ObjectTypePair(objA, MockObject.class, true, false)); + assertTrue(stack.contains(new ObjectTypePair(objA, MockObject.class, true, false))); + assertFalse(stack.contains(new ObjectTypePair(objB, MockObject.class, true, false))); } private static class MockObject { diff --git a/gson/src/test/java/com/google/gson/ParameterizedTypeHandlerMapTest.java b/gson/src/test/java/com/google/gson/ParameterizedTypeHandlerMapTest.java index 4c9231de..5e8212e8 100644 --- a/gson/src/test/java/com/google/gson/ParameterizedTypeHandlerMapTest.java +++ b/gson/src/test/java/com/google/gson/ParameterizedTypeHandlerMapTest.java @@ -41,8 +41,8 @@ public class ParameterizedTypeHandlerMapTest extends TestCase { public void testNullMap() throws Exception { assertFalse(paramMap.hasSpecificHandlerFor(String.class)); - assertNull(paramMap.getHandlerFor(String.class)); - assertNull(paramMap.getHandlerFor(String.class)); + assertNull(paramMap.getHandlerFor(String.class, false)); + assertNull(paramMap.getHandlerFor(String.class, false)); } public void testHasGenericButNotSpecific() throws Exception { @@ -52,9 +52,9 @@ public class ParameterizedTypeHandlerMapTest extends TestCase { assertFalse(paramMap.hasSpecificHandlerFor(specificType)); assertTrue(paramMap.hasSpecificHandlerFor(List.class)); - assertNotNull(paramMap.getHandlerFor(specificType)); - assertNotNull(paramMap.getHandlerFor(List.class)); - assertEquals(handler, paramMap.getHandlerFor(specificType)); + assertNotNull(paramMap.getHandlerFor(specificType, false)); + assertNotNull(paramMap.getHandlerFor(List.class, false)); + assertEquals(handler, paramMap.getHandlerFor(specificType, false)); } public void testHasSpecificType() throws Exception { @@ -64,9 +64,9 @@ public class ParameterizedTypeHandlerMapTest extends TestCase { assertTrue(paramMap.hasSpecificHandlerFor(specificType)); assertFalse(paramMap.hasSpecificHandlerFor(List.class)); - assertNotNull(paramMap.getHandlerFor(specificType)); - assertNull(paramMap.getHandlerFor(List.class)); - assertEquals(handler, paramMap.getHandlerFor(specificType)); + assertNotNull(paramMap.getHandlerFor(specificType, false)); + assertNull(paramMap.getHandlerFor(List.class, false)); + assertEquals(handler, paramMap.getHandlerFor(specificType, false)); } public void testTypeOverridding() throws Exception { @@ -76,7 +76,7 @@ public class ParameterizedTypeHandlerMapTest extends TestCase { paramMap.register(String.class, handler2, false); assertTrue(paramMap.hasSpecificHandlerFor(String.class)); - assertEquals(handler2, paramMap.getHandlerFor(String.class)); + assertEquals(handler2, paramMap.getHandlerFor(String.class, false)); } public void testMakeUnmodifiable() throws Exception { @@ -89,14 +89,14 @@ public class ParameterizedTypeHandlerMapTest extends TestCase { public void testTypeHierarchy() { paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false); - String handler = paramMap.getHandlerFor(Sub.class); + String handler = paramMap.getHandlerFor(Sub.class, false); assertEquals("baseHandler", handler); } public void testTypeHierarchyMultipleHandlers() { paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false); paramMap.registerForTypeHierarchy(Sub.class, "subHandler", false); - String handler = paramMap.getHandlerFor(SubOfSub.class); + String handler = paramMap.getHandlerFor(SubOfSub.class, false); assertEquals("subHandler", handler); } @@ -105,14 +105,14 @@ public class ParameterizedTypeHandlerMapTest extends TestCase { ParameterizedTypeHandlerMap otherMap = new ParameterizedTypeHandlerMap(); otherMap.registerForTypeHierarchy(Base.class, "baseHandler2", false); paramMap.registerIfAbsent(otherMap); - String handler = paramMap.getHandlerFor(Base.class); + String handler = paramMap.getHandlerFor(Base.class, false); assertEquals("baseHandler", handler); } public void testReplaceExistingTypeHierarchyHandler() { paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false); paramMap.registerForTypeHierarchy(Base.class, "base2Handler", false); - String handler = paramMap.getHandlerFor(Base.class); + String handler = paramMap.getHandlerFor(Base.class, false); assertEquals("base2Handler", handler); } diff --git a/gson/src/test/java/com/google/gson/functional/SystemOnlyTypeAdaptersTest.java b/gson/src/test/java/com/google/gson/functional/SystemOnlyTypeAdaptersTest.java new file mode 100644 index 00000000..f76728fd --- /dev/null +++ b/gson/src/test/java/com/google/gson/functional/SystemOnlyTypeAdaptersTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.gson.functional; + +import java.lang.reflect.Type; + +import junit.framework.TestCase; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +/** + * Functional tests for serialize default behavior where a custom type adapter is allowed to invoke + * context.serialize on self. + * + * @author Inderjeet Singh + */ +public class SystemOnlyTypeAdaptersTest extends TestCase { + + private Gson gson; + @Override + protected void setUp() throws Exception { + super.setUp(); + this.gson = new GsonBuilder().registerTypeAdapter(Foo.class, new FooTypeAdapter()).create(); + } + + public void testSerializeDefault() { + String json = gson.toJson(new Foo()); + assertEquals("{\"a\":10,\"secret-key\":\"abracadabra\"}", json); + } + + public void testDeserializeDefault() { + String json = "{a:5,'secret-key':'abracadabra'}"; + Foo foo = gson.fromJson(json, Foo.class); + assertEquals(5, foo.a); + } + + private static class Foo { + int a = 10; + } + + private static class FooTypeAdapter implements JsonSerializer, JsonDeserializer { + public JsonElement serialize(Foo src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject json = context.serializeDefault(src, typeOfSrc).getAsJsonObject(); + json.addProperty("secret-key", "abracadabra"); + return json; + } + + public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + if (!"abracadabra".equals(json.getAsJsonObject().get("secret-key").getAsString())) { + throw new IllegalArgumentException("invalid key"); + } + return context.deserializeDefault(json, typeOfT); + } + } +}