Removed ExceptionWrapper from serializers.

This is done since it is improper to throw a parse exception from serializers. Moreover, the serializers dont deal with external input, they deal with classes, so they need not guard against spurious input.
This commit is contained in:
Inderjeet Singh 2008-11-14 02:17:19 +00:00
parent 9245bebdba
commit bc2c25f235
7 changed files with 12 additions and 175 deletions

View File

@ -29,7 +29,6 @@ import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
@ -90,15 +89,15 @@ final class DefaultTypeAdapters {
ParameterizedTypeHandlerMap<JsonSerializer<?>> map =
new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
map.register(Enum.class, wrapSerializer(ENUM_TYPE_ADAPTER));
map.register(URL.class, wrapSerializer(URL_TYPE_ADAPTER));
map.register(URI.class, wrapSerializer(URI_TYPE_ADAPTER));
map.register(Locale.class, wrapSerializer(LOCALE_TYPE_ADAPTER));
map.register(Enum.class, ENUM_TYPE_ADAPTER);
map.register(URL.class, URL_TYPE_ADAPTER);
map.register(URI.class, URI_TYPE_ADAPTER);
map.register(Locale.class, LOCALE_TYPE_ADAPTER);
map.register(Collection.class, COLLECTION_TYPE_ADAPTER);
map.register(Map.class, wrapSerializer(MAP_TYPE_ADAPTER));
map.register(Date.class, wrapSerializer(DATE_TYPE_ADAPTER));
map.register(BigDecimal.class, wrapSerializer(BIG_DECIMAL_TYPE_ADAPTER));
map.register(BigInteger.class, wrapSerializer(BIG_INTEGER_TYPE_ADAPTER));
map.register(Map.class, MAP_TYPE_ADAPTER);
map.register(Date.class, DATE_TYPE_ADAPTER);
map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER);
map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER);
map.makeUnmodifiable();
return map;
}
@ -158,11 +157,6 @@ final class DefaultTypeAdapters {
return map;
}
@SuppressWarnings("unchecked")
private static JsonSerializer<?> wrapSerializer(JsonSerializer<?> serializer) {
return new JsonSerializerExceptionWrapper(serializer);
}
@SuppressWarnings("unchecked")
private static JsonDeserializer<?> wrapDeserializer(JsonDeserializer<?> deserializer) {
return new JsonDeserializerExceptionWrapper(deserializer);

View File

@ -305,7 +305,7 @@ public final class GsonBuilder {
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
*/
private <T> GsonBuilder registerSerializer(Type typeOfT, final JsonSerializer<T> serializer) {
serializers.register(typeOfT, new JsonSerializerExceptionWrapper<T>(serializer));
serializers.register(typeOfT, serializer);
return this;
}

View File

@ -17,8 +17,6 @@
package com.google.gson;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;
import java.util.logging.Logger;
/**

View File

@ -1,69 +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 java.lang.reflect.Type;
/**
* Decorators a {@code JsonSerializer} instance with exception handling. This wrapper class
* ensures that a {@code JsonSerializer} will not propagate any exception other than a
* {@link JsonParseException}.
*
* @param <T> type of the serializer being wrapped.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
class JsonSerializerExceptionWrapper<T> implements JsonSerializer<T> {
private final JsonSerializer<T> delegate;
/**
* Returns a wrapped {@link JsonSerializer} object that has been decorated with
* {@link JsonParseException} handling.
*
* @param delegate the {@code JsonSerializer} instance to be wrapped
* @throws IllegalArgumentException if {@code delegate} is {@code null}.
*/
JsonSerializerExceptionWrapper(JsonSerializer<T> delegate) {
Preconditions.checkNotNull(delegate);
this.delegate = delegate;
}
public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
try {
return delegate.serialize(src, typeOfSrc, context);
} catch (JsonParseException e) {
// just rethrow the exception
throw e;
} catch (Exception e) {
// throw as a JsonParseException
StringBuilder errorMsg = new StringBuilder()
.append("The JsonSerializer ")
.append(delegate)
.append(" failed to serialized object ")
.append(src)
.append(" given the type ")
.append(typeOfSrc);
throw new JsonParseException(errorMsg.toString(), e);
}
}
@Override
public String toString() {
return delegate.toString();
}
}

View File

@ -52,7 +52,7 @@ public class GsonTypeAdapterTest extends TestCase {
try {
gson.toJson(new AtomicLong(0));
fail("Type Adapter should have thrown an exception");
} catch (JsonParseException expected) { }
} catch (IllegalStateException expected) { }
try {
gson.fromJson("123", AtomicLong.class);

View File

@ -1,86 +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.DefaultTypeAdapters.DefaultDateTypeAdapter;
import junit.framework.TestCase;
import java.lang.reflect.Type;
import java.text.DateFormat;
import java.util.Date;
/**
* Simple unit tests for the {@link JsonSerializerExceptionWrapper} class.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
public class JsonSerializerExceptionWrapperTest extends TestCase {
public void testRethrowJsonParseException() throws Exception {
String errorMsg = "please rethrow me";
JsonSerializerExceptionWrapper<String> wrappedJsonSerializer =
new JsonSerializerExceptionWrapper<String>(
new ExceptionJsonSerializer(new JsonParseException(errorMsg)));
try {
wrappedJsonSerializer.serialize("blah", String.class, null);
fail("JsonParseException should have been thrown");
} catch (JsonParseException expected) {
assertNull(expected.getCause());
assertEquals(errorMsg, expected.getMessage());
}
}
public void testWrappedExceptionPropagation() throws Exception {
IllegalArgumentException exceptionToThrow = new IllegalArgumentException();
JsonSerializerExceptionWrapper<String> wrappedJsonSerializer =
new JsonSerializerExceptionWrapper<String>(
new ExceptionJsonSerializer(exceptionToThrow));
try {
wrappedJsonSerializer.serialize("blah", String.class, null);
fail("JsonParseException should have been thrown");
} catch (JsonParseException expected) {
assertEquals(exceptionToThrow, expected.getCause());
}
}
public void testProperSerialization() throws Exception {
Date now = new Date();
DefaultDateTypeAdapter dateSerializer = new DefaultDateTypeAdapter(DateFormat.LONG);
JsonSerializerExceptionWrapper<Date> wrappedJsonSerializer =
new JsonSerializerExceptionWrapper<Date>(dateSerializer);
JsonElement expected = dateSerializer.serialize(now, Date.class, null);
JsonElement actual = wrappedJsonSerializer.serialize(now, Date.class, null);
assertEquals(expected.getAsString(), actual.getAsString());
}
private static class ExceptionJsonSerializer implements JsonSerializer<String> {
private final RuntimeException exceptionToThrow;
public ExceptionJsonSerializer(RuntimeException exceptionToThrow) {
this.exceptionToThrow = exceptionToThrow;
}
public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) {
throw exceptionToThrow;
}
}
}

View File

@ -95,8 +95,8 @@ public class MapTest extends TestCase {
}).create();
String json = "{\"a\":1,\"b\":2}";
MyParameterizedMap<String, Integer> map = gson.fromJson(json, type);
assertEquals(1, ((Integer) map.get("a")).intValue());
assertEquals(2, ((Integer) map.get("b")).intValue());
assertEquals(1, map.get("a").intValue());
assertEquals(2, map.get("b").intValue());
}
private static class MyParameterizedMap<K, V> extends LinkedHashMap<K, V> {