From b28e518c7e19f5ad1f881144c3651e7c3f9c759a Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Wed, 21 Dec 2011 21:30:18 +0000 Subject: [PATCH] Hide toJson/fromJson APIs for the 2.1 release. --- .../java/com/google/gson/TypeAdapter.java | 67 +++++++++--------- .../internal/bind/MapTypeAdapterFactory.java | 15 +++- .../functional/StreamingTypeAdaptersTest.java | 68 +++++++++++-------- 3 files changed, 88 insertions(+), 62 deletions(-) diff --git a/gson/src/main/java/com/google/gson/TypeAdapter.java b/gson/src/main/java/com/google/gson/TypeAdapter.java index d02a3bc3..6477b55d 100644 --- a/gson/src/main/java/com/google/gson/TypeAdapter.java +++ b/gson/src/main/java/com/google/gson/TypeAdapter.java @@ -16,18 +16,17 @@ package com.google.gson; -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; - import com.google.gson.internal.bind.JsonElementWriter; import com.google.gson.internal.bind.JsonTreeReader; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; /** * Converts Java objects to and from JSON. @@ -94,28 +93,30 @@ import com.google.gson.stream.JsonWriter; * Gson gson = builder.create(); * } * - *

JSON Conversion

- *

A type adapter registered with Gson is automatically invoked while serializing - * or deserializing JSON. However, you can also use type adapters directly to serialize - * and deserialize JSON. Here is an example for deserialization:

   {@code
- *
- *   String json = "{'origin':'0,0','points':['1,2','3,4']}";
- *   TypeAdapter graphAdapter = gson.getAdapter(Graph.class);
- *   Graph graph = graphAdapter.fromJson(json);
- * }
- * And an example for serialization:
   {@code
- *
- *   Graph graph = new Graph(...);
- *   TypeAdapter graphAdapter = gson.getAdapter(Graph.class);
- *   String json = graphAdapter.toJson(graph);
- * }
- * - *

Type adapters are type-specific. For example, a {@code - * TypeAdapter} can convert {@code Date} instances to JSON and JSON to - * instances of {@code Date}, but cannot convert any other types. - * * @since 2.1 */ +// non-Javadoc: +// +//

JSON Conversion

+//

A type adapter registered with Gson is automatically invoked while serializing +// or deserializing JSON. However, you can also use type adapters directly to serialize +// and deserialize JSON. Here is an example for deserialization:

   {@code
+//
+//   String json = "{'origin':'0,0','points':['1,2','3,4']}";
+//   TypeAdapter graphAdapter = gson.getAdapter(Graph.class);
+//   Graph graph = graphAdapter.fromJson(json);
+// }
+// And an example for serialization:
   {@code
+//
+//   Graph graph = new Graph(...);
+//   TypeAdapter graphAdapter = gson.getAdapter(Graph.class);
+//   String json = graphAdapter.toJson(graph);
+// }
+// +//

Type adapters are type-specific. For example, a {@code +// TypeAdapter} can convert {@code Date} instances to JSON and JSON to +// instances of {@code Date}, but cannot convert any other types. +// public abstract class TypeAdapter { /** @@ -136,7 +137,7 @@ public abstract class TypeAdapter { * * @param value the Java object to convert. May be null. */ - public final void toJson(Writer out, T value) throws IOException { + /*public*/ final void toJson(Writer out, T value) throws IOException { JsonWriter writer = new JsonWriter(out); write(writer, value); } @@ -181,7 +182,7 @@ public abstract class TypeAdapter { * } * Note that we didn't need to check for nulls in our type adapter after we used nullSafe. */ - public TypeAdapter nullSafe() { + public final TypeAdapter nullSafe() { return new TypeAdapter() { @Override public void write(JsonWriter out, T value) throws IOException { if (value == null) { @@ -209,7 +210,7 @@ public abstract class TypeAdapter { * * @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(); toJson(stringWriter, value); return stringWriter.toString(); @@ -221,7 +222,7 @@ public abstract class TypeAdapter { * @param value the Java object to convert. May be null. * @return the converted JSON tree. May be {@link JsonNull}. */ - public JsonElement toJsonTree(T value) { + /*public*/ final JsonElement toJsonTree(T value) { try { JsonElementWriter jsonWriter = new JsonElementWriter(); jsonWriter.setLenient(true); @@ -248,7 +249,7 @@ public abstract class TypeAdapter { * * @return the converted Java object. May be null. */ - public final T fromJson(Reader in) throws IOException { + /*public*/ final T fromJson(Reader in) throws IOException { JsonReader reader = new JsonReader(in); reader.setLenient(true); // TODO: non-lenient? return read(reader); @@ -262,7 +263,7 @@ public abstract class TypeAdapter { * * @return the converted Java object. May be null. */ - public final T fromJson(String json) throws IOException { + /*public*/ final T fromJson(String json) throws IOException { return fromJson(new StringReader(json)); } @@ -271,7 +272,7 @@ public abstract class TypeAdapter { * * @param jsonTree the Java object to convert. May be {@link JsonNull}. */ - public T fromJsonTree(JsonElement jsonTree) { + /*public*/ final T fromJsonTree(JsonElement jsonTree) { try { JsonReader jsonReader = new JsonTreeReader(jsonTree); jsonReader.setLenient(true); diff --git a/gson/src/main/java/com/google/gson/internal/bind/MapTypeAdapterFactory.java b/gson/src/main/java/com/google/gson/internal/bind/MapTypeAdapterFactory.java index 12b1fdf3..7e395089 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/MapTypeAdapterFactory.java +++ b/gson/src/main/java/com/google/gson/internal/bind/MapTypeAdapterFactory.java @@ -18,6 +18,7 @@ package com.google.gson.internal.bind; import com.google.gson.Gson; import com.google.gson.JsonElement; +import com.google.gson.JsonIOException; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSyntaxException; import com.google.gson.TypeAdapter; @@ -215,7 +216,7 @@ public final class MapTypeAdapterFactory implements TypeAdapter.Factory { List values = new ArrayList(map.size()); for (Map.Entry entry : map.entrySet()) { - JsonElement keyElement = keyTypeAdapter.toJsonTree(entry.getKey()); + JsonElement keyElement = toJsonTree(keyTypeAdapter, entry.getKey()); keys.add(keyElement); values.add(entry.getValue()); hasComplexKeys |= keyElement.isJsonArray() || keyElement.isJsonObject(); @@ -260,4 +261,16 @@ public final class MapTypeAdapterFactory implements TypeAdapter.Factory { } } } + + // TODO: remove this when TypeAdapter.toJsonTree() is public + private static JsonElement toJsonTree(TypeAdapter typeAdapter, T value) { + try { + JsonElementWriter jsonWriter = new JsonElementWriter(); + jsonWriter.setLenient(true); + typeAdapter.write(jsonWriter, value); + return jsonWriter.get(); + } catch (IOException e) { + throw new JsonIOException(e); + } + } } diff --git a/gson/src/test/java/com/google/gson/functional/StreamingTypeAdaptersTest.java b/gson/src/test/java/com/google/gson/functional/StreamingTypeAdaptersTest.java index 8002d216..e01e1077 100644 --- a/gson/src/test/java/com/google/gson/functional/StreamingTypeAdaptersTest.java +++ b/gson/src/test/java/com/google/gson/functional/StreamingTypeAdaptersTest.java @@ -16,16 +16,6 @@ package com.google.gson.functional; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import junit.framework.TestCase; - import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonSyntaxException; @@ -33,6 +23,16 @@ import com.google.gson.TypeAdapter; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import junit.framework.TestCase; public final class StreamingTypeAdaptersTest extends TestCase { private Gson miniGson = new GsonBuilder().create(); @@ -47,13 +47,13 @@ public final class StreamingTypeAdaptersTest extends TestCase { assertEquals("{'horsePower':300.0," + "'passengers':[{'age':29,'name':'Jesse'},{'age':29,'name':'Jodie'}]}", - truckAdapter.toJson(truck).replace('\"', '\'')); + toJson(truckAdapter, truck).replace('\"', '\'')); } public void testDeserialize() throws IOException { String json = "{'horsePower':300.0," + "'passengers':[{'age':29,'name':'Jesse'},{'age':29,'name':'Jodie'}]}"; - Truck truck = truckAdapter.fromJson(json); + Truck truck = fromJson(truckAdapter, json); assertEquals(300.0, truck.horsePower); assertEquals(Arrays.asList(new Person("Jesse", 29), new Person("Jodie", 29)), truck.passengers); } @@ -62,11 +62,11 @@ public final class StreamingTypeAdaptersTest extends TestCase { Truck truck = new Truck(); truck.passengers = null; assertEquals("{'horsePower':0.0,'passengers':null}", - truckAdapter.toJson(truck).replace('\"', '\'')); + toJson(truckAdapter, truck).replace('\"', '\'')); } public void testDeserializeNullField() throws IOException { - Truck truck = truckAdapter.fromJson("{'horsePower':0.0,'passengers':null}"); + Truck truck = fromJson(truckAdapter, "{'horsePower':0.0,'passengers':null}"); assertNull(truck.passengers); } @@ -74,11 +74,11 @@ public final class StreamingTypeAdaptersTest extends TestCase { Truck truck = new Truck(); truck.passengers = Arrays.asList((Person) null); assertEquals("{'horsePower':0.0,'passengers':[null]}", - truckAdapter.toJson(truck).replace('\"', '\'')); + toJson(truckAdapter, truck).replace('\"', '\'')); } public void testDeserializeNullObject() throws IOException { - Truck truck = truckAdapter.fromJson("{'horsePower':0.0,'passengers':[null]}"); + Truck truck = fromJson(truckAdapter, "{'horsePower':0.0,'passengers':[null]}"); assertEquals(Arrays.asList((Person) null), truck.passengers); } @@ -87,12 +87,12 @@ public final class StreamingTypeAdaptersTest extends TestCase { Truck truck = new Truck(); truck.passengers = Arrays.asList(new Person("Jesse", 29), new Person("Jodie", 29)); assertEquals("{'horsePower':0.0,'passengers':['Jesse','Jodie']}", - truckAdapter.toJson(truck).replace('\"', '\'')); + toJson(truckAdapter, truck).replace('\"', '\'')); } public void testDeserializeWithCustomTypeAdapter() throws IOException { usePersonNameAdapter(); - Truck truck = truckAdapter.fromJson("{'horsePower':0.0,'passengers':['Jesse','Jodie']}"); + Truck truck = fromJson(truckAdapter, "{'horsePower':0.0,'passengers':['Jesse','Jodie']}"); assertEquals(Arrays.asList(new Person("Jesse", -1), new Person("Jodie", -1)), truck.passengers); } @@ -114,36 +114,36 @@ public final class StreamingTypeAdaptersTest extends TestCase { Map map = new LinkedHashMap(); map.put("a", 5.0); map.put("b", 10.0); - assertEquals("{'a':5.0,'b':10.0}", mapAdapter.toJson(map).replace('"', '\'')); + assertEquals("{'a':5.0,'b':10.0}", toJson(mapAdapter, map).replace('"', '\'')); } public void testDeserializeMap() throws IOException { Map map = new LinkedHashMap(); map.put("a", 5.0); map.put("b", 10.0); - assertEquals(map, mapAdapter.fromJson("{'a':5.0,'b':10.0}")); + assertEquals(map, fromJson(mapAdapter, "{'a':5.0,'b':10.0}")); } public void testSerialize1dArray() throws IOException { TypeAdapter arrayAdapter = miniGson.getAdapter(new TypeToken() {}); - assertEquals("[1.0,2.0,3.0]", arrayAdapter.toJson(new double[]{1.0, 2.0, 3.0})); + assertEquals("[1.0,2.0,3.0]", toJson(arrayAdapter, new double[]{1.0, 2.0, 3.0})); } public void testDeserialize1dArray() throws IOException { TypeAdapter arrayAdapter = miniGson.getAdapter(new TypeToken() {}); - double[] array = arrayAdapter.fromJson("[1.0,2.0,3.0]"); + double[] array = fromJson(arrayAdapter, "[1.0,2.0,3.0]"); assertTrue(Arrays.toString(array), Arrays.equals(new double[]{1.0, 2.0, 3.0}, array)); } public void testSerialize2dArray() throws IOException { TypeAdapter arrayAdapter = miniGson.getAdapter(new TypeToken() {}); double[][] array = { {1.0, 2.0 }, { 3.0 } }; - assertEquals("[[1.0,2.0],[3.0]]", arrayAdapter.toJson(array)); + assertEquals("[[1.0,2.0],[3.0]]", toJson(arrayAdapter, array)); } public void testDeserialize2dArray() throws IOException { TypeAdapter arrayAdapter = miniGson.getAdapter(new TypeToken() {}); - double[][] array = arrayAdapter.fromJson("[[1.0,2.0],[3.0]]"); + double[][] array = fromJson(arrayAdapter, "[[1.0,2.0],[3.0]]"); double[][] expected = { {1.0, 2.0 }, { 3.0 } }; assertTrue(Arrays.toString(array), Arrays.deepEquals(expected, array)); } @@ -191,7 +191,7 @@ public final class StreamingTypeAdaptersTest extends TestCase { assertEquals("{'label':'root'," + "'left':{'label':'left','left':null,'right':null}," + "'right':{'label':'right','left':null,'right':null}}", - nodeAdapter.toJson(root).replace('"', '\'')); + toJson(nodeAdapter, root).replace('"', '\'')); } static class Truck { @@ -207,8 +207,6 @@ public final class StreamingTypeAdaptersTest extends TestCase { this.age = age; } - public Person() {} // TODO: use Joel's constructor code so we don't need this - @Override public boolean equals(Object o) { return o instanceof Person && ((Person) o).name.equals(name) @@ -226,6 +224,20 @@ public final class StreamingTypeAdaptersTest extends TestCase { Node(String label) { this.label = label; } - public Node() {} // TODO: use Joel's constructor code so we don't need this + } + + // TODO: remove this when TypeAdapter.toJson() is public + private static String toJson(TypeAdapter typeAdapter, T value) throws IOException { + StringWriter stringWriter = new StringWriter(); + JsonWriter writer = new JsonWriter(stringWriter); + typeAdapter.write(writer, value); + return stringWriter.toString(); + } + + // TODO: remove this when TypeAdapter.fromJson() is public + private T fromJson(TypeAdapter typeAdapter, String json) throws IOException { + JsonReader reader = new JsonReader(new StringReader(json)); + reader.setLenient(true); // TODO: non-lenient? + return typeAdapter.read(reader); } }