Update to GSON 2.3.1

This commit is contained in:
Olof Larsson 2015-05-12 11:38:19 +02:00
parent 30f2460838
commit 057b827db0
5 changed files with 51 additions and 36 deletions

View File

@ -16,6 +16,21 @@
package com.massivecraft.massivecore.xlib.gson;
import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.massivecraft.massivecore.xlib.gson.internal.ConstructorConstructor;
import com.massivecraft.massivecore.xlib.gson.internal.Excluder;
import com.massivecraft.massivecore.xlib.gson.internal.Primitives;
@ -38,21 +53,6 @@ import com.massivecraft.massivecore.xlib.gson.stream.JsonToken;
import com.massivecraft.massivecore.xlib.gson.stream.JsonWriter;
import com.massivecraft.massivecore.xlib.gson.stream.MalformedJsonException;
import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This is the main class for using Gson. Gson is typically used by first constructing a
* Gson instance and then invoking {@link #toJson(Object)} or {@link #fromJson(String, Class)}
@ -233,13 +233,13 @@ public final class Gson {
factories.add(SqlDateTypeAdapter.FACTORY);
factories.add(TypeAdapters.TIMESTAMP_FACTORY);
factories.add(ArrayTypeAdapter.FACTORY);
factories.add(TypeAdapters.ENUM_FACTORY);
factories.add(TypeAdapters.CLASS_FACTORY);
// type adapters for composite and user-defined types
factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
factories.add(new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor));
factories.add(TypeAdapters.ENUM_FACTORY);
factories.add(new ReflectiveTypeAdapterFactory(
constructorConstructor, fieldNamingPolicy, excluder));
@ -411,7 +411,7 @@ public final class Gson {
* }</pre>
* Note that since you can not override type adapter factories for String and Java primitive
* types, our stats factory will not count the number of String or primitives that will be
* read or written.
* read or written.
* @param skipPast The type adapter factory that needs to be skipped while searching for
* a matching type adapter. In most cases, you should just pass <i>this</i> (the type adapter
* factory from where {@link #getDelegateAdapter} method is being invoked).
@ -421,6 +421,10 @@ public final class Gson {
*/
public <T> TypeAdapter<T> getDelegateAdapter(TypeAdapterFactory skipPast, TypeToken<T> type) {
boolean skipPastFound = false;
// Skip past if and only if the specified factory is present in the factories.
// This is useful because the factories created through JsonAdapter annotations are not
// registered in this list.
if (!factories.contains(skipPast)) skipPastFound = true;
for (TypeAdapterFactory factory : factories) {
if (!skipPastFound) {

View File

@ -37,7 +37,7 @@ public final class JsonAdapterAnnotationTypeAdapterFactory implements TypeAdapte
this.constructorConstructor = constructorConstructor;
}
@SuppressWarnings({"unchecked"})
@SuppressWarnings("unchecked")
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> targetType) {
JsonAdapter annotation = targetType.getRawType().getAnnotation(JsonAdapter.class);
if (annotation == null) {

View File

@ -57,10 +57,18 @@ public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory {
}
public boolean excludeField(Field f, boolean serialize) {
return excludeField(f, serialize, excluder);
}
static boolean excludeField(Field f, boolean serialize, Excluder excluder) {
return !excluder.excludeClass(f.getType(), serialize) && !excluder.excludeField(f, serialize);
}
private String getFieldName(Field f) {
return getFieldName(fieldNamingPolicy, f);
}
static String getFieldName(FieldNamingStrategy fieldNamingPolicy, Field f) {
SerializedName serializedName = f.getAnnotation(SerializedName.class);
return serializedName == null ? fieldNamingPolicy.translateName(f) : serializedName.value();
}
@ -98,6 +106,11 @@ public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory {
field.set(value, fieldValue);
}
}
public boolean writeField(Object value) throws IOException, IllegalAccessException {
if (!serialized) return false;
Object fieldValue = field.get(value);
return fieldValue != value; // avoid recursion for example for Throwable.cause
}
};
}
@ -151,7 +164,7 @@ public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory {
this.serialized = serialized;
this.deserialized = deserialized;
}
abstract boolean writeField(Object value) throws IOException, IllegalAccessException;
abstract void write(JsonWriter writer, Object value) throws IOException, IllegalAccessException;
abstract void read(JsonReader reader, Object value) throws IOException, IllegalAccessException;
}
@ -202,7 +215,7 @@ public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory {
out.beginObject();
try {
for (BoundField boundField : boundFields.values()) {
if (boundField.serialized) {
if (boundField.writeField(value)) {
out.name(boundField.name);
boundField.write(out, value);
}

View File

@ -746,23 +746,19 @@ public final class TypeAdapters {
}
}
public static final TypeAdapterFactory ENUM_FACTORY = newEnumTypeHierarchyFactory();
public static TypeAdapterFactory newEnumTypeHierarchyFactory() {
return new TypeAdapterFactory() {
@SuppressWarnings({"rawtypes", "unchecked"})
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Class<? super T> rawType = typeToken.getRawType();
if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class) {
return null;
}
if (!rawType.isEnum()) {
rawType = rawType.getSuperclass(); // handle anonymous subclasses
}
return (TypeAdapter<T>) new EnumTypeAdapter(rawType);
public static final TypeAdapterFactory ENUM_FACTORY = new TypeAdapterFactory() {
@SuppressWarnings({"rawtypes", "unchecked"})
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Class<? super T> rawType = typeToken.getRawType();
if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class) {
return null;
}
};
}
if (!rawType.isEnum()) {
rawType = rawType.getSuperclass(); // handle anonymous subclasses
}
return (TypeAdapter<T>) new EnumTypeAdapter(rawType);
}
};
public static <TT> TypeAdapterFactory newFactory(
final TypeToken<TT> type, final TypeAdapter<TT> typeAdapter) {

View File

@ -364,6 +364,7 @@ public class JsonReader implements Closeable {
}
if (p == PEEKED_END_ARRAY) {
stackSize--;
pathIndices[stackSize - 1]++;
peeked = PEEKED_NONE;
} else {
throw new IllegalStateException("Expected END_ARRAY but was " + peek()
@ -401,6 +402,7 @@ public class JsonReader implements Closeable {
if (p == PEEKED_END_OBJECT) {
stackSize--;
pathNames[stackSize] = null; // Free the last path name so that it can be garbage collected!
pathIndices[stackSize - 1]++;
peeked = PEEKED_NONE;
} else {
throw new IllegalStateException("Expected END_OBJECT but was " + peek()