Temporary fix for JSON null fields

This commit is contained in:
Ziver Koc 2015-10-07 16:25:59 +00:00
parent cf43992266
commit 0bb193fba3
5 changed files with 71 additions and 25 deletions

View file

@ -8,7 +8,6 @@
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="libs" level="project" />
<orderEntry type="module-library" scope="TEST"> <orderEntry type="module-library" scope="TEST">
<library name="JUnit4"> <library name="JUnit4">
<CLASSES> <CLASSES>
@ -20,5 +19,18 @@
<SOURCES /> <SOURCES />
</library> </library>
</orderEntry> </orderEntry>
<orderEntry type="module-library">
<library name="libs">
<CLASSES>
<root url="file://$MODULE_DIR$/libs" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$MODULE_DIR$/libs" />
</SOURCES>
<jarDirectory url="file://$MODULE_DIR$/libs" recursive="false" />
<jarDirectory url="file://$MODULE_DIR$/libs" recursive="false" type="SOURCES" />
</library>
</orderEntry>
</component> </component>
</module> </module>

View file

@ -26,6 +26,7 @@ package zutil.parser.json;
import sun.reflect.generics.reflectiveObjects.NotImplementedException; import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import zutil.ClassUtil; import zutil.ClassUtil;
import zutil.log.LogUtil;
import zutil.parser.Base64Decoder; import zutil.parser.Base64Decoder;
import zutil.parser.DataNode; import zutil.parser.DataNode;
@ -38,8 +39,11 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
public class JSONObjectInputStream extends InputStream implements ObjectInput, Closeable{ public class JSONObjectInputStream extends InputStream implements ObjectInput, Closeable{
private static final Logger logger = LogUtil.getLogger();
protected static final String MD_OBJECT_ID = "@object_id"; protected static final String MD_OBJECT_ID = "@object_id";
protected static final String MD_CLASS = "@class"; protected static final String MD_CLASS = "@class";
@ -89,32 +93,29 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
try{ try{
DataNode root = parser.read(); DataNode root = parser.read();
if(root != null){ if(root != null){
return readObject(null, root); return readObject(null, null, root);
} }
// TODO: Fix Exceptions } catch (Exception e) {
} catch (InstantiationException e) { logger.log(Level.WARNING, null, e);
e.printStackTrace(); } finally {
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
objectCache.clear(); objectCache.clear();
} }
return null; return null;
} }
protected Object readObject(String key, DataNode json) throws IllegalAccessException, InstantiationException, ClassNotFoundException, IllegalArgumentException, UnsupportedDataTypeException { protected Object readObject(Class<?> type, String key, DataNode json) throws IllegalAccessException, InstantiationException, ClassNotFoundException, IllegalArgumentException, UnsupportedDataTypeException, NoSuchFieldException {
// See if the Object id is in the cache before continuing // See if the Object id is in the cache before continuing
if(json.getString("@object_id") != null && objectCache.containsKey(json.getInt(MD_OBJECT_ID))) if(json.getString("@object_id") != null && objectCache.containsKey(json.getInt(MD_OBJECT_ID)))
return objectCache.get(json.getInt(MD_OBJECT_ID)); return objectCache.get(json.getInt(MD_OBJECT_ID));
// Resolve the class // Resolve the class
Object obj = null; Object obj = null;
// Try using explicit class
if(type != null){
obj = type.newInstance();
}
// Try using metadata // Try using metadata
if(json.getString(MD_CLASS) != null) { else if(json.getString(MD_CLASS) != null) {
Class<?> objClass = Class.forName(json.getString(MD_CLASS)); Class<?> objClass = Class.forName(json.getString(MD_CLASS));
obj = objClass.newInstance(); obj = objClass.newInstance();
} }
@ -123,8 +124,11 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
Class<?> objClass = registeredClasses.get(key); Class<?> objClass = registeredClasses.get(key);
obj = objClass.newInstance(); obj = objClass.newInstance();
} }
// Unknown Class // Unknown class
else return null; else {
logger.warning("Unknown type for key: '"+key+"'");
return null;
}
// Read all fields from the new object instance // Read all fields from the new object instance
for(Field field : obj.getClass().getDeclaredFields()){ for(Field field : obj.getClass().getDeclaredFields()){
@ -146,7 +150,7 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
} }
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
protected Object readField(Class<?> type, String key, DataNode json) throws IllegalAccessException, ClassNotFoundException, InstantiationException, UnsupportedDataTypeException { protected Object readField(Class<?> type, String key, DataNode json) throws IllegalAccessException, ClassNotFoundException, InstantiationException, UnsupportedDataTypeException, NoSuchFieldException {
// Field type is a primitive? // Field type is a primitive?
if(type.isPrimitive() || String.class.isAssignableFrom(type)){ if(type.isPrimitive() || String.class.isAssignableFrom(type)){
return readPrimitive(type, json); return readPrimitive(type, json);
@ -165,7 +169,7 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
else if(List.class.isAssignableFrom(type)){ else if(List.class.isAssignableFrom(type)){
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(readObject(key, json.get(i))); list.add(readObject(null, key, json.get(i)));
} }
return list; return list;
} }
@ -175,13 +179,17 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C
String subKey = it.next(); String subKey = it.next();
map.put( map.put(
subKey, subKey,
readObject(subKey, json.get(subKey))); readObject(null, subKey, json.get(subKey)));
} }
return map; return map;
} }
// Field is a new Object // Field is a new Object
else{ else{
return readObject(key, json); Field field = type.getField(key);
if(field != null)
return readObject(field.getType(), key, json);
else
return readObject(null, key, json);
} }
} }

View file

@ -73,6 +73,8 @@ 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)
return null;
DataNode root; DataNode root;
// Check if the object is a primitive // Check if the object is a primitive
@ -132,7 +134,7 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput
} }
private DataNode getPrimitiveDataNode(Class<?> type, Object value) throws UnsupportedDataTypeException, IllegalArgumentException, IllegalAccessException { private DataNode getPrimitiveDataNode(Class<?> type, Object value) throws UnsupportedDataTypeException, IllegalArgumentException, IllegalAccessException {
DataNode node; DataNode node = null;
if (type == int.class || if (type == int.class ||
type == Integer.class || type == Integer.class ||
type == long.class || type == long.class ||
@ -152,7 +154,8 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput
else else
throw new UnsupportedDataTypeException("Unsupported primitive data type: "+type.getName()); throw new UnsupportedDataTypeException("Unsupported primitive data type: "+type.getName());
node.set(value.toString()); if(value != null)
node.set(value.toString());
return node; return node;
} }

View file

@ -75,6 +75,11 @@ public class JSONWriter{
* @param root is the root node * @param root is the root node
*/ */
public void write(DataNode root){ public void write(DataNode root){
if(root == null){
out.print("null");
return;
}
boolean first = true; boolean first = true;
switch(root.getType()){ switch(root.getType()){
// Write Map // Write Map

View file

@ -109,6 +109,20 @@ public class JSONSerializerTest{
assertEquals( sourceObj, targetObj ); assertEquals( sourceObj, targetObj );
} }
@Test
public void testSerializerWithNullFields() throws InterruptedException, IOException, ClassNotFoundException{
TestClass sourceObj = new TestClass();
String data = writeObjectToJson(sourceObj, false);
data = data.replace("\"", "'");
assertEquals(
"{'str': null, 'obj1': null, 'obj2': null, 'decimal': 0.0}",
data);
TestClass targetObj = sendReceiveObject(sourceObj);
assertEquals( sourceObj, targetObj );
}
/******************* Utility Functions ************************************/ /******************* Utility Functions ************************************/
@ -127,9 +141,13 @@ public class JSONSerializerTest{
return targetObj; return targetObj;
} }
public static <T> String writeObjectToJson(T sourceObj) throws IOException{ public static <T> String writeObjectToJson(T sourceObj) throws IOException{
return writeObjectToJson(sourceObj, true);
}
public static <T> String writeObjectToJson(T sourceObj, boolean metadata) throws IOException{
StringOutputStream bout = new StringOutputStream(); StringOutputStream bout = new StringOutputStream();
JSONObjectOutputStream out = new JSONObjectOutputStream(bout); JSONObjectOutputStream out = new JSONObjectOutputStream(bout);
out.enableMetaData(metadata);
out.writeObject(sourceObj); out.writeObject(sourceObj);
out.flush(); out.flush();