181 lines
5.5 KiB
Java
181 lines
5.5 KiB
Java
|
|
package com.foundation.util.json;
|
||
|
|
|
||
|
|
import java.io.IOException;
|
||
|
|
import java.io.StringWriter;
|
||
|
|
import java.util.regex.Matcher;
|
||
|
|
import java.util.regex.Pattern;
|
||
|
|
|
||
|
|
import com.common.comparison.Comparator;
|
||
|
|
import com.common.debug.Debug;
|
||
|
|
import com.common.exception.InvalidArgumentException;
|
||
|
|
import com.common.util.IIterator;
|
||
|
|
import com.common.util.LiteHashMap;
|
||
|
|
import com.common.util.LiteHashSet;
|
||
|
|
import com.common.util.LiteList;
|
||
|
|
import com.foundation.common.Entity;
|
||
|
|
import com.foundation.common.MetadataContainer;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Reads and writes JSON formatted data.
|
||
|
|
* Uses hashmaps and lists for the java side data structure.
|
||
|
|
*/
|
||
|
|
public class JsonBuilder {
|
||
|
|
private JsonBuilder() {
|
||
|
|
}//JsonBuilder()//
|
||
|
|
private static LiteHashMap readObject(JSONObject object) throws JSONException {
|
||
|
|
String[] keys = JSONObject.getNames(object);
|
||
|
|
LiteHashMap result = new LiteHashMap(keys.length > 10 ? keys.length : 10);
|
||
|
|
|
||
|
|
for(int index = 0; index < keys.length; index++) {
|
||
|
|
Object value = object.get(keys[index]);
|
||
|
|
|
||
|
|
if(value instanceof JSONObject) {
|
||
|
|
value = readObject((JSONObject) value);
|
||
|
|
}//if//
|
||
|
|
else if(value instanceof JSONArray) {
|
||
|
|
value = readArray((JSONArray) value);
|
||
|
|
}//else if//
|
||
|
|
else if(value == JSONObject.NULL) {
|
||
|
|
value = null;
|
||
|
|
}//else if//
|
||
|
|
|
||
|
|
result.put(keys[index], value);
|
||
|
|
}//for//
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}//readObject()//
|
||
|
|
private static LiteList readArray(JSONArray array) throws JSONException {
|
||
|
|
LiteList result = new LiteList(array.length() > 10 ? array.length() : 10);
|
||
|
|
|
||
|
|
for(int index = 0; index < array.length(); index++) {
|
||
|
|
Object value = array.get(index);
|
||
|
|
|
||
|
|
if(value instanceof JSONObject) {
|
||
|
|
value = readObject((JSONObject) value);
|
||
|
|
}//if//
|
||
|
|
else if(value instanceof JSONArray) {
|
||
|
|
value = readArray((JSONArray) value);
|
||
|
|
}//else if//
|
||
|
|
else if(value == JSONObject.NULL) {
|
||
|
|
value = null;
|
||
|
|
}//else if//
|
||
|
|
|
||
|
|
result.add(value);
|
||
|
|
}//for//
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}//readArray()//
|
||
|
|
/**
|
||
|
|
* Converts the JSON string into a collection of LiteHashMap and LiteList instances.
|
||
|
|
* @param json
|
||
|
|
* @return
|
||
|
|
*/
|
||
|
|
public static LiteHashMap readJson(String json) {
|
||
|
|
try {
|
||
|
|
JSONTokener tokener = new JSONTokener(json);
|
||
|
|
//TODO: It may be an array starting the JSON, not an object.
|
||
|
|
JSONObject object = new JSONObject(tokener);
|
||
|
|
|
||
|
|
return readObject(object);
|
||
|
|
}//try//
|
||
|
|
catch(JSONException e) {
|
||
|
|
Debug.log(e);
|
||
|
|
throw new InvalidArgumentException("Invalid JSON string.");
|
||
|
|
}//catch//
|
||
|
|
}//readJson()//
|
||
|
|
private static JSONObject writeObject(LiteHashMap object) throws JSONException {
|
||
|
|
JSONObject result = new JSONObject();
|
||
|
|
|
||
|
|
for(IIterator iterator = object.keyIterator(); iterator.hasNext(); ) {
|
||
|
|
String key = (String) iterator.next();
|
||
|
|
Object value = object.get(key);
|
||
|
|
|
||
|
|
if(value instanceof LiteHashMap) {
|
||
|
|
value = writeObject((LiteHashMap) value);
|
||
|
|
}//if//
|
||
|
|
else if(value instanceof LiteList) {
|
||
|
|
value = writeArray((LiteList) value);
|
||
|
|
}//else if//
|
||
|
|
else if(value == null) {
|
||
|
|
value = JSONObject.NULL;
|
||
|
|
}//else if//
|
||
|
|
|
||
|
|
result.put(key, value);
|
||
|
|
}//for//
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}//writeObject()//
|
||
|
|
private static JSONArray writeArray(LiteList array) throws JSONException {
|
||
|
|
JSONArray result = new JSONArray();
|
||
|
|
|
||
|
|
for(int index = 0; index < array.getSize(); index++) {
|
||
|
|
Object value = array.get(index);
|
||
|
|
|
||
|
|
if(value instanceof LiteHashMap) {
|
||
|
|
value = writeObject((LiteHashMap) value);
|
||
|
|
}//if//
|
||
|
|
else if(value instanceof LiteList) {
|
||
|
|
value = writeArray((LiteList) value);
|
||
|
|
}//else if//
|
||
|
|
else if(value == null) {
|
||
|
|
value = JSONObject.NULL;
|
||
|
|
}//else if//
|
||
|
|
|
||
|
|
result.put(value);
|
||
|
|
}//for//
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}//writeArray()//
|
||
|
|
/**
|
||
|
|
* Converts the value into a compact JSON string.
|
||
|
|
* Includes all attributes that are not cyclical.
|
||
|
|
* @param value The value to be converted (it will delve into collections and examine Entity objects to build the JSON string).
|
||
|
|
* @return The JSON formatted string for the tree of objects.
|
||
|
|
*/
|
||
|
|
public static String writeJson(Object value) {
|
||
|
|
return writeJson(value, null, null);
|
||
|
|
}//writeJson()//
|
||
|
|
/**
|
||
|
|
* Converts the value into a JSON string.
|
||
|
|
* Includes all attributes that are not cyclical.
|
||
|
|
* @param indent The indent string to be used, or null if spacing should be minimized.
|
||
|
|
* @return The JSON formatted string for the tree of objects.
|
||
|
|
*/
|
||
|
|
public static String writeJson(Object value, String indent) {
|
||
|
|
return writeJson(value, null, indent);
|
||
|
|
}//toJson()//
|
||
|
|
/**
|
||
|
|
* Converts the value into a compact JSON string.
|
||
|
|
* Includes all attributes that are not cyclical.
|
||
|
|
* @param metadataContainer The container containing metadata on what to include in the JSON.
|
||
|
|
* @return The JSON formatted string for the tree of objects.
|
||
|
|
*/
|
||
|
|
public static String writeJson(Object value, MetadataContainer metadataContainer) {
|
||
|
|
return writeJson(value, metadataContainer, null);
|
||
|
|
}//toJson()//
|
||
|
|
/**
|
||
|
|
* Converts the value into a JSON string.
|
||
|
|
* Includes all attributes that are not cyclical.
|
||
|
|
* @param metadataContainer The container containing metadata on what to include in the JSON.
|
||
|
|
* @param indent The indent string to be used, or null if spacing should be minimized.
|
||
|
|
* @return The JSON formatted string for the tree of objects.
|
||
|
|
*/
|
||
|
|
public static String writeJson(Object value, MetadataContainer metadataContainer, String indent) {
|
||
|
|
StringWriter writer = new StringWriter(10000);
|
||
|
|
|
||
|
|
if(value != null) {
|
||
|
|
try {
|
||
|
|
Entity.jsonValue(value, metadataContainer, indent, 0, new LiteHashSet(100, Comparator.getIdentityComparator(), LiteHashSet.STYLE_NO_DUPLICATES), writer);
|
||
|
|
}//try//
|
||
|
|
catch(IOException e) {
|
||
|
|
//Shouldn't ever occur.//
|
||
|
|
Debug.log(e);
|
||
|
|
}//catch//
|
||
|
|
catch(Throwable e) {
|
||
|
|
Debug.log(e);
|
||
|
|
}//catch//
|
||
|
|
}//if//
|
||
|
|
|
||
|
|
return writer.toString();
|
||
|
|
}//toJson()//
|
||
|
|
}//JsonBuilder//
|