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.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* This is the main class for using Gson. Gson is typically used by first constructing a * This is the main class for using Gson. Gson is typically used by first constructing a
@ -904,4 +906,14 @@ public final class Gson {
.append("}") .append("}")
.toString(); .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(); Class<? super T> clazz = targetType.getRawType();
JsonAdapter annotation = clazz.getAnnotation(JsonAdapter.class); JsonAdapter annotation = clazz.getAnnotation(JsonAdapter.class);
if (annotation == null) return null; if (annotation == null) return null;
TypeAdapter adapter = getAnnotationTypeAdapter(constructorConstructor, annotation); TypeAdapter adapter = getAnnotationTypeAdapter(gson, constructorConstructor, annotation);
return adapter; return adapter;
} }
static TypeAdapter<?> getAnnotationTypeAdapter( static TypeAdapter<?> getAnnotationTypeAdapter(Gson gson,
ConstructorConstructor constructorConstructor, JsonAdapter annotation) { ConstructorConstructor constructorConstructor, JsonAdapter annotation) {
Class<? extends TypeAdapter<?>> adapterClass = annotation.value(); Class<? extends TypeAdapter<?>> adapterClass = annotation.value();
ObjectConstructor<? extends TypeAdapter<?>> constructor = ObjectConstructor<? extends TypeAdapter<?>> constructor =
constructorConstructor.get(TypeToken.get(adapterClass)); 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); 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( private ReflectiveTypeAdapterFactory.BoundField createBoundField(
@ -99,14 +101,13 @@ public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory {
}; };
} }
private TypeAdapter<?> getFieldAdapter(Gson context, Field field, TypeToken<?> fieldType) { private TypeAdapter<?> getFieldAdapter(Gson gson, Field field, TypeToken<?> fieldType) {
TypeAdapter<?> adapter = context.getAdapter(fieldType); TypeAdapter<?> adapter = gson.getAdapter(fieldType);
// check if the registered adapter is a reflective type adapter. If so, JsonAdapter boolean generatedAdapter = Gson.$$Internal.isGeneratedTypeAdapter(gson, adapter);
// annotation should take precedence. Somewhat hackish, but works. if (generatedAdapter && field.isAnnotationPresent(JsonAdapter.class)) {
if (adapter instanceof Adapter && field.isAnnotationPresent(JsonAdapter.class)) {
JsonAdapter annotation = field.getAnnotation(JsonAdapter.class); JsonAdapter annotation = field.getAnnotation(JsonAdapter.class);
return JsonAdapterAnnotationTypeAdapterFactory.getAnnotationTypeAdapter( return JsonAdapterAnnotationTypeAdapterFactory.getAnnotationTypeAdapter(
constructorConstructor, annotation); gson, constructorConstructor, annotation);
} }
return adapter; return adapter;
} }