Add a type adapter for JsonElement, so it serializes just like everything else.
Fixes issue 362.
This commit is contained in:
parent
3a3870591e
commit
65df3b97ba
@ -248,6 +248,7 @@ public final class Gson {
|
||||
.typeAdapter(BigDecimal.class, new BigDecimalTypeAdapter())
|
||||
.typeAdapter(BigInteger.class, new BigIntegerTypeAdapter())
|
||||
.factory(new CollectionTypeAdapterFactory(constructorConstructor))
|
||||
.factory(TypeAdapters.JSON_ELEMENT_FACTORY)
|
||||
.factory(ObjectTypeAdapter.FACTORY);
|
||||
|
||||
for (TypeAdapter.Factory factory : typeAdapterFactories) {
|
||||
|
@ -16,27 +16,23 @@
|
||||
|
||||
package com.google.gson.internal;
|
||||
|
||||
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.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
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;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Reads and writes GSON parse trees over streams.
|
||||
*/
|
||||
public final class Streams {
|
||||
|
||||
/**
|
||||
* Takes a reader in any state and returns the next value as a JsonElement.
|
||||
*/
|
||||
@ -45,7 +41,7 @@ public final class Streams {
|
||||
try {
|
||||
reader.peek();
|
||||
isEmpty = false;
|
||||
return parseRecursive(reader);
|
||||
return TypeAdapters.JSON_ELEMENT.read(reader);
|
||||
} catch (EOFException e) {
|
||||
/*
|
||||
* For compatibility with JSON 1.5 and earlier, we return a JsonNull for
|
||||
@ -64,79 +60,11 @@ public final class Streams {
|
||||
}
|
||||
}
|
||||
|
||||
private static JsonElement parseRecursive(JsonReader reader) throws IOException {
|
||||
switch (reader.peek()) {
|
||||
case STRING:
|
||||
return new JsonPrimitive(reader.nextString());
|
||||
case NUMBER:
|
||||
String number = reader.nextString();
|
||||
return new JsonPrimitive(new LazilyParsedNumber(number));
|
||||
case BOOLEAN:
|
||||
return new JsonPrimitive(reader.nextBoolean());
|
||||
case NULL:
|
||||
reader.nextNull();
|
||||
return JsonNull.INSTANCE;
|
||||
case BEGIN_ARRAY:
|
||||
JsonArray array = new JsonArray();
|
||||
reader.beginArray();
|
||||
while (reader.hasNext()) {
|
||||
array.add(parseRecursive(reader));
|
||||
}
|
||||
reader.endArray();
|
||||
return array;
|
||||
case BEGIN_OBJECT:
|
||||
JsonObject object = new JsonObject();
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
object.add(reader.nextName(), parseRecursive(reader));
|
||||
}
|
||||
reader.endObject();
|
||||
return object;
|
||||
case END_DOCUMENT:
|
||||
case NAME:
|
||||
case END_OBJECT:
|
||||
case END_ARRAY:
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the JSON element to the writer, recursively.
|
||||
*/
|
||||
public static void write(JsonElement element, JsonWriter writer)
|
||||
throws IOException {
|
||||
if (element == null || element.isJsonNull()) {
|
||||
writer.nullValue();
|
||||
} else if (element.isJsonPrimitive()) {
|
||||
JsonPrimitive primitive = element.getAsJsonPrimitive();
|
||||
if (primitive.isNumber()) {
|
||||
writer.value(primitive.getAsNumber());
|
||||
} else if (primitive.isBoolean()) {
|
||||
writer.value(primitive.getAsBoolean());
|
||||
} else {
|
||||
writer.value(primitive.getAsString());
|
||||
}
|
||||
|
||||
} else if (element.isJsonArray()) {
|
||||
writer.beginArray();
|
||||
for (JsonElement e : element.getAsJsonArray()) {
|
||||
write(e, writer);
|
||||
}
|
||||
writer.endArray();
|
||||
|
||||
} else if (element.isJsonObject()) {
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, JsonElement> e : element.getAsJsonObject().entrySet()) {
|
||||
JsonElement value = e.getValue();
|
||||
writer.name(e.getKey());
|
||||
write(value, writer);
|
||||
}
|
||||
writer.endObject();
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("Couldn't write " + element.getClass());
|
||||
}
|
||||
public static void write(JsonElement element, JsonWriter writer) throws IOException {
|
||||
TypeAdapters.JSON_ELEMENT.write(writer, element);
|
||||
}
|
||||
|
||||
public static Writer writerForAppendable(Appendable appendable) {
|
||||
@ -183,4 +111,5 @@ public final class Streams {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,12 @@
|
||||
|
||||
package com.google.gson.internal.bind;
|
||||
|
||||
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.internal.LazilyParsedNumber;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
@ -34,6 +39,7 @@ import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -526,6 +532,81 @@ public final class TypeAdapters {
|
||||
|
||||
public static final TypeAdapter.Factory LOCALE_FACTORY = newFactory(Locale.class, LOCALE);
|
||||
|
||||
public static final TypeAdapter<JsonElement> JSON_ELEMENT = new TypeAdapter<JsonElement>() {
|
||||
@Override public JsonElement read(JsonReader reader) throws IOException {
|
||||
switch (reader.peek()) {
|
||||
case STRING:
|
||||
return new JsonPrimitive(reader.nextString());
|
||||
case NUMBER:
|
||||
String number = reader.nextString();
|
||||
return new JsonPrimitive(new LazilyParsedNumber(number));
|
||||
case BOOLEAN:
|
||||
return new JsonPrimitive(reader.nextBoolean());
|
||||
case NULL:
|
||||
reader.nextNull();
|
||||
return JsonNull.INSTANCE;
|
||||
case BEGIN_ARRAY:
|
||||
JsonArray array = new JsonArray();
|
||||
reader.beginArray();
|
||||
while (reader.hasNext()) {
|
||||
array.add(read(reader));
|
||||
}
|
||||
reader.endArray();
|
||||
return array;
|
||||
case BEGIN_OBJECT:
|
||||
JsonObject object = new JsonObject();
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
object.add(reader.nextName(), read(reader));
|
||||
}
|
||||
reader.endObject();
|
||||
return object;
|
||||
case END_DOCUMENT:
|
||||
case NAME:
|
||||
case END_OBJECT:
|
||||
case END_ARRAY:
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void write(JsonWriter writer, JsonElement value) throws IOException {
|
||||
if (value == null || value.isJsonNull()) {
|
||||
writer.nullValue();
|
||||
} else if (value.isJsonPrimitive()) {
|
||||
JsonPrimitive primitive = value.getAsJsonPrimitive();
|
||||
if (primitive.isNumber()) {
|
||||
writer.value(primitive.getAsNumber());
|
||||
} else if (primitive.isBoolean()) {
|
||||
writer.value(primitive.getAsBoolean());
|
||||
} else {
|
||||
writer.value(primitive.getAsString());
|
||||
}
|
||||
|
||||
} else if (value.isJsonArray()) {
|
||||
writer.beginArray();
|
||||
for (JsonElement e : value.getAsJsonArray()) {
|
||||
write(writer, e);
|
||||
}
|
||||
writer.endArray();
|
||||
|
||||
} else if (value.isJsonObject()) {
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, JsonElement> e : value.getAsJsonObject().entrySet()) {
|
||||
writer.name(e.getKey());
|
||||
write(writer, e.getValue());
|
||||
}
|
||||
writer.endObject();
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("Couldn't write " + value.getClass());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final TypeAdapter.Factory JSON_ELEMENT_FACTORY
|
||||
= newFactory(JsonElement.class, JSON_ELEMENT);
|
||||
|
||||
private static final class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
|
||||
private final Class<T> classOfT;
|
||||
|
||||
|
@ -17,10 +17,14 @@ package com.google.gson.functional;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
@ -459,6 +463,66 @@ public class DefaultTypeAdaptersTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testJsonPrimitiveSerialization() {
|
||||
assertEquals("5", gson.toJson(new JsonPrimitive(5), JsonElement.class));
|
||||
assertEquals("true", gson.toJson(new JsonPrimitive(true), JsonElement.class));
|
||||
assertEquals("\"foo\"", gson.toJson(new JsonPrimitive("foo"), JsonElement.class));
|
||||
assertEquals("\"a\"", gson.toJson(new JsonPrimitive('a'), JsonElement.class));
|
||||
}
|
||||
|
||||
public void testJsonPrimitiveDeserialization() {
|
||||
assertEquals(new JsonPrimitive(5), gson.fromJson("5", JsonElement.class));
|
||||
assertEquals(new JsonPrimitive(true), gson.fromJson("true", JsonElement.class));
|
||||
assertEquals(new JsonPrimitive("foo"), gson.fromJson("\"foo\"", JsonElement.class));
|
||||
assertEquals(new JsonPrimitive('a'), gson.fromJson("\"a\"", JsonElement.class));
|
||||
}
|
||||
|
||||
public void testJsonNullSerialization() {
|
||||
assertEquals("null", gson.toJson(JsonNull.INSTANCE, JsonElement.class));
|
||||
}
|
||||
|
||||
public void testNullJsonElementSerialization() {
|
||||
assertEquals("null", gson.toJson(null, JsonElement.class));
|
||||
}
|
||||
|
||||
public void testJsonArraySerialization() {
|
||||
JsonArray array = new JsonArray();
|
||||
array.add(new JsonPrimitive(1));
|
||||
array.add(new JsonPrimitive(2));
|
||||
array.add(new JsonPrimitive(3));
|
||||
assertEquals("[1,2,3]", gson.toJson(array, JsonElement.class));
|
||||
}
|
||||
|
||||
public void testJsonArrayDeerialization() {
|
||||
JsonArray array = new JsonArray();
|
||||
array.add(new JsonPrimitive(1));
|
||||
array.add(new JsonPrimitive(2));
|
||||
array.add(new JsonPrimitive(3));
|
||||
assertEquals(array, gson.fromJson("[1,2,3]", JsonElement.class));
|
||||
}
|
||||
|
||||
public void testJsonObjectSerialization() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.add("foo", new JsonPrimitive(1));
|
||||
object.add("bar", new JsonPrimitive(2));
|
||||
assertEquals("{\"foo\":1,\"bar\":2}", gson.toJson(object, JsonElement.class));
|
||||
}
|
||||
|
||||
public void testJsonObjectDeerialization() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.add("foo", new JsonPrimitive(1));
|
||||
object.add("bar", new JsonPrimitive(2));
|
||||
assertEquals(object, gson.fromJson("{\"foo\":1,\"bar\":2}", JsonElement.class));
|
||||
}
|
||||
|
||||
public void testJsonNullDeerialization() {
|
||||
assertEquals(JsonNull.INSTANCE, gson.fromJson("null", JsonElement.class));
|
||||
}
|
||||
|
||||
public void testNullJsonElementDeserialization() {
|
||||
assertEquals(JsonNull.INSTANCE, gson.fromJson("null", JsonElement.class));
|
||||
}
|
||||
|
||||
private static class ClassWithBigDecimal {
|
||||
BigDecimal value;
|
||||
ClassWithBigDecimal(String value) {
|
||||
|
Loading…
Reference in New Issue
Block a user