Added serializeDefault and deserializeDefault methods in contexts that only invoke system type adapters on the top-level object.
With this, the RuntimeTypeAdapterTest passes.
This commit is contained in:
parent
5f4e88f62a
commit
62675b7f46
|
@ -184,7 +184,7 @@ public final class RuntimeTypeAdapter<T> implements JsonSerializer<T>, JsonDeser
|
||||||
throw new JsonParseException("cannot serialize " + srcType.getName()
|
throw new JsonParseException("cannot serialize " + srcType.getName()
|
||||||
+ "; did you forget to register a subtype?");
|
+ "; did you forget to register a subtype?");
|
||||||
}
|
}
|
||||||
JsonElement serialized = context.serialize(src, srcType);
|
JsonElement serialized = context.serializeDefault(src, srcType);
|
||||||
final JsonObject jsonObject = serialized.getAsJsonObject();
|
final JsonObject jsonObject = serialized.getAsJsonObject();
|
||||||
if (jsonObject.has(typeFieldName)) {
|
if (jsonObject.has(typeFieldName)) {
|
||||||
throw new JsonParseException("cannot serialize " + srcType.getName()
|
throw new JsonParseException("cannot serialize " + srcType.getName()
|
||||||
|
@ -212,7 +212,7 @@ public final class RuntimeTypeAdapter<T> implements JsonSerializer<T>, JsonDeser
|
||||||
+ label + "; did you forget to register a subtype?");
|
+ label + "; did you forget to register a subtype?");
|
||||||
}
|
}
|
||||||
@SuppressWarnings("unchecked") // registration requires that subtype extends T
|
@SuppressWarnings("unchecked") // registration requires that subtype extends T
|
||||||
T result = (T) context.deserialize(json, subtype);
|
T result = (T) context.deserializeDefault(json, subtype);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public final class RuntimeTypeAdapterTest extends TestCase {
|
||||||
assertEquals("{\"type\":\"BillingInstrument\",\"ownerName\":\"Jesse\"}",
|
assertEquals("{\"type\":\"BillingInstrument\",\"ownerName\":\"Jesse\"}",
|
||||||
gson.toJson(original, BillingInstrument.class));
|
gson.toJson(original, BillingInstrument.class));
|
||||||
BillingInstrument deserialized = gson.fromJson(
|
BillingInstrument deserialized = gson.fromJson(
|
||||||
"{type:'CreditCard',ownerName:'Jesse'}", BillingInstrument.class);
|
"{type:'BillingInstrument',ownerName:'Jesse'}", BillingInstrument.class);
|
||||||
assertEquals("Jesse", deserialized.ownerName);
|
assertEquals("Jesse", deserialized.ownerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ abstract class BaseMapTypeAdapter
|
||||||
|
|
||||||
protected static final JsonElement serialize(JsonSerializationContext context,
|
protected static final JsonElement serialize(JsonSerializationContext context,
|
||||||
Object src, Type srcType) {
|
Object src, Type srcType) {
|
||||||
return context.serialize(src, srcType, false);
|
return context.serialize(src, srcType, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static final Map<Object, Object> constructMapType(
|
protected static final Map<Object, Object> constructMapType(
|
||||||
|
|
|
@ -677,7 +677,7 @@ 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, false);
|
JsonElement element = context.serialize(child, childType, false, false);
|
||||||
array.add(element);
|
array.add(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,29 +55,29 @@ public final class JsonDeserializationContext {
|
||||||
|
|
||||||
|
|
||||||
private <T> T fromJsonArray(Type arrayType, JsonArray jsonArray,
|
private <T> T fromJsonArray(Type arrayType, JsonArray jsonArray,
|
||||||
JsonDeserializationContext context) throws JsonParseException {
|
JsonDeserializationContext context, boolean systemOnly) throws JsonParseException {
|
||||||
JsonArrayDeserializationVisitor<T> visitor = new JsonArrayDeserializationVisitor<T>(
|
JsonArrayDeserializationVisitor<T> visitor = new JsonArrayDeserializationVisitor<T>(
|
||||||
jsonArray, arrayType, objectNavigator, fieldNamingPolicy,
|
jsonArray, arrayType, objectNavigator, fieldNamingPolicy,
|
||||||
objectConstructor, deserializers, context);
|
objectConstructor, deserializers, context);
|
||||||
objectNavigator.accept(new ObjectTypePair(null, arrayType, true), visitor);
|
objectNavigator.accept(new ObjectTypePair(null, arrayType, true, systemOnly), visitor);
|
||||||
return visitor.getTarget();
|
return visitor.getTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T fromJsonObject(Type typeOfT, JsonObject jsonObject,
|
private <T> T fromJsonObject(Type typeOfT, JsonObject jsonObject,
|
||||||
JsonDeserializationContext context) throws JsonParseException {
|
JsonDeserializationContext context, boolean systemOnly) throws JsonParseException {
|
||||||
JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
|
JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
|
||||||
jsonObject, typeOfT, objectNavigator, fieldNamingPolicy,
|
jsonObject, typeOfT, objectNavigator, fieldNamingPolicy,
|
||||||
objectConstructor, deserializers, context);
|
objectConstructor, deserializers, context);
|
||||||
objectNavigator.accept(new ObjectTypePair(null, typeOfT, true), visitor);
|
objectNavigator.accept(new ObjectTypePair(null, typeOfT, true, systemOnly), visitor);
|
||||||
return visitor.getTarget();
|
return visitor.getTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <T> T fromJsonPrimitive(Type typeOfT, JsonPrimitive json,
|
private <T> T fromJsonPrimitive(Type typeOfT, JsonPrimitive json,
|
||||||
JsonDeserializationContext context) throws JsonParseException {
|
JsonDeserializationContext context, boolean systemOnly) throws JsonParseException {
|
||||||
JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
|
JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
|
||||||
json, typeOfT, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context);
|
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();
|
Object target = visitor.getTarget();
|
||||||
return (T) target;
|
return (T) target;
|
||||||
}
|
}
|
||||||
|
@ -99,13 +99,31 @@ public final class JsonDeserializationContext {
|
||||||
if (json == null || json.isJsonNull()) {
|
if (json == null || json.isJsonNull()) {
|
||||||
return null;
|
return null;
|
||||||
} else if (json.isJsonArray()) {
|
} else if (json.isJsonArray()) {
|
||||||
Object array = fromJsonArray(typeOfT, json.getAsJsonArray(), this);
|
Object array = fromJsonArray(typeOfT, json.getAsJsonArray(), this, false);
|
||||||
return (T) array;
|
return (T) array;
|
||||||
} else if (json.isJsonObject()) {
|
} else if (json.isJsonObject()) {
|
||||||
Object object = fromJsonObject(typeOfT, json.getAsJsonObject(), this);
|
Object object = fromJsonObject(typeOfT, json.getAsJsonObject(), this, false);
|
||||||
return (T) object;
|
return (T) object;
|
||||||
} else if (json.isJsonPrimitive()) {
|
} 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> 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;
|
return (T) primitive;
|
||||||
} else {
|
} else {
|
||||||
throw new JsonParseException("Failed parsing JSON source: " + json + " to Json");
|
throw new JsonParseException("Failed parsing JSON source: " + json + " to Json");
|
||||||
|
|
|
@ -107,7 +107,7 @@ abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object visitChild(Type type, JsonDeserializationVisitor<?> childVisitor) {
|
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
|
// the underlying object may have changed during the construction phase
|
||||||
// This happens primarily because of custom deserializers
|
// This happens primarily because of custom deserializers
|
||||||
return childVisitor.getTarget();
|
return childVisitor.getTarget();
|
||||||
|
|
|
@ -109,7 +109,7 @@ final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisit
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ObjectTypePair objTypePair = new ObjectTypePair(null, declaredTypeOfField, false);
|
ObjectTypePair objTypePair = new ObjectTypePair(null, declaredTypeOfField, false, false);
|
||||||
Pair<JsonDeserializer<?>, ObjectTypePair> pair = objTypePair.getMatchingHandler(deserializers);
|
Pair<JsonDeserializer<?>, ObjectTypePair> pair = objTypePair.getMatchingHandler(deserializers);
|
||||||
if (pair == null) {
|
if (pair == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -53,7 +53,7 @@ public final class JsonSerializationContext {
|
||||||
if (src == null) {
|
if (src == null) {
|
||||||
return JsonNull.INSTANCE;
|
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}.
|
* @return a tree of {@link JsonElement}s corresponding to the serialized form of {@code src}.
|
||||||
*/
|
*/
|
||||||
public JsonElement serialize(Object src, Type typeOfSrc) {
|
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) {
|
if (src == null) {
|
||||||
return JsonNull.INSTANCE;
|
return JsonNull.INSTANCE;
|
||||||
}
|
}
|
||||||
JsonSerializationVisitor visitor = new JsonSerializationVisitor(
|
JsonSerializationVisitor visitor = new JsonSerializationVisitor(
|
||||||
objectNavigator, fieldNamingPolicy, serializeNulls, serializers, this, ancestors);
|
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);
|
objectNavigator.accept(objTypePair, visitor);
|
||||||
return visitor.getJsonElement();
|
return visitor.getJsonElement();
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start(ObjectTypePair node) {
|
public void start(ObjectTypePair node) {
|
||||||
if (node == null) {
|
if (node == null || node.isSystemOnly()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ancestors.contains(node)) {
|
if (ancestors.contains(node)) {
|
||||||
|
@ -64,7 +64,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void end(ObjectTypePair node) {
|
public void end(ObjectTypePair node) {
|
||||||
if (node != null) {
|
if (node != null && !node.isSystemOnly()) {
|
||||||
ancestors.pop();
|
ancestors.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||||
Object child = Array.get(array, i);
|
Object child = Array.get(array, i);
|
||||||
// we should not get more specific component type yet since it is possible
|
// we should not get more specific component type yet since it is possible
|
||||||
// that a custom serializer is registered for the componentType
|
// 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 {
|
} else {
|
||||||
Object array = getFieldValue(f, obj);
|
Object array = getFieldValue(f, obj);
|
||||||
addAsChildOfObject(f, new ObjectTypePair(array, typeOfF, false));
|
addAsChildOfObject(f, new ObjectTypePair(array, typeOfF, false, false));
|
||||||
}
|
}
|
||||||
} catch (CircularReferenceException e) {
|
} catch (CircularReferenceException e) {
|
||||||
throw e.createDetailedException(f);
|
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
|
// we should not get more specific component type yet since it is
|
||||||
// possible that a custom
|
// possible that a custom
|
||||||
// serializer is registered for the componentType
|
// serializer is registered for the componentType
|
||||||
addAsChildOfObject(f, new ObjectTypePair(fieldValue, typeOfF, false));
|
addAsChildOfObject(f, new ObjectTypePair(fieldValue, typeOfF, false, false));
|
||||||
}
|
}
|
||||||
} catch (CircularReferenceException e) {
|
} catch (CircularReferenceException e) {
|
||||||
throw e.createDetailedException(f);
|
throw e.createDetailedException(f);
|
||||||
|
@ -200,7 +200,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ObjectTypePair objTypePair = new ObjectTypePair(obj, declaredTypeOfField, false);
|
ObjectTypePair objTypePair = new ObjectTypePair(obj, declaredTypeOfField, false, false);
|
||||||
JsonElement child = findAndInvokeCustomSerializer(objTypePair);
|
JsonElement child = findAndInvokeCustomSerializer(objTypePair);
|
||||||
if (child != null) {
|
if (child != null) {
|
||||||
addChildAsElement(f, child);
|
addChildAsElement(f, child);
|
||||||
|
|
|
@ -45,7 +45,7 @@ final class MappedObjectConstructor implements ObjectConstructor {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> T construct(Type typeOfT) {
|
public <T> T construct(Type typeOfT) {
|
||||||
InstanceCreator<T> creator = (InstanceCreator<T>) instanceCreatorMap.getHandlerFor(typeOfT);
|
InstanceCreator<T> creator = (InstanceCreator<T>) instanceCreatorMap.getHandlerFor(typeOfT, false);
|
||||||
if (creator != null) {
|
if (creator != null) {
|
||||||
return creator.createInstance(typeOfT);
|
return creator.createInstance(typeOfT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,11 +27,13 @@ final class ObjectTypePair {
|
||||||
private Object obj;
|
private Object obj;
|
||||||
final Type type;
|
final Type type;
|
||||||
private final boolean preserveType;
|
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.obj = obj;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.preserveType = preserveType;
|
this.preserveType = preserveType;
|
||||||
|
this.systemOnly = systemOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object getObject() {
|
Object getObject() {
|
||||||
|
@ -57,13 +59,13 @@ final class ObjectTypePair {
|
||||||
if (!preserveType && obj != null) {
|
if (!preserveType && obj != null) {
|
||||||
// First try looking up the handler for the actual type
|
// First try looking up the handler for the actual type
|
||||||
ObjectTypePair moreSpecificType = toMoreSpecificType();
|
ObjectTypePair moreSpecificType = toMoreSpecificType();
|
||||||
handler = handlers.getHandlerFor(moreSpecificType.type);
|
handler = handlers.getHandlerFor(moreSpecificType.type, systemOnly);
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
return new Pair<HANDLER, ObjectTypePair>(handler, moreSpecificType);
|
return new Pair<HANDLER, ObjectTypePair>(handler, moreSpecificType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Try the specified type
|
// Try the specified type
|
||||||
handler = handlers.getHandlerFor(type);
|
handler = handlers.getHandlerFor(type, systemOnly);
|
||||||
return handler == null ? null : new Pair<HANDLER, ObjectTypePair>(handler, this);
|
return handler == null ? null : new Pair<HANDLER, ObjectTypePair>(handler, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +77,7 @@ final class ObjectTypePair {
|
||||||
if (actualType == type) {
|
if (actualType == type) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return new ObjectTypePair(obj, actualType, true);
|
return new ObjectTypePair(obj, actualType, true, systemOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type getMoreSpecificType() {
|
Type getMoreSpecificType() {
|
||||||
|
@ -135,10 +137,14 @@ final class ObjectTypePair {
|
||||||
} else if (!type.equals(other.type)) {
|
} else if (!type.equals(other.type)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return preserveType == other.preserveType;
|
return preserveType == other.preserveType && systemOnly == other.systemOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPreserveType() {
|
public boolean isPreserveType() {
|
||||||
return preserveType;
|
return preserveType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSystemOnly() {
|
||||||
|
return systemOnly;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,33 +164,38 @@ final class ParameterizedTypeHandlerMap<T> {
|
||||||
modifiable = false;
|
modifiable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized T getHandlerFor(Type type) {
|
public synchronized T getHandlerFor(Type type, boolean systemOnly) {
|
||||||
T handler = userMap.get(type);
|
T handler;
|
||||||
|
if (!systemOnly) {
|
||||||
|
handler = userMap.get(type);
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
handler = systemMap.get(type);
|
handler = systemMap.get(type);
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
Class<?> rawClass = $Gson$Types.getRawType(type);
|
Class<?> rawClass = $Gson$Types.getRawType(type);
|
||||||
if (rawClass != type) {
|
if (rawClass != type) {
|
||||||
handler = getHandlerFor(rawClass);
|
handler = getHandlerFor(rawClass, systemOnly);
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check if something registered for type hierarchy
|
// check if something registered for type hierarchy
|
||||||
handler = getHandlerForTypeHierarchy(rawClass);
|
handler = getHandlerForTypeHierarchy(rawClass, systemOnly);
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
private T getHandlerForTypeHierarchy(Class<?> type) {
|
private T getHandlerForTypeHierarchy(Class<?> type, boolean systemOnly) {
|
||||||
|
if (!systemOnly) {
|
||||||
for (Pair<Class<?>, T> entry : userTypeHierarchyList) {
|
for (Pair<Class<?>, T> entry : userTypeHierarchyList) {
|
||||||
if (entry.first.isAssignableFrom(type)) {
|
if (entry.first.isAssignableFrom(type)) {
|
||||||
return entry.second;
|
return entry.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for (Pair<Class<?>, T> entry : systemTypeHierarchyList) {
|
for (Pair<Class<?>, T> entry : systemTypeHierarchyList) {
|
||||||
if (entry.first.isAssignableFrom(type)) {
|
if (entry.first.isAssignableFrom(type)) {
|
||||||
return entry.second;
|
return entry.second;
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class MemoryRefStackTest extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPushPeekAndPop() throws Exception {
|
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.push(obj));
|
||||||
assertEquals(obj, stack.peek());
|
assertEquals(obj, stack.peek());
|
||||||
|
@ -50,7 +50,7 @@ public class MemoryRefStackTest extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPopTooMany() throws Exception {
|
public void testPopTooMany() throws Exception {
|
||||||
ObjectTypePair obj = new ObjectTypePair(this, getClass(), true);
|
ObjectTypePair obj = new ObjectTypePair(this, getClass(), true, false);
|
||||||
stack.push(obj);
|
stack.push(obj);
|
||||||
assertEquals(obj, stack.pop());
|
assertEquals(obj, stack.pop());
|
||||||
|
|
||||||
|
@ -63,9 +63,9 @@ public class MemoryRefStackTest extends TestCase {
|
||||||
MockObject objA = new MockObject();
|
MockObject objA = new MockObject();
|
||||||
MockObject objB = new MockObject();
|
MockObject objB = new MockObject();
|
||||||
assertEquals(objA, objB);
|
assertEquals(objA, objB);
|
||||||
stack.push(new ObjectTypePair(objA, MockObject.class, true));
|
stack.push(new ObjectTypePair(objA, MockObject.class, true, false));
|
||||||
assertTrue(stack.contains(new ObjectTypePair(objA, MockObject.class, true)));
|
assertTrue(stack.contains(new ObjectTypePair(objA, MockObject.class, true, false)));
|
||||||
assertFalse(stack.contains(new ObjectTypePair(objB, MockObject.class, true)));
|
assertFalse(stack.contains(new ObjectTypePair(objB, MockObject.class, true, false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MockObject {
|
private static class MockObject {
|
||||||
|
|
|
@ -41,8 +41,8 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
|
||||||
|
|
||||||
public void testNullMap() throws Exception {
|
public void testNullMap() throws Exception {
|
||||||
assertFalse(paramMap.hasSpecificHandlerFor(String.class));
|
assertFalse(paramMap.hasSpecificHandlerFor(String.class));
|
||||||
assertNull(paramMap.getHandlerFor(String.class));
|
assertNull(paramMap.getHandlerFor(String.class, false));
|
||||||
assertNull(paramMap.getHandlerFor(String.class));
|
assertNull(paramMap.getHandlerFor(String.class, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testHasGenericButNotSpecific() throws Exception {
|
public void testHasGenericButNotSpecific() throws Exception {
|
||||||
|
@ -52,9 +52,9 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
|
||||||
|
|
||||||
assertFalse(paramMap.hasSpecificHandlerFor(specificType));
|
assertFalse(paramMap.hasSpecificHandlerFor(specificType));
|
||||||
assertTrue(paramMap.hasSpecificHandlerFor(List.class));
|
assertTrue(paramMap.hasSpecificHandlerFor(List.class));
|
||||||
assertNotNull(paramMap.getHandlerFor(specificType));
|
assertNotNull(paramMap.getHandlerFor(specificType, false));
|
||||||
assertNotNull(paramMap.getHandlerFor(List.class));
|
assertNotNull(paramMap.getHandlerFor(List.class, false));
|
||||||
assertEquals(handler, paramMap.getHandlerFor(specificType));
|
assertEquals(handler, paramMap.getHandlerFor(specificType, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testHasSpecificType() throws Exception {
|
public void testHasSpecificType() throws Exception {
|
||||||
|
@ -64,9 +64,9 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
|
||||||
|
|
||||||
assertTrue(paramMap.hasSpecificHandlerFor(specificType));
|
assertTrue(paramMap.hasSpecificHandlerFor(specificType));
|
||||||
assertFalse(paramMap.hasSpecificHandlerFor(List.class));
|
assertFalse(paramMap.hasSpecificHandlerFor(List.class));
|
||||||
assertNotNull(paramMap.getHandlerFor(specificType));
|
assertNotNull(paramMap.getHandlerFor(specificType, false));
|
||||||
assertNull(paramMap.getHandlerFor(List.class));
|
assertNull(paramMap.getHandlerFor(List.class, false));
|
||||||
assertEquals(handler, paramMap.getHandlerFor(specificType));
|
assertEquals(handler, paramMap.getHandlerFor(specificType, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testTypeOverridding() throws Exception {
|
public void testTypeOverridding() throws Exception {
|
||||||
|
@ -76,7 +76,7 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
|
||||||
paramMap.register(String.class, handler2, false);
|
paramMap.register(String.class, handler2, false);
|
||||||
|
|
||||||
assertTrue(paramMap.hasSpecificHandlerFor(String.class));
|
assertTrue(paramMap.hasSpecificHandlerFor(String.class));
|
||||||
assertEquals(handler2, paramMap.getHandlerFor(String.class));
|
assertEquals(handler2, paramMap.getHandlerFor(String.class, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMakeUnmodifiable() throws Exception {
|
public void testMakeUnmodifiable() throws Exception {
|
||||||
|
@ -89,14 +89,14 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
|
||||||
|
|
||||||
public void testTypeHierarchy() {
|
public void testTypeHierarchy() {
|
||||||
paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false);
|
paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false);
|
||||||
String handler = paramMap.getHandlerFor(Sub.class);
|
String handler = paramMap.getHandlerFor(Sub.class, false);
|
||||||
assertEquals("baseHandler", handler);
|
assertEquals("baseHandler", handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testTypeHierarchyMultipleHandlers() {
|
public void testTypeHierarchyMultipleHandlers() {
|
||||||
paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false);
|
paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false);
|
||||||
paramMap.registerForTypeHierarchy(Sub.class, "subHandler", false);
|
paramMap.registerForTypeHierarchy(Sub.class, "subHandler", false);
|
||||||
String handler = paramMap.getHandlerFor(SubOfSub.class);
|
String handler = paramMap.getHandlerFor(SubOfSub.class, false);
|
||||||
assertEquals("subHandler", handler);
|
assertEquals("subHandler", handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,14 +105,14 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
|
||||||
ParameterizedTypeHandlerMap<String> otherMap = new ParameterizedTypeHandlerMap<String>();
|
ParameterizedTypeHandlerMap<String> otherMap = new ParameterizedTypeHandlerMap<String>();
|
||||||
otherMap.registerForTypeHierarchy(Base.class, "baseHandler2", false);
|
otherMap.registerForTypeHierarchy(Base.class, "baseHandler2", false);
|
||||||
paramMap.registerIfAbsent(otherMap);
|
paramMap.registerIfAbsent(otherMap);
|
||||||
String handler = paramMap.getHandlerFor(Base.class);
|
String handler = paramMap.getHandlerFor(Base.class, false);
|
||||||
assertEquals("baseHandler", handler);
|
assertEquals("baseHandler", handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testReplaceExistingTypeHierarchyHandler() {
|
public void testReplaceExistingTypeHierarchyHandler() {
|
||||||
paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false);
|
paramMap.registerForTypeHierarchy(Base.class, "baseHandler", false);
|
||||||
paramMap.registerForTypeHierarchy(Base.class, "base2Handler", false);
|
paramMap.registerForTypeHierarchy(Base.class, "base2Handler", false);
|
||||||
String handler = paramMap.getHandlerFor(Base.class);
|
String handler = paramMap.getHandlerFor(Base.class, false);
|
||||||
assertEquals("base2Handler", handler);
|
assertEquals("base2Handler", handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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<Foo>, JsonDeserializer<Foo> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user