package com.nfwork.dbfound.json;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public final class JSONUtils {
private static String javaVersion = "1.3.1";
static {
javaVersion = System.getProperty("java.version");
}
/**
* Produce a string from a double. The string "null" will be returned if the
* number is not finite.
*
* @param d
* A double.
* @return A String.
*/
public static String doubleToString(double d) {
if (Double.isInfinite(d) || Double.isNaN(d)) {
return "null";
}
// Shave off trailing zeros and decimal point, if possible.
String s = Double.toString(d);
if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) {
while (s.endsWith("0")) {
s = s.substring(0, s.length() - 1);
}
if (s.endsWith(".")) {
s = s.substring(0, s.length() - 1);
}
}
return s;
}
public static int getDimensions(Class arrayClass) {
if (arrayClass == null || !arrayClass.isArray()) {
return 0;
}
return 1 + getDimensions(arrayClass.getComponentType());
}
/**
* Returns the params of a function literal.
*/
public static String getFunctionParams(String function) {
return null;
}
public static Class getInnerComponentType(Class type) {
if (!type.isArray()) {
return type;
}
return getInnerComponentType(type.getComponentType());
}
/**
* Creates a Map with all the properties of the JSONObject.
*/
public static Map getJSONProperties(JSONObject jsonObject) {
Map properties = new HashMap();
for (Iterator keys = jsonObject.keys(); keys.hasNext();) {
String key = (String) keys.next();
properties.put(key, getJSONType(jsonObject.get(key)));
}
return properties;
}
/**
* Returns the JSON type.
*/
public static Object getJSONType(Object obj) {
if (isNull(obj)) {
return JSONTypes.OBJECT;
} else if (isArray(obj)) {
return JSONTypes.ARRAY;
} else if (isBoolean(obj)) {
return JSONTypes.BOOLEAN;
} else if (isNumber(obj)) {
return JSONTypes.NUMBER;
} else if (isString(obj)) {
return JSONTypes.STRING;
} else if (isObject(obj)) {
return JSONTypes.OBJECT;
} else {
throw new JSONException("Unsupported type");
}
}
/**
* Creates a Map with all the properties of the JSONObject.
*/
public static Map getProperties(JSONObject jsonObject) {
Map properties = new HashMap();
for (Iterator keys = jsonObject.keys(); keys.hasNext();) {
String key = (String) keys.next();
properties.put(key, getTypeClass(jsonObject.get(key)));
}
return properties;
}
/**
* Returns the JSON type.
*/
public static Class getTypeClass(Object obj) {
if (isNull(obj)) {
return Object.class;
} else if (isArray(obj)) {
return List.class;
} else if (isBoolean(obj)) {
return Boolean.class;
} else if (isNumber(obj)) {
return Double.class;
} else if (isString(obj)) {
return String.class;
} else if (isObject(obj)) {
return Object.class;
} else {
throw new JSONException("Unsupported type");
}
}
/**
* Tests if obj is an array or Collection.
*/
public static boolean isArray(Object obj) {
if (obj != null && obj.getClass().isArray()) {
return true;
}
if (obj instanceof Collection) {
return true;
}
return false;
}
/**
* Tests if obj is a Boolean or primitive boolean
*/
public static boolean isBoolean(Object obj) {
if (obj instanceof Boolean) {
return true;
}
if (obj != null && obj.getClass() == Boolean.TYPE) {
return true;
}
return false;
}
public static boolean isJDK13() {
return javaVersion.indexOf("1.3") != -1;
}
/**
* Tests if the obj is a javaScript null.
*/
public static boolean isNull(Object obj) {
if (obj instanceof JSONObject) {
return ((JSONObject) obj).isNullObject();
}
return JSONNull.getInstance().equals(obj);
}
/**
* Tests if obj is a primitive number or wrapper.<br>
*/
public static boolean isNumber(Object obj) {
if ((obj != null && obj.getClass() == Byte.TYPE)
|| (obj != null && obj.getClass() == Short.TYPE)
|| (obj != null && obj.getClass() == Integer.TYPE)
|| (obj != null && obj.getClass() == Long.TYPE)
|| (obj != null && obj.getClass() == Float.TYPE)
|| (obj != null && obj.getClass() == Double.TYPE)) {
return true;
}
if ((obj instanceof Byte) || (obj instanceof Short)
|| (obj instanceof Integer) || (obj instanceof Long)
|| (obj instanceof Float) || (obj instanceof Double)) {
return true;
}
return false;
}
/**
* Tests if obj is not a boolean, number, string or array.
*/
public static boolean isObject(Object obj) {
return !isNumber(obj) && !isString(obj) && !isBoolean(obj)
&& !isArray(obj) || isNull(obj);
}
/**
* Tests if obj is a String or a char
*/
public static boolean isString(Object obj) {
if (obj instanceof String) {
return true;
}
if (obj instanceof Character) {
return true;
}
if (obj != null && obj.getClass() == Character.TYPE) {
return true;
}
return false;
}
/**
* Produce a string from a Number.
*
* @param n
* A Number
* @return A String.
* @throws JSONException
* If n is a non-finite number.
*/
public static String numberToString(Number n) {
if (n == null) {
throw new JSONException("Null pointer");
}
JSONUtils.testValidity(n);
// Shave off trailing zeros and decimal point, if possible.
String s = n.toString();
if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) {
while (s.endsWith("0")) {
s = s.substring(0, s.length() - 1);
}
if (s.endsWith(".")) {
s = s.substring(0, s.length() - 1);
}
}
return s;
}
public static String quote(String string) {
if (string == null || string.length() == 0) {
return "\"\"";
}
char b;
char c = 0;
int i;
int len = string.length();
StringBuffer sb = new StringBuffer(len + 4);
String t;
sb.append('"');
for (i = 0; i < len; i += 1) {
b = c;
c = string.charAt(i);
switch (c) {
case '\\':
case '"':
sb.append('\\');
sb.append(c);
break;
case '/':
if (b == '<') {
sb.append('\\');
}
sb.append(c);
break;
case '\b':
sb.append("\\b");
break;
case '\t':
sb.append("\\t");
break;
case '\n':
sb.append("\\n");
break;
case '\f':
sb.append("\\f");
break;
case '\r':
sb.append("\\r");
break;
default:
if (c < ' ') {
t = "000" + Integer.toHexString(c);
sb.append("\\u" + t.substring(t.length() - 4));
} else {
sb.append(c);
}
}
}
sb.append('"');
return sb.toString();
}
/**
* Throw an exception if the object is an NaN or infinite number.
*
* @param o
* The object to test.
* @throws JSONException
* If o is a non-finite number.
*/
public static void testValidity(Object o) {
if (o != null) {
if (o instanceof Double) {
if (((Double) o).isInfinite() || ((Double) o).isNaN()) {
throw new JSONException(
"JSON does not allow non-finite numbers");
}
} else if (o instanceof Float) {
if (((Float) o).isInfinite() || ((Float) o).isNaN()) {
throw new JSONException(
"JSON does not allow non-finite numbers.");
}
}
}
}
/**
* Converts an array of primitive chars to objects.<br>
* <p>
* <strong>This method is not in ArrayUtils. (commons-lang 2.1)</strong>
* </p>
* <p>
* This method returns <code>null</code> for a <code>null</code> input
* array.
* </p>
*
* @param array
* a <code>char</code> array
* @return a <code>Character</code> array, <code>null</code> if null array
* input
*/
public static Object[] toObject(char[] array) {
if (array == null) {
return null;
}
final Character[] result = new Character[array.length];
for (int i = 0; i < array.length; i++) {
result[i] = new Character(array[i]);
}
return result;
}
/**
* Make a JSON text of an Object value. If the object has an
* value.toJSONString() method, then that method will be used to produce the
* JSON text. The method is required to produce a strictly conforming text.
* If the object does not contain a toJSONString method (which is the most
* common case), then a text will be produced by the rules.
* <p>
* Warning: This method assumes that the data structure is acyclical.
*
* @param value
* The value to be serialized.
* @return a printable, displayable, transmittable representation of the
* object, beginning with <code>{</code> <small>(left
* brace)</small> and ending with <code>}</code> <small>(right
* brace)</small>.
* @throws JSONException
* If the value is or contains an invalid number.
*/
public static String valueToString(Object value) {
if (value == null || value.equals(null)) {
return "null";
}
if (value instanceof JSONString) {
Object o;
try {
o = ((JSONString) value).toJSONString();
} catch (Exception e) {
throw new JSONException(e);
}
if (o instanceof String) {
return (String) o;
}
throw new JSONException("Bad value from toJSONString: " + o);
}
if (value instanceof Number) {
return numberToString((Number) value);
}
if (value instanceof Boolean || value instanceof JSONObject
|| value instanceof JSONArray) {
return value.toString();
}
return quote(value.toString());
}
public static String valueToString(Object value, int indentFactor,
int indent) {
if (value == null || value.equals(null)) {
return "null";
}
try {
if (value instanceof JSONString) {
Object o = ((JSONString) value).toJSONString();
if (o instanceof String) {
return (String) o;
}
}
} catch (Exception e) {
/* forget about it */
}
if (value instanceof Number) {
return numberToString((Number) value);
}
if (value instanceof Boolean) {
return value.toString();
}
if (value instanceof JSONObject) {
return ((JSONObject) value).toString(indentFactor, indent);
}
if (value instanceof JSONArray) {
return ((JSONArray) value).toString(indentFactor, indent);
}
return quote(value.toString());
}
private JSONUtils() {
super();
}
}