Temporary fix for JSON null fields
This commit is contained in:
parent
cf43992266
commit
0bb193fba3
5 changed files with 71 additions and 25 deletions
14
Zutil.iml
14
Zutil.iml
|
|
@ -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>
|
||||||
|
|
@ -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();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,6 +154,7 @@ 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());
|
||||||
|
|
||||||
|
if(value != null)
|
||||||
node.set(value.toString());
|
node.set(value.toString());
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 ************************************/
|
||||||
|
|
||||||
|
|
@ -128,8 +142,12 @@ public class JSONSerializerTest{
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue