Fixed broken test to ensure that a field JsonAdapter annotation supersedes the class JsonAdapter annotation.

Added a map in Gson to keep track of TypeAdapters which are generated by Gson.
This commit is contained in:
Inderjeet Singh 2014-03-09 08:36:24 +00:00
parent 0922af5be6
commit e280ffd7e2
3 changed files with 28 additions and 13 deletions

View File

@ -49,8 +49,10 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* This is the main class for using Gson. Gson is typically used by first constructing a
@ -897,11 +899,21 @@ public final class Gson {
@Override
public String toString() {
return new StringBuilder("{serializeNulls:")
.append(serializeNulls)
.append("factories:").append(factories)
return new StringBuilder("{serializeNulls:")
.append(serializeNulls)
.append("factories:").append(factories)
.append(",instanceCreators:").append(constructorConstructor)
.append("}")
.toString();
}
private final Set<TypeAdapter<?>> generatedTypeAdapters = new HashSet<TypeAdapter<?>>();
public static final class $$Internal {
public static void addGeneratedTypeAdapter(Gson gson, TypeAdapter<?> typeAdapter) {
gson.generatedTypeAdapters.add(typeAdapter);
}
public static boolean isGeneratedTypeAdapter(Gson gson, TypeAdapter<?> typeAdapter) {
return gson.generatedTypeAdapters.contains(typeAdapter);
}
}
}

View File

@ -43,15 +43,17 @@ public final class JsonAdapterAnnotationTypeAdapterFactory implements TypeAdapte
Class<? super T> clazz = targetType.getRawType();
JsonAdapter annotation = clazz.getAnnotation(JsonAdapter.class);
if (annotation == null) return null;
TypeAdapter adapter = getAnnotationTypeAdapter(constructorConstructor, annotation);
TypeAdapter adapter = getAnnotationTypeAdapter(gson, constructorConstructor, annotation);
return adapter;
}
static TypeAdapter<?> getAnnotationTypeAdapter(
static TypeAdapter<?> getAnnotationTypeAdapter(Gson gson,
ConstructorConstructor constructorConstructor, JsonAdapter annotation) {
Class<? extends TypeAdapter<?>> adapterClass = annotation.value();
ObjectConstructor<? extends TypeAdapter<?>> constructor =
constructorConstructor.get(TypeToken.get(adapterClass));
return constructor.construct();
TypeAdapter<?> adapter = constructor.construct();
Gson.$$Internal.addGeneratedTypeAdapter(gson, adapter);
return adapter;
}
}

View File

@ -71,7 +71,9 @@ public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory {
}
ObjectConstructor<T> constructor = constructorConstructor.get(type);
return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
Adapter<T> adapter = new Adapter<T>(constructor, getBoundFields(gson, type, raw));
Gson.$$Internal.addGeneratedTypeAdapter(gson, adapter);
return adapter;
}
private ReflectiveTypeAdapterFactory.BoundField createBoundField(
@ -99,14 +101,13 @@ public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory {
};
}
private TypeAdapter<?> getFieldAdapter(Gson context, Field field, TypeToken<?> fieldType) {
TypeAdapter<?> adapter = context.getAdapter(fieldType);
// check if the registered adapter is a reflective type adapter. If so, JsonAdapter
// annotation should take precedence. Somewhat hackish, but works.
if (adapter instanceof Adapter && field.isAnnotationPresent(JsonAdapter.class)) {
private TypeAdapter<?> getFieldAdapter(Gson gson, Field field, TypeToken<?> fieldType) {
TypeAdapter<?> adapter = gson.getAdapter(fieldType);
boolean generatedAdapter = Gson.$$Internal.isGeneratedTypeAdapter(gson, adapter);
if (generatedAdapter && field.isAnnotationPresent(JsonAdapter.class)) {
JsonAdapter annotation = field.getAnnotation(JsonAdapter.class);
return JsonAdapterAnnotationTypeAdapterFactory.getAnnotationTypeAdapter(
constructorConstructor, annotation);
gson, constructorConstructor, annotation);
}
return adapter;
}