From 566c27cf211fcf307bcb94b47dbbe992fbe0d2d9 Mon Sep 17 00:00:00 2001 From: Inderjeet Singh Date: Wed, 3 Aug 2011 02:17:42 +0000 Subject: [PATCH] Adapted legacy Gson adapters into mini Gson. --- gson/src/main/java/com/google/gson/Gson.java | 11 +- .../gson/GsonToMiniGsonTypeAdapter.java | 104 ++++++++++++++++++ .../gson/JsonDeserializationContext.java | 5 +- .../google/gson/JsonSerializationContext.java | 6 +- 4 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapter.java diff --git a/gson/src/main/java/com/google/gson/Gson.java b/gson/src/main/java/com/google/gson/Gson.java index 23d84623..8741762a 100644 --- a/gson/src/main/java/com/google/gson/Gson.java +++ b/gson/src/main/java/com/google/gson/Gson.java @@ -88,7 +88,7 @@ public final class Gson { //TODO(inder): get rid of all the registerXXX methods and take all such parameters in the // constructor instead. At the minimum, mark those methods private. - static final boolean DEFAULT_JSON_NON_EXECUTABLE = false; + static final boolean DEFAULT_JSON_NON_EXECUTABLE = false; // Default instances of plug-ins static final AnonymousAndLocalClassExclusionStrategy DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY = @@ -165,9 +165,9 @@ public final class Gson { Gson(ExclusionStrategy deserializationExclusionStrategy, ExclusionStrategy serializationExclusionStrategy, FieldNamingStrategy2 fieldNamingPolicy, - MappedObjectConstructor objectConstructor, boolean serializeNulls, - ParameterizedTypeHandlerMap> serializers, - ParameterizedTypeHandlerMap> deserializers, + final MappedObjectConstructor objectConstructor, boolean serializeNulls, + final ParameterizedTypeHandlerMap> serializers, + final ParameterizedTypeHandlerMap> deserializers, boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting) { this.deserializationExclusionStrategy = deserializationExclusionStrategy; this.serializationExclusionStrategy = serializationExclusionStrategy; @@ -200,7 +200,7 @@ public final class Gson { new FieldAttributes(declaringClazz, f, declaredType)); } }; - + this.miniGson = new MiniGson.Builder() .withoutDefaultFactories() .factory(TypeAdapters.BOOLEAN_FACTORY) @@ -208,6 +208,7 @@ public final class Gson { .factory(TypeAdapters.DOUBLE_FACTORY) .factory(TypeAdapters.LONG_FACTORY) .factory(TypeAdapters.STRING_FACTORY) + .factory(new GsonToMiniGsonTypeAdapter(serializers, deserializers, serializeNulls)) .factory(CollectionTypeAdapter.FACTORY) .factory(StringToValueMapTypeAdapter.FACTORY) .factory(ArrayTypeAdapter.FACTORY) diff --git a/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapter.java b/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapter.java new file mode 100644 index 00000000..c3f3b2c4 --- /dev/null +++ b/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapter.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.gson; + +import java.beans.DesignMode; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.lang.reflect.Type; + +import com.google.gson.internal.bind.MiniGson; +import com.google.gson.internal.bind.TypeAdapter; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +final class GsonToMiniGsonTypeAdapter implements TypeAdapter.Factory { + private final ParameterizedTypeHandlerMap> serializers; + private final ParameterizedTypeHandlerMap> deserializers; + private final boolean serializeNulls; + + GsonToMiniGsonTypeAdapter(ParameterizedTypeHandlerMap> serializers, + ParameterizedTypeHandlerMap> deserializers, boolean serializeNulls) { + this.serializers = serializers; + this.deserializers = deserializers; + this.serializeNulls = serializeNulls; + } + + public TypeAdapter create(final MiniGson miniGson, TypeToken type) { + final Type typeOfT = type.getType(); + final JsonSerializer serializer = serializers.getHandlerFor(typeOfT, false); + final JsonDeserializer deserializer = deserializers.getHandlerFor(typeOfT, false); + if (serializer == null && deserializer == null) { + return null; + } + return new TypeAdapter() { + @Override + public Object read(JsonReader reader) throws IOException { + if (deserializer == null) { + // TODO: handle if deserializer is null + throw new UnsupportedOperationException(); + } + return deserializer.deserialize(Streams.parse(reader), typeOfT, createDeserializationContext(miniGson)); + } + @Override + public void write(JsonWriter writer, Object value) throws IOException { + if (serializer == null) { + // TODO: handle if serializer is null + throw new UnsupportedOperationException(); + } + JsonElement element = serializer.serialize(value, typeOfT, createSerializationContext(miniGson)); + Streams.write(element, serializeNulls, writer); + } + }; + } + + public JsonSerializationContext createSerializationContext(final MiniGson miniGson) { + 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); + } + } + }; + } + public JsonDeserializationContext createDeserializationContext(final MiniGson miniGson) { + 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); + } + } + }; + } +} diff --git a/gson/src/main/java/com/google/gson/JsonDeserializationContext.java b/gson/src/main/java/com/google/gson/JsonDeserializationContext.java index d5a98b22..df5d9382 100644 --- a/gson/src/main/java/com/google/gson/JsonDeserializationContext.java +++ b/gson/src/main/java/com/google/gson/JsonDeserializationContext.java @@ -26,7 +26,7 @@ import java.lang.reflect.Type; * @author Inderjeet Singh * @author Joel Leitch */ -public final class JsonDeserializationContext { +public class JsonDeserializationContext { private final ObjectNavigator objectNavigator; private final FieldNamingStrategy2 fieldNamingPolicy; private final ParameterizedTypeHandlerMap> deserializers; @@ -42,6 +42,9 @@ public final class JsonDeserializationContext { this.objectConstructor = objectConstructor; } + JsonDeserializationContext() { + this(null, null, null, null); + } @SuppressWarnings("unchecked") public T construct(Type type) { diff --git a/gson/src/main/java/com/google/gson/JsonSerializationContext.java b/gson/src/main/java/com/google/gson/JsonSerializationContext.java index 317da418..7198a1bf 100644 --- a/gson/src/main/java/com/google/gson/JsonSerializationContext.java +++ b/gson/src/main/java/com/google/gson/JsonSerializationContext.java @@ -25,7 +25,7 @@ import java.lang.reflect.Type; * @author Inderjeet Singh * @author Joel Leitch */ -public final class JsonSerializationContext { +public class JsonSerializationContext { private final ObjectNavigator objectNavigator; private final FieldNamingStrategy2 fieldNamingPolicy; @@ -42,6 +42,10 @@ public final class JsonSerializationContext { this.serializers = serializers; this.ancestors = new MemoryRefStack(); } + + JsonSerializationContext() { + this(null, null, false, null); + } /** * Invokes default serialization on the specified object.