Major restructuring of Primitve type serialization and deserializtion. From the end-user's point of view there should be no difference other than the user can now override the default serialization/deserialization their own custom type adapter (not sure if there is a real use-case out there for this).
This restructuring greatly cleans up the code and reduces some complexity; however, there is more that can be done to clean this up (i.e. get rid of "InstanceCreators" for primitive Type Adapters).
This commit is contained in:
parent
7e360b95e7
commit
0d8150fe52
@ -64,14 +64,16 @@ final class DefaultTypeAdapters {
|
||||
private static final BigDecimalTypeAdapter BIG_DECIMAL_TYPE_ADAPTER = new BigDecimalTypeAdapter();
|
||||
private static final BigIntegerTypeAdapter BIG_INTEGER_TYPE_ADAPTER = new BigIntegerTypeAdapter();
|
||||
|
||||
private static final BooleanCreator BOOLEAN_CREATOR = new BooleanCreator();
|
||||
private static final ByteCreator BYTE_CREATOR = new ByteCreator();
|
||||
private static final CharacterCreator CHARACTER_CREATOR = new CharacterCreator();
|
||||
private static final DoubleCreator DOUBLE_CREATOR = new DoubleCreator();
|
||||
private static final FloatCreator FLOAT_CREATOR = new FloatCreator();
|
||||
private static final IntegerCreator INTEGER_CREATOR = new IntegerCreator();
|
||||
private static final LongCreator LONG_CREATOR = new LongCreator();
|
||||
private static final ShortCreator SHORT_CREATOR = new ShortCreator();
|
||||
private static final BooleanTypeAdapter BOOLEAN_TYPE_ADAPTER = new BooleanTypeAdapter();
|
||||
private static final ByteTypeAdapter BYTE_TYPE_ADAPTER = new ByteTypeAdapter();
|
||||
private static final CharacterTypeAdapter CHARACTER_TYPE_ADAPTER = new CharacterTypeAdapter();
|
||||
private static final DoubleTypeAdapter DOUBLE_TYPE_ADAPTER = new DoubleTypeAdapter();
|
||||
private static final FloatTypeAdapter FLOAT_TYPE_ADAPTER = new FloatTypeAdapter();
|
||||
private static final IntegerTypeAdapter INTEGER_TYPE_ADAPTER = new IntegerTypeAdapter();
|
||||
private static final LongTypeAdapter LONG_TYPE_ADAPTER = new LongTypeAdapter();
|
||||
private static final ShortTypeAdapter SHORT_TYPE_ADAPTER = new ShortTypeAdapter();
|
||||
private static final StringTypeAdapter STRING_TYPE_ADAPTER = new StringTypeAdapter();
|
||||
|
||||
private static final LinkedListCreator LINKED_LIST_CREATOR = new LinkedListCreator();
|
||||
private static final TreeSetCreator TREE_SET_CREATOR = new TreeSetCreator();
|
||||
|
||||
@ -98,6 +100,26 @@ final class DefaultTypeAdapters {
|
||||
map.register(Date.class, DATE_TYPE_ADAPTER);
|
||||
map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER);
|
||||
map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER);
|
||||
|
||||
// Add primitive serializers
|
||||
map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER);
|
||||
map.register(boolean.class, BOOLEAN_TYPE_ADAPTER);
|
||||
map.register(Byte.class, BYTE_TYPE_ADAPTER);
|
||||
map.register(byte.class, BYTE_TYPE_ADAPTER);
|
||||
map.register(Character.class, CHARACTER_TYPE_ADAPTER);
|
||||
map.register(char.class, CHARACTER_TYPE_ADAPTER);
|
||||
map.register(Double.class, DOUBLE_TYPE_ADAPTER);
|
||||
map.register(double.class, DOUBLE_TYPE_ADAPTER);
|
||||
map.register(Float.class, FLOAT_TYPE_ADAPTER);
|
||||
map.register(float.class, FLOAT_TYPE_ADAPTER);
|
||||
map.register(Integer.class, INTEGER_TYPE_ADAPTER);
|
||||
map.register(int.class, INTEGER_TYPE_ADAPTER);
|
||||
map.register(Long.class, LONG_TYPE_ADAPTER);
|
||||
map.register(long.class, LONG_TYPE_ADAPTER);
|
||||
map.register(Short.class, SHORT_TYPE_ADAPTER);
|
||||
map.register(short.class, SHORT_TYPE_ADAPTER);
|
||||
map.register(String.class, STRING_TYPE_ADAPTER);
|
||||
|
||||
map.makeUnmodifiable();
|
||||
return map;
|
||||
}
|
||||
@ -114,6 +136,26 @@ final class DefaultTypeAdapters {
|
||||
map.register(Date.class, wrapDeserializer(DATE_TYPE_ADAPTER));
|
||||
map.register(BigDecimal.class, wrapDeserializer(BIG_DECIMAL_TYPE_ADAPTER));
|
||||
map.register(BigInteger.class, wrapDeserializer(BIG_INTEGER_TYPE_ADAPTER));
|
||||
|
||||
// Add primitive deserializers
|
||||
map.register(Boolean.class, wrapDeserializer(BOOLEAN_TYPE_ADAPTER));
|
||||
map.register(boolean.class, wrapDeserializer(BOOLEAN_TYPE_ADAPTER));
|
||||
map.register(Byte.class, wrapDeserializer(BYTE_TYPE_ADAPTER));
|
||||
map.register(byte.class, wrapDeserializer(BYTE_TYPE_ADAPTER));
|
||||
map.register(Character.class, wrapDeserializer(CHARACTER_TYPE_ADAPTER));
|
||||
map.register(char.class, wrapDeserializer(CHARACTER_TYPE_ADAPTER));
|
||||
map.register(Double.class, wrapDeserializer(DOUBLE_TYPE_ADAPTER));
|
||||
map.register(double.class, wrapDeserializer(DOUBLE_TYPE_ADAPTER));
|
||||
map.register(Float.class, wrapDeserializer(FLOAT_TYPE_ADAPTER));
|
||||
map.register(float.class, wrapDeserializer(FLOAT_TYPE_ADAPTER));
|
||||
map.register(Integer.class, wrapDeserializer(INTEGER_TYPE_ADAPTER));
|
||||
map.register(int.class, wrapDeserializer(INTEGER_TYPE_ADAPTER));
|
||||
map.register(Long.class, wrapDeserializer(LONG_TYPE_ADAPTER));
|
||||
map.register(long.class, wrapDeserializer(LONG_TYPE_ADAPTER));
|
||||
map.register(Short.class, wrapDeserializer(SHORT_TYPE_ADAPTER));
|
||||
map.register(short.class, wrapDeserializer(SHORT_TYPE_ADAPTER));
|
||||
map.register(String.class, wrapDeserializer(STRING_TYPE_ADAPTER));
|
||||
|
||||
map.makeUnmodifiable();
|
||||
return map;
|
||||
}
|
||||
@ -124,30 +166,31 @@ final class DefaultTypeAdapters {
|
||||
map.register(Enum.class, ENUM_TYPE_ADAPTER);
|
||||
map.register(URL.class, URL_TYPE_ADAPTER);
|
||||
map.register(Locale.class, LOCALE_TYPE_ADAPTER);
|
||||
map.register(Collection.class, COLLECTION_TYPE_ADAPTER);
|
||||
map.register(Map.class, MAP_TYPE_ADAPTER);
|
||||
map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER);
|
||||
map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER);
|
||||
|
||||
// Add primitive instance creators
|
||||
map.register(Boolean.class, BOOLEAN_CREATOR);
|
||||
map.register(boolean.class, BOOLEAN_CREATOR);
|
||||
map.register(Byte.class, BYTE_CREATOR);
|
||||
map.register(byte.class, BYTE_CREATOR);
|
||||
map.register(Character.class, CHARACTER_CREATOR);
|
||||
map.register(char.class, CHARACTER_CREATOR);
|
||||
map.register(Double.class, DOUBLE_CREATOR);
|
||||
map.register(double.class, DOUBLE_CREATOR);
|
||||
map.register(Float.class, FLOAT_CREATOR);
|
||||
map.register(float.class, FLOAT_CREATOR);
|
||||
map.register(Integer.class, INTEGER_CREATOR);
|
||||
map.register(int.class, INTEGER_CREATOR);
|
||||
map.register(Long.class, LONG_CREATOR);
|
||||
map.register(long.class, LONG_CREATOR);
|
||||
map.register(Short.class, SHORT_CREATOR);
|
||||
map.register(short.class, SHORT_CREATOR);
|
||||
|
||||
map.register(Collection.class, LINKED_LIST_CREATOR);
|
||||
map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER);
|
||||
map.register(boolean.class, BOOLEAN_TYPE_ADAPTER);
|
||||
map.register(Byte.class, BYTE_TYPE_ADAPTER);
|
||||
map.register(byte.class, BYTE_TYPE_ADAPTER);
|
||||
map.register(Character.class, CHARACTER_TYPE_ADAPTER);
|
||||
map.register(char.class, CHARACTER_TYPE_ADAPTER);
|
||||
map.register(Double.class, DOUBLE_TYPE_ADAPTER);
|
||||
map.register(double.class, DOUBLE_TYPE_ADAPTER);
|
||||
map.register(Float.class, FLOAT_TYPE_ADAPTER);
|
||||
map.register(float.class, FLOAT_TYPE_ADAPTER);
|
||||
map.register(Integer.class, INTEGER_TYPE_ADAPTER);
|
||||
map.register(int.class, INTEGER_TYPE_ADAPTER);
|
||||
map.register(Long.class, LONG_TYPE_ADAPTER);
|
||||
map.register(long.class, LONG_TYPE_ADAPTER);
|
||||
map.register(Short.class, SHORT_TYPE_ADAPTER);
|
||||
map.register(short.class, SHORT_TYPE_ADAPTER);
|
||||
map.register(String.class, STRING_TYPE_ADAPTER);
|
||||
|
||||
// Add Collection type instance creators
|
||||
map.register(Collection.class, COLLECTION_TYPE_ADAPTER);
|
||||
map.register(List.class, LINKED_LIST_CREATOR);
|
||||
map.register(Queue.class, LINKED_LIST_CREATOR);
|
||||
|
||||
@ -468,83 +511,192 @@ final class DefaultTypeAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
private static class LongCreator implements InstanceCreator<Long> {
|
||||
private static class LongTypeAdapter
|
||||
implements InstanceCreator<Long>, JsonSerializer<Long>, JsonDeserializer<Long> {
|
||||
public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src);
|
||||
}
|
||||
|
||||
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
return json.getAsLong();
|
||||
}
|
||||
|
||||
public Long createInstance(Type type) {
|
||||
return new Long(0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return LongCreator.class.getSimpleName();
|
||||
return LongTypeAdapter.class.getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
private static class IntegerCreator implements InstanceCreator<Integer> {
|
||||
private static class IntegerTypeAdapter
|
||||
implements InstanceCreator<Integer>, JsonSerializer<Integer>, JsonDeserializer<Integer> {
|
||||
public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src);
|
||||
}
|
||||
|
||||
public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
return json.getAsInt();
|
||||
}
|
||||
|
||||
public Integer createInstance(Type type) {
|
||||
return new Integer(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return IntegerCreator.class.getSimpleName();
|
||||
return IntegerTypeAdapter.class.getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ShortCreator implements InstanceCreator<Short> {
|
||||
private static class ShortTypeAdapter
|
||||
implements InstanceCreator<Short>, JsonSerializer<Short>, JsonDeserializer<Short> {
|
||||
public JsonElement serialize(Short src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src);
|
||||
}
|
||||
|
||||
public Short deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
return json.getAsShort();
|
||||
}
|
||||
|
||||
public Short createInstance(Type type) {
|
||||
return new Short((short) 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ShortCreator.class.getSimpleName();
|
||||
return ShortTypeAdapter.class.getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ByteCreator implements InstanceCreator<Byte> {
|
||||
private static class ByteTypeAdapter
|
||||
implements InstanceCreator<Byte>, JsonSerializer<Byte>, JsonDeserializer<Byte> {
|
||||
public JsonElement serialize(Byte src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src);
|
||||
}
|
||||
|
||||
public Byte deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
return json.getAsByte();
|
||||
}
|
||||
|
||||
public Byte createInstance(Type type) {
|
||||
return new Byte((byte) 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ByteCreator.class.getSimpleName();
|
||||
return ByteTypeAdapter.class.getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
private static class FloatCreator implements InstanceCreator<Float> {
|
||||
private static class FloatTypeAdapter
|
||||
implements InstanceCreator<Float>, JsonSerializer<Float>, JsonDeserializer<Float> {
|
||||
public JsonElement serialize(Float src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src);
|
||||
}
|
||||
|
||||
public Float deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
return json.getAsFloat();
|
||||
}
|
||||
|
||||
public Float createInstance(Type type) {
|
||||
return new Float(0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return FloatCreator.class.getSimpleName();
|
||||
return FloatTypeAdapter.class.getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
private static class DoubleCreator implements InstanceCreator<Double> {
|
||||
private static class DoubleTypeAdapter
|
||||
implements InstanceCreator<Double>, JsonSerializer<Double>, JsonDeserializer<Double> {
|
||||
public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src);
|
||||
}
|
||||
|
||||
public Double deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
return json.getAsDouble();
|
||||
}
|
||||
|
||||
public Double createInstance(Type type) {
|
||||
return new Double(0D);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return DoubleCreator.class.getSimpleName();
|
||||
return DoubleTypeAdapter.class.getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
private static class CharacterCreator implements InstanceCreator<Character> {
|
||||
private static class CharacterTypeAdapter implements InstanceCreator<Character>,
|
||||
JsonSerializer<Character>, JsonDeserializer<Character> {
|
||||
public JsonElement serialize(Character src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src);
|
||||
}
|
||||
|
||||
public Character deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
return json.getAsCharacter();
|
||||
}
|
||||
|
||||
public Character createInstance(Type type) {
|
||||
return new Character((char) 0);
|
||||
return new Character('0');
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return CharacterCreator.class.getSimpleName();
|
||||
return CharacterTypeAdapter.class.getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
private static class StringTypeAdapter
|
||||
implements InstanceCreator<String>, JsonSerializer<String>, JsonDeserializer<String> {
|
||||
public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src);
|
||||
}
|
||||
|
||||
public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
return json.getAsString();
|
||||
}
|
||||
|
||||
public String createInstance(Type type) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringTypeAdapter.class.getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
private static class BooleanCreator implements InstanceCreator<Boolean> {
|
||||
private static class BooleanTypeAdapter
|
||||
implements InstanceCreator<Boolean>, JsonSerializer<Boolean>, JsonDeserializer<Boolean> {
|
||||
public JsonElement serialize(Boolean src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src);
|
||||
}
|
||||
|
||||
public Boolean deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
return json.getAsBoolean();
|
||||
}
|
||||
|
||||
public Boolean createInstance(Type type) {
|
||||
return new Boolean(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return BooleanCreator.class.getSimpleName();
|
||||
return BooleanTypeAdapter.class.getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,6 +225,22 @@ public final class JsonArray extends JsonElement implements Iterable<JsonElement
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getAsByte() {
|
||||
if (elements.size() == 1) {
|
||||
return elements.get(0).getAsByte();
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char getAsCharacter() {
|
||||
if (elements.size() == 1) {
|
||||
return elements.get(0).getAsCharacter();
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
/**
|
||||
* convenience method to get this array as a primitive short if it contains a single element.
|
||||
|
@ -28,14 +28,12 @@ import java.lang.reflect.Type;
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class JsonArrayDeserializationVisitor<T> extends JsonDeserializationVisitor<T> {
|
||||
private final Class<?> componentType;
|
||||
|
||||
JsonArrayDeserializationVisitor(JsonArray jsonArray, Type arrayType,
|
||||
ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
|
||||
TypeAdapter typeAdapter, ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
|
||||
JsonDeserializationContext context) {
|
||||
super(jsonArray, arrayType, factory, objectConstructor, typeAdapter, deserializers, context);
|
||||
this.componentType = TypeUtils.toRawClass(arrayType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -45,13 +43,7 @@ final class JsonArrayDeserializationVisitor<T> extends JsonDeserializationVisito
|
||||
TypeInfo typeInfo = new TypeInfo(targetType);
|
||||
|
||||
JsonArray jsonArray = json.getAsJsonArray();
|
||||
if (typeInfo.isPrimitiveOrStringAndNotAnArray()) {
|
||||
if (jsonArray.size() != 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"Primitives should be an array of length 1, but was: " + jsonArray);
|
||||
}
|
||||
return (T) objectConstructor.construct(typeInfo.getWrappedClass());
|
||||
} else if (typeInfo.isArray()) {
|
||||
if (typeInfo.isArray()) {
|
||||
TypeInfoArray arrayTypeInfo = TypeInfoFactory.getTypeInfoForArray(targetType);
|
||||
// We know that we are getting back an array of the required type, so
|
||||
// this typecasting is safe.
|
||||
@ -76,7 +68,7 @@ final class JsonArrayDeserializationVisitor<T> extends JsonDeserializationVisito
|
||||
} else if (jsonChild instanceof JsonArray) {
|
||||
child = visitChildAsArray(arrayTypeInfo.getSecondLevelType(), jsonChild.getAsJsonArray());
|
||||
} else if (jsonChild instanceof JsonPrimitive) {
|
||||
child = visitChildAsPrimitive(arrayTypeInfo.getComponentRawType(),
|
||||
child = visitChildAsObject(arrayTypeInfo.getComponentRawType(),
|
||||
jsonChild.getAsJsonPrimitive());
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
@ -85,11 +77,6 @@ final class JsonArrayDeserializationVisitor<T> extends JsonDeserializationVisito
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void visitPrimitiveValue(Object obj) {
|
||||
target = (T) typeAdapter.adaptType(json.getAsJsonArray().get(0).getAsObject(), componentType);
|
||||
}
|
||||
|
||||
// We should not implement any other method from Visitor interface since
|
||||
// all other methods should be invoked on JsonObjectDeserializationVisitor
|
||||
// instead.
|
||||
@ -106,10 +93,6 @@ final class JsonArrayDeserializationVisitor<T> extends JsonDeserializationVisito
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void visitPrimitiveField(Field f, Type typeOfF, Object obj) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean visitFieldUsingCustomHandler(Field f, Type actualTypeOfField, Object parent) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
@ -83,12 +83,11 @@ final class JsonDeserializationContextDefault implements JsonDeserializationCont
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T fromJsonPrimitive(Type typeOfT, JsonPrimitive json,
|
||||
JsonDeserializationContext context) throws JsonParseException {
|
||||
JsonPrimitiveDeserializationVisitor<T> visitor = new JsonPrimitiveDeserializationVisitor<T>(
|
||||
JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
|
||||
json, typeOfT, navigatorFactory, objectConstructor, typeAdapter, deserializers, context);
|
||||
Object target = visitor.getTarget();
|
||||
ObjectNavigator on = navigatorFactory.create(target, typeOfT);
|
||||
ObjectNavigator on = navigatorFactory.create(json.getAsObject(), typeOfT);
|
||||
on.accept(visitor);
|
||||
target = visitor.getTarget();
|
||||
Object target = visitor.getTarget();
|
||||
if (typeOfT instanceof Class) {
|
||||
target = typeAdapter.adaptType(target, (Class) typeOfT);
|
||||
}
|
||||
|
@ -87,31 +87,6 @@ abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor
|
||||
return visitChild(childType, childVisitor);
|
||||
}
|
||||
|
||||
final Object visitChildAsPrimitive(Type childType, JsonPrimitive jsonChild) {
|
||||
Preconditions.checkNotNull(jsonChild);
|
||||
Class<?> childClass;
|
||||
if (childType instanceof Class) {
|
||||
childClass = (Class<?>) childType;
|
||||
} else {
|
||||
childClass = TypeUtils.toRawClass(childType);
|
||||
}
|
||||
return typeAdapter.adaptType(jsonChild.getAsObject(), childClass);
|
||||
}
|
||||
|
||||
final Object visitChild(Type childType, JsonElement jsonChild) {
|
||||
if (jsonChild == null) {
|
||||
return null;
|
||||
} else if (jsonChild instanceof JsonArray) {
|
||||
return visitChildAsArray(childType, jsonChild.getAsJsonArray());
|
||||
} else if (jsonChild instanceof JsonObject) {
|
||||
return visitChildAsObject(childType, jsonChild);
|
||||
} else if (jsonChild instanceof JsonPrimitive) {
|
||||
return visitChildAsPrimitive(childType, jsonChild.getAsJsonPrimitive());
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
private Object visitChild(Type type, JsonDeserializationVisitor<?> childVisitor) {
|
||||
Object child = childVisitor.getTarget();
|
||||
ObjectNavigator on = factory.create(child, type);
|
||||
|
@ -221,6 +221,32 @@ public abstract class JsonElement {
|
||||
public int getAsInt() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* convenience method to get this element as a primitive byte value.
|
||||
*
|
||||
* @return get this element as a primitive byte value.
|
||||
* @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
|
||||
* byte value.
|
||||
* @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
|
||||
* more than a single element.
|
||||
*/
|
||||
public byte getAsByte() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* convenience method to get this element as a primitive character value.
|
||||
*
|
||||
* @return get this element as a primitive char value.
|
||||
* @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
|
||||
* char value.
|
||||
* @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
|
||||
* more than a single element.
|
||||
*/
|
||||
public char getAsCharacter() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* convenience method to get this element as a {@link BigDecimal}.
|
||||
|
@ -50,11 +50,6 @@ final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisit
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void visitPrimitiveValue(Object obj) {
|
||||
// should not be called since this case should invoke JsonPrimitiveDeserializationVisitor
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void visitObjectField(Field f, Type typeOfF, Object obj) {
|
||||
try {
|
||||
JsonObject jsonObject = json.getAsJsonObject();
|
||||
@ -87,25 +82,6 @@ final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisit
|
||||
}
|
||||
}
|
||||
|
||||
public void visitPrimitiveField(Field f, Type typeOfF, Object obj) {
|
||||
try {
|
||||
JsonObject jsonObject = json.getAsJsonObject();
|
||||
String fName = getFieldName(f);
|
||||
JsonPrimitive value = jsonObject.getAsJsonPrimitive(fName);
|
||||
if (value != null) {
|
||||
f.set(obj, typeAdapter.adaptType(value.getAsObject(), TypeUtils.toRawClass(typeOfF)));
|
||||
} else {
|
||||
// For Strings, we need to set the field to null
|
||||
// For other primitive types, any value created during default construction is fine
|
||||
if (f.getType() == String.class) {
|
||||
f.set(obj, null);
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getFieldName(Field f) {
|
||||
FieldNamingStrategy namingPolicy = factory.getFieldNamingPolicy();
|
||||
return namingPolicy.translateName(f);
|
||||
|
@ -255,6 +255,16 @@ public final class JsonPrimitive extends JsonElement {
|
||||
public int getAsInt() {
|
||||
return ((Number) value).intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getAsByte() {
|
||||
return ((Number) value).byteValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char getAsCharacter() {
|
||||
return getAsString().charAt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* convenience method to get this element as an Object.
|
||||
|
@ -1,84 +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.Field;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* A visitor that populates a primitive value from its JSON representation
|
||||
*
|
||||
* @author Inderjeet Singh
|
||||
*/
|
||||
final class JsonPrimitiveDeserializationVisitor<T> extends JsonDeserializationVisitor<T> {
|
||||
|
||||
JsonPrimitiveDeserializationVisitor(JsonPrimitive json, Type type,
|
||||
ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
|
||||
TypeAdapter typeAdapter, ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
|
||||
JsonDeserializationContext context) {
|
||||
super(json, type, factory, objectConstructor, typeAdapter, deserializers, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T constructTarget() {
|
||||
return (T) objectConstructor.construct(targetType);
|
||||
}
|
||||
|
||||
public void startVisitingObject(Object node) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void visitArray(Object array, Type componentType) {
|
||||
// should not be called since this case should invoke JsonArrayDeserializationVisitor
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void visitPrimitiveValue(Object obj) {
|
||||
JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive();
|
||||
if (jsonPrimitive.isBoolean()) {
|
||||
target = (T) jsonPrimitive.getAsBooleanWrapper();
|
||||
} else if (jsonPrimitive.isNumber()) {
|
||||
target = (T) jsonPrimitive.getAsNumber();
|
||||
} else if (jsonPrimitive.isString()) {
|
||||
target = (T) jsonPrimitive.getAsString();
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
public void visitObjectField(Field f, Type typeOfF, Object obj) {
|
||||
// should not be called since this case should invoke JsonArrayDeserializationVisitor
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void visitArrayField(Field f, Type typeOfF, Object obj) {
|
||||
// should not be called since this case should invoke JsonArrayDeserializationVisitor
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public void visitPrimitiveField(Field f, Type fType, Object obj) {
|
||||
// should not be called since this case should invoke JsonArrayDeserializationVisitor
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public boolean visitFieldUsingCustomHandler(Field f, Type actualTypeOfField, Object parent) {
|
||||
// should not be called since this case should invoke JsonObjectDeserializationVisitor
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
@ -118,26 +118,6 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
return childVisitor.getJsonElement();
|
||||
}
|
||||
|
||||
public void visitPrimitiveField(Field f, Type typeOfF, Object obj) {
|
||||
if (isFieldNull(f, obj)) {
|
||||
if (serializeNulls) {
|
||||
addChildAsElement(f, JsonNull.INSTANCE);
|
||||
}
|
||||
} else {
|
||||
TypeInfo typeInfo = new TypeInfo(typeOfF);
|
||||
if (typeInfo.isPrimitiveOrStringAndNotAnArray()) {
|
||||
Object fieldValue = getFieldValue(f, obj);
|
||||
addAsChildOfObject(f, typeOfF, fieldValue);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Not a primitive type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void visitPrimitiveValue(Object obj) {
|
||||
assignToRoot(new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean visitUsingCustomHandler(Object obj, Type objType) {
|
||||
JsonSerializer serializer = serializers.getHandlerFor(objType);
|
||||
|
@ -39,11 +39,6 @@ final class ObjectNavigator {
|
||||
*/
|
||||
void visitArray(Object array, Type componentType);
|
||||
|
||||
/**
|
||||
* This is called to visit the current object if it is a primitive
|
||||
*/
|
||||
void visitPrimitiveValue(Object obj);
|
||||
|
||||
/**
|
||||
* This is called to visit an object field of the current object
|
||||
*/
|
||||
@ -54,11 +49,6 @@ final class ObjectNavigator {
|
||||
*/
|
||||
void visitArrayField(Field f, Type typeOfF, Object obj);
|
||||
|
||||
/**
|
||||
* This is called to visit a primitive field of the current object
|
||||
*/
|
||||
void visitPrimitiveField(Field f, Type typeOfF, Object obj);
|
||||
|
||||
/**
|
||||
* This is called to visit an object using a custom handler
|
||||
* @return true if a custom handler exists, false otherwise
|
||||
@ -116,8 +106,6 @@ final class ObjectNavigator {
|
||||
if (!visitedWithCustomHandler) {
|
||||
if (objTypeInfo.isArray()) {
|
||||
visitor.visitArray(obj, objType);
|
||||
} else if (objTypeInfo.isPrimitiveOrStringAndNotAnArray()) {
|
||||
visitor.visitPrimitiveValue(obj);
|
||||
} else {
|
||||
visitor.startVisitingObject(obj);
|
||||
// For all classes in the inheritance hierarchy (including the current class),
|
||||
@ -149,8 +137,6 @@ final class ObjectNavigator {
|
||||
if (!visitedWithCustomHandler) {
|
||||
if (fieldTypeInfo.isArray()) {
|
||||
visitor.visitArrayField(f, actualTypeOfField, obj);
|
||||
} else if (fieldTypeInfo.isPrimitiveOrStringAndNotAnArray()) {
|
||||
visitor.visitPrimitiveField(f, actualTypeOfField, obj);
|
||||
} else {
|
||||
visitor.visitObjectField(f, actualTypeOfField, obj);
|
||||
}
|
||||
|
@ -73,12 +73,4 @@ class TypeInfo {
|
||||
public final boolean isPrimitive() {
|
||||
return Primitives.isWrapperType(Primitives.wrap(rawClass));
|
||||
}
|
||||
|
||||
public final boolean isString() {
|
||||
return rawClass == String.class;
|
||||
}
|
||||
|
||||
public final boolean isPrimitiveOrStringAndNotAnArray() {
|
||||
return (isPrimitive() || isString()) && !isArray();
|
||||
}
|
||||
}
|
@ -80,8 +80,8 @@ public class TypeInfoArrayTest extends TestCase {
|
||||
TypeInfoArray arrayTypeInfo = new TypeInfoArray(int[].class);
|
||||
|
||||
assertTrue(arrayTypeInfo.isArray());
|
||||
assertFalse(arrayTypeInfo.isPrimitive());
|
||||
assertEquals(int.class, arrayTypeInfo.getSecondLevelType());
|
||||
assertFalse(arrayTypeInfo.isPrimitiveOrStringAndNotAnArray());
|
||||
}
|
||||
|
||||
public void testStringArray() throws Exception {
|
||||
|
@ -35,7 +35,6 @@ public class TypeInfoTest extends TestCase {
|
||||
TypeInfo typeInfo = new TypeInfo(boolean.class);
|
||||
|
||||
assertFalse(typeInfo.isArray());
|
||||
assertFalse(typeInfo.isString());
|
||||
assertTrue(typeInfo.isPrimitive());
|
||||
assertEquals(boolean.class, typeInfo.getRawClass());
|
||||
assertEquals(Boolean.class, typeInfo.getWrappedClass());
|
||||
@ -46,7 +45,7 @@ public class TypeInfoTest extends TestCase {
|
||||
|
||||
assertEquals(Integer.class, typeInfo.getRawClass());
|
||||
assertTrue(typeInfo.isPrimitive());
|
||||
assertTrue(typeInfo.isPrimitiveOrStringAndNotAnArray());
|
||||
assertFalse(typeInfo.isArray());
|
||||
}
|
||||
|
||||
public void testString() throws Exception {
|
||||
@ -55,7 +54,6 @@ public class TypeInfoTest extends TestCase {
|
||||
assertFalse(typeInfo.isArray());
|
||||
assertFalse(typeInfo.isPrimitive());
|
||||
assertEquals(String.class, typeInfo.getRawClass());
|
||||
assertTrue(typeInfo.isPrimitiveOrStringAndNotAnArray());
|
||||
}
|
||||
|
||||
public void testObject() throws Exception {
|
||||
@ -64,7 +62,6 @@ public class TypeInfoTest extends TestCase {
|
||||
assertFalse(typeInfo.isArray());
|
||||
assertFalse(typeInfo.isPrimitive());
|
||||
assertEquals(Object.class, typeInfo.getRawClass());
|
||||
assertFalse(typeInfo.isPrimitiveOrStringAndNotAnArray());
|
||||
}
|
||||
|
||||
public void testPrimitiveType() throws Exception {
|
||||
@ -76,7 +73,7 @@ public class TypeInfoTest extends TestCase {
|
||||
public void testObjectType() throws Exception {
|
||||
TypeInfo typeInfo = new TypeInfo(String.class);
|
||||
assertFalse(typeInfo.isArray());
|
||||
assertTrue(typeInfo.isString());
|
||||
assertFalse(typeInfo.isPrimitive());
|
||||
assertEquals(String.class, typeInfo.getRawClass());
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,15 @@
|
||||
|
||||
package com.google.gson.common;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
@ -349,4 +358,17 @@ public class TestTypes {
|
||||
return '{' + "\"fooBar\":" + f + '}';
|
||||
}
|
||||
}
|
||||
|
||||
public static class CrazyLongTypeAdapter
|
||||
implements JsonSerializer<Long>, JsonDeserializer<Long> {
|
||||
public static final long DIFFERENCE = 5L;
|
||||
public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src + DIFFERENCE);
|
||||
}
|
||||
|
||||
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
return json.getAsLong() - DIFFERENCE;
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,9 @@
|
||||
package com.google.gson.functional;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.common.MoreAsserts;
|
||||
import com.google.gson.common.TestTypes.CrazyLongTypeAdapter;
|
||||
import com.google.gson.common.TestTypes.MyEnum;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@ -133,4 +135,20 @@ public class ArrayTest extends TestCase {
|
||||
MoreAsserts.assertEquals(new Integer[] { 1, 2 }, target[0].toArray(new Integer[0]));
|
||||
MoreAsserts.assertEquals(new Integer[] { 3, 4 }, target[1].toArray(new Integer[0]));
|
||||
}
|
||||
|
||||
public void testArrayOfPrimitivesWithCustomTypeAdapter() throws Exception {
|
||||
CrazyLongTypeAdapter typeAdapter = new CrazyLongTypeAdapter();
|
||||
gson = new GsonBuilder()
|
||||
.registerTypeAdapter(long.class, typeAdapter)
|
||||
.registerTypeAdapter(Long.class, typeAdapter)
|
||||
.create();
|
||||
long[] value = { 1L };
|
||||
String serializedValue = gson.toJson(value);
|
||||
String expected = "[" + String.valueOf(value[0] + CrazyLongTypeAdapter.DIFFERENCE) + "]";
|
||||
assertEquals(expected, serializedValue);
|
||||
|
||||
long[] deserializedValue = gson.fromJson(serializedValue, long[].class);
|
||||
assertEquals(1, deserializedValue.length);
|
||||
assertEquals(value[0], deserializedValue[0]);
|
||||
}
|
||||
}
|
||||
|
@ -334,13 +334,25 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||
return new JsonPrimitive(contents);
|
||||
}
|
||||
}
|
||||
|
||||
// Test created from Issue 70
|
||||
public void testCustomAdapterInvokedForCollectionElementSerializationWithType() {
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(StringHolder.class, new StringHolderTypeAdapter())
|
||||
.create();
|
||||
Type setType = new TypeToken<Set<StringHolder>>() {}.getType();
|
||||
StringHolder holder = new StringHolder("Jacob", "Tomaw");
|
||||
Set<StringHolder> setOfHolders = new HashSet<StringHolder>();
|
||||
setOfHolders.add(holder);
|
||||
String json = gson.toJson(setOfHolders, setType);
|
||||
assertTrue(json.contains("Jacob:Tomaw"));
|
||||
}
|
||||
|
||||
// Test created from Issue 70
|
||||
public void testCustomAdapterInvokedForCollectionElementSerialization() {
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(StringHolder.class, new StringHolderTypeAdapter())
|
||||
.create();
|
||||
Type setType = new TypeToken<Set<StringHolder>>() {}.getType();
|
||||
StringHolder holder = new StringHolder("Jacob", "Tomaw");
|
||||
Set<StringHolder> setOfHolders = new HashSet<StringHolder>();
|
||||
setOfHolders.add(holder);
|
||||
@ -362,7 +374,7 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||
}
|
||||
|
||||
// Test created from Issue 70
|
||||
public void testCustomAdapterInvokedForMapElementSerialization() {
|
||||
public void testCustomAdapterInvokedForMapElementSerializationWithType() {
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(StringHolder.class, new StringHolderTypeAdapter())
|
||||
.create();
|
||||
@ -370,6 +382,18 @@ public class CustomTypeAdaptersTest extends TestCase {
|
||||
StringHolder holder = new StringHolder("Jacob", "Tomaw");
|
||||
Map<String, StringHolder> mapOfHolders = new HashMap<String, StringHolder>();
|
||||
mapOfHolders.put("foo", holder);
|
||||
String json = gson.toJson(mapOfHolders, mapType);
|
||||
assertTrue(json.contains("\"foo\":\"Jacob:Tomaw\""));
|
||||
}
|
||||
|
||||
// Test created from Issue 70
|
||||
public void testCustomAdapterInvokedForMapElementSerialization() {
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(StringHolder.class, new StringHolderTypeAdapter())
|
||||
.create();
|
||||
StringHolder holder = new StringHolder("Jacob", "Tomaw");
|
||||
Map<String, StringHolder> mapOfHolders = new HashMap<String, StringHolder>();
|
||||
mapOfHolders.put("foo", holder);
|
||||
String json = gson.toJson(mapOfHolders);
|
||||
assertTrue(json.contains("\"foo\":\"Jacob:Tomaw\""));
|
||||
}
|
||||
|
@ -271,7 +271,6 @@ public class ObjectTest extends TestCase {
|
||||
public void testSubInterfacesOfCollectionDeserialization() throws Exception {
|
||||
String json = "{\"list\":[0,1,2,3],\"queue\":[0,1,2,3],\"set\":[0.1,0.2,0.3,0.4],"
|
||||
+ "\"sortedSet\":[\"a\",\"b\",\"c\",\"d\"]"
|
||||
// + ",\"navigableSet\":[\"abc\",\"def\",\"ghi\",\"jkl\"]"
|
||||
+ "}";
|
||||
ClassWithSubInterfacesOfCollection target = gson.fromJson(
|
||||
json, ClassWithSubInterfacesOfCollection.class);
|
||||
|
@ -67,7 +67,7 @@ public class ParameterizedTypesTest extends TestCase {
|
||||
.create();
|
||||
|
||||
String json = expected.getExpectedJson();
|
||||
MyParameterizedType<Integer> actual = gson.fromJson(json, expectedType);
|
||||
MyParameterizedType<BagOfPrimitives> actual = gson.fromJson(json, expectedType);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
|
@ -16,13 +16,15 @@
|
||||
|
||||
package com.google.gson.functional;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.common.TestTypes.CrazyLongTypeAdapter;
|
||||
|
||||
/**
|
||||
* Functional tests for Json primitive values: integers, and floating point numbers.
|
||||
@ -257,6 +259,20 @@ public class PrimitiveTest extends TestCase {
|
||||
fail("BigInteger can not be decimal values.");
|
||||
} catch (JsonParseException expected) { }
|
||||
}
|
||||
|
||||
public void testOverridingDefaultPrimitiveSerialization() {
|
||||
CrazyLongTypeAdapter typeAdapter = new CrazyLongTypeAdapter();
|
||||
gson = new GsonBuilder()
|
||||
.registerTypeAdapter(long.class, typeAdapter)
|
||||
.registerTypeAdapter(Long.class, typeAdapter)
|
||||
.create();
|
||||
long value = 1L;
|
||||
String serializedValue = gson.toJson(value);
|
||||
assertEquals(String.valueOf(value + CrazyLongTypeAdapter.DIFFERENCE), serializedValue);
|
||||
|
||||
long deserializedValue = gson.fromJson(serializedValue, long.class);
|
||||
assertEquals(value, deserializedValue);
|
||||
}
|
||||
|
||||
private String extractElementFromArray(String json) {
|
||||
return json.substring(json.indexOf('[') + 1, json.indexOf(']'));
|
||||
|
Loading…
Reference in New Issue
Block a user