diff --git a/gson/src/main/java/com/google/gson/Gson.java b/gson/src/main/java/com/google/gson/Gson.java index 8741762a..13437371 100644 --- a/gson/src/main/java/com/google/gson/Gson.java +++ b/gson/src/main/java/com/google/gson/Gson.java @@ -28,6 +28,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import com.google.gson.internal.Streams; import com.google.gson.internal.bind.ArrayTypeAdapter; import com.google.gson.internal.bind.CollectionTypeAdapter; import com.google.gson.internal.bind.MiniGson; @@ -264,13 +265,7 @@ public final class Gson { public JsonElement toJsonTree(Object src, Type typeOfSrc) { // Serialize 'src' to JSON, then deserialize that to a JSON tree. TypeAdapter adapter = miniGson.getAdapter(TypeToken.get(typeOfSrc)); - StringWriter writer = new StringWriter(); - try { - adapter.write(writer, src); - } catch (IOException e) { - throw new RuntimeException(e); - } - return Streams.parse(new JsonReader(new StringReader(writer.toString()))); + return adapter.toJsonElement(src); } /** diff --git a/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapter.java b/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapter.java index c3f3b2c4..b7ff2054 100644 --- a/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapter.java +++ b/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapter.java @@ -21,6 +21,7 @@ import java.io.StringReader; import java.io.StringWriter; import java.lang.reflect.Type; +import com.google.gson.internal.Streams; import com.google.gson.internal.bind.MiniGson; import com.google.gson.internal.bind.TypeAdapter; import com.google.gson.reflect.TypeToken; @@ -61,6 +62,10 @@ final class GsonToMiniGsonTypeAdapter implements TypeAdapter.Factory { // TODO: handle if serializer is null throw new UnsupportedOperationException(); } + if (value == null) { + writer.nullValue(); + return; + } JsonElement element = serializer.serialize(value, typeOfT, createSerializationContext(miniGson)); Streams.write(element, serializeNulls, writer); } @@ -71,15 +76,8 @@ final class GsonToMiniGsonTypeAdapter implements TypeAdapter.Factory { return new JsonSerializationContext() { @Override JsonElement serialize(Object src, Type typeOfSrc, boolean preserveType, boolean defaultOnly) { - try { - TypeToken typeToken = TypeToken.get(typeOfSrc); - String json = miniGson.getAdapter(typeToken).toJson(src); - JsonReader jsonReader = new JsonReader(new StringReader(json)); - jsonReader.setLenient(true); - return Streams.parse(jsonReader); - } catch (IOException e) { - throw new RuntimeException(e); - } + TypeToken typeToken = TypeToken.get(typeOfSrc); + return miniGson.getAdapter(typeToken).toJsonElement(src); } }; } @@ -87,17 +85,8 @@ final class GsonToMiniGsonTypeAdapter implements TypeAdapter.Factory { return new JsonDeserializationContext() { @Override public T deserialize(JsonElement json, Type typeOfT) throws JsonParseException { - try { - TypeToken typeToken = TypeToken.get(typeOfT); - StringWriter stringWriter = new StringWriter(); - JsonWriter jsonWriter = new JsonWriter(stringWriter); - jsonWriter.setLenient(true); - Streams.write(json, serializeNulls, jsonWriter); - Object target = miniGson.getAdapter(typeToken).fromJson(stringWriter.toString()); - return (T) target; - } catch (IOException e) { - throw new JsonParseException(e); - } + TypeToken typeToken = TypeToken.get(typeOfT); + return (T) miniGson.getAdapter(typeToken).fromJsonElement(json); } }; } diff --git a/gson/src/main/java/com/google/gson/JsonElement.java b/gson/src/main/java/com/google/gson/JsonElement.java index 710397c7..5ed477e4 100644 --- a/gson/src/main/java/com/google/gson/JsonElement.java +++ b/gson/src/main/java/com/google/gson/JsonElement.java @@ -16,6 +16,7 @@ package com.google.gson; +import com.google.gson.internal.Streams; import com.google.gson.stream.JsonWriter; import java.io.IOException; import java.io.StringWriter; diff --git a/gson/src/main/java/com/google/gson/JsonParser.java b/gson/src/main/java/com/google/gson/JsonParser.java index 180d7813..53b58072 100755 --- a/gson/src/main/java/com/google/gson/JsonParser.java +++ b/gson/src/main/java/com/google/gson/JsonParser.java @@ -15,6 +15,7 @@ */ 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; diff --git a/gson/src/main/java/com/google/gson/JsonPrimitive.java b/gson/src/main/java/com/google/gson/JsonPrimitive.java index 4a08b265..32ff6502 100644 --- a/gson/src/main/java/com/google/gson/JsonPrimitive.java +++ b/gson/src/main/java/com/google/gson/JsonPrimitive.java @@ -17,6 +17,8 @@ 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; diff --git a/gson/src/main/java/com/google/gson/JsonStreamParser.java b/gson/src/main/java/com/google/gson/JsonStreamParser.java index e4608e28..d27854ce 100644 --- a/gson/src/main/java/com/google/gson/JsonStreamParser.java +++ b/gson/src/main/java/com/google/gson/JsonStreamParser.java @@ -22,6 +22,7 @@ import java.io.StringReader; import java.util.Iterator; import java.util.NoSuchElementException; +import com.google.gson.internal.Streams; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.MalformedJsonException; diff --git a/gson/src/main/java/com/google/gson/LazilyParsedNumber.java b/gson/src/main/java/com/google/gson/internal/LazilyParsedNumber.java similarity index 92% rename from gson/src/main/java/com/google/gson/LazilyParsedNumber.java rename to gson/src/main/java/com/google/gson/internal/LazilyParsedNumber.java index 6201616d..94ddd792 100644 --- a/gson/src/main/java/com/google/gson/LazilyParsedNumber.java +++ b/gson/src/main/java/com/google/gson/internal/LazilyParsedNumber.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.gson; +package com.google.gson.internal; import java.math.BigInteger; @@ -23,10 +23,10 @@ import java.math.BigInteger; * @author Inderjeet Singh */ @SuppressWarnings("serial") -final class LazilyParsedNumber extends Number { +public final class LazilyParsedNumber extends Number { private final String value; - LazilyParsedNumber(String value) { + public LazilyParsedNumber(String value) { this.value = value; } diff --git a/gson/src/main/java/com/google/gson/Streams.java b/gson/src/main/java/com/google/gson/internal/Streams.java similarity index 89% rename from gson/src/main/java/com/google/gson/Streams.java rename to gson/src/main/java/com/google/gson/internal/Streams.java index d53c0142..ea59cc56 100644 --- a/gson/src/main/java/com/google/gson/Streams.java +++ b/gson/src/main/java/com/google/gson/internal/Streams.java @@ -14,8 +14,16 @@ * limitations under the License. */ -package com.google.gson; +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.stream.JsonReader; import com.google.gson.stream.JsonWriter; import com.google.gson.stream.MalformedJsonException; @@ -27,12 +35,12 @@ import java.util.Map; /** * Reads and writes GSON parse trees over streams. */ -final class Streams { +public final class Streams { /** * Takes a reader in any state and returns the next value as a JsonElement. */ - static JsonElement parse(JsonReader reader) throws JsonParseException { + public static JsonElement parse(JsonReader reader) throws JsonParseException { boolean isEmpty = true; try { reader.peek(); @@ -96,7 +104,7 @@ final class Streams { /** * Writes the JSON element to the writer, recursively. */ - static void write(JsonElement element, boolean serializeNulls, JsonWriter writer) + public static void write(JsonElement element, boolean serializeNulls, JsonWriter writer) throws IOException { if (element == null || element.isJsonNull()) { if (serializeNulls) { @@ -142,7 +150,7 @@ final class Streams { } } - static Writer writerForAppendable(Appendable appendable) { + public static Writer writerForAppendable(Appendable appendable) { return appendable instanceof Writer ? (Writer) appendable : new AppendableWriter(appendable); } diff --git a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapter.java b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapter.java index 49eb92b4..e91e6a44 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapter.java +++ b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapter.java @@ -16,15 +16,18 @@ package com.google.gson.internal.bind; -import com.google.gson.reflect.TypeToken; -import com.google.gson.stream.JsonReader; -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; +import com.google.gson.JsonElement; +import com.google.gson.internal.Streams; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + public abstract class TypeAdapter { public abstract T read(JsonReader reader) throws IOException; public abstract void write(JsonWriter writer, T value) throws IOException; @@ -50,6 +53,34 @@ public abstract class TypeAdapter { return read(reader); } + public JsonElement toJsonElement(T src) { + try { + StringWriter stringWriter = new StringWriter(); + JsonWriter jsonWriter = new JsonWriter(stringWriter); + jsonWriter.setLenient(true); + write(jsonWriter, src); + JsonReader reader = new JsonReader(new StringReader(stringWriter.toString())); + reader.setLenient(true); + return Streams.parse(reader); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public T fromJsonElement(JsonElement json) { + try { + StringWriter stringWriter = new StringWriter(); + JsonWriter jsonWriter = new JsonWriter(stringWriter); + jsonWriter.setLenient(true); + Streams.write(json, false, jsonWriter); + JsonReader jsonReader = new JsonReader(new StringReader(stringWriter.toString())); + jsonReader.setLenient(true); + return read(jsonReader); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + public interface Factory { TypeAdapter create(MiniGson context, TypeToken type); } diff --git a/gson/src/test/java/com/google/gson/JsonParserTest.java b/gson/src/test/java/com/google/gson/JsonParserTest.java index a7344452..30ccdf27 100644 --- a/gson/src/test/java/com/google/gson/JsonParserTest.java +++ b/gson/src/test/java/com/google/gson/JsonParserTest.java @@ -17,6 +17,7 @@ package com.google.gson; import com.google.gson.common.TestTypes.BagOfPrimitives; +import com.google.gson.internal.Streams; import com.google.gson.stream.JsonReader; import java.io.CharArrayReader; import java.io.CharArrayWriter;