PageRenderTime 285ms CodeModel.GetById 32ms app.highlight 214ms RepoModel.GetById 8ms app.codeStats 1ms

/src/org/json/JSONObject.java

http://github.com/nddrylliog/ooc
Java | 1575 lines | 911 code | 132 blank | 532 comment | 121 complexity | 94b1ecd8fe8f8fd2be5cae09338ecc0b MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1package org.json;
   2
   3/*
   4Copyright (c) 2002 JSON.org
   5
   6Permission is hereby granted, free of charge, to any person obtaining a copy
   7of this software and associated documentation files (the "Software"), to deal
   8in the Software without restriction, including without limitation the rights
   9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10copies of the Software, and to permit persons to whom the Software is
  11furnished to do so, subject to the following conditions:
  12
  13The above copyright notice and this permission notice shall be included in all
  14copies or substantial portions of the Software.
  15
  16The Software shall be used for Good, not Evil.
  17
  18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24SOFTWARE.
  25*/
  26
  27import java.io.IOException;
  28import java.io.Writer;
  29import java.lang.reflect.Field;
  30import java.lang.reflect.Method;
  31import java.lang.reflect.Modifier;
  32import java.util.Collection;
  33import java.util.HashMap;
  34import java.util.Iterator;
  35import java.util.Map;
  36import java.util.TreeSet;
  37
  38/**
  39 * A JSONObject is an unordered collection of name/value pairs. Its
  40 * external form is a string wrapped in curly braces with colons between the
  41 * names and values, and commas between the values and names. The internal form
  42 * is an object having <code>get</code> and <code>opt</code> methods for
  43 * accessing the values by name, and <code>put</code> methods for adding or
  44 * replacing values by name. The values can be any of these types:
  45 * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
  46 * <code>Number</code>, <code>String</code>, or the <code>JSONObject.NULL</code>
  47 * object. A JSONObject constructor can be used to convert an external form
  48 * JSON text into an internal form whose values can be retrieved with the
  49 * <code>get</code> and <code>opt</code> methods, or to convert values into a
  50 * JSON text using the <code>put</code> and <code>toString</code> methods.
  51 * A <code>get</code> method returns a value if one can be found, and throws an
  52 * exception if one cannot be found. An <code>opt</code> method returns a
  53 * default value instead of throwing an exception, and so is useful for
  54 * obtaining optional values.
  55 * <p>
  56 * The generic <code>get()</code> and <code>opt()</code> methods return an
  57 * object, which you can cast or query for type. There are also typed
  58 * <code>get</code> and <code>opt</code> methods that do type checking and type
  59 * coercion for you.
  60 * <p>
  61 * The <code>put</code> methods adds values to an object. For example, <pre>
  62 *     myString = new JSONObject().put("JSON", "Hello, World!").toString();</pre>
  63 * produces the string <code>{"JSON": "Hello, World"}</code>.
  64 * <p>
  65 * The texts produced by the <code>toString</code> methods strictly conform to
  66 * the JSON syntax rules.
  67 * The constructors are more forgiving in the texts they will accept:
  68 * <ul>
  69 * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just
  70 *     before the closing brace.</li>
  71 * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single
  72 *     quote)</small>.</li>
  73 * <li>Strings do not need to be quoted at all if they do not begin with a quote
  74 *     or single quote, and if they do not contain leading or trailing spaces,
  75 *     and if they do not contain any of these characters:
  76 *     <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers
  77 *     and if they are not the reserved words <code>true</code>,
  78 *     <code>false</code>, or <code>null</code>.</li>
  79 * <li>Keys can be followed by <code>=</code> or <code>=></code> as well as
  80 *     by <code>:</code>.</li>
  81 * <li>Values can be followed by <code>;</code> <small>(semicolon)</small> as
  82 *     well as by <code>,</code> <small>(comma)</small>.</li>
  83 * <li>Numbers may have the <code>0-</code> <small>(octal)</small> or
  84 *     <code>0x-</code> <small>(hex)</small> prefix.</li>
  85 * </ul>
  86 * @author JSON.org
  87 * @version 2009-03-06
  88 */
  89public class JSONObject {
  90
  91    /**
  92     * JSONObject.NULL is equivalent to the value that JavaScript calls null,
  93     * whilst Java's null is equivalent to the value that JavaScript calls
  94     * undefined.
  95     */
  96     static final class Null {
  97
  98        /**
  99         * There is only intended to be a single instance of the NULL object,
 100         * so the clone method returns itself.
 101         * @return     NULL.
 102         */
 103    	@Override
 104        protected final Object clone() {
 105            return this;
 106        }
 107
 108
 109        /**
 110         * A Null object is equal to the null value and to itself.
 111         * @param object    An object to test for nullness.
 112         * @return true if the object parameter is the JSONObject.NULL object
 113         *  or null.
 114         */
 115    	@Override
 116        public boolean equals(Object object) {
 117            return object == null || object == this;
 118        }
 119
 120
 121        /**
 122         * Get the "null" string value.
 123         * @return The string "null".
 124         */
 125        @Override
 126		public String toString() {
 127            return "null";
 128        }
 129    }
 130
 131
 132    /**
 133     * The map where the JSONObject's properties are kept.
 134     */
 135    private Map<Object, Object> map;
 136
 137
 138    /**
 139     * It is sometimes more convenient and less ambiguous to have a
 140     * <code>NULL</code> object than to use Java's <code>null</code> value.
 141     * <code>JSONObject.NULL.equals(null)</code> returns <code>true</code>.
 142     * <code>JSONObject.NULL.toString()</code> returns <code>"null"</code>.
 143     */
 144    public static final Object NULL = new Null();
 145
 146
 147    /**
 148     * Construct an empty JSONObject.
 149     */
 150    public JSONObject() {
 151        this.map = new HashMap<Object, Object>();
 152    }
 153
 154
 155    /**
 156     * Construct a JSONObject from a subset of another JSONObject.
 157     * An array of strings is used to identify the keys that should be copied.
 158     * Missing keys are ignored.
 159     * @param jo A JSONObject.
 160     * @param names An array of strings.
 161     * @exception JSONException If a value is a non-finite number or if a name is duplicated.
 162     */
 163    public JSONObject(JSONObject jo, String[] names) throws JSONException {
 164        this();
 165        for (int i = 0; i < names.length; i += 1) {
 166            putOnce(names[i], jo.opt(names[i]));
 167        }
 168    }
 169
 170
 171    /**
 172     * Construct a JSONObject from a JSONTokener.
 173     * @param x A JSONTokener object containing the source string.
 174     * @throws JSONException If there is a syntax error in the source string
 175     *  or a duplicated key.
 176     */
 177    public JSONObject(JSONTokener x) throws JSONException {
 178        this();
 179        char c;
 180        String key;
 181
 182        if (x.nextClean() != '{') {
 183            throw x.syntaxError("A JSONObject text must begin with '{'");
 184        }
 185        for (;;) {
 186            c = x.nextClean();
 187            switch (c) {
 188            case 0:
 189                throw x.syntaxError("A JSONObject text must end with '}'");
 190            case '}':
 191                return;
 192            default:
 193                x.back();
 194                key = x.nextValue().toString();
 195            }
 196
 197            /*
 198             * The key is followed by ':'. We will also tolerate '=' or '=>'.
 199             */
 200
 201            c = x.nextClean();
 202            if (c == '=') {
 203                if (x.next() != '>') {
 204                    x.back();
 205                }
 206            } else if (c != ':') {
 207                throw x.syntaxError("Expected a ':' after a key");
 208            }
 209            putOnce(key, x.nextValue());
 210
 211            /*
 212             * Pairs are separated by ','. We will also tolerate ';'.
 213             */
 214
 215            switch (x.nextClean()) {
 216            case ';':
 217            case ',':
 218                if (x.nextClean() == '}') {
 219                    return;
 220                }
 221                x.back();
 222                break;
 223            case '}':
 224                return;
 225            default:
 226                throw x.syntaxError("Expected a ',' or '}'");
 227            }
 228        }
 229    }
 230
 231
 232    /**
 233     * Construct a JSONObject from a Map.
 234     *
 235     * @param map A map object that can be used to initialize the contents of
 236     *  the JSONObject.
 237     */
 238    public JSONObject(Map<Object, Object> map) {
 239        this.map = (map == null) ? new HashMap<Object, Object>() : map;
 240    }
 241
 242
 243    /**
 244     * Construct a JSONObject from a Map.
 245     *
 246     * Note: Use this constructor when the map contains <key,bean>.
 247     *
 248     * @param map - A map with Key-Bean data.
 249     * @param includeSuperClass - Tell whether to include the super class properties.
 250     */
 251    public JSONObject(Map<?, ?> map, boolean includeSuperClass) {
 252        this.map = new HashMap<Object, Object>();
 253        if (map != null) {
 254            Iterator<?> i = map.entrySet().iterator();
 255            while (i.hasNext()) {
 256                Map.Entry<?, ?> e = (Map.Entry<?, ?>) i.next();
 257                if (isStandardProperty(e.getValue().getClass())) {
 258                    this.map.put(e.getKey(), e.getValue());
 259                } else {
 260                    this.map.put(e.getKey(), new JSONObject(e.getValue(),
 261                            includeSuperClass));
 262                }
 263            }
 264        }
 265    }
 266
 267
 268    /**
 269     * Construct a JSONObject from an Object using bean getters.
 270     * It reflects on all of the public methods of the object.
 271     * For each of the methods with no parameters and a name starting
 272     * with <code>"get"</code> or <code>"is"</code> followed by an uppercase letter,
 273     * the method is invoked, and a key and the value returned from the getter method
 274     * are put into the new JSONObject.
 275     *
 276     * The key is formed by removing the <code>"get"</code> or <code>"is"</code> prefix.
 277     * If the second remaining character is not upper case, then the first
 278     * character is converted to lower case.
 279     *
 280     * For example, if an object has a method named <code>"getName"</code>, and
 281     * if the result of calling <code>object.getName()</code> is <code>"Larry Fine"</code>,
 282     * then the JSONObject will contain <code>"name": "Larry Fine"</code>.
 283     *
 284     * @param bean An object that has getter methods that should be used
 285     * to make a JSONObject.
 286     */
 287    public JSONObject(Object bean) {
 288        this();
 289        populateInternalMap(bean, false);
 290    }
 291
 292
 293    /**
 294     * Construct a JSONObject from an Object using bean getters.
 295     * It reflects on all of the public methods of the object.
 296     * For each of the methods with no parameters and a name starting
 297     * with <code>"get"</code> or <code>"is"</code> followed by an uppercase letter,
 298     * the method is invoked, and a key and the value returned from the getter method
 299     * are put into the new JSONObject.
 300     *
 301     * The key is formed by removing the <code>"get"</code> or <code>"is"</code> prefix.
 302     * If the second remaining character is not upper case, then the first
 303     * character is converted to lower case.
 304     *
 305     * @param bean An object that has getter methods that should be used
 306     * to make a JSONObject.
 307     * @param includeSuperClass If true, include the super class properties.
 308     */
 309    public JSONObject(Object bean, boolean includeSuperClass) {
 310        this();
 311        populateInternalMap(bean, includeSuperClass);
 312    }
 313
 314    @SuppressWarnings("cast")
 315	private void populateInternalMap(Object bean, boolean includeSuperClassParam){
 316    	boolean includeSuperClass = includeSuperClassParam;
 317        Class<?> klass = bean.getClass();
 318
 319        /* If klass.getSuperClass is System class then force includeSuperClass to false. */
 320
 321        if (klass.getClassLoader() == null) {
 322            includeSuperClass = false;
 323        }
 324
 325        Method[] methods = (includeSuperClass) ?
 326                klass.getMethods() : klass.getDeclaredMethods();
 327        for (int i = 0; i < methods.length; i += 1) {
 328            try {
 329                Method method = methods[i];
 330                if (Modifier.isPublic(method.getModifiers())) {
 331                    String name = method.getName();
 332                    String key = "";
 333                    if (name.startsWith("get")) {
 334                        key = name.substring(3);
 335                    } else if (name.startsWith("is")) {
 336                        key = name.substring(2);
 337                    }
 338                    if (key.length() > 0 &&
 339                            Character.isUpperCase(key.charAt(0)) &&
 340                            method.getParameterTypes().length == 0) {
 341                        if (key.length() == 1) {
 342                            key = key.toLowerCase();
 343                        } else if (!Character.isUpperCase(key.charAt(1))) {
 344                            key = key.substring(0, 1).toLowerCase() +
 345                                key.substring(1);
 346                        }
 347
 348                        Object result = method.invoke(bean, (Object[])null);
 349                        if (result == null) {
 350                            map.put(key, NULL);
 351                        } else if (result.getClass().isArray()) {
 352                            map.put(key, new JSONArray(result, includeSuperClass));
 353                        } else if (result instanceof Collection<?>) { // List or Set
 354                            map.put(key, new JSONArray((Collection<?>) result, includeSuperClass));
 355                        } else if (result instanceof Map<?, ?>) {
 356                            map.put(key, new JSONObject((Map<?, ?>)result, includeSuperClass));
 357                        } else if (isStandardProperty(result.getClass())) { // Primitives, String and Wrapper
 358                            map.put(key, result);
 359                        } else {
 360                            if (result.getClass().getPackage().getName().startsWith("java") ||
 361                                    result.getClass().getClassLoader() == null) {
 362                                map.put(key, result.toString());
 363                            } else { // User defined Objects
 364                                map.put(key, new JSONObject(result, includeSuperClass));
 365                            }
 366                        }
 367                    }
 368                }
 369            } catch (Exception e) {
 370                throw new RuntimeException(e);
 371            }
 372        }
 373    }
 374
 375
 376    static boolean isStandardProperty(Class<?> clazz) {
 377        return clazz.isPrimitive()                  ||
 378            clazz.isAssignableFrom(Byte.class)      ||
 379            clazz.isAssignableFrom(Short.class)     ||
 380            clazz.isAssignableFrom(Integer.class)   ||
 381            clazz.isAssignableFrom(Long.class)      ||
 382            clazz.isAssignableFrom(Float.class)     ||
 383            clazz.isAssignableFrom(Double.class)    ||
 384            clazz.isAssignableFrom(Character.class) ||
 385            clazz.isAssignableFrom(String.class)    ||
 386            clazz.isAssignableFrom(Boolean.class);
 387    }
 388
 389
 390    /**
 391     * Construct a JSONObject from an Object, using reflection to find the
 392     * public members. The resulting JSONObject's keys will be the strings
 393     * from the names array, and the values will be the field values associated
 394     * with those keys in the object. If a key is not found or not visible,
 395     * then it will not be copied into the new JSONObject.
 396     * @param object An object that has fields that should be used to make a
 397     * JSONObject.
 398     * @param names An array of strings, the names of the fields to be obtained
 399     * from the object.
 400     */
 401    public JSONObject(Object object, String names[]) {
 402        this();
 403        Class<?> c = object.getClass();
 404        for (int i = 0; i < names.length; i += 1) {
 405            String name = names[i];
 406            try {
 407                putOpt(name, c.getField(name).get(object));
 408            } catch (Exception e) {
 409                /* forget about it */
 410            }
 411        }
 412    }
 413
 414
 415    /**
 416     * Construct a JSONObject from a source JSON text string.
 417     * This is the most commonly used JSONObject constructor.
 418     * @param source    A string beginning
 419     *  with <code>{</code>&nbsp;<small>(left brace)</small> and ending
 420     *  with <code>}</code>&nbsp;<small>(right brace)</small>.
 421     * @exception JSONException If there is a syntax error in the source
 422     *  string or a duplicated key.
 423     */
 424    public JSONObject(String source) throws JSONException {
 425        this(new JSONTokener(source));
 426    }
 427
 428
 429    /**
 430     * Accumulate values under a key. It is similar to the put method except
 431     * that if there is already an object stored under the key then a
 432     * JSONArray is stored under the key to hold all of the accumulated values.
 433     * If there is already a JSONArray, then the new value is appended to it.
 434     * In contrast, the put method replaces the previous value.
 435     * @param key   A key string.
 436     * @param value An object to be accumulated under the key.
 437     * @return this.
 438     * @throws JSONException If the value is an invalid number
 439     *  or if the key is null.
 440     */
 441    public JSONObject accumulate(String key, Object value)
 442            throws JSONException {
 443        testValidity(value);
 444        Object o = opt(key);
 445        if (o == null) {
 446            put(key, value instanceof JSONArray ?
 447                    new JSONArray().put(value) :
 448                    value);
 449        } else if (o instanceof JSONArray) {
 450            ((JSONArray)o).put(value);
 451        } else {
 452            put(key, new JSONArray().put(o).put(value));
 453        }
 454        return this;
 455    }
 456
 457
 458    /**
 459     * Append values to the array under a key. If the key does not exist in the
 460     * JSONObject, then the key is put in the JSONObject with its value being a
 461     * JSONArray containing the value parameter. If the key was already
 462     * associated with a JSONArray, then the value parameter is appended to it.
 463     * @param key   A key string.
 464     * @param value An object to be accumulated under the key.
 465     * @return this.
 466     * @throws JSONException If the key is null or if the current value
 467     *  associated with the key is not a JSONArray.
 468     */
 469    public JSONObject append(String key, Object value)
 470            throws JSONException {
 471        testValidity(value);
 472        Object o = opt(key);
 473        if (o == null) {
 474            put(key, new JSONArray().put(value));
 475        } else if (o instanceof JSONArray) {
 476            put(key, ((JSONArray)o).put(value));
 477        } else {
 478            throw new JSONException("JSONObject[" + key +
 479                    "] is not a JSONArray.");
 480        }
 481        return this;
 482    }
 483
 484
 485    /**
 486     * Produce a string from a double. The string "null" will be returned if
 487     * the number is not finite.
 488     * @param  d A double.
 489     * @return A String.
 490     */
 491    static public String doubleToString(double d) {
 492        if (Double.isInfinite(d) || Double.isNaN(d)) {
 493            return "null";
 494        }
 495
 496// Shave off trailing zeros and decimal point, if possible.
 497
 498        String s = Double.toString(d);
 499        if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) {
 500            while (s.endsWith("0")) {
 501                s = s.substring(0, s.length() - 1);
 502            }
 503            if (s.endsWith(".")) {
 504                s = s.substring(0, s.length() - 1);
 505            }
 506        }
 507        return s;
 508    }
 509
 510
 511    /**
 512     * Get the value object associated with a key.
 513     *
 514     * @param key   A key string.
 515     * @return      The object associated with the key.
 516     * @throws   JSONException if the key is not found.
 517     */
 518    public Object get(String key) throws JSONException {
 519        Object o = opt(key);
 520        if (o == null) {
 521            throw new JSONException("JSONObject[" + quote(key) +
 522                    "] not found.");
 523        }
 524        return o;
 525    }
 526
 527
 528    /**
 529     * Get the boolean value associated with a key.
 530     *
 531     * @param key   A key string.
 532     * @return      The truth.
 533     * @throws   JSONException
 534     *  if the value is not a Boolean or the String "true" or "false".
 535     */
 536    public boolean getBoolean(String key) throws JSONException {
 537        Object o = get(key);
 538        if (o.equals(Boolean.FALSE) ||
 539                (o instanceof String &&
 540                ((String)o).equalsIgnoreCase("false"))) {
 541            return false;
 542        } else if (o.equals(Boolean.TRUE) ||
 543                (o instanceof String &&
 544                ((String)o).equalsIgnoreCase("true"))) {
 545            return true;
 546        }
 547        throw new JSONException("JSONObject[" + quote(key) +
 548                "] is not a Boolean.");
 549    }
 550
 551
 552    /**
 553     * Get the double value associated with a key.
 554     * @param key   A key string.
 555     * @return      The numeric value.
 556     * @throws JSONException if the key is not found or
 557     *  if the value is not a Number object and cannot be converted to a number.
 558     */
 559    public double getDouble(String key) throws JSONException {
 560        Object o = get(key);
 561        try {
 562            return o instanceof Number ?
 563                ((Number)o).doubleValue() :
 564                Double.valueOf((String)o).doubleValue();
 565        } catch (Exception e) {
 566            throw new JSONException("JSONObject[" + quote(key) +
 567                "] is not a number.");
 568        }
 569    }
 570
 571
 572    /**
 573     * Get the int value associated with a key. If the number value is too
 574     * large for an int, it will be clipped.
 575     *
 576     * @param key   A key string.
 577     * @return      The integer value.
 578     * @throws   JSONException if the key is not found or if the value cannot
 579     *  be converted to an integer.
 580     */
 581    public int getInt(String key) throws JSONException {
 582        Object o = get(key);
 583        return o instanceof Number ?
 584                ((Number)o).intValue() : (int)getDouble(key);
 585    }
 586
 587
 588    /**
 589     * Get the JSONArray value associated with a key.
 590     *
 591     * @param key   A key string.
 592     * @return      A JSONArray which is the value.
 593     * @throws   JSONException if the key is not found or
 594     *  if the value is not a JSONArray.
 595     */
 596    public JSONArray getJSONArray(String key) throws JSONException {
 597        Object o = get(key);
 598        if (o instanceof JSONArray) {
 599            return (JSONArray)o;
 600        }
 601        throw new JSONException("JSONObject[" + quote(key) +
 602                "] is not a JSONArray.");
 603    }
 604
 605
 606    /**
 607     * Get the JSONObject value associated with a key.
 608     *
 609     * @param key   A key string.
 610     * @return      A JSONObject which is the value.
 611     * @throws   JSONException if the key is not found or
 612     *  if the value is not a JSONObject.
 613     */
 614    public JSONObject getJSONObject(String key) throws JSONException {
 615        Object o = get(key);
 616        if (o instanceof JSONObject) {
 617            return (JSONObject)o;
 618        }
 619        throw new JSONException("JSONObject[" + quote(key) +
 620                "] is not a JSONObject.");
 621    }
 622
 623
 624    /**
 625     * Get the long value associated with a key. If the number value is too
 626     * long for a long, it will be clipped.
 627     *
 628     * @param key   A key string.
 629     * @return      The long value.
 630     * @throws   JSONException if the key is not found or if the value cannot
 631     *  be converted to a long.
 632     */
 633    public long getLong(String key) throws JSONException {
 634        Object o = get(key);
 635        return o instanceof Number ?
 636                ((Number)o).longValue() : (long)getDouble(key);
 637    }
 638
 639
 640    /**
 641     * Get an array of field names from a JSONObject.
 642     *
 643     * @return An array of field names, or null if there are no names.
 644     */
 645    public static String[] getNames(JSONObject jo) {
 646        int length = jo.length();
 647        if (length == 0) {
 648            return null;
 649        }
 650        Iterator<?> i = jo.keys();
 651        String[] names = new String[length];
 652        int j = 0;
 653        while (i.hasNext()) {
 654            names[j] = (String)i.next();
 655            j += 1;
 656        }
 657        return names;
 658    }
 659
 660
 661    /**
 662     * Get an array of field names from an Object.
 663     *
 664     * @return An array of field names, or null if there are no names.
 665     */
 666    public static String[] getNames(Object object) {
 667        if (object == null) {
 668            return null;
 669        }
 670        Class<?> klass = object.getClass();
 671        Field[] fields = klass.getFields();
 672        int length = fields.length;
 673        if (length == 0) {
 674            return null;
 675        }
 676        String[] names = new String[length];
 677        for (int i = 0; i < length; i += 1) {
 678            names[i] = fields[i].getName();
 679        }
 680        return names;
 681    }
 682
 683
 684    /**
 685     * Get the string associated with a key.
 686     *
 687     * @param key   A key string.
 688     * @return      A string which is the value.
 689     * @throws   JSONException if the key is not found.
 690     */
 691    public String getString(String key) throws JSONException {
 692        return get(key).toString();
 693    }
 694
 695
 696    /**
 697     * Determine if the JSONObject contains a specific key.
 698     * @param key   A key string.
 699     * @return      true if the key exists in the JSONObject.
 700     */
 701    public boolean has(String key) {
 702        return this.map.containsKey(key);
 703    }
 704
 705
 706    /**
 707     * Determine if the value associated with the key is null or if there is
 708     *  no value.
 709     * @param key   A key string.
 710     * @return      true if there is no value associated with the key or if
 711     *  the value is the JSONObject.NULL object.
 712     */
 713    public boolean isNull(String key) {
 714        return JSONObject.NULL.equals(opt(key));
 715    }
 716
 717
 718    /**
 719     * Get an enumeration of the keys of the JSONObject.
 720     *
 721     * @return An iterator of the keys.
 722     */
 723    public Iterator<?> keys() {
 724        return this.map.keySet().iterator();
 725    }
 726
 727
 728    /**
 729     * Get the number of keys stored in the JSONObject.
 730     *
 731     * @return The number of keys in the JSONObject.
 732     */
 733    public int length() {
 734        return this.map.size();
 735    }
 736
 737
 738    /**
 739     * Produce a JSONArray containing the names of the elements of this
 740     * JSONObject.
 741     * @return A JSONArray containing the key strings, or null if the JSONObject
 742     * is empty.
 743     */
 744    public JSONArray names() {
 745        JSONArray ja = new JSONArray();
 746        Iterator<?>  keys = keys();
 747        while (keys.hasNext()) {
 748            ja.put(keys.next());
 749        }
 750        return ja.length() == 0 ? null : ja;
 751    }
 752
 753    /**
 754     * Produce a string from a Number.
 755     * @param  n A Number
 756     * @return A String.
 757     * @throws JSONException If n is a non-finite number.
 758     */
 759    static public String numberToString(Number n)
 760            throws JSONException {
 761        if (n == null) {
 762            throw new JSONException("Null pointer");
 763        }
 764        testValidity(n);
 765
 766// Shave off trailing zeros and decimal point, if possible.
 767
 768        String s = n.toString();
 769        if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) {
 770            while (s.endsWith("0")) {
 771                s = s.substring(0, s.length() - 1);
 772            }
 773            if (s.endsWith(".")) {
 774                s = s.substring(0, s.length() - 1);
 775            }
 776        }
 777        return s;
 778    }
 779
 780
 781    /**
 782     * Get an optional value associated with a key.
 783     * @param key   A key string.
 784     * @return      An object which is the value, or null if there is no value.
 785     */
 786    public Object opt(String key) {
 787        return key == null ? null : this.map.get(key);
 788    }
 789
 790
 791    /**
 792     * Get an optional boolean associated with a key.
 793     * It returns false if there is no such key, or if the value is not
 794     * Boolean.TRUE or the String "true".
 795     *
 796     * @param key   A key string.
 797     * @return      The truth.
 798     */
 799    public boolean optBoolean(String key) {
 800        return optBoolean(key, false);
 801    }
 802
 803
 804    /**
 805     * Get an optional boolean associated with a key.
 806     * It returns the defaultValue if there is no such key, or if it is not
 807     * a Boolean or the String "true" or "false" (case insensitive).
 808     *
 809     * @param key              A key string.
 810     * @param defaultValue     The default.
 811     * @return      The truth.
 812     */
 813    public boolean optBoolean(String key, boolean defaultValue) {
 814        try {
 815            return getBoolean(key);
 816        } catch (Exception e) {
 817            return defaultValue;
 818        }
 819    }
 820
 821
 822    /**
 823     * Put a key/value pair in the JSONObject, where the value will be a
 824     * JSONArray which is produced from a Collection.
 825     * @param key   A key string.
 826     * @param value A Collection value.
 827     * @return      this.
 828     * @throws JSONException
 829     */
 830    public JSONObject put(String key, Collection<Object> value) throws JSONException {
 831        put(key, new JSONArray(value));
 832        return this;
 833    }
 834
 835
 836    /**
 837     * Get an optional double associated with a key,
 838     * or NaN if there is no such key or if its value is not a number.
 839     * If the value is a string, an attempt will be made to evaluate it as
 840     * a number.
 841     *
 842     * @param key   A string which is the key.
 843     * @return      An object which is the value.
 844     */
 845    public double optDouble(String key) {
 846        return optDouble(key, Double.NaN);
 847    }
 848
 849
 850    /**
 851     * Get an optional double associated with a key, or the
 852     * defaultValue if there is no such key or if its value is not a number.
 853     * If the value is a string, an attempt will be made to evaluate it as
 854     * a number.
 855     *
 856     * @param key   A key string.
 857     * @param defaultValue     The default.
 858     * @return      An object which is the value.
 859     */
 860    public double optDouble(String key, double defaultValue) {
 861        try {
 862            Object o = opt(key);
 863            return o instanceof Number ? ((Number)o).doubleValue() :
 864                new Double((String)o).doubleValue();
 865        } catch (Exception e) {
 866            return defaultValue;
 867        }
 868    }
 869
 870
 871    /**
 872     * Get an optional int value associated with a key,
 873     * or zero if there is no such key or if the value is not a number.
 874     * If the value is a string, an attempt will be made to evaluate it as
 875     * a number.
 876     *
 877     * @param key   A key string.
 878     * @return      An object which is the value.
 879     */
 880    public int optInt(String key) {
 881        return optInt(key, 0);
 882    }
 883
 884
 885    /**
 886     * Get an optional int value associated with a key,
 887     * or the default if there is no such key or if the value is not a number.
 888     * If the value is a string, an attempt will be made to evaluate it as
 889     * a number.
 890     *
 891     * @param key   A key string.
 892     * @param defaultValue     The default.
 893     * @return      An object which is the value.
 894     */
 895    public int optInt(String key, int defaultValue) {
 896        try {
 897            return getInt(key);
 898        } catch (Exception e) {
 899            return defaultValue;
 900        }
 901    }
 902
 903
 904    /**
 905     * Get an optional JSONArray associated with a key.
 906     * It returns null if there is no such key, or if its value is not a
 907     * JSONArray.
 908     *
 909     * @param key   A key string.
 910     * @return      A JSONArray which is the value.
 911     */
 912    public JSONArray optJSONArray(String key) {
 913        Object o = opt(key);
 914        return o instanceof JSONArray ? (JSONArray)o : null;
 915    }
 916
 917
 918    /**
 919     * Get an optional JSONObject associated with a key.
 920     * It returns null if there is no such key, or if its value is not a
 921     * JSONObject.
 922     *
 923     * @param key   A key string.
 924     * @return      A JSONObject which is the value.
 925     */
 926    public JSONObject optJSONObject(String key) {
 927        Object o = opt(key);
 928        return o instanceof JSONObject ? (JSONObject)o : null;
 929    }
 930
 931
 932    /**
 933     * Get an optional long value associated with a key,
 934     * or zero if there is no such key or if the value is not a number.
 935     * If the value is a string, an attempt will be made to evaluate it as
 936     * a number.
 937     *
 938     * @param key   A key string.
 939     * @return      An object which is the value.
 940     */
 941    public long optLong(String key) {
 942        return optLong(key, 0);
 943    }
 944
 945
 946    /**
 947     * Get an optional long value associated with a key,
 948     * or the default if there is no such key or if the value is not a number.
 949     * If the value is a string, an attempt will be made to evaluate it as
 950     * a number.
 951     *
 952     * @param key   A key string.
 953     * @param defaultValue     The default.
 954     * @return      An object which is the value.
 955     */
 956    public long optLong(String key, long defaultValue) {
 957        try {
 958            return getLong(key);
 959        } catch (Exception e) {
 960            return defaultValue;
 961        }
 962    }
 963
 964
 965    /**
 966     * Get an optional string associated with a key.
 967     * It returns an empty string if there is no such key. If the value is not
 968     * a string and is not null, then it is coverted to a string.
 969     *
 970     * @param key   A key string.
 971     * @return      A string which is the value.
 972     */
 973    public String optString(String key) {
 974        return optString(key, "");
 975    }
 976
 977
 978    /**
 979     * Get an optional string associated with a key.
 980     * It returns the defaultValue if there is no such key.
 981     *
 982     * @param key   A key string.
 983     * @param defaultValue     The default.
 984     * @return      A string which is the value.
 985     */
 986    public String optString(String key, String defaultValue) {
 987        Object o = opt(key);
 988        return o != null ? o.toString() : defaultValue;
 989    }
 990
 991
 992    /**
 993     * Put a key/boolean pair in the JSONObject.
 994     *
 995     * @param key   A key string.
 996     * @param value A boolean which is the value.
 997     * @return this.
 998     * @throws JSONException If the key is null.
 999     */
1000    public JSONObject put(String key, boolean value) throws JSONException {
1001        put(key, value ? Boolean.TRUE : Boolean.FALSE);
1002        return this;
1003    }
1004
1005
1006    /**
1007     * Put a key/double pair in the JSONObject.
1008     *
1009     * @param key   A key string.
1010     * @param value A double which is the value.
1011     * @return this.
1012     * @throws JSONException If the key is null or if the number is invalid.
1013     */
1014    public JSONObject put(String key, double value) throws JSONException {
1015        put(key, new Double(value));
1016        return this;
1017    }
1018
1019
1020    /**
1021     * Put a key/int pair in the JSONObject.
1022     *
1023     * @param key   A key string.
1024     * @param value An int which is the value.
1025     * @return this.
1026     * @throws JSONException If the key is null.
1027     */
1028    public JSONObject put(String key, int value) throws JSONException {
1029        put(key, new Integer(value));
1030        return this;
1031    }
1032
1033
1034    /**
1035     * Put a key/long pair in the JSONObject.
1036     *
1037     * @param key   A key string.
1038     * @param value A long which is the value.
1039     * @return this.
1040     * @throws JSONException If the key is null.
1041     */
1042    public JSONObject put(String key, long value) throws JSONException {
1043        put(key, new Long(value));
1044        return this;
1045    }
1046
1047
1048    /**
1049     * Put a key/value pair in the JSONObject, where the value will be a
1050     * JSONObject which is produced from a Map.
1051     * @param key   A key string.
1052     * @param value A Map value.
1053     * @return      this.
1054     * @throws JSONException
1055     */
1056    public JSONObject put(String key, Map<?, ?> value) throws JSONException {
1057        put(key, new JSONObject(value));
1058        return this;
1059    }
1060
1061
1062    /**
1063     * Put a key/value pair in the JSONObject. If the value is null,
1064     * then the key will be removed from the JSONObject if it is present.
1065     * @param key   A key string.
1066     * @param value An object which is the value. It should be of one of these
1067     *  types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String,
1068     *  or the JSONObject.NULL object.
1069     * @return this.
1070     * @throws JSONException If the value is non-finite number
1071     *  or if the key is null.
1072     */
1073    public JSONObject put(String key, Object value) throws JSONException {
1074        if (key == null) {
1075            throw new JSONException("Null key.");
1076        }
1077        if (value != null) {
1078            testValidity(value);
1079            this.map.put(key, value);
1080        } else {
1081            remove(key);
1082        }
1083        return this;
1084    }
1085
1086
1087    /**
1088     * Put a key/value pair in the JSONObject, but only if the key and the
1089     * value are both non-null, and only if there is not already a member
1090     * with that name.
1091     * @param key
1092     * @param value
1093     * @return his.
1094     * @throws JSONException if the key is a duplicate
1095     */
1096    public JSONObject putOnce(String key, Object value) throws JSONException {
1097        if (key != null && value != null) {
1098            if (opt(key) != null) {
1099                throw new JSONException("Duplicate key \"" + key + "\"");
1100            }
1101            put(key, value);
1102        }
1103        return this;
1104    }
1105
1106
1107    /**
1108     * Put a key/value pair in the JSONObject, but only if the
1109     * key and the value are both non-null.
1110     * @param key   A key string.
1111     * @param value An object which is the value. It should be of one of these
1112     *  types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String,
1113     *  or the JSONObject.NULL object.
1114     * @return this.
1115     * @throws JSONException If the value is a non-finite number.
1116     */
1117    public JSONObject putOpt(String key, Object value) throws JSONException {
1118        if (key != null && value != null) {
1119            put(key, value);
1120        }
1121        return this;
1122    }
1123
1124
1125    /**
1126     * Produce a string in double quotes with backslash sequences in all the
1127     * right places. A backslash will be inserted within </, allowing JSON
1128     * text to be delivered in HTML. In JSON text, a string cannot contain a
1129     * control character or an unescaped quote or backslash.
1130     * @param string A String
1131     * @return  A String correctly formatted for insertion in a JSON text.
1132     */
1133    public static String quote(String string) {
1134        if (string == null || string.length() == 0) {
1135            return "\"\"";
1136        }
1137
1138        char         b;
1139        char         c = 0;
1140        int          i;
1141        int          len = string.length();
1142        StringBuffer sb = new StringBuffer(len + 4);
1143        String       t;
1144
1145        sb.append('"');
1146        for (i = 0; i < len; i += 1) {
1147            b = c;
1148            c = string.charAt(i);
1149            switch (c) {
1150            case '\\':
1151            case '"':
1152                sb.append('\\');
1153                sb.append(c);
1154                break;
1155            case '/':
1156                if (b == '<') {
1157                    sb.append('\\');
1158                }
1159                sb.append(c);
1160                break;
1161            case '\b':
1162                sb.append("\\b");
1163                break;
1164            case '\t':
1165                sb.append("\\t");
1166                break;
1167            case '\n':
1168                sb.append("\\n");
1169                break;
1170            case '\f':
1171                sb.append("\\f");
1172                break;
1173            case '\r':
1174                sb.append("\\r");
1175                break;
1176            default:
1177                if (c < ' ' || (c >= '\u0080' && c < '\u00a0') ||
1178                               (c >= '\u2000' && c < '\u2100')) {
1179                    t = "000" + Integer.toHexString(c);
1180                    sb.append("\\u" + t.substring(t.length() - 4));
1181                } else {
1182                    sb.append(c);
1183                }
1184            }
1185        }
1186        sb.append('"');
1187        return sb.toString();
1188    }
1189
1190    /**
1191     * Remove a name and its value, if present.
1192     * @param key The name to be removed.
1193     * @return The value that was associated with the name,
1194     * or null if there was no value.
1195     */
1196    public Object remove(String key) {
1197        return this.map.remove(key);
1198    }
1199
1200    /**
1201     * Get an enumeration of the keys of the JSONObject.
1202     * The keys will be sorted alphabetically.
1203     *
1204     * @return An iterator of the keys.
1205     */
1206    public Iterator<?> sortedKeys() {
1207      return new TreeSet<Object>(this.map.keySet()).iterator();
1208    }
1209
1210    /**
1211     * Try to convert a string into a number, boolean, or null. If the string
1212     * can't be converted, return the string.
1213     * @param s A String.
1214     * @return A simple JSON value.
1215     */
1216    static public Object stringToValue(String s) {
1217        if (s.equals("")) {
1218            return s;
1219        }
1220        if (s.equalsIgnoreCase("true")) {
1221            return Boolean.TRUE;
1222        }
1223        if (s.equalsIgnoreCase("false")) {
1224            return Boolean.FALSE;
1225        }
1226        if (s.equalsIgnoreCase("null")) {
1227            return JSONObject.NULL;
1228        }
1229
1230        /*
1231         * If it might be a number, try converting it. We support the 0- and 0x-
1232         * conventions. If a number cannot be produced, then the value will just
1233         * be a string. Note that the 0-, 0x-, plus, and implied string
1234         * conventions are non-standard. A JSON parser is free to accept
1235         * non-JSON forms as long as it accepts all correct JSON forms.
1236         */
1237
1238        char b = s.charAt(0);
1239        if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') {
1240            if (b == '0') {
1241                if (s.length() > 2 &&
1242                        (s.charAt(1) == 'x' || s.charAt(1) == 'X')) {
1243                    try {
1244                        return new Integer(Integer.parseInt(s.substring(2),
1245                                16));
1246                    } catch (Exception e) {
1247                        /* Ignore the error */
1248                    }
1249                } else {
1250                    try {
1251                        return new Integer(Integer.parseInt(s, 8));
1252                    } catch (Exception e) {
1253                        /* Ignore the error */
1254                    }
1255                }
1256            }
1257            try {
1258                if (s.indexOf('.') > -1 || s.indexOf('e') > -1 || s.indexOf('E') > -1) {
1259                    return Double.valueOf(s);
1260                }
1261				Long myLong = new Long(s);
1262				if (myLong.longValue() == myLong.intValue()) {
1263				    return new Integer(myLong.intValue());
1264				}
1265				return myLong;
1266            }  catch (Exception f) {
1267                /* Ignore the error */
1268            }
1269        }
1270        return s;
1271    }
1272
1273
1274    /**
1275     * Throw an exception if the object is an NaN or infinite number.
1276     * @param o The object to test.
1277     * @throws JSONException If o is a non-finite number.
1278     */
1279    static void testValidity(Object o) throws JSONException {
1280        if (o != null) {
1281            if (o instanceof Double) {
1282                if (((Double)o).isInfinite() || ((Double)o).isNaN()) {
1283                    throw new JSONException(
1284                        "JSON does not allow non-finite numbers.");
1285                }
1286            } else if (o instanceof Float) {
1287                if (((Float)o).isInfinite() || ((Float)o).isNaN()) {
1288                    throw new JSONException(
1289                        "JSON does not allow non-finite numbers.");
1290                }
1291            }
1292        }
1293    }
1294
1295
1296    /**
1297     * Produce a JSONArray containing the values of the members of this
1298     * JSONObject.
1299     * @param names A JSONArray containing a list of key strings. This
1300     * determines the sequence of the values in the result.
1301     * @return A JSONArray of values.
1302     * @throws JSONException If any of the values are non-finite numbers.
1303     */
1304    public JSONArray toJSONArray(JSONArray names) throws JSONException {
1305        if (names == null || names.length() == 0) {
1306            return null;
1307        }
1308        JSONArray ja = new JSONArray();
1309        for (int i = 0; i < names.length(); i += 1) {
1310            ja.put(this.opt(names.getString(i)));
1311        }
1312        return ja;
1313    }
1314
1315    /**
1316     * Make a JSON text of this JSONObject. For compactness, no whitespace
1317     * is added. If this would not result in a syntactically correct JSON text,
1318     * then null will be returned instead.
1319     * <p>
1320     * Warning: This method assumes that the data structure is acyclical.
1321     *
1322     * @return a printable, displayable, portable, transmittable
1323     *  representation of the object, beginning
1324     *  with <code>{</code>&nbsp;<small>(left brace)</small> and ending
1325     *  with <code>}</code>&nbsp;<small>(right brace)</small>.
1326     */
1327    @Override
1328	public String toString() {
1329        try {
1330            Iterator<?>     keys = keys();
1331            StringBuffer sb = new StringBuffer("{");
1332
1333            while (keys.hasNext()) {
1334                if (sb.length() > 1) {
1335                    sb.append(',');
1336                }
1337                Object o = keys.next();
1338                sb.append(quote(o.toString()));
1339                sb.append(':');
1340                sb.append(valueToString(this.map.get(o)));
1341            }
1342            sb.append('}');
1343            return sb.toString();
1344        } catch (Exception e) {
1345            return null;
1346        }
1347    }
1348
1349
1350    /**
1351     * Make a prettyprinted JSON text of this JSONObject.
1352     * <p>
1353     * Warning: This method assumes that the data structure is acyclical.
1354     * @param indentFactor The number of spaces to add to each level of
1355     *  indentation.
1356     * @return a printable, displayable, portable, transmittable
1357     *  representation of the object, beginning
1358     *  with <code>{</code>&nbsp;<small>(left brace)</small> and ending
1359     *  with <code>}</code>&nbsp;<small>(right brace)</small>.
1360     * @throws JSONException If the object contains an invalid number.
1361     */
1362    public String toString(int indentFactor) throws JSONException {
1363        return toString(indentFactor, 0);
1364    }
1365
1366
1367    /**
1368     * Make a prettyprinted JSON text of this JSONObject.
1369     * <p>
1370     * Warning: This method assumes that the data structure is acyclical.
1371     * @param indentFactor The number of spaces to add to each level of
1372     *  indentation.
1373     * @param indent The indentation of the top level.
1374     * @return a printable, displayable, transmittable
1375     *  representation of the object, beginning
1376     *  with <code>{</code>&nbsp;<small>(left brace)</small> and ending
1377     *  with <code>}</code>&nbsp;<small>(right brace)</small>.
1378     * @throws JSONException If the object contains an invalid number.
1379     */
1380    String toString(int indentFactor, int indent) throws JSONException {
1381        int j;
1382        int n = length();
1383        if (n == 0) {
1384            return "{}";
1385        }
1386        Iterator<?>     keys = sortedKeys();
1387        StringBuffer sb = new StringBuffer("{");
1388        int          newindent = indent + indentFactor;
1389        Object       o;
1390        if (n == 1) {
1391            o = keys.next();
1392            sb.append(quote(o.toString()));
1393            sb.append(": ");
1394            sb.append(valueToString(this.map.get(o), indentFactor,
1395                    indent));
1396        } else {
1397            while (keys.hasNext()) {
1398                o = keys.next();
1399                if (sb.length() > 1) {
1400                    sb.append(",\n");
1401                } else {
1402                    sb.append('\n');
1403                }
1404                for (j = 0; j < newindent; j += 1) {
1405                    sb.append(' ');
1406                }
1407                sb.append(quote(o.toString()));
1408                sb.append(": ");
1409                sb.append(valueToString(this.map.get(o), indentFactor,
1410                        newindent));
1411            }
1412            if (sb.length() > 1) {
1413                sb.append('\n');
1414                for (j = 0; j < indent; j += 1) {
1415                    sb.append(' ');
1416                }
1417            }
1418        }
1419        sb.append('}');
1420        return sb.toString();
1421    }
1422
1423
1424    /**
1425     * Make a JSON text of an Object value. If the object has an
1426     * value.toJSONString() method, then that method will be used to produce
1427     * the JSON text. The method is required to produce a strictly
1428     * conforming text. If the object does not contain a toJSONString
1429     * method (which is the most common case), then a text will be
1430     * produced by other means. If the value is an array or Collection,
1431     * then a JSONArray will be made from it and its toJSONString method
1432     * will be called. If the value is a MAP, then a JSONObject will be made
1433     * from it and its toJSONString method will be called. Otherwise, the
1434     * value's toString method will be called, and the result will be quoted.
1435     *
1436     * <p>
1437     * Warning: This method assumes that the data structure is acyclical.
1438     * @param value The value to be serialized.
1439     * @return a printable, displayable, transmittable
1440     *  representation of the object, beginning
1441     *  with <code>{</code>&nbsp;<small>(left brace)</small> and ending
1442     *  with <code>}</code>&nbsp;<small>(right brace)</small>.
1443     * @throws JSONException If the value is or contains an invalid number.
1444     */
1445    @SuppressWarnings("cast")
1446	static String valueToString(Object value) throws JSONException {
1447        if (value == null || value.equals(null)) {
1448            return "null";
1449        }
1450        if (value instanceof JSONString) {
1451            Object o;
1452            try {
1453                o = ((JSONString)value).toJSONString();
1454            } catch (Exception e) {
1455                throw new JSONException(e);
1456            }
1457            if (o instanceof String) {
1458                return (String)o;
1459            }
1460            throw new JSONException("Bad value from toJSONString: " + o);
1461        }
1462        if (value instanceof Number) {
1463            return numberToString((Number) value);
1464        }
1465        if (value instanceof Boolean || value instanceof JSONObject ||
1466                value instanceof JSONArray) {
1467            return value.toString();
1468        }
1469        if (value instanceof Map<?, ?>) {
1470            return new JSONObject((Map<?, ?>)value).toString();
1471        }
1472        if (value instanceof Collection<?>) {
1473            return new JSONArray((Collection<?>) value).toString();
1474        }
1475        if (value.getClass().isArray()) {
1476       

Large files files are truncated, but you can click here to view the full file