Revised ancestor stack to use both object and type
This commit is contained in:
parent
fbf834c3f6
commit
2716d96516
@ -60,7 +60,7 @@ final class JsonDeserializationContextDefault implements JsonDeserializationCont
|
||||
JsonDeserializationContext context) throws JsonParseException {
|
||||
JsonArrayDeserializationVisitor<T> visitor = new JsonArrayDeserializationVisitor<T>(
|
||||
jsonArray, arrayType, navigatorFactory, objectConstructor, deserializers, context);
|
||||
ObjectNavigator on = navigatorFactory.create(null, arrayType);
|
||||
ObjectNavigator on = navigatorFactory.create(new ObjectTypePair(null, arrayType));
|
||||
on.accept(visitor);
|
||||
return visitor.getTarget();
|
||||
}
|
||||
@ -69,7 +69,7 @@ final class JsonDeserializationContextDefault implements JsonDeserializationCont
|
||||
JsonDeserializationContext context) throws JsonParseException {
|
||||
JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
|
||||
jsonObject, typeOfT, navigatorFactory, objectConstructor, deserializers, context);
|
||||
ObjectNavigator on = navigatorFactory.create(null, typeOfT);
|
||||
ObjectNavigator on = navigatorFactory.create(new ObjectTypePair(null, typeOfT));
|
||||
on.accept(visitor);
|
||||
return visitor.getTarget();
|
||||
}
|
||||
@ -79,7 +79,7 @@ final class JsonDeserializationContextDefault implements JsonDeserializationCont
|
||||
JsonDeserializationContext context) throws JsonParseException {
|
||||
JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
|
||||
json, typeOfT, navigatorFactory, objectConstructor, deserializers, context);
|
||||
ObjectNavigator on = navigatorFactory.create(json.getAsObject(), typeOfT);
|
||||
ObjectNavigator on = navigatorFactory.create(new ObjectTypePair(json.getAsObject(), typeOfT));
|
||||
on.accept(visitor);
|
||||
Object target = visitor.getTarget();
|
||||
return (T) target;
|
||||
|
@ -58,14 +58,15 @@ abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor
|
||||
|
||||
protected abstract T constructTarget();
|
||||
|
||||
public void start(Object node) {
|
||||
public void start(ObjectTypePair node) {
|
||||
}
|
||||
|
||||
public void end(Object node) {
|
||||
public void end(ObjectTypePair node) {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final boolean visitUsingCustomHandler(Object obj, Type objType) {
|
||||
public final boolean visitUsingCustomHandler(ObjectTypePair objTypePair) {
|
||||
Type objType = objTypePair.getType();
|
||||
JsonDeserializer deserializer = deserializers.getHandlerFor(objType);
|
||||
if (deserializer != null) {
|
||||
target = (T) deserializer.deserialize(json, objType, context);
|
||||
@ -89,7 +90,7 @@ abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor
|
||||
}
|
||||
|
||||
private Object visitChild(Type type, JsonDeserializationVisitor<?> childVisitor) {
|
||||
ObjectNavigator on = factory.create(null, type);
|
||||
ObjectNavigator on = factory.create(new ObjectTypePair(null, type));
|
||||
on.accept(childVisitor);
|
||||
// the underlying object may have changed during the construction phase
|
||||
// This happens primarily because of custom deserializers
|
||||
|
@ -28,14 +28,14 @@ final class JsonSerializationContextDefault implements JsonSerializationContext
|
||||
private final ObjectNavigatorFactory factory;
|
||||
private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
|
||||
private final boolean serializeNulls;
|
||||
private final MemoryRefStack<Object> ancestors;
|
||||
private final MemoryRefStack ancestors;
|
||||
|
||||
JsonSerializationContextDefault(ObjectNavigatorFactory factory, boolean serializeNulls,
|
||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers) {
|
||||
this.factory = factory;
|
||||
this.serializeNulls = serializeNulls;
|
||||
this.serializers = serializers;
|
||||
this.ancestors = new MemoryRefStack<Object>();
|
||||
this.ancestors = new MemoryRefStack();
|
||||
}
|
||||
|
||||
public JsonElement serialize(Object src) {
|
||||
@ -43,7 +43,7 @@ final class JsonSerializationContextDefault implements JsonSerializationContext
|
||||
}
|
||||
|
||||
public JsonElement serialize(Object src, Type typeOfSrc) {
|
||||
ObjectNavigator on = factory.create(src, typeOfSrc);
|
||||
ObjectNavigator on = factory.create(new ObjectTypePair(src, typeOfSrc));
|
||||
JsonSerializationVisitor visitor =
|
||||
new JsonSerializationVisitor(factory, serializeNulls, serializers, this, ancestors);
|
||||
on.accept(visitor);
|
||||
|
@ -32,12 +32,12 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
|
||||
private final boolean serializeNulls;
|
||||
private final JsonSerializationContext context;
|
||||
private final MemoryRefStack<Object> ancestors;
|
||||
private final MemoryRefStack ancestors;
|
||||
private JsonElement root;
|
||||
|
||||
JsonSerializationVisitor(ObjectNavigatorFactory factory, boolean serializeNulls,
|
||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
|
||||
JsonSerializationContext context, MemoryRefStack<Object> ancestors) {
|
||||
JsonSerializationContext context, MemoryRefStack ancestors) {
|
||||
this.factory = factory;
|
||||
this.serializeNulls = serializeNulls;
|
||||
this.serializers = serializers;
|
||||
@ -49,7 +49,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void start(Object node) {
|
||||
public void start(ObjectTypePair node) {
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
@ -59,7 +59,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
ancestors.push(node);
|
||||
}
|
||||
|
||||
public void end(Object node) {
|
||||
public void end(ObjectTypePair node) {
|
||||
if (node != null) {
|
||||
ancestors.pop();
|
||||
}
|
||||
@ -80,7 +80,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
if (child != null) {
|
||||
childType = getActualTypeIfMoreSpecific(childType, child.getClass());
|
||||
}
|
||||
addAsArrayElement(childType, child);
|
||||
addAsArrayElement(new ObjectTypePair(child, childType));
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
}
|
||||
} else {
|
||||
Object array = getFieldValue(f, obj);
|
||||
addAsChildOfObject(f, typeOfF, array);
|
||||
addAsChildOfObject(f, new ObjectTypePair(array, typeOfF));
|
||||
}
|
||||
} catch (CircularReferenceException e) {
|
||||
throw e.createDetailedException(f);
|
||||
@ -110,7 +110,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
if (fieldValue != null) {
|
||||
typeOfF = getActualTypeIfMoreSpecific(typeOfF, fieldValue.getClass());
|
||||
}
|
||||
addAsChildOfObject(f, typeOfF, fieldValue);
|
||||
addAsChildOfObject(f, new ObjectTypePair(fieldValue, typeOfF));
|
||||
}
|
||||
} catch (CircularReferenceException e) {
|
||||
throw e.createDetailedException(f);
|
||||
@ -139,8 +139,8 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
assignToRoot(json);
|
||||
}
|
||||
|
||||
private void addAsChildOfObject(Field f, Type fieldType, Object fieldValue) {
|
||||
JsonElement childElement = getJsonElementForChild(fieldType, fieldValue);
|
||||
private void addAsChildOfObject(Field f, ObjectTypePair fieldValuePair) {
|
||||
JsonElement childElement = getJsonElementForChild(fieldValuePair);
|
||||
addChildAsElement(f, childElement);
|
||||
}
|
||||
|
||||
@ -149,17 +149,17 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
root.getAsJsonObject().add(namingPolicy.translateName(f), childElement);
|
||||
}
|
||||
|
||||
private void addAsArrayElement(Type elementType, Object elementValue) {
|
||||
if (elementValue == null) {
|
||||
private void addAsArrayElement(ObjectTypePair elementTypePair) {
|
||||
if (elementTypePair.getObj() == null) {
|
||||
root.getAsJsonArray().add(JsonNull.createJsonNull());
|
||||
} else {
|
||||
JsonElement childElement = getJsonElementForChild(elementType, elementValue);
|
||||
JsonElement childElement = getJsonElementForChild(elementTypePair);
|
||||
root.getAsJsonArray().add(childElement);
|
||||
}
|
||||
}
|
||||
|
||||
private JsonElement getJsonElementForChild(Type fieldType, Object fieldValue) {
|
||||
ObjectNavigator on = factory.create(fieldValue, fieldType);
|
||||
private JsonElement getJsonElementForChild(ObjectTypePair fieldValueTypePair) {
|
||||
ObjectNavigator on = factory.create(fieldValueTypePair);
|
||||
JsonSerializationVisitor childVisitor =
|
||||
new JsonSerializationVisitor(factory, serializeNulls, serializers, context, ancestors);
|
||||
on.accept(childVisitor);
|
||||
@ -167,8 +167,10 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean visitUsingCustomHandler(Object obj, Type objType) {
|
||||
public boolean visitUsingCustomHandler(ObjectTypePair objTypePair) {
|
||||
try {
|
||||
Object obj = objTypePair.getObj();
|
||||
Type objType = objTypePair.getType();
|
||||
JsonSerializer serializer = serializers.getHandlerFor(objType);
|
||||
if (serializer == null && obj != null) {
|
||||
serializer = serializers.getHandlerFor(obj.getClass());
|
||||
@ -178,7 +180,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
if (obj == null) {
|
||||
assignToRoot(JsonNull.createJsonNull());
|
||||
} else {
|
||||
assignToRoot(invokeCustomHandler(obj, objType, serializer));
|
||||
assignToRoot(invokeCustomHandler(objTypePair, serializer));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -189,12 +191,12 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private JsonElement invokeCustomHandler(Object obj, Type objType, JsonSerializer serializer) {
|
||||
start(obj);
|
||||
private JsonElement invokeCustomHandler(ObjectTypePair objTypePair, JsonSerializer serializer) {
|
||||
start(objTypePair);
|
||||
try {
|
||||
return serializer.serialize(obj, objType, context);
|
||||
return serializer.serialize(objTypePair.getObj(), objTypePair.getType(), context);
|
||||
} finally {
|
||||
end(obj);
|
||||
end(objTypePair);
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,7 +213,8 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
|
||||
}
|
||||
JsonSerializer serializer = serializers.getHandlerFor(actualTypeOfField);
|
||||
if (serializer != null) {
|
||||
JsonElement child = invokeCustomHandler(obj, actualTypeOfField, serializer);
|
||||
ObjectTypePair objTypePair = new ObjectTypePair(obj, actualTypeOfField);
|
||||
JsonElement child = invokeCustomHandler(objTypePair, serializer);
|
||||
addChildAsElement(f, child);
|
||||
return true;
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ import java.util.Stack;
|
||||
*
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
final class MemoryRefStack<T> {
|
||||
private final Stack<T> stack = new Stack<T>();
|
||||
final class MemoryRefStack {
|
||||
private final Stack<ObjectTypePair> stack = new Stack<ObjectTypePair>();
|
||||
|
||||
/**
|
||||
* Adds a new element to the top of the stack.
|
||||
@ -34,7 +34,7 @@ final class MemoryRefStack<T> {
|
||||
* @param obj the object to add to the stack
|
||||
* @return the object that was added
|
||||
*/
|
||||
public T push(T obj) {
|
||||
public ObjectTypePair push(ObjectTypePair obj) {
|
||||
Preconditions.checkNotNull(obj);
|
||||
|
||||
return stack.push(obj);
|
||||
@ -46,7 +46,7 @@ final class MemoryRefStack<T> {
|
||||
* @return the element being removed from the stack
|
||||
* @throws java.util.EmptyStackException thrown if the stack is empty
|
||||
*/
|
||||
public T pop() {
|
||||
public ObjectTypePair pop() {
|
||||
return stack.pop();
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ final class MemoryRefStack<T> {
|
||||
* @return the item from the top of the stack
|
||||
* @throws java.util.EmptyStackException thrown if the stack is empty
|
||||
*/
|
||||
public T peek() {
|
||||
public ObjectTypePair peek() {
|
||||
return stack.peek();
|
||||
}
|
||||
|
||||
@ -71,13 +71,13 @@ final class MemoryRefStack<T> {
|
||||
* @param obj the object to search for in the stack
|
||||
* @return true if this object is already in the stack otherwise false
|
||||
*/
|
||||
public boolean contains(T obj) {
|
||||
public boolean contains(ObjectTypePair obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (T stackObject : stack) {
|
||||
if (obj == stackObject) {
|
||||
for (ObjectTypePair stackObject : stack) {
|
||||
if (stackObject.getObj() == obj.getObj() && stackObject.getType().equals(obj.getType()) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -29,8 +29,8 @@ import java.lang.reflect.Type;
|
||||
final class ObjectNavigator {
|
||||
|
||||
public interface Visitor {
|
||||
public void start(Object node);
|
||||
public void end(Object node);
|
||||
public void start(ObjectTypePair node);
|
||||
public void end(ObjectTypePair node);
|
||||
|
||||
/**
|
||||
* This is called before the object navigator starts visiting the current object
|
||||
@ -56,7 +56,7 @@ final class ObjectNavigator {
|
||||
* This is called to visit an object using a custom handler
|
||||
* @return true if a custom handler exists, false otherwise
|
||||
*/
|
||||
public boolean visitUsingCustomHandler(Object obj, Type objType);
|
||||
public boolean visitUsingCustomHandler(ObjectTypePair objTypePair);
|
||||
|
||||
/**
|
||||
* This is called to visit a field of the current object using a custom handler
|
||||
@ -72,20 +72,17 @@ final class ObjectNavigator {
|
||||
}
|
||||
|
||||
private final ExclusionStrategy exclusionStrategy;
|
||||
private final Object obj;
|
||||
private final Type objType;
|
||||
private final ObjectTypePair objTypePair;
|
||||
|
||||
/**
|
||||
* @param obj The object being navigated
|
||||
* @param objType The (fully genericized) type of the object being navigated
|
||||
* @param objTypePair The object,type (fully genericized) being navigated
|
||||
* @param exclusionStrategy the concrete strategy object to be used to
|
||||
* filter out fields of an object.
|
||||
*/
|
||||
ObjectNavigator(Object obj, Type objType, ExclusionStrategy exclusionStrategy) {
|
||||
ObjectNavigator(ObjectTypePair objTypePair, ExclusionStrategy exclusionStrategy) {
|
||||
Preconditions.checkNotNull(exclusionStrategy);
|
||||
|
||||
this.obj = obj;
|
||||
this.objType = objType;
|
||||
this.objTypePair = objTypePair;
|
||||
this.exclusionStrategy = exclusionStrategy;
|
||||
}
|
||||
|
||||
@ -94,20 +91,21 @@ final class ObjectNavigator {
|
||||
* If a field is null, it does not get visited.
|
||||
*/
|
||||
public void accept(Visitor visitor) {
|
||||
boolean visitedWithCustomHandler = visitor.visitUsingCustomHandler(obj, objType);
|
||||
boolean visitedWithCustomHandler = visitor.visitUsingCustomHandler(objTypePair);
|
||||
if (!visitedWithCustomHandler) {
|
||||
Object obj = objTypePair.getObj();
|
||||
Object objectToVisit = (obj == null) ? visitor.getTarget() : obj;
|
||||
if (objectToVisit == null) {
|
||||
return;
|
||||
}
|
||||
TypeInfo objTypeInfo = new TypeInfo(objType);
|
||||
TypeInfo objTypeInfo = new TypeInfo(objTypePair.getType());
|
||||
if (exclusionStrategy.shouldSkipClass(objTypeInfo.getRawClass())) {
|
||||
return;
|
||||
}
|
||||
visitor.start(obj);
|
||||
visitor.start(objTypePair);
|
||||
try {
|
||||
if (objTypeInfo.isArray()) {
|
||||
visitor.visitArray(objectToVisit, objType);
|
||||
visitor.visitArray(objectToVisit, objTypePair.getType());
|
||||
} else if (objTypeInfo.getActualType() == Object.class
|
||||
&& isPrimitiveOrString(objectToVisit)) {
|
||||
// TODO(Joel): this is only used for deserialization of "primitves"
|
||||
@ -128,7 +126,7 @@ final class ObjectNavigator {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
visitor.end(obj);
|
||||
visitor.end(objTypePair);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -146,7 +144,7 @@ final class ObjectNavigator {
|
||||
if (exclusionStrategy.shouldSkipField(f)) {
|
||||
continue; // skip
|
||||
} else {
|
||||
TypeInfo fieldTypeInfo = TypeInfoFactory.getTypeInfoForField(f, objType);
|
||||
TypeInfo fieldTypeInfo = TypeInfoFactory.getTypeInfoForField(f, objTypePair.getType());
|
||||
Type actualTypeOfField = fieldTypeInfo.getActualType();
|
||||
boolean visitedWithCustomHandler =
|
||||
visitor.visitFieldUsingCustomHandler(f, actualTypeOfField, obj);
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* A factory class used to simplify {@link ObjectNavigator} creation.
|
||||
* This object holds on to a reference of the {@link ExclusionStrategy}
|
||||
@ -48,15 +46,13 @@ final class ObjectNavigatorFactory {
|
||||
* Creates a new {@link ObjectNavigator} for this {@code srcObject},
|
||||
* {@code type} pair.
|
||||
*
|
||||
* @param srcObject object to navigate
|
||||
* @param type the "actual" type of this {@code srcObject}. NOTE: this can
|
||||
* be a {@link java.lang.reflect.ParameterizedType} rather than a {@link Class}.
|
||||
* @param objTypePair The object,type (fully genericized) being navigated
|
||||
* @return a new instance of a {@link ObjectNavigator} ready to navigate the
|
||||
* {@code srcObject} while taking into consideration the
|
||||
* {@code type}.
|
||||
*/
|
||||
public ObjectNavigator create(Object srcObject, Type type) {
|
||||
return new ObjectNavigator(srcObject, type, strategy);
|
||||
public ObjectNavigator create(ObjectTypePair objTypePair) {
|
||||
return new ObjectNavigator(objTypePair, strategy);
|
||||
}
|
||||
|
||||
FieldNamingStrategy getFieldNamingPolicy() {
|
||||
|
47
gson/src/main/java/com/google/gson/ObjectTypePair.java
Normal file
47
gson/src/main/java/com/google/gson/ObjectTypePair.java
Normal file
@ -0,0 +1,47 @@
|
||||
package com.google.gson;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
final class ObjectTypePair {
|
||||
private final Object obj;
|
||||
private final Type type;
|
||||
public ObjectTypePair(Object obj, Type type) {
|
||||
this.obj = obj;
|
||||
this.type = type;
|
||||
}
|
||||
public Object getObj() {
|
||||
return obj;
|
||||
}
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((obj == null) ? 0 : obj.hashCode());
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ObjectTypePair other = (ObjectTypePair) obj;
|
||||
if (this.obj == null) {
|
||||
if (other.obj != null)
|
||||
return false;
|
||||
} else if (!this.obj.equals(other.obj))
|
||||
return false;
|
||||
if (type == null) {
|
||||
if (other.type != null)
|
||||
return false;
|
||||
} else if (!type.equals(other.type))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
@ -28,12 +28,12 @@ import java.util.EmptyStackException;
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
public class MemoryRefStackTest extends TestCase {
|
||||
private MemoryRefStack<MockObject> stack;
|
||||
private MemoryRefStack stack;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
stack = new MemoryRefStack<MockObject>();
|
||||
stack = new MemoryRefStack();
|
||||
}
|
||||
|
||||
public void testPeekEmptyStack() throws Exception {
|
||||
@ -43,7 +43,7 @@ public class MemoryRefStackTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testPushPeekAndPop() throws Exception {
|
||||
MockObject obj = new MockObject();
|
||||
ObjectTypePair obj = new ObjectTypePair(this, getClass());
|
||||
|
||||
assertEquals(obj, stack.push(obj));
|
||||
assertEquals(obj, stack.peek());
|
||||
@ -51,7 +51,7 @@ public class MemoryRefStackTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testPopTooMany() throws Exception {
|
||||
MockObject obj = new MockObject();
|
||||
ObjectTypePair obj = new ObjectTypePair(this, getClass());
|
||||
stack.push(obj);
|
||||
assertEquals(obj, stack.pop());
|
||||
|
||||
@ -61,8 +61,8 @@ public class MemoryRefStackTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testContains() throws Exception {
|
||||
MockObject objA = new MockObject();
|
||||
MockObject objB = new MockObject();
|
||||
ObjectTypePair objA = new ObjectTypePair(new MockObject(), MockObject.class);
|
||||
ObjectTypePair objB = new ObjectTypePair(new MockObject(), MockObject.class);
|
||||
assertEquals(objA, objB);
|
||||
|
||||
stack.push(objA);
|
||||
|
@ -32,6 +32,7 @@ public class InterfaceTest extends TestCase {
|
||||
private Gson gson;
|
||||
private TestObject obj;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
gson = new Gson();
|
||||
|
Loading…
Reference in New Issue
Block a user