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:
parent
0922af5be6
commit
e280ffd7e2
@ -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
|
||||||
@ -897,11 +899,21 @@ public final class Gson {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new StringBuilder("{serializeNulls:")
|
return new StringBuilder("{serializeNulls:")
|
||||||
.append(serializeNulls)
|
.append(serializeNulls)
|
||||||
.append("factories:").append(factories)
|
.append("factories:").append(factories)
|
||||||
.append(",instanceCreators:").append(constructorConstructor)
|
.append(",instanceCreators:").append(constructorConstructor)
|
||||||
.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user