Nice documentation for TypeAdapter.

This commit is contained in:
Jesse Wilson 2011-12-03 19:46:25 +00:00
parent 8ee2c24f61
commit f602bce9f5
21 changed files with 673 additions and 386 deletions

View File

@ -195,8 +195,8 @@ public final class RuntimeTypeAdapterFactory<T> implements TypeAdapter.Factory {
} }
return new TypeAdapter<T>() { return new TypeAdapter<T>() {
@Override public T read(JsonReader reader) throws IOException { @Override public T read(JsonReader in) throws IOException {
JsonElement jsonElement = Streams.parse(reader); JsonElement jsonElement = Streams.parse(in);
JsonElement labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName); JsonElement labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName);
if (labelJsonElement == null) { if (labelJsonElement == null) {
throw new JsonParseException("cannot deserialize " + baseType throw new JsonParseException("cannot deserialize " + baseType
@ -212,7 +212,7 @@ public final class RuntimeTypeAdapterFactory<T> implements TypeAdapter.Factory {
return delegate.fromJsonTree(jsonElement); return delegate.fromJsonTree(jsonElement);
} }
@Override public void write(JsonWriter writer, T value) throws IOException { @Override public void write(JsonWriter out, T value) throws IOException {
Class<?> srcType = value.getClass(); Class<?> srcType = value.getClass();
String label = subtypeToLabel.get(srcType); String label = subtypeToLabel.get(srcType);
@SuppressWarnings("unchecked") // registration requires that subtype extends T @SuppressWarnings("unchecked") // registration requires that subtype extends T
@ -231,7 +231,7 @@ public final class RuntimeTypeAdapterFactory<T> implements TypeAdapter.Factory {
for (Map.Entry<String, JsonElement> e : jsonObject.entrySet()) { for (Map.Entry<String, JsonElement> e : jsonObject.entrySet()) {
clone.add(e.getKey(), e.getValue()); clone.add(e.getKey(), e.getValue());
} }
Streams.write(clone, writer); Streams.write(clone, out);
} }
}; };
} }

View File

@ -251,21 +251,21 @@ public final class Gson {
return TypeAdapters.DOUBLE; return TypeAdapters.DOUBLE;
} }
return new TypeAdapter<Number>() { return new TypeAdapter<Number>() {
@Override public Double read(JsonReader reader) throws IOException { @Override public Double read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return reader.nextDouble(); return in.nextDouble();
} }
@Override public void write(JsonWriter writer, Number value) throws IOException { @Override public void write(JsonWriter out, Number value) throws IOException {
if (value == null) { if (value == null) {
writer.nullValue(); out.nullValue();
return; return;
} }
double doubleValue = value.doubleValue(); double doubleValue = value.doubleValue();
checkValidFloatingPoint(doubleValue); checkValidFloatingPoint(doubleValue);
writer.value(value); out.value(value);
} }
}; };
} }
@ -275,21 +275,21 @@ public final class Gson {
return TypeAdapters.FLOAT; return TypeAdapters.FLOAT;
} }
return new TypeAdapter<Number>() { return new TypeAdapter<Number>() {
@Override public Float read(JsonReader reader) throws IOException { @Override public Float read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return (float) reader.nextDouble(); return (float) in.nextDouble();
} }
@Override public void write(JsonWriter writer, Number value) throws IOException { @Override public void write(JsonWriter out, Number value) throws IOException {
if (value == null) { if (value == null) {
writer.nullValue(); out.nullValue();
return; return;
} }
float floatValue = value.floatValue(); float floatValue = value.floatValue();
checkValidFloatingPoint(floatValue); checkValidFloatingPoint(floatValue);
writer.value(value); out.value(value);
} }
}; };
} }
@ -307,19 +307,19 @@ public final class Gson {
return TypeAdapters.LONG; return TypeAdapters.LONG;
} }
return new TypeAdapter<Number>() { return new TypeAdapter<Number>() {
@Override public Number read(JsonReader reader) throws IOException { @Override public Number read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return reader.nextLong(); return in.nextLong();
} }
@Override public void write(JsonWriter writer, Number value) throws IOException { @Override public void write(JsonWriter out, Number value) throws IOException {
if (value == null) { if (value == null) {
writer.nullValue(); out.nullValue();
return; return;
} }
writer.value(value.toString()); out.value(value.toString());
} }
}; };
} }
@ -828,18 +828,18 @@ public final class Gson {
delegate = typeAdapter; delegate = typeAdapter;
} }
@Override public T read(JsonReader reader) throws IOException { @Override public T read(JsonReader in) throws IOException {
if (delegate == null) { if (delegate == null) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
return delegate.read(reader); return delegate.read(in);
} }
@Override public void write(JsonWriter writer, T value) throws IOException { @Override public void write(JsonWriter out, T value) throws IOException {
if (delegate == null) { if (delegate == null) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
delegate.write(writer, value); delegate.write(out, value);
} }
} }

View File

@ -61,6 +61,9 @@ import java.lang.reflect.Type;
* Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdDeserializer()).create(); * Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdDeserializer()).create();
* </pre> * </pre>
* *
* <p>New applications should prefer {@link TypeAdapter}, whose streaming API
* is more efficient than this interface's tree API.
*
* @author Inderjeet Singh * @author Inderjeet Singh
* @author Joel Leitch * @author Joel Leitch
* *

View File

@ -60,6 +60,9 @@ import java.lang.reflect.Type;
* Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdSerializer()).create(); * Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdSerializer()).create();
* </pre> * </pre>
* *
* <p>New applications should prefer {@link TypeAdapter}, whose streaming API
* is more efficient than this interface's tree API.
*
* @author Inderjeet Singh * @author Inderjeet Singh
* @author Joel Leitch * @author Joel Leitch
* *

View File

@ -47,28 +47,28 @@ final class TreeTypeAdapter<T> extends TypeAdapter<T> {
this.skipPast = skipPast; this.skipPast = skipPast;
} }
@Override public T read(JsonReader reader) throws IOException { @Override public T read(JsonReader in) throws IOException {
if (deserializer == null) { if (deserializer == null) {
return delegate().read(reader); return delegate().read(in);
} }
JsonElement value = Streams.parse(reader); JsonElement value = Streams.parse(in);
if (value.isJsonNull()) { if (value.isJsonNull()) {
return null; return null;
} }
return deserializer.deserialize(value, typeToken.getType(), gson.deserializationContext); return deserializer.deserialize(value, typeToken.getType(), gson.deserializationContext);
} }
@Override public void write(JsonWriter writer, T value) throws IOException { @Override public void write(JsonWriter out, T value) throws IOException {
if (serializer == null) { if (serializer == null) {
delegate().write(writer, value); delegate().write(out, value);
return; return;
} }
if (value == null) { if (value == null) {
writer.nullValue(); out.nullValue();
return; return;
} }
JsonElement tree = serializer.serialize(value, typeToken.getType(), gson.serializationContext); JsonElement tree = serializer.serialize(value, typeToken.getType(), gson.serializationContext);
Streams.write(tree,writer); Streams.write(tree, out);
} }
private TypeAdapter<T> delegate() { private TypeAdapter<T> delegate() {

View File

@ -16,8 +16,8 @@
package com.google.gson; package com.google.gson;
import com.google.gson.internal.bind.JsonTreeReader;
import com.google.gson.internal.bind.JsonElementWriter; import com.google.gson.internal.bind.JsonElementWriter;
import com.google.gson.internal.bind.JsonTreeReader;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter; import com.google.gson.stream.JsonWriter;
@ -27,51 +27,188 @@ import java.io.StringReader;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.Writer; import java.io.Writer;
// TODO: nice documentation
/** /**
* Converts between Java objects and JSON. Applications use type adapters both
* for customizing types' JSON forms, and for JSON conversions.
*
* <h3>Defining a type's JSON form</h3>
* By default Gson converts application classes to JSON using its built-in type
* adapters. Change your Java objects' JSON representation by subclassing {@code
* TypeAdapter} and registering the subclass with a {@code GsonBuilder}. Here's
* an example of a type adapter for an (X,Y) coordinate point: <pre> {@code
*
* public class PointAdapter extends TypeAdapter<Point> {
* public Point read(JsonReader reader) throws IOException {
* if (reader.peek() == JsonToken.NULL) {
* reader.nextNull();
* return null;
* }
* String xy = reader.nextString();
* String[] parts = xy.split(",");
* int x = Integer.parseInt(parts[0]);
* int y = Integer.parseInt(parts[1]);
* return new Point(x, y);
* }
* public void write(JsonWriter writer, Point value) throws IOException {
* if (value == null) {
* writer.nullValue();
* return;
* }
* String xy = value.getX() + "," + value.getY();
* writer.value(xy);
* }
* }}</pre>
* With this type adapter installed, Gson will convert {@code Points} to JSON as
* strings like {@code "5,8"} rather than objects like {@code {"x":5,"y":8}}. In
* this case the type adapter binds a rich Java class to a compact JSON value.
*
* <p>The {@link #read(JsonReader) read()} method must read exactly one value
* and {@link #write(JsonWriter,Object) write()} must write exactly one value.
* For primitive types this is means readers should make exactly one call to
* <code>next<i>Type</i>()</code> and writers should make exactly one call to
* one of <code>value()</code> or <code>nullValue()</code>. For composite types,
* type adapters should start with a call to <code>begin<i>Type</i>()</code>,
* convert the entire contents of the object or array, and finish with a call
* to <code>end<i>Type</i>()</code>. Failing to convert a value or converting
* too many values will disrupt the cadence of the caller and may cause the
* application to crash.
*
* <p>Type adapters should be prepared to read null from the stream and write it
* to the stream. If your {@code Gson} instance has been configured to {@link
* GsonBuilder#serializeNulls()}, these will be written to the final document.
* Otherwise the value (and the corresponding name when writing to a JSON
* object) will be omitted automatically. In either case your type adapter must
* handle null.
*
* <p>To use a custom type adapter with Gson, you must <i>register</i> it with a
* {@link GsonBuilder}: <pre> {@code
*
* GsonBuilder builder = new GsonBuilder();
* builder.registerTypeAdapter(Point.class, new PointAdapter());
* ...
* Gson gson = builder.create();
* }</pre>
*
* <h3>JSON Conversion</h3>
* <p>Retrieve a type adapter from a {@code Gson} instance to deserialize a JSON
* document into a Java object: <pre> {@code
*
* String json = "{'origin':'0,0','points':['1,2','3,4']}";
* TypeAdapter<Graph> graphAdapter = gson.getAdapter(Graph.class);
* Graph graph = graphAdapter.fromJson(json);
* }</pre>
* ...or serialize a Java object to a JSON document: <pre> {@code
*
* Graph graph = new Graph(...);
* TypeAdapter<Graph> graphAdapter = gson.getAdapter(Graph.class);
* String json = graphAdapter.toJson(graph);
* }</pre>
*
* <p>Type adapters are <strong>type-specific</strong>. For example, a {@code
* TypeAdapter<Date>} can convert {@code Date} instances to JSON and JSON to
* instances of {@code Date}, but cannot convert any other types.
* *
* @since 2.1 * @since 2.1
*/ */
public abstract class TypeAdapter<T> { public abstract class TypeAdapter<T> {
public abstract T read(JsonReader reader) throws IOException;
public abstract void write(JsonWriter writer, T value) throws IOException;
/**
* Writes one JSON value (an array, object, string, number, boolean or null)
* for {@code value}.
*
* @param value the Java object to write. May be null.
*/
public abstract void write(JsonWriter out, T value) throws IOException;
/**
* Converts {@code value} to a JSON document and writes it to {@code out}.
* Unlike Gson's similar {@link Gson#toJson(JsonElement, Appendable) toJson}
* method, this write is strict. Create a {@link
* JsonWriter#setLenient(boolean) lenient} {@code JsonWriter} and call
* {@link #write(com.google.gson.stream.JsonWriter, Object)} for lenient
* writing.
*
* @param value the Java object to convert. May be null.
*/
public final void toJson(Writer out, T value) throws IOException {
JsonWriter writer = new JsonWriter(out);
write(writer, value);
}
/**
* Converts {@code value} to a JSON document. Unlike Gson's similar {@link
* Gson#toJson(Object) toJson} method, this write is strict. Create a {@link
* JsonWriter#setLenient(boolean) lenient} {@code JsonWriter} and call
* {@link #write(com.google.gson.stream.JsonWriter, Object)} for lenient
* writing.
*
* @param value the Java object to convert. May be null.
*/
public final String toJson(T value) throws IOException { public final String toJson(T value) throws IOException {
StringWriter stringWriter = new StringWriter(); StringWriter stringWriter = new StringWriter();
toJson(stringWriter, value); toJson(stringWriter, value);
return stringWriter.toString(); return stringWriter.toString();
} }
public final void toJson(Writer out, T value) throws IOException { /**
JsonWriter writer = new JsonWriter(out); * Converts {@code value} to a JSON tree.
write(writer, value); *
} * @param value the Java object to convert. May be null.
* @return the converted JSON tree. May be {@link JsonNull}.
public final T fromJson(String json) throws IOException { */
return fromJson(new StringReader(json)); public JsonElement toJsonTree(T value) {
}
public final T fromJson(Reader in) throws IOException {
JsonReader reader = new JsonReader(in);
reader.setLenient(true);
return read(reader);
}
public JsonElement toJsonTree(T src) {
try { try {
JsonElementWriter jsonWriter = new JsonElementWriter(); JsonElementWriter jsonWriter = new JsonElementWriter();
jsonWriter.setLenient(true); jsonWriter.setLenient(true);
write(jsonWriter, src); write(jsonWriter, value);
return jsonWriter.get(); return jsonWriter.get();
} catch (IOException e) { } catch (IOException e) {
throw new JsonIOException(e); throw new JsonIOException(e);
} }
} }
public T fromJsonTree(JsonElement json) { /**
* Reads one JSON value (an array, object, string, number, boolean or null)
* and converts it to a Java object. Returns the converted object.
*
* @return the converted Java object. May be null.
*/
public abstract T read(JsonReader in) throws IOException;
/**
* Converts the JSON document in {@code in} to a Java object. Unlike Gson's
* similar {@link Gson#fromJson(java.io.Reader, Class) fromJson} method, this
* read is strict. Create a {@link JsonReader#setLenient(boolean) lenient}
* {@code JsonReader} and call {@link #read(JsonReader)} for lenient reading.
*
* @return the converted Java object. May be null.
*/
public final T fromJson(Reader in) throws IOException {
JsonReader reader = new JsonReader(in);
reader.setLenient(true); // TODO: non-lenient?
return read(reader);
}
/**
* Converts the JSON document in {@code json} to a Java object. Unlike Gson's
* similar {@link Gson#fromJson(String, Class) fromJson} method, this read is
* strict. Create a {@link JsonReader#setLenient(boolean) lenient} {@code
* JsonReader} and call {@link #read(JsonReader)} for lenient reading.
*
* @return the converted Java object. May be null.
*/
public final T fromJson(String json) throws IOException {
return fromJson(new StringReader(json));
}
/**
* Converts {@code jsonTree} to a Java object.
*
* @param jsonTree the Java object to convert. May be {@link JsonNull}.
*/
public T fromJsonTree(JsonElement jsonTree) {
try { try {
JsonReader jsonReader = new JsonTreeReader(json); JsonReader jsonReader = new JsonTreeReader(jsonTree);
jsonReader.setLenient(true); jsonReader.setLenient(true);
return read(jsonReader); return read(jsonReader);
} catch (IOException e) { } catch (IOException e) {
@ -80,9 +217,153 @@ public abstract class TypeAdapter<T> {
} }
/** /**
* Creates type adapters for set of related types. Type adapter factories are
* most useful when several types share similar structure in their JSON form.
*
* <h3>Example: Converting enums to lowercase</h3>
* In this example, we implement a factory that creates type adapters for all
* enums. The type adapters will write enums in lowercase, despite the fact
* that they're defined in {@code CONSTANT_CASE} in the corresponding Java
* model: <pre> {@code
*
* public class LowercaseEnumTypeAdapterFactory implements TypeAdapter.Factory {
* public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
* Class<T> rawType = (Class<T>) type.getRawType();
* if (!rawType.isEnum()) {
* return null;
* }
*
* final Map<String, T> lowercaseToConstant = new HashMap<String, T>();
* for (T constant : rawType.getEnumConstants()) {
* lowercaseToConstant.put(toLowercase(constant), constant);
* }
*
* return new TypeAdapter<T>() {
* public void write(JsonWriter out, T value) throws IOException {
* if (value == null) {
* out.nullValue();
* } else {
* out.value(toLowercase(value));
* }
* }
*
* public T read(JsonReader reader) throws IOException {
* if (reader.peek() == JsonToken.NULL) {
* reader.nextNull();
* return null;
* } else {
* return lowercaseToConstant.get(reader.nextString());
* }
* }
* };
* }
*
* private String toLowercase(Object o) {
* return o.toString().toLowerCase(Locale.US);
* }
* }
* }</pre>
*
* <p>Type adapter factories select which types they provide type adapters
* for. If a factory cannot support a given type, it must return null when
* that type is passed to {@link #create}. Factories should expect {@code
* create()} to be called on them for many types and should return null for
* most of those types. In the above example the factory returns null for
* calls to {@code create()} where {@code type} is not an enum.
*
* <p>A factory is typically called once per type, but the returned type
* adapter may be used many times. It is most efficient to do expensive work
* like reflection in {@code create()} so that the type adapter's {@code
* read()} and {@code write()} methods can be very fast. In this example the
* mapping from lowercase name to enum value is computed eagerly.
*
* <p>As with type adapters, factories must be <i>registered</i> with a {@link
* GsonBuilder} for them to take effect: <pre> {@code
*
* GsonBuilder builder = new GsonBuilder();
* builder.registerTypeAdapterFactory(new LowercaseEnumTypeAdapterFactory());
* ...
* Gson gson = builder.create();
* }</pre>
* If multiple factories support the same type, the factory registered earlier
* takes precedence.
*
* <h3>Example: composing other type adapters</h3>
* In this example we implement a factory for Guava's {@code Multiset}
* collection type. The factory can be used to create type adapters for
* multisets of any element type: the type adapter for {@code
* Multiset<String>} is different from the type adapter for {@code
* Multiset<URL>}.
*
* <p>The type adapter <i>delegates</i> to another type adapter for the
* multiset elements. It figures out the element type by reflecting on the
* multiset's type token. A {@code Gson} is passed in to {@code create} for
* just this purpose: <pre> {@code
*
* public class MultisetTypeAdapterFactory implements TypeAdapter.Factory {
* public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
* Type type = typeToken.getType();
* if (typeToken.getRawType() != Multiset.class
* || !(type instanceof ParameterizedType)) {
* return null;
* }
*
* Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
* TypeAdapter<?> elementAdapter = gson.getAdapter(TypeToken.get(elementType));
* return (TypeAdapter<T>) newMultisetAdapter(elementAdapter);
* }
*
* private <E> TypeAdapter<Multiset<E>> newMultisetAdapter(
* final TypeAdapter<E> elementAdapter) {
* return new TypeAdapter<Multiset<E>>() {
* public void write(JsonWriter out, Multiset<E> value) throws IOException {
* if (value == null) {
* out.nullValue();
* return;
* }
*
* out.beginArray();
* for (Multiset.Entry<E> entry : value.entrySet()) {
* out.value(entry.getCount());
* elementAdapter.write(out, entry.getElement());
* }
* out.endArray();
* }
*
* public Multiset<E> read(JsonReader in) throws IOException {
* if (in.peek() == JsonToken.NULL) {
* in.nextNull();
* return null;
* }
*
* Multiset<E> result = LinkedHashMultiset.create();
* in.beginArray();
* while (in.hasNext()) {
* int count = in.nextInt();
* E element = elementAdapter.read(in);
* result.add(element, count);
* }
* in.endArray();
* return result;
* }
* };
* }
* }
* }</pre>
* Delegating from one type adapter to another is extremely powerful; it's
* the foundation of how Gson converts Java objects and collections. Whenever
* possible your factory should retrieve its delegate type adapter in the
* {@code create()} method; this ensures potentially-expensive type adapter
* creation happens only once.
*
* @since 2.1 * @since 2.1
*/ */
public interface Factory { public interface Factory {
/**
* Returns a type adapter for {@code type}, or null if this factory doesn't
* support {@code type}.
*/
<T> TypeAdapter<T> create(Gson gson, TypeToken<T> type); <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type);
} }
} }

View File

@ -120,20 +120,20 @@ public final class Excluder implements TypeAdapter.Factory, Cloneable {
/** The delegate is lazily created because it may not be needed, and creating it may fail. */ /** The delegate is lazily created because it may not be needed, and creating it may fail. */
private TypeAdapter<T> delegate; private TypeAdapter<T> delegate;
@Override public T read(JsonReader reader) throws IOException { @Override public T read(JsonReader in) throws IOException {
if (skipDeserialize) { if (skipDeserialize) {
reader.skipValue(); in.skipValue();
return null; return null;
} }
return delegate().read(reader); return delegate().read(in);
} }
@Override public void write(JsonWriter writer, T value) throws IOException { @Override public void write(JsonWriter out, T value) throws IOException {
if (skipSerialize) { if (skipSerialize) {
writer.nullValue(); out.nullValue();
return; return;
} }
delegate().write(writer, value); delegate().write(out, value);
} }
private TypeAdapter<T> delegate() { private TypeAdapter<T> delegate() {

View File

@ -59,19 +59,19 @@ public final class ArrayTypeAdapter<E> extends TypeAdapter<Object> {
this.componentType = componentType; this.componentType = componentType;
} }
public Object read(JsonReader reader) throws IOException { public Object read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
List<E> list = new ArrayList<E>(); List<E> list = new ArrayList<E>();
reader.beginArray(); in.beginArray();
while (reader.hasNext()) { while (in.hasNext()) {
E instance = componentTypeAdapter.read(reader); E instance = componentTypeAdapter.read(in);
list.add(instance); list.add(instance);
} }
reader.endArray(); in.endArray();
Object array = Array.newInstance(componentType, list.size()); Object array = Array.newInstance(componentType, list.size());
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
Array.set(array, i, list.get(i)); Array.set(array, i, list.get(i));
@ -80,17 +80,17 @@ public final class ArrayTypeAdapter<E> extends TypeAdapter<Object> {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override public void write(JsonWriter writer, Object array) throws IOException { @Override public void write(JsonWriter out, Object array) throws IOException {
if (array == null) { if (array == null) {
writer.nullValue(); out.nullValue();
return; return;
} }
writer.beginArray(); out.beginArray();
for (int i = 0, length = Array.getLength(array); i < length; i++) { for (int i = 0, length = Array.getLength(array); i < length; i++) {
E value = (E) Array.get(array, i); E value = (E) Array.get(array, i);
componentTypeAdapter.write(writer, value); componentTypeAdapter.write(out, value);
} }
writer.endArray(); out.endArray();
} }
} }

View File

@ -33,20 +33,20 @@ import java.math.BigDecimal;
public final class BigDecimalTypeAdapter extends TypeAdapter<BigDecimal> { public final class BigDecimalTypeAdapter extends TypeAdapter<BigDecimal> {
@Override @Override
public BigDecimal read(JsonReader reader) throws IOException { public BigDecimal read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
try { try {
return new BigDecimal(reader.nextString()); return new BigDecimal(in.nextString());
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new JsonSyntaxException(e); throw new JsonSyntaxException(e);
} }
} }
@Override @Override
public void write(JsonWriter writer, BigDecimal value) throws IOException { public void write(JsonWriter out, BigDecimal value) throws IOException {
writer.value(value); out.value(value);
} }
} }

View File

@ -32,20 +32,20 @@ import java.math.BigInteger;
public final class BigIntegerTypeAdapter extends TypeAdapter<BigInteger> { public final class BigIntegerTypeAdapter extends TypeAdapter<BigInteger> {
@Override @Override
public BigInteger read(JsonReader reader) throws IOException { public BigInteger read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
try { try {
return new BigInteger(reader.nextString()); return new BigInteger(in.nextString());
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new JsonSyntaxException(e); throw new JsonSyntaxException(e);
} }
} }
@Override @Override
public void write(JsonWriter writer, BigInteger value) throws IOException { public void write(JsonWriter out, BigInteger value) throws IOException {
writer.value(value); out.value(value);
} }
} }

View File

@ -68,33 +68,33 @@ public final class CollectionTypeAdapterFactory implements TypeAdapter.Factory {
this.constructor = constructor; this.constructor = constructor;
} }
public Collection<E> read(JsonReader reader) throws IOException { public Collection<E> read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
Collection<E> collection = constructor.construct(); Collection<E> collection = constructor.construct();
reader.beginArray(); in.beginArray();
while (reader.hasNext()) { while (in.hasNext()) {
E instance = elementTypeAdapter.read(reader); E instance = elementTypeAdapter.read(in);
collection.add(instance); collection.add(instance);
} }
reader.endArray(); in.endArray();
return collection; return collection;
} }
public void write(JsonWriter writer, Collection<E> collection) throws IOException { public void write(JsonWriter out, Collection<E> collection) throws IOException {
if (collection == null) { if (collection == null) {
writer.nullValue(); // TODO: better policy here? out.nullValue(); // TODO: better policy here?
return; return;
} }
writer.beginArray(); out.beginArray();
for (E element : collection) { for (E element : collection) {
elementTypeAdapter.write(writer, element); elementTypeAdapter.write(out, element);
} }
writer.endArray(); out.endArray();
} }
} }
} }

View File

@ -57,12 +57,12 @@ public final class DateTypeAdapter extends TypeAdapter<Date> {
return iso8601Format; return iso8601Format;
} }
@Override public Date read(JsonReader reader) throws IOException { @Override public Date read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return deserializeToDate(reader.nextString()); return deserializeToDate(in.nextString());
} }
private synchronized Date deserializeToDate(String json) { private synchronized Date deserializeToDate(String json) {
@ -81,12 +81,12 @@ public final class DateTypeAdapter extends TypeAdapter<Date> {
} }
} }
@Override public synchronized void write(JsonWriter writer, Date value) throws IOException { @Override public synchronized void write(JsonWriter out, Date value) throws IOException {
if (value == null) { if (value == null) {
writer.nullValue(); out.nullValue();
return; return;
} }
String dateFormatAsString = enUsFormat.format(value); String dateFormatAsString = enUsFormat.format(value);
writer.value(dateFormatAsString); out.value(dateFormatAsString);
} }
} }

View File

@ -156,57 +156,57 @@ public final class MapTypeAdapterFactory implements TypeAdapter.Factory {
this.constructor = constructor; this.constructor = constructor;
} }
public Map<K, V> read(JsonReader reader) throws IOException { public Map<K, V> read(JsonReader in) throws IOException {
JsonToken peek = reader.peek(); JsonToken peek = in.peek();
if (peek == JsonToken.NULL) { if (peek == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
Map<K, V> map = constructor.construct(); Map<K, V> map = constructor.construct();
if (peek == JsonToken.BEGIN_ARRAY) { if (peek == JsonToken.BEGIN_ARRAY) {
reader.beginArray(); in.beginArray();
while (reader.hasNext()) { while (in.hasNext()) {
reader.beginArray(); // entry array in.beginArray(); // entry array
K key = keyTypeAdapter.read(reader); K key = keyTypeAdapter.read(in);
V value = valueTypeAdapter.read(reader); V value = valueTypeAdapter.read(in);
V replaced = map.put(key, value); V replaced = map.put(key, value);
if (replaced != null) { if (replaced != null) {
throw new JsonSyntaxException("duplicate key: " + key); throw new JsonSyntaxException("duplicate key: " + key);
} }
reader.endArray(); in.endArray();
} }
reader.endArray(); in.endArray();
} else { } else {
reader.beginObject(); in.beginObject();
while (reader.hasNext()) { while (in.hasNext()) {
JsonReaderInternalAccess.INSTANCE.promoteNameToValue(reader); JsonReaderInternalAccess.INSTANCE.promoteNameToValue(in);
K key = keyTypeAdapter.read(reader); K key = keyTypeAdapter.read(in);
V value = valueTypeAdapter.read(reader); V value = valueTypeAdapter.read(in);
V replaced = map.put(key, value); V replaced = map.put(key, value);
if (replaced != null) { if (replaced != null) {
throw new JsonSyntaxException("duplicate key: " + key); throw new JsonSyntaxException("duplicate key: " + key);
} }
} }
reader.endObject(); in.endObject();
} }
return map; return map;
} }
public void write(JsonWriter writer, Map<K, V> map) throws IOException { public void write(JsonWriter out, Map<K, V> map) throws IOException {
if (map == null) { if (map == null) {
writer.nullValue(); out.nullValue();
return; return;
} }
if (!complexMapKeySerialization) { if (!complexMapKeySerialization) {
writer.beginObject(); out.beginObject();
for (Map.Entry<K, V> entry : map.entrySet()) { for (Map.Entry<K, V> entry : map.entrySet()) {
writer.name(String.valueOf(entry.getKey())); out.name(String.valueOf(entry.getKey()));
valueTypeAdapter.write(writer, entry.getValue()); valueTypeAdapter.write(out, entry.getValue());
} }
writer.endObject(); out.endObject();
return; return;
} }
@ -222,22 +222,22 @@ public final class MapTypeAdapterFactory implements TypeAdapter.Factory {
} }
if (hasComplexKeys) { if (hasComplexKeys) {
writer.beginArray(); out.beginArray();
for (int i = 0; i < keys.size(); i++) { for (int i = 0; i < keys.size(); i++) {
writer.beginArray(); // entry array out.beginArray(); // entry array
Streams.write(keys.get(i), writer); Streams.write(keys.get(i), out);
valueTypeAdapter.write(writer, values.get(i)); valueTypeAdapter.write(out, values.get(i));
writer.endArray(); out.endArray();
} }
writer.endArray(); out.endArray();
} else { } else {
writer.beginObject(); out.beginObject();
for (int i = 0; i < keys.size(); i++) { for (int i = 0; i < keys.size(); i++) {
JsonElement keyElement = keys.get(i); JsonElement keyElement = keys.get(i);
writer.name(keyToString(keyElement)); out.name(keyToString(keyElement));
valueTypeAdapter.write(writer, values.get(i)); valueTypeAdapter.write(out, values.get(i));
} }
writer.endObject(); out.endObject();
} }
} }

View File

@ -49,38 +49,38 @@ public final class ObjectTypeAdapter extends TypeAdapter<Object> {
this.gson = gson; this.gson = gson;
} }
@Override public Object read(JsonReader reader) throws IOException { @Override public Object read(JsonReader in) throws IOException {
JsonToken token = reader.peek(); JsonToken token = in.peek();
switch (token) { switch (token) {
case BEGIN_ARRAY: case BEGIN_ARRAY:
List<Object> list = new ArrayList<Object>(); List<Object> list = new ArrayList<Object>();
reader.beginArray(); in.beginArray();
while (reader.hasNext()) { while (in.hasNext()) {
list.add(read(reader)); list.add(read(in));
} }
reader.endArray(); in.endArray();
return list; return list;
case BEGIN_OBJECT: case BEGIN_OBJECT:
Map<String, Object> map = new LinkedHashMap<String, Object>(); Map<String, Object> map = new LinkedHashMap<String, Object>();
reader.beginObject(); in.beginObject();
while (reader.hasNext()) { while (in.hasNext()) {
map.put(reader.nextName(), read(reader)); map.put(in.nextName(), read(in));
} }
reader.endObject(); in.endObject();
return map; return map;
case STRING: case STRING:
return reader.nextString(); return in.nextString();
case NUMBER: case NUMBER:
return reader.nextDouble(); return in.nextDouble();
case BOOLEAN: case BOOLEAN:
return reader.nextBoolean(); return in.nextBoolean();
case NULL: case NULL:
reader.nextNull(); in.nextNull();
return null; return null;
} }
@ -88,19 +88,19 @@ public final class ObjectTypeAdapter extends TypeAdapter<Object> {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override public void write(JsonWriter writer, Object value) throws IOException { @Override public void write(JsonWriter out, Object value) throws IOException {
if (value == null) { if (value == null) {
writer.nullValue(); out.nullValue();
return; return;
} }
TypeAdapter<Object> typeAdapter = (TypeAdapter<Object>) gson.getAdapter(value.getClass()); TypeAdapter<Object> typeAdapter = (TypeAdapter<Object>) gson.getAdapter(value.getClass());
if (typeAdapter instanceof ObjectTypeAdapter) { if (typeAdapter instanceof ObjectTypeAdapter) {
writer.beginObject(); out.beginObject();
writer.endObject(); out.endObject();
return; return;
} }
typeAdapter.write(writer, value); typeAdapter.write(out, value);
} }
} }

View File

@ -154,9 +154,9 @@ public final class ReflectiveTypeAdapterFactory implements TypeAdapter.Factory {
} }
@Override @Override
public T read(JsonReader reader) throws IOException { public T read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
@ -165,15 +165,15 @@ public final class ReflectiveTypeAdapterFactory implements TypeAdapter.Factory {
// TODO: null out the other fields? // TODO: null out the other fields?
try { try {
reader.beginObject(); in.beginObject();
while (reader.hasNext()) { while (in.hasNext()) {
String name = reader.nextName(); String name = in.nextName();
BoundField field = boundFields.get(name); BoundField field = boundFields.get(name);
if (field == null || !field.deserialized) { if (field == null || !field.deserialized) {
// TODO: define a better policy // TODO: define a better policy
reader.skipValue(); in.skipValue();
} else { } else {
field.read(reader, instance); field.read(in, instance);
} }
} }
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
@ -181,29 +181,29 @@ public final class ReflectiveTypeAdapterFactory implements TypeAdapter.Factory {
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new AssertionError(e); throw new AssertionError(e);
} }
reader.endObject(); in.endObject();
return instance; return instance;
} }
@Override @Override
public void write(JsonWriter writer, T value) throws IOException { public void write(JsonWriter out, T value) throws IOException {
if (value == null) { if (value == null) {
writer.nullValue(); // TODO: better policy here? out.nullValue(); // TODO: better policy here?
return; return;
} }
writer.beginObject(); out.beginObject();
try { try {
for (BoundField boundField : boundFields.values()) { for (BoundField boundField : boundFields.values()) {
if (boundField.serialized) { if (boundField.serialized) {
writer.name(boundField.name); out.name(boundField.name);
boundField.write(writer, value); boundField.write(out, value);
} }
} }
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new AssertionError(); throw new AssertionError();
} }
writer.endObject(); out.endObject();
} }
} }
} }

View File

@ -46,13 +46,13 @@ public final class SqlDateTypeAdapter extends TypeAdapter<java.sql.Date> {
private final DateFormat format = new SimpleDateFormat("MMM d, yyyy"); private final DateFormat format = new SimpleDateFormat("MMM d, yyyy");
@Override @Override
public synchronized java.sql.Date read(JsonReader reader) throws IOException { public synchronized java.sql.Date read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
try { try {
final long utilDate = format.parse(reader.nextString()).getTime(); final long utilDate = format.parse(in.nextString()).getTime();
return new java.sql.Date(utilDate); return new java.sql.Date(utilDate);
} catch (ParseException e) { } catch (ParseException e) {
throw new JsonSyntaxException(e); throw new JsonSyntaxException(e);
@ -60,7 +60,7 @@ public final class SqlDateTypeAdapter extends TypeAdapter<java.sql.Date> {
} }
@Override @Override
public synchronized void write(JsonWriter writer, java.sql.Date value) throws IOException { public synchronized void write(JsonWriter out, java.sql.Date value) throws IOException {
writer.value(value == null ? null : format.format(value)); out.value(value == null ? null : format.format(value));
} }
} }

View File

@ -46,20 +46,20 @@ public final class TimeTypeAdapter extends TypeAdapter<Time> {
private final DateFormat format = new SimpleDateFormat("hh:mm:ss a"); private final DateFormat format = new SimpleDateFormat("hh:mm:ss a");
@Override public synchronized Time read(JsonReader reader) throws IOException { @Override public synchronized Time read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
try { try {
Date date = format.parse(reader.nextString()); Date date = format.parse(in.nextString());
return new Time(date.getTime()); return new Time(date.getTime());
} catch (ParseException e) { } catch (ParseException e) {
throw new JsonSyntaxException(e); throw new JsonSyntaxException(e);
} }
} }
@Override public synchronized void write(JsonWriter writer, Time value) throws IOException { @Override public synchronized void write(JsonWriter out, Time value) throws IOException {
writer.value(value == null ? null : format.format(value)); out.value(value == null ? null : format.format(value));
} }
} }

View File

@ -36,13 +36,13 @@ final class TypeAdapterRuntimeTypeWrapper<T> extends TypeAdapter<T> {
} }
@Override @Override
public T read(JsonReader reader) throws IOException { public T read(JsonReader in) throws IOException {
return delegate.read(reader); return delegate.read(in);
} }
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@Override @Override
public void write(JsonWriter writer, T value) throws IOException { public void write(JsonWriter out, T value) throws IOException {
// Order of preference for choosing type adapters // Order of preference for choosing type adapters
// First preference: a type adapter registered for the runtime type // First preference: a type adapter registered for the runtime type
// Second preference: a type adapter registered for the declared type // Second preference: a type adapter registered for the declared type
@ -65,7 +65,7 @@ final class TypeAdapterRuntimeTypeWrapper<T> extends TypeAdapter<T> {
chosen = runtimeTypeAdapter; chosen = runtimeTypeAdapter;
} }
} }
chosen.write(writer, value); chosen.write(out, value);
} }
/** /**

View File

@ -52,27 +52,27 @@ public final class TypeAdapters {
private TypeAdapters() {} private TypeAdapters() {}
public static final TypeAdapter<BitSet> BIT_SET = new TypeAdapter<BitSet>() { public static final TypeAdapter<BitSet> BIT_SET = new TypeAdapter<BitSet>() {
public BitSet read(JsonReader reader) throws IOException { public BitSet read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
BitSet bitset = new BitSet(); BitSet bitset = new BitSet();
reader.beginArray(); in.beginArray();
int i = 0; int i = 0;
JsonToken tokenType = reader.peek(); JsonToken tokenType = in.peek();
while (tokenType != JsonToken.END_ARRAY) { while (tokenType != JsonToken.END_ARRAY) {
boolean set; boolean set;
switch (tokenType) { switch (tokenType) {
case NUMBER: case NUMBER:
set = reader.nextInt() != 0; set = in.nextInt() != 0;
break; break;
case BOOLEAN: case BOOLEAN:
set = reader.nextBoolean(); set = in.nextBoolean();
break; break;
case STRING: case STRING:
String stringValue = reader.nextString(); String stringValue = in.nextString();
try { try {
set = Integer.parseInt(stringValue) != 0; set = Integer.parseInt(stringValue) != 0;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
@ -87,24 +87,24 @@ public final class TypeAdapters {
bitset.set(i); bitset.set(i);
} }
++i; ++i;
tokenType = reader.peek(); tokenType = in.peek();
} }
reader.endArray(); in.endArray();
return bitset; return bitset;
} }
public void write(JsonWriter writer, BitSet src) throws IOException { public void write(JsonWriter out, BitSet src) throws IOException {
if (src == null) { if (src == null) {
writer.nullValue(); out.nullValue();
return; return;
} }
writer.beginArray(); out.beginArray();
for (int i = 0; i < src.length(); i++) { for (int i = 0; i < src.length(); i++) {
int value = (src.get(i)) ? 1 : 0; int value = (src.get(i)) ? 1 : 0;
writer.value(value); out.value(value);
} }
writer.endArray(); out.endArray();
} }
}; };
@ -112,23 +112,23 @@ public final class TypeAdapters {
public static final TypeAdapter<Boolean> BOOLEAN = new TypeAdapter<Boolean>() { public static final TypeAdapter<Boolean> BOOLEAN = new TypeAdapter<Boolean>() {
@Override @Override
public Boolean read(JsonReader reader) throws IOException { public Boolean read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} else if (reader.peek() == JsonToken.STRING) { } else if (in.peek() == JsonToken.STRING) {
// support strings for compatibility with GSON 1.7 // support strings for compatibility with GSON 1.7
return Boolean.parseBoolean(reader.nextString()); return Boolean.parseBoolean(in.nextString());
} }
return reader.nextBoolean(); return in.nextBoolean();
} }
@Override @Override
public void write(JsonWriter writer, Boolean value) throws IOException { public void write(JsonWriter out, Boolean value) throws IOException {
if (value == null) { if (value == null) {
writer.nullValue(); out.nullValue();
return; return;
} }
writer.value(value); out.value(value);
} }
}; };
@ -137,16 +137,16 @@ public final class TypeAdapters {
* otherwise permitted. * otherwise permitted.
*/ */
public static final TypeAdapter<Boolean> BOOLEAN_AS_STRING = new TypeAdapter<Boolean>() { public static final TypeAdapter<Boolean> BOOLEAN_AS_STRING = new TypeAdapter<Boolean>() {
@Override public Boolean read(JsonReader reader) throws IOException { @Override public Boolean read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return Boolean.valueOf(reader.nextString()); return Boolean.valueOf(in.nextString());
} }
@Override public void write(JsonWriter writer, Boolean value) throws IOException { @Override public void write(JsonWriter out, Boolean value) throws IOException {
writer.value(value == null ? "null" : value.toString()); out.value(value == null ? "null" : value.toString());
} }
}; };
@ -155,21 +155,21 @@ public final class TypeAdapters {
public static final TypeAdapter<Number> BYTE = new TypeAdapter<Number>() { public static final TypeAdapter<Number> BYTE = new TypeAdapter<Number>() {
@Override @Override
public Number read(JsonReader reader) throws IOException { public Number read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
try { try {
int intValue = reader.nextInt(); int intValue = in.nextInt();
return (byte) intValue; return (byte) intValue;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new JsonSyntaxException(e); throw new JsonSyntaxException(e);
} }
} }
@Override @Override
public void write(JsonWriter writer, Number value) throws IOException { public void write(JsonWriter out, Number value) throws IOException {
writer.value(value); out.value(value);
} }
}; };
@ -178,20 +178,20 @@ public final class TypeAdapters {
public static final TypeAdapter<Number> SHORT = new TypeAdapter<Number>() { public static final TypeAdapter<Number> SHORT = new TypeAdapter<Number>() {
@Override @Override
public Number read(JsonReader reader) throws IOException { public Number read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
try { try {
return (short) reader.nextInt(); return (short) in.nextInt();
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new JsonSyntaxException(e); throw new JsonSyntaxException(e);
} }
} }
@Override @Override
public void write(JsonWriter writer, Number value) throws IOException { public void write(JsonWriter out, Number value) throws IOException {
writer.value(value); out.value(value);
} }
}; };
@ -200,20 +200,20 @@ public final class TypeAdapters {
public static final TypeAdapter<Number> INTEGER = new TypeAdapter<Number>() { public static final TypeAdapter<Number> INTEGER = new TypeAdapter<Number>() {
@Override @Override
public Number read(JsonReader reader) throws IOException { public Number read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
try { try {
return reader.nextInt(); return in.nextInt();
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new JsonSyntaxException(e); throw new JsonSyntaxException(e);
} }
} }
@Override @Override
public void write(JsonWriter writer, Number value) throws IOException { public void write(JsonWriter out, Number value) throws IOException {
writer.value(value); out.value(value);
} }
}; };
@ -222,70 +222,70 @@ public final class TypeAdapters {
public static final TypeAdapter<Number> LONG = new TypeAdapter<Number>() { public static final TypeAdapter<Number> LONG = new TypeAdapter<Number>() {
@Override @Override
public Number read(JsonReader reader) throws IOException { public Number read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
try { try {
return reader.nextLong(); return in.nextLong();
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new JsonSyntaxException(e); throw new JsonSyntaxException(e);
} }
} }
@Override @Override
public void write(JsonWriter writer, Number value) throws IOException { public void write(JsonWriter out, Number value) throws IOException {
writer.value(value); out.value(value);
} }
}; };
public static final TypeAdapter<Number> FLOAT = new TypeAdapter<Number>() { public static final TypeAdapter<Number> FLOAT = new TypeAdapter<Number>() {
@Override @Override
public Number read(JsonReader reader) throws IOException { public Number read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return (float) reader.nextDouble(); return (float) in.nextDouble();
} }
@Override @Override
public void write(JsonWriter writer, Number value) throws IOException { public void write(JsonWriter out, Number value) throws IOException {
writer.value(value); out.value(value);
} }
}; };
public static final TypeAdapter<Number> DOUBLE = new TypeAdapter<Number>() { public static final TypeAdapter<Number> DOUBLE = new TypeAdapter<Number>() {
@Override @Override
public Number read(JsonReader reader) throws IOException { public Number read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return reader.nextDouble(); return in.nextDouble();
} }
@Override @Override
public void write(JsonWriter writer, Number value) throws IOException { public void write(JsonWriter out, Number value) throws IOException {
writer.value(value); out.value(value);
} }
}; };
public static final TypeAdapter<Number> NUMBER = new TypeAdapter<Number>() { public static final TypeAdapter<Number> NUMBER = new TypeAdapter<Number>() {
@Override @Override
public Number read(JsonReader reader) throws IOException { public Number read(JsonReader in) throws IOException {
JsonToken jsonToken = reader.peek(); JsonToken jsonToken = in.peek();
switch (jsonToken) { switch (jsonToken) {
case NULL: case NULL:
reader.nextNull(); in.nextNull();
return null; return null;
case NUMBER: case NUMBER:
return new LazilyParsedNumber(reader.nextString()); return new LazilyParsedNumber(in.nextString());
default: default:
throw new JsonSyntaxException("Expecting number, got: " + jsonToken); throw new JsonSyntaxException("Expecting number, got: " + jsonToken);
} }
} }
@Override @Override
public void write(JsonWriter writer, Number value) throws IOException { public void write(JsonWriter out, Number value) throws IOException {
writer.value(value); out.value(value);
} }
}; };
@ -293,16 +293,16 @@ public final class TypeAdapters {
public static final TypeAdapter<Character> CHARACTER = new TypeAdapter<Character>() { public static final TypeAdapter<Character> CHARACTER = new TypeAdapter<Character>() {
@Override @Override
public Character read(JsonReader reader) throws IOException { public Character read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return reader.nextString().charAt(0); return in.nextString().charAt(0);
} }
@Override @Override
public void write(JsonWriter writer, Character value) throws IOException { public void write(JsonWriter out, Character value) throws IOException {
writer.value(value == null ? null : String.valueOf(value)); out.value(value == null ? null : String.valueOf(value));
} }
}; };
@ -311,21 +311,21 @@ public final class TypeAdapters {
public static final TypeAdapter<String> STRING = new TypeAdapter<String>() { public static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
@Override @Override
public String read(JsonReader reader) throws IOException { public String read(JsonReader in) throws IOException {
JsonToken peek = reader.peek(); JsonToken peek = in.peek();
if (peek == JsonToken.NULL) { if (peek == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
/* coerce booleans to strings for backwards compatibility */ /* coerce booleans to strings for backwards compatibility */
if (peek == JsonToken.BOOLEAN) { if (peek == JsonToken.BOOLEAN) {
return Boolean.toString(reader.nextBoolean()); return Boolean.toString(in.nextBoolean());
} }
return reader.nextString(); return in.nextString();
} }
@Override @Override
public void write(JsonWriter writer, String value) throws IOException { public void write(JsonWriter out, String value) throws IOException {
writer.value(value); out.value(value);
} }
}; };
@ -333,16 +333,16 @@ public final class TypeAdapters {
public static final TypeAdapter<StringBuilder> STRING_BUILDER = new TypeAdapter<StringBuilder>() { public static final TypeAdapter<StringBuilder> STRING_BUILDER = new TypeAdapter<StringBuilder>() {
@Override @Override
public StringBuilder read(JsonReader reader) throws IOException { public StringBuilder read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return new StringBuilder(reader.nextString()); return new StringBuilder(in.nextString());
} }
@Override @Override
public void write(JsonWriter writer, StringBuilder value) throws IOException { public void write(JsonWriter out, StringBuilder value) throws IOException {
writer.value(value == null ? null : value.toString()); out.value(value == null ? null : value.toString());
} }
}; };
@ -351,16 +351,16 @@ public final class TypeAdapters {
public static final TypeAdapter<StringBuffer> STRING_BUFFER = new TypeAdapter<StringBuffer>() { public static final TypeAdapter<StringBuffer> STRING_BUFFER = new TypeAdapter<StringBuffer>() {
@Override @Override
public StringBuffer read(JsonReader reader) throws IOException { public StringBuffer read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return new StringBuffer(reader.nextString()); return new StringBuffer(in.nextString());
} }
@Override @Override
public void write(JsonWriter writer, StringBuffer value) throws IOException { public void write(JsonWriter out, StringBuffer value) throws IOException {
writer.value(value == null ? null : value.toString()); out.value(value == null ? null : value.toString());
} }
}; };
@ -369,17 +369,17 @@ public final class TypeAdapters {
public static final TypeAdapter<URL> URL = new TypeAdapter<URL>() { public static final TypeAdapter<URL> URL = new TypeAdapter<URL>() {
@Override @Override
public URL read(JsonReader reader) throws IOException { public URL read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
String nextString = reader.nextString(); String nextString = in.nextString();
return "null".equals(nextString) ? null : new URL(nextString); return "null".equals(nextString) ? null : new URL(nextString);
} }
@Override @Override
public void write(JsonWriter writer, URL value) throws IOException { public void write(JsonWriter out, URL value) throws IOException {
writer.value(value == null ? null : value.toExternalForm()); out.value(value == null ? null : value.toExternalForm());
} }
}; };
@ -387,21 +387,21 @@ public final class TypeAdapters {
public static final TypeAdapter<URI> URI = new TypeAdapter<URI>() { public static final TypeAdapter<URI> URI = new TypeAdapter<URI>() {
@Override @Override
public URI read(JsonReader reader) throws IOException { public URI read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
try { try {
String nextString = reader.nextString(); String nextString = in.nextString();
return "null".equals(nextString) ? null : new URI(nextString); return "null".equals(nextString) ? null : new URI(nextString);
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
throw new JsonIOException(e); throw new JsonIOException(e);
} }
} }
@Override @Override
public void write(JsonWriter writer, URI value) throws IOException { public void write(JsonWriter out, URI value) throws IOException {
writer.value(value == null ? null : value.toASCIIString()); out.value(value == null ? null : value.toASCIIString());
} }
}; };
@ -409,16 +409,16 @@ public final class TypeAdapters {
public static final TypeAdapter<InetAddress> INET_ADDRESS = new TypeAdapter<InetAddress>() { public static final TypeAdapter<InetAddress> INET_ADDRESS = new TypeAdapter<InetAddress>() {
@Override @Override
public InetAddress read(JsonReader reader) throws IOException { public InetAddress read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return InetAddress.getByName(reader.nextString()); return InetAddress.getByName(in.nextString());
} }
@Override @Override
public void write(JsonWriter writer, InetAddress value) throws IOException { public void write(JsonWriter out, InetAddress value) throws IOException {
writer.value(value == null ? null : value.getHostAddress()); out.value(value == null ? null : value.getHostAddress());
} }
}; };
@ -427,16 +427,16 @@ public final class TypeAdapters {
public static final TypeAdapter<UUID> UUID = new TypeAdapter<UUID>() { public static final TypeAdapter<UUID> UUID = new TypeAdapter<UUID>() {
@Override @Override
public UUID read(JsonReader reader) throws IOException { public UUID read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return java.util.UUID.fromString(reader.nextString()); return java.util.UUID.fromString(in.nextString());
} }
@Override @Override
public void write(JsonWriter writer, UUID value) throws IOException { public void write(JsonWriter out, UUID value) throws IOException {
writer.value(value == null ? null : value.toString()); out.value(value == null ? null : value.toString());
} }
}; };
@ -451,13 +451,13 @@ public final class TypeAdapters {
final TypeAdapter<Date> dateTypeAdapter = gson.getAdapter(Date.class); final TypeAdapter<Date> dateTypeAdapter = gson.getAdapter(Date.class);
return (TypeAdapter<T>) new TypeAdapter<Timestamp>() { return (TypeAdapter<T>) new TypeAdapter<Timestamp>() {
@Override public Timestamp read(JsonReader reader) throws IOException { @Override public Timestamp read(JsonReader in) throws IOException {
Date date = dateTypeAdapter.read(reader); Date date = dateTypeAdapter.read(in);
return date != null ? new Timestamp(date.getTime()) : null; return date != null ? new Timestamp(date.getTime()) : null;
} }
@Override public void write(JsonWriter writer, Timestamp value) throws IOException { @Override public void write(JsonWriter out, Timestamp value) throws IOException {
dateTypeAdapter.write(writer, value); dateTypeAdapter.write(out, value);
} }
}; };
} }
@ -472,21 +472,21 @@ public final class TypeAdapters {
private static final String SECOND = "second"; private static final String SECOND = "second";
@Override @Override
public Calendar read(JsonReader reader) throws IOException { public Calendar read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
reader.beginObject(); in.beginObject();
int year = 0; int year = 0;
int month = 0; int month = 0;
int dayOfMonth = 0; int dayOfMonth = 0;
int hourOfDay = 0; int hourOfDay = 0;
int minute = 0; int minute = 0;
int second = 0; int second = 0;
while (reader.peek() != JsonToken.END_OBJECT) { while (in.peek() != JsonToken.END_OBJECT) {
String name = reader.nextName(); String name = in.nextName();
int value = reader.nextInt(); int value = in.nextInt();
if (YEAR.equals(name)) { if (YEAR.equals(name)) {
year = value; year = value;
} else if (MONTH.equals(name)) { } else if (MONTH.equals(name)) {
@ -501,30 +501,30 @@ public final class TypeAdapters {
second = value; second = value;
} }
} }
reader.endObject(); in.endObject();
return new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second); return new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second);
} }
@Override @Override
public void write(JsonWriter writer, Calendar value) throws IOException { public void write(JsonWriter out, Calendar value) throws IOException {
if (value == null) { if (value == null) {
writer.nullValue(); out.nullValue();
return; return;
} }
writer.beginObject(); out.beginObject();
writer.name(YEAR); out.name(YEAR);
writer.value(value.get(Calendar.YEAR)); out.value(value.get(Calendar.YEAR));
writer.name(MONTH); out.name(MONTH);
writer.value(value.get(Calendar.MONTH)); out.value(value.get(Calendar.MONTH));
writer.name(DAY_OF_MONTH); out.name(DAY_OF_MONTH);
writer.value(value.get(Calendar.DAY_OF_MONTH)); out.value(value.get(Calendar.DAY_OF_MONTH));
writer.name(HOUR_OF_DAY); out.name(HOUR_OF_DAY);
writer.value(value.get(Calendar.HOUR_OF_DAY)); out.value(value.get(Calendar.HOUR_OF_DAY));
writer.name(MINUTE); out.name(MINUTE);
writer.value(value.get(Calendar.MINUTE)); out.value(value.get(Calendar.MINUTE));
writer.name(SECOND); out.name(SECOND);
writer.value(value.get(Calendar.SECOND)); out.value(value.get(Calendar.SECOND));
writer.endObject(); out.endObject();
} }
}; };
@ -533,12 +533,12 @@ public final class TypeAdapters {
public static final TypeAdapter<Locale> LOCALE = new TypeAdapter<Locale>() { public static final TypeAdapter<Locale> LOCALE = new TypeAdapter<Locale>() {
@Override @Override
public Locale read(JsonReader reader) throws IOException { public Locale read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
String locale = reader.nextString(); String locale = in.nextString();
StringTokenizer tokenizer = new StringTokenizer(locale, "_"); StringTokenizer tokenizer = new StringTokenizer(locale, "_");
String language = null; String language = null;
String country = null; String country = null;
@ -561,41 +561,41 @@ public final class TypeAdapters {
} }
} }
@Override @Override
public void write(JsonWriter writer, Locale value) throws IOException { public void write(JsonWriter out, Locale value) throws IOException {
writer.value(value == null ? null : value.toString()); out.value(value == null ? null : value.toString());
} }
}; };
public static final TypeAdapter.Factory LOCALE_FACTORY = newFactory(Locale.class, LOCALE); public static final TypeAdapter.Factory LOCALE_FACTORY = newFactory(Locale.class, LOCALE);
public static final TypeAdapter<JsonElement> JSON_ELEMENT = new TypeAdapter<JsonElement>() { public static final TypeAdapter<JsonElement> JSON_ELEMENT = new TypeAdapter<JsonElement>() {
@Override public JsonElement read(JsonReader reader) throws IOException { @Override public JsonElement read(JsonReader in) throws IOException {
switch (reader.peek()) { switch (in.peek()) {
case STRING: case STRING:
return new JsonPrimitive(reader.nextString()); return new JsonPrimitive(in.nextString());
case NUMBER: case NUMBER:
String number = reader.nextString(); String number = in.nextString();
return new JsonPrimitive(new LazilyParsedNumber(number)); return new JsonPrimitive(new LazilyParsedNumber(number));
case BOOLEAN: case BOOLEAN:
return new JsonPrimitive(reader.nextBoolean()); return new JsonPrimitive(in.nextBoolean());
case NULL: case NULL:
reader.nextNull(); in.nextNull();
return JsonNull.INSTANCE; return JsonNull.INSTANCE;
case BEGIN_ARRAY: case BEGIN_ARRAY:
JsonArray array = new JsonArray(); JsonArray array = new JsonArray();
reader.beginArray(); in.beginArray();
while (reader.hasNext()) { while (in.hasNext()) {
array.add(read(reader)); array.add(read(in));
} }
reader.endArray(); in.endArray();
return array; return array;
case BEGIN_OBJECT: case BEGIN_OBJECT:
JsonObject object = new JsonObject(); JsonObject object = new JsonObject();
reader.beginObject(); in.beginObject();
while (reader.hasNext()) { while (in.hasNext()) {
object.add(reader.nextName(), read(reader)); object.add(in.nextName(), read(in));
} }
reader.endObject(); in.endObject();
return object; return object;
case END_DOCUMENT: case END_DOCUMENT:
case NAME: case NAME:
@ -606,33 +606,33 @@ public final class TypeAdapters {
} }
} }
@Override public void write(JsonWriter writer, JsonElement value) throws IOException { @Override public void write(JsonWriter out, JsonElement value) throws IOException {
if (value == null || value.isJsonNull()) { if (value == null || value.isJsonNull()) {
writer.nullValue(); out.nullValue();
} else if (value.isJsonPrimitive()) { } else if (value.isJsonPrimitive()) {
JsonPrimitive primitive = value.getAsJsonPrimitive(); JsonPrimitive primitive = value.getAsJsonPrimitive();
if (primitive.isNumber()) { if (primitive.isNumber()) {
writer.value(primitive.getAsNumber()); out.value(primitive.getAsNumber());
} else if (primitive.isBoolean()) { } else if (primitive.isBoolean()) {
writer.value(primitive.getAsBoolean()); out.value(primitive.getAsBoolean());
} else { } else {
writer.value(primitive.getAsString()); out.value(primitive.getAsString());
} }
} else if (value.isJsonArray()) { } else if (value.isJsonArray()) {
writer.beginArray(); out.beginArray();
for (JsonElement e : value.getAsJsonArray()) { for (JsonElement e : value.getAsJsonArray()) {
write(writer, e); write(out, e);
} }
writer.endArray(); out.endArray();
} else if (value.isJsonObject()) { } else if (value.isJsonObject()) {
writer.beginObject(); out.beginObject();
for (Map.Entry<String, JsonElement> e : value.getAsJsonObject().entrySet()) { for (Map.Entry<String, JsonElement> e : value.getAsJsonObject().entrySet()) {
writer.name(e.getKey()); out.name(e.getKey());
write(writer, e.getValue()); write(out, e.getValue());
} }
writer.endObject(); out.endObject();
} else { } else {
throw new IllegalArgumentException("Couldn't write " + value.getClass()); throw new IllegalArgumentException("Couldn't write " + value.getClass());
@ -649,16 +649,16 @@ public final class TypeAdapters {
public EnumTypeAdapter(Class<T> classOfT) { public EnumTypeAdapter(Class<T> classOfT) {
this.classOfT = classOfT; this.classOfT = classOfT;
} }
public T read(JsonReader reader) throws IOException { public T read(JsonReader in) throws IOException {
if (reader.peek() == JsonToken.NULL) { if (in.peek() == JsonToken.NULL) {
reader.nextNull(); in.nextNull();
return null; return null;
} }
return Enum.valueOf(classOfT, reader.nextString()); return Enum.valueOf(classOfT, in.nextString());
} }
public void write(JsonWriter writer, T value) throws IOException { public void write(JsonWriter out, T value) throws IOException {
writer.value(value == null ? null : value.name()); out.value(value == null ? null : value.name());
} }
} }

View File

@ -94,12 +94,12 @@ public final class StreamingTypeAdaptersTest extends TestCase {
private void usePersonNameAdapter() { private void usePersonNameAdapter() {
TypeAdapter<Person> personNameAdapter = new TypeAdapter<Person>() { TypeAdapter<Person> personNameAdapter = new TypeAdapter<Person>() {
@Override public Person read(JsonReader reader) throws IOException { @Override public Person read(JsonReader in) throws IOException {
String name = reader.nextString(); String name = in.nextString();
return new Person(name, -1); return new Person(name, -1);
} }
@Override public void write(JsonWriter writer, Person value) throws IOException { @Override public void write(JsonWriter out, Person value) throws IOException {
writer.value(value.name); out.value(value.name);
} }
}; };
miniGson = new GsonBuilder().registerTypeAdapter(Person.class, personNameAdapter).create(); miniGson = new GsonBuilder().registerTypeAdapter(Person.class, personNameAdapter).create();

View File

@ -118,11 +118,11 @@ public final class TypeAdapterPrecedenceTest extends TestCase {
private TypeAdapter<Foo> newTypeAdapter(final String name) { private TypeAdapter<Foo> newTypeAdapter(final String name) {
return new TypeAdapter<Foo>() { return new TypeAdapter<Foo>() {
@Override public Foo read(JsonReader reader) throws IOException { @Override public Foo read(JsonReader in) throws IOException {
return new Foo(reader.nextString() + " via " + name); return new Foo(in.nextString() + " via " + name);
} }
@Override public void write(JsonWriter writer, Foo value) throws IOException { @Override public void write(JsonWriter out, Foo value) throws IOException {
writer.value(value.name + " via " + name); out.value(value.name + " via " + name);
} }
}; };
} }