first commit
This commit is contained in:
commit
4d332ef662
27586 changed files with 3281783 additions and 0 deletions
|
|
@ -0,0 +1,73 @@
|
|||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
final class DefaultDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
|
||||
private final DateFormat enUsFormat;
|
||||
|
||||
private final DateFormat localFormat;
|
||||
|
||||
private final DateFormat iso8601Format;
|
||||
|
||||
DefaultDateTypeAdapter() {
|
||||
this(DateFormat.getDateTimeInstance(2, 2, Locale.US), DateFormat.getDateTimeInstance(2, 2));
|
||||
}
|
||||
|
||||
DefaultDateTypeAdapter(String datePattern) {
|
||||
this(new SimpleDateFormat(datePattern, Locale.US), new SimpleDateFormat(datePattern));
|
||||
}
|
||||
|
||||
DefaultDateTypeAdapter(int style) {
|
||||
this(DateFormat.getDateInstance(style, Locale.US), DateFormat.getDateInstance(style));
|
||||
}
|
||||
|
||||
public DefaultDateTypeAdapter(int dateStyle, int timeStyle) {
|
||||
this(DateFormat.getDateTimeInstance(dateStyle, timeStyle, Locale.US), DateFormat.getDateTimeInstance(dateStyle, timeStyle));
|
||||
}
|
||||
|
||||
DefaultDateTypeAdapter(DateFormat enUsFormat, DateFormat localFormat) {
|
||||
this.enUsFormat = enUsFormat;
|
||||
this.localFormat = localFormat;
|
||||
this.iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
|
||||
this.iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
}
|
||||
|
||||
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
synchronized (this.localFormat) {
|
||||
String dateFormatAsString = this.enUsFormat.format(src);
|
||||
return new JsonPrimitive(dateFormatAsString);
|
||||
}
|
||||
}
|
||||
|
||||
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
if (!(json instanceof JsonPrimitive))
|
||||
throw new JsonParseException("The date should be a string value");
|
||||
Date date = deserializeToDate(json);
|
||||
if (typeOfT == Date.class)
|
||||
return date;
|
||||
if (typeOfT == Timestamp.class)
|
||||
return new Timestamp(date.getTime());
|
||||
if (typeOfT == java.sql.Date.class)
|
||||
return new java.sql.Date(date.getTime());
|
||||
throw new IllegalArgumentException(getClass() + " cannot deserialize to " + typeOfT);
|
||||
}
|
||||
|
||||
private Date deserializeToDate(JsonElement json) {
|
||||
synchronized (this.localFormat) {
|
||||
return this.localFormat.parse(json.getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(DefaultDateTypeAdapter.class.getSimpleName());
|
||||
sb.append('(').append(this.localFormat.getClass().getSimpleName()).append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.google.gson;
|
||||
|
||||
public interface ExclusionStrategy {
|
||||
boolean shouldSkipField(FieldAttributes paramFieldAttributes);
|
||||
|
||||
boolean shouldSkipClass(Class<?> paramClass);
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.google.gson;
|
||||
|
||||
import com.google.gson.internal.$Gson$Preconditions;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
public final class FieldAttributes {
|
||||
private final Field field;
|
||||
|
||||
public FieldAttributes(Field f) {
|
||||
$Gson$Preconditions.<Field>checkNotNull(f);
|
||||
this.field = f;
|
||||
}
|
||||
|
||||
public Class<?> getDeclaringClass() {
|
||||
return this.field.getDeclaringClass();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.field.getName();
|
||||
}
|
||||
|
||||
public Type getDeclaredType() {
|
||||
return this.field.getGenericType();
|
||||
}
|
||||
|
||||
public Class<?> getDeclaredClass() {
|
||||
return this.field.getType();
|
||||
}
|
||||
|
||||
public <T extends Annotation> T getAnnotation(Class<T> annotation) {
|
||||
return this.field.<T>getAnnotation(annotation);
|
||||
}
|
||||
|
||||
public Collection<Annotation> getAnnotations() {
|
||||
return Arrays.<Annotation>asList(this.field.getAnnotations());
|
||||
}
|
||||
|
||||
public boolean hasModifier(int modifier) {
|
||||
return ((this.field.getModifiers() & modifier) != 0);
|
||||
}
|
||||
|
||||
Object get(Object instance) throws IllegalAccessException {
|
||||
return this.field.get(instance);
|
||||
}
|
||||
|
||||
boolean isSynthetic() {
|
||||
return this.field.isSynthetic();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public enum FieldNamingPolicy implements FieldNamingStrategy {
|
||||
IDENTITY {
|
||||
public String translateName(Field f) {
|
||||
return f.getName();
|
||||
}
|
||||
},
|
||||
UPPER_CAMEL_CASE {
|
||||
public String translateName(Field f) {
|
||||
return upperCaseFirstLetter(f.getName());
|
||||
}
|
||||
},
|
||||
UPPER_CAMEL_CASE_WITH_SPACES {
|
||||
public String translateName(Field f) {
|
||||
return upperCaseFirstLetter(separateCamelCase(f.getName(), " "));
|
||||
}
|
||||
},
|
||||
LOWER_CASE_WITH_UNDERSCORES {
|
||||
public String translateName(Field f) {
|
||||
return separateCamelCase(f.getName(), "_").toLowerCase();
|
||||
}
|
||||
},
|
||||
LOWER_CASE_WITH_DASHES {
|
||||
public String translateName(Field f) {
|
||||
return separateCamelCase(f.getName(), "-").toLowerCase();
|
||||
}
|
||||
};
|
||||
|
||||
private static String separateCamelCase(String name, String separator) {
|
||||
StringBuilder translation = new StringBuilder();
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
char character = name.charAt(i);
|
||||
if (Character.isUpperCase(character) && translation.length() != 0)
|
||||
translation.append(separator);
|
||||
translation.append(character);
|
||||
}
|
||||
return translation.toString();
|
||||
}
|
||||
|
||||
private static String upperCaseFirstLetter(String name) {
|
||||
StringBuilder fieldNameBuilder = new StringBuilder();
|
||||
int index = 0;
|
||||
char firstCharacter = name.charAt(index);
|
||||
while (index < name.length() - 1 &&
|
||||
!Character.isLetter(firstCharacter)) {
|
||||
fieldNameBuilder.append(firstCharacter);
|
||||
firstCharacter = name.charAt(++index);
|
||||
}
|
||||
if (index == name.length())
|
||||
return fieldNameBuilder.toString();
|
||||
if (!Character.isUpperCase(firstCharacter)) {
|
||||
String modifiedTarget = modifyString(Character.toUpperCase(firstCharacter), name, ++index);
|
||||
return fieldNameBuilder.append(modifiedTarget).toString();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private static String modifyString(char firstCharacter, String srcString, int indexOfSubstring) {
|
||||
return (indexOfSubstring < srcString.length()) ? (firstCharacter + srcString.substring(indexOfSubstring)) : String.valueOf(firstCharacter);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public interface FieldNamingStrategy {
|
||||
String translateName(Field paramField);
|
||||
}
|
||||
452
rus/WEB-INF/lib/gson-2.2.4_src/com/google/gson/Gson.java
Normal file
452
rus/WEB-INF/lib/gson-2.2.4_src/com/google/gson/Gson.java
Normal file
|
|
@ -0,0 +1,452 @@
|
|||
package com.google.gson;
|
||||
|
||||
import com.google.gson.internal.ConstructorConstructor;
|
||||
import com.google.gson.internal.Excluder;
|
||||
import com.google.gson.internal.Primitives;
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.internal.bind.ArrayTypeAdapter;
|
||||
import com.google.gson.internal.bind.CollectionTypeAdapterFactory;
|
||||
import com.google.gson.internal.bind.DateTypeAdapter;
|
||||
import com.google.gson.internal.bind.JsonTreeReader;
|
||||
import com.google.gson.internal.bind.JsonTreeWriter;
|
||||
import com.google.gson.internal.bind.MapTypeAdapterFactory;
|
||||
import com.google.gson.internal.bind.ObjectTypeAdapter;
|
||||
import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory;
|
||||
import com.google.gson.internal.bind.SqlDateTypeAdapter;
|
||||
import com.google.gson.internal.bind.TimeTypeAdapter;
|
||||
import com.google.gson.internal.bind.TypeAdapters;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import com.google.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;
|
||||
|
||||
public final class Gson {
|
||||
static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
|
||||
|
||||
private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";
|
||||
|
||||
private final ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>> calls = new ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>>();
|
||||
|
||||
private final Map<TypeToken<?>, TypeAdapter<?>> typeTokenCache = Collections.<TypeToken<?>, TypeAdapter<?>>synchronizedMap(new HashMap<TypeToken<?>, TypeAdapter<?>>());
|
||||
|
||||
private final List<TypeAdapterFactory> factories;
|
||||
|
||||
private final ConstructorConstructor constructorConstructor;
|
||||
|
||||
private final boolean serializeNulls;
|
||||
|
||||
private final boolean htmlSafe;
|
||||
|
||||
private final boolean generateNonExecutableJson;
|
||||
|
||||
private final boolean prettyPrinting;
|
||||
|
||||
final JsonDeserializationContext deserializationContext = new JsonDeserializationContext() {
|
||||
public <T> T deserialize(JsonElement json, Type typeOfT) throws JsonParseException {
|
||||
return Gson.this.<T>fromJson(json, typeOfT);
|
||||
}
|
||||
};
|
||||
|
||||
final JsonSerializationContext serializationContext = new JsonSerializationContext() {
|
||||
public JsonElement serialize(Object src) {
|
||||
return Gson.this.toJsonTree(src);
|
||||
}
|
||||
|
||||
public JsonElement serialize(Object src, Type typeOfSrc) {
|
||||
return Gson.this.toJsonTree(src, typeOfSrc);
|
||||
}
|
||||
};
|
||||
|
||||
public Gson() {
|
||||
this(Excluder.DEFAULT, FieldNamingPolicy.IDENTITY, Collections.<Type, InstanceCreator<?>>emptyMap(), false, false, false, true, false, false, LongSerializationPolicy.DEFAULT, Collections.<TypeAdapterFactory>emptyList());
|
||||
}
|
||||
|
||||
Gson(Excluder excluder, FieldNamingStrategy fieldNamingPolicy, Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls, boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting, boolean serializeSpecialFloatingPointValues, LongSerializationPolicy longSerializationPolicy, List<TypeAdapterFactory> typeAdapterFactories) {
|
||||
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
|
||||
this.serializeNulls = serializeNulls;
|
||||
this.generateNonExecutableJson = generateNonExecutableGson;
|
||||
this.htmlSafe = htmlSafe;
|
||||
this.prettyPrinting = prettyPrinting;
|
||||
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
|
||||
factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
|
||||
factories.add(ObjectTypeAdapter.FACTORY);
|
||||
factories.add(excluder);
|
||||
factories.addAll(typeAdapterFactories);
|
||||
factories.add(TypeAdapters.STRING_FACTORY);
|
||||
factories.add(TypeAdapters.INTEGER_FACTORY);
|
||||
factories.add(TypeAdapters.BOOLEAN_FACTORY);
|
||||
factories.add(TypeAdapters.BYTE_FACTORY);
|
||||
factories.add(TypeAdapters.SHORT_FACTORY);
|
||||
factories.add(TypeAdapters.<long>newFactory(long.class, (Class)Long.class, longAdapter(longSerializationPolicy)));
|
||||
factories.add(TypeAdapters.<double>newFactory(double.class, (Class)Double.class, doubleAdapter(serializeSpecialFloatingPointValues)));
|
||||
factories.add(TypeAdapters.<float>newFactory(float.class, (Class)Float.class, floatAdapter(serializeSpecialFloatingPointValues)));
|
||||
factories.add(TypeAdapters.NUMBER_FACTORY);
|
||||
factories.add(TypeAdapters.CHARACTER_FACTORY);
|
||||
factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
|
||||
factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
|
||||
factories.add(TypeAdapters.<BigDecimal>newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));
|
||||
factories.add(TypeAdapters.<BigInteger>newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));
|
||||
factories.add(TypeAdapters.URL_FACTORY);
|
||||
factories.add(TypeAdapters.URI_FACTORY);
|
||||
factories.add(TypeAdapters.UUID_FACTORY);
|
||||
factories.add(TypeAdapters.LOCALE_FACTORY);
|
||||
factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
|
||||
factories.add(TypeAdapters.BIT_SET_FACTORY);
|
||||
factories.add(DateTypeAdapter.FACTORY);
|
||||
factories.add(TypeAdapters.CALENDAR_FACTORY);
|
||||
factories.add(TimeTypeAdapter.FACTORY);
|
||||
factories.add(SqlDateTypeAdapter.FACTORY);
|
||||
factories.add(TypeAdapters.TIMESTAMP_FACTORY);
|
||||
factories.add(ArrayTypeAdapter.FACTORY);
|
||||
factories.add(TypeAdapters.ENUM_FACTORY);
|
||||
factories.add(TypeAdapters.CLASS_FACTORY);
|
||||
factories.add(new CollectionTypeAdapterFactory(this.constructorConstructor));
|
||||
factories.add(new MapTypeAdapterFactory(this.constructorConstructor, complexMapKeySerialization));
|
||||
factories.add(new ReflectiveTypeAdapterFactory(this.constructorConstructor, fieldNamingPolicy, excluder));
|
||||
this.factories = Collections.<TypeAdapterFactory>unmodifiableList(factories);
|
||||
}
|
||||
|
||||
private TypeAdapter<Number> doubleAdapter(boolean serializeSpecialFloatingPointValues) {
|
||||
if (serializeSpecialFloatingPointValues)
|
||||
return TypeAdapters.DOUBLE;
|
||||
return new TypeAdapter<Number>() {
|
||||
public Double read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
return in.nextDouble();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Number value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
double doubleValue = value.doubleValue();
|
||||
Gson.this.checkValidFloatingPoint(doubleValue);
|
||||
out.value(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private TypeAdapter<Number> floatAdapter(boolean serializeSpecialFloatingPointValues) {
|
||||
if (serializeSpecialFloatingPointValues)
|
||||
return TypeAdapters.FLOAT;
|
||||
return new TypeAdapter<Number>() {
|
||||
public Float read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
return (float)in.nextDouble();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Number value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
float floatValue = value.floatValue();
|
||||
Gson.this.checkValidFloatingPoint((double)floatValue);
|
||||
out.value(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void checkValidFloatingPoint(double value) {
|
||||
if (Double.isNaN(value) || Double.isInfinite(value))
|
||||
throw new IllegalArgumentException(value + " is not a valid double value as per JSON specification. To override this" + " behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method.");
|
||||
}
|
||||
|
||||
private TypeAdapter<Number> longAdapter(LongSerializationPolicy longSerializationPolicy) {
|
||||
if (longSerializationPolicy == LongSerializationPolicy.DEFAULT)
|
||||
return TypeAdapters.LONG;
|
||||
return new TypeAdapter<Number>() {
|
||||
public Number read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
return in.nextLong();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Number value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
out.value(value.toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
|
||||
TypeAdapter<?> cached = this.typeTokenCache.get(type);
|
||||
if (cached != null)
|
||||
return (TypeAdapter<T>)cached;
|
||||
Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = this.calls.get();
|
||||
boolean requiresThreadLocalCleanup = false;
|
||||
if (threadCalls == null) {
|
||||
threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
|
||||
this.calls.set(threadCalls);
|
||||
requiresThreadLocalCleanup = true;
|
||||
}
|
||||
FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>)threadCalls.get(type);
|
||||
if (ongoingCall != null)
|
||||
return ongoingCall;
|
||||
try {
|
||||
FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
|
||||
threadCalls.put(type, call);
|
||||
for (TypeAdapterFactory factory : this.factories) {
|
||||
TypeAdapter<T> candidate = factory.<T>create(this, type);
|
||||
if (candidate != null) {
|
||||
call.setDelegate(candidate);
|
||||
this.typeTokenCache.put(type, candidate);
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("GSON cannot handle " + type);
|
||||
} finally {
|
||||
threadCalls.remove(type);
|
||||
if (requiresThreadLocalCleanup)
|
||||
this.calls.remove();
|
||||
}
|
||||
}
|
||||
|
||||
public <T> TypeAdapter<T> getDelegateAdapter(TypeAdapterFactory skipPast, TypeToken<T> type) {
|
||||
boolean skipPastFound = false;
|
||||
for (TypeAdapterFactory factory : this.factories) {
|
||||
if (!skipPastFound) {
|
||||
if (factory == skipPast)
|
||||
skipPastFound = true;
|
||||
continue;
|
||||
}
|
||||
TypeAdapter<T> candidate = factory.<T>create(this, type);
|
||||
if (candidate != null)
|
||||
return candidate;
|
||||
}
|
||||
throw new IllegalArgumentException("GSON cannot serialize " + type);
|
||||
}
|
||||
|
||||
public <T> TypeAdapter<T> getAdapter(Class<T> type) {
|
||||
return getAdapter(TypeToken.<T>get(type));
|
||||
}
|
||||
|
||||
public JsonElement toJsonTree(Object src) {
|
||||
if (src == null)
|
||||
return JsonNull.INSTANCE;
|
||||
return toJsonTree(src, src.getClass());
|
||||
}
|
||||
|
||||
public JsonElement toJsonTree(Object src, Type typeOfSrc) {
|
||||
JsonTreeWriter writer = new JsonTreeWriter();
|
||||
toJson(src, typeOfSrc, writer);
|
||||
return writer.get();
|
||||
}
|
||||
|
||||
public String toJson(Object src) {
|
||||
if (src == null)
|
||||
return toJson((JsonElement)JsonNull.INSTANCE);
|
||||
return toJson(src, src.getClass());
|
||||
}
|
||||
|
||||
public String toJson(Object src, Type typeOfSrc) {
|
||||
StringWriter writer = new StringWriter();
|
||||
toJson(src, typeOfSrc, writer);
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
public void toJson(Object src, Appendable writer) throws JsonIOException {
|
||||
if (src != null) {
|
||||
toJson(src, src.getClass(), writer);
|
||||
} else {
|
||||
toJson((JsonElement)JsonNull.INSTANCE, writer);
|
||||
}
|
||||
}
|
||||
|
||||
public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOException {
|
||||
try {
|
||||
JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer));
|
||||
toJson(src, typeOfSrc, jsonWriter);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
|
||||
TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
|
||||
boolean oldLenient = writer.isLenient();
|
||||
writer.setLenient(true);
|
||||
boolean oldHtmlSafe = writer.isHtmlSafe();
|
||||
writer.setHtmlSafe(this.htmlSafe);
|
||||
boolean oldSerializeNulls = writer.getSerializeNulls();
|
||||
writer.setSerializeNulls(this.serializeNulls);
|
||||
try {
|
||||
adapter.write(writer, src);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
} finally {
|
||||
writer.setLenient(oldLenient);
|
||||
writer.setHtmlSafe(oldHtmlSafe);
|
||||
writer.setSerializeNulls(oldSerializeNulls);
|
||||
}
|
||||
}
|
||||
|
||||
public String toJson(JsonElement jsonElement) {
|
||||
StringWriter writer = new StringWriter();
|
||||
toJson(jsonElement, (Appendable)writer);
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
public void toJson(JsonElement jsonElement, Appendable writer) throws JsonIOException {
|
||||
try {
|
||||
JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer));
|
||||
toJson(jsonElement, jsonWriter);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private JsonWriter newJsonWriter(Writer writer) throws IOException {
|
||||
if (this.generateNonExecutableJson)
|
||||
writer.write(")]}'\n");
|
||||
JsonWriter jsonWriter = new JsonWriter(writer);
|
||||
if (this.prettyPrinting)
|
||||
jsonWriter.setIndent(" ");
|
||||
jsonWriter.setSerializeNulls(this.serializeNulls);
|
||||
return jsonWriter;
|
||||
}
|
||||
|
||||
public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOException {
|
||||
boolean oldLenient = writer.isLenient();
|
||||
writer.setLenient(true);
|
||||
boolean oldHtmlSafe = writer.isHtmlSafe();
|
||||
writer.setHtmlSafe(this.htmlSafe);
|
||||
boolean oldSerializeNulls = writer.getSerializeNulls();
|
||||
writer.setSerializeNulls(this.serializeNulls);
|
||||
try {
|
||||
Streams.write(jsonElement, writer);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
} finally {
|
||||
writer.setLenient(oldLenient);
|
||||
writer.setHtmlSafe(oldHtmlSafe);
|
||||
writer.setSerializeNulls(oldSerializeNulls);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
|
||||
Object object = fromJson(json, (Type)classOfT);
|
||||
return Primitives.<T>wrap(classOfT).cast(object);
|
||||
}
|
||||
|
||||
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
|
||||
if (json == null)
|
||||
return null;
|
||||
StringReader reader = new StringReader(json);
|
||||
T target = fromJson(reader, typeOfT);
|
||||
return target;
|
||||
}
|
||||
|
||||
public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException {
|
||||
JsonReader jsonReader = new JsonReader(json);
|
||||
Object object = fromJson(jsonReader, classOfT);
|
||||
assertFullConsumption(object, jsonReader);
|
||||
return Primitives.<T>wrap(classOfT).cast(object);
|
||||
}
|
||||
|
||||
public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
|
||||
JsonReader jsonReader = new JsonReader(json);
|
||||
T object = fromJson(jsonReader, typeOfT);
|
||||
assertFullConsumption(object, jsonReader);
|
||||
return object;
|
||||
}
|
||||
|
||||
private static void assertFullConsumption(Object obj, JsonReader reader) {
|
||||
try {
|
||||
if (obj != null && reader.peek() != JsonToken.END_DOCUMENT)
|
||||
throw new JsonIOException("JSON document was not fully consumed.");
|
||||
} catch (MalformedJsonException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
|
||||
boolean isEmpty = true;
|
||||
boolean oldLenient = reader.isLenient();
|
||||
reader.setLenient(true);
|
||||
try {
|
||||
reader.peek();
|
||||
isEmpty = false;
|
||||
TypeToken<T> typeToken = (TypeToken<T>)TypeToken.get(typeOfT);
|
||||
TypeAdapter<T> typeAdapter = getAdapter(typeToken);
|
||||
T object = typeAdapter.read(reader);
|
||||
return object;
|
||||
} catch (EOFException e) {
|
||||
if (isEmpty)
|
||||
return null;
|
||||
throw new JsonSyntaxException(e);
|
||||
} catch (IllegalStateException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
} catch (IOException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
} finally {
|
||||
reader.setLenient(oldLenient);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException {
|
||||
Object object = fromJson(json, (Type)classOfT);
|
||||
return Primitives.<T>wrap(classOfT).cast(object);
|
||||
}
|
||||
|
||||
public <T> T fromJson(JsonElement json, Type typeOfT) throws JsonSyntaxException {
|
||||
if (json == null)
|
||||
return null;
|
||||
return fromJson(new JsonTreeReader(json), typeOfT);
|
||||
}
|
||||
|
||||
static class FutureTypeAdapter<T> extends TypeAdapter<T> {
|
||||
private TypeAdapter<T> delegate;
|
||||
|
||||
public void setDelegate(TypeAdapter<T> typeAdapter) {
|
||||
if (this.delegate != null)
|
||||
throw new AssertionError();
|
||||
this.delegate = typeAdapter;
|
||||
}
|
||||
|
||||
public T read(JsonReader in) throws IOException {
|
||||
if (this.delegate == null)
|
||||
throw new IllegalStateException();
|
||||
return this.delegate.read(in);
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, T value) throws IOException {
|
||||
if (this.delegate == null)
|
||||
throw new IllegalStateException();
|
||||
this.delegate.write(out, value);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "{serializeNulls:" + this.serializeNulls + "factories:" + this.factories + ",instanceCreators:" + this.constructorConstructor + "}";
|
||||
}
|
||||
}
|
||||
195
rus/WEB-INF/lib/gson-2.2.4_src/com/google/gson/GsonBuilder.java
Normal file
195
rus/WEB-INF/lib/gson-2.2.4_src/com/google/gson/GsonBuilder.java
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
package com.google.gson;
|
||||
|
||||
import com.google.gson.internal.$Gson$Preconditions;
|
||||
import com.google.gson.internal.Excluder;
|
||||
import com.google.gson.internal.bind.TypeAdapters;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class GsonBuilder {
|
||||
private Excluder excluder = Excluder.DEFAULT;
|
||||
|
||||
private LongSerializationPolicy longSerializationPolicy = LongSerializationPolicy.DEFAULT;
|
||||
|
||||
private FieldNamingStrategy fieldNamingPolicy = FieldNamingPolicy.IDENTITY;
|
||||
|
||||
private final Map<Type, InstanceCreator<?>> instanceCreators = new HashMap<Type, InstanceCreator<?>>();
|
||||
|
||||
private final List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
|
||||
|
||||
private final List<TypeAdapterFactory> hierarchyFactories = new ArrayList<TypeAdapterFactory>();
|
||||
|
||||
private boolean serializeNulls;
|
||||
|
||||
private String datePattern;
|
||||
|
||||
private int dateStyle = 2;
|
||||
|
||||
private int timeStyle = 2;
|
||||
|
||||
private boolean complexMapKeySerialization;
|
||||
|
||||
private boolean serializeSpecialFloatingPointValues;
|
||||
|
||||
private boolean escapeHtmlChars = true;
|
||||
|
||||
private boolean prettyPrinting;
|
||||
|
||||
private boolean generateNonExecutableJson;
|
||||
|
||||
public GsonBuilder setVersion(double ignoreVersionsAfter) {
|
||||
this.excluder = this.excluder.withVersion(ignoreVersionsAfter);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder excludeFieldsWithModifiers(int... modifiers) {
|
||||
this.excluder = this.excluder.withModifiers(modifiers);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder generateNonExecutableJson() {
|
||||
this.generateNonExecutableJson = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder excludeFieldsWithoutExposeAnnotation() {
|
||||
this.excluder = this.excluder.excludeFieldsWithoutExposeAnnotation();
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder serializeNulls() {
|
||||
this.serializeNulls = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder enableComplexMapKeySerialization() {
|
||||
this.complexMapKeySerialization = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder disableInnerClassSerialization() {
|
||||
this.excluder = this.excluder.disableInnerClassSerialization();
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder setLongSerializationPolicy(LongSerializationPolicy serializationPolicy) {
|
||||
this.longSerializationPolicy = serializationPolicy;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder setFieldNamingPolicy(FieldNamingPolicy namingConvention) {
|
||||
this.fieldNamingPolicy = namingConvention;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) {
|
||||
this.fieldNamingPolicy = fieldNamingStrategy;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder setExclusionStrategies(ExclusionStrategy... strategies) {
|
||||
for (ExclusionStrategy strategy : strategies)
|
||||
this.excluder = this.excluder.withExclusionStrategy(strategy, true, true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder addSerializationExclusionStrategy(ExclusionStrategy strategy) {
|
||||
this.excluder = this.excluder.withExclusionStrategy(strategy, true, false);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder addDeserializationExclusionStrategy(ExclusionStrategy strategy) {
|
||||
this.excluder = this.excluder.withExclusionStrategy(strategy, false, true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder setPrettyPrinting() {
|
||||
this.prettyPrinting = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder disableHtmlEscaping() {
|
||||
this.escapeHtmlChars = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder setDateFormat(String pattern) {
|
||||
this.datePattern = pattern;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder setDateFormat(int style) {
|
||||
this.dateStyle = style;
|
||||
this.datePattern = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder setDateFormat(int dateStyle, int timeStyle) {
|
||||
this.dateStyle = dateStyle;
|
||||
this.timeStyle = timeStyle;
|
||||
this.datePattern = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
|
||||
$Gson$Preconditions.checkArgument((typeAdapter instanceof JsonSerializer || typeAdapter instanceof JsonDeserializer || typeAdapter instanceof InstanceCreator || typeAdapter instanceof TypeAdapter));
|
||||
if (typeAdapter instanceof InstanceCreator)
|
||||
this.instanceCreators.put(type, (InstanceCreator)typeAdapter);
|
||||
if (typeAdapter instanceof JsonSerializer || typeAdapter instanceof JsonDeserializer) {
|
||||
TypeToken<?> typeToken = TypeToken.get(type);
|
||||
this.factories.add(TreeTypeAdapter.newFactoryWithMatchRawType(typeToken, typeAdapter));
|
||||
}
|
||||
if (typeAdapter instanceof TypeAdapter)
|
||||
this.factories.add(TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter)typeAdapter));
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder registerTypeAdapterFactory(TypeAdapterFactory factory) {
|
||||
this.factories.add(factory);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
|
||||
$Gson$Preconditions.checkArgument((typeAdapter instanceof JsonSerializer || typeAdapter instanceof JsonDeserializer || typeAdapter instanceof TypeAdapter));
|
||||
if (typeAdapter instanceof JsonDeserializer || typeAdapter instanceof JsonSerializer)
|
||||
this.hierarchyFactories.add(0, TreeTypeAdapter.newTypeHierarchyFactory(baseType, typeAdapter));
|
||||
if (typeAdapter instanceof TypeAdapter)
|
||||
this.factories.add(TypeAdapters.newTypeHierarchyFactory(baseType, (TypeAdapter)typeAdapter));
|
||||
return this;
|
||||
}
|
||||
|
||||
public GsonBuilder serializeSpecialFloatingPointValues() {
|
||||
this.serializeSpecialFloatingPointValues = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Gson create() {
|
||||
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
|
||||
factories.addAll(this.factories);
|
||||
Collections.reverse(factories);
|
||||
factories.addAll(this.hierarchyFactories);
|
||||
addTypeAdaptersForDate(this.datePattern, this.dateStyle, this.timeStyle, factories);
|
||||
return new Gson(this.excluder, this.fieldNamingPolicy, this.instanceCreators, this.serializeNulls, this.complexMapKeySerialization, this.generateNonExecutableJson, this.escapeHtmlChars, this.prettyPrinting, this.serializeSpecialFloatingPointValues, this.longSerializationPolicy, factories);
|
||||
}
|
||||
|
||||
private void addTypeAdaptersForDate(String datePattern, int dateStyle, int timeStyle, List<TypeAdapterFactory> factories) {
|
||||
DefaultDateTypeAdapter dateTypeAdapter;
|
||||
if (datePattern != null && !"".equals(datePattern.trim())) {
|
||||
dateTypeAdapter = new DefaultDateTypeAdapter(datePattern);
|
||||
} else if (dateStyle != 2 && timeStyle != 2) {
|
||||
dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle, timeStyle);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
factories.add(TreeTypeAdapter.newFactory(TypeToken.<Date>get(Date.class), dateTypeAdapter));
|
||||
factories.add(TreeTypeAdapter.newFactory(TypeToken.<Timestamp>get(Timestamp.class), dateTypeAdapter));
|
||||
factories.add(TreeTypeAdapter.newFactory(TypeToken.<java.sql.Date>get(java.sql.Date.class), dateTypeAdapter));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public interface InstanceCreator<T> {
|
||||
T createInstance(Type paramType);
|
||||
}
|
||||
120
rus/WEB-INF/lib/gson-2.2.4_src/com/google/gson/JsonArray.java
Normal file
120
rus/WEB-INF/lib/gson-2.2.4_src/com/google/gson/JsonArray.java
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
package com.google.gson;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public final class JsonArray extends JsonElement implements Iterable<JsonElement> {
|
||||
private final List<JsonElement> elements = new ArrayList<JsonElement>();
|
||||
|
||||
JsonArray deepCopy() {
|
||||
JsonArray result = new JsonArray();
|
||||
for (JsonElement element : this.elements)
|
||||
result.add(element.deepCopy());
|
||||
return result;
|
||||
}
|
||||
|
||||
public void add(JsonElement element) {
|
||||
if (element == null)
|
||||
element = JsonNull.INSTANCE;
|
||||
this.elements.add(element);
|
||||
}
|
||||
|
||||
public void addAll(JsonArray array) {
|
||||
this.elements.addAll(array.elements);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.elements.size();
|
||||
}
|
||||
|
||||
public Iterator<JsonElement> iterator() {
|
||||
return this.elements.iterator();
|
||||
}
|
||||
|
||||
public JsonElement get(int i) {
|
||||
return this.elements.get(i);
|
||||
}
|
||||
|
||||
public Number getAsNumber() {
|
||||
if (this.elements.size() == 1)
|
||||
return this.elements.get(0).getAsNumber();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public String getAsString() {
|
||||
if (this.elements.size() == 1)
|
||||
return this.elements.get(0).getAsString();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public double getAsDouble() {
|
||||
if (this.elements.size() == 1)
|
||||
return this.elements.get(0).getAsDouble();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public BigDecimal getAsBigDecimal() {
|
||||
if (this.elements.size() == 1)
|
||||
return this.elements.get(0).getAsBigDecimal();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public BigInteger getAsBigInteger() {
|
||||
if (this.elements.size() == 1)
|
||||
return this.elements.get(0).getAsBigInteger();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public float getAsFloat() {
|
||||
if (this.elements.size() == 1)
|
||||
return this.elements.get(0).getAsFloat();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public long getAsLong() {
|
||||
if (this.elements.size() == 1)
|
||||
return this.elements.get(0).getAsLong();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public int getAsInt() {
|
||||
if (this.elements.size() == 1)
|
||||
return this.elements.get(0).getAsInt();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public byte getAsByte() {
|
||||
if (this.elements.size() == 1)
|
||||
return this.elements.get(0).getAsByte();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public char getAsCharacter() {
|
||||
if (this.elements.size() == 1)
|
||||
return this.elements.get(0).getAsCharacter();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public short getAsShort() {
|
||||
if (this.elements.size() == 1)
|
||||
return this.elements.get(0).getAsShort();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public boolean getAsBoolean() {
|
||||
if (this.elements.size() == 1)
|
||||
return this.elements.get(0).getAsBoolean();
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o == this || (o instanceof JsonArray && ((JsonArray)o).elements.equals(this.elements)));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.elements.hashCode();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public interface JsonDeserializationContext {
|
||||
<T> T deserialize(JsonElement paramJsonElement, Type paramType) throws JsonParseException;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public interface JsonDeserializer<T> {
|
||||
T deserialize(JsonElement paramJsonElement, Type paramType, JsonDeserializationContext paramJsonDeserializationContext) throws JsonParseException;
|
||||
}
|
||||
116
rus/WEB-INF/lib/gson-2.2.4_src/com/google/gson/JsonElement.java
Normal file
116
rus/WEB-INF/lib/gson-2.2.4_src/com/google/gson/JsonElement.java
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
package com.google.gson;
|
||||
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public abstract class JsonElement {
|
||||
abstract JsonElement deepCopy();
|
||||
|
||||
public boolean isJsonArray() {
|
||||
return this instanceof JsonArray;
|
||||
}
|
||||
|
||||
public boolean isJsonObject() {
|
||||
return this instanceof JsonObject;
|
||||
}
|
||||
|
||||
public boolean isJsonPrimitive() {
|
||||
return this instanceof JsonPrimitive;
|
||||
}
|
||||
|
||||
public boolean isJsonNull() {
|
||||
return this instanceof JsonNull;
|
||||
}
|
||||
|
||||
public JsonObject getAsJsonObject() {
|
||||
if (isJsonObject())
|
||||
return (JsonObject)this;
|
||||
throw new IllegalStateException("Not a JSON Object: " + this);
|
||||
}
|
||||
|
||||
public JsonArray getAsJsonArray() {
|
||||
if (isJsonArray())
|
||||
return (JsonArray)this;
|
||||
throw new IllegalStateException("This is not a JSON Array.");
|
||||
}
|
||||
|
||||
public JsonPrimitive getAsJsonPrimitive() {
|
||||
if (isJsonPrimitive())
|
||||
return (JsonPrimitive)this;
|
||||
throw new IllegalStateException("This is not a JSON Primitive.");
|
||||
}
|
||||
|
||||
public JsonNull getAsJsonNull() {
|
||||
if (isJsonNull())
|
||||
return (JsonNull)this;
|
||||
throw new IllegalStateException("This is not a JSON Null.");
|
||||
}
|
||||
|
||||
public boolean getAsBoolean() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
Boolean getAsBooleanWrapper() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public Number getAsNumber() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public String getAsString() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public double getAsDouble() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public float getAsFloat() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public long getAsLong() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public int getAsInt() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public byte getAsByte() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public char getAsCharacter() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public BigDecimal getAsBigDecimal() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public BigInteger getAsBigInteger() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public short getAsShort() {
|
||||
throw new UnsupportedOperationException(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
try {
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
JsonWriter jsonWriter = new JsonWriter(stringWriter);
|
||||
jsonWriter.setLenient(true);
|
||||
Streams.write(this, jsonWriter);
|
||||
return stringWriter.toString();
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.google.gson;
|
||||
|
||||
public final class JsonIOException extends JsonParseException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public JsonIOException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public JsonIOException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
public JsonIOException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
17
rus/WEB-INF/lib/gson-2.2.4_src/com/google/gson/JsonNull.java
Normal file
17
rus/WEB-INF/lib/gson-2.2.4_src/com/google/gson/JsonNull.java
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package com.google.gson;
|
||||
|
||||
public final class JsonNull extends JsonElement {
|
||||
public static final JsonNull INSTANCE = new JsonNull();
|
||||
|
||||
JsonNull deepCopy() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return JsonNull.class.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
return (this == other || other instanceof JsonNull);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
package com.google.gson;
|
||||
|
||||
import com.google.gson.internal.LinkedTreeMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public final class JsonObject extends JsonElement {
|
||||
private final LinkedTreeMap<String, JsonElement> members = new LinkedTreeMap<String, JsonElement>();
|
||||
|
||||
JsonObject deepCopy() {
|
||||
JsonObject result = new JsonObject();
|
||||
for (Map.Entry<String, JsonElement> entry : this.members.entrySet())
|
||||
result.add(entry.getKey(), entry.getValue().deepCopy());
|
||||
return result;
|
||||
}
|
||||
|
||||
public void add(String property, JsonElement value) {
|
||||
if (value == null)
|
||||
value = JsonNull.INSTANCE;
|
||||
this.members.put(property, value);
|
||||
}
|
||||
|
||||
public JsonElement remove(String property) {
|
||||
return this.members.remove(property);
|
||||
}
|
||||
|
||||
public void addProperty(String property, String value) {
|
||||
add(property, createJsonElement(value));
|
||||
}
|
||||
|
||||
public void addProperty(String property, Number value) {
|
||||
add(property, createJsonElement(value));
|
||||
}
|
||||
|
||||
public void addProperty(String property, Boolean value) {
|
||||
add(property, createJsonElement(value));
|
||||
}
|
||||
|
||||
public void addProperty(String property, Character value) {
|
||||
add(property, createJsonElement(value));
|
||||
}
|
||||
|
||||
private JsonElement createJsonElement(Object value) {
|
||||
return (value == null) ? JsonNull.INSTANCE : new JsonPrimitive(value);
|
||||
}
|
||||
|
||||
public Set<Map.Entry<String, JsonElement>> entrySet() {
|
||||
return this.members.entrySet();
|
||||
}
|
||||
|
||||
public boolean has(String memberName) {
|
||||
return this.members.containsKey(memberName);
|
||||
}
|
||||
|
||||
public JsonElement get(String memberName) {
|
||||
return this.members.get(memberName);
|
||||
}
|
||||
|
||||
public JsonPrimitive getAsJsonPrimitive(String memberName) {
|
||||
return (JsonPrimitive)this.members.get(memberName);
|
||||
}
|
||||
|
||||
public JsonArray getAsJsonArray(String memberName) {
|
||||
return (JsonArray)this.members.get(memberName);
|
||||
}
|
||||
|
||||
public JsonObject getAsJsonObject(String memberName) {
|
||||
return (JsonObject)this.members.get(memberName);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o == this || (o instanceof JsonObject && ((JsonObject)o).members.equals(this.members)));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.members.hashCode();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.google.gson;
|
||||
|
||||
public class JsonParseException extends RuntimeException {
|
||||
static final long serialVersionUID = -4086729973971783390L;
|
||||
|
||||
public JsonParseException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public JsonParseException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
public JsonParseException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package com.google.gson;
|
||||
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.MalformedJsonException;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
public final class JsonParser {
|
||||
public JsonElement parse(String json) throws JsonSyntaxException {
|
||||
return parse(new StringReader(json));
|
||||
}
|
||||
|
||||
public JsonElement parse(Reader json) throws JsonIOException, JsonSyntaxException {
|
||||
try {
|
||||
JsonReader jsonReader = new JsonReader(json);
|
||||
JsonElement element = parse(jsonReader);
|
||||
if (!element.isJsonNull() && jsonReader.peek() != JsonToken.END_DOCUMENT)
|
||||
throw new JsonSyntaxException("Did not consume the entire document.");
|
||||
return element;
|
||||
} catch (MalformedJsonException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement parse(JsonReader json) throws JsonIOException, JsonSyntaxException {
|
||||
boolean lenient = json.isLenient();
|
||||
json.setLenient(true);
|
||||
try {
|
||||
return Streams.parse(json);
|
||||
} catch (StackOverflowError e) {
|
||||
throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", e);
|
||||
} finally {
|
||||
json.setLenient(lenient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
package com.google.gson;
|
||||
|
||||
import com.google.gson.internal.$Gson$Preconditions;
|
||||
import com.google.gson.internal.LazilyParsedNumber;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public final class JsonPrimitive extends JsonElement {
|
||||
private static final Class<?>[] PRIMITIVE_TYPES = new Class<?>[] {
|
||||
int.class, long.class, short.class, float.class, double.class, byte.class, boolean.class, char.class, Integer.class, Long.class,
|
||||
Short.class, Float.class, Double.class, Byte.class, Boolean.class, Character.class };
|
||||
|
||||
private Object value;
|
||||
|
||||
public JsonPrimitive(Boolean bool) {
|
||||
setValue(bool);
|
||||
}
|
||||
|
||||
public JsonPrimitive(Number number) {
|
||||
setValue(number);
|
||||
}
|
||||
|
||||
public JsonPrimitive(String string) {
|
||||
setValue(string);
|
||||
}
|
||||
|
||||
public JsonPrimitive(Character c) {
|
||||
setValue(c);
|
||||
}
|
||||
|
||||
JsonPrimitive(Object primitive) {
|
||||
setValue(primitive);
|
||||
}
|
||||
|
||||
JsonPrimitive deepCopy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
void setValue(Object primitive) {
|
||||
if (primitive instanceof Character) {
|
||||
char c = (Character)primitive;
|
||||
this.value = String.valueOf(c);
|
||||
} else {
|
||||
$Gson$Preconditions.checkArgument((primitive instanceof Number || isPrimitiveOrString(primitive)));
|
||||
this.value = primitive;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBoolean() {
|
||||
return this.value instanceof Boolean;
|
||||
}
|
||||
|
||||
Boolean getAsBooleanWrapper() {
|
||||
return (Boolean)this.value;
|
||||
}
|
||||
|
||||
public boolean getAsBoolean() {
|
||||
if (isBoolean())
|
||||
return getAsBooleanWrapper();
|
||||
return Boolean.parseBoolean(getAsString());
|
||||
}
|
||||
|
||||
public boolean isNumber() {
|
||||
return this.value instanceof Number;
|
||||
}
|
||||
|
||||
public Number getAsNumber() {
|
||||
return (this.value instanceof String) ? new LazilyParsedNumber((String)this.value) : (Number)this.value;
|
||||
}
|
||||
|
||||
public boolean isString() {
|
||||
return this.value instanceof String;
|
||||
}
|
||||
|
||||
public String getAsString() {
|
||||
if (isNumber())
|
||||
return getAsNumber().toString();
|
||||
if (isBoolean())
|
||||
return getAsBooleanWrapper().toString();
|
||||
return (String)this.value;
|
||||
}
|
||||
|
||||
public double getAsDouble() {
|
||||
return isNumber() ? getAsNumber().doubleValue() : Double.parseDouble(getAsString());
|
||||
}
|
||||
|
||||
public BigDecimal getAsBigDecimal() {
|
||||
return (this.value instanceof BigDecimal) ? (BigDecimal)this.value : new BigDecimal(this.value.toString());
|
||||
}
|
||||
|
||||
public BigInteger getAsBigInteger() {
|
||||
return (this.value instanceof BigInteger) ? (BigInteger)this.value : new BigInteger(this.value.toString());
|
||||
}
|
||||
|
||||
public float getAsFloat() {
|
||||
return isNumber() ? getAsNumber().floatValue() : Float.parseFloat(getAsString());
|
||||
}
|
||||
|
||||
public long getAsLong() {
|
||||
return isNumber() ? getAsNumber().longValue() : Long.parseLong(getAsString());
|
||||
}
|
||||
|
||||
public short getAsShort() {
|
||||
return isNumber() ? getAsNumber().shortValue() : Short.parseShort(getAsString());
|
||||
}
|
||||
|
||||
public int getAsInt() {
|
||||
return isNumber() ? getAsNumber().intValue() : Integer.parseInt(getAsString());
|
||||
}
|
||||
|
||||
public byte getAsByte() {
|
||||
return isNumber() ? getAsNumber().byteValue() : Byte.parseByte(getAsString());
|
||||
}
|
||||
|
||||
public char getAsCharacter() {
|
||||
return getAsString().charAt(0);
|
||||
}
|
||||
|
||||
private static boolean isPrimitiveOrString(Object target) {
|
||||
if (target instanceof String)
|
||||
return true;
|
||||
Class<?> classOfPrimitive = target.getClass();
|
||||
for (Class<?> standardPrimitive : PRIMITIVE_TYPES) {
|
||||
if (standardPrimitive.isAssignableFrom(classOfPrimitive))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
if (this.value == null)
|
||||
return 31;
|
||||
if (isIntegral(this)) {
|
||||
long value = getAsNumber().longValue();
|
||||
return (int)(value ^ value >>> 32L);
|
||||
}
|
||||
if (this.value instanceof Number) {
|
||||
long value = Double.doubleToLongBits(getAsNumber().doubleValue());
|
||||
return (int)(value ^ value >>> 32L);
|
||||
}
|
||||
return this.value.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
JsonPrimitive other = (JsonPrimitive)obj;
|
||||
if (this.value == null)
|
||||
return (other.value == null);
|
||||
if (isIntegral(this) && isIntegral(other))
|
||||
return (getAsNumber().longValue() == other.getAsNumber().longValue());
|
||||
if (this.value instanceof Number && other.value instanceof Number) {
|
||||
double a = getAsNumber().doubleValue();
|
||||
double b = other.getAsNumber().doubleValue();
|
||||
return (a == b || (Double.isNaN(a) && Double.isNaN(b)));
|
||||
}
|
||||
return this.value.equals(other.value);
|
||||
}
|
||||
|
||||
private static boolean isIntegral(JsonPrimitive primitive) {
|
||||
if (primitive.value instanceof Number) {
|
||||
Number number = (Number)primitive.value;
|
||||
return (number instanceof BigInteger || number instanceof Long || number instanceof Integer || number instanceof Short || number instanceof Byte);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public interface JsonSerializationContext {
|
||||
JsonElement serialize(Object paramObject);
|
||||
|
||||
JsonElement serialize(Object paramObject, Type paramType);
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public interface JsonSerializer<T> {
|
||||
JsonElement serialize(T paramT, Type paramType, JsonSerializationContext paramJsonSerializationContext);
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.google.gson;
|
||||
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public final class JsonStreamParser implements Iterator<JsonElement> {
|
||||
private final JsonReader parser;
|
||||
|
||||
private final Object lock;
|
||||
|
||||
public JsonStreamParser(String json) {
|
||||
this(new StringReader(json));
|
||||
}
|
||||
|
||||
public JsonStreamParser(Reader reader) {
|
||||
this.parser = new JsonReader(reader);
|
||||
this.parser.setLenient(true);
|
||||
this.lock = new Object();
|
||||
}
|
||||
|
||||
public JsonElement next() throws JsonParseException {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
try {
|
||||
return Streams.parse(this.parser);
|
||||
} catch (StackOverflowError e) {
|
||||
throw new JsonParseException("Failed parsing JSON source to Json", e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw new JsonParseException("Failed parsing JSON source to Json", e);
|
||||
} catch (JsonParseException e) {
|
||||
throw (e.getCause() instanceof java.io.EOFException) ? new NoSuchElementException() : e;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
synchronized (this.lock) {
|
||||
return (this.parser.peek() != JsonToken.END_DOCUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.google.gson;
|
||||
|
||||
public final class JsonSyntaxException extends JsonParseException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public JsonSyntaxException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public JsonSyntaxException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
public JsonSyntaxException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.google.gson;
|
||||
|
||||
public enum LongSerializationPolicy {
|
||||
DEFAULT {
|
||||
public JsonElement serialize(Long value) {
|
||||
return new JsonPrimitive(value);
|
||||
}
|
||||
},
|
||||
STRING {
|
||||
public JsonElement serialize(Long value) {
|
||||
return new JsonPrimitive(String.valueOf(value));
|
||||
}
|
||||
};
|
||||
|
||||
public abstract JsonElement serialize(Long paramLong);
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
package com.google.gson;
|
||||
|
||||
import com.google.gson.internal.$Gson$Preconditions;
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
final class TreeTypeAdapter<T> extends TypeAdapter<T> {
|
||||
private final JsonSerializer<T> serializer;
|
||||
|
||||
private final JsonDeserializer<T> deserializer;
|
||||
|
||||
private final Gson gson;
|
||||
|
||||
private final TypeToken<T> typeToken;
|
||||
|
||||
private final TypeAdapterFactory skipPast;
|
||||
|
||||
private TypeAdapter<T> delegate;
|
||||
|
||||
private TreeTypeAdapter(JsonSerializer<T> serializer, JsonDeserializer<T> deserializer, Gson gson, TypeToken<T> typeToken, TypeAdapterFactory skipPast) {
|
||||
this.serializer = serializer;
|
||||
this.deserializer = deserializer;
|
||||
this.gson = gson;
|
||||
this.typeToken = typeToken;
|
||||
this.skipPast = skipPast;
|
||||
}
|
||||
|
||||
public T read(JsonReader in) throws IOException {
|
||||
if (this.deserializer == null)
|
||||
return delegate().read(in);
|
||||
JsonElement value = Streams.parse(in);
|
||||
if (value.isJsonNull())
|
||||
return null;
|
||||
return this.deserializer.deserialize(value, this.typeToken.getType(), this.gson.deserializationContext);
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, T value) throws IOException {
|
||||
if (this.serializer == null) {
|
||||
delegate().write(out, value);
|
||||
return;
|
||||
}
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
JsonElement tree = this.serializer.serialize(value, this.typeToken.getType(), this.gson.serializationContext);
|
||||
Streams.write(tree, out);
|
||||
}
|
||||
|
||||
private TypeAdapter<T> delegate() {
|
||||
TypeAdapter<T> d = this.delegate;
|
||||
return (d != null) ? d : (this.delegate = this.gson.<T>getDelegateAdapter(this.skipPast, this.typeToken));
|
||||
}
|
||||
|
||||
public static TypeAdapterFactory newFactory(TypeToken<?> exactType, Object typeAdapter) {
|
||||
return new SingleTypeFactory(typeAdapter, exactType, false, null);
|
||||
}
|
||||
|
||||
public static TypeAdapterFactory newFactoryWithMatchRawType(TypeToken<?> exactType, Object typeAdapter) {
|
||||
boolean matchRawType = (exactType.getType() == exactType.getRawType());
|
||||
return new SingleTypeFactory(typeAdapter, exactType, matchRawType, null);
|
||||
}
|
||||
|
||||
public static TypeAdapterFactory newTypeHierarchyFactory(Class<?> hierarchyType, Object typeAdapter) {
|
||||
return new SingleTypeFactory(typeAdapter, null, false, hierarchyType);
|
||||
}
|
||||
|
||||
private static class SingleTypeFactory implements TypeAdapterFactory {
|
||||
private final TypeToken<?> exactType;
|
||||
|
||||
private final boolean matchRawType;
|
||||
|
||||
private final Class<?> hierarchyType;
|
||||
|
||||
private final JsonSerializer<?> serializer;
|
||||
|
||||
private final JsonDeserializer<?> deserializer;
|
||||
|
||||
private SingleTypeFactory(Object typeAdapter, TypeToken<?> exactType, boolean matchRawType, Class<?> hierarchyType) {
|
||||
this.serializer = (typeAdapter instanceof JsonSerializer) ? (JsonSerializer)typeAdapter : null;
|
||||
this.deserializer = (typeAdapter instanceof JsonDeserializer) ? (JsonDeserializer)typeAdapter : null;
|
||||
$Gson$Preconditions.checkArgument((this.serializer != null || this.deserializer != null));
|
||||
this.exactType = exactType;
|
||||
this.matchRawType = matchRawType;
|
||||
this.hierarchyType = hierarchyType;
|
||||
}
|
||||
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
|
||||
boolean matches = (this.exactType != null) ? ((this.exactType.equals(type) || (this.matchRawType && this.exactType.getType() == type.getRawType()))) : this.hierarchyType.isAssignableFrom(type.getRawType());
|
||||
return matches ? new TreeTypeAdapter<T>(this.serializer, this.deserializer, gson, type, this) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package com.google.gson;
|
||||
|
||||
import com.google.gson.internal.bind.JsonTreeReader;
|
||||
import com.google.gson.internal.bind.JsonTreeWriter;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
public abstract class TypeAdapter<T> {
|
||||
public abstract void write(JsonWriter paramJsonWriter, T paramT) throws IOException;
|
||||
|
||||
public final void toJson(Writer out, T value) throws IOException {
|
||||
JsonWriter writer = new JsonWriter(out);
|
||||
write(writer, value);
|
||||
}
|
||||
|
||||
public final TypeAdapter<T> nullSafe() {
|
||||
return new TypeAdapter<T>() {
|
||||
public void write(JsonWriter out, T value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
} else {
|
||||
TypeAdapter.this.write(out, value);
|
||||
}
|
||||
}
|
||||
|
||||
public T read(JsonReader reader) throws IOException {
|
||||
if (reader.peek() == JsonToken.NULL) {
|
||||
reader.nextNull();
|
||||
return null;
|
||||
}
|
||||
return TypeAdapter.this.read(reader);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public final String toJson(T value) throws IOException {
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
toJson(stringWriter, value);
|
||||
return stringWriter.toString();
|
||||
}
|
||||
|
||||
public final JsonElement toJsonTree(T value) {
|
||||
try {
|
||||
JsonTreeWriter jsonWriter = new JsonTreeWriter();
|
||||
write(jsonWriter, value);
|
||||
return jsonWriter.get();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract T read(JsonReader paramJsonReader) throws IOException;
|
||||
|
||||
public final T fromJson(Reader in) throws IOException {
|
||||
JsonReader reader = new JsonReader(in);
|
||||
return read(reader);
|
||||
}
|
||||
|
||||
public final T fromJson(String json) throws IOException {
|
||||
return fromJson(new StringReader(json));
|
||||
}
|
||||
|
||||
public final T fromJsonTree(JsonElement jsonTree) {
|
||||
try {
|
||||
JsonReader jsonReader = new JsonTreeReader(jsonTree);
|
||||
return read(jsonReader);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.google.gson;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
public interface TypeAdapterFactory {
|
||||
<T> TypeAdapter<T> create(Gson paramGson, TypeToken<T> paramTypeToken);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.google.gson.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface Expose {
|
||||
boolean serialize() default true;
|
||||
|
||||
boolean deserialize() default true;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.google.gson.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface SerializedName {
|
||||
String value();
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.google.gson.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD, ElementType.TYPE})
|
||||
public @interface Since {
|
||||
double value();
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.google.gson.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD, ElementType.TYPE})
|
||||
public @interface Until {
|
||||
double value();
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
package com.google.gson.internal;
|
||||
|
||||
import com.google.gson.InstanceCreator;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public final class ConstructorConstructor {
|
||||
private final Map<Type, InstanceCreator<?>> instanceCreators;
|
||||
|
||||
public ConstructorConstructor(Map<Type, InstanceCreator<?>> instanceCreators) {
|
||||
this.instanceCreators = instanceCreators;
|
||||
}
|
||||
|
||||
public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
|
||||
final Type type = typeToken.getType();
|
||||
Class<? super T> rawType = typeToken.getRawType();
|
||||
final InstanceCreator<T> typeCreator = (InstanceCreator<T>)this.instanceCreators.get(type);
|
||||
if (typeCreator != null)
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
return typeCreator.createInstance(type);
|
||||
}
|
||||
};
|
||||
final InstanceCreator<T> rawTypeCreator = (InstanceCreator<T>)this.instanceCreators.get(rawType);
|
||||
if (rawTypeCreator != null)
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
return rawTypeCreator.createInstance(type);
|
||||
}
|
||||
};
|
||||
ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType);
|
||||
if (defaultConstructor != null)
|
||||
return defaultConstructor;
|
||||
ObjectConstructor<T> defaultImplementation = newDefaultImplementationConstructor(type, rawType);
|
||||
if (defaultImplementation != null)
|
||||
return defaultImplementation;
|
||||
return newUnsafeAllocator(type, rawType);
|
||||
}
|
||||
|
||||
private <T> ObjectConstructor<T> newDefaultConstructor(Class<? super T> rawType) {
|
||||
try {
|
||||
final Constructor<? super T> constructor = rawType.getDeclaredConstructor();
|
||||
if (!constructor.isAccessible())
|
||||
constructor.setAccessible(true);
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
try {
|
||||
Object[] args = null;
|
||||
return constructor.newInstance(args);
|
||||
} catch (InstantiationException e) {
|
||||
throw new RuntimeException("Failed to invoke " + constructor + " with no args", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException("Failed to invoke " + constructor + " with no args", e.getTargetException());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private <T> ObjectConstructor<T> newDefaultImplementationConstructor(final Type type, Class<? super T> rawType) {
|
||||
if (Collection.class.isAssignableFrom(rawType)) {
|
||||
if (SortedSet.class.isAssignableFrom(rawType))
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
return (T)new TreeSet();
|
||||
}
|
||||
};
|
||||
if (EnumSet.class.isAssignableFrom(rawType))
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
if (type instanceof ParameterizedType) {
|
||||
Type elementType = ((ParameterizedType)type).getActualTypeArguments()[0];
|
||||
if (elementType instanceof Class)
|
||||
return (T)EnumSet.noneOf((Class<Enum>)elementType);
|
||||
throw new JsonIOException("Invalid EnumSet type: " + type.toString());
|
||||
}
|
||||
throw new JsonIOException("Invalid EnumSet type: " + type.toString());
|
||||
}
|
||||
};
|
||||
if (Set.class.isAssignableFrom(rawType))
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
return (T)new LinkedHashSet();
|
||||
}
|
||||
};
|
||||
if (Queue.class.isAssignableFrom(rawType))
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
return (T)new LinkedList();
|
||||
}
|
||||
};
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
return (T)new ArrayList();
|
||||
}
|
||||
};
|
||||
}
|
||||
if (Map.class.isAssignableFrom(rawType)) {
|
||||
if (SortedMap.class.isAssignableFrom(rawType))
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
return (T)new TreeMap();
|
||||
}
|
||||
};
|
||||
if (type instanceof ParameterizedType && !String.class.isAssignableFrom(TypeToken.get(((ParameterizedType)type).getActualTypeArguments()[0]).getRawType()))
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
return (T)new LinkedHashMap();
|
||||
}
|
||||
};
|
||||
return new ObjectConstructor<T>() {
|
||||
public T construct() {
|
||||
return (T)new LinkedTreeMap();
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private <T> ObjectConstructor<T> newUnsafeAllocator(final Type type, final Class<? super T> rawType) {
|
||||
return new ObjectConstructor<T>() {
|
||||
private final UnsafeAllocator unsafeAllocator;
|
||||
|
||||
{
|
||||
this.unsafeAllocator = UnsafeAllocator.create();
|
||||
}
|
||||
|
||||
public T construct() {
|
||||
try {
|
||||
Object newInstance = this.unsafeAllocator.newInstance(rawType);
|
||||
return (T)newInstance;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to invoke no-args constructor for " + type + ". " + "Register an InstanceCreator with Gson for this type may fix this problem.", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.instanceCreators.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
package com.google.gson.internal;
|
||||
|
||||
import com.google.gson.ExclusionStrategy;
|
||||
import com.google.gson.FieldAttributes;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.Since;
|
||||
import com.google.gson.annotations.Until;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class Excluder implements TypeAdapterFactory, Cloneable {
|
||||
private static final double IGNORE_VERSIONS = -1.0D;
|
||||
|
||||
public static final Excluder DEFAULT = new Excluder();
|
||||
|
||||
private double version = -1.0D;
|
||||
|
||||
private int modifiers = 136;
|
||||
|
||||
private boolean serializeInnerClasses = true;
|
||||
|
||||
private boolean requireExpose;
|
||||
|
||||
private List<ExclusionStrategy> serializationStrategies = Collections.<ExclusionStrategy>emptyList();
|
||||
|
||||
private List<ExclusionStrategy> deserializationStrategies = Collections.<ExclusionStrategy>emptyList();
|
||||
|
||||
protected Excluder clone() {
|
||||
try {
|
||||
return (Excluder)super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
public Excluder withVersion(double ignoreVersionsAfter) {
|
||||
Excluder result = clone();
|
||||
result.version = ignoreVersionsAfter;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Excluder withModifiers(int... modifiers) {
|
||||
Excluder result = clone();
|
||||
result.modifiers = 0;
|
||||
for (int modifier : modifiers)
|
||||
result.modifiers |= modifier;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Excluder disableInnerClassSerialization() {
|
||||
Excluder result = clone();
|
||||
result.serializeInnerClasses = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Excluder excludeFieldsWithoutExposeAnnotation() {
|
||||
Excluder result = clone();
|
||||
result.requireExpose = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Excluder withExclusionStrategy(ExclusionStrategy exclusionStrategy, boolean serialization, boolean deserialization) {
|
||||
Excluder result = clone();
|
||||
if (serialization) {
|
||||
result.serializationStrategies = new ArrayList<ExclusionStrategy>(this.serializationStrategies);
|
||||
result.serializationStrategies.add(exclusionStrategy);
|
||||
}
|
||||
if (deserialization) {
|
||||
result.deserializationStrategies = new ArrayList<ExclusionStrategy>(this.deserializationStrategies);
|
||||
result.deserializationStrategies.add(exclusionStrategy);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
|
||||
Class<?> rawType = type.getRawType();
|
||||
final boolean skipSerialize = excludeClass(rawType, true);
|
||||
final boolean skipDeserialize = excludeClass(rawType, false);
|
||||
if (!skipSerialize && !skipDeserialize)
|
||||
return null;
|
||||
return new TypeAdapter<T>() {
|
||||
private TypeAdapter<T> delegate;
|
||||
|
||||
public T read(JsonReader in) throws IOException {
|
||||
if (skipDeserialize) {
|
||||
in.skipValue();
|
||||
return null;
|
||||
}
|
||||
return delegate().read(in);
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, T value) throws IOException {
|
||||
if (skipSerialize) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
delegate().write(out, value);
|
||||
}
|
||||
|
||||
private TypeAdapter<T> delegate() {
|
||||
TypeAdapter<T> d = this.delegate;
|
||||
return (d != null) ? d : (this.delegate = gson.<T>getDelegateAdapter(Excluder.this, type));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean excludeField(Field field, boolean serialize) {
|
||||
if ((this.modifiers & field.getModifiers()) != 0)
|
||||
return true;
|
||||
if (this.version != -1.0D && !isValidVersion(field.<Since>getAnnotation(Since.class), field.<Until>getAnnotation(Until.class)))
|
||||
return true;
|
||||
if (field.isSynthetic())
|
||||
return true;
|
||||
if (this.requireExpose) {
|
||||
Expose annotation = field.<Expose>getAnnotation(Expose.class);
|
||||
if (annotation == null || (serialize ? !annotation.serialize() : !annotation.deserialize()))
|
||||
return true;
|
||||
}
|
||||
if (!this.serializeInnerClasses && isInnerClass(field.getType()))
|
||||
return true;
|
||||
if (isAnonymousOrLocal(field.getType()))
|
||||
return true;
|
||||
List<ExclusionStrategy> list = serialize ? this.serializationStrategies : this.deserializationStrategies;
|
||||
if (!list.isEmpty()) {
|
||||
FieldAttributes fieldAttributes = new FieldAttributes(field);
|
||||
for (ExclusionStrategy exclusionStrategy : list) {
|
||||
if (exclusionStrategy.shouldSkipField(fieldAttributes))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean excludeClass(Class<?> clazz, boolean serialize) {
|
||||
if (this.version != -1.0D && !isValidVersion(clazz.<Since>getAnnotation(Since.class), clazz.<Until>getAnnotation(Until.class)))
|
||||
return true;
|
||||
if (!this.serializeInnerClasses && isInnerClass(clazz))
|
||||
return true;
|
||||
if (isAnonymousOrLocal(clazz))
|
||||
return true;
|
||||
List<ExclusionStrategy> list = serialize ? this.serializationStrategies : this.deserializationStrategies;
|
||||
for (ExclusionStrategy exclusionStrategy : list) {
|
||||
if (exclusionStrategy.shouldSkipClass(clazz))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isAnonymousOrLocal(Class<?> clazz) {
|
||||
return (!Enum.class.isAssignableFrom(clazz) && (clazz.isAnonymousClass() || clazz.isLocalClass()));
|
||||
}
|
||||
|
||||
private boolean isInnerClass(Class<?> clazz) {
|
||||
return (clazz.isMemberClass() && !isStatic(clazz));
|
||||
}
|
||||
|
||||
private boolean isStatic(Class<?> clazz) {
|
||||
return ((clazz.getModifiers() & 0x8) != 0);
|
||||
}
|
||||
|
||||
private boolean isValidVersion(Since since, Until until) {
|
||||
return (isValidSince(since) && isValidUntil(until));
|
||||
}
|
||||
|
||||
private boolean isValidSince(Since annotation) {
|
||||
if (annotation != null) {
|
||||
double annotationVersion = annotation.value();
|
||||
if (annotationVersion > this.version)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isValidUntil(Until annotation) {
|
||||
if (annotation != null) {
|
||||
double annotationVersion = annotation.value();
|
||||
if (annotationVersion <= this.version)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.google.gson.internal;
|
||||
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class JsonReaderInternalAccess {
|
||||
public static JsonReaderInternalAccess INSTANCE;
|
||||
|
||||
public abstract void promoteNameToValue(JsonReader paramJsonReader) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package com.google.gson.internal;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public final class LazilyParsedNumber extends Number {
|
||||
private final String value;
|
||||
|
||||
public LazilyParsedNumber(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int intValue() {
|
||||
try {
|
||||
return Integer.parseInt(this.value);
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
return (int)Long.parseLong(this.value);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return new BigDecimal(this.value).intValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
try {
|
||||
return Long.parseLong(this.value);
|
||||
} catch (NumberFormatException e) {
|
||||
return new BigDecimal(this.value).longValue();
|
||||
}
|
||||
}
|
||||
|
||||
public float floatValue() {
|
||||
return Float.parseFloat(this.value);
|
||||
}
|
||||
|
||||
public double doubleValue() {
|
||||
return Double.parseDouble(this.value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private Object writeReplace() throws ObjectStreamException {
|
||||
return new BigDecimal(this.value);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,471 @@
|
|||
package com.google.gson.internal;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Comparator;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
public final class LinkedTreeMap<K, V> extends AbstractMap<K, V> implements Serializable {
|
||||
private static final Comparator<Comparable> NATURAL_ORDER = new Comparator<Comparable>() {
|
||||
public int compare(Comparable a, Comparable b) {
|
||||
return a.compareTo(b);
|
||||
}
|
||||
};
|
||||
|
||||
Comparator<? super K> comparator;
|
||||
|
||||
Node<K, V> root;
|
||||
|
||||
int size = 0;
|
||||
|
||||
int modCount = 0;
|
||||
|
||||
final Node<K, V> header = new Node<K, V>();
|
||||
|
||||
private EntrySet entrySet;
|
||||
|
||||
private KeySet keySet;
|
||||
|
||||
public LinkedTreeMap() {
|
||||
this(NATURAL_ORDER);
|
||||
}
|
||||
|
||||
public LinkedTreeMap(Comparator<? super K> comparator) {
|
||||
this.comparator = (comparator != null) ? comparator : NATURAL_ORDER;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public V get(Object key) {
|
||||
Node<K, V> node = findByObject(key);
|
||||
return (node != null) ? node.value : null;
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
return (findByObject(key) != null);
|
||||
}
|
||||
|
||||
public V put(K key, V value) {
|
||||
if (key == null)
|
||||
throw new NullPointerException("key == null");
|
||||
Node<K, V> created = find(key, true);
|
||||
V result = created.value;
|
||||
created.value = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.root = null;
|
||||
this.size = 0;
|
||||
this.modCount++;
|
||||
Node<K, V> header = this.header;
|
||||
header.next = header.prev = header;
|
||||
}
|
||||
|
||||
public V remove(Object key) {
|
||||
Node<K, V> node = removeInternalByKey(key);
|
||||
return (node != null) ? node.value : null;
|
||||
}
|
||||
|
||||
Node<K, V> find(K key, boolean create) {
|
||||
Node<K, V> created;
|
||||
Comparator<? super K> comparator = this.comparator;
|
||||
Node<K, V> nearest = this.root;
|
||||
int comparison = 0;
|
||||
if (nearest != null) {
|
||||
Comparable<Object> comparableKey = (comparator == NATURAL_ORDER) ? (Comparable<Object>)key : null;
|
||||
while (true) {
|
||||
comparison = (comparableKey != null) ? comparableKey.compareTo(nearest.key) : comparator.compare(key, nearest.key);
|
||||
if (comparison == 0)
|
||||
return nearest;
|
||||
Node<K, V> child = (comparison < 0) ? nearest.left : nearest.right;
|
||||
if (child == null)
|
||||
break;
|
||||
nearest = child;
|
||||
}
|
||||
}
|
||||
if (!create)
|
||||
return null;
|
||||
Node<K, V> header = this.header;
|
||||
if (nearest == null) {
|
||||
if (comparator == NATURAL_ORDER && !(key instanceof Comparable))
|
||||
throw new ClassCastException(key.getClass().getName() + " is not Comparable");
|
||||
created = new Node<K, V>(nearest, key, header, header.prev);
|
||||
this.root = created;
|
||||
} else {
|
||||
created = new Node<K, V>(nearest, key, header, header.prev);
|
||||
if (comparison < 0) {
|
||||
nearest.left = created;
|
||||
} else {
|
||||
nearest.right = created;
|
||||
}
|
||||
rebalance(nearest, true);
|
||||
}
|
||||
this.size++;
|
||||
this.modCount++;
|
||||
return created;
|
||||
}
|
||||
|
||||
Node<K, V> findByObject(Object key) {
|
||||
try {
|
||||
return (key != null) ? find((K)key, false) : null;
|
||||
} catch (ClassCastException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Node<K, V> findByEntry(Map.Entry<?, ?> entry) {
|
||||
Node<K, V> mine = findByObject(entry.getKey());
|
||||
boolean valuesEqual = (mine != null && equal(mine.value, entry.getValue()));
|
||||
return valuesEqual ? mine : null;
|
||||
}
|
||||
|
||||
private boolean equal(Object a, Object b) {
|
||||
return (a == b || (a != null && a.equals(b)));
|
||||
}
|
||||
|
||||
void removeInternal(Node<K, V> node, boolean unlink) {
|
||||
if (unlink) {
|
||||
node.prev.next = node.next;
|
||||
node.next.prev = node.prev;
|
||||
}
|
||||
Node<K, V> left = node.left;
|
||||
Node<K, V> right = node.right;
|
||||
Node<K, V> originalParent = node.parent;
|
||||
if (left != null && right != null) {
|
||||
Node<K, V> adjacent = (left.height > right.height) ? left.last() : right.first();
|
||||
removeInternal(adjacent, false);
|
||||
int leftHeight = 0;
|
||||
left = node.left;
|
||||
if (left != null) {
|
||||
leftHeight = left.height;
|
||||
adjacent.left = left;
|
||||
left.parent = adjacent;
|
||||
node.left = null;
|
||||
}
|
||||
int rightHeight = 0;
|
||||
right = node.right;
|
||||
if (right != null) {
|
||||
rightHeight = right.height;
|
||||
adjacent.right = right;
|
||||
right.parent = adjacent;
|
||||
node.right = null;
|
||||
}
|
||||
adjacent.height = Math.max(leftHeight, rightHeight) + 1;
|
||||
replaceInParent(node, adjacent);
|
||||
return;
|
||||
}
|
||||
if (left != null) {
|
||||
replaceInParent(node, left);
|
||||
node.left = null;
|
||||
} else if (right != null) {
|
||||
replaceInParent(node, right);
|
||||
node.right = null;
|
||||
} else {
|
||||
replaceInParent(node, null);
|
||||
}
|
||||
rebalance(originalParent, false);
|
||||
this.size--;
|
||||
this.modCount++;
|
||||
}
|
||||
|
||||
Node<K, V> removeInternalByKey(Object key) {
|
||||
Node<K, V> node = findByObject(key);
|
||||
if (node != null)
|
||||
removeInternal(node, true);
|
||||
return node;
|
||||
}
|
||||
|
||||
private void replaceInParent(Node<K, V> node, Node<K, V> replacement) {
|
||||
Node<K, V> parent = node.parent;
|
||||
node.parent = null;
|
||||
if (replacement != null)
|
||||
replacement.parent = parent;
|
||||
if (parent != null) {
|
||||
if (parent.left == node) {
|
||||
parent.left = replacement;
|
||||
} else {
|
||||
assert parent.right == node;
|
||||
parent.right = replacement;
|
||||
}
|
||||
} else {
|
||||
this.root = replacement;
|
||||
}
|
||||
}
|
||||
|
||||
private void rebalance(Node<K, V> unbalanced, boolean insert) {
|
||||
for (Node<K, V> node = unbalanced; node != null; node = node.parent) {
|
||||
Node<K, V> left = node.left;
|
||||
Node<K, V> right = node.right;
|
||||
int leftHeight = (left != null) ? left.height : 0;
|
||||
int rightHeight = (right != null) ? right.height : 0;
|
||||
int delta = leftHeight - rightHeight;
|
||||
if (delta == -2) {
|
||||
Node<K, V> rightLeft = right.left;
|
||||
Node<K, V> rightRight = right.right;
|
||||
int rightRightHeight = (rightRight != null) ? rightRight.height : 0;
|
||||
int rightLeftHeight = (rightLeft != null) ? rightLeft.height : 0;
|
||||
int rightDelta = rightLeftHeight - rightRightHeight;
|
||||
if (rightDelta == -1 || (rightDelta == 0 && !insert)) {
|
||||
rotateLeft(node);
|
||||
} else {
|
||||
assert rightDelta == 1;
|
||||
rotateRight(right);
|
||||
rotateLeft(node);
|
||||
}
|
||||
if (insert)
|
||||
break;
|
||||
} else if (delta == 2) {
|
||||
Node<K, V> leftLeft = left.left;
|
||||
Node<K, V> leftRight = left.right;
|
||||
int leftRightHeight = (leftRight != null) ? leftRight.height : 0;
|
||||
int leftLeftHeight = (leftLeft != null) ? leftLeft.height : 0;
|
||||
int leftDelta = leftLeftHeight - leftRightHeight;
|
||||
if (leftDelta == 1 || (leftDelta == 0 && !insert)) {
|
||||
rotateRight(node);
|
||||
} else {
|
||||
assert leftDelta == -1;
|
||||
rotateLeft(left);
|
||||
rotateRight(node);
|
||||
}
|
||||
if (insert)
|
||||
break;
|
||||
} else if (delta == 0) {
|
||||
node.height = leftHeight + 1;
|
||||
if (insert)
|
||||
break;
|
||||
} else {
|
||||
assert delta == -1 || delta == 1;
|
||||
node.height = Math.max(leftHeight, rightHeight) + 1;
|
||||
if (!insert)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void rotateLeft(Node<K, V> root) {
|
||||
Node<K, V> left = root.left;
|
||||
Node<K, V> pivot = root.right;
|
||||
Node<K, V> pivotLeft = pivot.left;
|
||||
Node<K, V> pivotRight = pivot.right;
|
||||
root.right = pivotLeft;
|
||||
if (pivotLeft != null)
|
||||
pivotLeft.parent = root;
|
||||
replaceInParent(root, pivot);
|
||||
pivot.left = root;
|
||||
root.parent = pivot;
|
||||
root.height = Math.max((left != null) ? left.height : 0, (pivotLeft != null) ? pivotLeft.height : 0) + 1;
|
||||
pivot.height = Math.max(root.height, (pivotRight != null) ? pivotRight.height : 0) + 1;
|
||||
}
|
||||
|
||||
private void rotateRight(Node<K, V> root) {
|
||||
Node<K, V> pivot = root.left;
|
||||
Node<K, V> right = root.right;
|
||||
Node<K, V> pivotLeft = pivot.left;
|
||||
Node<K, V> pivotRight = pivot.right;
|
||||
root.left = pivotRight;
|
||||
if (pivotRight != null)
|
||||
pivotRight.parent = root;
|
||||
replaceInParent(root, pivot);
|
||||
pivot.right = root;
|
||||
root.parent = pivot;
|
||||
root.height = Math.max((right != null) ? right.height : 0, (pivotRight != null) ? pivotRight.height : 0) + 1;
|
||||
pivot.height = Math.max(root.height, (pivotLeft != null) ? pivotLeft.height : 0) + 1;
|
||||
}
|
||||
|
||||
public Set<Map.Entry<K, V>> entrySet() {
|
||||
EntrySet result = this.entrySet;
|
||||
return (result != null) ? result : (this.entrySet = new EntrySet());
|
||||
}
|
||||
|
||||
public Set<K> keySet() {
|
||||
KeySet result = this.keySet;
|
||||
return (result != null) ? result : (this.keySet = new KeySet());
|
||||
}
|
||||
|
||||
static final class Node<K, V> implements Map.Entry<K, V> {
|
||||
Node<K, V> parent;
|
||||
|
||||
Node<K, V> left;
|
||||
|
||||
Node<K, V> right;
|
||||
|
||||
Node<K, V> next;
|
||||
|
||||
Node<K, V> prev;
|
||||
|
||||
final K key;
|
||||
|
||||
V value;
|
||||
|
||||
int height;
|
||||
|
||||
Node() {
|
||||
this.key = null;
|
||||
this.next = this.prev = this;
|
||||
}
|
||||
|
||||
Node(Node<K, V> parent, K key, Node<K, V> next, Node<K, V> prev) {
|
||||
this.parent = parent;
|
||||
this.key = key;
|
||||
this.height = 1;
|
||||
this.next = next;
|
||||
this.prev = prev;
|
||||
prev.next = this;
|
||||
next.prev = this;
|
||||
}
|
||||
|
||||
public K getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public V getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public V setValue(V value) {
|
||||
V oldValue = this.value;
|
||||
this.value = value;
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Map.Entry) {
|
||||
Map.Entry other = (Map.Entry)o;
|
||||
return (((this.key == null) ? (other.getKey() == null) : this.key.equals(other.getKey())) && ((this.value == null) ? (other.getValue() == null) : this.value.equals(other.getValue())));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return ((this.key == null) ? 0 : this.key.hashCode()) ^ ((this.value == null) ? 0 : this.value.hashCode());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new StringBuilder().append(this.key).append("=").append(this.value).toString();
|
||||
}
|
||||
|
||||
public Node<K, V> first() {
|
||||
Node<K, V> node = this;
|
||||
Node<K, V> child = node.left;
|
||||
while (child != null) {
|
||||
node = child;
|
||||
child = node.left;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public Node<K, V> last() {
|
||||
Node<K, V> node = this;
|
||||
Node<K, V> child = node.right;
|
||||
while (child != null) {
|
||||
node = child;
|
||||
child = node.right;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class LinkedTreeMapIterator<T> implements Iterator<T> {
|
||||
LinkedTreeMap.Node<K, V> next = LinkedTreeMap.this.header.next;
|
||||
|
||||
LinkedTreeMap.Node<K, V> lastReturned = null;
|
||||
|
||||
int expectedModCount = LinkedTreeMap.this.modCount;
|
||||
|
||||
public final boolean hasNext() {
|
||||
return (this.next != LinkedTreeMap.this.header);
|
||||
}
|
||||
|
||||
final LinkedTreeMap.Node<K, V> nextNode() {
|
||||
LinkedTreeMap.Node<K, V> e = this.next;
|
||||
if (e == LinkedTreeMap.this.header)
|
||||
throw new NoSuchElementException();
|
||||
if (LinkedTreeMap.this.modCount != this.expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
this.next = e.next;
|
||||
return this.lastReturned = e;
|
||||
}
|
||||
|
||||
public final void remove() {
|
||||
if (this.lastReturned == null)
|
||||
throw new IllegalStateException();
|
||||
LinkedTreeMap.this.removeInternal(this.lastReturned, true);
|
||||
this.lastReturned = null;
|
||||
this.expectedModCount = LinkedTreeMap.this.modCount;
|
||||
}
|
||||
|
||||
private LinkedTreeMapIterator() {}
|
||||
}
|
||||
|
||||
class EntrySet extends AbstractSet<Map.Entry<K, V>> {
|
||||
public int size() {
|
||||
return LinkedTreeMap.this.size;
|
||||
}
|
||||
|
||||
public Iterator<Map.Entry<K, V>> iterator() {
|
||||
return new LinkedTreeMap<K, V>.LinkedTreeMapIterator<Map.Entry<K, V>>() {
|
||||
public Map.Entry<K, V> next() {
|
||||
return nextNode();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean contains(Object o) {
|
||||
return (o instanceof Map.Entry && LinkedTreeMap.this.findByEntry((Map.Entry<?, ?>)o) != null);
|
||||
}
|
||||
|
||||
public boolean remove(Object o) {
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
LinkedTreeMap.Node<K, V> node = LinkedTreeMap.this.findByEntry((Map.Entry<?, ?>)o);
|
||||
if (node == null)
|
||||
return false;
|
||||
LinkedTreeMap.this.removeInternal(node, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
LinkedTreeMap.this.clear();
|
||||
}
|
||||
}
|
||||
|
||||
class KeySet extends AbstractSet<K> {
|
||||
public int size() {
|
||||
return LinkedTreeMap.this.size;
|
||||
}
|
||||
|
||||
public Iterator<K> iterator() {
|
||||
return new LinkedTreeMap<K, V>.LinkedTreeMapIterator<K>() {
|
||||
public K next() {
|
||||
return (nextNode()).key;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean contains(Object o) {
|
||||
return LinkedTreeMap.this.containsKey(o);
|
||||
}
|
||||
|
||||
public boolean remove(Object key) {
|
||||
return (LinkedTreeMap.this.removeInternalByKey(key) != null);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
LinkedTreeMap.this.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private Object writeReplace() throws ObjectStreamException {
|
||||
return new LinkedHashMap<K, V>(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.google.gson.internal;
|
||||
|
||||
public interface ObjectConstructor<T> {
|
||||
T construct();
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.google.gson.internal;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class Primitives {
|
||||
private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER_TYPE;
|
||||
|
||||
private static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE_TYPE;
|
||||
|
||||
static {
|
||||
Map<Class<?>, Class<?>> primToWrap = new HashMap<Class<?>, Class<?>>(16);
|
||||
Map<Class<?>, Class<?>> wrapToPrim = new HashMap<Class<?>, Class<?>>(16);
|
||||
add(primToWrap, wrapToPrim, boolean.class, Boolean.class);
|
||||
add(primToWrap, wrapToPrim, byte.class, Byte.class);
|
||||
add(primToWrap, wrapToPrim, char.class, Character.class);
|
||||
add(primToWrap, wrapToPrim, double.class, Double.class);
|
||||
add(primToWrap, wrapToPrim, float.class, Float.class);
|
||||
add(primToWrap, wrapToPrim, int.class, Integer.class);
|
||||
add(primToWrap, wrapToPrim, long.class, Long.class);
|
||||
add(primToWrap, wrapToPrim, short.class, Short.class);
|
||||
add(primToWrap, wrapToPrim, void.class, Void.class);
|
||||
PRIMITIVE_TO_WRAPPER_TYPE = Collections.<Class<?>, Class<?>>unmodifiableMap(primToWrap);
|
||||
WRAPPER_TO_PRIMITIVE_TYPE = Collections.<Class<?>, Class<?>>unmodifiableMap(wrapToPrim);
|
||||
}
|
||||
|
||||
private static void add(Map<Class<?>, Class<?>> forward, Map<Class<?>, Class<?>> backward, Class<?> key, Class<?> value) {
|
||||
forward.put(key, value);
|
||||
backward.put(value, key);
|
||||
}
|
||||
|
||||
public static boolean isPrimitive(Type type) {
|
||||
return PRIMITIVE_TO_WRAPPER_TYPE.containsKey(type);
|
||||
}
|
||||
|
||||
public static boolean isWrapperType(Type type) {
|
||||
return WRAPPER_TO_PRIMITIVE_TYPE.containsKey($Gson$Preconditions.<Type>checkNotNull(type));
|
||||
}
|
||||
|
||||
public static <T> Class<T> wrap(Class<T> type) {
|
||||
Class<T> wrapped = (Class<T>)PRIMITIVE_TO_WRAPPER_TYPE.get($Gson$Preconditions.<Class<T>>checkNotNull(type));
|
||||
return (wrapped == null) ? type : wrapped;
|
||||
}
|
||||
|
||||
public static <T> Class<T> unwrap(Class<T> type) {
|
||||
Class<T> unwrapped = (Class<T>)WRAPPER_TO_PRIMITIVE_TYPE.get($Gson$Preconditions.<Class<T>>checkNotNull(type));
|
||||
return (unwrapped == null) ? type : unwrapped;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package com.google.gson.internal;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.internal.bind.TypeAdapters;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import com.google.gson.stream.MalformedJsonException;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
public final class Streams {
|
||||
public static JsonElement parse(JsonReader reader) throws JsonParseException {
|
||||
boolean isEmpty = true;
|
||||
try {
|
||||
reader.peek();
|
||||
isEmpty = false;
|
||||
return TypeAdapters.JSON_ELEMENT.read(reader);
|
||||
} catch (EOFException e) {
|
||||
if (isEmpty)
|
||||
return JsonNull.INSTANCE;
|
||||
throw new JsonSyntaxException(e);
|
||||
} catch (MalformedJsonException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void write(JsonElement element, JsonWriter writer) throws IOException {
|
||||
TypeAdapters.JSON_ELEMENT.write(writer, element);
|
||||
}
|
||||
|
||||
public static Writer writerForAppendable(Appendable appendable) {
|
||||
return (appendable instanceof Writer) ? (Writer)appendable : new AppendableWriter(appendable);
|
||||
}
|
||||
|
||||
private static final class AppendableWriter extends Writer {
|
||||
private final Appendable appendable;
|
||||
|
||||
private final CurrentWrite currentWrite = new CurrentWrite();
|
||||
|
||||
private AppendableWriter(Appendable appendable) {
|
||||
this.appendable = appendable;
|
||||
}
|
||||
|
||||
public void write(char[] chars, int offset, int length) throws IOException {
|
||||
this.currentWrite.chars = chars;
|
||||
this.appendable.append(this.currentWrite, offset, offset + length);
|
||||
}
|
||||
|
||||
public void write(int i) throws IOException {
|
||||
this.appendable.append((char)i);
|
||||
}
|
||||
|
||||
public void flush() {}
|
||||
|
||||
public void close() {}
|
||||
|
||||
static class CurrentWrite implements CharSequence {
|
||||
char[] chars;
|
||||
|
||||
public int length() {
|
||||
return this.chars.length;
|
||||
}
|
||||
|
||||
public char charAt(int i) {
|
||||
return this.chars[i];
|
||||
}
|
||||
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
return new String(this.chars, start, end - start);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package com.google.gson.internal;
|
||||
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectStreamClass;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public abstract class UnsafeAllocator {
|
||||
public abstract <T> T newInstance(Class<T> paramClass) throws Exception;
|
||||
|
||||
public static UnsafeAllocator create() {
|
||||
try {
|
||||
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
|
||||
Field f = unsafeClass.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
final Object unsafe = f.get(null);
|
||||
final Method allocateInstance = unsafeClass.getMethod("allocateInstance", Class.class);
|
||||
return new UnsafeAllocator() {
|
||||
public <T> T newInstance(Class<T> c) throws Exception {
|
||||
return (T)allocateInstance.invoke(unsafe, c);
|
||||
}
|
||||
};
|
||||
} catch (Exception ignored) {
|
||||
try {
|
||||
final Method newInstance = ObjectInputStream.class.getDeclaredMethod("newInstance", Class.class, Class.class);
|
||||
newInstance.setAccessible(true);
|
||||
return new UnsafeAllocator() {
|
||||
public <T> T newInstance(Class<T> c) throws Exception {
|
||||
return (T)newInstance.invoke(null, c, Object.class);
|
||||
}
|
||||
};
|
||||
} catch (Exception exception) {
|
||||
try {
|
||||
Method getConstructorId = ObjectStreamClass.class.getDeclaredMethod("getConstructorId", Class.class);
|
||||
getConstructorId.setAccessible(true);
|
||||
final int constructorId = (Integer)getConstructorId.invoke(null, Object.class);
|
||||
final Method newInstance = ObjectStreamClass.class.getDeclaredMethod("newInstance", Class.class, int.class);
|
||||
newInstance.setAccessible(true);
|
||||
return new UnsafeAllocator() {
|
||||
public <T> T newInstance(Class<T> c) throws Exception {
|
||||
return (T)newInstance.invoke(null, c, constructorId);
|
||||
}
|
||||
};
|
||||
} catch (Exception exception1) {
|
||||
return new UnsafeAllocator() {
|
||||
public <T> T newInstance(Class<T> c) {
|
||||
throw new UnsupportedOperationException("Cannot allocate " + c);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.internal.$Gson$Types;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class ArrayTypeAdapter<E> extends TypeAdapter<Object> {
|
||||
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
Type type = typeToken.getType();
|
||||
if (!(type instanceof java.lang.reflect.GenericArrayType) && (!(type instanceof Class) || !((Class)type).isArray()))
|
||||
return null;
|
||||
Type componentType = $Gson$Types.getArrayComponentType(type);
|
||||
TypeAdapter<?> componentTypeAdapter = gson.getAdapter(TypeToken.get(componentType));
|
||||
return new ArrayTypeAdapter(gson, componentTypeAdapter, $Gson$Types.getRawType(componentType));
|
||||
}
|
||||
};
|
||||
|
||||
private final Class<E> componentType;
|
||||
|
||||
private final TypeAdapter<E> componentTypeAdapter;
|
||||
|
||||
public ArrayTypeAdapter(Gson context, TypeAdapter<E> componentTypeAdapter, Class<E> componentType) {
|
||||
this.componentTypeAdapter = new TypeAdapterRuntimeTypeWrapper<E>(context, componentTypeAdapter, componentType);
|
||||
this.componentType = componentType;
|
||||
}
|
||||
|
||||
public Object read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
List<E> list = new ArrayList<E>();
|
||||
in.beginArray();
|
||||
while (in.hasNext()) {
|
||||
E instance = this.componentTypeAdapter.read(in);
|
||||
list.add(instance);
|
||||
}
|
||||
in.endArray();
|
||||
Object array = Array.newInstance(this.componentType, list.size());
|
||||
for (int i = 0; i < list.size(); i++)
|
||||
Array.set(array, i, list.get(i));
|
||||
return array;
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Object array) throws IOException {
|
||||
if (array == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
out.beginArray();
|
||||
for (int i = 0, length = Array.getLength(array); i < length; i++) {
|
||||
E value = (E)Array.get(array, i);
|
||||
this.componentTypeAdapter.write(out, value);
|
||||
}
|
||||
out.endArray();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.internal.$Gson$Types;
|
||||
import com.google.gson.internal.ConstructorConstructor;
|
||||
import com.google.gson.internal.ObjectConstructor;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
|
||||
public final class CollectionTypeAdapterFactory implements TypeAdapterFactory {
|
||||
private final ConstructorConstructor constructorConstructor;
|
||||
|
||||
public CollectionTypeAdapterFactory(ConstructorConstructor constructorConstructor) {
|
||||
this.constructorConstructor = constructorConstructor;
|
||||
}
|
||||
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
Type type = typeToken.getType();
|
||||
Class<? super T> rawType = typeToken.getRawType();
|
||||
if (!Collection.class.isAssignableFrom(rawType))
|
||||
return null;
|
||||
Type elementType = $Gson$Types.getCollectionElementType(type, rawType);
|
||||
TypeAdapter<?> elementTypeAdapter = gson.getAdapter(TypeToken.get(elementType));
|
||||
ObjectConstructor<T> constructor = this.constructorConstructor.<T>get(typeToken);
|
||||
TypeAdapter<T> result = new Adapter(gson, elementType, elementTypeAdapter, (ObjectConstructor)constructor);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final class Adapter<E> extends TypeAdapter<Collection<E>> {
|
||||
private final TypeAdapter<E> elementTypeAdapter;
|
||||
|
||||
private final ObjectConstructor<? extends Collection<E>> constructor;
|
||||
|
||||
public Adapter(Gson context, Type elementType, TypeAdapter<E> elementTypeAdapter, ObjectConstructor<? extends Collection<E>> constructor) {
|
||||
this.elementTypeAdapter = new TypeAdapterRuntimeTypeWrapper<E>(context, elementTypeAdapter, elementType);
|
||||
this.constructor = constructor;
|
||||
}
|
||||
|
||||
public Collection<E> read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
Collection<E> collection = this.constructor.construct();
|
||||
in.beginArray();
|
||||
while (in.hasNext()) {
|
||||
E instance = this.elementTypeAdapter.read(in);
|
||||
collection.add(instance);
|
||||
}
|
||||
in.endArray();
|
||||
return collection;
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Collection<E> collection) throws IOException {
|
||||
if (collection == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
out.beginArray();
|
||||
for (E element : (Iterable<E>)collection)
|
||||
this.elementTypeAdapter.write(out, element);
|
||||
out.endArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public final class DateTypeAdapter extends TypeAdapter<Date> {
|
||||
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
return (typeToken.getRawType() == Date.class) ? new DateTypeAdapter() : null;
|
||||
}
|
||||
};
|
||||
|
||||
private final DateFormat enUsFormat = DateFormat.getDateTimeInstance(2, 2, Locale.US);
|
||||
|
||||
private final DateFormat localFormat = DateFormat.getDateTimeInstance(2, 2);
|
||||
|
||||
private final DateFormat iso8601Format = buildIso8601Format();
|
||||
|
||||
private static DateFormat buildIso8601Format() {
|
||||
DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
|
||||
iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
return iso8601Format;
|
||||
}
|
||||
|
||||
public Date read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
return deserializeToDate(in.nextString());
|
||||
}
|
||||
|
||||
private synchronized Date deserializeToDate(String json) {
|
||||
try {
|
||||
return this.localFormat.parse(json);
|
||||
} catch (ParseException ignored) {
|
||||
try {
|
||||
return this.enUsFormat.parse(json);
|
||||
} catch (ParseException parseException) {
|
||||
try {
|
||||
return this.iso8601Format.parse(json);
|
||||
} catch (ParseException e) {
|
||||
throw new JsonSyntaxException(json, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void write(JsonWriter out, Date value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
String dateFormatAsString = this.enUsFormat.format(value);
|
||||
out.value(dateFormatAsString);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class JsonTreeReader extends JsonReader {
|
||||
private static final Reader UNREADABLE_READER = new Reader() {
|
||||
public int read(char[] buffer, int offset, int count) throws IOException {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
throw new AssertionError();
|
||||
}
|
||||
};
|
||||
|
||||
private static final Object SENTINEL_CLOSED = new Object();
|
||||
|
||||
private final List<Object> stack = new ArrayList();
|
||||
|
||||
public JsonTreeReader(JsonElement element) {
|
||||
super(UNREADABLE_READER);
|
||||
this.stack.add(element);
|
||||
}
|
||||
|
||||
public void beginArray() throws IOException {
|
||||
expect(JsonToken.BEGIN_ARRAY);
|
||||
JsonArray array = (JsonArray)peekStack();
|
||||
this.stack.add(array.iterator());
|
||||
}
|
||||
|
||||
public void endArray() throws IOException {
|
||||
expect(JsonToken.END_ARRAY);
|
||||
popStack();
|
||||
popStack();
|
||||
}
|
||||
|
||||
public void beginObject() throws IOException {
|
||||
expect(JsonToken.BEGIN_OBJECT);
|
||||
JsonObject object = (JsonObject)peekStack();
|
||||
this.stack.add(object.entrySet().iterator());
|
||||
}
|
||||
|
||||
public void endObject() throws IOException {
|
||||
expect(JsonToken.END_OBJECT);
|
||||
popStack();
|
||||
popStack();
|
||||
}
|
||||
|
||||
public boolean hasNext() throws IOException {
|
||||
JsonToken token = peek();
|
||||
return (token != JsonToken.END_OBJECT && token != JsonToken.END_ARRAY);
|
||||
}
|
||||
|
||||
public JsonToken peek() throws IOException {
|
||||
if (this.stack.isEmpty())
|
||||
return JsonToken.END_DOCUMENT;
|
||||
Object o = peekStack();
|
||||
if (o instanceof Iterator) {
|
||||
boolean isObject = this.stack.get(this.stack.size() - 2) instanceof JsonObject;
|
||||
Iterator<?> iterator = (Iterator)o;
|
||||
if (iterator.hasNext()) {
|
||||
if (isObject)
|
||||
return JsonToken.NAME;
|
||||
this.stack.add(iterator.next());
|
||||
return peek();
|
||||
}
|
||||
return isObject ? JsonToken.END_OBJECT : JsonToken.END_ARRAY;
|
||||
}
|
||||
if (o instanceof JsonObject)
|
||||
return JsonToken.BEGIN_OBJECT;
|
||||
if (o instanceof JsonArray)
|
||||
return JsonToken.BEGIN_ARRAY;
|
||||
if (o instanceof JsonPrimitive) {
|
||||
JsonPrimitive primitive = (JsonPrimitive)o;
|
||||
if (primitive.isString())
|
||||
return JsonToken.STRING;
|
||||
if (primitive.isBoolean())
|
||||
return JsonToken.BOOLEAN;
|
||||
if (primitive.isNumber())
|
||||
return JsonToken.NUMBER;
|
||||
throw new AssertionError();
|
||||
}
|
||||
if (o instanceof com.google.gson.JsonNull)
|
||||
return JsonToken.NULL;
|
||||
if (o == SENTINEL_CLOSED)
|
||||
throw new IllegalStateException("JsonReader is closed");
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
private Object peekStack() {
|
||||
return this.stack.get(this.stack.size() - 1);
|
||||
}
|
||||
|
||||
private Object popStack() {
|
||||
return this.stack.remove(this.stack.size() - 1);
|
||||
}
|
||||
|
||||
private void expect(JsonToken expected) throws IOException {
|
||||
if (peek() != expected)
|
||||
throw new IllegalStateException("Expected " + expected + " but was " + peek());
|
||||
}
|
||||
|
||||
public String nextName() throws IOException {
|
||||
expect(JsonToken.NAME);
|
||||
Iterator<?> i = (Iterator)peekStack();
|
||||
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)i.next();
|
||||
this.stack.add(entry.getValue());
|
||||
return (String)entry.getKey();
|
||||
}
|
||||
|
||||
public String nextString() throws IOException {
|
||||
JsonToken token = peek();
|
||||
if (token != JsonToken.STRING && token != JsonToken.NUMBER)
|
||||
throw new IllegalStateException("Expected " + JsonToken.STRING + " but was " + token);
|
||||
return ((JsonPrimitive)popStack()).getAsString();
|
||||
}
|
||||
|
||||
public boolean nextBoolean() throws IOException {
|
||||
expect(JsonToken.BOOLEAN);
|
||||
return ((JsonPrimitive)popStack()).getAsBoolean();
|
||||
}
|
||||
|
||||
public void nextNull() throws IOException {
|
||||
expect(JsonToken.NULL);
|
||||
popStack();
|
||||
}
|
||||
|
||||
public double nextDouble() throws IOException {
|
||||
JsonToken token = peek();
|
||||
if (token != JsonToken.NUMBER && token != JsonToken.STRING)
|
||||
throw new IllegalStateException("Expected " + JsonToken.NUMBER + " but was " + token);
|
||||
double result = ((JsonPrimitive)peekStack()).getAsDouble();
|
||||
if (!isLenient() && (Double.isNaN(result) || Double.isInfinite(result)))
|
||||
throw new NumberFormatException("JSON forbids NaN and infinities: " + result);
|
||||
popStack();
|
||||
return result;
|
||||
}
|
||||
|
||||
public long nextLong() throws IOException {
|
||||
JsonToken token = peek();
|
||||
if (token != JsonToken.NUMBER && token != JsonToken.STRING)
|
||||
throw new IllegalStateException("Expected " + JsonToken.NUMBER + " but was " + token);
|
||||
long result = ((JsonPrimitive)peekStack()).getAsLong();
|
||||
popStack();
|
||||
return result;
|
||||
}
|
||||
|
||||
public int nextInt() throws IOException {
|
||||
JsonToken token = peek();
|
||||
if (token != JsonToken.NUMBER && token != JsonToken.STRING)
|
||||
throw new IllegalStateException("Expected " + JsonToken.NUMBER + " but was " + token);
|
||||
int result = ((JsonPrimitive)peekStack()).getAsInt();
|
||||
popStack();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
this.stack.clear();
|
||||
this.stack.add(SENTINEL_CLOSED);
|
||||
}
|
||||
|
||||
public void skipValue() throws IOException {
|
||||
if (peek() == JsonToken.NAME) {
|
||||
nextName();
|
||||
} else {
|
||||
popStack();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
public void promoteNameToValue() throws IOException {
|
||||
expect(JsonToken.NAME);
|
||||
Iterator<?> i = (Iterator)peekStack();
|
||||
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)i.next();
|
||||
this.stack.add(entry.getValue());
|
||||
this.stack.add(new JsonPrimitive((String)entry.getKey()));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class JsonTreeWriter extends JsonWriter {
|
||||
private static final Writer UNWRITABLE_WRITER = new Writer() {
|
||||
public void write(char[] buffer, int offset, int counter) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
throw new AssertionError();
|
||||
}
|
||||
};
|
||||
|
||||
private static final JsonPrimitive SENTINEL_CLOSED = new JsonPrimitive("closed");
|
||||
|
||||
private final List<JsonElement> stack = new ArrayList<JsonElement>();
|
||||
|
||||
private String pendingName;
|
||||
|
||||
private JsonElement product = JsonNull.INSTANCE;
|
||||
|
||||
public JsonTreeWriter() {
|
||||
super(UNWRITABLE_WRITER);
|
||||
}
|
||||
|
||||
public JsonElement get() {
|
||||
if (!this.stack.isEmpty())
|
||||
throw new IllegalStateException("Expected one JSON element but was " + this.stack);
|
||||
return this.product;
|
||||
}
|
||||
|
||||
private JsonElement peek() {
|
||||
return this.stack.get(this.stack.size() - 1);
|
||||
}
|
||||
|
||||
private void put(JsonElement value) {
|
||||
if (this.pendingName != null) {
|
||||
if (!value.isJsonNull() || getSerializeNulls()) {
|
||||
JsonObject object = (JsonObject)peek();
|
||||
object.add(this.pendingName, value);
|
||||
}
|
||||
this.pendingName = null;
|
||||
} else if (this.stack.isEmpty()) {
|
||||
this.product = value;
|
||||
} else {
|
||||
JsonElement element = peek();
|
||||
if (element instanceof JsonArray) {
|
||||
((JsonArray)element).add(value);
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JsonWriter beginArray() throws IOException {
|
||||
JsonArray array = new JsonArray();
|
||||
put(array);
|
||||
this.stack.add(array);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonWriter endArray() throws IOException {
|
||||
if (this.stack.isEmpty() || this.pendingName != null)
|
||||
throw new IllegalStateException();
|
||||
JsonElement element = peek();
|
||||
if (element instanceof JsonArray) {
|
||||
this.stack.remove(this.stack.size() - 1);
|
||||
return this;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public JsonWriter beginObject() throws IOException {
|
||||
JsonObject object = new JsonObject();
|
||||
put(object);
|
||||
this.stack.add(object);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonWriter endObject() throws IOException {
|
||||
if (this.stack.isEmpty() || this.pendingName != null)
|
||||
throw new IllegalStateException();
|
||||
JsonElement element = peek();
|
||||
if (element instanceof JsonObject) {
|
||||
this.stack.remove(this.stack.size() - 1);
|
||||
return this;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public JsonWriter name(String name) throws IOException {
|
||||
if (this.stack.isEmpty() || this.pendingName != null)
|
||||
throw new IllegalStateException();
|
||||
JsonElement element = peek();
|
||||
if (element instanceof JsonObject) {
|
||||
this.pendingName = name;
|
||||
return this;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public JsonWriter value(String value) throws IOException {
|
||||
if (value == null)
|
||||
return nullValue();
|
||||
put(new JsonPrimitive(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonWriter nullValue() throws IOException {
|
||||
put(JsonNull.INSTANCE);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonWriter value(boolean value) throws IOException {
|
||||
put(new JsonPrimitive(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonWriter value(double value) throws IOException {
|
||||
if (!isLenient() && (Double.isNaN(value) || Double.isInfinite(value)))
|
||||
throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);
|
||||
put(new JsonPrimitive((Number)value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonWriter value(long value) throws IOException {
|
||||
put(new JsonPrimitive((Number)value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonWriter value(Number value) throws IOException {
|
||||
if (value == null)
|
||||
return nullValue();
|
||||
if (!isLenient()) {
|
||||
double d = value.doubleValue();
|
||||
if (Double.isNaN(d) || Double.isInfinite(d))
|
||||
throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);
|
||||
}
|
||||
put(new JsonPrimitive(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public void flush() throws IOException {}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (!this.stack.isEmpty())
|
||||
throw new IOException("Incomplete document");
|
||||
this.stack.add(SENTINEL_CLOSED);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.internal.$Gson$Types;
|
||||
import com.google.gson.internal.ConstructorConstructor;
|
||||
import com.google.gson.internal.JsonReaderInternalAccess;
|
||||
import com.google.gson.internal.ObjectConstructor;
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class MapTypeAdapterFactory implements TypeAdapterFactory {
|
||||
private final ConstructorConstructor constructorConstructor;
|
||||
|
||||
private final boolean complexMapKeySerialization;
|
||||
|
||||
public MapTypeAdapterFactory(ConstructorConstructor constructorConstructor, boolean complexMapKeySerialization) {
|
||||
this.constructorConstructor = constructorConstructor;
|
||||
this.complexMapKeySerialization = complexMapKeySerialization;
|
||||
}
|
||||
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
Type type = typeToken.getType();
|
||||
Class<? super T> rawType = typeToken.getRawType();
|
||||
if (!Map.class.isAssignableFrom(rawType))
|
||||
return null;
|
||||
Class<?> rawTypeOfSrc = $Gson$Types.getRawType(type);
|
||||
Type[] keyAndValueTypes = $Gson$Types.getMapKeyAndValueTypes(type, rawTypeOfSrc);
|
||||
TypeAdapter<?> keyAdapter = getKeyAdapter(gson, keyAndValueTypes[0]);
|
||||
TypeAdapter<?> valueAdapter = gson.getAdapter(TypeToken.get(keyAndValueTypes[1]));
|
||||
ObjectConstructor<T> constructor = this.constructorConstructor.<T>get(typeToken);
|
||||
TypeAdapter<T> result = new Adapter(gson, keyAndValueTypes[0], keyAdapter, keyAndValueTypes[1], valueAdapter, (ObjectConstructor)constructor);
|
||||
return result;
|
||||
}
|
||||
|
||||
private TypeAdapter<?> getKeyAdapter(Gson context, Type keyType) {
|
||||
return (keyType == boolean.class || keyType == Boolean.class) ? TypeAdapters.BOOLEAN_AS_STRING : context.getAdapter(TypeToken.get(keyType));
|
||||
}
|
||||
|
||||
private final class Adapter<K, V> extends TypeAdapter<Map<K, V>> {
|
||||
private final TypeAdapter<K> keyTypeAdapter;
|
||||
|
||||
private final TypeAdapter<V> valueTypeAdapter;
|
||||
|
||||
private final ObjectConstructor<? extends Map<K, V>> constructor;
|
||||
|
||||
public Adapter(Gson context, Type keyType, TypeAdapter<K> keyTypeAdapter, Type valueType, TypeAdapter<V> valueTypeAdapter, ObjectConstructor<? extends Map<K, V>> constructor) {
|
||||
this.keyTypeAdapter = new TypeAdapterRuntimeTypeWrapper<K>(context, keyTypeAdapter, keyType);
|
||||
this.valueTypeAdapter = new TypeAdapterRuntimeTypeWrapper<V>(context, valueTypeAdapter, valueType);
|
||||
this.constructor = constructor;
|
||||
}
|
||||
|
||||
public Map<K, V> read(JsonReader in) throws IOException {
|
||||
JsonToken peek = in.peek();
|
||||
if (peek == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
Map<K, V> map = this.constructor.construct();
|
||||
if (peek == JsonToken.BEGIN_ARRAY) {
|
||||
in.beginArray();
|
||||
while (in.hasNext()) {
|
||||
in.beginArray();
|
||||
K key = this.keyTypeAdapter.read(in);
|
||||
V value = this.valueTypeAdapter.read(in);
|
||||
V replaced = map.put(key, value);
|
||||
if (replaced != null)
|
||||
throw new JsonSyntaxException("duplicate key: " + key);
|
||||
in.endArray();
|
||||
}
|
||||
in.endArray();
|
||||
} else {
|
||||
in.beginObject();
|
||||
while (in.hasNext()) {
|
||||
JsonReaderInternalAccess.INSTANCE.promoteNameToValue(in);
|
||||
K key = this.keyTypeAdapter.read(in);
|
||||
V value = this.valueTypeAdapter.read(in);
|
||||
V replaced = map.put(key, value);
|
||||
if (replaced != null)
|
||||
throw new JsonSyntaxException("duplicate key: " + key);
|
||||
}
|
||||
in.endObject();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Map<K, V> map) throws IOException {
|
||||
if (map == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
if (!MapTypeAdapterFactory.this.complexMapKeySerialization) {
|
||||
out.beginObject();
|
||||
for (Map.Entry<K, V> entry : map.entrySet()) {
|
||||
out.name(String.valueOf(entry.getKey()));
|
||||
this.valueTypeAdapter.write(out, entry.getValue());
|
||||
}
|
||||
out.endObject();
|
||||
return;
|
||||
}
|
||||
boolean hasComplexKeys = false;
|
||||
List<JsonElement> keys = new ArrayList<JsonElement>(map.size());
|
||||
List<V> values = new ArrayList<V>(map.size());
|
||||
for (Map.Entry<K, V> entry : map.entrySet()) {
|
||||
JsonElement keyElement = this.keyTypeAdapter.toJsonTree(entry.getKey());
|
||||
keys.add(keyElement);
|
||||
values.add(entry.getValue());
|
||||
hasComplexKeys |= (keyElement.isJsonArray() || keyElement.isJsonObject()) ? true : false;
|
||||
}
|
||||
if (hasComplexKeys) {
|
||||
out.beginArray();
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
out.beginArray();
|
||||
Streams.write(keys.get(i), out);
|
||||
this.valueTypeAdapter.write(out, values.get(i));
|
||||
out.endArray();
|
||||
}
|
||||
out.endArray();
|
||||
} else {
|
||||
out.beginObject();
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
JsonElement keyElement = keys.get(i);
|
||||
out.name(keyToString(keyElement));
|
||||
this.valueTypeAdapter.write(out, values.get(i));
|
||||
}
|
||||
out.endObject();
|
||||
}
|
||||
}
|
||||
|
||||
private String keyToString(JsonElement keyElement) {
|
||||
if (keyElement.isJsonPrimitive()) {
|
||||
JsonPrimitive primitive = keyElement.getAsJsonPrimitive();
|
||||
if (primitive.isNumber())
|
||||
return String.valueOf(primitive.getAsNumber());
|
||||
if (primitive.isBoolean())
|
||||
return Boolean.toString(primitive.getAsBoolean());
|
||||
if (primitive.isString())
|
||||
return primitive.getAsString();
|
||||
throw new AssertionError();
|
||||
}
|
||||
if (keyElement.isJsonNull())
|
||||
return "null";
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.internal.LinkedTreeMap;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class ObjectTypeAdapter extends TypeAdapter<Object> {
|
||||
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
|
||||
if (type.getRawType() == Object.class)
|
||||
return new ObjectTypeAdapter(gson);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
private final Gson gson;
|
||||
|
||||
private ObjectTypeAdapter(Gson gson) {
|
||||
this.gson = gson;
|
||||
}
|
||||
|
||||
public Object read(JsonReader in) throws IOException {
|
||||
List<Object> list;
|
||||
Map<String, Object> map;
|
||||
JsonToken token = in.peek();
|
||||
switch (token) {
|
||||
case BEGIN_ARRAY:
|
||||
list = new ArrayList();
|
||||
in.beginArray();
|
||||
while (in.hasNext())
|
||||
list.add(read(in));
|
||||
in.endArray();
|
||||
return list;
|
||||
case BEGIN_OBJECT:
|
||||
map = new LinkedTreeMap<String, Object>();
|
||||
in.beginObject();
|
||||
while (in.hasNext())
|
||||
map.put(in.nextName(), read(in));
|
||||
in.endObject();
|
||||
return map;
|
||||
case STRING:
|
||||
return in.nextString();
|
||||
case NUMBER:
|
||||
return in.nextDouble();
|
||||
case BOOLEAN:
|
||||
return in.nextBoolean();
|
||||
case NULL:
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Object value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
TypeAdapter<Object> typeAdapter = this.gson.getAdapter(value.getClass());
|
||||
if (typeAdapter instanceof ObjectTypeAdapter) {
|
||||
out.beginObject();
|
||||
out.endObject();
|
||||
return;
|
||||
}
|
||||
typeAdapter.write(out, value);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.FieldNamingStrategy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.internal.$Gson$Types;
|
||||
import com.google.gson.internal.ConstructorConstructor;
|
||||
import com.google.gson.internal.Excluder;
|
||||
import com.google.gson.internal.ObjectConstructor;
|
||||
import com.google.gson.internal.Primitives;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory {
|
||||
private final ConstructorConstructor constructorConstructor;
|
||||
|
||||
private final FieldNamingStrategy fieldNamingPolicy;
|
||||
|
||||
private final Excluder excluder;
|
||||
|
||||
public ReflectiveTypeAdapterFactory(ConstructorConstructor constructorConstructor, FieldNamingStrategy fieldNamingPolicy, Excluder excluder) {
|
||||
this.constructorConstructor = constructorConstructor;
|
||||
this.fieldNamingPolicy = fieldNamingPolicy;
|
||||
this.excluder = excluder;
|
||||
}
|
||||
|
||||
public boolean excludeField(Field f, boolean serialize) {
|
||||
return (!this.excluder.excludeClass(f.getType(), serialize) && !this.excluder.excludeField(f, serialize));
|
||||
}
|
||||
|
||||
private String getFieldName(Field f) {
|
||||
SerializedName serializedName = f.<SerializedName>getAnnotation(SerializedName.class);
|
||||
return (serializedName == null) ? this.fieldNamingPolicy.translateName(f) : serializedName.value();
|
||||
}
|
||||
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
|
||||
Class<? super T> raw = type.getRawType();
|
||||
if (!Object.class.isAssignableFrom(raw))
|
||||
return null;
|
||||
ObjectConstructor<T> constructor = this.constructorConstructor.<T>get(type);
|
||||
return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
|
||||
}
|
||||
|
||||
private BoundField createBoundField(final Gson context, final Field field, String name, final TypeToken<?> fieldType, boolean serialize, boolean deserialize) {
|
||||
final boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType());
|
||||
return new BoundField(name, serialize, deserialize) {
|
||||
final TypeAdapter<?> typeAdapter;
|
||||
|
||||
{
|
||||
this.typeAdapter = context.getAdapter(fieldType);
|
||||
}
|
||||
|
||||
void write(JsonWriter writer, Object value) throws IOException, IllegalAccessException {
|
||||
Object fieldValue = field.get(value);
|
||||
TypeAdapter t = new TypeAdapterRuntimeTypeWrapper(context, this.typeAdapter, fieldType.getType());
|
||||
t.write(writer, fieldValue);
|
||||
}
|
||||
|
||||
void read(JsonReader reader, Object value) throws IOException, IllegalAccessException {
|
||||
Object fieldValue = this.typeAdapter.read(reader);
|
||||
if (fieldValue != null || !isPrimitive)
|
||||
field.set(value, fieldValue);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {
|
||||
Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
|
||||
if (raw.isInterface())
|
||||
return result;
|
||||
Type declaredType = type.getType();
|
||||
while (raw != Object.class) {
|
||||
Field[] fields = raw.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
boolean serialize = excludeField(field, true);
|
||||
boolean deserialize = excludeField(field, false);
|
||||
if (serialize || deserialize) {
|
||||
field.setAccessible(true);
|
||||
Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
|
||||
BoundField boundField = createBoundField(context, field, getFieldName(field), TypeToken.get(fieldType), serialize, deserialize);
|
||||
BoundField previous = result.put(boundField.name, boundField);
|
||||
if (previous != null)
|
||||
throw new IllegalArgumentException(declaredType + " declares multiple JSON fields named " + previous.name);
|
||||
}
|
||||
}
|
||||
type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));
|
||||
raw = type.getRawType();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static abstract class BoundField {
|
||||
final String name;
|
||||
|
||||
final boolean serialized;
|
||||
|
||||
final boolean deserialized;
|
||||
|
||||
protected BoundField(String name, boolean serialized, boolean deserialized) {
|
||||
this.name = name;
|
||||
this.serialized = serialized;
|
||||
this.deserialized = deserialized;
|
||||
}
|
||||
|
||||
abstract void write(JsonWriter param1JsonWriter, Object param1Object) throws IOException, IllegalAccessException;
|
||||
|
||||
abstract void read(JsonReader param1JsonReader, Object param1Object) throws IOException, IllegalAccessException;
|
||||
}
|
||||
|
||||
public static final class Adapter<T> extends TypeAdapter<T> {
|
||||
private final ObjectConstructor<T> constructor;
|
||||
|
||||
private final Map<String, ReflectiveTypeAdapterFactory.BoundField> boundFields;
|
||||
|
||||
private Adapter(ObjectConstructor<T> constructor, Map<String, ReflectiveTypeAdapterFactory.BoundField> boundFields) {
|
||||
this.constructor = constructor;
|
||||
this.boundFields = boundFields;
|
||||
}
|
||||
|
||||
public T read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
T instance = this.constructor.construct();
|
||||
try {
|
||||
in.beginObject();
|
||||
while (in.hasNext()) {
|
||||
String name = in.nextName();
|
||||
ReflectiveTypeAdapterFactory.BoundField field = this.boundFields.get(name);
|
||||
if (field == null || !field.deserialized) {
|
||||
in.skipValue();
|
||||
continue;
|
||||
}
|
||||
field.read(in, instance);
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
in.endObject();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, T value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
out.beginObject();
|
||||
try {
|
||||
for (ReflectiveTypeAdapterFactory.BoundField boundField : this.boundFields.values()) {
|
||||
if (boundField.serialized) {
|
||||
out.name(boundField.name);
|
||||
boundField.write(out, value);
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
out.endObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.sql.Date;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
public final class SqlDateTypeAdapter extends TypeAdapter<Date> {
|
||||
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
return (typeToken.getRawType() == Date.class) ? new SqlDateTypeAdapter() : null;
|
||||
}
|
||||
};
|
||||
|
||||
private final DateFormat format = new SimpleDateFormat("MMM d, yyyy");
|
||||
|
||||
public synchronized Date read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
long utilDate = this.format.parse(in.nextString()).getTime();
|
||||
return new Date(utilDate);
|
||||
} catch (ParseException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void write(JsonWriter out, Date value) throws IOException {
|
||||
out.value((value == null) ? null : this.format.format((java.util.Date)value));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.sql.Time;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public final class TimeTypeAdapter extends TypeAdapter<Time> {
|
||||
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
return (typeToken.getRawType() == Time.class) ? new TimeTypeAdapter() : null;
|
||||
}
|
||||
};
|
||||
|
||||
private final DateFormat format = new SimpleDateFormat("hh:mm:ss a");
|
||||
|
||||
public synchronized Time read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Date date = this.format.parse(in.nextString());
|
||||
return new Time(date.getTime());
|
||||
} catch (ParseException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void write(JsonWriter out, Time value) throws IOException {
|
||||
out.value((value == null) ? null : this.format.format((Date)value));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
final class TypeAdapterRuntimeTypeWrapper<T> extends TypeAdapter<T> {
|
||||
private final Gson context;
|
||||
|
||||
private final TypeAdapter<T> delegate;
|
||||
|
||||
private final Type type;
|
||||
|
||||
TypeAdapterRuntimeTypeWrapper(Gson context, TypeAdapter<T> delegate, Type type) {
|
||||
this.context = context;
|
||||
this.delegate = delegate;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public T read(JsonReader in) throws IOException {
|
||||
return this.delegate.read(in);
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, T value) throws IOException {
|
||||
TypeAdapter<T> chosen = this.delegate;
|
||||
Type runtimeType = getRuntimeTypeIfMoreSpecific(this.type, value);
|
||||
if (runtimeType != this.type) {
|
||||
TypeAdapter<?> runtimeTypeAdapter = this.context.getAdapter(TypeToken.get(runtimeType));
|
||||
if (!(runtimeTypeAdapter instanceof ReflectiveTypeAdapterFactory.Adapter)) {
|
||||
chosen = (TypeAdapter<T>)runtimeTypeAdapter;
|
||||
} else if (!(this.delegate instanceof ReflectiveTypeAdapterFactory.Adapter)) {
|
||||
chosen = this.delegate;
|
||||
} else {
|
||||
chosen = (TypeAdapter<T>)runtimeTypeAdapter;
|
||||
}
|
||||
}
|
||||
chosen.write(out, value);
|
||||
}
|
||||
|
||||
private Type getRuntimeTypeIfMoreSpecific(Type<?> type, Object value) {
|
||||
if (value != null && (type == Object.class || type instanceof java.lang.reflect.TypeVariable || type instanceof Class))
|
||||
type = value.getClass();
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,752 @@
|
|||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.internal.LazilyParsedNumber;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.BitSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class TypeAdapters {
|
||||
public static final TypeAdapter<Class> CLASS = new TypeAdapter<Class>() {
|
||||
public void write(JsonWriter out, Class value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Attempted to serialize java.lang.Class: " + value.getName() + ". Forgot to register a type adapter?");
|
||||
}
|
||||
}
|
||||
|
||||
public Class read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
throw new UnsupportedOperationException("Attempted to deserialize a java.lang.Class. Forgot to register a type adapter?");
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory CLASS_FACTORY = TypeAdapters.<Class<?>>newFactory(Class.class, CLASS);
|
||||
|
||||
public static final TypeAdapter<BitSet> BIT_SET = new TypeAdapter<BitSet>() {
|
||||
public BitSet read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
BitSet bitset = new BitSet();
|
||||
in.beginArray();
|
||||
int i = 0;
|
||||
JsonToken tokenType = in.peek();
|
||||
while (tokenType != JsonToken.END_ARRAY) {
|
||||
boolean set;
|
||||
String stringValue;
|
||||
switch (tokenType) {
|
||||
case NUMBER:
|
||||
set = (in.nextInt() != 0);
|
||||
break;
|
||||
case BOOLEAN:
|
||||
set = in.nextBoolean();
|
||||
break;
|
||||
case STRING:
|
||||
stringValue = in.nextString();
|
||||
try {
|
||||
set = (Integer.parseInt(stringValue) != 0);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException("Error: Expecting: bitset number value (1, 0), Found: " + stringValue);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new JsonSyntaxException("Invalid bitset value type: " + tokenType);
|
||||
}
|
||||
if (set)
|
||||
bitset.set(i);
|
||||
i++;
|
||||
tokenType = in.peek();
|
||||
}
|
||||
in.endArray();
|
||||
return bitset;
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, BitSet src) throws IOException {
|
||||
if (src == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
out.beginArray();
|
||||
for (int i = 0; i < src.length(); i++) {
|
||||
int value = src.get(i) ? 1 : 0;
|
||||
out.value((long)value);
|
||||
}
|
||||
out.endArray();
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory BIT_SET_FACTORY = TypeAdapters.<BitSet>newFactory(BitSet.class, BIT_SET);
|
||||
|
||||
public static final TypeAdapter<Boolean> BOOLEAN = new TypeAdapter<Boolean>() {
|
||||
public Boolean read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
if (in.peek() == JsonToken.STRING)
|
||||
return Boolean.parseBoolean(in.nextString());
|
||||
return in.nextBoolean();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Boolean value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
out.value(value.booleanValue());
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapter<Boolean> BOOLEAN_AS_STRING = new TypeAdapter<Boolean>() {
|
||||
public Boolean read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
return Boolean.valueOf(in.nextString());
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Boolean value) throws IOException {
|
||||
out.value((value == null) ? "null" : value.toString());
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory BOOLEAN_FACTORY = TypeAdapters.<boolean>newFactory(boolean.class, (Class)Boolean.class, BOOLEAN);
|
||||
|
||||
public static final TypeAdapter<Number> BYTE = new TypeAdapter<Number>() {
|
||||
public Number read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
int intValue = in.nextInt();
|
||||
return (byte)intValue;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Number value) throws IOException {
|
||||
out.value(value);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory BYTE_FACTORY = TypeAdapters.<byte>newFactory(byte.class, (Class)Byte.class, BYTE);
|
||||
|
||||
public static final TypeAdapter<Number> SHORT = new TypeAdapter<Number>() {
|
||||
public Number read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return (short)in.nextInt();
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Number value) throws IOException {
|
||||
out.value(value);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory SHORT_FACTORY = TypeAdapters.<short>newFactory(short.class, (Class)Short.class, SHORT);
|
||||
|
||||
public static final TypeAdapter<Number> INTEGER = new TypeAdapter<Number>() {
|
||||
public Number read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return in.nextInt();
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Number value) throws IOException {
|
||||
out.value(value);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory INTEGER_FACTORY = TypeAdapters.<int>newFactory(int.class, (Class)Integer.class, INTEGER);
|
||||
|
||||
public static final TypeAdapter<Number> LONG = new TypeAdapter<Number>() {
|
||||
public Number read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return in.nextLong();
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Number value) throws IOException {
|
||||
out.value(value);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapter<Number> FLOAT = new TypeAdapter<Number>() {
|
||||
public Number read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
return (float)in.nextDouble();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Number value) throws IOException {
|
||||
out.value(value);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapter<Number> DOUBLE = new TypeAdapter<Number>() {
|
||||
public Number read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
return in.nextDouble();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Number value) throws IOException {
|
||||
out.value(value);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapter<Number> NUMBER = new TypeAdapter<Number>() {
|
||||
public Number read(JsonReader in) throws IOException {
|
||||
JsonToken jsonToken = in.peek();
|
||||
switch (jsonToken) {
|
||||
case NULL:
|
||||
in.nextNull();
|
||||
return null;
|
||||
case NUMBER:
|
||||
return new LazilyParsedNumber(in.nextString());
|
||||
}
|
||||
throw new JsonSyntaxException("Expecting number, got: " + jsonToken);
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Number value) throws IOException {
|
||||
out.value(value);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory NUMBER_FACTORY = TypeAdapters.<Number>newFactory(Number.class, NUMBER);
|
||||
|
||||
public static final TypeAdapter<Character> CHARACTER = new TypeAdapter<Character>() {
|
||||
public Character read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
String str = in.nextString();
|
||||
if (str.length() != 1)
|
||||
throw new JsonSyntaxException("Expecting character, got: " + str);
|
||||
return str.charAt(0);
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Character value) throws IOException {
|
||||
out.value((value == null) ? null : String.valueOf(value));
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory CHARACTER_FACTORY = TypeAdapters.<char>newFactory(char.class, (Class)Character.class, CHARACTER);
|
||||
|
||||
public static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
|
||||
public String read(JsonReader in) throws IOException {
|
||||
JsonToken peek = in.peek();
|
||||
if (peek == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
if (peek == JsonToken.BOOLEAN)
|
||||
return Boolean.toString(in.nextBoolean());
|
||||
return in.nextString();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, String value) throws IOException {
|
||||
out.value(value);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapter<BigDecimal> BIG_DECIMAL = new TypeAdapter<BigDecimal>() {
|
||||
public BigDecimal read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new BigDecimal(in.nextString());
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, BigDecimal value) throws IOException {
|
||||
out.value(value);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapter<BigInteger> BIG_INTEGER = new TypeAdapter<BigInteger>() {
|
||||
public BigInteger read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new BigInteger(in.nextString());
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, BigInteger value) throws IOException {
|
||||
out.value(value);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory STRING_FACTORY = TypeAdapters.<String>newFactory(String.class, STRING);
|
||||
|
||||
public static final TypeAdapter<StringBuilder> STRING_BUILDER = new TypeAdapter<StringBuilder>() {
|
||||
public StringBuilder read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
return new StringBuilder(in.nextString());
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, StringBuilder value) throws IOException {
|
||||
out.value((value == null) ? null : value.toString());
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory STRING_BUILDER_FACTORY = TypeAdapters.<StringBuilder>newFactory(StringBuilder.class, STRING_BUILDER);
|
||||
|
||||
public static final TypeAdapter<StringBuffer> STRING_BUFFER = new TypeAdapter<StringBuffer>() {
|
||||
public StringBuffer read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
return new StringBuffer(in.nextString());
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, StringBuffer value) throws IOException {
|
||||
out.value((value == null) ? null : value.toString());
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory STRING_BUFFER_FACTORY = TypeAdapters.<StringBuffer>newFactory(StringBuffer.class, STRING_BUFFER);
|
||||
|
||||
public static final TypeAdapter<URL> URL = new TypeAdapter<URL>() {
|
||||
public URL read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
String nextString = in.nextString();
|
||||
return "null".equals(nextString) ? null : new URL(nextString);
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, URL value) throws IOException {
|
||||
out.value((value == null) ? null : value.toExternalForm());
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory URL_FACTORY = TypeAdapters.<URL>newFactory(URL.class, URL);
|
||||
|
||||
public static final TypeAdapter<URI> URI = new TypeAdapter<URI>() {
|
||||
public URI read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
String nextString = in.nextString();
|
||||
return "null".equals(nextString) ? null : new URI(nextString);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, URI value) throws IOException {
|
||||
out.value((value == null) ? null : value.toASCIIString());
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory URI_FACTORY = TypeAdapters.<URI>newFactory(URI.class, URI);
|
||||
|
||||
public static final TypeAdapter<InetAddress> INET_ADDRESS = new TypeAdapter<InetAddress>() {
|
||||
public InetAddress read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
return InetAddress.getByName(in.nextString());
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, InetAddress value) throws IOException {
|
||||
out.value((value == null) ? null : value.getHostAddress());
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory INET_ADDRESS_FACTORY = TypeAdapters.<InetAddress>newTypeHierarchyFactory(InetAddress.class, INET_ADDRESS);
|
||||
|
||||
public static final TypeAdapter<UUID> UUID = new TypeAdapter<UUID>() {
|
||||
public UUID read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
return UUID.fromString(in.nextString());
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, UUID value) throws IOException {
|
||||
out.value((value == null) ? null : value.toString());
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory UUID_FACTORY = TypeAdapters.<UUID>newFactory(UUID.class, UUID);
|
||||
|
||||
public static final TypeAdapterFactory TIMESTAMP_FACTORY = new TypeAdapterFactory() {
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
if (typeToken.getRawType() != Timestamp.class)
|
||||
return null;
|
||||
final TypeAdapter<Date> dateTypeAdapter = gson.<Date>getAdapter(Date.class);
|
||||
return new TypeAdapter<Timestamp>() {
|
||||
public Timestamp read(JsonReader in) throws IOException {
|
||||
Date date = dateTypeAdapter.read(in);
|
||||
return (date != null) ? new Timestamp(date.getTime()) : null;
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Timestamp value) throws IOException {
|
||||
dateTypeAdapter.write(out, value);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapter<Calendar> CALENDAR = new TypeAdapter<Calendar>() {
|
||||
private static final String YEAR = "year";
|
||||
|
||||
private static final String MONTH = "month";
|
||||
|
||||
private static final String DAY_OF_MONTH = "dayOfMonth";
|
||||
|
||||
private static final String HOUR_OF_DAY = "hourOfDay";
|
||||
|
||||
private static final String MINUTE = "minute";
|
||||
|
||||
private static final String SECOND = "second";
|
||||
|
||||
public Calendar read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
in.beginObject();
|
||||
int year = 0;
|
||||
int month = 0;
|
||||
int dayOfMonth = 0;
|
||||
int hourOfDay = 0;
|
||||
int minute = 0;
|
||||
int second = 0;
|
||||
while (in.peek() != JsonToken.END_OBJECT) {
|
||||
String name = in.nextName();
|
||||
int value = in.nextInt();
|
||||
if ("year".equals(name)) {
|
||||
year = value;
|
||||
continue;
|
||||
}
|
||||
if ("month".equals(name)) {
|
||||
month = value;
|
||||
continue;
|
||||
}
|
||||
if ("dayOfMonth".equals(name)) {
|
||||
dayOfMonth = value;
|
||||
continue;
|
||||
}
|
||||
if ("hourOfDay".equals(name)) {
|
||||
hourOfDay = value;
|
||||
continue;
|
||||
}
|
||||
if ("minute".equals(name)) {
|
||||
minute = value;
|
||||
continue;
|
||||
}
|
||||
if ("second".equals(name))
|
||||
second = value;
|
||||
}
|
||||
in.endObject();
|
||||
return new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second);
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Calendar value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
out.beginObject();
|
||||
out.name("year");
|
||||
out.value((long)value.get(1));
|
||||
out.name("month");
|
||||
out.value((long)value.get(2));
|
||||
out.name("dayOfMonth");
|
||||
out.value((long)value.get(5));
|
||||
out.name("hourOfDay");
|
||||
out.value((long)value.get(11));
|
||||
out.name("minute");
|
||||
out.value((long)value.get(12));
|
||||
out.name("second");
|
||||
out.value((long)value.get(13));
|
||||
out.endObject();
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory CALENDAR_FACTORY = TypeAdapters.<Calendar>newFactoryForMultipleTypes(Calendar.class, GregorianCalendar.class, CALENDAR);
|
||||
|
||||
public static final TypeAdapter<Locale> LOCALE = new TypeAdapter<Locale>() {
|
||||
public Locale read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
String locale = in.nextString();
|
||||
StringTokenizer tokenizer = new StringTokenizer(locale, "_");
|
||||
String language = null;
|
||||
String country = null;
|
||||
String variant = null;
|
||||
if (tokenizer.hasMoreElements())
|
||||
language = tokenizer.nextToken();
|
||||
if (tokenizer.hasMoreElements())
|
||||
country = tokenizer.nextToken();
|
||||
if (tokenizer.hasMoreElements())
|
||||
variant = tokenizer.nextToken();
|
||||
if (country == null && variant == null)
|
||||
return new Locale(language);
|
||||
if (variant == null)
|
||||
return new Locale(language, country);
|
||||
return new Locale(language, country, variant);
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Locale value) throws IOException {
|
||||
out.value((value == null) ? null : value.toString());
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory LOCALE_FACTORY = TypeAdapters.<Locale>newFactory(Locale.class, LOCALE);
|
||||
|
||||
public static final TypeAdapter<JsonElement> JSON_ELEMENT = new TypeAdapter<JsonElement>() {
|
||||
public JsonElement read(JsonReader in) throws IOException {
|
||||
String number;
|
||||
JsonArray array;
|
||||
JsonObject object;
|
||||
switch (in.peek()) {
|
||||
case STRING:
|
||||
return new JsonPrimitive(in.nextString());
|
||||
case NUMBER:
|
||||
number = in.nextString();
|
||||
return new JsonPrimitive((Number)new LazilyParsedNumber(number));
|
||||
case BOOLEAN:
|
||||
return new JsonPrimitive(in.nextBoolean());
|
||||
case NULL:
|
||||
in.nextNull();
|
||||
return JsonNull.INSTANCE;
|
||||
case BEGIN_ARRAY:
|
||||
array = new JsonArray();
|
||||
in.beginArray();
|
||||
while (in.hasNext())
|
||||
array.add(read(in));
|
||||
in.endArray();
|
||||
return array;
|
||||
case BEGIN_OBJECT:
|
||||
object = new JsonObject();
|
||||
in.beginObject();
|
||||
while (in.hasNext())
|
||||
object.add(in.nextName(), read(in));
|
||||
in.endObject();
|
||||
return object;
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, JsonElement value) throws IOException {
|
||||
if (value == null || value.isJsonNull()) {
|
||||
out.nullValue();
|
||||
} else if (value.isJsonPrimitive()) {
|
||||
JsonPrimitive primitive = value.getAsJsonPrimitive();
|
||||
if (primitive.isNumber()) {
|
||||
out.value(primitive.getAsNumber());
|
||||
} else if (primitive.isBoolean()) {
|
||||
out.value(primitive.getAsBoolean());
|
||||
} else {
|
||||
out.value(primitive.getAsString());
|
||||
}
|
||||
} else if (value.isJsonArray()) {
|
||||
out.beginArray();
|
||||
for (JsonElement e : (Iterable<JsonElement>)value.getAsJsonArray())
|
||||
write(out, e);
|
||||
out.endArray();
|
||||
} else if (value.isJsonObject()) {
|
||||
out.beginObject();
|
||||
for (Map.Entry<String, JsonElement> e : value.getAsJsonObject().entrySet()) {
|
||||
out.name(e.getKey());
|
||||
write(out, e.getValue());
|
||||
}
|
||||
out.endObject();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Couldn't write " + value.getClass());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapterFactory JSON_ELEMENT_FACTORY = TypeAdapters.<JsonElement>newTypeHierarchyFactory(JsonElement.class, JSON_ELEMENT);
|
||||
|
||||
private static final class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
|
||||
private final Map<String, T> nameToConstant = new HashMap<String, T>();
|
||||
|
||||
private final Map<T, String> constantToName = new HashMap<T, String>();
|
||||
|
||||
public EnumTypeAdapter(Class<T> classOfT) {
|
||||
try {
|
||||
for (T constant : classOfT.getEnumConstants()) {
|
||||
String name = constant.name();
|
||||
SerializedName annotation = classOfT.getField(name).<SerializedName>getAnnotation(SerializedName.class);
|
||||
if (annotation != null)
|
||||
name = annotation.value();
|
||||
this.nameToConstant.put(name, constant);
|
||||
this.constantToName.put(constant, name);
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
public T read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
return this.nameToConstant.get(in.nextString());
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, T value) throws IOException {
|
||||
out.value((value == null) ? null : this.constantToName.get(value));
|
||||
}
|
||||
}
|
||||
|
||||
public static final TypeAdapterFactory ENUM_FACTORY = newEnumTypeHierarchyFactory();
|
||||
|
||||
public static TypeAdapterFactory newEnumTypeHierarchyFactory() {
|
||||
return new TypeAdapterFactory() {
|
||||
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();
|
||||
return new TypeAdapters.EnumTypeAdapter<T>(rawType);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <TT> TypeAdapterFactory newFactory(final TypeToken<TT> type, final TypeAdapter<TT> typeAdapter) {
|
||||
return new TypeAdapterFactory() {
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
return typeToken.equals(type) ? typeAdapter : null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <TT> TypeAdapterFactory newFactory(final Class<TT> type, final TypeAdapter<TT> typeAdapter) {
|
||||
return new TypeAdapterFactory() {
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
return (typeToken.getRawType() == type) ? typeAdapter : null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Factory[type=" + type.getName() + ",adapter=" + typeAdapter + "]";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <TT> TypeAdapterFactory newFactory(final Class<TT> unboxed, final Class<TT> boxed, final TypeAdapter<? super TT> typeAdapter) {
|
||||
return new TypeAdapterFactory() {
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
Class<? super T> rawType = typeToken.getRawType();
|
||||
return (rawType == unboxed || rawType == boxed) ? typeAdapter : null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Factory[type=" + boxed.getName() + "+" + unboxed.getName() + ",adapter=" + typeAdapter + "]";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <TT> TypeAdapterFactory newFactoryForMultipleTypes(final Class<TT> base, final Class<? extends TT> sub, final TypeAdapter<? super TT> typeAdapter) {
|
||||
return new TypeAdapterFactory() {
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
Class<? super T> rawType = typeToken.getRawType();
|
||||
return (rawType == base || rawType == sub) ? typeAdapter : null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Factory[type=" + base.getName() + "+" + sub.getName() + ",adapter=" + typeAdapter + "]";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <TT> TypeAdapterFactory newTypeHierarchyFactory(final Class<TT> clazz, final TypeAdapter<TT> typeAdapter) {
|
||||
return new TypeAdapterFactory() {
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
return clazz.isAssignableFrom(typeToken.getRawType()) ? typeAdapter : null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Factory[typeHierarchy=" + clazz.getName() + ",adapter=" + typeAdapter + "]";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
package com.google.gson.reflect;
|
||||
|
||||
import com.google.gson.internal.$Gson$Preconditions;
|
||||
import com.google.gson.internal.$Gson$Types;
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TypeToken<T> {
|
||||
final Class<? super T> rawType;
|
||||
|
||||
final Type type;
|
||||
|
||||
final int hashCode;
|
||||
|
||||
protected TypeToken() {
|
||||
this.type = getSuperclassTypeParameter(getClass());
|
||||
this.rawType = $Gson$Types.getRawType(this.type);
|
||||
this.hashCode = this.type.hashCode();
|
||||
}
|
||||
|
||||
TypeToken(Type type) {
|
||||
this.type = $Gson$Types.canonicalize($Gson$Preconditions.<Type>checkNotNull(type));
|
||||
this.rawType = $Gson$Types.getRawType(this.type);
|
||||
this.hashCode = this.type.hashCode();
|
||||
}
|
||||
|
||||
static Type getSuperclassTypeParameter(Class<?> subclass) {
|
||||
Type superclass = subclass.getGenericSuperclass();
|
||||
if (superclass instanceof Class)
|
||||
throw new RuntimeException("Missing type parameter.");
|
||||
ParameterizedType parameterized = (ParameterizedType)superclass;
|
||||
return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
|
||||
}
|
||||
|
||||
public final Class<? super T> getRawType() {
|
||||
return this.rawType;
|
||||
}
|
||||
|
||||
public final Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean isAssignableFrom(Class<?> cls) {
|
||||
return isAssignableFrom((Type)cls);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean isAssignableFrom(Type from) {
|
||||
if (from == null)
|
||||
return false;
|
||||
if (this.type.equals(from))
|
||||
return true;
|
||||
if (this.type instanceof Class)
|
||||
return this.rawType.isAssignableFrom($Gson$Types.getRawType(from));
|
||||
if (this.type instanceof ParameterizedType)
|
||||
return isAssignableFrom(from, (ParameterizedType)this.type, new HashMap<String, Type>());
|
||||
if (this.type instanceof GenericArrayType)
|
||||
return (this.rawType.isAssignableFrom($Gson$Types.getRawType(from)) && isAssignableFrom(from, (GenericArrayType)this.type));
|
||||
throw buildUnexpectedTypeError(this.type, new Class<?>[] { Class.class, ParameterizedType.class, GenericArrayType.class });
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean isAssignableFrom(TypeToken<?> token) {
|
||||
return isAssignableFrom(token.getType());
|
||||
}
|
||||
|
||||
private static boolean isAssignableFrom(Type<?> from, GenericArrayType to) {
|
||||
Type toGenericComponentType = to.getGenericComponentType();
|
||||
if (toGenericComponentType instanceof ParameterizedType) {
|
||||
Type<?> t = from;
|
||||
if (from instanceof GenericArrayType) {
|
||||
t = ((GenericArrayType)from).getGenericComponentType();
|
||||
} else if (from instanceof Class) {
|
||||
Class<?> classType = (Class)from;
|
||||
while (classType.isArray())
|
||||
classType = classType.getComponentType();
|
||||
t = classType;
|
||||
}
|
||||
return isAssignableFrom(t, (ParameterizedType)toGenericComponentType, new HashMap<String, Type>());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isAssignableFrom(Type from, ParameterizedType to, Map<String, Type> typeVarMap) {
|
||||
if (from == null)
|
||||
return false;
|
||||
if (to.equals(from))
|
||||
return true;
|
||||
Class<?> clazz = $Gson$Types.getRawType(from);
|
||||
ParameterizedType ptype = null;
|
||||
if (from instanceof ParameterizedType)
|
||||
ptype = (ParameterizedType)from;
|
||||
if (ptype != null) {
|
||||
Type[] tArgs = ptype.getActualTypeArguments();
|
||||
TypeVariable<?>[] tParams = clazz.getTypeParameters();
|
||||
for (int i = 0; i < tArgs.length; i++) {
|
||||
Type arg = tArgs[i];
|
||||
TypeVariable<?> var = tParams[i];
|
||||
while (arg instanceof TypeVariable) {
|
||||
TypeVariable<?> v = (TypeVariable)arg;
|
||||
arg = typeVarMap.get(v.getName());
|
||||
}
|
||||
typeVarMap.put(var.getName(), arg);
|
||||
}
|
||||
if (typeEquals(ptype, to, typeVarMap))
|
||||
return true;
|
||||
}
|
||||
for (Type itype : clazz.getGenericInterfaces()) {
|
||||
if (isAssignableFrom(itype, to, new HashMap<String, Type>(typeVarMap)))
|
||||
return true;
|
||||
}
|
||||
Type sType = clazz.getGenericSuperclass();
|
||||
return isAssignableFrom(sType, to, new HashMap<String, Type>(typeVarMap));
|
||||
}
|
||||
|
||||
private static boolean typeEquals(ParameterizedType from, ParameterizedType to, Map<String, Type> typeVarMap) {
|
||||
if (from.getRawType().equals(to.getRawType())) {
|
||||
Type[] fromArgs = from.getActualTypeArguments();
|
||||
Type[] toArgs = to.getActualTypeArguments();
|
||||
for (int i = 0; i < fromArgs.length; i++) {
|
||||
if (!matches(fromArgs[i], toArgs[i], typeVarMap))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static AssertionError buildUnexpectedTypeError(Type token, Class<?>... expected) {
|
||||
StringBuilder exceptionMessage = new StringBuilder("Unexpected type. Expected one of: ");
|
||||
for (Class<?> clazz : expected)
|
||||
exceptionMessage.append(clazz.getName()).append(", ");
|
||||
exceptionMessage.append("but got: ").append(token.getClass().getName()).append(", for type token: ").append(token.toString()).append('.');
|
||||
return new AssertionError((Object)exceptionMessage.toString());
|
||||
}
|
||||
|
||||
private static boolean matches(Type from, Type to, Map<String, Type> typeMap) {
|
||||
return (to.equals(from) || (from instanceof TypeVariable && to.equals(typeMap.get(((TypeVariable)from).getName()))));
|
||||
}
|
||||
|
||||
public final int hashCode() {
|
||||
return this.hashCode;
|
||||
}
|
||||
|
||||
public final boolean equals(Object o) {
|
||||
return (o instanceof TypeToken && $Gson$Types.equals(this.type, ((TypeToken)o).type));
|
||||
}
|
||||
|
||||
public final String toString() {
|
||||
return $Gson$Types.typeToString(this.type);
|
||||
}
|
||||
|
||||
public static TypeToken<?> get(Type type) {
|
||||
return new TypeToken(type);
|
||||
}
|
||||
|
||||
public static <T> TypeToken<T> get(Class<T> type) {
|
||||
return new TypeToken<T>(type);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,19 @@
|
|||
package com.google.gson.stream;
|
||||
|
||||
final class JsonScope {
|
||||
static final int EMPTY_ARRAY = 1;
|
||||
|
||||
static final int NONEMPTY_ARRAY = 2;
|
||||
|
||||
static final int EMPTY_OBJECT = 3;
|
||||
|
||||
static final int DANGLING_NAME = 4;
|
||||
|
||||
static final int NONEMPTY_OBJECT = 5;
|
||||
|
||||
static final int EMPTY_DOCUMENT = 6;
|
||||
|
||||
static final int NONEMPTY_DOCUMENT = 7;
|
||||
|
||||
static final int CLOSED = 8;
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.google.gson.stream;
|
||||
|
||||
public enum JsonToken {
|
||||
BEGIN_ARRAY, END_ARRAY, BEGIN_OBJECT, END_OBJECT, NAME, STRING, NUMBER, BOOLEAN, NULL, END_DOCUMENT;
|
||||
}
|
||||
|
|
@ -0,0 +1,315 @@
|
|||
package com.google.gson.stream;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.Flushable;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
public class JsonWriter implements Closeable, Flushable {
|
||||
private static final String[] REPLACEMENT_CHARS = new String[128];
|
||||
|
||||
static {
|
||||
for (int i = 0; i <= 31; i++)
|
||||
REPLACEMENT_CHARS[i] = String.format("\\u%04x", i);
|
||||
REPLACEMENT_CHARS[34] = "\\\"";
|
||||
REPLACEMENT_CHARS[92] = "\\\\";
|
||||
REPLACEMENT_CHARS[9] = "\\t";
|
||||
REPLACEMENT_CHARS[8] = "\\b";
|
||||
REPLACEMENT_CHARS[10] = "\\n";
|
||||
REPLACEMENT_CHARS[13] = "\\r";
|
||||
REPLACEMENT_CHARS[12] = "\\f";
|
||||
}
|
||||
|
||||
private static final String[] HTML_SAFE_REPLACEMENT_CHARS = (String[])REPLACEMENT_CHARS.clone();
|
||||
|
||||
private final Writer out;
|
||||
|
||||
static {
|
||||
HTML_SAFE_REPLACEMENT_CHARS[60] = "\\u003c";
|
||||
HTML_SAFE_REPLACEMENT_CHARS[62] = "\\u003e";
|
||||
HTML_SAFE_REPLACEMENT_CHARS[38] = "\\u0026";
|
||||
HTML_SAFE_REPLACEMENT_CHARS[61] = "\\u003d";
|
||||
HTML_SAFE_REPLACEMENT_CHARS[39] = "\\u0027";
|
||||
}
|
||||
|
||||
private int[] stack = new int[32];
|
||||
|
||||
private int stackSize = 0;
|
||||
|
||||
private String indent;
|
||||
|
||||
private String separator;
|
||||
|
||||
private boolean lenient;
|
||||
|
||||
private boolean htmlSafe;
|
||||
|
||||
private String deferredName;
|
||||
|
||||
private boolean serializeNulls;
|
||||
|
||||
public JsonWriter(Writer out) {
|
||||
push(6);
|
||||
this.separator = ":";
|
||||
this.serializeNulls = true;
|
||||
if (out == null)
|
||||
throw new NullPointerException("out == null");
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
public final void setIndent(String indent) {
|
||||
if (indent.length() == 0) {
|
||||
this.indent = null;
|
||||
this.separator = ":";
|
||||
} else {
|
||||
this.indent = indent;
|
||||
this.separator = ": ";
|
||||
}
|
||||
}
|
||||
|
||||
public final void setLenient(boolean lenient) {
|
||||
this.lenient = lenient;
|
||||
}
|
||||
|
||||
public boolean isLenient() {
|
||||
return this.lenient;
|
||||
}
|
||||
|
||||
public final void setHtmlSafe(boolean htmlSafe) {
|
||||
this.htmlSafe = htmlSafe;
|
||||
}
|
||||
|
||||
public final boolean isHtmlSafe() {
|
||||
return this.htmlSafe;
|
||||
}
|
||||
|
||||
public final void setSerializeNulls(boolean serializeNulls) {
|
||||
this.serializeNulls = serializeNulls;
|
||||
}
|
||||
|
||||
public final boolean getSerializeNulls() {
|
||||
return this.serializeNulls;
|
||||
}
|
||||
|
||||
public JsonWriter beginArray() throws IOException {
|
||||
writeDeferredName();
|
||||
return open(1, "[");
|
||||
}
|
||||
|
||||
public JsonWriter endArray() throws IOException {
|
||||
return close(1, 2, "]");
|
||||
}
|
||||
|
||||
public JsonWriter beginObject() throws IOException {
|
||||
writeDeferredName();
|
||||
return open(3, "{");
|
||||
}
|
||||
|
||||
public JsonWriter endObject() throws IOException {
|
||||
return close(3, 5, "}");
|
||||
}
|
||||
|
||||
private JsonWriter open(int empty, String openBracket) throws IOException {
|
||||
beforeValue(true);
|
||||
push(empty);
|
||||
this.out.write(openBracket);
|
||||
return this;
|
||||
}
|
||||
|
||||
private JsonWriter close(int empty, int nonempty, String closeBracket) throws IOException {
|
||||
int context = peek();
|
||||
if (context != nonempty && context != empty)
|
||||
throw new IllegalStateException("Nesting problem.");
|
||||
if (this.deferredName != null)
|
||||
throw new IllegalStateException("Dangling name: " + this.deferredName);
|
||||
this.stackSize--;
|
||||
if (context == nonempty)
|
||||
newline();
|
||||
this.out.write(closeBracket);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void push(int newTop) {
|
||||
if (this.stackSize == this.stack.length) {
|
||||
int[] newStack = new int[this.stackSize * 2];
|
||||
System.arraycopy(this.stack, 0, newStack, 0, this.stackSize);
|
||||
this.stack = newStack;
|
||||
}
|
||||
this.stack[this.stackSize++] = newTop;
|
||||
}
|
||||
|
||||
private int peek() {
|
||||
if (this.stackSize == 0)
|
||||
throw new IllegalStateException("JsonWriter is closed.");
|
||||
return this.stack[this.stackSize - 1];
|
||||
}
|
||||
|
||||
private void replaceTop(int topOfStack) {
|
||||
this.stack[this.stackSize - 1] = topOfStack;
|
||||
}
|
||||
|
||||
public JsonWriter name(String name) throws IOException {
|
||||
if (name == null)
|
||||
throw new NullPointerException("name == null");
|
||||
if (this.deferredName != null)
|
||||
throw new IllegalStateException();
|
||||
if (this.stackSize == 0)
|
||||
throw new IllegalStateException("JsonWriter is closed.");
|
||||
this.deferredName = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
private void writeDeferredName() throws IOException {
|
||||
if (this.deferredName != null) {
|
||||
beforeName();
|
||||
string(this.deferredName);
|
||||
this.deferredName = null;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonWriter value(String value) throws IOException {
|
||||
if (value == null)
|
||||
return nullValue();
|
||||
writeDeferredName();
|
||||
beforeValue(false);
|
||||
string(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonWriter nullValue() throws IOException {
|
||||
if (this.deferredName != null)
|
||||
if (this.serializeNulls) {
|
||||
writeDeferredName();
|
||||
} else {
|
||||
this.deferredName = null;
|
||||
return this;
|
||||
}
|
||||
beforeValue(false);
|
||||
this.out.write("null");
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonWriter value(boolean value) throws IOException {
|
||||
writeDeferredName();
|
||||
beforeValue(false);
|
||||
this.out.write(value ? "true" : "false");
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonWriter value(double value) throws IOException {
|
||||
if (Double.isNaN(value) || Double.isInfinite(value))
|
||||
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
|
||||
writeDeferredName();
|
||||
beforeValue(false);
|
||||
this.out.append(Double.toString(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonWriter value(long value) throws IOException {
|
||||
writeDeferredName();
|
||||
beforeValue(false);
|
||||
this.out.write(Long.toString(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonWriter value(Number value) throws IOException {
|
||||
if (value == null)
|
||||
return nullValue();
|
||||
writeDeferredName();
|
||||
String string = value.toString();
|
||||
if (!this.lenient && (string.equals("-Infinity") || string.equals("Infinity") || string.equals("NaN")))
|
||||
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
|
||||
beforeValue(false);
|
||||
this.out.append(string);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
if (this.stackSize == 0)
|
||||
throw new IllegalStateException("JsonWriter is closed.");
|
||||
this.out.flush();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
this.out.close();
|
||||
int size = this.stackSize;
|
||||
if (size > 1 || (size == 1 && this.stack[size - 1] != 7))
|
||||
throw new IOException("Incomplete document");
|
||||
this.stackSize = 0;
|
||||
}
|
||||
|
||||
private void string(String value) throws IOException {
|
||||
String[] replacements = this.htmlSafe ? HTML_SAFE_REPLACEMENT_CHARS : REPLACEMENT_CHARS;
|
||||
this.out.write("\"");
|
||||
int last = 0;
|
||||
int length = value.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
String replacement;
|
||||
char c = value.charAt(i);
|
||||
if (c < '\u0080') {
|
||||
replacement = replacements[c];
|
||||
if (replacement == null)
|
||||
continue;
|
||||
} else if (c == '
') {
|
||||
replacement = "\\u2028";
|
||||
} else if (c == '
') {
|
||||
replacement = "\\u2029";
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
if (last < i)
|
||||
this.out.write(value, last, i - last);
|
||||
this.out.write(replacement);
|
||||
last = i + 1;
|
||||
}
|
||||
if (last < length)
|
||||
this.out.write(value, last, length - last);
|
||||
this.out.write("\"");
|
||||
}
|
||||
|
||||
private void newline() throws IOException {
|
||||
if (this.indent == null)
|
||||
return;
|
||||
this.out.write("\n");
|
||||
for (int i = 1, size = this.stackSize; i < size; i++)
|
||||
this.out.write(this.indent);
|
||||
}
|
||||
|
||||
private void beforeName() throws IOException {
|
||||
int context = peek();
|
||||
if (context == 5) {
|
||||
this.out.write(44);
|
||||
} else if (context != 3) {
|
||||
throw new IllegalStateException("Nesting problem.");
|
||||
}
|
||||
newline();
|
||||
replaceTop(4);
|
||||
}
|
||||
|
||||
private void beforeValue(boolean root) throws IOException {
|
||||
switch (peek()) {
|
||||
case 7:
|
||||
if (!this.lenient)
|
||||
throw new IllegalStateException("JSON must have only one top-level value.");
|
||||
case 6:
|
||||
if (!this.lenient && !root)
|
||||
throw new IllegalStateException("JSON must start with an array or an object.");
|
||||
replaceTop(7);
|
||||
break;
|
||||
case 1:
|
||||
replaceTop(2);
|
||||
newline();
|
||||
break;
|
||||
case 2:
|
||||
this.out.append(',');
|
||||
newline();
|
||||
break;
|
||||
case 4:
|
||||
this.out.append(this.separator);
|
||||
replaceTop(5);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Nesting problem.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.google.gson.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class MalformedJsonException extends IOException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public MalformedJsonException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public MalformedJsonException(String msg, Throwable throwable) {
|
||||
super(msg);
|
||||
initCause(throwable);
|
||||
}
|
||||
|
||||
public MalformedJsonException(Throwable throwable) {
|
||||
initCause(throwable);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue