JSON object stream bug fixes

This commit is contained in:
Ziver Koc 2015-11-12 15:16:00 +01:00
parent 0f94a575a3
commit 2a51090813
3 changed files with 51 additions and 67 deletions

View file

@ -129,7 +129,7 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
protected Object readType(Class<?> type, String key, DataNode json) throws IllegalAccessException, ClassNotFoundException, InstantiationException, UnsupportedDataTypeException, NoSuchFieldException { protected Object readType(Class<?> type, Class<?>[] genType, String key, DataNode json) throws IllegalAccessException, ClassNotFoundException, InstantiationException, UnsupportedDataTypeException, NoSuchFieldException {
if(json == null || type == null) if(json == null || type == null)
return null; return null;
// Field type is a primitive? // Field type is a primitive?
@ -142,27 +142,29 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
else{ else{
Object array = Array.newInstance(type.getComponentType(), json.size()); Object array = Array.newInstance(type.getComponentType(), json.size());
for(int i=0; i<json.size(); i++){ for(int i=0; i<json.size(); i++){
Array.set(array, i, readType(type.getComponentType(), key, json.get(i))); Array.set(array, i, readType(type.getComponentType(), null, key, json.get(i)));
} }
return array; return array;
} }
} }
else if(List.class.isAssignableFrom(type)){ else if(List.class.isAssignableFrom(type)){
Class<?>[] genType = ClassUtil.getGenericClasses(type, List.class); if(genType == null || genType.length < 1)
genType = ClassUtil.getGenericClasses(type, List.class);
List list = (List)type.newInstance(); List list = (List)type.newInstance();
for(int i=0; i<json.size(); i++){ for(int i=0; i<json.size(); i++){
list.add(readType((genType.length>=1? genType[0] : null), key, json.get(i))); list.add(readType((genType.length>=1? genType[0] : null), null, key, json.get(i)));
} }
return list; return list;
} }
else if(Map.class.isAssignableFrom(type)){ else if(Map.class.isAssignableFrom(type)){
Class<?>[] genType = ClassUtil.getGenericClasses(type, Map.class); if(genType == null || genType.length < 2)
genType = ClassUtil.getGenericClasses(type, Map.class);
Map map = (Map)type.newInstance(); Map map = (Map)type.newInstance();
for(Iterator<String> it=json.keyIterator(); it.hasNext();){ for(Iterator<String> it=json.keyIterator(); it.hasNext();){
String subKey = it.next(); String subKey = it.next();
map.put( map.put(
subKey, subKey,
readType((genType.length>=2? genType[1] : null), subKey, json.get(subKey))); readType((genType.length>=2? genType[1] : null), null, subKey, json.get(subKey)));
} }
return map; return map;
} }
@ -210,8 +212,10 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
json.get(field.getName()) != null){ json.get(field.getName()) != null){
// Parse field // Parse field
field.setAccessible(true); field.setAccessible(true);
field.set(obj, readType( field.set(obj,
readType(
field.getType(), field.getType(),
ClassUtil.getGenericClasses(field),
field.getName(), field.getName(),
json.get(field.getName()))); json.get(field.getName())));
} }

60
src/zutil/parser/json/JSONObjectOutputStream.java Normal file → Executable file
View file

@ -76,6 +76,7 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput
protected DataNode getDataNode(Object obj) throws IOException, IllegalArgumentException, IllegalAccessException { protected DataNode getDataNode(Object obj) throws IOException, IllegalArgumentException, IllegalAccessException {
if(obj == null) if(obj == null)
return null; return null;
Class objClass = obj.getClass();
DataNode root; DataNode root;
// Check if the object is a primitive // Check if the object is a primitive
@ -83,6 +84,31 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput
ClassUtil.isWrapper(obj.getClass())){ ClassUtil.isWrapper(obj.getClass())){
root = getPrimitiveDataNode(obj.getClass(), obj); root = getPrimitiveDataNode(obj.getClass(), obj);
} }
// Add an array
else if(objClass.isArray()){
root = new DataNode(DataNode.DataType.List);
for(int i=0; i< Array.getLength(obj) ;i++){
root.add(getDataNode(Array.get(obj, i)));
}
}
// List
else if(List.class.isAssignableFrom(objClass)){
root = new DataNode(DataNode.DataType.List);
List list = (List)obj;
for(Object item : list){
root.add(getDataNode(item));
}
}
// Map
else if(Map.class.isAssignableFrom(objClass)){
root = new DataNode(DataNode.DataType.Map);
Map map = (Map)obj;
for(Object key : map.keySet()){
root.set(
getDataNode(key).getString(),
getDataNode(map.get(key)));
}
}
// Object is a complex data type // Object is a complex data type
else { else {
root = new DataNode(DataNode.DataType.Map); root = new DataNode(DataNode.DataType.Map);
@ -109,43 +135,11 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput
// has object a value? // has object a value?
if(ignoreNullFields && fieldObj == null) if(ignoreNullFields && fieldObj == null)
continue; continue;
// Add basic type (int, float...) else
else if(ClassUtil.isPrimitive(field.getType()) ||
ClassUtil.isWrapper(field.getType())){
root.set(field.getName(), getPrimitiveDataNode(field.getType(), fieldObj));
}
// Add an array
else if(field.getType().isArray()){
DataNode arrayNode = new DataNode(DataNode.DataType.List);
for(int i=0; i< Array.getLength(fieldObj) ;i++){
arrayNode.add(getDataNode(Array.get(fieldObj, i)));
}
root.set(field.getName(), arrayNode);
}
else if(List.class.isAssignableFrom(field.getType())){
DataNode listNode = new DataNode(DataNode.DataType.List);
List list = (List)fieldObj;
for(Object item : list){
listNode.add(getDataNode(item));
}
root.set(field.getName(), listNode);
}
else if(Map.class.isAssignableFrom(field.getType())){
DataNode mapNode = new DataNode(DataNode.DataType.Map);
Map map = (Map)fieldObj;
for(Object key : map.keySet()){
mapNode.set(
getDataNode(key).getString(),
getDataNode(map.get(key)));
}
root.set(field.getName(), mapNode);
}
else{
root.set(field.getName(), getDataNode(fieldObj)); root.set(field.getName(), getDataNode(fieldObj));
} }
} }
} }
}
return root; return root;
} }

View file

@ -36,7 +36,9 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class JSONSerializerTest{ public class JSONSerializerTest{
@ -47,9 +49,9 @@ public class JSONSerializerTest{
String data = writeObjectToJson(sourceObj); String data = writeObjectToJson(sourceObj);
data = data.replace("\"", "'"); data = data.replace("\"", "'");
assertEquals( assertThat(data, containsString("'str': 'abcd'"));
"{'str': 'abcd', '@class': 'zutil.test.JSONSerializerTest$TestClass', 'obj1': {'@class': 'zutil.test.JSONSerializerTest$TestObj', 'value': 42, '@object_id': 2}, 'obj2': {'@class': 'zutil.test.JSONSerializerTest$TestObj', 'value': 42, '@object_id': 3}, 'decimal': 1.1, '@object_id': 1}\n", assertThat(data, containsString("'value': 42"));
data); assertThat(data, containsString("'decimal': 1.1"));
} }
@Test @Test
@ -68,9 +70,9 @@ public class JSONSerializerTest{
String data = writeObjectToJson(sourceObj); String data = writeObjectToJson(sourceObj);
data = data.replace("\"", "'"); data = data.replace("\"", "'");
assertEquals( assertThat(data, containsString("'@class': 'zutil.test.JSONSerializerTest$TestClassObjClone'"));
"{'@class': 'zutil.test.JSONSerializerTest$TestClassObjClone', 'obj1': {'@class': 'zutil.test.JSONSerializerTest$TestObj', 'value': 42, '@object_id': 2}, 'obj2': {'@object_id': 2}, '@object_id': 1}\n", assertThat(data, containsString("'obj1': {'@class': 'zutil.test.JSONSerializerTest$TestObj', '@object_id': 2, 'value': 42}"));
data); assertThat(data, containsString("'obj2': {'@object_id': 2}"));
} }
@Test @Test
@ -99,7 +101,6 @@ public class JSONSerializerTest{
TestClassArray sourceObj = new TestClassArray().init(); TestClassArray sourceObj = new TestClassArray().init();
TestClassArray targetObj = sendReceiveObject(sourceObj); TestClassArray targetObj = sendReceiveObject(sourceObj);
assertEquals( sourceObj, targetObj ); assertEquals( sourceObj, targetObj );
} }
@ -108,7 +109,6 @@ public class JSONSerializerTest{
TestClassStringArray sourceObj = new TestClassStringArray().init(); TestClassStringArray sourceObj = new TestClassStringArray().init();
TestClassStringArray targetObj = sendReceiveObject(sourceObj); TestClassStringArray targetObj = sendReceiveObject(sourceObj);
assertEquals( sourceObj, targetObj ); assertEquals( sourceObj, targetObj );
} }
@ -130,12 +130,6 @@ public class JSONSerializerTest{
public void testSerializerWithMapField() throws InterruptedException, IOException, ClassNotFoundException{ public void testSerializerWithMapField() throws InterruptedException, IOException, ClassNotFoundException{
TestClassMap sourceObj = new TestClassMap().init(); TestClassMap sourceObj = new TestClassMap().init();
String data = writeObjectToJson(sourceObj, false);
data = data.replace("\"", "'");
assertEquals(
"{'map': {'key2': 'value2', 'key1': 'value1'}}\n",
data);
TestClassMap targetObj = sendReceiveObject(sourceObj); TestClassMap targetObj = sendReceiveObject(sourceObj);
TestClassMap.assertEquals(sourceObj, targetObj); TestClassMap.assertEquals(sourceObj, targetObj);
} }
@ -145,12 +139,6 @@ public class JSONSerializerTest{
TestClassMap sourceObj = new TestClassMap().init(); TestClassMap sourceObj = new TestClassMap().init();
sourceObj.map.put("key1", null); sourceObj.map.put("key1", null);
String data = writeObjectToJson(sourceObj, false);
data = data.replace("\"", "'");
assertEquals(
"{'map': {'key2': 'value2', 'key1': null}}\n",
data);
TestClassMap targetObj = sendReceiveObject(sourceObj); TestClassMap targetObj = sendReceiveObject(sourceObj);
TestClassMap.assertEquals(sourceObj, targetObj); TestClassMap.assertEquals(sourceObj, targetObj);
} }
@ -159,11 +147,9 @@ public class JSONSerializerTest{
public void testSerializerWithListField() throws InterruptedException, IOException, ClassNotFoundException{ public void testSerializerWithListField() throws InterruptedException, IOException, ClassNotFoundException{
TestClassList sourceObj = new TestClassList().init(); TestClassList sourceObj = new TestClassList().init();
String data = writeObjectToJson(sourceObj, false); String data = writeObjectToJson(sourceObj);
data = data.replace("\"", "'"); data = data.replace("\"", "'");
assertEquals( assertThat(data, containsString("'list': ['value1', 'value2']"));
"{'list': ['value1', 'value2']}\n",
data);
TestClassList targetObj = sendReceiveObject(sourceObj); TestClassList targetObj = sendReceiveObject(sourceObj);
TestClassList.assertEquals(sourceObj, targetObj); TestClassList.assertEquals(sourceObj, targetObj);