From 25c6ae177b1ca56db7f3c29eb574bdd032a06165 Mon Sep 17 00:00:00 2001
From: Jesse Wilson
Date: Sun, 11 Sep 2011 07:04:56 +0000
Subject: [PATCH] Down to 22 failing tests.
Consolidated all of the different code paths that we use to construct instances. We now have an ObjectConstructor class that knows what type it constructs; this means that we don't need to ever do reflection to lookup a constructor at construction time.
Cleaned up some buggy type adapters, particularly around handling of null.
Removed dead code for object graph navigation.
Moved some classes into 'internal' so they are visible to the 'bind' subpackage.
Turned some TypeAdapterFactory/TypeAdapter pairs inside out so that the TypeAdapter is now the inner class. This is necessary so that the factories can take parameters.
Added an API to request the 'next' type adapter for a type. This allows type adapters to compose other type adapters. We're using this in two places:
- where the user has excluded a type from serialization but not deserialization, we need to use the "default" deserialization but interpose null on serialization. We create a type adapter that delegates for one and returns null for the other.
- similarly when a DOM type serializer is registered but no deserializer, or vice versa.
This is the biggest change to the MiniGson core.
For backwards compatibility, return null for the empty string.
Simplify JsonSerializationContext/JsonDeserializationContext to simply call through to GSON. SerializeDefault is currently unsupported.
More useful error messages when calling getAsBoolean on a JsonNull.
Remove currently unused MemoryRefStack. We might need this back again, though wiring it back in will be much more difficult because we don't interject ourselves between the users' various type adapters.
---
.../com/google/gson/BaseMapTypeAdapter.java | 40 ---
.../com/google/gson/DefaultTypeAdapters.java | 69 +----
.../gson/DelegatingJsonElementVisitor.java | 118 ---------
.../java/com/google/gson/FieldAttributes.java | 1 +
gson/src/main/java/com/google/gson/Gson.java | 97 ++++---
.../java/com/google/gson/GsonBuilder.java | 7 +-
.../gson/GsonToMiniGsonTypeAdapter.java | 106 --------
.../GsonToMiniGsonTypeAdapterFactory.java | 99 ++++++++
.../gson/JsonArrayDeserializationVisitor.java | 111 --------
.../gson/JsonDeserializationContext.java | 83 +-----
.../gson/JsonDeserializationVisitor.java | 115 ---------
.../java/com/google/gson/JsonElement.java | 28 +--
.../JsonObjectDeserializationVisitor.java | 136 ----------
.../google/gson/JsonSerializationContext.java | 40 +--
.../google/gson/JsonSerializationVisitor.java | 236 ------------------
.../com/google/gson/JsonTreeNavigator.java | 111 --------
.../google/gson/MapAsArrayTypeAdapter.java | 74 +-----
.../java/com/google/gson/MapTypeAdapter.java | 78 ------
.../google/gson/MappedObjectConstructor.java | 78 ------
.../java/com/google/gson/MemoryRefStack.java | 88 -------
.../google/gson/NullExclusionStrategy.java | 36 ---
.../java/com/google/gson/ObjectNavigator.java | 134 ----------
.../java/com/google/gson/ObjectTypePair.java | 150 -----------
.../google/gson/ReflectingFieldNavigator.java | 121 ---------
.../gson/internal/ConstructorConstructor.java | 173 +++++++++++++
.../{ => internal}/ObjectConstructor.java | 22 +-
.../com/google/gson/{ => internal}/Pair.java | 4 +-
.../ParameterizedTypeHandlerMap.java | 8 +-
.../gson/{ => internal}/Primitives.java | 4 +-
.../internal/bind/BigDecimalTypeAdapter.java | 2 +-
.../internal/bind/BigIntegerTypeAdapter.java | 2 +-
.../internal/bind/CollectionTypeAdapter.java | 121 ---------
.../bind/CollectionTypeAdapterFactory.java | 98 ++++++++
.../bind/ExcludedTypeAdapterFactory.java | 79 ++++++
.../bind/GsonCompatibleMapTypeAdapter.java | 105 --------
.../internal/bind/MapTypeAdapterFactory.java | 101 ++++++++
.../google/gson/internal/bind/MiniGson.java | 42 +++-
.../google/gson/internal/bind/Reflection.java | 25 +-
.../internal/bind/ReflectiveTypeAdapter.java | 213 ----------------
.../bind/ReflectiveTypeAdapterFactory.java | 219 ++++++++++++++++
.../bind/StringToValueMapTypeAdapter.java | 106 --------
.../StringToValueMapTypeAdapterFactory.java | 106 ++++++++
.../bind/TypeAdapterRuntimeTypeWrapper.java | 9 +-
.../gson/internal/bind/TypeAdapters.java | 17 +-
.../gson/DefaultConstructorAllocatorTest.java | 60 -----
.../gson/DefaultMapJsonSerializerTest.java | 18 +-
.../FunctionWithInternalDependenciesTest.java | 6 +-
.../gson/MappedObjectConstructorTest.java | 88 -------
.../com/google/gson/MemoryRefStackTest.java | 84 -------
.../java/com/google/gson/MixedStreamTest.java | 12 +-
.../gson/NullExclusionStrategyTest.java | 43 ----
.../google/gson/ParamterizedTypeFixtures.java | 1 +
.../com/google/gson/PrimitiveTypeAdapter.java | 1 +
.../ExclusionStrategyFunctionalTest.java | 10 +-
.../functional/MapAsArrayTypeAdapterTest.java | 14 +-
.../ParameterizedTypeHandlerMapTest.java | 5 +-
56 files changed, 1068 insertions(+), 2886 deletions(-)
delete mode 100644 gson/src/main/java/com/google/gson/BaseMapTypeAdapter.java
delete mode 100644 gson/src/main/java/com/google/gson/DelegatingJsonElementVisitor.java
delete mode 100644 gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapter.java
create mode 100644 gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapterFactory.java
delete mode 100644 gson/src/main/java/com/google/gson/JsonArrayDeserializationVisitor.java
delete mode 100644 gson/src/main/java/com/google/gson/JsonDeserializationVisitor.java
delete mode 100644 gson/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java
delete mode 100644 gson/src/main/java/com/google/gson/JsonSerializationVisitor.java
delete mode 100644 gson/src/main/java/com/google/gson/JsonTreeNavigator.java
delete mode 100644 gson/src/main/java/com/google/gson/MapTypeAdapter.java
delete mode 100644 gson/src/main/java/com/google/gson/MappedObjectConstructor.java
delete mode 100644 gson/src/main/java/com/google/gson/MemoryRefStack.java
delete mode 100644 gson/src/main/java/com/google/gson/NullExclusionStrategy.java
delete mode 100644 gson/src/main/java/com/google/gson/ObjectNavigator.java
delete mode 100644 gson/src/main/java/com/google/gson/ObjectTypePair.java
delete mode 100644 gson/src/main/java/com/google/gson/ReflectingFieldNavigator.java
create mode 100644 gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java
rename gson/src/main/java/com/google/gson/{ => internal}/ObjectConstructor.java (60%)
rename gson/src/main/java/com/google/gson/{ => internal}/Pair.java (95%)
rename gson/src/main/java/com/google/gson/{ => internal}/ParameterizedTypeHandlerMap.java (98%)
rename gson/src/main/java/com/google/gson/{ => internal}/Primitives.java (98%)
delete mode 100644 gson/src/main/java/com/google/gson/internal/bind/CollectionTypeAdapter.java
create mode 100644 gson/src/main/java/com/google/gson/internal/bind/CollectionTypeAdapterFactory.java
create mode 100644 gson/src/main/java/com/google/gson/internal/bind/ExcludedTypeAdapterFactory.java
delete mode 100644 gson/src/main/java/com/google/gson/internal/bind/GsonCompatibleMapTypeAdapter.java
create mode 100644 gson/src/main/java/com/google/gson/internal/bind/MapTypeAdapterFactory.java
delete mode 100644 gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapter.java
create mode 100644 gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java
delete mode 100644 gson/src/main/java/com/google/gson/internal/bind/StringToValueMapTypeAdapter.java
create mode 100644 gson/src/main/java/com/google/gson/internal/bind/StringToValueMapTypeAdapterFactory.java
delete mode 100644 gson/src/test/java/com/google/gson/DefaultConstructorAllocatorTest.java
delete mode 100644 gson/src/test/java/com/google/gson/MappedObjectConstructorTest.java
delete mode 100644 gson/src/test/java/com/google/gson/MemoryRefStackTest.java
delete mode 100644 gson/src/test/java/com/google/gson/NullExclusionStrategyTest.java
rename gson/src/test/java/com/google/gson/{ => internal}/ParameterizedTypeHandlerMapTest.java (96%)
diff --git a/gson/src/main/java/com/google/gson/BaseMapTypeAdapter.java b/gson/src/main/java/com/google/gson/BaseMapTypeAdapter.java
deleted file mode 100644
index b196e7cc..00000000
--- a/gson/src/main/java/com/google/gson/BaseMapTypeAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.lang.reflect.Type;
-import java.util.Map;
-
-/**
- * Captures all the common/shared logic between the old, ({@link MapTypeAdapter}, and
- * the new, {@link MapAsArrayTypeAdapter}, map type adapters.
- *
- * @author Joel Leitch
- */
-abstract class BaseMapTypeAdapter
- implements JsonSerializer
- *
- * @author Joel Leitch
- */
-final class DelegatingJsonElementVisitor implements JsonElementVisitor {
- private final JsonElementVisitor delegate;
-
- protected DelegatingJsonElementVisitor(JsonElementVisitor delegate) {
- this.delegate = $Gson$Preconditions.checkNotNull(delegate);
- }
-
- public void endArray(JsonArray array) throws IOException {
- delegate.endArray(array);
- }
-
- public void endObject(JsonObject object) throws IOException {
- delegate.endObject(object);
- }
-
- public void startArray(JsonArray array) throws IOException {
- delegate.startArray(array);
- }
-
- public void startObject(JsonObject object) throws IOException {
- delegate.startObject(object);
- }
-
- public void visitArrayMember(JsonArray parent, JsonPrimitive member,
- boolean isFirst) throws IOException {
- delegate.visitArrayMember(parent, member, isFirst);
- }
-
- public void visitArrayMember(JsonArray parent, JsonArray member,
- boolean isFirst) throws IOException {
- delegate.visitArrayMember(parent, member, isFirst);
- }
-
- public void visitArrayMember(JsonArray parent, JsonObject member,
- boolean isFirst) throws IOException {
- delegate.visitArrayMember(parent, member, isFirst);
- }
-
- public void visitObjectMember(JsonObject parent, String memberName, JsonPrimitive member,
- boolean isFirst) throws IOException {
- delegate.visitObjectMember(parent, memberName, member, isFirst);
- }
-
- public void visitObjectMember(JsonObject parent, String memberName, JsonArray member,
- boolean isFirst) throws IOException {
- delegate.visitObjectMember(parent, memberName, member, isFirst);
- }
-
- public void visitObjectMember(JsonObject parent, String memberName, JsonObject member,
- boolean isFirst) throws IOException {
- delegate.visitObjectMember(parent, memberName, member, isFirst);
- }
-
- public void visitNullObjectMember(JsonObject parent, String memberName,
- boolean isFirst) throws IOException {
- delegate.visitNullObjectMember(parent, memberName, isFirst);
- }
-
- public void visitPrimitive(JsonPrimitive primitive) throws IOException {
- delegate.visitPrimitive(primitive);
- }
-
- public void visitNull() throws IOException {
- delegate.visitNull();
- }
-
- public void visitNullArrayMember(JsonArray parent, boolean isFirst) throws IOException {
- delegate.visitNullArrayMember(parent, isFirst);
- }
-}
diff --git a/gson/src/main/java/com/google/gson/FieldAttributes.java b/gson/src/main/java/com/google/gson/FieldAttributes.java
index 0aa47511..1df8f2ff 100644
--- a/gson/src/main/java/com/google/gson/FieldAttributes.java
+++ b/gson/src/main/java/com/google/gson/FieldAttributes.java
@@ -19,6 +19,7 @@ package com.google.gson;
import com.google.gson.internal.$Gson$Preconditions;
import com.google.gson.internal.$Gson$Types;
+import com.google.gson.internal.Pair;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
diff --git a/gson/src/main/java/com/google/gson/Gson.java b/gson/src/main/java/com/google/gson/Gson.java
index ddc70ed8..17eefe2c 100644
--- a/gson/src/main/java/com/google/gson/Gson.java
+++ b/gson/src/main/java/com/google/gson/Gson.java
@@ -16,15 +16,19 @@
package com.google.gson;
+import com.google.gson.internal.ConstructorConstructor;
+import com.google.gson.internal.ParameterizedTypeHandlerMap;
+import com.google.gson.internal.Primitives;
import com.google.gson.internal.Streams;
import com.google.gson.internal.bind.ArrayTypeAdapter;
import com.google.gson.internal.bind.BigDecimalTypeAdapter;
import com.google.gson.internal.bind.BigIntegerTypeAdapter;
-import com.google.gson.internal.bind.CollectionTypeAdapter;
-import com.google.gson.internal.bind.GsonCompatibleMapTypeAdapter;
+import com.google.gson.internal.bind.CollectionTypeAdapterFactory;
+import com.google.gson.internal.bind.ExcludedTypeAdapterFactory;
+import com.google.gson.internal.bind.MapTypeAdapterFactory;
import com.google.gson.internal.bind.MiniGson;
import com.google.gson.internal.bind.ObjectTypeAdapter;
-import com.google.gson.internal.bind.ReflectiveTypeAdapter;
+import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory;
import com.google.gson.internal.bind.TypeAdapter;
import com.google.gson.internal.bind.TypeAdapters;
import com.google.gson.reflect.TypeToken;
@@ -32,7 +36,7 @@ import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.google.gson.stream.MalformedJsonException;
-
+import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
@@ -113,7 +117,7 @@ public final class Gson {
private final ExclusionStrategy deserializationExclusionStrategy;
private final ExclusionStrategy serializationExclusionStrategy;
private final FieldNamingStrategy2 fieldNamingPolicy;
- private final MappedObjectConstructor objectConstructor;
+ private final ConstructorConstructor constructorConstructor;
/** Map containing Type or Class objects as keys */
private final ParameterizedTypeHandlerMap> serializers;
@@ -164,7 +168,7 @@ public final class Gson {
*/
public Gson() {
this(DEFAULT_EXCLUSION_STRATEGY, DEFAULT_EXCLUSION_STRATEGY, DEFAULT_NAMING_POLICY,
- new MappedObjectConstructor(DefaultTypeAdapters.getDefaultInstanceCreators()),
+ DefaultTypeAdapters.getDefaultInstanceCreators(),
false, DefaultTypeAdapters.getAllDefaultSerializers(),
DefaultTypeAdapters.getAllDefaultDeserializers(), DEFAULT_JSON_NON_EXECUTABLE, true, false,
false, LongSerializationPolicy.DEFAULT);
@@ -173,7 +177,7 @@ public final class Gson {
Gson(final ExclusionStrategy deserializationExclusionStrategy,
final ExclusionStrategy serializationExclusionStrategy,
final FieldNamingStrategy2 fieldNamingPolicy,
- final MappedObjectConstructor objectConstructor, boolean serializeNulls,
+ final ParameterizedTypeHandlerMap> instanceCreators, boolean serializeNulls,
final ParameterizedTypeHandlerMap> serializers,
final ParameterizedTypeHandlerMap> deserializers,
boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting,
@@ -181,7 +185,7 @@ public final class Gson {
this.deserializationExclusionStrategy = deserializationExclusionStrategy;
this.serializationExclusionStrategy = serializationExclusionStrategy;
this.fieldNamingPolicy = fieldNamingPolicy;
- this.objectConstructor = objectConstructor;
+ this.constructorConstructor = new ConstructorConstructor(instanceCreators);
this.serializeNulls = serializeNulls;
this.serializers = serializers;
this.deserializers = deserializers;
@@ -196,33 +200,24 @@ public final class Gson {
serializeNulls
serializers
*/
- TypeAdapter.Factory reflectiveTypeAdapterFactory =
- new ReflectiveTypeAdapter.FactoryImpl() {
+ TypeAdapter.Factory reflectiveTypeAdapterFactory
+ = new ReflectiveTypeAdapterFactory(constructorConstructor) {
@Override
public String getFieldName(Class> declaringClazz, Field f, Type declaredType) {
return fieldNamingPolicy.translateName(new FieldAttributes(declaringClazz, f, declaredType));
}
@Override
public boolean serializeField(Class> declaringClazz, Field f, Type declaredType) {
- return !Gson.this.serializationExclusionStrategy.shouldSkipField(
- new FieldAttributes(declaringClazz, f, declaredType));
+ ExclusionStrategy strategy = Gson.this.serializationExclusionStrategy;
+ return !strategy.shouldSkipClass(f.getType())
+ && !strategy.shouldSkipField(new FieldAttributes(declaringClazz, f, declaredType));
}
+
@Override
public boolean deserializeField(Class> declaringClazz, Field f, Type declaredType) {
- return !Gson.this.deserializationExclusionStrategy.shouldSkipField(
- new FieldAttributes(declaringClazz, f, declaredType));
- }
- };
-
- TypeAdapter.Factory excludedTypeFactory = new TypeAdapter.Factory() {
- public TypeAdapter create(MiniGson context, TypeToken type) {
- Class> rawType = type.getRawType();
- if (serializationExclusionStrategy.shouldSkipClass(rawType)
- || deserializationExclusionStrategy.shouldSkipClass(rawType)) {
- return TypeAdapters.EXCLUDED_TYPE_ADAPTER;
- } else {
- return null;
- }
+ ExclusionStrategy strategy = Gson.this.deserializationExclusionStrategy;
+ return !strategy.shouldSkipClass(f.getType())
+ && !strategy.shouldSkipField(new FieldAttributes(declaringClazz, f, declaredType));
}
};
@@ -238,6 +233,8 @@ public final class Gson {
doubleAdapter(serializeSpecialFloatingPointValues)))
.factory(TypeAdapters.newFactory(float.class, Float.class,
floatAdapter(serializeSpecialFloatingPointValues)))
+ .factory(new ExcludedTypeAdapterFactory(
+ serializationExclusionStrategy, deserializationExclusionStrategy))
.factory(TypeAdapters.STRING_FACTORY)
.factory(TypeAdapters.STRING_BUILDER_FACTORY)
.factory(TypeAdapters.STRING_BUFFER_FACTORY)
@@ -248,11 +245,12 @@ public final class Gson {
.factory(TypeAdapters.INET_ADDRESS_FACTORY)
.typeAdapter(BigDecimal.class, new BigDecimalTypeAdapter())
.typeAdapter(BigInteger.class, new BigIntegerTypeAdapter())
- .factory(excludedTypeFactory)
- .factory(GsonCompatibleMapTypeAdapter.FACTORY)
- .factory(CollectionTypeAdapter.FACTORY)
+ .factory(new MapTypeAdapterFactory(constructorConstructor))
+ .factory(new CollectionTypeAdapterFactory(constructorConstructor))
.factory(ObjectTypeAdapter.FACTORY)
- .factory(new GsonToMiniGsonTypeAdapter(serializers, deserializers, serializeNulls))
+ .factory(new GsonToMiniGsonTypeAdapterFactory(serializers, deserializers,
+ new JsonDeserializationContext(this), new JsonSerializationContext(this), serializeNulls
+ ))
.factory(ArrayTypeAdapter.FACTORY)
.factory(reflectiveTypeAdapterFactory);
@@ -265,9 +263,17 @@ public final class Gson {
}
return new TypeAdapter() {
@Override public Double read(JsonReader reader) throws IOException {
+ if (reader.peek() == JsonToken.NULL) {
+ reader.nextNull(); // TODO: does this belong here?
+ return null;
+ }
return reader.nextDouble();
}
@Override public void write(JsonWriter writer, Number value) throws IOException {
+ if (value == null) {
+ writer.nullValue(); // TODO: better policy here?
+ return;
+ }
double doubleValue = value.doubleValue();
checkValidFloatingPoint(doubleValue);
writer.value(value);
@@ -281,9 +287,17 @@ public final class Gson {
}
return new TypeAdapter() {
@Override public Float read(JsonReader reader) throws IOException {
+ if (reader.peek() == JsonToken.NULL) {
+ reader.nextNull(); // TODO: does this belong here?
+ return null;
+ }
return (float) reader.nextDouble();
}
@Override public void write(JsonWriter writer, Number value) throws IOException {
+ if (value == null) {
+ writer.nullValue(); // TODO: better policy here?
+ return;
+ }
float floatValue = value.floatValue();
checkValidFloatingPoint(floatValue);
writer.value(value);
@@ -305,9 +319,17 @@ public final class Gson {
}
return new TypeAdapter() {
@Override public Number read(JsonReader reader) throws IOException {
+ if (reader.peek() == JsonToken.NULL) {
+ reader.nextNull(); // TODO: does this belong here?
+ return null;
+ }
return reader.nextLong();
}
@Override public void write(JsonWriter writer, Number value) throws IOException {
+ if (value == null) {
+ writer.nullValue(); // TODO: better policy here?
+ return;
+ }
writer.value(value.toString());
}
};
@@ -640,11 +662,23 @@ public final class Gson {
*/
@SuppressWarnings("unchecked")
public T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
+ boolean isEmpty = true;
boolean oldLenient = reader.isLenient();
reader.setLenient(true);
try {
+ reader.peek();
+ isEmpty = false;
TypeAdapter typeAdapter = (TypeAdapter) miniGson.getAdapter(TypeToken.get(typeOfT));
return typeAdapter.read(reader);
+ } catch (EOFException e) {
+ /*
+ * For compatibility with JSON 1.5 and earlier, we return null for empty
+ * documents instead of throwing.
+ */
+ if (isEmpty) {
+ return null;
+ }
+ throw new JsonSyntaxException(e);
} catch (IOException e) {
// TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException
throw new JsonSyntaxException(e);
@@ -710,8 +744,9 @@ public final class Gson {
// using the name instanceCreator instead of ObjectConstructor since the users of Gson are
// more familiar with the concept of Instance Creators. Moreover, the objectConstructor is
// just a utility class around instance creators, and its toString() only displays them.
- .append(",instanceCreators:").append(objectConstructor)
+ .append(",instanceCreators:").append(constructorConstructor)
.append("}");
return sb.toString();
}
+
}
diff --git a/gson/src/main/java/com/google/gson/GsonBuilder.java b/gson/src/main/java/com/google/gson/GsonBuilder.java
index cdd123cc..09f580c0 100644
--- a/gson/src/main/java/com/google/gson/GsonBuilder.java
+++ b/gson/src/main/java/com/google/gson/GsonBuilder.java
@@ -18,6 +18,8 @@ package com.google.gson;
import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
import com.google.gson.internal.$Gson$Preconditions;
+import com.google.gson.internal.ParameterizedTypeHandlerMap;
+import com.google.gson.internal.Primitives;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.text.DateFormat;
@@ -678,6 +680,7 @@ public final class GsonBuilder {
addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, customSerializers,
customDeserializers);
+ customSerializers.registerIfAbsent(DefaultTypeAdapters.getDefaultSerializers());
customDeserializers.registerIfAbsent(DefaultTypeAdapters.getDefaultDeserializers());
ParameterizedTypeHandlerMap> customInstanceCreators =
@@ -688,11 +691,9 @@ public final class GsonBuilder {
customDeserializers.makeUnmodifiable();
instanceCreators.makeUnmodifiable();
- MappedObjectConstructor objConstructor = new MappedObjectConstructor(customInstanceCreators);
-
return new Gson(new DisjunctionExclusionStrategy(deserializationStrategies),
new DisjunctionExclusionStrategy(serializationStrategies),
- fieldNamingPolicy, objConstructor, serializeNulls,
+ fieldNamingPolicy, instanceCreators, serializeNulls,
customSerializers, customDeserializers, generateNonExecutableJson, escapeHtmlChars,
prettyPrinting, serializeSpecialFloatingPointValues, longSerializationPolicy);
}
diff --git a/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapter.java b/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapter.java
deleted file mode 100644
index 0daa1ff4..00000000
--- a/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapter.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.io.IOException;
-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;
-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();
- }
- JsonElement value = Streams.parse(reader);
- if (value.isJsonNull()) {
- return null;
- }
- return deserializer.deserialize(value, 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();
- }
- if (value == null) {
- writer.nullValue();
- return;
- }
- 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) {
- TypeToken typeToken = TypeToken.get(typeOfSrc);
- return miniGson.getAdapter(typeToken).toJsonElement(src);
- }
- };
- }
- public JsonDeserializationContext createDeserializationContext(final MiniGson miniGson) {
- return new JsonDeserializationContext() {
- @Override
- public T deserialize(JsonElement json, Type typeOfT) throws JsonParseException {
- TypeToken typeToken = TypeToken.get(typeOfT);
- return (T) miniGson.getAdapter(typeToken).fromJsonElement(json);
- }
-
- @Override public T construct(Type type) {
- throw new UnsupportedOperationException();
- }
-
- @Override public Object constructArray(Type type, int length) {
- throw new UnsupportedOperationException();
- }
-
- @Override public T deserializeDefault(JsonElement json, Type typeOfT) throws JsonParseException {
- throw new UnsupportedOperationException();
- }
- };
- }
-}
diff --git a/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapterFactory.java b/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapterFactory.java
new file mode 100644
index 00000000..77fdd02a
--- /dev/null
+++ b/gson/src/main/java/com/google/gson/GsonToMiniGsonTypeAdapterFactory.java
@@ -0,0 +1,99 @@
+/*
+ * 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 com.google.gson.internal.ParameterizedTypeHandlerMap;
+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;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+final class GsonToMiniGsonTypeAdapterFactory implements TypeAdapter.Factory {
+ private final ParameterizedTypeHandlerMap> serializers;
+ private final ParameterizedTypeHandlerMap> deserializers;
+ private final JsonDeserializationContext deserializationContext;
+ private final JsonSerializationContext serializationContext;
+ private final boolean serializeNulls;
+
+ GsonToMiniGsonTypeAdapterFactory(ParameterizedTypeHandlerMap> serializers,
+ ParameterizedTypeHandlerMap> deserializers,
+ JsonDeserializationContext deserializationContext,
+ JsonSerializationContext serializationContext, boolean serializeNulls) {
+ this.serializers = serializers;
+ this.deserializers = deserializers;
+ this.serializeNulls = serializeNulls;
+ this.deserializationContext = deserializationContext;
+ this.serializationContext = serializationContext;
+ }
+
+ public TypeAdapter create(final MiniGson context, final TypeToken typeToken) {
+ final Type type = typeToken.getType();
+
+ @SuppressWarnings("unchecked") // guaranteed to match typeOfT
+ final JsonSerializer serializer
+ = (JsonSerializer) serializers.getHandlerFor(type, false);
+ @SuppressWarnings("unchecked") // guaranteed to match typeOfT
+ final JsonDeserializer deserializer
+ = (JsonDeserializer) deserializers.getHandlerFor(type, false);
+
+ if (serializer == null && deserializer == null) {
+ return null;
+ }
+
+ return new TypeAdapter() {
+ /**
+ * The delegate is lazily created because it may not be needed, and
+ * creating it may fail.
+ */
+ private TypeAdapter delegate;
+
+ @Override public T read(JsonReader reader) throws IOException {
+ if (deserializer == null) {
+ return delegate().read(reader);
+ }
+ JsonElement value = Streams.parse(reader);
+ if (value.isJsonNull()) {
+ return null;
+ }
+ return deserializer.deserialize(value, type, deserializationContext);
+ }
+
+ @Override public void write(JsonWriter writer, T value) throws IOException {
+ if (serializer == null) {
+ delegate().write(writer, value);
+ return;
+ }
+ if (value == null) {
+ writer.nullValue();
+ return;
+ }
+ JsonElement element = serializer.serialize(value, type, serializationContext);
+ Streams.write(element, serializeNulls, writer);
+ }
+
+ private TypeAdapter delegate() {
+ TypeAdapter d = delegate;
+ return d != null
+ ? d
+ : (delegate = context.getNextAdapter(GsonToMiniGsonTypeAdapterFactory.this, typeToken));
+ }
+ };
+ }
+}
diff --git a/gson/src/main/java/com/google/gson/JsonArrayDeserializationVisitor.java b/gson/src/main/java/com/google/gson/JsonArrayDeserializationVisitor.java
deleted file mode 100644
index c7806acf..00000000
--- a/gson/src/main/java/com/google/gson/JsonArrayDeserializationVisitor.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2008 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 com.google.gson.internal.$Gson$Types;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Type;
-
-/**
- * A visitor that populates fields of an object with data from its equivalent
- * JSON representation
- *
- * @author Inderjeet Singh
- * @author Joel Leitch
- */
-final class JsonArrayDeserializationVisitor extends JsonDeserializationVisitor {
-
- JsonArrayDeserializationVisitor(JsonArray jsonArray, Type arrayType,
- ObjectNavigator objectNavigator, FieldNamingStrategy2 fieldNamingPolicy,
- ObjectConstructor objectConstructor,
- ParameterizedTypeHandlerMap> deserializers,
- JsonDeserializationContext context) {
- super(jsonArray, arrayType, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- protected T constructTarget() {
- if (!json.isJsonArray()) {
- throw new JsonParseException("Expecting array found: " + json);
- }
- JsonArray jsonArray = json.getAsJsonArray();
- if ($Gson$Types.isArray(targetType)) {
- // We know that we are getting back an array of the required type, so
- // this typecasting is safe.
- return (T) objectConstructor.constructArray($Gson$Types.getArrayComponentType(targetType),
- jsonArray.size());
- }
- // is a collection
- return (T) objectConstructor.construct($Gson$Types.getRawType(targetType));
- }
-
- public void visitArray(Object array, Type arrayType) {
- if (!json.isJsonArray()) {
- throw new JsonParseException("Expecting array found: " + json);
- }
- JsonArray jsonArray = json.getAsJsonArray();
- for (int i = 0; i < jsonArray.size(); i++) {
- JsonElement jsonChild = jsonArray.get(i);
- Object child;
-
- if (jsonChild == null || jsonChild.isJsonNull()) {
- child = null;
- } else if (jsonChild instanceof JsonObject) {
- child = visitChildAsObject($Gson$Types.getArrayComponentType(arrayType), jsonChild);
- } else if (jsonChild instanceof JsonArray) {
- child = visitChildAsArray($Gson$Types.getArrayComponentType(arrayType),
- jsonChild.getAsJsonArray());
- } else if (jsonChild instanceof JsonPrimitive) {
- child = visitChildAsObject($Gson$Types.getArrayComponentType(arrayType),
- jsonChild.getAsJsonPrimitive());
- } else {
- throw new IllegalStateException();
- }
- Array.set(array, i, child);
- }
- }
-
- // We should not implement any other method from Visitor interface since
- // all other methods should be invoked on JsonObjectDeserializationVisitor
- // instead.
-
- public void startVisitingObject(Object node) {
- throw new JsonParseException("Expecting array but found object: " + node);
- }
-
- public void visitArrayField(FieldAttributes f, Type typeOfF, Object obj) {
- throw new JsonParseException("Expecting array but found array field " + f.getName() + ": "
- + obj);
- }
-
- public void visitObjectField(FieldAttributes f, Type typeOfF, Object obj) {
- throw new JsonParseException("Expecting array but found object field " + f.getName() + ": "
- + obj);
- }
-
- public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type actualTypeOfField, Object parent) {
- throw new JsonParseException("Expecting array but found field " + f.getName() + ": "
- + parent);
- }
-
- public void visitPrimitive(Object primitive) {
- throw new JsonParseException(
- "Type information is unavailable, and the target is not a primitive: " + json);
- }
-}
diff --git a/gson/src/main/java/com/google/gson/JsonDeserializationContext.java b/gson/src/main/java/com/google/gson/JsonDeserializationContext.java
index 3bfbe763..578e6e89 100644
--- a/gson/src/main/java/com/google/gson/JsonDeserializationContext.java
+++ b/gson/src/main/java/com/google/gson/JsonDeserializationContext.java
@@ -27,23 +27,10 @@ import java.lang.reflect.Type;
* @author Joel Leitch
*/
public class JsonDeserializationContext {
- private final ObjectNavigator objectNavigator;
- private final FieldNamingStrategy2 fieldNamingPolicy;
- private final ParameterizedTypeHandlerMap> deserializers;
- private final MappedObjectConstructor objectConstructor;
+ private final Gson gson;
- JsonDeserializationContext(ObjectNavigator objectNavigator,
- FieldNamingStrategy2 fieldNamingPolicy,
- ParameterizedTypeHandlerMap> deserializers,
- MappedObjectConstructor objectConstructor) {
- this.objectNavigator = objectNavigator;
- this.fieldNamingPolicy = fieldNamingPolicy;
- this.deserializers = deserializers;
- this.objectConstructor = objectConstructor;
- }
-
- JsonDeserializationContext() {
- this(null, null, null, null);
+ JsonDeserializationContext(Gson gson) {
+ this.gson = gson;
}
/**
@@ -51,41 +38,11 @@ public class JsonDeserializationContext {
*/
@SuppressWarnings("unchecked") @Deprecated
public T construct(Type type) {
- Object instance = objectConstructor.construct(type);
- return (T) instance;
+ throw new UnsupportedOperationException();
}
public Object constructArray(Type type, int length) {
- return objectConstructor.constructArray(type, length);
- }
-
-
- private T fromJsonArray(Type arrayType, JsonArray jsonArray,
- JsonDeserializationContext context, boolean systemOnly) throws JsonParseException {
- JsonArrayDeserializationVisitor visitor = new JsonArrayDeserializationVisitor(
- jsonArray, arrayType, objectNavigator, fieldNamingPolicy,
- objectConstructor, deserializers, context);
- objectNavigator.accept(new ObjectTypePair(null, arrayType, true, systemOnly), visitor);
- return visitor.getTarget();
- }
-
- private T fromJsonObject(Type typeOfT, JsonObject jsonObject,
- JsonDeserializationContext context, boolean systemOnly) throws JsonParseException {
- JsonObjectDeserializationVisitor visitor = new JsonObjectDeserializationVisitor(
- jsonObject, typeOfT, objectNavigator, fieldNamingPolicy,
- objectConstructor, deserializers, context);
- objectNavigator.accept(new ObjectTypePair(null, typeOfT, true, systemOnly), visitor);
- return visitor.getTarget();
- }
-
- @SuppressWarnings("unchecked")
- private T fromJsonPrimitive(Type typeOfT, JsonPrimitive json,
- JsonDeserializationContext context, boolean systemOnly) throws JsonParseException {
- JsonObjectDeserializationVisitor visitor = new JsonObjectDeserializationVisitor(
- json, typeOfT, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context);
- objectNavigator.accept(new ObjectTypePair(json.getAsObject(), typeOfT, true, systemOnly), visitor);
- Object target = visitor.getTarget();
- return (T) target;
+ throw new UnsupportedOperationException();
}
/**
@@ -102,37 +59,11 @@ public class JsonDeserializationContext {
*/
@SuppressWarnings("unchecked")
public T deserialize(JsonElement json, Type typeOfT) throws JsonParseException {
- if (json == null || json.isJsonNull()) {
- return null;
- } else if (json.isJsonArray()) {
- Object array = fromJsonArray(typeOfT, json.getAsJsonArray(), this, false);
- return (T) array;
- } else if (json.isJsonObject()) {
- Object object = fromJsonObject(typeOfT, json.getAsJsonObject(), this, false);
- return (T) object;
- } else if (json.isJsonPrimitive()) {
- Object primitive = fromJsonPrimitive(typeOfT, json.getAsJsonPrimitive(), this, false);
- return (T) primitive;
- } else {
- throw new JsonParseException("Failed parsing JSON source: " + json + " to Json");
- }
+ return gson.fromJson(json, typeOfT);
}
@SuppressWarnings("unchecked")
public T deserializeDefault(JsonElement json, Type typeOfT) throws JsonParseException {
- if (json == null || json.isJsonNull()) {
- return null;
- } else if (json.isJsonArray()) {
- Object array = fromJsonArray(typeOfT, json.getAsJsonArray(), this, true);
- return (T) array;
- } else if (json.isJsonObject()) {
- Object object = fromJsonObject(typeOfT, json.getAsJsonObject(), this, true);
- return (T) object;
- } else if (json.isJsonPrimitive()) {
- Object primitive = fromJsonPrimitive(typeOfT, json.getAsJsonPrimitive(), this, true);
- return (T) primitive;
- } else {
- throw new JsonParseException("Failed parsing JSON source: " + json + " to Json");
- }
+ throw new UnsupportedOperationException();
}
}
\ No newline at end of file
diff --git a/gson/src/main/java/com/google/gson/JsonDeserializationVisitor.java b/gson/src/main/java/com/google/gson/JsonDeserializationVisitor.java
deleted file mode 100644
index 033bf20d..00000000
--- a/gson/src/main/java/com/google/gson/JsonDeserializationVisitor.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2008 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 com.google.gson.internal.$Gson$Preconditions;
-
-import java.lang.reflect.Type;
-
-/**
- * Abstract data value container for the {@link ObjectNavigator.Visitor}
- * implementations. This class exposes the {@link #getTarget()} method
- * which returns the class that was visited by this object.
- *
- * @author Inderjeet Singh
- * @author Joel Leitch
- */
-abstract class JsonDeserializationVisitor implements ObjectNavigator.Visitor {
-
- protected final ObjectNavigator objectNavigator;
- protected final FieldNamingStrategy2 fieldNamingPolicy;
- protected final ObjectConstructor objectConstructor;
- protected final ParameterizedTypeHandlerMap> deserializers;
- protected T target;
- protected final JsonElement json;
- protected final Type targetType;
- protected final JsonDeserializationContext context;
- protected boolean constructed;
-
- JsonDeserializationVisitor(JsonElement json, Type targetType,
- ObjectNavigator objectNavigator, FieldNamingStrategy2 fieldNamingPolicy,
- ObjectConstructor objectConstructor,
- ParameterizedTypeHandlerMap> deserializers,
- JsonDeserializationContext context) {
- this.targetType = targetType;
- this.objectNavigator = objectNavigator;
- this.fieldNamingPolicy = fieldNamingPolicy;
- this.objectConstructor = objectConstructor;
- this.deserializers = deserializers;
- this.json = $Gson$Preconditions.checkNotNull(json);
- this.context = context;
- this.constructed = false;
- }
-
- public T getTarget() {
- if (!constructed) {
- target = constructTarget();
- constructed = true;
- }
- return target;
- }
-
- protected abstract T constructTarget();
-
- public void start(ObjectTypePair node) {
- }
-
- public void end(ObjectTypePair node) {
- }
-
- @SuppressWarnings("unchecked")
- public final boolean visitUsingCustomHandler(ObjectTypePair objTypePair) {
- Pair, ObjectTypePair> pair = objTypePair.getMatchingHandler(deserializers);
- if (pair == null) {
- return false;
- }
- Object value = invokeCustomDeserializer(json, pair);
- target = (T) value;
- constructed = true;
- return true;
- }
-
- protected Object invokeCustomDeserializer(JsonElement element,
- Pair, ObjectTypePair> pair) {
- if (element == null || element.isJsonNull()) {
- return null;
- }
- Type objType = pair.second.type;
- return (pair.first).deserialize(element, objType, context);
- }
-
- final Object visitChildAsObject(Type childType, JsonElement jsonChild) {
- JsonDeserializationVisitor> childVisitor =
- new JsonObjectDeserializationVisitor