diff --git a/src/zutil/parser/json/JSONObjectInputStream.java b/src/zutil/parser/json/JSONObjectInputStream.java index 8e07c66..463b46f 100644 --- a/src/zutil/parser/json/JSONObjectInputStream.java +++ b/src/zutil/parser/json/JSONObjectInputStream.java @@ -32,6 +32,8 @@ import java.lang.reflect.Modifier; import java.util.List; import java.util.Map; +import javax.activation.UnsupportedDataTypeException; + public class JSONObjectInputStream extends InputStream implements ObjectInput, Closeable{ private JSONParser parser; @@ -39,22 +41,27 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C this.parser = new JSONParser(in); } - public Object readObject() throws ClassNotFoundException, IOException { + public Object readObject() throws IOException { try{ DataNode root = parser.read(); if(root != null){ - readObject(root); + return readObject(root); } + // TODO: Fix Exceptions } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); - } + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } return null; } - protected static Object readObject(DataNode json) throws IllegalAccessException, InstantiationException, ClassNotFoundException { - Class objClass = Class.forName(json.getString("@class")); + protected static Object readObject(DataNode json) throws IllegalAccessException, InstantiationException, ClassNotFoundException, IllegalArgumentException, UnsupportedDataTypeException { + Class objClass = Class.forName(json.getString("@class")); Object obj = objClass.newInstance(); // Read all fields from the new object instance @@ -65,16 +72,17 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C // Parse field field.setAccessible(true); field.set(obj, readValue( - field.getDeclaringClass(), + field.getType(), json.get(field.getName()))); } } return obj; } - protected static Object readValue(Class type, DataNode json) throws IllegalAccessException, ClassNotFoundException, InstantiationException { + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected static Object readValue(Class type, DataNode json) throws IllegalAccessException, ClassNotFoundException, InstantiationException, UnsupportedDataTypeException { // Field type is a primitive? - if(type.isPrimitive()){ + if(type.isPrimitive() || String.class.isAssignableFrom(type)){ return readPrimitive(type, json); } else if(type.isArray()){ @@ -90,9 +98,9 @@ public class JSONObjectInputStream extends InputStream implements ObjectInput, C } else if(List.class.isAssignableFrom(type)){ // TODO Add List Support - List list = (List)type.newInstance(); + List list = (List)type.newInstance(); for(int i=0; i type, DataNode json){ - //if (type == Short.class) return json.getShort(); - if (type == Integer.class) return json.getInt(); - else if(type == Long.class) return json.getLong(); + if (type == int.class || + type == Integer.class) return json.getInt(); + else if(type == long.class || + type == Long.class) return json.getLong(); + + else if(type == double.class || + type == Double.class) return json.getDouble(); - //else if(type == Float.class) field.setFloat(obj, json.getFloat()); - else if(type == Double.class) return json.getDouble(); - - else if(type == Boolean.class) return json.getBoolean(); - //else if(type == Character.class) return json.getChar(); + else if(type == boolean.class || + type == Boolean.class) return json.getBoolean(); else if(type == String.class) return json.getString(); - //else if(type == Byte.class) return Base64Decoder.decodeToByte(json.getString()); return null; } diff --git a/src/zutil/parser/json/JSONObjectOutputStream.java b/src/zutil/parser/json/JSONObjectOutputStream.java index e72bd18..d38e924 100644 --- a/src/zutil/parser/json/JSONObjectOutputStream.java +++ b/src/zutil/parser/json/JSONObjectOutputStream.java @@ -120,7 +120,7 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput field.setAccessible(true); // Add basic type (int, float...) if(field.getType().isPrimitive() || - field.getType() == String.class){ + String.class.isAssignableFrom(field.getType())){ root.set(field.getName(), field.get(obj).toString()); } // Add an array diff --git a/src/zutil/test/JSONSerializerTest.java b/src/zutil/test/JSONSerializerTest.java index 49c5220..951bbf4 100644 --- a/src/zutil/test/JSONSerializerTest.java +++ b/src/zutil/test/JSONSerializerTest.java @@ -28,7 +28,6 @@ import java.io.*; import org.junit.Test; -import zutil.io.StringInputStream; import zutil.io.StringOutputStream; import zutil.parser.json.JSONObjectInputStream; import zutil.parser.json.JSONObjectOutputStream; @@ -36,8 +35,8 @@ import zutil.parser.json.JSONObjectOutputStream; public class JSONSerializerTest{ @Test - public void testJSONObjectOutputStream() throws InterruptedException, IOException, ClassNotFoundException{ - TestClass sourceObj = new TestClass(); + public void testOutputSerializer() throws InterruptedException, IOException, ClassNotFoundException{ + TestClass sourceObj = new TestClass().init(); StringOutputStream bout = new StringOutputStream(); JSONObjectOutputStream out = new JSONObjectOutputStream(bout); @@ -48,13 +47,13 @@ public class JSONSerializerTest{ System.out.println(data); assertEquals( - "{\"str\": \"1234\", \"@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}, \"@object_id\": 1}", + "{\"str\": \"1234\", \"@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}", data); } @Test - public void testJavaObjectInOutSerialize() throws InterruptedException, IOException, ClassNotFoundException{ - TestClass sourceObj = new TestClass(); + public void testJavaLegacySerialize() throws InterruptedException, IOException, ClassNotFoundException{ + TestClass sourceObj = new TestClass().init(); ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bout); @@ -72,9 +71,31 @@ public class JSONSerializerTest{ } @Test - public void testJSONObjectInOutSerialize2() throws InterruptedException, IOException, ClassNotFoundException{ - TestClass sourceObj = new TestClass(); + public void testInputSerializerWithPrimitives() throws InterruptedException, IOException, ClassNotFoundException{ + TestClass sourceObj = new TestClass().init(); + TestClass targetObj = sendReceiveObject(sourceObj); + + assertEquals( sourceObj, targetObj ); + } + + @Test + public void testInputSerializerWithClones() throws InterruptedException, IOException, ClassNotFoundException{ + TestClassObjClone sourceObj = new TestClassObjClone().init(); + + TestClassObjClone targetObj = sendReceiveObject(sourceObj); + + assertEquals( sourceObj, targetObj ); + } + + + + + /******************* Utility Functions ************************************/ + + @SuppressWarnings("unchecked") + private static T sendReceiveObject(T sourceObj) throws IOException{ + // Send StringOutputStream bout = new StringOutputStream(); JSONObjectOutputStream out = new JSONObjectOutputStream(bout); out.writeObject(sourceObj); @@ -83,35 +104,65 @@ public class JSONSerializerTest{ String data = bout.toString(); System.out.println(data); + // Receive StringReader bin = new StringReader(data); JSONObjectInputStream in = new JSONObjectInputStream(bin); - TestClass targetObj = (TestClass) in.readObject(); + T targetObj = (T) in.readObject(); in.close(); - - assertEquals( sourceObj, targetObj ); + return targetObj; } - - - + /******************** Test Classes ************************************/ public static class TestClass implements Serializable{ private static final long serialVersionUID = 1L; - String str = "1234"; - TestObj obj1 = new TestObj(); - TestObj obj2 = new TestObj(); + String str; + double decimal; + TestObj obj1; + TestObj obj2; + + public TestClass init(){ + this.str = "1234"; + this.decimal = 1.1; + this.obj1 = new TestObj().init(); + this.obj2 = new TestObj().init(); + return this; + } public boolean equals(Object obj){ return obj instanceof TestClass && - this.str.equals(((TestClass)obj).str) && + this.str.equals(((TestClass)obj).str) && + this.decimal == ((TestClass)obj).decimal && this.obj1.equals(((TestClass)obj).obj1) && this.obj2.equals(((TestClass)obj).obj2); } } + public static class TestClassObjClone{ + TestObj obj1; + TestObj obj2; + + public TestClassObjClone init(){ + this.obj1 = this.obj2 = new TestObj().init(); + return this; + } + + public boolean equals(Object obj){ + return obj instanceof TestClassObjClone && + this.obj1.equals(((TestClass)obj).obj1) && + this.obj1 == this.obj2 && + ((TestClass)obj).obj1 == ((TestClass)obj).obj2; + } + } + public static class TestObj implements Serializable{ private static final long serialVersionUID = 1L; - int value = 42; + int value; + + public TestObj init(){ + this.value = 42; + return this; + } public boolean equals(Object obj){ return obj instanceof TestObj && this.value == ((TestObj)obj).value;