All Downloads are FREE. Search and download functionalities are using the official Maven repository.

panda.bind.json.JsonObject Maven / Gradle / Ivy

Go to download

Panda Core is the core module of Panda Framework, it contains commonly used utility classes similar to apache-commons.

There is a newer version: 1.8.0
Show newest version
package panda.bind.json;

import java.io.InputStream;
import java.io.Reader;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import panda.io.stream.CharSequenceReader;

/**
 * A JsonObject is an unordered collection of name/value pairs. Its external
 * form is a string wrapped in curly braces with colons between the names and
 * values, and commas between the values and names. The internal form is an
 * object having get and opt methods for accessing
 * the values by name, and put methods for adding or replacing
 * values by name. The values can be any of these types: Boolean,
 * JSONArray, JsonObject, Number,
 * String, or the JsonObject.NULL object. A
 * JsonObject constructor can be used to convert an external form JSON text
 * into an internal form whose values can be retrieved with the
 * get and opt methods, or to convert values into a
 * JSON text using the put and toString methods. A
 * get method returns a value if one can be found, and throws an
 * exception if one cannot be found. An opt method returns a
 * default value instead of throwing an exception, and so is useful for
 * obtaining optional values.
 * 

* The generic get() and opt() methods return an * object, which you can cast or query for type. There are also typed * get and opt methods that do type checking and type * coercion for you. The opt methods differ from the get methods in that they * do not throw. Instead, they return a specified value, such as null. *

* The put methods add or replace values in an object. For * example, * *

 * myString = new JsonObject()
 *         .put("JSON", "Hello, World!").toString();
 * 
* * produces the string {"JSON": "Hello, World"}. *

* The texts produced by the toString methods strictly conform to * the JSON syntax rules. The constructors are more forgiving in the texts they * will accept: *

    *
  • An extra , (comma) may appear just * before the closing brace.
  • *
  • Strings may be quoted with ' (single * quote).
  • *
  • Strings do not need to be quoted at all if they do not begin with a * quote or single quote, and if they do not contain leading or trailing * spaces, and if they do not contain any of these characters: * { } [ ] / \ : , # and if they do not look like numbers and * if they are not the reserved words true, false, * or null.
  • *
* * @see JSON.org */ public class JsonObject extends LinkedHashMap { /** * serialVersionUID */ private static final long serialVersionUID = 1L; /** * Construct an empty JsonObject. */ public JsonObject() { super(); } /** * @param initialCapacity the initial capacity * @param loadFactor the load factor */ public JsonObject(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); } /** * @param initialCapacity the initial capacity */ public JsonObject(int initialCapacity) { super(initialCapacity); } /** * Construct a JsonObject from a subset of another JsonObject. An array of strings is used to * identify the keys that should be copied. Missing keys are ignored. * * @param jo A JsonObject. * @param names An array of strings. * @exception JsonException If a value is a non-finite number or if a name is duplicated. */ public JsonObject(JsonObject jo, String[] names) { for (int i = 0; i < names.length; i += 1) { this.set(names[i], jo.opt(names[i])); } } /** * Construct a JsonObject from a Map. * * @param map A map object that can be used to initialize the contents of the JsonObject. */ public JsonObject(Map map) { if (map != null) { for (java.util.Map.Entry en : map.entrySet()) { this.set(en.getKey().toString(), en.getValue()); } } } /** * Accumulate values under a key. It is similar to the put method except that if there is * already an object stored under the key then a JSONArray is stored under the key to hold all * of the accumulated values. If there is already a JSONArray, then the new value is appended to * it. In contrast, the put method replaces the previous value. If only one value is accumulated * that is not a JSONArray, then the result will be the same as using put. But if multiple * values are accumulated, then the result will be like append. * * @param key A key string. * @param value An object to be accumulated under the key. * @return this. * @throws JsonException If the value is an invalid number or if the key is null. */ public JsonObject accumulate(String key, Object value) throws JsonException { Object object = this.opt(key); if (object == null) { this.set(key, value); } else if (object instanceof JsonArray) { ((JsonArray)object).put(value); } else { this.put(key, new JsonArray().put(object).put(value)); } return this; } public JsonObject accumulateAll(Map map) throws JsonException { for (java.util.Map.Entry en : map.entrySet()) { accumulate(en.getKey(), en.getValue()); } return this; } /** * Append values to the array under a key. If the key does not exist in the JsonObject, then the * key is put in the JsonObject with its value being a JSONArray containing the value parameter. * If the key was already associated with a JSONArray, then the value parameter is appended to * it. * * @param key A key string. * @param value An object to be accumulated under the key. * @return this. * @throws JsonException If the key is null or if the current value associated with the key is * not a JSONArray. */ public JsonObject append(String key, Object value) throws JsonException { Object object = this.opt(key); if (object == null) { this.put(key, new JsonArray().put(value)); } else if (object instanceof JsonArray) { ((JsonArray)object).put(value); } else { throw new JsonException("JsonObject[" + key + "] is not a JSONArray."); } return this; } /** * Get the value object associated with a key. * * @param key A key string. * @return The object associated with the key. * @throws JsonException if the key is not found. */ public Object get(String key) throws JsonException { if (key == null) { throw new JsonException("Null key."); } Object object = super.get(key); if (object == null) { throw new JsonException("JsonObject[" + key + "] not found."); } return object; } /** * Get the boolean value associated with a key. * * @param key A key string. * @return The truth. * @throws JsonException if the value is not a Boolean. */ public boolean getBoolean(String key) throws JsonException { Object object = this.get(key); if (object instanceof Boolean) { return ((Boolean)object).booleanValue(); } throw new JsonException("JsonObject[" + key + "] is not a Boolean."); } /** * Get the double value associated with a key. * * @param key A key string. * @return The numeric value. * @throws JsonException if the key is not found or if the value is not a Number object */ public double getDouble(String key) throws JsonException { Object object = this.get(key); if (object instanceof Number) { return ((Number)object).doubleValue(); } throw new JsonException("JsonObject[" + key + "] is not a number."); } /** * Get the float value associated with a key. * * @param key A key string. * @return The numeric value. * @throws JsonException if the key is not found or if the value is not a Number object */ public float getFloat(String key) throws JsonException { Object object = this.get(key); if (object instanceof Number) { return ((Number)object).floatValue(); } throw new JsonException("JsonObject[" + key + "] is not a number."); } /** * Get the int value associated with a key. * * @param key A key string. * @return The integer value. * @throws JsonException if the key is not found or if the value is not a Number object */ public int getInt(String key) throws JsonException { Object object = this.get(key); if (object instanceof Number) { return ((Number)object).intValue(); } throw new JsonException("JsonObject[" + key + "] is not a number."); } /** * Get the JSONArray value associated with a key. * * @param key A key string. * @return A JSONArray which is the value. * @throws JsonException if the key is not found or if the value is not a JSONArray. */ public JsonArray getJsonArray(String key) throws JsonException { Object object = this.get(key); if (object instanceof JsonArray) { return (JsonArray)object; } throw new JsonException("JsonObject[" + key + "] is not a JsonArray."); } /** * Get the JsonObject value associated with a key. * * @param key A key string. * @return A JsonObject which is the value. * @throws JsonException if the key is not found or if the value is not a JsonObject. */ public JsonObject getJsonObject(String key) throws JsonException { Object object = this.get(key); if (object instanceof JsonObject) { return (JsonObject)object; } throw new JsonException("JsonObject[" + key + "] is not a JsonObject."); } /** * Get the long value associated with a key. * * @param key A key string. * @return The long value. * @throws JsonException if the key is not found or if the value is not a Number object */ public long getLong(String key) throws JsonException { Object object = this.get(key); if (object instanceof Number) { return ((Number)object).longValue(); } throw new JsonException("JsonObject[" + key + "] is not a number."); } /** * Get the string associated with a key. * * @param key A key string. * @return A string which is the value. * @throws JsonException if there is no string value for the key. */ public String getString(String key) throws JsonException { Object object = this.get(key); if (object instanceof String) { return (String)object; } throw new JsonException("JsonObject[" + key + "] not a string."); } /** * Determine if the JsonObject contains a specific key. * * @param key A key string. * @return true if the key exists in the JsonObject. */ public boolean has(String key) { return this.containsKey(key); } /** * Increment a property of a JsonObject. If there is no such property, create one with a value * of 1. If there is such a property, and if it is an Integer, Long, Double, or Float, then add * one to it. * * @param key A key string. * @return this. * @throws JsonException If there is already a property with this name that is not an Integer, * Long, Double, or Float. */ public JsonObject increment(String key) throws JsonException { Object value = this.opt(key); if (value == null) { this.set(key, 1); } else if (value instanceof Short) { this.set(key, ((Short)value).shortValue() + 1); } else if (value instanceof Integer) { this.set(key, ((Integer)value).intValue() + 1); } else if (value instanceof Long) { this.set(key, ((Long)value).longValue() + 1); } else if (value instanceof Double) { this.set(key, ((Double)value).doubleValue() + 1); } else if (value instanceof Float) { this.set(key, ((Float)value).floatValue() + 1); } else { throw new JsonException("Unable to increment [" + key + "]."); } return this; } /** * Determine if the value associated with the key is null or if there is no value. * * @param key A key string. * @return true if there is no value associated with the key or if the value is null. */ public boolean isNull(String key) { return null == this.opt(key); } /** * Get an enumeration of the keys of the JsonObject. * * @return An iterator of the keys. */ public Iterator keys() { return this.keySet().iterator(); } /** * Get the number of keys stored in the JsonObject. * * @return The number of keys in the JsonObject. */ public int length() { return this.size(); } /** * Produce a JSONArray containing the names of the elements of this JsonObject. * * @return A JSONArray containing the key strings, or null if the JsonObject is empty. */ public JsonArray names() { JsonArray ja = new JsonArray(); Iterator keys = this.keys(); while (keys.hasNext()) { ja.put(keys.next()); } return ja.length() == 0 ? null : ja; } /** * Get an optional value associated with a key. * * @param key A key string. * @return An object which is the value, or null if there is no value. */ public Object opt(String key) { if (key == null) { return null; } return super.get(key); } /** * Get an optional boolean associated with a key. It returns false if there is no such key, or * if the value is not Boolean.TRUE. * * @param key A key string. * @return The truth. */ public boolean optBoolean(String key) { return this.optBoolean(key, false); } /** * Get an optional boolean associated with a key. It returns the defaultValue if there is no * such key, or if it is not a Boolean. * * @param key A key string. * @param defaultValue The default. * @return The truth. */ public boolean optBoolean(String key, boolean defaultValue) { Object object = this.opt(key); if (object instanceof Boolean) { return ((Boolean)object).booleanValue(); } return defaultValue; } /** * Get an optional double associated with a key, or NaN if there is no such key or if its value * is not a number. * * @param key A string which is the key. * @return An object which is the value. */ public double optDouble(String key) { return this.optDouble(key, Double.NaN); } /** * Get an optional double associated with a key, or the defaultValue if there is no such key or * if its value is not a number. * * @param key A key string. * @param defaultValue The default. * @return An object which is the value. */ public double optDouble(String key, double defaultValue) { Object object = this.opt(key); if (object instanceof Number) { return ((Number)object).doubleValue(); } return defaultValue; } /** * Get an optional float associated with a key, or NaN if there is no such key or if its value * is not a number. * * @param key A string which is the key. * @return An object which is the value. */ public float optFloat(String key) { return this.optFloat(key, Float.NaN); } /** * Get an optional float associated with a key, or the defaultValue if there is no such key or * if its value is not a number. * * @param key A key string. * @param defaultValue The default. * @return An object which is the value. */ public float optFloat(String key, float defaultValue) { Object object = this.opt(key); if (object instanceof Number) { return ((Number)object).floatValue(); } return defaultValue; } /** * Get an optional int value associated with a key, or zero if there is no such key or if the * value is not a number. * * @param key A key string. * @return An object which is the value. */ public int optInt(String key) { return this.optInt(key, 0); } /** * Get an optional int value associated with a key, or the default if there is no such key or if * the value is not a number. * * @param key A key string. * @param defaultValue The default. * @return An object which is the value. */ public int optInt(String key, int defaultValue) { Object object = this.opt(key); if (object instanceof Number) { return ((Number)object).intValue(); } return defaultValue; } /** * Get an optional JSONArray associated with a key. It returns null if there is no such key, or * if its value is not a JSONArray. * * @param key A key string. * @return A JSONArray which is the value. */ public JsonArray optJsonArray(String key) { Object o = this.opt(key); return o instanceof JsonArray ? (JsonArray)o : null; } /** * Get an optional JsonObject associated with a key. It returns null if there is no such key, or * if its value is not a JsonObject. * * @param key A key string. * @return A JsonObject which is the value. */ public JsonObject optJsonObject(String key) { Object object = this.opt(key); return object instanceof JsonObject ? (JsonObject)object : null; } /** * Get an optional long value associated with a key, or zero if there is no such key or if the * value is not a number. * * @param key A key string. * @return An object which is the value. */ public long optLong(String key) { return this.optLong(key, 0); } /** * Get an optional long value associated with a key, or the default if there is no such key or * if the value is not a number. * * @param key A key string. * @param defaultValue The default. * @return An object which is the value. */ public long optLong(String key, long defaultValue) { Object object = this.opt(key); if (object instanceof Number) { return ((Number)object).longValue(); } return defaultValue; } /** * Get an optional string associated with a key. It returns null if there is no such * key or if the value is not a string. * * @param key A key string. * @return A string which is the value. */ public String optString(String key) { return optString(key, null); } /** * Get an optional string associated with a key. It returns the defaultValue if there is no such * key or if the value is not a string. * * @param key A key string. * @param defaultValue The default. * @return A string which is the value. */ public String optString(String key, String defaultValue) { Object object = this.opt(key); if (object instanceof String) { return (String)object; } return defaultValue; } /** * Put a key/boolean pair in the JsonObject. * * @param key A key string. * @param value A boolean which is the value. * @return this. * @throws JsonException If the key is null. */ public JsonObject set(String key, boolean value) throws JsonException { this.put(key, value ? Boolean.TRUE : Boolean.FALSE); return this; } /** * Put a key/value pair in the JsonObject, where the value will be a JSONArray which is produced * from a Collection. * * @param key A key string. * @param value A Collection value. * @return this. * @throws JsonException if the value is invalid */ public JsonObject set(String key, Collection value) throws JsonException { this.put(key, new JsonArray(value)); return this; } /** * Put a key/double pair in the JsonObject. * * @param key A key string. * @param value A double which is the value. * @return this. * @throws JsonException If the key is null or if the number is invalid. */ public JsonObject set(String key, double value) throws JsonException { this.put(key, new Double(value)); return this; } /** * Put a key/float pair in the JsonObject. * * @param key A key string. * @param value A float which is the value. * @return this. * @throws JsonException If the key is null or if the number is invalid. */ public JsonObject set(String key, float value) throws JsonException { this.put(key, new Float(value)); return this; } /** * Put a key/int pair in the JsonObject. * * @param key A key string. * @param value An int which is the value. * @return this. * @throws JsonException If the key is null. */ public JsonObject set(String key, int value) throws JsonException { this.put(key, new Integer(value)); return this; } /** * Put a key/long pair in the JsonObject. * * @param key A key string. * @param value A long which is the value. * @return this. * @throws JsonException If the key is null. */ public JsonObject set(String key, long value) throws JsonException { this.put(key, new Long(value)); return this; } /** * Put a key/value pair in the JsonObject, where the value will be a JsonObject which is * produced from a Map. * * @param key A key string. * @param value A Map value. * @return this. * @throws JsonException if the value is invalid */ public JsonObject set(String key, Map value) throws JsonException { this.put(key, new JsonObject(value)); return this; } /** * Put a key/value pair in the JsonObject. If the value is null, then the key will be removed * from the JsonObject if it is present. * * @param key A key string. * @param value An object which is the value. It should be of one of these types: Boolean, * Double, Integer, JSONArray, JsonObject, Long, String, or the JsonObject.NULL * object. * @return this. * @throws JsonException If the value is non-finite number or if the key is null. */ public JsonObject set(String key, Object value) throws JsonException { this.put(key, value); return this; } /** * Put a key/value pair in the JsonObject, but only if the key and the value are both non-null. * * @param key A key string. * @param value An object which is the value. It should be of one of these types: Boolean, * Double, Integer, JSONArray, JsonObject, Long, String, or the JsonObject.NULL * object. * @return this. * @throws JsonException If the value is a non-finite number. */ public JsonObject setOpt(String key, Object value) throws JsonException { if (key != null) { this.set(key, value); } return this; } /** * {@inheritDoc} */ @Override public Object put(String key, Object value) { if (key == null) { throw new NullPointerException("Null key."); } return super.put(key, wrap(value)); } /** * Wrap an object, if necessary. If the object is null, return the NULL object. If it is an * array or collection, wrap it in a JSONArray. If it is a map, wrap it in a JsonObject. If it * is a standard property (Double, String, et al) then it is already wrapped. Otherwise, if it * comes from one of the java packages, turn it into a string. And if it doesn't, try to wrap it * in a JsonObject. If the wrapping fails, then null is returned. * * @param object The object to wrap * @return The wrapped value */ protected static Object wrap(Object object) { if (object == null) { return null; } if (object instanceof JsonObject || object instanceof JsonArray || object instanceof String || object instanceof Character || object instanceof Boolean || object instanceof Number) { return object; } if (object instanceof Collection) { return new JsonArray((Collection)object); } if (object.getClass().isArray()) { return new JsonArray(object); } if (object instanceof Map) { return new JsonObject((Map)object); } throw new JsonException("Invalid argument: " + object.getClass()); } /** * {@inheritDoc} */ public String toString() { return Jsons.toJson(this); } public String toString(boolean pretty) { return Jsons.toJson(this, pretty); } public String toString(int indent) { return Jsons.toJson(this, indent); } public static JsonObject fromJson(InputStream json) { return Jsons.fromJson(json, JsonObject.class); } public static JsonObject fromJson(InputStream json, String encoding) { return Jsons.fromJson(json, encoding, JsonObject.class); } public static JsonObject fromJson(Reader json) { return Jsons.fromJson(json, JsonObject.class); } public static JsonObject fromJson(CharSequence json) { if (json == null) { return null; } JsonTokener jt = new JsonTokener(new CharSequenceReader(json)); char c = jt.nextClean(); if (c != '{') { json = "{" + json + "}"; } return Jsons.fromJson(json, JsonObject.class); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy