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
|
* @param f the field to pull attributes from
|
||||||
*/
|
*/
|
||||||
FieldAttributes(Class<?> declaringClazz, Field f) {
|
public FieldAttributes(Field f) {
|
||||||
this.declaringClazz = $Gson$Preconditions.checkNotNull(declaringClazz);
|
this.declaringClazz = f.getDeclaringClass();
|
||||||
this.name = f.getName();
|
this.name = f.getName();
|
||||||
this.declaredType = f.getType();
|
this.declaredType = f.getType();
|
||||||
this.isSynthetic = f.isSynthetic();
|
this.isSynthetic = f.isSynthetic();
|
||||||
@ -200,14 +200,6 @@ public final class FieldAttributes {
|
|||||||
return isSynthetic;
|
return isSynthetic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated remove this when {@link FieldNamingStrategy} is deleted.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
Field getFieldObject() {
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private static <T extends Annotation> T getAnnotationFromArray(
|
private static <T extends Annotation> T getAnnotationFromArray(
|
||||||
Collection<Annotation> annotations, Class<T> annotation) {
|
Collection<Annotation> annotations, Class<T> annotation) {
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
import com.google.gson.internal.ConstructorConstructor;
|
import com.google.gson.internal.ConstructorConstructor;
|
||||||
import com.google.gson.internal.Primitives;
|
import com.google.gson.internal.Primitives;
|
||||||
import com.google.gson.internal.Streams;
|
import com.google.gson.internal.Streams;
|
||||||
@ -46,7 +45,6 @@ import java.io.Reader;
|
|||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@ -104,7 +102,7 @@ public final class Gson {
|
|||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
static final TypeMap EMPTY_MAP = new TypeMap().makeUnmodifiable();
|
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
|
// Default instances of plug-ins
|
||||||
static final AnonymousAndLocalClassExclusionStrategy DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY =
|
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 List<TypeAdapter.Factory> factories;
|
||||||
private final ExclusionStrategy deserializationExclusionStrategy;
|
|
||||||
private final ExclusionStrategy serializationExclusionStrategy;
|
|
||||||
private final ConstructorConstructor constructorConstructor;
|
private final ConstructorConstructor constructorConstructor;
|
||||||
|
|
||||||
/** Map containing Type or Class objects as keys */
|
/** Map containing Type or Class objects as keys */
|
||||||
@ -215,8 +211,6 @@ public final class Gson {
|
|||||||
boolean prettyPrinting, boolean serializeSpecialFloatingPointValues,
|
boolean prettyPrinting, boolean serializeSpecialFloatingPointValues,
|
||||||
LongSerializationPolicy longSerializationPolicy,
|
LongSerializationPolicy longSerializationPolicy,
|
||||||
List<TypeAdapter.Factory> typeAdapterFactories) {
|
List<TypeAdapter.Factory> typeAdapterFactories) {
|
||||||
this.deserializationExclusionStrategy = deserializationExclusionStrategy;
|
|
||||||
this.serializationExclusionStrategy = serializationExclusionStrategy;
|
|
||||||
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
|
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
|
||||||
this.serializeNulls = serializeNulls;
|
this.serializeNulls = serializeNulls;
|
||||||
this.serializers = serializers;
|
this.serializers = serializers;
|
||||||
@ -225,27 +219,9 @@ public final class Gson {
|
|||||||
this.htmlSafe = htmlSafe;
|
this.htmlSafe = htmlSafe;
|
||||||
this.prettyPrinting = prettyPrinting;
|
this.prettyPrinting = prettyPrinting;
|
||||||
|
|
||||||
TypeAdapter.Factory reflectiveTypeAdapterFactory
|
TypeAdapter.Factory reflectiveTypeAdapterFactory = new ReflectiveTypeAdapterFactory(
|
||||||
= new ReflectiveTypeAdapterFactory(constructorConstructor) {
|
constructorConstructor, fieldNamingPolicy, serializationExclusionStrategy,
|
||||||
@Override
|
deserializationExclusionStrategy);
|
||||||
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));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ConstructorConstructor constructorConstructor = new ConstructorConstructor();
|
ConstructorConstructor constructorConstructor = new ConstructorConstructor();
|
||||||
List<TypeAdapter.Factory> factories = new ArrayList<TypeAdapter.Factory>();
|
List<TypeAdapter.Factory> factories = new ArrayList<TypeAdapter.Factory>();
|
||||||
|
@ -16,9 +16,13 @@
|
|||||||
|
|
||||||
package com.google.gson.internal.bind;
|
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.Gson;
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
import com.google.gson.TypeAdapter;
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
import com.google.gson.internal.$Gson$Types;
|
import com.google.gson.internal.$Gson$Types;
|
||||||
import com.google.gson.internal.ConstructorConstructor;
|
import com.google.gson.internal.ConstructorConstructor;
|
||||||
import com.google.gson.internal.ObjectConstructor;
|
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.
|
* 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 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.constructorConstructor = constructorConstructor;
|
||||||
|
this.fieldNamingPolicy = fieldNamingPolicy;
|
||||||
|
this.serializationExclusionStrategy = serializationExclusionStrategy;
|
||||||
|
this.deserializationExclusionStrategy = deserializationExclusionStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean serializeField(Class<?> declaringClazz, Field f, Type declaredType) {
|
public boolean serializeField(Field f) {
|
||||||
return !f.isSynthetic();
|
return !serializationExclusionStrategy.shouldSkipClass(f.getType())
|
||||||
|
&& !serializationExclusionStrategy.shouldSkipField(new FieldAttributes(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean deserializeField(Class<?> declaringClazz, Field f, Type declaredType) {
|
private boolean deserializeField(Field f) {
|
||||||
return !f.isSynthetic();
|
return !deserializationExclusionStrategy.shouldSkipClass(f.getType())
|
||||||
|
&& !deserializationExclusionStrategy.shouldSkipField(new FieldAttributes(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getFieldName(Class<?> declaringClazz, Field f, Type declaredType) {
|
private String getFieldName(Field f) {
|
||||||
return f.getName();
|
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) {
|
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(
|
private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {
|
||||||
Gson context, TypeToken<?> type, Class<?> raw) {
|
|
||||||
Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
|
Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
|
||||||
if (raw.isInterface()) {
|
if (raw.isInterface()) {
|
||||||
return result;
|
return result;
|
||||||
@ -105,13 +119,13 @@ public class ReflectiveTypeAdapterFactory implements TypeAdapter.Factory {
|
|||||||
Field[] fields = raw.getDeclaredFields();
|
Field[] fields = raw.getDeclaredFields();
|
||||||
AccessibleObject.setAccessible(fields, true);
|
AccessibleObject.setAccessible(fields, true);
|
||||||
for (Field field : fields) {
|
for (Field field : fields) {
|
||||||
boolean serialize = serializeField(raw, field, declaredType);
|
boolean serialize = serializeField(field);
|
||||||
boolean deserialize = deserializeField(raw, field, declaredType);
|
boolean deserialize = deserializeField(field);
|
||||||
if (!serialize && !deserialize) {
|
if (!serialize && !deserialize) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
|
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);
|
TypeToken.get(fieldType), serialize, deserialize);
|
||||||
BoundField previous = result.put(boundField.name, boundField);
|
BoundField previous = result.put(boundField.name, boundField);
|
||||||
if (previous != null) {
|
if (previous != null) {
|
||||||
|
@ -35,7 +35,7 @@ public class DisjunctionExclusionStrategyTest extends TestCase {
|
|||||||
|
|
||||||
private static final Class<?> CLAZZ = String.class;
|
private static final Class<?> CLAZZ = String.class;
|
||||||
private static final FieldAttributes FIELD =
|
private static final FieldAttributes FIELD =
|
||||||
new FieldAttributes(CLAZZ, CLAZZ.getFields()[0]);
|
new FieldAttributes(CLAZZ.getFields()[0]);
|
||||||
|
|
||||||
public void testBadInstantiation() throws Exception {
|
public void testBadInstantiation() throws Exception {
|
||||||
try {
|
try {
|
||||||
|
@ -75,7 +75,7 @@ public class ExposeAnnotationExclusionStrategyTest extends TestCase {
|
|||||||
|
|
||||||
private static FieldAttributes createFieldAttributes(String fieldName) throws Exception {
|
private static FieldAttributes createFieldAttributes(String fieldName) throws Exception {
|
||||||
Field f = MockObject.class.getField(fieldName);
|
Field f = MockObject.class.getField(fieldName);
|
||||||
return new FieldAttributes(MockObject.class, f);
|
return new FieldAttributes(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -36,12 +36,12 @@ public class FieldAttributesTest extends TestCase {
|
|||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
fieldAttributes = new FieldAttributes(Foo.class, Foo.class.getField("bar"));
|
fieldAttributes = new FieldAttributes(Foo.class.getField("bar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNullField() throws Exception {
|
public void testNullField() throws Exception {
|
||||||
try {
|
try {
|
||||||
new FieldAttributes(Foo.class, null);
|
new FieldAttributes(null);
|
||||||
fail("Field parameter can not be null");
|
fail("Field parameter can not be null");
|
||||||
} catch (NullPointerException expected) { }
|
} catch (NullPointerException expected) { }
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public class InnerClassExclusionStrategyTest extends TestCase {
|
|||||||
|
|
||||||
public void testExcludeInnerClassField() throws Exception {
|
public void testExcludeInnerClassField() throws Exception {
|
||||||
Field f = getClass().getField("innerClass");
|
Field f = getClass().getField("innerClass");
|
||||||
assertTrue(strategy.shouldSkipField(new FieldAttributes(getClass(), f)));
|
assertTrue(strategy.shouldSkipField(new FieldAttributes(f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIncludeStaticNestedClassObject() throws Exception {
|
public void testIncludeStaticNestedClassObject() throws Exception {
|
||||||
@ -56,7 +56,7 @@ public class InnerClassExclusionStrategyTest extends TestCase {
|
|||||||
|
|
||||||
public void testIncludeStaticNestedClassField() throws Exception {
|
public void testIncludeStaticNestedClassField() throws Exception {
|
||||||
Field f = getClass().getField("staticNestedClass");
|
Field f = getClass().getField("staticNestedClass");
|
||||||
assertFalse(strategy.shouldSkipField(new FieldAttributes(getClass(), f)));
|
assertFalse(strategy.shouldSkipField(new FieldAttributes(f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
class InnerClass {
|
class InnerClass {
|
||||||
|
@ -43,7 +43,7 @@ public class VersionExclusionStrategyTest extends TestCase {
|
|||||||
VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION);
|
VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION);
|
||||||
assertFalse(strategy.shouldSkipClass(clazz));
|
assertFalse(strategy.shouldSkipClass(clazz));
|
||||||
|
|
||||||
FieldAttributes fieldAttributes = new FieldAttributes(clazz, f);
|
FieldAttributes fieldAttributes = new FieldAttributes(f);
|
||||||
assertFalse(strategy.shouldSkipField(fieldAttributes));
|
assertFalse(strategy.shouldSkipField(fieldAttributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ public class VersionExclusionStrategyTest extends TestCase {
|
|||||||
VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION + 1);
|
VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION + 1);
|
||||||
assertFalse(strategy.shouldSkipClass(clazz));
|
assertFalse(strategy.shouldSkipClass(clazz));
|
||||||
|
|
||||||
FieldAttributes fieldAttributes = new FieldAttributes(clazz, f);
|
FieldAttributes fieldAttributes = new FieldAttributes(f);
|
||||||
assertFalse(strategy.shouldSkipField(fieldAttributes));
|
assertFalse(strategy.shouldSkipField(fieldAttributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ public class VersionExclusionStrategyTest extends TestCase {
|
|||||||
VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION - 1);
|
VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION - 1);
|
||||||
assertTrue(strategy.shouldSkipClass(clazz));
|
assertTrue(strategy.shouldSkipClass(clazz));
|
||||||
|
|
||||||
FieldAttributes fieldAttributes = new FieldAttributes(clazz, f);
|
FieldAttributes fieldAttributes = new FieldAttributes(f);
|
||||||
assertTrue(strategy.shouldSkipField(fieldAttributes));
|
assertTrue(strategy.shouldSkipField(fieldAttributes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user