Removed the TypeAdapter object from GSON now that the primitive objects and fields are created by a custom Type Adapter.

This commit is contained in:
Joel Leitch 2008-11-15 05:11:28 +00:00
parent 0d8150fe52
commit cf2a457af7
11 changed files with 24 additions and 164 deletions

View File

@ -78,8 +78,6 @@ public final class Gson {
private static final String NULL_STRING = "null";
// Default instances of plug-ins
static final TypeAdapter DEFAULT_TYPE_ADAPTER =
new TypeAdapterNotRequired(new PrimitiveTypeAdapter());
static final ModifierBasedExclusionStrategy DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY =
new ModifierBasedExclusionStrategy(true, new int[] { Modifier.TRANSIENT, Modifier.STATIC });
static final JsonFormatter DEFAULT_JSON_FORMATTER = new JsonCompactFormatter();
@ -91,7 +89,6 @@ public final class Gson {
private final ExclusionStrategy strategy;
private final FieldNamingStrategy fieldNamingPolicy;
private final MappedObjectConstructor objectConstructor;
private final TypeAdapter typeAdapter;
/** Map containing Type or Class objects as keys */
private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
@ -146,19 +143,17 @@ public final class Gson {
*/
Gson(ExclusionStrategy strategy, FieldNamingStrategy fieldNamingPolicy) {
this(strategy, fieldNamingPolicy, createObjectConstructor(DefaultTypeAdapters.DEFAULT_INSTANCE_CREATORS),
DEFAULT_TYPE_ADAPTER, DEFAULT_JSON_FORMATTER, false,
DEFAULT_JSON_FORMATTER, false,
DefaultTypeAdapters.DEFAULT_SERIALIZERS, DefaultTypeAdapters.DEFAULT_DESERIALIZERS);
}
Gson(ExclusionStrategy strategy, FieldNamingStrategy fieldNamingPolicy,
MappedObjectConstructor objectConstructor,
TypeAdapter typeAdapter, JsonFormatter formatter, boolean serializeNulls,
MappedObjectConstructor objectConstructor, JsonFormatter formatter, boolean serializeNulls,
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers) {
this.strategy = strategy;
this.fieldNamingPolicy = fieldNamingPolicy;
this.objectConstructor = objectConstructor;
this.typeAdapter = typeAdapter;
this.formatter = formatter;
this.serializeNulls = serializeNulls;
this.serializers = serializers;
@ -374,7 +369,7 @@ public final class Gson {
JsonParser parser = new JsonParser(json);
JsonElement root = parser.parse();
JsonDeserializationContext context = new JsonDeserializationContextDefault(
createDefaultObjectNavigatorFactory(), deserializers, objectConstructor, typeAdapter);
createDefaultObjectNavigatorFactory(), deserializers, objectConstructor);
T target = (T) context.deserialize(root, typeOfT);
return target;
} catch (TokenMgrError e) {

View File

@ -55,7 +55,6 @@ public final class GsonBuilder {
private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy;
private final InnerClassExclusionStrategy innerClassExclusionStrategy;
private boolean excludeFieldsWithoutExposeAnnotation;
private final TypeAdapter typeAdapter;
private JsonFormatter formatter;
private FieldNamingStrategy fieldNamingPolicy;
private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreators;
@ -78,7 +77,6 @@ public final class GsonBuilder {
innerClassExclusionStrategy = new InnerClassExclusionStrategy();
modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY;
excludeFieldsWithoutExposeAnnotation = false;
typeAdapter = Gson.DEFAULT_TYPE_ADAPTER;
formatter = Gson.DEFAULT_JSON_FORMATTER;
fieldNamingPolicy = Gson.DEFAULT_NAMING_POLICY;
instanceCreators = new ParameterizedTypeHandlerMap<InstanceCreator<?>>();
@ -355,7 +353,7 @@ public final class GsonBuilder {
customInstanceCreators.registerIfAbsent(DefaultTypeAdapters.DEFAULT_INSTANCE_CREATORS);
MappedObjectConstructor objConstructor = Gson.createObjectConstructor(customInstanceCreators);
Gson gson = new Gson(exclusionStrategy, fieldNamingPolicy, objConstructor, typeAdapter,
Gson gson = new Gson(exclusionStrategy, fieldNamingPolicy, objConstructor,
formatter, serializeNulls, customSerializers, customDeserializers);
return gson;
}

View File

@ -31,9 +31,9 @@ final class JsonArrayDeserializationVisitor<T> extends JsonDeserializationVisito
JsonArrayDeserializationVisitor(JsonArray jsonArray, Type arrayType,
ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
TypeAdapter typeAdapter, ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
JsonDeserializationContext context) {
super(jsonArray, arrayType, factory, objectConstructor, typeAdapter, deserializers, context);
super(jsonArray, arrayType, factory, objectConstructor, deserializers, context);
}
@Override

View File

@ -28,15 +28,13 @@ final class JsonDeserializationContextDefault implements JsonDeserializationCont
private final ObjectNavigatorFactory navigatorFactory;
private final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
private final MappedObjectConstructor objectConstructor;
private final TypeAdapter typeAdapter;
JsonDeserializationContextDefault(ObjectNavigatorFactory navigatorFactory,
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
MappedObjectConstructor objectConstructor, TypeAdapter typeAdapter) {
MappedObjectConstructor objectConstructor) {
this.navigatorFactory = navigatorFactory;
this.deserializers = deserializers;
this.objectConstructor = objectConstructor;
this.typeAdapter = typeAdapter;
}
ObjectConstructor getObjectConstructor() {
@ -61,8 +59,7 @@ final class JsonDeserializationContextDefault implements JsonDeserializationCont
private <T> T fromJsonArray(Type arrayType, JsonArray jsonArray,
JsonDeserializationContext context) throws JsonParseException {
JsonArrayDeserializationVisitor<T> visitor = new JsonArrayDeserializationVisitor<T>(
jsonArray, arrayType, navigatorFactory, objectConstructor, typeAdapter, deserializers,
context);
jsonArray, arrayType, navigatorFactory, objectConstructor, deserializers, context);
Object target = visitor.getTarget();
ObjectNavigator on = navigatorFactory.create(target, arrayType);
on.accept(visitor);
@ -72,8 +69,7 @@ final class JsonDeserializationContextDefault implements JsonDeserializationCont
private <T> T fromJsonObject(Type typeOfT, JsonObject jsonObject,
JsonDeserializationContext context) throws JsonParseException {
JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
jsonObject, typeOfT, navigatorFactory, objectConstructor, typeAdapter, deserializers,
context);
jsonObject, typeOfT, navigatorFactory, objectConstructor, deserializers, context);
Object target = visitor.getTarget();
ObjectNavigator on = navigatorFactory.create(target, typeOfT);
on.accept(visitor);
@ -84,13 +80,10 @@ final class JsonDeserializationContextDefault implements JsonDeserializationCont
private <T> T fromJsonPrimitive(Type typeOfT, JsonPrimitive json,
JsonDeserializationContext context) throws JsonParseException {
JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
json, typeOfT, navigatorFactory, objectConstructor, typeAdapter, deserializers, context);
json, typeOfT, navigatorFactory, objectConstructor, deserializers, context);
ObjectNavigator on = navigatorFactory.create(json.getAsObject(), typeOfT);
on.accept(visitor);
Object target = visitor.getTarget();
if (typeOfT instanceof Class) {
target = typeAdapter.adaptType(target, (Class) typeOfT);
}
return (T) target;
}
}

View File

@ -33,7 +33,6 @@ abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor
protected final ObjectNavigatorFactory factory;
protected final ObjectConstructor objectConstructor;
protected final TypeAdapter typeAdapter;
protected final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
protected T target;
protected final JsonElement json;
@ -41,14 +40,13 @@ abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor
protected final JsonDeserializationContext context;
public JsonDeserializationVisitor(JsonElement json, Type targetType,
ObjectNavigatorFactory factory, ObjectConstructor objectConstructor, TypeAdapter typeAdapter,
ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
JsonDeserializationContext context) {
Preconditions.checkNotNull(json);
this.targetType = targetType;
this.factory = factory;
this.objectConstructor = objectConstructor;
this.typeAdapter = typeAdapter;
this.deserializers = deserializers;
this.json = json;
this.context = context;
@ -76,14 +74,14 @@ abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor
final Object visitChildAsObject(Type childType, JsonElement jsonChild) {
JsonDeserializationVisitor<?> childVisitor =
new JsonObjectDeserializationVisitor<Object>(jsonChild, childType,
factory, objectConstructor, typeAdapter, deserializers, context);
factory, objectConstructor, deserializers, context);
return visitChild(childType, childVisitor);
}
final Object visitChildAsArray(Type childType, JsonArray jsonChild) {
JsonDeserializationVisitor<?> childVisitor =
new JsonArrayDeserializationVisitor<Object>(jsonChild.getAsJsonArray(), childType,
factory, objectConstructor, typeAdapter, deserializers, context);
factory, objectConstructor, deserializers, context);
return visitChild(childType, childVisitor);
}

View File

@ -30,9 +30,9 @@ final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisit
JsonObjectDeserializationVisitor(JsonElement json, Type type,
ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
TypeAdapter typeAdapter, ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
JsonDeserializationContext context) {
super(json, type, factory, objectConstructor, typeAdapter, deserializers, context);
super(json, type, factory, objectConstructor, deserializers, context);
}
@Override

View File

@ -49,7 +49,7 @@ final class MappedObjectConstructor implements ObjectConstructor {
TypeInfo typeInfo = new TypeInfo(typeOfT);
if (typeInfo.isEnum()) {
InstanceCreator<T> creator =
(InstanceCreator<T>) instanceCreatorMap.getHandlerFor(Enum.class);
(InstanceCreator<T>) instanceCreatorMap.getHandlerFor(Enum.class);
return creator.createInstance(typeOfT);
}
return (T) constructWithNoArgConstructor(typeOfT);

View File

@ -1,53 +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;
/**
* This class implements the {@link TypeAdapter} interface; however, if the
* from instance type is the same as the to type then this object will
* terminate the chain early and return the "from" object to the calling
* class.
*
* If the incoming object does need some kind of conversion then this object
* will delegate to the {@link TypeAdapter} that it is wrapping.
*
* @author Joel Leitch
*/
final class TypeAdapterNotRequired implements TypeAdapter {
private final TypeAdapter delegate;
/**
* Constructs a TypeAdapterNotRequired that will wrap the delegate instance
* that is passed in.
*
* @param delegate the TypeConverter to delegate to if this instance can
* not handle the type adapting (can not be null)
*/
TypeAdapterNotRequired(TypeAdapter delegate) {
Preconditions.checkNotNull(delegate);
this.delegate = delegate;
}
@SuppressWarnings("unchecked")
public <T> T adaptType(Object from, Class<T> to) {
if (to.isAssignableFrom(from.getClass())) {
return (T) from;
}
return delegate.adaptType(from, to);
}
}

View File

@ -20,6 +20,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
/**
* This class contains some test fixtures for Parameterized types. These classes should ideally
* belong either in the common or functional package, but they are placed here because they need

View File

@ -20,15 +20,18 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.google.gson.JsonParseException;
import com.google.gson.Primitives;
/**
* Handles type conversion from some object to some primitive (or primitive
* wrapper instance).
*
*
* @author Joel Leitch
*/
final class PrimitiveTypeAdapter implements TypeAdapter {
final class PrimitiveTypeAdapter {
@SuppressWarnings({"unchecked"})
@SuppressWarnings( { "unchecked" })
public <T> T adaptType(Object from, Class<T> to) {
Class<?> aClass = Primitives.wrap(to);
if (Primitives.isWrapperType(aClass)) {
@ -67,8 +70,7 @@ final class PrimitiveTypeAdapter implements TypeAdapter {
throw new RuntimeException(e);
}
} else {
throw new JsonParseException(
"Can not adapt type " + from.getClass() + " to " + to);
throw new JsonParseException("Can not adapt type " + from.getClass() + " to " + to);
}
}
}

View File

@ -1,74 +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 junit.framework.TestCase;
/**
* Performs some unit testing for the {@link PrimitiveTypeAdapter} class.
*
* @author Joel Leitch
*/
public class PrimitiveTypeAdapterTest extends TestCase {
private PrimitiveTypeAdapter typeAdapter;
@Override
protected void setUp() throws Exception {
super.setUp();
typeAdapter = new PrimitiveTypeAdapter();
}
public void testImproperConversion() throws Exception {
double someValue = 1.0;
try {
typeAdapter.adaptType(someValue, String.class);
fail("Should not be able to convert incompatible types.");
} catch (JsonParseException expected) { }
}
public void testImproperCharacterConversion() throws Exception {
String someValue = "test123";
try {
typeAdapter.adaptType(someValue, Character.class);
fail("Should not be able to convert incompatible types.");
} catch (JsonParseException expected) { }
}
public void testProperPrimitiveConversions() throws Exception {
String stringValue = "1.0";
Double actualValue = typeAdapter.adaptType(stringValue, Double.class);
assertEquals(1.0, actualValue.doubleValue(), 0.0001);
Double doubleValue = 1.0;
actualValue = typeAdapter.adaptType(doubleValue, Double.class);
assertEquals(1.0, actualValue.doubleValue(), 0.0001);
stringValue = "A";
Character actualCharacter = typeAdapter.adaptType(stringValue, Character.class);
assertEquals('A', actualCharacter.charValue());
}
public void testProperEnumConversions() throws Exception {
TestEnum expected = TestEnum.TEST1;
TestEnum actual = typeAdapter.adaptType(expected, TestEnum.class);
assertEquals(expected, actual);
}
private static enum TestEnum {
TEST1, TEST2, TEST3
}
}