|
|
|
|
@@ -16,8 +16,14 @@ import java.util.Date;
|
|
|
|
|
import java.util.Iterator;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
import com.common.metadata.MetadataContainer;
|
|
|
|
|
import com.common.orb.*;
|
|
|
|
|
import com.common.util.*;
|
|
|
|
|
import com.common.util.json.IJsonContext;
|
|
|
|
|
import com.common.util.json.JSONArray;
|
|
|
|
|
import com.common.util.json.JSONException;
|
|
|
|
|
import com.common.util.json.JSONObject;
|
|
|
|
|
import com.common.util.json.JSONString;
|
|
|
|
|
import com.common.util.optimized.IIntIterator;
|
|
|
|
|
import com.common.util.optimized.IntHashSet;
|
|
|
|
|
import com.common.comparison.Comparator;
|
|
|
|
|
@@ -50,10 +56,6 @@ import com.foundation.model.LogicalObjectChangeLog;
|
|
|
|
|
import com.foundation.model.VersionedModel;
|
|
|
|
|
import com.foundation.util.IKeyExtractor;
|
|
|
|
|
import com.foundation.util.ITrackedCollection;
|
|
|
|
|
import com.foundation.util.json.JSONArray;
|
|
|
|
|
import com.foundation.util.json.JSONException;
|
|
|
|
|
import com.foundation.util.json.JSONObject;
|
|
|
|
|
import com.foundation.util.json.JSONString;
|
|
|
|
|
|
|
|
|
|
public abstract class Entity implements IEntity, ICloneable {
|
|
|
|
|
static final long serialVersionUID = -7739741506125052482L;
|
|
|
|
|
@@ -1662,62 +1664,18 @@ public boolean equalsEquals(Object object) {
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}//equalsEquals()//
|
|
|
|
|
/**
|
|
|
|
|
* Converts the entity into a compact JSON string.
|
|
|
|
|
* Includes all attributes that are not cyclical.
|
|
|
|
|
* @return The JSON formatted string for the tree of objects.
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
|
* @see com.common.util.json.IJsonAware#toJson(com.common.util.json.IJsonContext)
|
|
|
|
|
*/
|
|
|
|
|
public String toJson() {
|
|
|
|
|
return toJson(null, null);
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Converts the entity 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 String toJson(String indent) {
|
|
|
|
|
return toJson(null, indent);
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Converts the entity 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 String toJson(MetadataContainer metadataContainer) {
|
|
|
|
|
return toJson(metadataContainer, null);
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Converts the entity 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 String toJson(MetadataContainer metadataContainer, String indent) {
|
|
|
|
|
StringWriter writer = new StringWriter(10000);
|
|
|
|
|
|
|
|
|
|
toJson(metadataContainer, indent, 0, new LiteHashSet(100, Comparator.getIdentityComparator(), LiteHashSet.STYLE_NO_DUPLICATES), writer);
|
|
|
|
|
|
|
|
|
|
return writer.toString();
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Converts the entity 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.
|
|
|
|
|
* @param indentCount The number of indents currently being applied to the output.
|
|
|
|
|
* @param included The set of included objects, used to prevent recursion.
|
|
|
|
|
* @param writer The writer used to write the output.
|
|
|
|
|
*/
|
|
|
|
|
public void toJson(MetadataContainer metadataContainer, String indent, int indentCount, LiteHashSet included, StringWriter writer) {
|
|
|
|
|
public void toJson(IJsonContext context) {
|
|
|
|
|
try {
|
|
|
|
|
boolean commaPrefix = false;
|
|
|
|
|
EntityMetadata metadata = (EntityMetadata) metadataContainer.getMetadata(getClass());
|
|
|
|
|
EntityMetadata metadata = (EntityMetadata) context.getMetadataContainer().getMetadata(getClass());
|
|
|
|
|
IntHashSet metadataAttributes = null;
|
|
|
|
|
IIntIterator metadataAttributeIterator = null;
|
|
|
|
|
int count;
|
|
|
|
|
LiteHashSet included = context.getIncluded();
|
|
|
|
|
StringWriter writer = context.getWriter();
|
|
|
|
|
|
|
|
|
|
//Use the metadata provided if any.//
|
|
|
|
|
if(metadata != null) {
|
|
|
|
|
@@ -1776,7 +1734,6 @@ public void toJson(MetadataContainer metadataContainer, String indent, int inden
|
|
|
|
|
}//if//
|
|
|
|
|
}//for//
|
|
|
|
|
|
|
|
|
|
indentCount++;
|
|
|
|
|
metadataAttributeIterator.resetToFront();
|
|
|
|
|
|
|
|
|
|
//Add the actual attributes and values to the JSON output.//
|
|
|
|
|
@@ -1792,13 +1749,7 @@ public void toJson(MetadataContainer metadataContainer, String indent, int inden
|
|
|
|
|
writer.write(',');
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write('\n');
|
|
|
|
|
|
|
|
|
|
for(int indentCounter = 0; indentCounter < indentCount; indentCounter++) {
|
|
|
|
|
writer.write(indent);
|
|
|
|
|
}//for//
|
|
|
|
|
}//if//
|
|
|
|
|
context.writeNewLine();
|
|
|
|
|
|
|
|
|
|
//Note: No need to escape things since attribute names only allow A-z and underscore.//
|
|
|
|
|
writer.write('"');
|
|
|
|
|
@@ -1806,26 +1757,18 @@ public void toJson(MetadataContainer metadataContainer, String indent, int inden
|
|
|
|
|
writer.write('"');
|
|
|
|
|
writer.write(':');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
if(!context.isCompact()) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
//Write the value out.//
|
|
|
|
|
jsonValue(value, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
context.toJson(value);
|
|
|
|
|
|
|
|
|
|
commaPrefix = true;
|
|
|
|
|
}//if//
|
|
|
|
|
}//for//
|
|
|
|
|
|
|
|
|
|
indentCount--;
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write('\n');
|
|
|
|
|
|
|
|
|
|
for(int indentCounter = 0; indentCounter < indentCount; indentCounter++) {
|
|
|
|
|
writer.write(indent);
|
|
|
|
|
}//for//
|
|
|
|
|
}//if//
|
|
|
|
|
context.writeNewLine();
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write('}');
|
|
|
|
|
@@ -1834,545 +1777,6 @@ public void toJson(MetadataContainer metadataContainer, String indent, int inden
|
|
|
|
|
Debug.log(e);
|
|
|
|
|
}//catch//
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Converts an array of any type of value into a JSON string.
|
|
|
|
|
* @param value The collection.
|
|
|
|
|
* @param metadataContainer An optional container of metadata identifying which attributes of any class to be included. Classes that are encountered and not specified here will use the default include rules (ignore uninitialized and non-lazy loaded attributes, back references, etc).
|
|
|
|
|
* @param indent The optional indent text to be used. Passing null indicates that all extra spacing should be avoided.
|
|
|
|
|
* @param indentCount The starting indent count (for pre-indented output). Normally zero (negative values will be assumed to be zero).
|
|
|
|
|
* @return The JSON formatted text.
|
|
|
|
|
*/
|
|
|
|
|
public static String toJson(IHashMap value, MetadataContainer metadataContainer, String indent, int indentCount) {
|
|
|
|
|
StringWriter writer = new StringWriter(10000);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
toJson(value, metadataContainer, indent, indentCount < 0 ? 0 : indentCount, new LiteHashSet(100, Comparator.getIdentityComparator(), LiteHashSet.STYLE_NO_DUPLICATES), writer);
|
|
|
|
|
}//try//
|
|
|
|
|
catch(IOException e) {
|
|
|
|
|
//Shouldn't ever occur.//
|
|
|
|
|
Debug.log(e);
|
|
|
|
|
}//catch//
|
|
|
|
|
|
|
|
|
|
return writer.toString();
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Writes an array of values to the JSON stream. This method is intended for internal framework use and is subject to change.
|
|
|
|
|
* @param value The collection.
|
|
|
|
|
* @param metadataContainer An optional container of metadata identifying which attributes of any class to be included. Classes that are encountered and not specified here will use the default include rules (ignore uninitialized and non-lazy loaded attributes, back references, etc).
|
|
|
|
|
* @param indent The optional indent text to be used. Passing null indicates that all extra spacing should be avoided.
|
|
|
|
|
* @param indentCount The starting non-negative indent count (for pre-indented output).
|
|
|
|
|
* @param included The set of already included values to avoid recursion.
|
|
|
|
|
* @param writer The writer used to write the output.
|
|
|
|
|
*/
|
|
|
|
|
public static void toJson(IHashMap value, MetadataContainer metadataContainer, String indent, int indentCount, LiteHashSet included, StringWriter writer) throws IOException {
|
|
|
|
|
writer.write("{");
|
|
|
|
|
|
|
|
|
|
if(value != null) {
|
|
|
|
|
boolean isFirst = true;
|
|
|
|
|
|
|
|
|
|
for(IIterator iterator = value.keyIterator(); iterator.hasNext(); ) {
|
|
|
|
|
Object key = iterator.next();
|
|
|
|
|
Object next = value.get(key);
|
|
|
|
|
|
|
|
|
|
if(!isFirst) {
|
|
|
|
|
writer.write(',');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
}//if//
|
|
|
|
|
else {
|
|
|
|
|
isFirst = false;
|
|
|
|
|
}//else//
|
|
|
|
|
|
|
|
|
|
if(key != null && !(key instanceof String)) {
|
|
|
|
|
key = key.toString();
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
//Just roll over null's by converting them to strings. Better than an error IMO.
|
|
|
|
|
if(key == null) {
|
|
|
|
|
key = "null";
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
jsonValue(key, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
writer.write(':');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
jsonValue(next, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
}//for//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write("}");
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Converts an array of any type of value into a JSON string.
|
|
|
|
|
* @param value The collection.
|
|
|
|
|
* @param metadataContainer An optional container of metadata identifying which attributes of any class to be included. Classes that are encountered and not specified here will use the default include rules (ignore uninitialized and non-lazy loaded attributes, back references, etc).
|
|
|
|
|
* @param indent The optional indent text to be used. Passing null indicates that all extra spacing should be avoided.
|
|
|
|
|
* @param indentCount The starting indent count (for pre-indented output). Normally zero (negative values will be assumed to be zero).
|
|
|
|
|
* @return The JSON formatted text.
|
|
|
|
|
*/
|
|
|
|
|
public static String toJson(ICollection value, MetadataContainer metadataContainer, String indent, int indentCount) {
|
|
|
|
|
StringWriter writer = new StringWriter(10000);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
toJson(value, metadataContainer, indent, indentCount < 0 ? 0 : indentCount, new LiteHashSet(100, Comparator.getIdentityComparator(), LiteHashSet.STYLE_NO_DUPLICATES), writer);
|
|
|
|
|
}//try//
|
|
|
|
|
catch(IOException e) {
|
|
|
|
|
//Shouldn't ever occur.//
|
|
|
|
|
Debug.log(e);
|
|
|
|
|
}//catch//
|
|
|
|
|
|
|
|
|
|
return writer.toString();
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Writes an array of values to the JSON stream. This method is intended for internal framework use and is subject to change.
|
|
|
|
|
* @param value The collection.
|
|
|
|
|
* @param metadataContainer An optional container of metadata identifying which attributes of any class to be included. Classes that are encountered and not specified here will use the default include rules (ignore uninitialized and non-lazy loaded attributes, back references, etc).
|
|
|
|
|
* @param indent The optional indent text to be used. Passing null indicates that all extra spacing should be avoided.
|
|
|
|
|
* @param indentCount The starting non-negative indent count (for pre-indented output).
|
|
|
|
|
* @param included The set of already included values to avoid recursion.
|
|
|
|
|
* @param writer The writer used to write the output.
|
|
|
|
|
*/
|
|
|
|
|
public static void toJson(ICollection value, MetadataContainer metadataContainer, String indent, int indentCount, LiteHashSet included, StringWriter writer) throws IOException {
|
|
|
|
|
writer.write("[");
|
|
|
|
|
|
|
|
|
|
if(value != null) {
|
|
|
|
|
boolean isFirst = true;
|
|
|
|
|
|
|
|
|
|
for(IIterator iterator = value.iterator(); iterator.hasNext(); ) {
|
|
|
|
|
Object next = iterator.next();
|
|
|
|
|
|
|
|
|
|
if(!isFirst) {
|
|
|
|
|
writer.write(',');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
}//if//
|
|
|
|
|
else {
|
|
|
|
|
isFirst = false;
|
|
|
|
|
}//else//
|
|
|
|
|
|
|
|
|
|
jsonValue(next, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
}//for//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write("]");
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Converts an array of any type of value into a JSON string.
|
|
|
|
|
* @param value The collection.
|
|
|
|
|
* @param metadataContainer An optional container of metadata identifying which attributes of any class to be included. Classes that are encountered and not specified here will use the default include rules (ignore uninitialized and non-lazy loaded attributes, back references, etc).
|
|
|
|
|
* @param indent The optional indent text to be used. Passing null indicates that all extra spacing should be avoided.
|
|
|
|
|
* @param indentCount The starting indent count (for pre-indented output). Normally zero (negative values will be assumed to be zero).
|
|
|
|
|
* @return The JSON formatted text.
|
|
|
|
|
*/
|
|
|
|
|
public static String toJson(Map value, MetadataContainer metadataContainer, String indent, int indentCount) {
|
|
|
|
|
StringWriter writer = new StringWriter(10000);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
toJson(value, metadataContainer, indent, indentCount < 0 ? 0 : indentCount, new LiteHashSet(100, Comparator.getIdentityComparator(), LiteHashSet.STYLE_NO_DUPLICATES), writer);
|
|
|
|
|
}//try//
|
|
|
|
|
catch(IOException e) {
|
|
|
|
|
//Shouldn't ever occur.//
|
|
|
|
|
Debug.log(e);
|
|
|
|
|
}//catch//
|
|
|
|
|
|
|
|
|
|
return writer.toString();
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Writes an array of values to the JSON stream. This method is intended for internal framework use and is subject to change.
|
|
|
|
|
* @param value The collection.
|
|
|
|
|
* @param metadataContainer An optional container of metadata identifying which attributes of any class to be included. Classes that are encountered and not specified here will use the default include rules (ignore uninitialized and non-lazy loaded attributes, back references, etc).
|
|
|
|
|
* @param indent The optional indent text to be used. Passing null indicates that all extra spacing should be avoided.
|
|
|
|
|
* @param indentCount The starting non-negative indent count (for pre-indented output).
|
|
|
|
|
* @param included The set of already included values to avoid recursion.
|
|
|
|
|
* @param writer The writer used to write the output.
|
|
|
|
|
*/
|
|
|
|
|
public static void toJson(Map value, MetadataContainer metadataContainer, String indent, int indentCount, LiteHashSet included, StringWriter writer) throws IOException {
|
|
|
|
|
writer.write("{");
|
|
|
|
|
|
|
|
|
|
if(value != null) {
|
|
|
|
|
boolean isFirst = true;
|
|
|
|
|
|
|
|
|
|
for(Iterator iterator = value.keySet().iterator(); iterator.hasNext(); ) {
|
|
|
|
|
Object key = iterator.next();
|
|
|
|
|
Object next = value.get(key);
|
|
|
|
|
|
|
|
|
|
if(!isFirst) {
|
|
|
|
|
writer.write(',');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
}//if//
|
|
|
|
|
else {
|
|
|
|
|
isFirst = false;
|
|
|
|
|
}//else//
|
|
|
|
|
|
|
|
|
|
if(key != null && !(key instanceof String)) {
|
|
|
|
|
key = key.toString();
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
//Just roll over null's by converting them to strings. Better than an error IMO.
|
|
|
|
|
if(key == null) {
|
|
|
|
|
key = "null";
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
jsonValue(key, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
writer.write(':');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
jsonValue(next, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
}//for//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write("}");
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Converts an array of any type of value into a JSON string.
|
|
|
|
|
* @param value The collection.
|
|
|
|
|
* @param metadataContainer An optional container of metadata identifying which attributes of any class to be included. Classes that are encountered and not specified here will use the default include rules (ignore uninitialized and non-lazy loaded attributes, back references, etc).
|
|
|
|
|
* @param indent The optional indent text to be used. Passing null indicates that all extra spacing should be avoided.
|
|
|
|
|
* @param indentCount The starting indent count (for pre-indented output). Normally zero (negative values will be assumed to be zero).
|
|
|
|
|
* @return The JSON formatted text.
|
|
|
|
|
*/
|
|
|
|
|
public static String toJson(Collection value, MetadataContainer metadataContainer, String indent, int indentCount) {
|
|
|
|
|
StringWriter writer = new StringWriter(10000);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
toJson(value, metadataContainer, indent, indentCount < 0 ? 0 : indentCount, new LiteHashSet(100, Comparator.getIdentityComparator(), LiteHashSet.STYLE_NO_DUPLICATES), writer);
|
|
|
|
|
}//try//
|
|
|
|
|
catch(IOException e) {
|
|
|
|
|
//Shouldn't ever occur.//
|
|
|
|
|
Debug.log(e);
|
|
|
|
|
}//catch//
|
|
|
|
|
|
|
|
|
|
return writer.toString();
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Writes an array of values to the JSON stream. This method is intended for internal framework use and is subject to change.
|
|
|
|
|
* @param value The collection.
|
|
|
|
|
* @param metadataContainer An optional container of metadata identifying which attributes of any class to be included. Classes that are encountered and not specified here will use the default include rules (ignore uninitialized and non-lazy loaded attributes, back references, etc).
|
|
|
|
|
* @param indent The optional indent text to be used. Passing null indicates that all extra spacing should be avoided.
|
|
|
|
|
* @param indentCount The starting non-negative indent count (for pre-indented output).
|
|
|
|
|
* @param included The set of already included values to avoid recursion.
|
|
|
|
|
* @param writer The writer used to write the output.
|
|
|
|
|
*/
|
|
|
|
|
public static void toJson(Collection value, MetadataContainer metadataContainer, String indent, int indentCount, LiteHashSet included, StringWriter writer) throws IOException {
|
|
|
|
|
writer.write("[");
|
|
|
|
|
|
|
|
|
|
if(value != null) {
|
|
|
|
|
boolean isFirst = true;
|
|
|
|
|
|
|
|
|
|
for(Iterator iterator = value.iterator(); iterator.hasNext(); ) {
|
|
|
|
|
Object next = iterator.next();
|
|
|
|
|
|
|
|
|
|
if(!isFirst) {
|
|
|
|
|
writer.write(',');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
}//if//
|
|
|
|
|
else {
|
|
|
|
|
isFirst = false;
|
|
|
|
|
}//else//
|
|
|
|
|
|
|
|
|
|
jsonValue(next, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
}//for//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write("]");
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Converts an array of any type of value into a JSON string.
|
|
|
|
|
* @param value The array.
|
|
|
|
|
* @param metadataContainer An optional container of metadata identifying which attributes of any class to be included. Classes that are encountered and not specified here will use the default include rules (ignore uninitialized and non-lazy loaded attributes, back references, etc).
|
|
|
|
|
* @param indent The optional indent text to be used. Passing null indicates that all extra spacing should be avoided.
|
|
|
|
|
* @param indentCount The starting indent count (for pre-indented output). Normally zero (negative values will be assumed to be zero).
|
|
|
|
|
* @return The JSON formatted text.
|
|
|
|
|
*/
|
|
|
|
|
public static String toJson(Array value, MetadataContainer metadataContainer, String indent, int indentCount) {
|
|
|
|
|
StringWriter writer = new StringWriter(10000);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
toJson(value, metadataContainer, indent, indentCount < 0 ? 0 : indentCount, new LiteHashSet(100, Comparator.getIdentityComparator(), LiteHashSet.STYLE_NO_DUPLICATES), writer);
|
|
|
|
|
}//try//
|
|
|
|
|
catch(IOException e) {
|
|
|
|
|
//Shouldn't ever occur.//
|
|
|
|
|
Debug.log(e);
|
|
|
|
|
}//catch//
|
|
|
|
|
|
|
|
|
|
return writer.toString();
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Writes an array of values to the JSON stream. This method is intended for internal framework use and is subject to change.
|
|
|
|
|
* @param value The array.
|
|
|
|
|
* @param metadataContainer An optional container of metadata identifying which attributes of any class to be included. Classes that are encountered and not specified here will use the default include rules (ignore uninitialized and non-lazy loaded attributes, back references, etc).
|
|
|
|
|
* @param indent The optional indent text to be used. Passing null indicates that all extra spacing should be avoided.
|
|
|
|
|
* @param indentCount The starting non-negative indent count (for pre-indented output).
|
|
|
|
|
* @param included The set of already included values to avoid recursion.
|
|
|
|
|
* @param writer The writer used to write the output.
|
|
|
|
|
*/
|
|
|
|
|
public static void toJson(Array value, MetadataContainer metadataContainer, String indent, int indentCount, LiteHashSet included, StringWriter writer) throws IOException {
|
|
|
|
|
writer.write("[");
|
|
|
|
|
|
|
|
|
|
if(value != null) {
|
|
|
|
|
int length = Array.getLength(value);
|
|
|
|
|
Class valueType = value.getClass().getComponentType();
|
|
|
|
|
|
|
|
|
|
if(valueType.isPrimitive()) {
|
|
|
|
|
switch(valueType.getName().charAt(0)) {
|
|
|
|
|
case 'Z':
|
|
|
|
|
for(int index = 0; index < length; index++) {
|
|
|
|
|
if(index > 0) {
|
|
|
|
|
writer.write(',');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write(Array.getBoolean(value, index) ? "true" : "false");
|
|
|
|
|
}//for//
|
|
|
|
|
break;
|
|
|
|
|
case 'C':
|
|
|
|
|
for(int index = 0; index < length; index++) {
|
|
|
|
|
if(index > 0) {
|
|
|
|
|
writer.write(',');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
//TODO: This could be optimized.
|
|
|
|
|
jsonQuote("" + Array.getChar(value, index), writer);
|
|
|
|
|
}//for//
|
|
|
|
|
break;
|
|
|
|
|
case 'B':
|
|
|
|
|
for(int index = 0; index < length; index++) {
|
|
|
|
|
if(index > 0) {
|
|
|
|
|
writer.write(',');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write(Byte.toString(Array.getByte(value, index)));
|
|
|
|
|
}//for//
|
|
|
|
|
break;
|
|
|
|
|
case 'S':
|
|
|
|
|
for(int index = 0; index < length; index++) {
|
|
|
|
|
if(index > 0) {
|
|
|
|
|
writer.write(',');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write(Short.toString(Array.getShort(value, index)));
|
|
|
|
|
}//for//
|
|
|
|
|
break;
|
|
|
|
|
case 'I':
|
|
|
|
|
for(int index = 0; index < length; index++) {
|
|
|
|
|
if(index > 0) {
|
|
|
|
|
writer.write(',');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write(Integer.toString(Array.getInt(value, index)));
|
|
|
|
|
}//for//
|
|
|
|
|
break;
|
|
|
|
|
case 'J':
|
|
|
|
|
for(int index = 0; index < length; index++) {
|
|
|
|
|
if(index > 0) {
|
|
|
|
|
writer.write(',');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write(Long.toString(Array.getLong(value, index)));
|
|
|
|
|
}//for//
|
|
|
|
|
break;
|
|
|
|
|
case 'F':
|
|
|
|
|
for(int index = 0; index < length; index++) {
|
|
|
|
|
if(index > 0) {
|
|
|
|
|
writer.write(',');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write(Float.toString(Array.getFloat(value, index)));
|
|
|
|
|
}//for//
|
|
|
|
|
break;
|
|
|
|
|
case 'D':
|
|
|
|
|
for(int index = 0; index < length; index++) {
|
|
|
|
|
if(index > 0) {
|
|
|
|
|
writer.write(',');
|
|
|
|
|
|
|
|
|
|
if(indent != null) {
|
|
|
|
|
writer.write(' ');
|
|
|
|
|
}//if//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write(Double.toString(Array.getDouble(value, index)));
|
|
|
|
|
}//for//
|
|
|
|
|
break;
|
|
|
|
|
}//switch//
|
|
|
|
|
}//if//
|
|
|
|
|
else {
|
|
|
|
|
for(int index = 0; index < length; index++) {
|
|
|
|
|
Object next = Array.get(value, index);
|
|
|
|
|
|
|
|
|
|
jsonValue(next, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
}//for//
|
|
|
|
|
}//else//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write("]");
|
|
|
|
|
}//toJson()//
|
|
|
|
|
/**
|
|
|
|
|
* Writes a value to the JSON stream. This method is intended for internal framework use and is subject to change.
|
|
|
|
|
* @param value The array.
|
|
|
|
|
* @param metadataContainer An optional container of metadata identifying which attributes of any class to be included. Classes that are encountered and not specified here will use the default include rules (ignore uninitialized and non-lazy loaded attributes, back references, etc).
|
|
|
|
|
* @param indent The optional indent text to be used. Passing null indicates that all extra spacing should be avoided.
|
|
|
|
|
* @param indentCount The starting non-negative indent count (for pre-indented output).
|
|
|
|
|
* @param included The set of already included values to avoid recursion.
|
|
|
|
|
* @param writer The writer used to write the output.
|
|
|
|
|
* @throws IOException
|
|
|
|
|
*/
|
|
|
|
|
public static void jsonValue(Object value, MetadataContainer metadataContainer, String indent, int indentCount, LiteHashSet included, StringWriter writer) throws IOException {
|
|
|
|
|
//Write the value.//
|
|
|
|
|
if(value == null || value.equals(null)) {
|
|
|
|
|
writer.write("null");
|
|
|
|
|
}//if//
|
|
|
|
|
else if(value instanceof Entity) {
|
|
|
|
|
((Entity) value).toJson(metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
}//else if//
|
|
|
|
|
else if(value instanceof ICollection) {
|
|
|
|
|
toJson((ICollection) value, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
}
|
|
|
|
|
else if(value instanceof IHashMap) {
|
|
|
|
|
toJson((IHashMap) value, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
}
|
|
|
|
|
else if(value instanceof Map) {
|
|
|
|
|
toJson((Map) value, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
}
|
|
|
|
|
else if(value instanceof Collection) {
|
|
|
|
|
toJson((Collection) value, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
}
|
|
|
|
|
else if(value.getClass().isArray()) {
|
|
|
|
|
toJson((Array) value, metadataContainer, indent, indentCount, included, writer);
|
|
|
|
|
}
|
|
|
|
|
else if(value instanceof Number) {
|
|
|
|
|
if(value instanceof Double && (((Double) value).isInfinite() || ((Double) value).isNaN()) || value instanceof Float && (((Float) value).isInfinite() || ((Float) value).isNaN())) {
|
|
|
|
|
//TODO: Can we convert the number perhaps? Show a max value or something?
|
|
|
|
|
throw new RuntimeException("JSON does not allow non-finite numbers.");
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
String s = value.toString().toLowerCase();
|
|
|
|
|
|
|
|
|
|
//Remove trailing zeros and the decimal if possible.//
|
|
|
|
|
if(s.indexOf('.') > 0 && s.indexOf('e') < 0) {
|
|
|
|
|
int sIndex = s.length() - 1;
|
|
|
|
|
|
|
|
|
|
while(s.charAt(sIndex) == '0') {
|
|
|
|
|
sIndex--;
|
|
|
|
|
}//while//
|
|
|
|
|
|
|
|
|
|
if(s.charAt(sIndex) == '.') {
|
|
|
|
|
s = s.substring(0, sIndex);
|
|
|
|
|
}//if//
|
|
|
|
|
else {
|
|
|
|
|
s = s.substring(0, sIndex + 1);
|
|
|
|
|
}//else//
|
|
|
|
|
}//if//
|
|
|
|
|
|
|
|
|
|
writer.write(s);
|
|
|
|
|
}//else if//
|
|
|
|
|
else if(value instanceof Boolean) {
|
|
|
|
|
writer.write(value.toString());
|
|
|
|
|
}//else if//
|
|
|
|
|
else if(value instanceof String) {
|
|
|
|
|
jsonQuote((String) value, writer);
|
|
|
|
|
}//else if//
|
|
|
|
|
else {
|
|
|
|
|
jsonQuote(value.toString(), writer);
|
|
|
|
|
}//else if//
|
|
|
|
|
}//jsonValue()//
|
|
|
|
|
private static void jsonQuote(String string, Writer w) throws IOException {
|
|
|
|
|
if(string == null || string.length() == 0) {
|
|
|
|
|
w.write("\"\"");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
char b;
|
|
|
|
|
char c = 0;
|
|
|
|
|
String hhhh;
|
|
|
|
|
int i;
|
|
|
|
|
int len = string.length();
|
|
|
|
|
|
|
|
|
|
w.write('"');
|
|
|
|
|
for(i = 0; i < len; i += 1) {
|
|
|
|
|
b = c;
|
|
|
|
|
c = string.charAt(i);
|
|
|
|
|
switch(c) {
|
|
|
|
|
case '\\':
|
|
|
|
|
case '"':
|
|
|
|
|
w.write('\\');
|
|
|
|
|
w.write(c);
|
|
|
|
|
break;
|
|
|
|
|
case '/':
|
|
|
|
|
if(b == '<') {
|
|
|
|
|
w.write('\\');
|
|
|
|
|
}
|
|
|
|
|
w.write(c);
|
|
|
|
|
break;
|
|
|
|
|
case '\b':
|
|
|
|
|
w.write("\\b");
|
|
|
|
|
break;
|
|
|
|
|
case '\t':
|
|
|
|
|
w.write("\\t");
|
|
|
|
|
break;
|
|
|
|
|
case '\n':
|
|
|
|
|
w.write("\\n");
|
|
|
|
|
break;
|
|
|
|
|
case '\f':
|
|
|
|
|
w.write("\\f");
|
|
|
|
|
break;
|
|
|
|
|
case '\r':
|
|
|
|
|
w.write("\\r");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if(c < ' ' || (c >= '\u0080' && c < '\u00a0') || (c >= '\u2000' && c < '\u2100')) {
|
|
|
|
|
hhhh = "000" + Integer.toHexString(c);
|
|
|
|
|
w.write("\\u" + hhhh.substring(hhhh.length() - 4));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
w.write(c);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
w.write('"');
|
|
|
|
|
}//else//
|
|
|
|
|
}//jsonQuote()//
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
|
* @see com.foundation.common.IEntity#getApplication()
|
|
|
|
|
*/
|
|
|
|
|
|