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

kong.unirest.core.json.JSONObject Maven / Gradle / Ivy

There is a newer version: 4.4.5
Show newest version
/**
 * The MIT License
 *
 * Copyright for portions of unirest-java are held by Kong Inc (c) 2013.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package kong.unirest.core.json;


import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.function.Supplier;

import static java.util.Objects.requireNonNull;

/**
 * https://json.org/
 * https://tools.ietf.org/html/rfc7159#section-4
 * represents a JSON Object
 */
public class JSONObject extends JSONElement {

    public static final Object NULL = new NullObject();
    private transient final JsonEngine.Object obj;

    /**
     * https://tools.ietf.org/html/rfc7159#section-4
     * @param string a json object string
     */
    public JSONObject(String string) {
        this(CoreFactory.getCore().newEngineObject(string));
    }

    /**
     * construct using a map
     * @param map a map representing the elements of a JSON Object
     */
    public JSONObject(Map map) {
        this(toTree(map));
    }

    /**
     * construct using an object. The Properties of the JSONObject
     * will be taken from getters and properties of the object
     * @param object the object to turn into a JSONObject
     */
    public JSONObject(Object object) {
        this(toTree(object));
    }

    /**
     * an empty JSON object
     */
    public JSONObject() {
        this(CoreFactory.getCore().newEngineObject());
    }


    JSONObject(JsonEngine.Element jsonElement) {
        super(jsonElement);
        this.obj = jsonElement.getAsJsonObject();
    }

    /**
     * quite escape a string
     * @param s a string
     * @return a quoted string
     */
    public static String quote(String s) {
        return CoreFactory.getCore().quote(s);
    }

    /**
     * quite escape a string
     * @param s a string
     * @param writer a writer to write the string to
     * @return the same writer
     * @throws IOException if some IO thing goes wrong
     */
    public static Writer quote(String s, Writer writer) throws IOException {
        writer.write(quote(s));
        return writer;
    }

    /**
     * convert a primitive JSON type in a string (bool, number, null) to its primitive type
     * all decimal types will become doubles
     * @param str a string
     * @return a object
     */
    public static Object stringToValue(String str) {
        if(str.contentEquals("null")){
            return NULL;
        } else if (str.equalsIgnoreCase("true")){
            return true;
        }else if (str.equalsIgnoreCase("false")) {
            return false;
        }
        if(str.contains(".")){
            return Double.valueOf(str);
        } else {
            return Integer.valueOf(str);
        }
    }

    /**
     * Convert an object to a object that can be added to a JSONElement
     *    If the object is null return the NULL object
     *    If the object is primitive return the original object
     *    If the object is a map convert it to a JSONObject
     *    If the object is a Collection or array return a JSONArray
     *    If the object is anything else return a empty JSON Object
     * @param obj the object
     * @return another object suitable for use as JSON
     */
    public static Object wrap(Object obj) {
        if(obj == null || obj.equals(NULL)){
            return NULL;
        }
        if(isPrimitive(obj)){
            return obj;
        }
        if(obj instanceof Map){
            return new JSONObject((Map)obj);
        }
        if(obj instanceof Collection){
            return new JSONArray((Collection)obj);
        }
        if(obj.getClass().isArray()){
            return wrapArray(obj);
        }
        return new JSONObject();
    }

    private static JSONArray wrapArray(Object obj) {
        JSONArray array = new JSONArray();
        int length = Array.getLength(obj);
        for (int i = 0; i < length; i ++) {
            Object arrayElement = Array.get(obj, i);
            array.put(arrayElement);
        }
        return array;
    }

    /**
     * convert a primitive number to a string
     * if the double can be converted to a whole number the decimal will be dropped
     * @param d a double
     * @return a string representation of the double
     */
    public static String doubleToString(double d) {
        if (d == Math.floor(d) && !Double.isInfinite(d)) {
            return Integer.toString((int)d);
        }
        return Double.toString(d);
    }

    /**
     * Convert a number to a string
     * @param number the number to convert
     * @return a string representation of that number
     * @throws JSONException if something goes wrong
     */
    public static String numberToString(Number number) throws JSONException {
        return String.valueOf(number);
    }

    /**
     * Converts an object to a JSON String
     * @param o any object
     * @return a json string
     * @throws JSONException if something goes wrong
     */
    public static String valueToString(Object o) throws JSONException {
        if(o == null){
            return "null";
        }
        if(o instanceof JSONElement){
            return o.toString();
        }
        return CoreFactory.getCore().quote(o);
    }

    /**
     * get all of the keys of a JSONObject
     * @param jsonObject a JSONObject
     * @return a String[] of the objects keys
     */
    public static String[] getNames(JSONObject jsonObject) {
        if(jsonObject == null || jsonObject.isEmpty()){
            return null;
        }
        List list = jsonObject.names().toList();
        return list.toArray(new String[list.size()]);
    }

    /**
     * get all of the keys of a JSONObject or a empty array if not an JSONObject
     * @param o a Object
     * @return a String[] of the objects keys
     */
    public static String[] getNames(Object o) {
        if(o instanceof JSONObject){
            return getNames((JSONObject)o);
        }
        return new String[]{};
    }

    JsonEngine.Element asElement() {
        return obj;
    }

    /**
     * @return the object as a JSON string with no formatting
     */
    @Override
    public String toString() {
        return toJson(obj);
    }

    /**
     * render the  object as a JSON String
     * @param i (ignored due to limitations  in gson which uses a hardcoded indentation)
     * @return a JSON  String
     */
    public String toString(int i)  throws JSONException {
        return toPrettyJson(obj);
    }

    /**
     * indicates if a JSONObject has the same elements as another JSONObject
     * @param o another object
     * @return a bool
     */
    public boolean similar(Object o) {
        if (!(o instanceof JSONObject)) {
            return false;
        }
        JSONObject cst = (JSONObject) o;
        return this.obj.equals(cst.obj);
    }


    /**
     * @param key the key element to operate on
     * @return indicates that the structure has this key
     */
    public boolean has(String key) {
        return this.obj.has(key);
    }

    /**
     * @return number of keys in the structure
     */
    public int length() {
        return this.obj.size();
    }

    /**
     * get and element by key as its native object
     * @param key the key element to operate on
     * @return the object, this could be an object, array or primitive
     * @throws JSONException if the key does not exist
     */
    public Object get(String key) throws JSONException {
        JsonEngine.Element property = getProperty(key);
        return MAPPER.apply(property);
    }

    /**
     * get the element as a JSONObject
     * @param key the key element to operate on
     * @return the element as a JSONObject
     * @throws JSONException  if it is not a object or the key does not exist
     */
    public JSONObject getJSONObject(String key) throws JSONException {
        try {
            return new JSONObject(getProperty(key).getAsJsonObject());
        } catch (IllegalStateException e) {
            throw new JSONException("JSONObject[\"%s\"] is not a JSONObject.", key);
        }
    }

    /**
     * get the element as a JSONObject
     * @param key the key element to operate on
     * @return an object or null if it is not an object or the key does not exist
     */
    public JSONObject optJSONObject(String key) {
        return getOrDefault(() -> getJSONObject(key), null);
    }

    /**
     * get the element as a JSONArray
     * @param key the key element to operate on
     * @return the element as a JSONArray
     * @throws JSONException  if it is not an array or the key does not exist
     */
    public JSONArray getJSONArray(String key) throws JSONException {
        try {
            return new JSONArray(getProperty(key).getAsJsonArray());
        } catch (IllegalStateException e) {
            throw new JSONException("JSONObject[\"%s\"] is not a JSONArray.", key);
        }
    }

    /**
     * optionally get the element as a JSONArray
     * @param key the key element to operate on
     * @return the element as a JSONArray or null if it doesn't exist or is not an array
     */
    public JSONArray optJSONArray(String key) {
        return getOrDefault(() -> getJSONArray(key), null);
    }

    /**
     * get a element property as a string
     * @param key the key element to operate on
     * @return a string representation of the value
     * @throws JSONException if the key does not exist
     */
    public String getString(String key) throws JSONException {
        return getProperty(key).getAsString();
    }

    /**
     * get a element property as a string
     * @param key the key element to operate on
     * @return a string representation of the value or null of it doesn't exist
     */
    public String optString(String key) {
        return optString(key, "");
    }

    /**
     * get a element property as a string
     * @param key the key element to operate on
     * @param defaultValue default value if the key does not exist or cannot be converted to a string
     * @return a string representation of the value or default value
     */
    public String optString(String key, String defaultValue) {
        return getOrDefault(() -> getString(key), defaultValue);
    }

    /**
     * get the value as a double
     * @param key the key element to operate on
     * @return the value
     * @throws JSONException if the object is not a number or does not exist
     */
    public double getDouble(String key) throws JSONException {
        return tryNumber(() -> getProperty(key).getAsDouble(), key);
    }

    /**
     * the value as double or NaN
     * @param key the key element to operate on
     * @return the value as a double or NaN if the key doesn't exist or the value is not a number
     */
    public double optDouble(String key) {
        return optDouble(key, Double.NaN);
    }

    /**
     * get the  value as a double or default value
     * @param key the key element to operate on
     * @param defaultValue the default value to return if the index or value type are not valid
     * @return return value as double or a default value if value is not viable
     */
    public double optDouble(String key, double defaultValue) {
        return getOrDefault(() -> getDouble(key), defaultValue);
    }

    /**
     * get the value as a float
     * @param key the key element to operate on
     * @return the value
     * @throws JSONException if the object is not a number or does not exist
     */
    public float getFloat(String key) throws JSONException {
        return tryNumber(() -> getProperty(key).getAsFloat(), key);
    }

    /**
     * the value as double or NaN
     * @param key the key element to operate on
     * @return the value as a float or NaN if the key doesn't exist or the value is not a number
     */
    public float optFloat(String key) {
        return optFloat(key, Float.NaN);
    }

    /**
     * get the  value as a float or default value
     * @param key the key element to operate on
     * @param defaultValue the default value to return if the index or value type are not valid
     * @return return value as double or a default value if value is not viable
     */
    public float optFloat(String key, float defaultValue) {
        return getOrDefault(() -> getFloat(key), defaultValue);
    }

    /**
     * get the value as a long
     * @param key the key element to operate on
     * @return the value
     * @throws JSONException if the object is not a number or does not exist
     */
    public long getLong(String key) throws JSONException {
        return tryNumber(() -> getProperty(key).getAsLong(), key);
    }

    /**
     * the value as long or NaN
     * @param key the key element to operate on
     * @return the value as a long or NaN if the key doesn't exist or the value is not a number
     */
    public long optLong(String key) {
        return optLong(key, 0L);
    }

    /**
     * get the  value as a long or default value
     * @param key the key element to operate on
     * @param defaultValue the default value to return if the index or value type are not valid
     * @return return value as long or a default value if value is not viable
     */
    public long optLong(String key, long defaultValue) {
        return getOrDefault(() -> getLong(key), defaultValue);
    }

    /**
     * get an element property as a Number
     * @param key the key element to operate on
     * @return the element as a Number if it can be cast to one.
     * @throws JSONException  if it is not a number or the key does not exist
     */
    public Number getNumber(String key) throws JSONException {
        return tryNumber(() -> getProperty(key).getAsInt(), key);
    }

    /**
     * the value as int or 0
     * @param key the key element to operate on
     * @return the value as a int or 0 if the key doesn't exist or the value is not a number
     */
    public Number optNumber(String key) {
        return optNumber(key, 0);
    }

    /**
     * get the value as a Number or default value
     * @param key the key element to operate on
     * @param defaultValue the default value to return if the index or value type are not valid
     * @return return value as long or a default value if value is not viable
     */
    public Number optNumber(String key, Number defaultValue) {
        return getOrDefault(() -> getNumber(key), defaultValue);
    }

    /**
     * get an element property as a int
     * @param key the key element to operate on
     * @return the element as a int if it can be cast to one.
     * @throws JSONException  if it is not a number or the key does not exist
     */
    public int getInt(String key) throws JSONException {
        return tryNumber(() -> getProperty(key).getAsInt(), key);
    }

    /**
     * the value as int or NaN
     * @param key the key element to operate on
     * @return the value as a int or 0 if the key doesn't exist or the value is not a number
     */
    public int optInt(String key) {
        return optInt(key, 0);
    }

    /**
     * get the  value as a int or default value
     * @param key the key element to operate on
     * @param defaultValue the default value to return if the index or value type are not valid
     * @return return value as long or a default value if value is not viable
     */
    public int optInt(String key, int defaultValue) {
        return getOrDefault(() -> getInt(key), defaultValue);
    }

    /**
     * get an element property as a BigInteger
     * @param key the key element to operate on
     * @return the element as a BigInteger if it can be cast to one.
     * @throws JSONException  if it is not a number or the key does not exist
     */
    public BigInteger getBigInteger(String key) throws JSONException {
        return tryNumber(() -> getProperty(key).getAsBigInteger(), key);
    }

    /**
     * get the  value as a BigInteger or default value
     * @param key the key element to operate on
     * @param defaultValue the default value to return if the index or value type are not valid
     * @return return value as BigInteger or a default value if value is not viable
     */
    public BigInteger optBigInteger(String key, BigInteger defaultValue) {
        return getOrDefault(() -> getBigInteger(key), defaultValue);
    }

    /**
     * get an element property as a BigDecimal
     * @param key the key element to operate on
     * @return the element as a BigInteger if it can be cast to one.
     * @throws JSONException  if it is not a number or the key does not exist
     */
    public BigDecimal getBigDecimal(String key) throws JSONException {
        return tryNumber(() -> getProperty(key).getAsBigDecimal(), key);
    }

    /**
     * get the  value as a BigDecimal or default value
     * @param key the key element to operate on
     * @param defaultValue the default value to return if the index or value type are not valid
     * @return return value as BigDecimal or a default value if value is not viable
     */
    public BigDecimal optBigDecimal(String key, BigDecimal defaultValue) {
        return getOrDefault(() -> getBigDecimal(key), defaultValue);
    }


    /**
     * gets a boolean value at a particular key
     * @param key the key
     * @return a boolean
     * @throws JSONException if the element does not exist or is not a boolean
     */
    public boolean getBoolean(String key) throws JSONException {
        JsonEngine.Element e = getProperty(key);
        if (!e.isJsonPrimitive() || !e.getAsJsonPrimitive().isBoolean()) {
            throw new JSONException("JSONObject[\"%s\"] is not a boolean.", key);
        }
        return e.getAsBoolean();
    }

    /**
     * gets a boolean value at a particular key or false as default
     * @param key the key
     * @return a boolean
     */
    public boolean optBoolean(String key) {
        return optBoolean(key, false);
    }

    /**
     * gets a boolean value at a particular key or a default value
     * @param key the key
     * @param defaultValue a default value if the key does not exist or value is not a boolean
     * @return a boolean
     */
    public boolean optBoolean(String key, boolean defaultValue) {
        return getOrDefault(() -> getBoolean(key), defaultValue);
    }

    /**
     * get element as a enum value
     * @param  the type of enum you want
     * @param enumClass a enum class
     * @param key the key element to operate on
     * @return the value as a enum of T
     * @throws JSONException  if it does not map to a enum of T or the key does not exist
     */
    public > T getEnum(Class enumClass, String key) throws JSONException {
        try {
            String v = getProperty(key).getAsString();
            return Enum.valueOf(enumClass, v);
        } catch (IllegalArgumentException e) {
            throw new JSONException("JSONObject[\"%s\"] is not an enum of type \"%s\".", key, enumClass.getSimpleName());
        }
    }

    /**
     * get element as a enum value or null if the value cannot be mapped
     * @param  the type of enum you want
     * @param enumClass a enum class
     * @param key the key element to operate on
     * @return the value as a enum of T
     */
    public > T optEnum(Class enumClass, String key) {
        return optEnum(enumClass, key, null);
    }

    /**
     * get element as a enum value or a default value if the value cannot be mapped
     * @param  the type of enum you want
     * @param enumClass a enum class
     * @param key the key element to operate on
     * @param defaultValue the default value to return if the index or value type are not valid
     * @return the value as a enum of T
     */
    public > T optEnum(Class enumClass, String key, T defaultValue) {
        return getOrDefault(() -> getEnum(enumClass, key), defaultValue);
    }

    /**
     * put a JSONObject at a particular key
     * @param key the key element to operate on
     * @param object JSONObject
     * @return this JSONObject
     */
    public JSONObject put(String key, JSONObject object) throws JSONException {
        obj.add(key, object.obj);
        return this;
    }

    /**
     * put a JSONArray at a particular key
     * @param key the key element to operate on
     * @param array JSONArray
     * @return this JSONObject
     */
    public JSONObject put(String key, JSONArray array) throws JSONException {
        obj.add(key, array.getArray());
        return this;
    }

    /**
     * put a boolean at a particular key
     * @param key the key element to operate on
     * @param value the boolean value to put
     * @return this JSONObject
     * @throws JSONException if something goes wrong
     */
    public JSONObject put(String key, boolean value) throws JSONException {
        obj.addProperty(key, value);
        return this;
    }

    /**
     * put a Number at a particular key
     * @param key the key element to operate on
     * @param value Number
     * @return this JSONObject
     */
    public JSONObject put(String key, Number value) throws JSONException {
        this.obj.addProperty(key, value);
        return this;
    }

    /**
     * put a double at a particular key
     * @param key the key element to operate on
     * @param value double
     * @return this JSONObject
     * @throws JSONException if something goes wrong
     */
    public JSONObject put(String key, double value) throws JSONException {
        this.obj.addProperty(key, value);
        return this;
    }

    /**
     * put a float at a particular key
     * @param key the key element to operate on
     * @param value float
     * @return this JSONObject
     * @throws JSONException if something goes wrong
     */
    public JSONObject put(String key, float value) throws JSONException {
        this.obj.addProperty(key, value);
        return this;
    }

    /**
     * put a long at a particular key
     * @param key the key element to operate on
     * @param value long
     * @return this JSONObject
     * @throws JSONException if something goes wrong
     */
    public JSONObject put(String key, long value) throws JSONException {
        this.obj.addProperty(key, value);
        return this;
    }

    /**
     * put a int at a particular key
     * @param key the key element to operate on
     * @param value int
     * @return this JSONObject
     * @throws JSONException if something goes wrong
     */
    public JSONObject put(String key, int value) throws JSONException {
        this.obj.addProperty(key, value);
        return this;
    }

    /**
     * put a String at a particular key
     * @param key the key element to operate on
     * @param value Number
     * @return this JSONObject
     */
    public JSONObject put(String key, String value) throws JSONException {
        Objects.requireNonNull(key, "key == null");
        this.obj.addProperty(key, value);
        return this;
    }

    /**
     * put a Collection as a JSONArray at a particular key
     * @param key the key element to operate on
     * @param value Collection
     * @return this JSONObject
     */
    public JSONObject put(String key, Collection value) throws JSONException {
        this.put(key, new JSONArray(value));
        return this;
    }

    /**
     * put a Collection as a JSONArray at a particular key
     * @param key the key element to operate on
     * @param value Collection
     * @return this JSONObject
     */
    public JSONObject put(String key, Map value) throws JSONException {
        this.put(key, new JSONObject(value));
        return this;
    }

    /**
     * put a enum at a particular key. The enum will be stored as a string by name
     * @param  a type of enum
     * @param key the key element to operate on
     * @param enumvalue a enum
     * @return this JSONObject
     * @throws JSONException if something goes wrong
     */
    public > JSONObject put(String key, T enumvalue) throws JSONException {
        obj.add(key, enumvalue);
        return this;
    }

    /**
     * remove a element by key name
     * @param key the key element to operate on
     * @return the object value that was removed
     */
    public Object remove(String key) {
        if(!has(key)){
            return null;
        }
        Object o = get(key);
        obj.remove(key);
        return o;
    }

    /**
     * Add a element to a JSONArray in a element. If the value is not
     * already an array it will be made one with the original value as the first element
     * @param key the key element to operate on
     * @param additionalValue value to append to the array
     * @return this JSONObject
     */
    public JSONObject accumulate(String key, Object additionalValue) throws JSONException {
        requireNonNull(key, "Null key.");
        if (!obj.has(key)) {
            return this;
        }
        Object existing = get(key);
        if (existing instanceof JSONArray) {
            ((JSONArray) existing).put(additionalValue);
            put(key, (JSONArray) existing);
        } else {
            JSONArray a = new JSONArray();
            a.put(existing);
            a.put(additionalValue);
            put(key, a);
        }
        return  this;
    }

    /**
     * appends to an existing array
     * @param key the key element to operate on
     * @param value the object to put
     * @throws JSONException if the value exists and is not an array
     * @return this JSONObject
     */
    public JSONObject append(String key, Object value) throws JSONException {
        requireNonNull(key, "Null key.");
        if (has(key)) {
            JSONArray arr = getJSONArray(key);
            arr.put(value);
            put(key, arr);
        } else {
            JSONArray arr = new JSONArray();
            arr.put(value);
            put(key, arr);
        }
        return this;
    }

    /**
     * increments a numeric value by 1, or creates it with a value of 1 if
     * it does not exist.
     * @param key the key element to operate on
     * @return this JSONObject
     * @throws JSONException if something goes wrong
     */
    public JSONObject increment(String key) throws JSONException {
        if (!has(key)) {
            put(key, 1);
        } else {
            Object n = get(key);
            if (!(n instanceof Number)) {
                throw new JSONException("");
            } else if (n instanceof Integer) {
                put(key, ((Integer) n) + 1);
            } else if (n instanceof Double) {
                put(key, ((Double) n) + 1);
            }
        }
        return this;
    }

    /**
     * put a value to a key only if it does not exist
     * @param key the key element to operate on
     * @param value the object to put
     * @return this JSONObject
     * @throws JSONException if the key exists.
     */
    public JSONObject putOnce(String key, Object value) throws JSONException {
        if(has(key)){
            throw new JSONException("Duplicate key \"foo\"");
        }
        return put(key, value);
    }

    /**
     * put an object to a key.
     * the value must be a JSON type
     * @param key the key element to operate on
     * @param value the  object to put
     * @return this JSONObject
     * @throws JSONException if something goes wrong
     */
    public JSONObject put(String key, Object value) throws JSONException {
        if(value == null){
            put(key, (String) value);
        } else if (value instanceof Number){
            put(key, (Number) value);
        } else if (value instanceof Boolean){
            put(key, (boolean) value);
        } else if (value instanceof JSONArray) {
            put(key, (JSONArray) value);
        } else if (value instanceof JSONObject) {
            put(key, (JSONObject) value);
        } else if (value instanceof Map){
            put(key, (Map) value);
        } else if (value instanceof Collection) {
            put(key, (Collection) value);
        } else if (value.getClass().isArray()){
            put(key, wrapArray(value));
        } else {
            put(key, String.valueOf(value));
        }
        return this;
    }

    /**
     * optional put a value at a key as long as both they key and value are not null
     * otherwise it does nothing
     * @param key the key element to operate on
     * @param value the  object to put
     * @return this JSONObject
     * @throws JSONException if something goes wrong
     */
    public JSONObject putOpt(String key, Object value) throws JSONException {
        if(key == null || value == null){
            return this;
        }
        return put(key, value);
    }

    /**
     * get all the keys as a set
     * @return a set of keys
     */
    public Set keySet() {
        return obj.keySet();
    }

    /**
     * get a iterator for the keyset
     * @return a Iterator of keys
     */
    public Iterator keys() {
        return obj.keySet().iterator();
    }

    /**
     * converts this object to a map
     * @return this object as a map
     */
    public Map toMap() {
        return toMap(obj);
    }

    /**
     * get the key names as a JSONArray
     * @return a JSONArray of keys
     */
    public JSONArray names() {
        return new JSONArray(keySet());
    }

    /**
     * creates an  array of the values for they keys you provide
     * @param names a list of keys you want an array for
     * @return a JSONArray of values or null of the array is null or empty
     * @throws JSONException if something goes wrong
     */
    public JSONArray toJSONArray(JSONArray names) throws JSONException {
        if(names == null || names.isEmpty()){
            return null;
        }
        JSONArray array = new JSONArray();
        for(Object name : names){
            array.put(opt(String.valueOf(name)));
        }
        return array;
    }

    private JsonEngine.Element getProperty(String key) {
        if (!obj.has(key)) {
            throw new JSONException("JSONObject[\"%s\"] not found.", key);
        }
        return obj.get(key);
    }

    private  T tryNumber(Supplier supplier, String key) {
        try {
            return supplier.get();
        } catch (NumberFormatException e) {
            throw new JSONException("JSONObject[\"%s\"] is not a number.", key);
        }
    }

    private  T getOrDefault(Supplier supplier, T defaultValue) {
        try {
            return supplier.get();
        } catch (Exception e) {
            return defaultValue;
        }
    }

    @Override
    public boolean equals(Object other) {
        return this.similar(other);
    }

    @Override
    public int hashCode() {
        return obj.hashCode();
    }

    /**
     * optionally return the object or null if it doesn't exist
     * @param key the key
     * @return the object at the key or null
     */
    public Object opt(String key) {
        try{
            return get(key);
        }catch (JSONException e){
            return null;
        }
    }

    /**
     * @return boolean if the object is empty
     */
    public boolean isEmpty() {
        return obj.size() == 0;
    }

    /**
     * indicate if the key does not exist or its value is null
     * @param key the key
     * @return a boolean indicating null
     */
    public boolean isNull(String key) {
        return !has(key) || get(key) == null;
    }


    private static boolean isPrimitive(Object o){
        return (o instanceof String
                || o instanceof Number
                || o instanceof Boolean);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy