Forbid custom serializers for primitive types (so we can avoid boxing in the reflective and array adapters)
This commit is contained in:
parent
fede584b98
commit
e756608568
|
@ -30,4 +30,10 @@ com.google.gson.functional.PrimitiveTest.testDeserializingBigIntegerAsLong
|
||||||
|
|
||||||
GSON 1.x uses arbitrary precision for primitive type conversion (so -122.08e-2132 != 0)
|
GSON 1.x uses arbitrary precision for primitive type conversion (so -122.08e-2132 != 0)
|
||||||
GSON 2.x uses double precision (so -122.08e-2132 == 0)
|
GSON 2.x uses double precision (so -122.08e-2132 == 0)
|
||||||
com.google.gson.functional.PrimitiveTest.testDeserializingBigDecimalAsLongFails
|
com.google.gson.functional.PrimitiveTest.testDeserializingBigDecimalAsLongFails
|
||||||
|
|
||||||
|
|
||||||
|
GSON 1.x supports type adapters for primitive types
|
||||||
|
GSON 2.x doesn't
|
||||||
|
com.google.gson.functional.CustomTypeAdaptersTest.testCustomSerializerForLong
|
||||||
|
com.google.gson.functional.CustomTypeAdaptersTest.testCustomDeserializerForLong
|
||||||
|
|
|
@ -18,7 +18,6 @@ package com.google.gson;
|
||||||
|
|
||||||
import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
|
import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
|
||||||
import com.google.gson.internal.$Gson$Preconditions;
|
import com.google.gson.internal.$Gson$Preconditions;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
|
@ -495,6 +494,10 @@ public final class GsonBuilder {
|
||||||
private GsonBuilder registerTypeAdapter(Type type, Object typeAdapter, boolean isSystem) {
|
private GsonBuilder registerTypeAdapter(Type type, Object typeAdapter, boolean isSystem) {
|
||||||
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|
||||||
|| typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
|
|| typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
|
||||||
|
if (Primitives.isPrimitive(type) || Primitives.isWrapperType(type)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Cannot register type adapters for " + type);
|
||||||
|
}
|
||||||
if (typeAdapter instanceof InstanceCreator<?>) {
|
if (typeAdapter instanceof InstanceCreator<?>) {
|
||||||
registerInstanceCreator(type, (InstanceCreator<?>) typeAdapter, isSystem);
|
registerInstanceCreator(type, (InstanceCreator<?>) typeAdapter, isSystem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,12 @@
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.gson.internal.$Gson$Preconditions;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.google.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains static utility methods pertaining to primitive types and their
|
* Contains static utility methods pertaining to primitive types and their
|
||||||
* corresponding wrapper types.
|
* corresponding wrapper types.
|
||||||
|
@ -78,7 +77,7 @@ final class Primitives {
|
||||||
*
|
*
|
||||||
* @see Class#isPrimitive
|
* @see Class#isPrimitive
|
||||||
*/
|
*/
|
||||||
public static boolean isWrapperType(Class<?> type) {
|
public static boolean isWrapperType(Type type) {
|
||||||
return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(
|
return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(
|
||||||
$Gson$Preconditions.checkNotNull(type));
|
$Gson$Preconditions.checkNotNull(type));
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ import junit.framework.TestCase;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functional Test exercising custom deserialization only. When test applies to both
|
* Functional Test exercising custom deserialization only. When test applies to both
|
||||||
* serialization and deserialization then add it to CustomTypeAdapterTest.
|
* serialization and deserialization then add it to CustomTypeAdapterTest.
|
||||||
*
|
*
|
||||||
* @author Joel Leitch
|
* @author Joel Leitch
|
||||||
|
@ -39,27 +39,27 @@ import java.lang.reflect.Type;
|
||||||
public class CustomDeserializerTest extends TestCase {
|
public class CustomDeserializerTest extends TestCase {
|
||||||
private static final String DEFAULT_VALUE = "test123";
|
private static final String DEFAULT_VALUE = "test123";
|
||||||
private static final String SUFFIX = "blah";
|
private static final String SUFFIX = "blah";
|
||||||
|
|
||||||
private Gson gson;
|
private Gson gson;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
gson = new GsonBuilder().registerTypeAdapter(DataHolder.class, new DataHolderDeserializer()).create();
|
gson = new GsonBuilder().registerTypeAdapter(DataHolder.class, new DataHolderDeserializer()).create();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDefaultConstructorNotCalledOnObject() throws Exception {
|
public void testDefaultConstructorNotCalledOnObject() throws Exception {
|
||||||
DataHolder data = new DataHolder(DEFAULT_VALUE);
|
DataHolder data = new DataHolder(DEFAULT_VALUE);
|
||||||
String json = gson.toJson(data);
|
String json = gson.toJson(data);
|
||||||
|
|
||||||
DataHolder actual = gson.fromJson(json, DataHolder.class);
|
DataHolder actual = gson.fromJson(json, DataHolder.class);
|
||||||
assertEquals(DEFAULT_VALUE + SUFFIX, actual.getData());
|
assertEquals(DEFAULT_VALUE + SUFFIX, actual.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDefaultConstructorNotCalledOnField() throws Exception {
|
public void testDefaultConstructorNotCalledOnField() throws Exception {
|
||||||
DataHolderWrapper dataWrapper = new DataHolderWrapper(new DataHolder(DEFAULT_VALUE));
|
DataHolderWrapper dataWrapper = new DataHolderWrapper(new DataHolder(DEFAULT_VALUE));
|
||||||
String json = gson.toJson(dataWrapper);
|
String json = gson.toJson(dataWrapper);
|
||||||
|
|
||||||
DataHolderWrapper actual = gson.fromJson(json, DataHolderWrapper.class);
|
DataHolderWrapper actual = gson.fromJson(json, DataHolderWrapper.class);
|
||||||
assertEquals(DEFAULT_VALUE + SUFFIX, actual.getWrappedData().getData());
|
assertEquals(DEFAULT_VALUE + SUFFIX, actual.getWrappedData().getData());
|
||||||
}
|
}
|
||||||
|
@ -72,25 +72,25 @@ public class CustomDeserializerTest extends TestCase {
|
||||||
private DataHolder() {
|
private DataHolder() {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataHolder(String data) {
|
public DataHolder(String data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getData() {
|
public String getData() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DataHolderWrapper {
|
private static class DataHolderWrapper {
|
||||||
private final DataHolder wrappedData;
|
private final DataHolder wrappedData;
|
||||||
|
|
||||||
// For use by Gson
|
// For use by Gson
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private DataHolderWrapper() {
|
private DataHolderWrapper() {
|
||||||
this(new DataHolder(DEFAULT_VALUE));
|
this(new DataHolder(DEFAULT_VALUE));
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataHolderWrapper(DataHolder data) {
|
public DataHolderWrapper(DataHolder data) {
|
||||||
this.wrappedData = data;
|
this.wrappedData = data;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ public class CustomDeserializerTest extends TestCase {
|
||||||
return wrappedData;
|
return wrappedData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DataHolderDeserializer implements JsonDeserializer<DataHolder> {
|
private static class DataHolderDeserializer implements JsonDeserializer<DataHolder> {
|
||||||
public DataHolder deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
public DataHolder deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
throws JsonParseException {
|
throws JsonParseException {
|
||||||
|
@ -108,7 +108,7 @@ public class CustomDeserializerTest extends TestCase {
|
||||||
return new DataHolder(dataString + SUFFIX);
|
return new DataHolder(dataString + SUFFIX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testJsonTypeFieldBasedDeserialization() {
|
public void testJsonTypeFieldBasedDeserialization() {
|
||||||
String json = "{field1:'abc',field2:'def',__type__:'SUB_TYPE1'}";
|
String json = "{field1:'abc',field2:'def',__type__:'SUB_TYPE1'}";
|
||||||
Gson gson = new GsonBuilder().registerTypeAdapter(MyBase.class, new JsonDeserializer<MyBase>() {
|
Gson gson = new GsonBuilder().registerTypeAdapter(MyBase.class, new JsonDeserializer<MyBase>() {
|
||||||
|
@ -117,16 +117,16 @@ public class CustomDeserializerTest extends TestCase {
|
||||||
String type = json.getAsJsonObject().get(MyBase.TYPE_ACCESS).getAsString();
|
String type = json.getAsJsonObject().get(MyBase.TYPE_ACCESS).getAsString();
|
||||||
return context.deserialize(json, SubTypes.valueOf(type).getSubclass());
|
return context.deserialize(json, SubTypes.valueOf(type).getSubclass());
|
||||||
}
|
}
|
||||||
}).create();
|
}).create();
|
||||||
SubType1 target = (SubType1) gson.fromJson(json, MyBase.class);
|
SubType1 target = (SubType1) gson.fromJson(json, MyBase.class);
|
||||||
assertEquals("abc", target.field1);
|
assertEquals("abc", target.field1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MyBase {
|
private static class MyBase {
|
||||||
static final String TYPE_ACCESS = "__type__";
|
static final String TYPE_ACCESS = "__type__";
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum SubTypes {
|
private enum SubTypes {
|
||||||
SUB_TYPE1(SubType1.class),
|
SUB_TYPE1(SubType1.class),
|
||||||
SUB_TYPE2(SubType2.class);
|
SUB_TYPE2(SubType2.class);
|
||||||
private final Type subClass;
|
private final Type subClass;
|
||||||
|
@ -139,14 +139,14 @@ public class CustomDeserializerTest extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SubType1 extends MyBase {
|
private static class SubType1 extends MyBase {
|
||||||
String field1;
|
String field1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SubType2 extends MyBase {
|
private static class SubType2 extends MyBase {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
String field2;
|
String field2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCustomDeserializerReturnsNullForTopLevelObject() {
|
public void testCustomDeserializerReturnsNullForTopLevelObject() {
|
||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
.registerTypeAdapter(Base.class, new JsonDeserializer<Base>() {
|
.registerTypeAdapter(Base.class, new JsonDeserializer<Base>() {
|
||||||
|
@ -173,34 +173,6 @@ public class CustomDeserializerTest extends TestCase {
|
||||||
assertNull(target.base);
|
assertNull(target.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCustomDeserializerReturnsNullForTopLevelPrimitives() {
|
|
||||||
Gson gson = new GsonBuilder()
|
|
||||||
.registerTypeAdapter(long.class, new JsonDeserializer<Long>() {
|
|
||||||
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
|
||||||
throws JsonParseException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).create();
|
|
||||||
String json = "10";
|
|
||||||
assertNull(gson.fromJson(json, long.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCustomDeserializerReturnsNullForPrimitiveFields() {
|
|
||||||
Gson gson = new GsonBuilder()
|
|
||||||
.registerTypeAdapter(long.class, new JsonDeserializer<Long>() {
|
|
||||||
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
|
||||||
throws JsonParseException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).create();
|
|
||||||
String json = "{field:10}";
|
|
||||||
ClassWithLong target = gson.fromJson(json, ClassWithLong.class);
|
|
||||||
assertEquals(0, target.field);
|
|
||||||
}
|
|
||||||
private static class ClassWithLong {
|
|
||||||
long field;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCustomDeserializerReturnsNullForArrayElements() {
|
public void testCustomDeserializerReturnsNullForArrayElements() {
|
||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
.registerTypeAdapter(Base.class, new JsonDeserializer<Base>() {
|
.registerTypeAdapter(Base.class, new JsonDeserializer<Base>() {
|
||||||
|
|
|
@ -83,14 +83,14 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
ClassWithCustomTypeConverter target = gson.fromJson(json, ClassWithCustomTypeConverter.class);
|
ClassWithCustomTypeConverter target = gson.fromJson(json, ClassWithCustomTypeConverter.class);
|
||||||
assertEquals(5, target.getBag().getIntValue());
|
assertEquals(5, target.getBag().getIntValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disable_testCustomSerializersOfSelf() {
|
public void disable_testCustomSerializersOfSelf() {
|
||||||
Gson gson = createGsonObjectWithFooTypeAdapter();
|
Gson gson = createGsonObjectWithFooTypeAdapter();
|
||||||
Gson basicGson = new Gson();
|
Gson basicGson = new Gson();
|
||||||
Foo newFooObject = new Foo(1, 2L);
|
Foo newFooObject = new Foo(1, 2L);
|
||||||
String jsonFromCustomSerializer = gson.toJson(newFooObject);
|
String jsonFromCustomSerializer = gson.toJson(newFooObject);
|
||||||
String jsonFromGson = basicGson.toJson(newFooObject);
|
String jsonFromGson = basicGson.toJson(newFooObject);
|
||||||
|
|
||||||
assertEquals(jsonFromGson, jsonFromCustomSerializer);
|
assertEquals(jsonFromGson, jsonFromCustomSerializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
Foo expectedFoo = new Foo(1, 2L);
|
Foo expectedFoo = new Foo(1, 2L);
|
||||||
String json = basicGson.toJson(expectedFoo);
|
String json = basicGson.toJson(expectedFoo);
|
||||||
Foo newFooObject = gson.fromJson(json, Foo.class);
|
Foo newFooObject = gson.fromJson(json, Foo.class);
|
||||||
|
|
||||||
assertEquals(expectedFoo.key, newFooObject.key);
|
assertEquals(expectedFoo.key, newFooObject.key);
|
||||||
assertEquals(expectedFoo.value, newFooObject.value);
|
assertEquals(expectedFoo.value, newFooObject.value);
|
||||||
}
|
}
|
||||||
|
@ -130,58 +130,58 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
ClassWithCustomTypeConverter target = gson.fromJson(json, ClassWithCustomTypeConverter.class);
|
ClassWithCustomTypeConverter target = gson.fromJson(json, ClassWithCustomTypeConverter.class);
|
||||||
assertEquals(7, target.getBag().getIntValue());
|
assertEquals(7, target.getBag().getIntValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCustomTypeAdapterDoesNotAppliesToSubClasses() {
|
public void testCustomTypeAdapterDoesNotAppliesToSubClasses() {
|
||||||
Gson gson = new GsonBuilder().registerTypeAdapter(Base.class, new JsonSerializer<Base> () {
|
Gson gson = new GsonBuilder().registerTypeAdapter(Base.class, new JsonSerializer<Base> () {
|
||||||
public JsonElement serialize(Base src, Type typeOfSrc, JsonSerializationContext context) {
|
public JsonElement serialize(Base src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
JsonObject json = new JsonObject();
|
JsonObject json = new JsonObject();
|
||||||
json.addProperty("value", src.baseValue);
|
json.addProperty("value", src.baseValue);
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
}).create();
|
}).create();
|
||||||
Base b = new Base();
|
Base b = new Base();
|
||||||
String json = gson.toJson(b);
|
String json = gson.toJson(b);
|
||||||
assertTrue(json.contains("value"));
|
assertTrue(json.contains("value"));
|
||||||
b = new Derived();
|
b = new Derived();
|
||||||
json = gson.toJson(b);
|
json = gson.toJson(b);
|
||||||
assertTrue(json.contains("derivedValue"));
|
assertTrue(json.contains("derivedValue"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCustomTypeAdapterAppliesToSubClassesSerializedAsBaseClass() {
|
public void testCustomTypeAdapterAppliesToSubClassesSerializedAsBaseClass() {
|
||||||
Gson gson = new GsonBuilder().registerTypeAdapter(Base.class, new JsonSerializer<Base> () {
|
Gson gson = new GsonBuilder().registerTypeAdapter(Base.class, new JsonSerializer<Base> () {
|
||||||
public JsonElement serialize(Base src, Type typeOfSrc, JsonSerializationContext context) {
|
public JsonElement serialize(Base src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
JsonObject json = new JsonObject();
|
JsonObject json = new JsonObject();
|
||||||
json.addProperty("value", src.baseValue);
|
json.addProperty("value", src.baseValue);
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
}).create();
|
}).create();
|
||||||
Base b = new Base();
|
Base b = new Base();
|
||||||
String json = gson.toJson(b);
|
String json = gson.toJson(b);
|
||||||
assertTrue(json.contains("value"));
|
assertTrue(json.contains("value"));
|
||||||
b = new Derived();
|
b = new Derived();
|
||||||
json = gson.toJson(b, Base.class);
|
json = gson.toJson(b, Base.class);
|
||||||
assertTrue(json.contains("value"));
|
assertTrue(json.contains("value"));
|
||||||
assertFalse(json.contains("derivedValue"));
|
assertFalse(json.contains("derivedValue"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Base {
|
private static class Base {
|
||||||
int baseValue = 2;
|
int baseValue = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Derived extends Base {
|
private static class Derived extends Base {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
int derivedValue = 3;
|
int derivedValue = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Gson createGsonObjectWithFooTypeAdapter() {
|
private Gson createGsonObjectWithFooTypeAdapter() {
|
||||||
return new GsonBuilder().registerTypeAdapter(Foo.class, new FooTypeAdapter()).create();
|
return new GsonBuilder().registerTypeAdapter(Foo.class, new FooTypeAdapter()).create();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Foo {
|
public static class Foo {
|
||||||
private final int key;
|
private final int key;
|
||||||
private final long value;
|
private final long value;
|
||||||
|
|
||||||
public Foo() {
|
public Foo() {
|
||||||
this(0, 0L);
|
this(0, 0L);
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FooTypeAdapter implements JsonSerializer<Foo>, JsonDeserializer<Foo> {
|
public static class FooTypeAdapter implements JsonSerializer<Foo>, JsonDeserializer<Foo> {
|
||||||
public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
throws JsonParseException {
|
throws JsonParseException {
|
||||||
|
@ -202,62 +202,31 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
return context.serialize(src, typeOfSrc);
|
return context.serialize(src, typeOfSrc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCustomSerializerForLong() {
|
public void testCustomSerializerForbiddenForPrimitives() {
|
||||||
final ClassWithBooleanField customSerializerInvoked = new ClassWithBooleanField();
|
try {
|
||||||
customSerializerInvoked.value = false;
|
new GsonBuilder().registerTypeAdapter(long.class, new JsonSerializer<Long>() {
|
||||||
Gson gson = new GsonBuilder().registerTypeAdapter(Long.class, new JsonSerializer<Long>() {
|
public JsonElement serialize(Long s, Type t, JsonSerializationContext c) {
|
||||||
public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
|
throw new AssertionError();
|
||||||
customSerializerInvoked.value = true;
|
|
||||||
return new JsonPrimitive(src);
|
|
||||||
}
|
|
||||||
}).serializeNulls().create();
|
|
||||||
ClassWithWrapperLongField src = new ClassWithWrapperLongField();
|
|
||||||
String json = gson.toJson(src);
|
|
||||||
assertTrue(json.contains("\"value\":null"));
|
|
||||||
assertFalse(customSerializerInvoked.value);
|
|
||||||
|
|
||||||
customSerializerInvoked.value = false;
|
|
||||||
src.value = 10L;
|
|
||||||
json = gson.toJson(src);
|
|
||||||
assertTrue(json.contains("\"value\":10"));
|
|
||||||
assertTrue(customSerializerInvoked.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCustomDeserializerForLong() {
|
|
||||||
final ClassWithBooleanField customDeserializerInvoked = new ClassWithBooleanField();
|
|
||||||
customDeserializerInvoked.value = false;
|
|
||||||
Gson gson = new GsonBuilder().registerTypeAdapter(Long.class, new JsonDeserializer<Long>() {
|
|
||||||
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
|
||||||
throws JsonParseException {
|
|
||||||
customDeserializerInvoked.value = true;
|
|
||||||
if (json == null || json.isJsonNull()) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
Number number = json.getAsJsonPrimitive().getAsNumber();
|
});
|
||||||
return number == null ? null : number.longValue();
|
fail();
|
||||||
}
|
} catch (IllegalArgumentException expected) {
|
||||||
}).create();
|
}
|
||||||
String json = "{'value':null}";
|
|
||||||
ClassWithWrapperLongField target = gson.fromJson(json, ClassWithWrapperLongField.class);
|
|
||||||
assertNull(target.value);
|
|
||||||
assertFalse(customDeserializerInvoked.value);
|
|
||||||
|
|
||||||
customDeserializerInvoked.value = false;
|
|
||||||
json = "{'value':10}";
|
|
||||||
target = gson.fromJson(json, ClassWithWrapperLongField.class);
|
|
||||||
assertEquals(10L, target.value.longValue());
|
|
||||||
assertTrue(customDeserializerInvoked.value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ClassWithWrapperLongField {
|
public void testCustomDeserializerForbiddenForPrimitives() {
|
||||||
Long value;
|
try {
|
||||||
|
new GsonBuilder().registerTypeAdapter(long.class, new JsonDeserializer<Long>() {
|
||||||
|
public Long deserialize(JsonElement json, Type t, JsonDeserializationContext c) {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fail();
|
||||||
|
} catch (Exception expected) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ClassWithBooleanField {
|
|
||||||
Boolean value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCustomByteArraySerializer() {
|
public void testCustomByteArraySerializer() {
|
||||||
Gson gson = new GsonBuilder().registerTypeAdapter(byte[].class, new JsonSerializer<byte[]>() {
|
Gson gson = new GsonBuilder().registerTypeAdapter(byte[].class, new JsonSerializer<byte[]>() {
|
||||||
public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
|
public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
@ -266,15 +235,15 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
sb.append(b);
|
sb.append(b);
|
||||||
}
|
}
|
||||||
return new JsonPrimitive(sb.toString());
|
return new JsonPrimitive(sb.toString());
|
||||||
}
|
}
|
||||||
}).create();
|
}).create();
|
||||||
byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
String json = gson.toJson(data);
|
String json = gson.toJson(data);
|
||||||
assertEquals("\"0123456789\"", json);
|
assertEquals("\"0123456789\"", json);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCustomByteArrayDeserializerAndInstanceCreator() {
|
public void testCustomByteArrayDeserializerAndInstanceCreator() {
|
||||||
GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapter(byte[].class,
|
GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapter(byte[].class,
|
||||||
new JsonDeserializer<byte[]>() {
|
new JsonDeserializer<byte[]>() {
|
||||||
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
throws JsonParseException {
|
throws JsonParseException {
|
||||||
|
@ -284,7 +253,7 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
data[i] = Byte.parseByte(""+str.charAt(i));
|
data[i] = Byte.parseByte(""+str.charAt(i));
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Gson gson = gsonBuilder.create();
|
Gson gson = gsonBuilder.create();
|
||||||
String json = "'0123456789'";
|
String json = "'0123456789'";
|
||||||
|
@ -294,7 +263,7 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
assertEquals(expected[i], actual[i]);
|
assertEquals(expected[i], actual[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class StringHolder {
|
private static class StringHolder {
|
||||||
String part1;
|
String part1;
|
||||||
String part2;
|
String part2;
|
||||||
|
@ -309,8 +278,8 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
this.part2 = part2;
|
this.part2 = part2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class StringHolderTypeAdapter implements JsonSerializer<StringHolder>,
|
private static class StringHolderTypeAdapter implements JsonSerializer<StringHolder>,
|
||||||
JsonDeserializer<StringHolder>, InstanceCreator<StringHolder> {
|
JsonDeserializer<StringHolder>, InstanceCreator<StringHolder> {
|
||||||
|
|
||||||
public StringHolder createInstance(Type type) {
|
public StringHolder createInstance(Type type) {
|
||||||
|
@ -318,18 +287,18 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
return new StringHolder("unknown:thing");
|
return new StringHolder("unknown:thing");
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringHolder deserialize(JsonElement src, Type type,
|
public StringHolder deserialize(JsonElement src, Type type,
|
||||||
JsonDeserializationContext context) {
|
JsonDeserializationContext context) {
|
||||||
return new StringHolder(src.getAsString());
|
return new StringHolder(src.getAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonElement serialize(StringHolder src, Type typeOfSrc,
|
public JsonElement serialize(StringHolder src, Type typeOfSrc,
|
||||||
JsonSerializationContext context) {
|
JsonSerializationContext context) {
|
||||||
String contents = src.part1 + ':' + src.part2;
|
String contents = src.part1 + ':' + src.part2;
|
||||||
return new JsonPrimitive(contents);
|
return new JsonPrimitive(contents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test created from Issue 70
|
// Test created from Issue 70
|
||||||
public void testCustomAdapterInvokedForCollectionElementSerializationWithType() {
|
public void testCustomAdapterInvokedForCollectionElementSerializationWithType() {
|
||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
|
@ -367,7 +336,7 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
assertEquals("Jacob", foo.part1);
|
assertEquals("Jacob", foo.part1);
|
||||||
assertEquals("Tomaw", foo.part2);
|
assertEquals("Tomaw", foo.part2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test created from Issue 70
|
// Test created from Issue 70
|
||||||
public void testCustomAdapterInvokedForMapElementSerializationWithType() {
|
public void testCustomAdapterInvokedForMapElementSerializationWithType() {
|
||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
|
@ -380,7 +349,7 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
String json = gson.toJson(mapOfHolders, mapType);
|
String json = gson.toJson(mapOfHolders, mapType);
|
||||||
assertTrue(json.contains("\"foo\":\"Jacob:Tomaw\""));
|
assertTrue(json.contains("\"foo\":\"Jacob:Tomaw\""));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test created from Issue 70
|
// Test created from Issue 70
|
||||||
public void testCustomAdapterInvokedForMapElementSerialization() {
|
public void testCustomAdapterInvokedForMapElementSerialization() {
|
||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
|
@ -431,15 +400,15 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DataHolderWrapper {
|
private static class DataHolderWrapper {
|
||||||
final DataHolder wrappedData;
|
final DataHolder wrappedData;
|
||||||
|
|
||||||
public DataHolderWrapper(DataHolder data) {
|
public DataHolderWrapper(DataHolder data) {
|
||||||
this.wrappedData = data;
|
this.wrappedData = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DataHolderSerializer implements JsonSerializer<DataHolder> {
|
private static class DataHolderSerializer implements JsonSerializer<DataHolder> {
|
||||||
public JsonElement serialize(DataHolder src, Type typeOfSrc, JsonSerializationContext context) {
|
public JsonElement serialize(DataHolder src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
JsonObject obj = new JsonObject();
|
JsonObject obj = new JsonObject();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user