Smash together ReflectiveTypeAdapterFactory and its subclass. The separation was useful earlier when we were contemplating keeping Gson and MiniGson separate.
This commit is contained in:
parent
f39ac8d946
commit
e23973afec
@ -58,8 +58,8 @@ public final class FieldAttributes {
|
||||
*
|
||||
* @param f the field to pull attributes from
|
||||
*/
|
||||
FieldAttributes(Class<?> declaringClazz, Field f) {
|
||||
this.declaringClazz = $Gson$Preconditions.checkNotNull(declaringClazz);
|
||||
public FieldAttributes(Field f) {
|
||||
this.declaringClazz = f.getDeclaringClass();
|
||||
this.name = f.getName();
|
||||
this.declaredType = f.getType();
|
||||
this.isSynthetic = f.isSynthetic();
|
||||
@ -200,14 +200,6 @@ public final class FieldAttributes {
|
||||
return isSynthetic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated remove this when {@link FieldNamingStrategy} is deleted.
|
||||
*/
|
||||
@Deprecated
|
||||
Field getFieldObject() {
|
||||
return field;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends Annotation> T getAnnotationFromArray(
|
||||
Collection<Annotation> annotations, Class<T> annotation) {
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
package com.google.gson;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.internal.ConstructorConstructor;
|
||||
import com.google.gson.internal.Primitives;
|
||||
import com.google.gson.internal.Streams;
|
||||
@ -46,7 +45,6 @@ import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
@ -104,7 +102,7 @@ public final class Gson {
|
||||
@SuppressWarnings("rawtypes")
|
||||
static final TypeMap EMPTY_MAP = new TypeMap().makeUnmodifiable();
|
||||
|
||||
static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
|
||||
static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
|
||||
|
||||
// Default instances of plug-ins
|
||||
static final AnonymousAndLocalClassExclusionStrategy DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY =
|
||||
@ -133,8 +131,6 @@ public final class Gson {
|
||||
};
|
||||
|
||||
private final List<TypeAdapter.Factory> factories;
|
||||
private final ExclusionStrategy deserializationExclusionStrategy;
|
||||
private final ExclusionStrategy serializationExclusionStrategy;
|
||||
private final ConstructorConstructor constructorConstructor;
|
||||
|
||||
/** Map containing Type or Class objects as keys */
|
||||
@ -215,8 +211,6 @@ public final class Gson {
|
||||
boolean prettyPrinting, boolean serializeSpecialFloatingPointValues,
|
||||
LongSerializationPolicy longSerializationPolicy,
|
||||
List<TypeAdapter.Factory> typeAdapterFactories) {
|
||||
this.deserializationExclusionStrategy = deserializationExclusionStrategy;
|
||||
this.serializationExclusionStrategy = serializationExclusionStrategy;
|
||||
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
|
||||
this.serializeNulls = serializeNulls;
|
||||
this.serializers = serializers;
|
||||
@ -225,27 +219,9 @@ public final class Gson {
|
||||
this.htmlSafe = htmlSafe;
|
||||
this.prettyPrinting = prettyPrinting;
|
||||
|
||||
TypeAdapter.Factory reflectiveTypeAdapterFactory
|
||||
= new ReflectiveTypeAdapterFactory(constructorConstructor) {
|
||||
@Override
|
||||
public String getFieldName(Class<?> declaringClazz, Field f, Type declaredType) {
|
||||
SerializedName serializedName = f.getAnnotation(SerializedName.class);
|
||||
return serializedName == null ? fieldNamingPolicy.translateName(f) : serializedName.value();
|
||||
}
|
||||
@Override
|
||||
public boolean serializeField(Class<?> declaringClazz, Field f, Type declaredType) {
|
||||
ExclusionStrategy strategy = Gson.this.serializationExclusionStrategy;
|
||||
return !strategy.shouldSkipClass(f.getType())
|
||||
&& !strategy.shouldSkipField(new FieldAttributes(declaringClazz, f));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deserializeField(Class<?> declaringClazz, Field f, Type declaredType) {
|
||||
ExclusionStrategy strategy = Gson.this.deserializationExclusionStrategy;
|
||||
return !strategy.shouldSkipClass(f.getType())
|
||||
&& !strategy.shouldSkipField(new FieldAttributes(declaringClazz, f));
|
||||
}
|
||||
};
|
||||
TypeAdapter.Factory reflectiveTypeAdapterFactory = new ReflectiveTypeAdapterFactory(
|
||||
constructorConstructor, fieldNamingPolicy, serializationExclusionStrategy,
|
||||
deserializationExclusionStrategy);
|
||||
|
||||
ConstructorConstructor constructorConstructor = new ConstructorConstructor();
|
||||
List<TypeAdapter.Factory> factories = new ArrayList<TypeAdapter.Factory>();
|
||||
|
@ -16,9 +16,13 @@
|
||||
|
||||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.ExclusionStrategy;
|
||||
import com.google.gson.FieldAttributes;
|
||||
import com.google.gson.FieldNamingStrategy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.internal.$Gson$Types;
|
||||
import com.google.gson.internal.ConstructorConstructor;
|
||||
import com.google.gson.internal.ObjectConstructor;
|
||||
@ -37,23 +41,34 @@ import java.util.Map;
|
||||
/**
|
||||
* Type adapter that reflects over the fields and methods of a class.
|
||||
*/
|
||||
public class ReflectiveTypeAdapterFactory implements TypeAdapter.Factory {
|
||||
public final class ReflectiveTypeAdapterFactory implements TypeAdapter.Factory {
|
||||
private final ConstructorConstructor constructorConstructor;
|
||||
private final FieldNamingStrategy fieldNamingPolicy;
|
||||
private final ExclusionStrategy serializationExclusionStrategy;
|
||||
private final ExclusionStrategy deserializationExclusionStrategy;
|
||||
|
||||
public ReflectiveTypeAdapterFactory(ConstructorConstructor constructorConstructor) {
|
||||
public ReflectiveTypeAdapterFactory(ConstructorConstructor constructorConstructor,
|
||||
FieldNamingStrategy fieldNamingPolicy, ExclusionStrategy serializationExclusionStrategy,
|
||||
ExclusionStrategy deserializationExclusionStrategy) {
|
||||
this.constructorConstructor = constructorConstructor;
|
||||
this.fieldNamingPolicy = fieldNamingPolicy;
|
||||
this.serializationExclusionStrategy = serializationExclusionStrategy;
|
||||
this.deserializationExclusionStrategy = deserializationExclusionStrategy;
|
||||
}
|
||||
|
||||
protected boolean serializeField(Class<?> declaringClazz, Field f, Type declaredType) {
|
||||
return !f.isSynthetic();
|
||||
public boolean serializeField(Field f) {
|
||||
return !serializationExclusionStrategy.shouldSkipClass(f.getType())
|
||||
&& !serializationExclusionStrategy.shouldSkipField(new FieldAttributes(f));
|
||||
}
|
||||
|
||||
protected boolean deserializeField(Class<?> declaringClazz, Field f, Type declaredType) {
|
||||
return !f.isSynthetic();
|
||||
private boolean deserializeField(Field f) {
|
||||
return !deserializationExclusionStrategy.shouldSkipClass(f.getType())
|
||||
&& !deserializationExclusionStrategy.shouldSkipField(new FieldAttributes(f));
|
||||
}
|
||||
|
||||
protected String getFieldName(Class<?> declaringClazz, Field f, Type declaredType) {
|
||||
return f.getName();
|
||||
private String getFieldName(Field f) {
|
||||
SerializedName serializedName = f.getAnnotation(SerializedName.class);
|
||||
return serializedName == null ? fieldNamingPolicy.translateName(f) : serializedName.value();
|
||||
}
|
||||
|
||||
public <T> TypeAdapter<T> create(Gson context, final TypeToken<T> type) {
|
||||
@ -93,8 +108,7 @@ public class ReflectiveTypeAdapterFactory implements TypeAdapter.Factory {
|
||||
};
|
||||
}
|
||||
|
||||
private Map<String, BoundField> getBoundFields(
|
||||
Gson context, TypeToken<?> type, Class<?> raw) {
|
||||
private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {
|
||||
Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
|
||||
if (raw.isInterface()) {
|
||||
return result;
|
||||
@ -105,13 +119,13 @@ public class ReflectiveTypeAdapterFactory implements TypeAdapter.Factory {
|
||||
Field[] fields = raw.getDeclaredFields();
|
||||
AccessibleObject.setAccessible(fields, true);
|
||||
for (Field field : fields) {
|
||||
boolean serialize = serializeField(raw, field, declaredType);
|
||||
boolean deserialize = deserializeField(raw, field, declaredType);
|
||||
boolean serialize = serializeField(field);
|
||||
boolean deserialize = deserializeField(field);
|
||||
if (!serialize && !deserialize) {
|
||||
continue;
|
||||
}
|
||||
Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
|
||||
BoundField boundField = createBoundField(context, field, getFieldName(raw, field, declaredType),
|
||||
BoundField boundField = createBoundField(context, field, getFieldName(field),
|
||||
TypeToken.get(fieldType), serialize, deserialize);
|
||||
BoundField previous = result.put(boundField.name, boundField);
|
||||
if (previous != null) {
|
||||
|
@ -28,14 +28,14 @@ import java.util.List;
|
||||
*/
|
||||
public class DisjunctionExclusionStrategyTest extends TestCase {
|
||||
|
||||
private static final ExclusionStrategy FALSE_STRATEGY =
|
||||
private static final ExclusionStrategy FALSE_STRATEGY =
|
||||
new MockExclusionStrategy(false, false);
|
||||
private static final ExclusionStrategy TRUE_STRATEGY =
|
||||
private static final ExclusionStrategy TRUE_STRATEGY =
|
||||
new MockExclusionStrategy(true, true);
|
||||
|
||||
|
||||
private static final Class<?> CLAZZ = String.class;
|
||||
private static final FieldAttributes FIELD =
|
||||
new FieldAttributes(CLAZZ, CLAZZ.getFields()[0]);
|
||||
new FieldAttributes(CLAZZ.getFields()[0]);
|
||||
|
||||
public void testBadInstantiation() throws Exception {
|
||||
try {
|
||||
|
@ -66,18 +66,18 @@ public class ExposeAnnotationExclusionStrategyTest extends TestCase {
|
||||
assertFalse(deserializationStrategy.shouldSkipField(f));
|
||||
assertFalse(serializationStrategy.shouldSkipField(f));
|
||||
}
|
||||
|
||||
|
||||
public void testDifferentSerializeAndDeserializeField() throws Exception {
|
||||
FieldAttributes f = createFieldAttributes("explicitlyDifferentModeField");
|
||||
assertTrue(deserializationStrategy.shouldSkipField(f));
|
||||
assertFalse(serializationStrategy.shouldSkipField(f));
|
||||
}
|
||||
|
||||
|
||||
private static FieldAttributes createFieldAttributes(String fieldName) throws Exception {
|
||||
Field f = MockObject.class.getField(fieldName);
|
||||
return new FieldAttributes(MockObject.class, f);
|
||||
return new FieldAttributes(f);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class MockObject {
|
||||
@Expose
|
||||
@ -88,7 +88,7 @@ public class ExposeAnnotationExclusionStrategyTest extends TestCase {
|
||||
|
||||
@Expose(serialize=false, deserialize=false)
|
||||
public final int explicitlyHiddenField = 0;
|
||||
|
||||
|
||||
@Expose(serialize=true, deserialize=false)
|
||||
public final int explicitlyDifferentModeField = 0;
|
||||
|
||||
|
@ -36,12 +36,12 @@ public class FieldAttributesTest extends TestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
fieldAttributes = new FieldAttributes(Foo.class, Foo.class.getField("bar"));
|
||||
fieldAttributes = new FieldAttributes(Foo.class.getField("bar"));
|
||||
}
|
||||
|
||||
public void testNullField() throws Exception {
|
||||
try {
|
||||
new FieldAttributes(Foo.class, null);
|
||||
new FieldAttributes(null);
|
||||
fail("Field parameter can not be null");
|
||||
} catch (NullPointerException expected) { }
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public class InnerClassExclusionStrategyTest extends TestCase {
|
||||
|
||||
public void testExcludeInnerClassField() throws Exception {
|
||||
Field f = getClass().getField("innerClass");
|
||||
assertTrue(strategy.shouldSkipField(new FieldAttributes(getClass(), f)));
|
||||
assertTrue(strategy.shouldSkipField(new FieldAttributes(f)));
|
||||
}
|
||||
|
||||
public void testIncludeStaticNestedClassObject() throws Exception {
|
||||
@ -56,7 +56,7 @@ public class InnerClassExclusionStrategyTest extends TestCase {
|
||||
|
||||
public void testIncludeStaticNestedClassField() throws Exception {
|
||||
Field f = getClass().getField("staticNestedClass");
|
||||
assertFalse(strategy.shouldSkipField(new FieldAttributes(getClass(), f)));
|
||||
assertFalse(strategy.shouldSkipField(new FieldAttributes(f)));
|
||||
}
|
||||
|
||||
class InnerClass {
|
||||
|
@ -43,7 +43,7 @@ public class VersionExclusionStrategyTest extends TestCase {
|
||||
VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION);
|
||||
assertFalse(strategy.shouldSkipClass(clazz));
|
||||
|
||||
FieldAttributes fieldAttributes = new FieldAttributes(clazz, f);
|
||||
FieldAttributes fieldAttributes = new FieldAttributes(f);
|
||||
assertFalse(strategy.shouldSkipField(fieldAttributes));
|
||||
}
|
||||
|
||||
@ -52,8 +52,8 @@ public class VersionExclusionStrategyTest extends TestCase {
|
||||
Field f = clazz.getField("someField");
|
||||
VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION + 1);
|
||||
assertFalse(strategy.shouldSkipClass(clazz));
|
||||
|
||||
FieldAttributes fieldAttributes = new FieldAttributes(clazz, f);
|
||||
|
||||
FieldAttributes fieldAttributes = new FieldAttributes(f);
|
||||
assertFalse(strategy.shouldSkipField(fieldAttributes));
|
||||
}
|
||||
|
||||
@ -62,8 +62,8 @@ public class VersionExclusionStrategyTest extends TestCase {
|
||||
Field f = clazz.getField("someField");
|
||||
VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION - 1);
|
||||
assertTrue(strategy.shouldSkipClass(clazz));
|
||||
|
||||
FieldAttributes fieldAttributes = new FieldAttributes(clazz, f);
|
||||
|
||||
FieldAttributes fieldAttributes = new FieldAttributes(f);
|
||||
assertTrue(strategy.shouldSkipField(fieldAttributes));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user