From fe66cc996218888f48cc90bb7626ece926fa34a8 Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Thu, 1 Aug 2013 13:21:25 +0000 Subject: [PATCH] Move OSAL and added array support to JSONSerializers --- src/zutil/ClassUtil.java | 78 +++++++++++++++ .../{zutil => }/osal/OSAbstractionLayer.java | 2 +- src/zutil/{zutil => }/osal/OsalLinuxImpl.java | 2 +- .../{zutil => }/osal/OsalWindowsImpl.java | 12 ++- .../parser/json/JSONObjectOutputStream.java | 97 ++++++++++--------- src/zutil/parser/json/JSONParser.java | 1 - src/zutil/test/JSONSerializerTest.java | 41 +++++++- 7 files changed, 181 insertions(+), 52 deletions(-) create mode 100644 src/zutil/ClassUtil.java rename src/zutil/{zutil => }/osal/OSAbstractionLayer.java (96%) rename src/zutil/{zutil => }/osal/OsalLinuxImpl.java (95%) rename src/zutil/{zutil => }/osal/OsalWindowsImpl.java (87%) diff --git a/src/zutil/ClassUtil.java b/src/zutil/ClassUtil.java new file mode 100644 index 0000000..42175f0 --- /dev/null +++ b/src/zutil/ClassUtil.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013 ezivkoc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil; + +import java.util.HashSet; + +/** + * This class include some utility functions for classes + * + * User: Ziver + */ +public class ClassUtil { + /** A Set that contains possible wrapper objects for primitives **/ + private static final HashSet> wrappers; + static { + wrappers = new HashSet>(); + wrappers.add(Boolean.class); + wrappers.add(Character.class); + wrappers.add(Byte.class); + wrappers.add(Short.class); + wrappers.add(Integer.class); + wrappers.add(Long.class); + wrappers.add(Float.class); + wrappers.add(Double.class); + wrappers.add(Void.class); + } + + /** A Set that contains possible primitives **/ + private static final HashSet> primitives; + static { + primitives = new HashSet>(); + primitives.add(boolean.class); + primitives.add(char.class); + primitives.add(byte.class); + primitives.add(short.class); + primitives.add(int.class); + primitives.add(long.class); + primitives.add(float.class); + primitives.add(double.class); + primitives.add(void.class); + primitives.add(String.class); + } + + + /** + * @return if the given class is a wrapper for a primitive + */ + public static boolean isWrapper(Class type){ + return wrappers.contains( type ); + } + + /** + * @return if the given class is a primitive including String + */ + public static boolean isPrimitive(Class type){ + return primitives.contains( type ); + } +} diff --git a/src/zutil/zutil/osal/OSAbstractionLayer.java b/src/zutil/osal/OSAbstractionLayer.java similarity index 96% rename from src/zutil/zutil/osal/OSAbstractionLayer.java rename to src/zutil/osal/OSAbstractionLayer.java index efe2fe9..da519bf 100644 --- a/src/zutil/zutil/osal/OSAbstractionLayer.java +++ b/src/zutil/osal/OSAbstractionLayer.java @@ -20,7 +20,7 @@ * THE SOFTWARE. */ -package zutil.zutil.osal; +package zutil.osal; import java.io.BufferedReader; import java.io.File; diff --git a/src/zutil/zutil/osal/OsalLinuxImpl.java b/src/zutil/osal/OsalLinuxImpl.java similarity index 95% rename from src/zutil/zutil/osal/OsalLinuxImpl.java rename to src/zutil/osal/OsalLinuxImpl.java index e9a5d5e..9d21603 100644 --- a/src/zutil/zutil/osal/OsalLinuxImpl.java +++ b/src/zutil/osal/OsalLinuxImpl.java @@ -20,7 +20,7 @@ * THE SOFTWARE. */ -package zutil.zutil.osal; +package zutil.osal; import java.io.File; diff --git a/src/zutil/zutil/osal/OsalWindowsImpl.java b/src/zutil/osal/OsalWindowsImpl.java similarity index 87% rename from src/zutil/zutil/osal/OsalWindowsImpl.java rename to src/zutil/osal/OsalWindowsImpl.java index 462ce82..0dd6c9a 100644 --- a/src/zutil/zutil/osal/OsalWindowsImpl.java +++ b/src/zutil/osal/OsalWindowsImpl.java @@ -20,16 +20,17 @@ * THE SOFTWARE. */ -package zutil.zutil.osal; +package zutil.osal; import java.io.File; +import java.io.IOException; /** * User: ezivkoc */ public class OsalWindowsImpl extends OSAbstractionLayer { @Override - public String getOSType() { + public OSType getOSType() { return null; //To change body of implemented methods use File | Settings | File Templates. } @@ -45,7 +46,12 @@ public class OsalWindowsImpl extends OSAbstractionLayer { @Override public String getKernelVersion() { - return runCommand("ver"); + try { + return runCommand("ver"); + } catch (Exception e) { + e.printStackTrace(); + } + return null; } @Override diff --git a/src/zutil/parser/json/JSONObjectOutputStream.java b/src/zutil/parser/json/JSONObjectOutputStream.java index 71b0980..01f1169 100644 --- a/src/zutil/parser/json/JSONObjectOutputStream.java +++ b/src/zutil/parser/json/JSONObjectOutputStream.java @@ -22,6 +22,8 @@ package zutil.parser.json; +import sun.misc.ClassLoaderUtil; +import zutil.ClassUtil; import zutil.parser.DataNode; import zutil.parser.DataNode.DataType; @@ -100,58 +102,65 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput } protected DataNode getDataNode(Object obj) throws IOException, IllegalArgumentException, IllegalAccessException { - //if(!(obj instanceof Serializable)) - // throw new UnSerializable - - DataNode root = new DataNode(DataNode.DataType.Map); - // Generate meta data - if(generateMetaData){ - // Cache - if(objectCache.containsKey(obj)){ // Hit - root.set("@object_id", objectCache.get(obj)); - return root; - } - else{ // Miss - objectCache.put(obj, objectCache.size()+1); - root.set("@object_id", objectCache.size()); - } - root.set("@class", obj.getClass().getName()); + DataNode root = null; + + // Check if the object is a primitive + if(ClassUtil.isPrimitive(obj.getClass()) || + ClassUtil.isWrapper(obj.getClass())){ + root = getPrimitiveDataNode(obj.getClass(), obj); } - // Add all the fields to the DataNode - for(Field field : obj.getClass().getDeclaredFields()){ - if((field.getModifiers() & Modifier.STATIC) == 0 && - (field.getModifiers() & Modifier.TRANSIENT) == 0){ - field.setAccessible(true); - // Add basic type (int, float...) - if(field.getType().isPrimitive() || - String.class.isAssignableFrom(field.getType())){ - root.set(field.getName(), getPrimitiveDataNode(field, obj)); + // Object is a complex data type + else { + root = new DataNode(DataNode.DataType.Map); + // Generate meta data + if(generateMetaData){ + // Cache + if(objectCache.containsKey(obj)){ // Hit + root.set("@object_id", objectCache.get(obj)); + return root; } - // Add an array - else if(field.getType().isArray()){ - DataNode arrayNode = new DataNode(DataNode.DataType.List); - Object array = field.get(obj); - for(int i=0; i< Array.getLength(array) ;i++){ - arrayNode.add(Array.get(array, i).toString()); + else{ // Miss + objectCache.put(obj, objectCache.size()+1); + root.set("@object_id", objectCache.size()); + } + root.set("@class", obj.getClass().getName()); + } + // Add all the fields to the DataNode + for(Field field : obj.getClass().getDeclaredFields()){ + if((field.getModifiers() & Modifier.STATIC) == 0 && + (field.getModifiers() & Modifier.TRANSIENT) == 0){ + field.setAccessible(true); + + // Add basic type (int, float...) + if(ClassUtil.isPrimitive(field.getType()) || + ClassUtil.isWrapper(field.getType())){ + root.set(field.getName(), getPrimitiveDataNode(field.getType(), field.get(obj))); + } + // Add an array + else if(field.getType().isArray()){ + DataNode arrayNode = new DataNode(DataNode.DataType.List); + Object array = field.get(obj); + for(int i=0; i< Array.getLength(array) ;i++){ + arrayNode.add(getDataNode(Array.get(array, i))); + } + root.set(field.getName(), arrayNode); + } + else if(List.class.isAssignableFrom(field.getType())){ + // TODO Add List Support + } + else if(Map.class.isAssignableFrom(field.getType())){ + // TODO Add Map Support + } + else{ + root.set(field.getName(), getDataNode(field.get(obj))); } - root.set(field.getName(), arrayNode); - } - else if(List.class.isAssignableFrom(field.getType())){ - // TODO Add List Support - } - else if(Map.class.isAssignableFrom(field.getType())){ - // TODO Add Map Support - } - else{ - root.set(field.getName(), getDataNode(field.get(obj))); } } } return root; } - private DataNode getPrimitiveDataNode(Field field, Object obj) throws UnsupportedDataTypeException, IllegalArgumentException, IllegalAccessException { - Class type = field.getType(); + private DataNode getPrimitiveDataNode(Class type, Object value) throws UnsupportedDataTypeException, IllegalArgumentException, IllegalAccessException { DataNode node = null; if (type == int.class || type == Integer.class || @@ -172,7 +181,7 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput else throw new UnsupportedDataTypeException("Unsupported primitive data type: "+type.getName()); - node.set(field.get(obj).toString()); + node.set(value.toString()); return node; } diff --git a/src/zutil/parser/json/JSONParser.java b/src/zutil/parser/json/JSONParser.java index 7b7569c..a95bf76 100644 --- a/src/zutil/parser/json/JSONParser.java +++ b/src/zutil/parser/json/JSONParser.java @@ -128,7 +128,6 @@ public class JSONParser{ } // Check what type of type the data is String data = tmp.toString(); - System.out.println("\""+data+"\""); if( BOOLEAN_PATTERN.matcher(data).matches() ) root = new DataNode(DataType.Boolean); else if( NUMBER_PATTERN.matcher(data).matches() ) diff --git a/src/zutil/test/JSONSerializerTest.java b/src/zutil/test/JSONSerializerTest.java index 1baa286..2084596 100644 --- a/src/zutil/test/JSONSerializerTest.java +++ b/src/zutil/test/JSONSerializerTest.java @@ -25,6 +25,7 @@ package zutil.test; import static org.junit.Assert.assertEquals; import java.io.*; +import java.util.Arrays; import org.junit.Test; @@ -61,7 +62,7 @@ public class JSONSerializerTest{ data = data.replace("\"", "'"); assertEquals( - "{'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}", + "{'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}", data); } @@ -94,6 +95,27 @@ public class JSONSerializerTest{ assertEquals( sourceObj, targetObj ); } + + @Test + public void testOutputSerializerWithArrays() throws InterruptedException, IOException, ClassNotFoundException{ + TestClassArray sourceObj = new TestClassArray().init(); + + String data = writeObjectToJson(sourceObj); + data = data.replace("\"", "'"); + + assertEquals( + "{'@class': 'zutil.test.JSONSerializerTest$TestClassArray', 'array': [1, 2, 3, 4], '@object_id': 1}", + data); + } + + @Test + public void testInputSerializerWithArrays() throws InterruptedException, IOException, ClassNotFoundException{ + TestClassArray sourceObj = new TestClassArray().init(); + + TestClassArray targetObj = sendReceiveObject(sourceObj); + + assertEquals( sourceObj, targetObj ); + } @@ -182,7 +204,22 @@ public class JSONSerializerTest{ } public boolean equals(Object obj){ - return obj instanceof TestObj && this.value == ((TestObj)obj).value; + return obj instanceof TestObj && + this.value == ((TestObj)obj).value; } } + + public static class TestClassArray{ + private int[] array; + + public TestClassArray init(){ + array = new int[]{1,2,3,4}; + return this; + } + + public boolean equals(Object obj){ + return obj instanceof TestClassArray && + Arrays.equals(this.array ,((TestClassArray)obj).array); + } + } }