Improved JSON Node and Outputstream
This commit is contained in:
parent
7ccf26dc37
commit
86d463be88
5 changed files with 108 additions and 29 deletions
|
|
@ -188,43 +188,47 @@ public class DataNode implements Iterable<DataNode>{
|
|||
map.put(key, new DataNode(value));
|
||||
}
|
||||
/**
|
||||
* Sets the value of the node, but only if it is setup as an JSONType.Value
|
||||
* Sets the value of the node
|
||||
* @exception NullPointerException if the node is setup as anything other than a DataType.Number
|
||||
*/
|
||||
public void set(int value){
|
||||
if( !this.isValue() ) throw new NullPointerException("The node is not setup as a value");
|
||||
type = DataType.Number;
|
||||
if( this.type != DataType.Number )
|
||||
throw new NullPointerException("The node is not setup as a DataType.Number");
|
||||
this.value = ""+value;
|
||||
}
|
||||
/**
|
||||
* Sets the value of the node, but only if it is setup as an JSONType.Value
|
||||
* Sets the value of the node
|
||||
* @exception NullPointerException if the node is setup as anything other than a DataType.Number
|
||||
*/
|
||||
public void set(double value){
|
||||
if( !this.isValue() ) throw new NullPointerException("The node is not setup as a value");
|
||||
type = DataType.Number;
|
||||
if( this.type != DataType.Number )
|
||||
throw new NullPointerException("The node is not setup as a DataType.Number");
|
||||
this.value = ""+value;
|
||||
}
|
||||
/**
|
||||
* Sets the value of the node, but only if it is setup as an JSONType.Value
|
||||
* Sets the value of the node
|
||||
* @exception NullPointerException if the node is setup as anything other than a DataType.Boolean
|
||||
*/
|
||||
public void set(boolean value){
|
||||
if( !this.isValue() ) throw new NullPointerException("The node is not setup as a value");
|
||||
type = DataType.Boolean;
|
||||
if( this.type != DataType.Boolean )
|
||||
throw new NullPointerException("The node is not setup as a DataType.Boolean");
|
||||
this.value = ""+value;
|
||||
}
|
||||
/**
|
||||
* Sets the value of the node, but only if it is setup as an JSONType.Value
|
||||
* Sets the value of the node, but only
|
||||
* @exception NullPointerException if the node is setup as anything other than a DataType.Number
|
||||
*/
|
||||
public void set(long value){
|
||||
if( !this.isValue() ) throw new NullPointerException("The node is not setup as a value");
|
||||
type = DataType.Number;
|
||||
if( this.type != DataType.Number )
|
||||
throw new NullPointerException("The node is not setup as a DataType.Number");
|
||||
this.value = ""+value;
|
||||
}
|
||||
/**
|
||||
* Sets the value of the node, but only if it is setup as an JSONType.Value
|
||||
* Sets the value of the node
|
||||
* @exception NullPointerException if the method DataType.isValue() returns false
|
||||
*/
|
||||
public void set(String value){
|
||||
if( !this.isValue() ) throw new NullPointerException("The node is not setup as a value");
|
||||
type = DataType.String;
|
||||
if( !this.isValue() ) throw new NullPointerException("The node is not setup as a value node");
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
package zutil.parser.json;
|
||||
|
||||
import zutil.parser.DataNode;
|
||||
import zutil.parser.DataNode.DataType;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Array;
|
||||
|
|
@ -32,6 +33,8 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.activation.UnsupportedDataTypeException;
|
||||
|
||||
public class JSONObjectOutputStream extends OutputStream implements ObjectOutput, Closeable{
|
||||
private boolean generateMetaData;
|
||||
|
||||
|
|
@ -96,13 +99,13 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput
|
|||
}
|
||||
}
|
||||
|
||||
protected DataNode getDataNode(Object obj) throws IllegalAccessException {
|
||||
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){
|
||||
root.set("@class", obj.getClass().getName());
|
||||
// Cache
|
||||
if(objectCache.containsKey(obj)){ // Hit
|
||||
root.set("@object_id", objectCache.get(obj));
|
||||
|
|
@ -112,6 +115,7 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput
|
|||
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()){
|
||||
|
|
@ -121,7 +125,7 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput
|
|||
// Add basic type (int, float...)
|
||||
if(field.getType().isPrimitive() ||
|
||||
String.class.isAssignableFrom(field.getType())){
|
||||
root.set(field.getName(), field.get(obj).toString());
|
||||
root.set(field.getName(), getPrimitiveDataNode(field, obj));
|
||||
}
|
||||
// Add an array
|
||||
else if(field.getType().isArray()){
|
||||
|
|
@ -146,7 +150,33 @@ public class JSONObjectOutputStream extends OutputStream implements ObjectOutput
|
|||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
private DataNode getPrimitiveDataNode(Field field, Object obj) throws UnsupportedDataTypeException, IllegalArgumentException, IllegalAccessException {
|
||||
Class<?> type = field.getType();
|
||||
DataNode node = null;
|
||||
if (type == int.class ||
|
||||
type == Integer.class ||
|
||||
type == long.class ||
|
||||
type == Long.class ||
|
||||
type == double.class ||
|
||||
type == Double.class)
|
||||
node = new DataNode(DataType.Number);
|
||||
|
||||
else if(type == boolean.class ||
|
||||
type == Boolean.class)
|
||||
node = new DataNode(DataType.Boolean);
|
||||
|
||||
else if(type == String.class ||
|
||||
type == char.class ||
|
||||
type == Character.class)
|
||||
node = new DataNode(DataType.String);
|
||||
else
|
||||
throw new UnsupportedDataTypeException("Unsupported primitive data type: "+type.getName());
|
||||
|
||||
node.set(field.get(obj).toString());
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
// TODO:
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,12 +22,12 @@
|
|||
|
||||
package zutil.parser.json;
|
||||
|
||||
import zutil.io.StringInputStream;
|
||||
import zutil.parser.DataNode;
|
||||
import zutil.parser.DataNode.DataType;
|
||||
import zutil.struct.MutableInt;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* This is a JSON parser class
|
||||
|
|
@ -35,6 +35,9 @@ import java.io.*;
|
|||
* @author Ziver
|
||||
*/
|
||||
public class JSONParser{
|
||||
public static final Pattern NUMBER_PATTERN = Pattern.compile("^[0-9.]++$");
|
||||
public static final Pattern BOOLEAN_PATTERN = Pattern.compile("^(true|false)$", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
private Reader in;
|
||||
|
||||
public JSONParser(Reader in){
|
||||
|
|
@ -112,19 +115,27 @@ public class JSONParser{
|
|||
str.append(c);
|
||||
root.set(str.toString());
|
||||
break;
|
||||
// Parse Number
|
||||
// Parse unknown type
|
||||
default:
|
||||
root = new DataNode(DataType.Number);
|
||||
StringBuilder num = new StringBuilder().append(c);
|
||||
StringBuilder tmp = new StringBuilder().append(c);
|
||||
while((c=(char)in.read()) != (char)-1 && !Character.isWhitespace(c) &&
|
||||
c != ',' && c != '='){
|
||||
if(c == ']' || c == '}'){
|
||||
end.i = 1;
|
||||
break;
|
||||
}
|
||||
num.append(c);
|
||||
tmp.append(c);
|
||||
}
|
||||
root.set(num.toString());
|
||||
// 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() )
|
||||
root = new DataNode(DataType.Number);
|
||||
else
|
||||
root = new DataNode(DataType.String);
|
||||
root.set(data);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public class JSONSerializerTest{
|
|||
data = data.replace("\"", "'");
|
||||
|
||||
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}, '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);
|
||||
}
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ public class JSONSerializerTest{
|
|||
data = data.replace("\"", "'");
|
||||
|
||||
assertEquals(
|
||||
"{'@class': 'zutil.test.JSONSerializerTest$TestClassObjClone', 'obj1': {'@class': 'zutil.test.JSONSerializerTest$TestObj', 'value': '42', '@object_id': 2}, 'obj2': {'@class': 'zutil.test.JSONSerializerTest$TestObj', '@object_id': 2}, '@object_id': 1}",
|
||||
"{'@class': 'zutil.test.JSONSerializerTest$TestClassObjClone', 'obj1': {'@class': 'zutil.test.JSONSerializerTest$TestObj', 'value': 42, '@object_id': 2}, 'obj2': {'@object_id': 2}, '@object_id': 1}",
|
||||
data);
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +139,7 @@ public class JSONSerializerTest{
|
|||
TestObj obj2;
|
||||
|
||||
public TestClass init(){
|
||||
this.str = "1234";
|
||||
this.str = "abcd";
|
||||
this.decimal = 1.1;
|
||||
this.obj1 = new TestObj().init();
|
||||
this.obj2 = new TestObj().init();
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import static org.junit.Assert.assertNull;
|
|||
import org.junit.Test;
|
||||
|
||||
import zutil.parser.DataNode;
|
||||
import zutil.parser.DataNode.DataType;
|
||||
import zutil.parser.json.JSONParser;
|
||||
|
||||
|
||||
|
|
@ -61,12 +62,45 @@ public class JSONTest{
|
|||
}
|
||||
|
||||
@Test
|
||||
public void number(){
|
||||
public void valueInt(){
|
||||
DataNode data = JSONParser.read("1234");
|
||||
assert(data.isValue());
|
||||
assertEquals( DataType.Number, data.getType());
|
||||
assertEquals( 1234, data.getInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void valueDouble(){
|
||||
DataNode data = JSONParser.read("12.34");
|
||||
assert(data.isValue());
|
||||
assertEquals( DataType.Number, data.getType());
|
||||
assertEquals( 12.34, data.getDouble(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void valueBoolean(){
|
||||
DataNode data = JSONParser.read("false");
|
||||
assert(data.isValue());
|
||||
assertEquals( DataType.Boolean, data.getType());
|
||||
assertEquals( false, data.getBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void valueBooleanUpperCase(){
|
||||
DataNode data = JSONParser.read("TRUE");
|
||||
assert(data.isValue());
|
||||
assertEquals( DataType.Boolean, data.getType());
|
||||
assertEquals( true, data.getBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void valueStringNoQuotes(){
|
||||
DataNode data = JSONParser.read("teststring");
|
||||
assert(data.isValue());
|
||||
assertEquals( DataType.String, data.getType());
|
||||
assertEquals( "teststring", data.getString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toManyCommasInList(){
|
||||
DataNode data = JSONParser.read("[1,2,3,]");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue