1 package org.json;
2
3 import java.io.Closeable;
4
5 /*
6  Copyright (c) 2002 JSON.org
7
8  Permission is hereby granted, free of charge, to any person obtaining a copy
9  of this software and associated documentation files (the "Software"), to deal
10  in the Software without restriction, including without limitation the rights
11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  copies of the Software, and to permit persons to whom the Software is
13  furnished to do so, subject to the following conditions:
14
15  The above copyright notice and this permission notice shall be included in all
16  copies or substantial portions of the Software.
17
18  The Software shall be used for Good, not Evil.
19
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26  SOFTWARE.
27  */

28
29 import java.io.IOException;
30 import java.io.StringWriter;
31 import java.io.Writer;
32 import java.lang.annotation.Annotation;
33 import java.lang.reflect.Field;
34 import java.lang.reflect.InvocationTargetException;
35 import java.lang.reflect.Method;
36 import java.lang.reflect.Modifier;
37 import java.math.BigDecimal;
38 import java.math.BigInteger;
39 import java.util.Collection;
40 import java.util.Enumeration;
41 import java.util.HashMap;
42 import java.util.Iterator;
43 import java.util.Locale;
44 import java.util.Map;
45 import java.util.Map.Entry;
46 import java.util.ResourceBundle;
47 import java.util.Set;
48 import java.util.regex.Pattern;
49
50 /**
51  * A JSONObject is an unordered collection of name/value pairs. Its external
52  * form is a string wrapped in curly braces with colons between the names and
53  * values, and commas between the values and names. The internal form is an
54  * object having <code>get</code> and <code>opt</code> methods for accessing
55  * the values by name, and <code>put</code> methods for adding or replacing
56  * values by name. The values can be any of these types: <code>Boolean</code>,
57  * <code>JSONArray</code>, <code>JSONObject</code>, <code>Number</code>,
58  * <code>String</code>, or the <code>JSONObject.NULL</code> object. A
59  * JSONObject constructor can be used to convert an external form JSON text
60  * into an internal form whose values can be retrieved with the
61  * <code>get</code> and <code>opt</code> methods, or to convert values into a
62  * JSON text using the <code>put</code> and <code>toString</code> methods. A
63  * <code>get</code> method returns a value if one can be found, and throws an
64  * exception if one cannot be found. An <code>opt</code> method returns a
65  * default value instead of throwing an exception, and so is useful for
66  * obtaining optional values.
67  * <p>
68  * The generic <code>get()</code> and <code>opt()</code> methods return an
69  * object, which you can cast or query for type. There are also typed
70  * <code>get</code> and <code>opt</code> methods that do type checking and type
71  * coercion for you. The opt methods differ from the get methods in that they
72  * do not throw. Instead, they return a specified value, such as null.
73  * <p>
74  * The <code>put</code> methods add or replace values in an object. For
75  * example,
76  *
77  * <pre>
78  * myString = new JSONObject()
79  *         .put(&quot;JSON&quot;, &quot;Hello, World!&quot;).toString();
80  * </pre>
81  *
82  * produces the string <code>{"JSON""Hello, World"}</code>.
83  * <p>
84  * The texts produced by the <code>toString</code> methods strictly conform to
85  * the JSON syntax rules. The constructors are more forgiving in the texts they
86  * will accept:
87  * <ul>
88  * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just
89  * before the closing brace.</li>
90  * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single
91  * quote)</small>.</li>
92  * <li>Strings do not need to be quoted at all if they do not begin with a
93  * quote or single quote, and if they do not contain leading or trailing
94  * spaces, and if they do not contain any of these characters:
95  * <code>{ } [ ] / \ : , #</code> and if they do not look like numbers and
96  * if they are not the reserved words <code>true</code>, <code>false</code>,
97  * or <code>null</code>.</li>
98  * </ul>
99  *
100  * @author JSON.org
101  * @version 2016-08-15
102  */

103 public class JSONObject {
104     /**
105      * JSONObject.NULL is equivalent to the value that JavaScript calls null,
106      * whilst Java's null is equivalent to the value that JavaScript calls
107      * undefined.
108      */

109     private static final class Null {
110
111         /**
112          * There is only intended to be a single instance of the NULL object,
113          * so the clone method returns itself.
114          *
115          * @return NULL.
116          */

117         @Override
118         protected final Object clone() {
119             return this;
120         }
121
122         /**
123          * A Null object is equal to the null value and to itself.
124          *
125          * @param object
126          *            An object to test for nullness.
127          * @return true if the object parameter is the JSONObject.NULL object or
128          *         null.
129          */

130         @Override
131         public boolean equals(Object object) {
132             return object == null || object == this;
133         }
134         /**
135          * A Null object is equal to the null value and to itself.
136          *
137          * @return always returns 0.
138          */

139         @Override
140         public int hashCode() {
141             return 0;
142         }
143
144         /**
145          * Get the "null" string value.
146          *
147          * @return The string "null".
148          */

149         @Override
150         public String toString() {
151             return "null";
152         }
153     }
154     
155     /**
156      *  Regular Expression Pattern that matches JSON Numbers. This is primarily used for
157      *  output to guarantee that we are always writing valid JSON. 
158      */

159     static final Pattern NUMBER_PATTERN = Pattern.compile("-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?");
160
161     /**
162      * The map where the JSONObject's properties are kept.
163      */

164     private final Map<String, Object> map;
165
166     /**
167      * It is sometimes more convenient and less ambiguous to have a
168      * <code>NULL</code> object than to use Java's <code>null</code> value.
169      * <code>JSONObject.NULL.equals(null)</code> returns <code>true</code>.
170      * <code>JSONObject.NULL.toString()</code> returns <code>"null"</code>.
171      */

172     public static final Object NULL = new Null();
173
174     /**
175      * Construct an empty JSONObject.
176      */

177     public JSONObject() {
178         // HashMap is used on purpose to ensure that elements are unordered by 
179         // the specification.
180         // JSON tends to be a portable transfer format to allows the container 
181         // implementations to rearrange their items for a faster element 
182         // retrieval based on associative access.
183         // Therefore, an implementation mustn't rely on the order of the item.
184         this.map = new HashMap<String, Object>();
185     }
186
187     /**
188      * Construct a JSONObject from a subset of another JSONObject. An array of
189      * strings is used to identify the keys that should be copied. Missing keys
190      * are ignored.
191      *
192      * @param jo
193      *            A JSONObject.
194      * @param names
195      *            An array of strings.
196      */

197     public JSONObject(JSONObject jo, String ... names) {
198         this(names.length);
199         for (int i = 0; i < names.length; i += 1) {
200             try {
201                 this.putOnce(names[i], jo.opt(names[i]));
202             } catch (Exception ignore) {
203             }
204         }
205     }
206
207     /**
208      * Construct a JSONObject from a JSONTokener.
209      *
210      * @param x
211      *            A JSONTokener object containing the source string.
212      * @throws JSONException
213      *             If there is a syntax error in the source string or a
214      *             duplicated key.
215      */

216     public JSONObject(JSONTokener x) throws JSONException {
217         this();
218         char c;
219         String key;
220
221         if (x.nextClean() != '{') {
222             throw x.syntaxError("A JSONObject text must begin with '{'");
223         }
224         for (;;) {
225             c = x.nextClean();
226             switch (c) {
227             case 0:
228                 throw x.syntaxError("A JSONObject text must end with '}'");
229             case '}':
230                 return;
231             default:
232                 x.back();
233                 key = x.nextValue().toString();
234             }
235
236             // The key is followed by ':'.
237
238             c = x.nextClean();
239             if (c != ':') {
240                 throw x.syntaxError("Expected a ':' after a key");
241             }
242             
243             // Use syntaxError(..) to include error location
244             
245             if (key != null) {
246                 // Check if key exists
247                 if (this.opt(key) != null) {
248                     // key already exists
249                     throw x.syntaxError("Duplicate key \"" + key + "\"");
250                 }
251                 // Only add value if non-null
252                 Object value = x.nextValue();
253                 if (value!=null) {
254                     this.put(key, value);
255                 }
256             }
257
258             // Pairs are separated by ','.
259
260             switch (x.nextClean()) {
261             case ';':
262             case ',':
263                 if (x.nextClean() == '}') {
264                     return;
265                 }
266                 x.back();
267                 break;
268             case '}':
269                 return;
270             default:
271                 throw x.syntaxError("Expected a ',' or '}'");
272             }
273         }
274     }
275
276     /**
277      * Construct a JSONObject from a Map.
278      *
279      * @param m
280      *            A map object that can be used to initialize the contents of
281      *            the JSONObject.
282      * @throws JSONException
283      *            If a value in the map is non-finite number.
284      * @throws NullPointerException
285      *            If a key in the map is <code>null</code>
286      */

287     public JSONObject(Map<?, ?> m) {
288         if (m == null) {
289             this.map = new HashMap<String, Object>();
290         } else {
291             this.map = new HashMap<String, Object>(m.size());
292             for (final Entry<?, ?> e : m.entrySet()) {
293                 if(e.getKey() == null) {
294                     throw new NullPointerException("Null key.");
295                 }
296                 final Object value = e.getValue();
297                 if (value != null) {
298                     this.map.put(String.valueOf(e.getKey()), wrap(value));
299                 }
300             }
301         }
302     }
303
304     /**
305      * Construct a JSONObject from an Object using bean getters. It reflects on
306      * all of the public methods of the object. For each of the methods with no
307      * parameters and a name starting with <code>"get"</code> or
308      * <code>"is"</code> followed by an uppercase letter, the method is invoked,
309      * and a key and the value returned from the getter method are put into the
310      * new JSONObject.
311      * <p>
312      * The key is formed by removing the <code>"get"</code> or <code>"is"</code>
313      * prefix. If the second remaining character is not upper case, then the
314      * first character is converted to lower case.
315      * <p>
316      * Methods that are <code>static</code>, return <code>void</code>,
317      * have parameters, or are "bridge" methods, are ignored.
318      * <p>
319      * For example, if an object has a method named <code>"getName"</code>, and
320      * if the result of calling <code>object.getName()</code> is
321      * <code>"Larry Fine"</code>, then the JSONObject will contain
322      * <code>"name""Larry Fine"</code>.
323      * <p>
324      * The {@link JSONPropertyName} annotation can be used on a bean getter to
325      * override key name used in the JSONObject. For example, using the object
326      * above with the <code>getName</code> method, if we annotated it with:
327      * <pre>
328      * &#64;JSONPropertyName("FullName")
329      * public String getName() { return this.name; }
330      * </pre>
331      * The resulting JSON object would contain <code>"FullName""Larry Fine"</code>
332      * <p>
333      * Similarly, the {@link JSONPropertyName} annotation can be used on non-
334      * <code>get</code> and <code>is</code> methods. We can also override key
335      * name used in the JSONObject as seen below even though the field would normally
336      * be ignored:
337      * <pre>
338      * &#64;JSONPropertyName("FullName")
339      * public String fullName() { return this.name; }
340      * </pre>
341      * The resulting JSON object would contain <code>"FullName""Larry Fine"</code>
342      * <p>
343      * The {@link JSONPropertyIgnore} annotation can be used to force the bean property
344      * to not be serialized into JSON. If both {@link JSONPropertyIgnore} and
345      * {@link JSONPropertyName} are defined on the same method, a depth comparison is
346      * performed and the one closest to the concrete class being serialized is used.
347      * If both annotations are at the same level, then the {@link JSONPropertyIgnore}
348      * annotation takes precedent and the field is not serialized.
349      * For example, the following declaration would prevent the <code>getName</code>
350      * method from being serialized:
351      * <pre>
352      * &#64;JSONPropertyName("FullName")
353      * &#64;JSONPropertyIgnore 
354      * public String getName() { return this.name; }
355      * </pre>
356      * <p>
357      * 
358      * @param bean
359      *            An object that has getter methods that should be used to make
360      *            a JSONObject.
361      */

362     public JSONObject(Object bean) {
363         this();
364         this.populateMap(bean);
365     }
366
367     /**
368      * Construct a JSONObject from an Object, using reflection to find the
369      * public members. The resulting JSONObject's keys will be the strings from
370      * the names array, and the values will be the field values associated with
371      * those keys in the object. If a key is not found or not visible, then it
372      * will not be copied into the new JSONObject.
373      *
374      * @param object
375      *            An object that has fields that should be used to make a
376      *            JSONObject.
377      * @param names
378      *            An array of strings, the names of the fields to be obtained
379      *            from the object.
380      */

381     public JSONObject(Object object, String ... names) {
382         this(names.length);
383         Class<?> c = object.getClass();
384         for (int i = 0; i < names.length; i += 1) {
385             String name = names[i];
386             try {
387                 this.putOpt(name, c.getField(name).get(object));
388             } catch (Exception ignore) {
389             }
390         }
391     }
392
393     /**
394      * Construct a JSONObject from a source JSON text string. This is the most
395      * commonly used JSONObject constructor.
396      *
397      * @param source
398      *            A string beginning with <code>{</code>&nbsp;<small>(left
399      *            brace)</small> and ending with <code>}</code>
400      *            &nbsp;<small>(right brace)</small>.
401      * @exception JSONException
402      *                If there is a syntax error in the source string or a
403      *                duplicated key.
404      */

405     public JSONObject(String source) throws JSONException {
406         this(new JSONTokener(source));
407     }
408
409     /**
410      * Construct a JSONObject from a ResourceBundle.
411      *
412      * @param baseName
413      *            The ResourceBundle base name.
414      * @param locale
415      *            The Locale to load the ResourceBundle for.
416      * @throws JSONException
417      *             If any JSONExceptions are detected.
418      */

419     public JSONObject(String baseName, Locale locale) throws JSONException {
420         this();
421         ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale,
422                 Thread.currentThread().getContextClassLoader());
423
424 // Iterate through the keys in the bundle.
425
426         Enumeration<String> keys = bundle.getKeys();
427         while (keys.hasMoreElements()) {
428             Object key = keys.nextElement();
429             if (key != null) {
430
431 // Go through the path, ensuring that there is a nested JSONObject for each
432 // segment except the last. Add the value using the last segment's name into
433 // the deepest nested JSONObject.
434
435                 String[] path = ((String) key).split("\\.");
436                 int last = path.length - 1;
437                 JSONObject target = this;
438                 for (int i = 0; i < last; i += 1) {
439                     String segment = path[i];
440                     JSONObject nextTarget = target.optJSONObject(segment);
441                     if (nextTarget == null) {
442                         nextTarget = new JSONObject();
443                         target.put(segment, nextTarget);
444                     }
445                     target = nextTarget;
446                 }
447                 target.put(path[last], bundle.getString((String) key));
448             }
449         }
450     }
451     
452     /**
453      * Constructor to specify an initial capacity of the internal map. Useful for library 
454      * internal calls where we know, or at least can best guess, how big this JSONObject
455      * will be.
456      * 
457      * @param initialCapacity initial capacity of the internal map.
458      */

459     protected JSONObject(int initialCapacity){
460         this.map = new HashMap<String, Object>(initialCapacity);
461     }
462
463     /**
464      * Accumulate values under a key. It is similar to the put method except
465      * that if there is already an object stored under the key then a JSONArray
466      * is stored under the key to hold all of the accumulated values. If there
467      * is already a JSONArray, then the new value is appended to it. In
468      * contrast, the put method replaces the previous value.
469      *
470      * If only one value is accumulated that is not a JSONArray, then the result
471      * will be the same as using put. But if multiple values are accumulated,
472      * then the result will be like append.
473      *
474      * @param key
475      *            A key string.
476      * @param value
477      *            An object to be accumulated under the key.
478      * @return this.
479      * @throws JSONException
480      *            If the value is non-finite number.
481      * @throws NullPointerException
482      *            If the key is <code>null</code>.
483      */

484     public JSONObject accumulate(String key, Object value) throws JSONException {
485         testValidity(value);
486         Object object = this.opt(key);
487         if (object == null) {
488             this.put(key,
489                     value instanceof JSONArray ? new JSONArray().put(value)
490                             : value);
491         } else if (object instanceof JSONArray) {
492             ((JSONArray) object).put(value);
493         } else {
494             this.put(key, new JSONArray().put(object).put(value));
495         }
496         return this;
497     }
498
499     /**
500      * Append values to the array under a key. If the key does not exist in the
501      * JSONObject, then the key is put in the JSONObject with its value being a
502      * JSONArray containing the value parameter. If the key was already
503      * associated with a JSONArray, then the value parameter is appended to it.
504      *
505      * @param key
506      *            A key string.
507      * @param value
508      *            An object to be accumulated under the key.
509      * @return this.
510      * @throws JSONException
511      *            If the value is non-finite number or if the current value associated with
512      *             the key is not a JSONArray.
513      * @throws NullPointerException
514      *            If the key is <code>null</code>.
515      */

516     public JSONObject append(String key, Object value) throws JSONException {
517         testValidity(value);
518         Object object = this.opt(key);
519         if (object == null) {
520             this.put(key, new JSONArray().put(value));
521         } else if (object instanceof JSONArray) {
522             this.put(key, ((JSONArray) object).put(value));
523         } else {
524             throw wrongValueFormatException(key, "JSONArray"nullnull);
525         }
526         return this;
527     }
528
529     /**
530      * Produce a string from a double. The string "null" will be returned if the
531      * number is not finite.
532      *
533      * @param d
534      *            A double.
535      * @return A String.
536      */

537     public static String doubleToString(double d) {
538         if (Double.isInfinite(d) || Double.isNaN(d)) {
539             return "null";
540         }
541
542 // Shave off trailing zeros and decimal point, if possible.
543
544         String string = Double.toString(d);
545         if (string.indexOf('.') > 0 && string.indexOf('e') < 0
546                 && string.indexOf('E') < 0) {
547             while (string.endsWith("0")) {
548                 string = string.substring(0, string.length() - 1);
549             }
550             if (string.endsWith(".")) {
551                 string = string.substring(0, string.length() - 1);
552             }
553         }
554         return string;
555     }
556
557     /**
558      * Get the value object associated with a key.
559      *
560      * @param key
561      *            A key string.
562      * @return The object associated with the key.
563      * @throws JSONException
564      *             if the key is not found.
565      */

566     public Object get(String key) throws JSONException {
567         if (key == null) {
568             throw new JSONException("Null key.");
569         }
570         Object object = this.opt(key);
571         if (object == null) {
572             throw new JSONException("JSONObject[" + quote(key) + "] not found.");
573         }
574         return object;
575     }
576
577     /**
578      * Get the enum value associated with a key.
579      * 
580      * @param <E>
581      *            Enum Type
582      * @param clazz
583      *           The type of enum to retrieve.
584      * @param key
585      *           A key string.
586      * @return The enum value associated with the key
587      * @throws JSONException
588      *             if the key is not found or if the value cannot be converted
589      *             to an enum.
590      */

591     public <E extends Enum<E>> E getEnum(Class<E> clazz, String key) throws JSONException {
592         E val = optEnum(clazz, key);
593         if(val==null) {
594             // JSONException should really take a throwable argument.
595             // If it did, I would re-implement this with the Enum.valueOf
596             // method and place any thrown exception in the JSONException
597             throw wrongValueFormatException(key, "enum of type " + quote(clazz.getSimpleName()), null);
598         }
599         return val;
600     }
601
602     /**
603      * Get the boolean value associated with a key.
604      *
605      * @param key
606      *            A key string.
607      * @return The truth.
608      * @throws JSONException
609      *             if the value is not a Boolean or the String "true" or
610      *             "false".
611      */

612     public boolean getBoolean(String key) throws JSONException {
613         Object object = this.get(key);
614         if (object.equals(Boolean.FALSE)
615                 || (object instanceof String && ((String) object)
616                         .equalsIgnoreCase("false"))) {
617             return false;
618         } else if (object.equals(Boolean.TRUE)
619                 || (object instanceof String && ((String) object)
620                         .equalsIgnoreCase("true"))) {
621             return true;
622         }
623         throw wrongValueFormatException(key, "Boolean"null);
624     }
625
626     /**
627      * Get the BigInteger value associated with a key.
628      *
629      * @param key
630      *            A key string.
631      * @return The numeric value.
632      * @throws JSONException
633      *             if the key is not found or if the value cannot 
634      *             be converted to BigInteger.
635      */

636     public BigInteger getBigInteger(String key) throws JSONException {
637         Object object = this.get(key);
638         BigInteger ret = objectToBigInteger(object, null);
639         if (ret != null) {
640             return ret;
641         }
642         throw wrongValueFormatException(key, "BigInteger", object, null);
643     }
644
645     /**
646      * Get the BigDecimal value associated with a key. If the value is float or
647      * double, the the {@link BigDecimal#BigDecimal(double)} constructor will
648      * be used. See notes on the constructor for conversion issues that may
649      * arise.
650      *
651      * @param key
652      *            A key string.
653      * @return The numeric value.
654      * @throws JSONException
655      *             if the key is not found or if the value
656      *             cannot be converted to BigDecimal.
657      */

658     public BigDecimal getBigDecimal(String key) throws JSONException {
659         Object object = this.get(key);
660         BigDecimal ret = objectToBigDecimal(object, null);
661         if (ret != null) {
662             return ret;
663         }
664         throw wrongValueFormatException(key, "BigDecimal", object, null);
665     }
666
667     /**
668      * Get the double value associated with a key.
669      *
670      * @param key
671      *            A key string.
672      * @return The numeric value.
673      * @throws JSONException
674      *             if the key is not found or if the value is not a Number
675      *             object and cannot be converted to a number.
676      */

677     public double getDouble(String key) throws JSONException {
678         final Object object = this.get(key);
679         if(object instanceof Number) {
680             return ((Number)object).doubleValue();
681         }
682         try {
683             return Double.parseDouble(object.toString());
684         } catch (Exception e) {
685             throw wrongValueFormatException(key, "double", e);
686         }
687     }
688
689     /**
690      * Get the float value associated with a key.
691      *
692      * @param key
693      *            A key string.
694      * @return The numeric value.
695      * @throws JSONException
696      *             if the key is not found or if the value is not a Number
697      *             object and cannot be converted to a number.
698      */

699     public float getFloat(String key) throws JSONException {
700         final Object object = this.get(key);
701         if(object instanceof Number) {
702             return ((Number)object).floatValue();
703         }
704         try {
705             return Float.parseFloat(object.toString());
706         } catch (Exception e) {
707             throw wrongValueFormatException(key, "float", e);
708         }
709     }
710
711     /**
712      * Get the Number value associated with a key.
713      *
714      * @param key
715      *            A key string.
716      * @return The numeric value.
717      * @throws JSONException
718      *             if the key is not found or if the value is not a Number
719      *             object and cannot be converted to a number.
720      */

721     public Number getNumber(String key) throws JSONException {
722         Object object = this.get(key);
723         try {
724             if (object instanceof Number) {
725                 return (Number)object;
726             }
727             return stringToNumber(object.toString());
728         } catch (Exception e) {
729             throw wrongValueFormatException(key, "number", e);
730         }
731     }
732
733     /**
734      * Get the int value associated with a key.
735      *
736      * @param key
737      *            A key string.
738      * @return The integer value.
739      * @throws JSONException
740      *             if the key is not found or if the value cannot be converted
741      *             to an integer.
742      */

743     public int getInt(String key) throws JSONException {
744         final Object object = this.get(key);
745         if(object instanceof Number) {
746             return ((Number)object).intValue();
747         }
748         try {
749             return Integer.parseInt(object.toString());
750         } catch (Exception e) {
751             throw wrongValueFormatException(key, "int", e);
752         }
753     }
754
755     /**
756      * Get the JSONArray value associated with a key.
757      *
758      * @param key
759      *            A key string.
760      * @return A JSONArray which is the value.
761      * @throws JSONException
762      *             if the key is not found or if the value is not a JSONArray.
763      */

764     public JSONArray getJSONArray(String key) throws JSONException {
765         Object object = this.get(key);
766         if (object instanceof JSONArray) {
767             return (JSONArray) object;
768         }
769         throw wrongValueFormatException(key, "JSONArray"null);
770     }
771
772     /**
773      * Get the JSONObject value associated with a key.
774      *
775      * @param key
776      *            A key string.
777      * @return A JSONObject which is the value.
778      * @throws JSONException
779      *             if the key is not found or if the value is not a JSONObject.
780      */

781     public JSONObject getJSONObject(String key) throws JSONException {
782         Object object = this.get(key);
783         if (object instanceof JSONObject) {
784             return (JSONObject) object;
785         }
786         throw wrongValueFormatException(key, "JSONObject"null);
787     }
788
789     /**
790      * Get the long value associated with a key.
791      *
792      * @param key
793      *            A key string.
794      * @return The long value.
795      * @throws JSONException
796      *             if the key is not found or if the value cannot be converted
797      *             to a long.
798      */

799     public long getLong(String key) throws JSONException {
800         final Object object = this.get(key);
801         if(object instanceof Number) {
802             return ((Number)object).longValue();
803         }
804         try {
805             return Long.parseLong(object.toString());
806         } catch (Exception e) {
807             throw wrongValueFormatException(key, "long", e);
808         }
809     }
810
811     /**
812      * Get an array of field names from a JSONObject.
813      *
814      * @param jo
815      *            JSON object
816      * @return An array of field names, or null if there are no names.
817      */

818     public static String[] getNames(JSONObject jo) {
819         if (jo.isEmpty()) {
820             return null;
821         }
822         return jo.keySet().toArray(new String[jo.length()]);
823     }
824
825     /**
826      * Get an array of public field names from an Object.
827      *
828      * @param object
829      *            object to read
830      * @return An array of field names, or null if there are no names.
831      */

832     public static String[] getNames(Object object) {
833         if (object == null) {
834             return null;
835         }
836         Class<?> klass = object.getClass();
837         Field[] fields = klass.getFields();
838         int length = fields.length;
839         if (length == 0) {
840             return null;
841         }
842         String[] names = new String[length];
843         for (int i = 0; i < length; i += 1) {
844             names[i] = fields[i].getName();
845         }
846         return names;
847     }
848
849     /**
850      * Get the string associated with a key.
851      *
852      * @param key
853      *            A key string.
854      * @return A string which is the value.
855      * @throws JSONException
856      *             if there is no string value for the key.
857      */

858     public String getString(String key) throws JSONException {
859         Object object = this.get(key);
860         if (object instanceof String) {
861             return (String) object;
862         }
863         throw wrongValueFormatException(key, "string"null);
864     }
865
866     /**
867      * Determine if the JSONObject contains a specific key.
868      *
869      * @param key
870      *            A key string.
871      * @return true if the key exists in the JSONObject.
872      */

873     public boolean has(String key) {
874         return this.map.containsKey(key);
875     }
876
877     /**
878      * Increment a property of a JSONObject. If there is no such property,
879      * create one with a value of 1 (Integer). If there is such a property, and if it is
880      * an Integer, Long, Double, Float, BigInteger, or BigDecimal then add one to it.
881      * No overflow bounds checking is performed, so callers should initialize the key
882      * prior to this call with an appropriate type that can handle the maximum expected
883      * value.
884      *
885      * @param key
886      *            A key string.
887      * @return this.
888      * @throws JSONException
889      *             If there is already a property with this name that is not an
890      *             Integer, Long, Double, or Float.
891      */

892     public JSONObject increment(String key) throws JSONException {
893         Object value = this.opt(key);
894         if (value == null) {
895             this.put(key, 1);
896         } else if (value instanceof Integer) {
897             this.put(key, ((Integer) value).intValue() + 1);
898         } else if (value instanceof Long) {
899             this.put(key, ((Long) value).longValue() + 1L);
900         } else if (value instanceof BigInteger) {
901             this.put(key, ((BigInteger)value).add(BigInteger.ONE));
902         } else if (value instanceof Float) {
903             this.put(key, ((Float) value).floatValue() + 1.0f);
904         } else if (value instanceof Double) {
905             this.put(key, ((Double) value).doubleValue() + 1.0d);
906         } else if (value instanceof BigDecimal) {
907             this.put(key, ((BigDecimal)value).add(BigDecimal.ONE));
908         } else {
909             throw new JSONException("Unable to increment [" + quote(key) + "].");
910         }
911         return this;
912     }
913
914     /**
915      * Determine if the value associated with the key is <code>null</code> or if there is no
916      * value.
917      *
918      * @param key
919      *            A key string.
920      * @return true if there is no value associated with the key or if the value
921      *        is the JSONObject.NULL object.
922      */

923     public boolean isNull(String key) {
924         return JSONObject.NULL.equals(this.opt(key));
925     }
926
927     /**
928      * Get an enumeration of the keys of the JSONObject. Modifying this key Set will also
929      * modify the JSONObject. Use with caution.
930      *
931      * @see Set#iterator()
932      * 
933      * @return An iterator of the keys.
934      */

935     public Iterator<String> keys() {
936         return this.keySet().iterator();
937     }
938
939     /**
940      * Get a set of keys of the JSONObject. Modifying this key Set will also modify the
941      * JSONObject. Use with caution.
942      *
943      * @see Map#keySet()
944      *
945      * @return A keySet.
946      */

947     public Set<String> keySet() {
948         return this.map.keySet();
949     }
950
951     /**
952      * Get a set of entries of the JSONObject. These are raw values and may not
953      * match what is returned by the JSONObject get* and opt* functions. Modifying 
954      * the returned EntrySet or the Entry objects contained therein will modify the
955      * backing JSONObject. This does not return a clone or a read-only view.
956      * 
957      * Use with caution.
958      *
959      * @see Map#entrySet()
960      *
961      * @return An Entry Set
962      */

963     protected Set<Entry<String, Object>> entrySet() {
964         return this.map.entrySet();
965     }
966
967     /**
968      * Get the number of keys stored in the JSONObject.
969      *
970      * @return The number of keys in the JSONObject.
971      */

972     public int length() {
973         return this.map.size();
974     }
975
976     /**
977      * Check if JSONObject is empty.
978      *
979      * @return true if JSONObject is empty, otherwise false.
980      */

981     public boolean isEmpty() {
982         return this.map.isEmpty();
983     }
984
985     /**
986      * Produce a JSONArray containing the names of the elements of this
987      * JSONObject.
988      *
989      * @return A JSONArray containing the key strings, or null if the JSONObject
990      *        is empty.
991      */

992     public JSONArray names() {
993         if(this.map.isEmpty()) {
994             return null;
995         }
996         return new JSONArray(this.map.keySet());
997     }
998
999     /**
1000      * Produce a string from a Number.
1001      *
1002      * @param number
1003      *            A Number
1004      * @return A String.
1005      * @throws JSONException
1006      *             If n is a non-finite number.
1007      */

1008     public static String numberToString(Number number) throws JSONException {
1009         if (number == null) {
1010             throw new JSONException("Null pointer");
1011         }
1012         testValidity(number);
1013
1014         // Shave off trailing zeros and decimal point, if possible.
1015
1016         String string = number.toString();
1017         if (string.indexOf('.') > 0 && string.indexOf('e') < 0
1018                 && string.indexOf('E') < 0) {
1019             while (string.endsWith("0")) {
1020                 string = string.substring(0, string.length() - 1);
1021             }
1022             if (string.endsWith(".")) {
1023                 string = string.substring(0, string.length() - 1);
1024             }
1025         }
1026         return string;
1027     }
1028
1029     /**
1030      * Get an optional value associated with a key.
1031      *
1032      * @param key
1033      *            A key string.
1034      * @return An object which is the value, or null if there is no value.
1035      */

1036     public Object opt(String key) {
1037         return key == null ? null : this.map.get(key);
1038     }
1039
1040     /**
1041      * Get the enum value associated with a key.
1042      * 
1043      * @param <E>
1044      *            Enum Type
1045      * @param clazz
1046      *            The type of enum to retrieve.
1047      * @param key
1048      *            A key string.
1049      * @return The enum value associated with the key or null if not found
1050      */

1051     public <E extends Enum<E>> E optEnum(Class<E> clazz, String key) {
1052         return this.optEnum(clazz, key, null);
1053     }
1054
1055     /**
1056      * Get the enum value associated with a key.
1057      * 
1058      * @param <E>
1059      *            Enum Type
1060      * @param clazz
1061      *            The type of enum to retrieve.
1062      * @param key
1063      *            A key string.
1064      * @param defaultValue
1065      *            The default in case the value is not found
1066      * @return The enum value associated with the key or defaultValue
1067      *            if the value is not found or cannot be assigned to <code>clazz</code>
1068      */

1069     public <E extends Enum<E>> E optEnum(Class<E> clazz, String key, E defaultValue) {
1070         try {
1071             Object val = this.opt(key);
1072             if (NULL.equals(val)) {
1073                 return defaultValue;
1074             }
1075             if (clazz.isAssignableFrom(val.getClass())) {
1076                 // we just checked it!
1077                 @SuppressWarnings("unchecked")
1078                 E myE = (E) val;
1079                 return myE;
1080             }
1081             return Enum.valueOf(clazz, val.toString());
1082         } catch (IllegalArgumentException e) {
1083             return defaultValue;
1084         } catch (NullPointerException e) {
1085             return defaultValue;
1086         }
1087     }
1088
1089     /**
1090      * Get an optional boolean associated with a key. It returns false if there
1091      * is no such key, or if the value is not Boolean.TRUE or the String "true".
1092      *
1093      * @param key
1094      *            A key string.
1095      * @return The truth.
1096      */

1097     public boolean optBoolean(String key) {
1098         return this.optBoolean(key, false);
1099     }
1100
1101     /**
1102      * Get an optional boolean associated with a key. It returns the
1103      * defaultValue if there is no such key, or if it is not a Boolean or the
1104      * String "true" or "false" (case insensitive).
1105      *
1106      * @param key
1107      *            A key string.
1108      * @param defaultValue
1109      *            The default.
1110      * @return The truth.
1111      */

1112     public boolean optBoolean(String key, boolean defaultValue) {
1113         Object val = this.opt(key);
1114         if (NULL.equals(val)) {
1115             return defaultValue;
1116         }
1117         if (val instanceof Boolean){
1118             return ((Boolean) val).booleanValue();
1119         }
1120         try {
1121             // we'll use the get anyway because it does string conversion.
1122             return this.getBoolean(key);
1123         } catch (Exception e) {
1124             return defaultValue;
1125         }
1126     }
1127
1128     /**
1129      * Get an optional BigDecimal associated with a key, or the defaultValue if
1130      * there is no such key or if its value is not a number. If the value is a
1131      * string, an attempt will be made to evaluate it as a number. If the value
1132      * is float or double, then the {@link BigDecimal#BigDecimal(double)}
1133      * constructor will be used. See notes on the constructor for conversion
1134      * issues that may arise.
1135      *
1136      * @param key
1137      *            A key string.
1138      * @param defaultValue
1139      *            The default.
1140      * @return An object which is the value.
1141      */

1142     public BigDecimal optBigDecimal(String key, BigDecimal defaultValue) {
1143         Object val = this.opt(key);
1144         return objectToBigDecimal(val, defaultValue);
1145     }
1146
1147     /**
1148      * @param val value to convert
1149      * @param defaultValue default value to return is the conversion doesn't work or is null.
1150      * @return BigDecimal conversion of the original value, or the defaultValue if unable
1151      *          to convert. 
1152      */

1153     static BigDecimal objectToBigDecimal(Object val, BigDecimal defaultValue) {
1154         if (NULL.equals(val)) {
1155             return defaultValue;
1156         }
1157         if (val instanceof BigDecimal){
1158             return (BigDecimal) val;
1159         }
1160         if (val instanceof BigInteger){
1161             return new BigDecimal((BigInteger) val);
1162         }
1163         if (val instanceof Double || val instanceof Float){
1164             final double d = ((Number) val).doubleValue();
1165             if(Double.isNaN(d)) {
1166                 return defaultValue;
1167             }
1168             return new BigDecimal(((Number) val).doubleValue());
1169         }
1170         if (val instanceof Long || val instanceof Integer
1171                 || val instanceof Short || val instanceof Byte){
1172             return new BigDecimal(((Number) val).longValue());
1173         }
1174         // don't check if it's a string in case of unchecked Number subclasses
1175         try {
1176             return new BigDecimal(val.toString());
1177         } catch (Exception e) {
1178             return defaultValue;
1179         }
1180     }
1181
1182     /**
1183      * Get an optional BigInteger associated with a key, or the defaultValue if
1184      * there is no such key or if its value is not a number. If the value is a
1185      * string, an attempt will be made to evaluate it as a number.
1186      *
1187      * @param key
1188      *            A key string.
1189      * @param defaultValue
1190      *            The default.
1191      * @return An object which is the value.
1192      */

1193     public BigInteger optBigInteger(String key, BigInteger defaultValue) {
1194         Object val = this.opt(key);
1195         return objectToBigInteger(val, defaultValue);
1196     }
1197
1198     /**
1199      * @param val value to convert
1200      * @param defaultValue default value to return is the conversion doesn't work or is null.
1201      * @return BigInteger conversion of the original value, or the defaultValue if unable
1202      *          to convert. 
1203      */

1204     static BigInteger objectToBigInteger(Object val, BigInteger defaultValue) {
1205         if (NULL.equals(val)) {
1206             return defaultValue;
1207         }
1208         if (val instanceof BigInteger){
1209             return (BigInteger) val;
1210         }
1211         if (val instanceof BigDecimal){
1212             return ((BigDecimal) val).toBigInteger();
1213         }
1214         if (val instanceof Double || val instanceof Float){
1215             final double d = ((Number) val).doubleValue();
1216             if(Double.isNaN(d)) {
1217                 return defaultValue;
1218             }
1219             return new BigDecimal(d).toBigInteger();
1220         }
1221         if (val instanceof Long || val instanceof Integer
1222                 || val instanceof Short || val instanceof Byte){
1223             return BigInteger.valueOf(((Number) val).longValue());
1224         }
1225         // don't check if it's a string in case of unchecked Number subclasses
1226         try {
1227             // the other opt functions handle implicit conversions, i.e. 
1228             // jo.put("double",1.1d);
1229             // jo.optInt("double"); -- will return 1, not an error
1230             // this conversion to BigDecimal then to BigInteger is to maintain
1231             // that type cast support that may truncate the decimal.
1232             final String valStr = val.toString();
1233             if(isDecimalNotation(valStr)) {
1234                 return new BigDecimal(valStr).toBigInteger();
1235             }
1236             return new BigInteger(valStr);
1237         } catch (Exception e) {
1238             return defaultValue;
1239         }
1240     }
1241
1242     /**
1243      * Get an optional double associated with a key, or NaN if there is no such
1244      * key or if its value is not a number. If the value is a string, an attempt
1245      * will be made to evaluate it as a number.
1246      *
1247      * @param key
1248      *            A string which is the key.
1249      * @return An object which is the value.
1250      */

1251     public double optDouble(String key) {
1252         return this.optDouble(key, Double.NaN);
1253     }
1254
1255     /**
1256      * Get an optional double associated with a key, or the defaultValue if
1257      * there is no such key or if its value is not a number. If the value is a
1258      * string, an attempt will be made to evaluate it as a number.
1259      *
1260      * @param key
1261      *            A key string.
1262      * @param defaultValue
1263      *            The default.
1264      * @return An object which is the value.
1265      */

1266     public double optDouble(String key, double defaultValue) {
1267         Number val = this.optNumber(key);
1268         if (val == null) {
1269             return defaultValue;
1270         }
1271         final double doubleValue = val.doubleValue();
1272         // if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue)) {
1273         // return defaultValue;
1274         // }
1275         return doubleValue;
1276     }
1277
1278     /**
1279      * Get the optional double value associated with an index. NaN is returned
1280      * if there is no value for the index, or if the value is not a number and
1281      * cannot be converted to a number.
1282      *
1283      * @param key
1284      *            A key string.
1285      * @return The value.
1286      */

1287     public float optFloat(String key) {
1288         return this.optFloat(key, Float.NaN);
1289     }
1290
1291     /**
1292      * Get the optional double value associated with an index. The defaultValue
1293      * is returned if there is no value for the index, or if the value is not a
1294      * number and cannot be converted to a number.
1295      *
1296      * @param key
1297      *            A key string.
1298      * @param defaultValue
1299      *            The default value.
1300      * @return The value.
1301      */

1302     public float optFloat(String key, float defaultValue) {
1303         Number val = this.optNumber(key);
1304         if (val == null) {
1305             return defaultValue;
1306         }
1307         final float floatValue = val.floatValue();
1308         // if (Float.isNaN(floatValue) || Float.isInfinite(floatValue)) {
1309         // return defaultValue;
1310         // }
1311         return floatValue;
1312     }
1313
1314     /**
1315      * Get an optional int value associated with a key, or zero if there is no
1316      * such key or if the value is not a number. If the value is a string, an
1317      * attempt will be made to evaluate it as a number.
1318      *
1319      * @param key
1320      *            A key string.
1321      * @return An object which is the value.
1322      */

1323     public int optInt(String key) {
1324         return this.optInt(key, 0);
1325     }
1326
1327     /**
1328      * Get an optional int value associated with a key, or the default if there
1329      * is no such key or if the value is not a number. If the value is a string,
1330      * an attempt will be made to evaluate it as a number.
1331      *
1332      * @param key
1333      *            A key string.
1334      * @param defaultValue
1335      *            The default.
1336      * @return An object which is the value.
1337      */

1338     public int optInt(String key, int defaultValue) {
1339         final Number val = this.optNumber(key, null);
1340         if (val == null) {
1341             return defaultValue;
1342         }
1343         return val.intValue();
1344     }
1345
1346     /**
1347      * Get an optional JSONArray associated with a key. It returns null if there
1348      * is no such key, or if its value is not a JSONArray.
1349      *
1350      * @param key
1351      *            A key string.
1352      * @return A JSONArray which is the value.
1353      */

1354     public JSONArray optJSONArray(String key) {
1355         Object o = this.opt(key);
1356         return o instanceof JSONArray ? (JSONArray) o : null;
1357     }
1358
1359     /**
1360      * Get an optional JSONObject associated with a key. It returns null if
1361      * there is no such key, or if its value is not a JSONObject.
1362      *
1363      * @param key
1364      *            A key string.
1365      * @return A JSONObject which is the value.
1366      */

1367     public JSONObject optJSONObject(String key) {
1368         Object object = this.opt(key);
1369         return object instanceof JSONObject ? (JSONObject) object : null;
1370     }
1371
1372     /**
1373      * Get an optional long value associated with a key, or zero if there is no
1374      * such key or if the value is not a number. If the value is a string, an
1375      * attempt will be made to evaluate it as a number.
1376      *
1377      * @param key
1378      *            A key string.
1379      * @return An object which is the value.
1380      */

1381     public long optLong(String key) {
1382         return this.optLong(key, 0);
1383     }
1384
1385     /**
1386      * Get an optional long value associated with a key, or the default if there
1387      * is no such key or if the value is not a number. If the value is a string,
1388      * an attempt will be made to evaluate it as a number.
1389      *
1390      * @param key
1391      *            A key string.
1392      * @param defaultValue
1393      *            The default.
1394      * @return An object which is the value.
1395      */

1396     public long optLong(String key, long defaultValue) {
1397         final Number val = this.optNumber(key, null);
1398         if (val == null) {
1399             return defaultValue;
1400         }
1401         
1402         return val.longValue();
1403     }
1404     
1405     /**
1406      * Get an optional {@link Number} value associated with a key, or <code>null</code>
1407      * if there is no such key or if the value is not a number. If the value is a string,
1408      * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
1409      * would be used in cases where type coercion of the number value is unwanted.
1410      *
1411      * @param key
1412      *            A key string.
1413      * @return An object which is the value.
1414      */

1415     public Number optNumber(String key) {
1416         return this.optNumber(key, null);
1417     }
1418
1419     /**
1420      * Get an optional {@link Number} value associated with a key, or the default if there
1421      * is no such key or if the value is not a number. If the value is a string,
1422      * an attempt will be made to evaluate it as a number. This method
1423      * would be used in cases where type coercion of the number value is unwanted.
1424      *
1425      * @param key
1426      *            A key string.
1427      * @param defaultValue
1428      *            The default.
1429      * @return An object which is the value.
1430      */

1431     public Number optNumber(String key, Number defaultValue) {
1432         Object val = this.opt(key);
1433         if (NULL.equals(val)) {
1434             return defaultValue;
1435         }
1436         if (val instanceof Number){
1437             return (Number) val;
1438         }
1439         
1440         try {
1441             return stringToNumber(val.toString());
1442         } catch (Exception e) {
1443             return defaultValue;
1444         }
1445     }
1446     
1447     /**
1448      * Get an optional string associated with a key. It returns an empty string
1449      * if there is no such key. If the value is not a string and is not null,
1450      * then it is converted to a string.
1451      *
1452      * @param key
1453      *            A key string.
1454      * @return A string which is the value.
1455      */

1456     public String optString(String key) {
1457         return this.optString(key, "");
1458     }
1459
1460     /**
1461      * Get an optional string associated with a key. It returns the defaultValue
1462      * if there is no such key.
1463      *
1464      * @param key
1465      *            A key string.
1466      * @param defaultValue
1467      *            The default.
1468      * @return A string which is the value.
1469      */

1470     public String optString(String key, String defaultValue) {
1471         Object object = this.opt(key);
1472         return NULL.equals(object) ? defaultValue : object.toString();
1473     }
1474
1475     /**
1476      * Populates the internal map of the JSONObject with the bean properties. The
1477      * bean can not be recursive.
1478      *
1479      * @see JSONObject#JSONObject(Object)
1480      *
1481      * @param bean
1482      *            the bean
1483      */

1484     private void populateMap(Object bean) {
1485         Class<?> klass = bean.getClass();
1486
1487         // If klass is a System class then set includeSuperClass to false.
1488
1489         boolean includeSuperClass = klass.getClassLoader() != null;
1490
1491         Method[] methods = includeSuperClass ? klass.getMethods() : klass.getDeclaredMethods();
1492         for (final Method method : methods) {
1493             final int modifiers = method.getModifiers();
1494             if (Modifier.isPublic(modifiers)
1495                     && !Modifier.isStatic(modifiers)
1496                     && method.getParameterTypes().length == 0
1497                     && !method.isBridge()
1498                     && method.getReturnType() != Void.TYPE
1499                     && isValidMethodName(method.getName())) {
1500                 final String key = getKeyNameFromMethod(method);
1501                 if (key != null && !key.isEmpty()) {
1502                     try {
1503                         final Object result = method.invoke(bean);
1504                         if (result != null) {
1505                             this.map.put(key, wrap(result));
1506                             // we don't use the result anywhere outside of wrap
1507                             // if it's a resource we should be sure to close it
1508                             // after calling toString
1509                             if (result instanceof Closeable) {
1510                                 try {
1511                                     ((Closeable) result).close();
1512                                 } catch (IOException ignore) {
1513                                 }
1514                             }
1515                         }
1516                     } catch (IllegalAccessException ignore) {
1517                     } catch (IllegalArgumentException ignore) {
1518                     } catch (InvocationTargetException ignore) {
1519                     }
1520                 }
1521             }
1522         }
1523     }
1524
1525     private static boolean isValidMethodName(String name) {
1526         return !"getClass".equals(name) && !"getDeclaringClass".equals(name);
1527     }
1528
1529     private static String getKeyNameFromMethod(Method method) {
1530         final int ignoreDepth = getAnnotationDepth(method, JSONPropertyIgnore.class);
1531         if (ignoreDepth > 0) {
1532             final int forcedNameDepth = getAnnotationDepth(method, JSONPropertyName.class);
1533             if (forcedNameDepth < 0 || ignoreDepth <= forcedNameDepth) {
1534                 // the hierarchy asked to ignore, and the nearest name override
1535                 // was higher or non-existent
1536                 return null;
1537             }
1538         }
1539         JSONPropertyName annotation = getAnnotation(method, JSONPropertyName.class);
1540         if (annotation != null && annotation.value() != null && !annotation.value().isEmpty()) {
1541             return annotation.value();
1542         }
1543         String key;
1544         final String name = method.getName();
1545         if (name.startsWith("get") && name.length() > 3) {
1546             key = name.substring(3);
1547         } else if (name.startsWith("is") && name.length() > 2) {
1548             key = name.substring(2);
1549         } else {
1550             return null;
1551         }
1552         // if the first letter in the key is not uppercase, then skip.
1553         // This is to maintain backwards compatibility before PR406
1554         // (https://github.com/stleary/JSON-java/pull/406/)
1555         if (Character.isLowerCase(key.charAt(0))) {
1556             return null;
1557         }
1558         if (key.length() == 1) {
1559             key = key.toLowerCase(Locale.ROOT);
1560         } else if (!Character.isUpperCase(key.charAt(1))) {
1561             key = key.substring(0, 1).toLowerCase(Locale.ROOT) + key.substring(1);
1562         }
1563         return key;
1564     }
1565
1566     /**
1567      * Searches the class hierarchy to see if the method or it's super
1568      * implementations and interfaces has the annotation.
1569      *
1570      * @param <A>
1571      *            type of the annotation
1572      *
1573      * @param m
1574      *            method to check
1575      * @param annotationClass
1576      *            annotation to look for
1577      * @return the {@link Annotation} if the annotation exists on the current method
1578      *         or one of it's super class definitions
1579      */

1580     private static <A extends Annotation> A getAnnotation(final Method m, final Class<A> annotationClass) {
1581         // if we have invalid data the result is null
1582         if (m == null || annotationClass == null) {
1583             return null;
1584         }
1585
1586         if (m.isAnnotationPresent(annotationClass)) {
1587             return m.getAnnotation(annotationClass);
1588         }
1589
1590         // if we've already reached the Object classreturn null;
1591         Class<?> c = m.getDeclaringClass();
1592         if (c.getSuperclass() == null) {
1593             return null;
1594         }
1595
1596         // check directly implemented interfaces for the method being checked
1597         for (Class<?> i : c.getInterfaces()) {
1598             try {
1599                 Method im = i.getMethod(m.getName(), m.getParameterTypes());
1600                 return getAnnotation(im, annotationClass);
1601             } catch (final SecurityException ex) {
1602                 continue;
1603             } catch (final NoSuchMethodException ex) {
1604                 continue;
1605             }
1606         }
1607
1608         try {
1609             return getAnnotation(
1610                     c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()),
1611                     annotationClass);
1612         } catch (final SecurityException ex) {
1613             return null;
1614         } catch (final NoSuchMethodException ex) {
1615             return null;
1616         }
1617     }
1618
1619     /**
1620      * Searches the class hierarchy to see if the method or it's super
1621      * implementations and interfaces has the annotation. Returns the depth of the
1622      * annotation in the hierarchy.
1623      *
1624      * @param <A>
1625      *            type of the annotation
1626      *
1627      * @param m
1628      *            method to check
1629      * @param annotationClass
1630      *            annotation to look for
1631      * @return Depth of the annotation or -1 if the annotation is not on the method.
1632      */

1633     private static int getAnnotationDepth(final Method m, final Class<? extends Annotation> annotationClass) {
1634         // if we have invalid data the result is -1
1635         if (m == null || annotationClass == null) {
1636             return -1;
1637         }
1638
1639         if (m.isAnnotationPresent(annotationClass)) {
1640             return 1;
1641         }
1642
1643         // if we've already reached the Object classreturn -1;
1644         Class<?> c = m.getDeclaringClass();
1645         if (c.getSuperclass() == null) {
1646             return -1;
1647         }
1648
1649         // check directly implemented interfaces for the method being checked
1650         for (Class<?> i : c.getInterfaces()) {
1651             try {
1652                 Method im = i.getMethod(m.getName(), m.getParameterTypes());
1653                 int d = getAnnotationDepth(im, annotationClass);
1654                 if (d > 0) {
1655                     // since the annotation was on the interface, add 1
1656                     return d + 1;
1657                 }
1658             } catch (final SecurityException ex) {
1659                 continue;
1660             } catch (final NoSuchMethodException ex) {
1661                 continue;
1662             }
1663         }
1664
1665         try {
1666             int d = getAnnotationDepth(
1667                     c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()),
1668                     annotationClass);
1669             if (d > 0) {
1670                 // since the annotation was on the superclass, add 1
1671                 return d + 1;
1672             }
1673             return -1;
1674         } catch (final SecurityException ex) {
1675             return -1;
1676         } catch (final NoSuchMethodException ex) {
1677             return -1;
1678         }
1679     }
1680
1681     /**
1682      * Put a key/boolean pair in the JSONObject.
1683      *
1684      * @param key
1685      *            A key string.
1686      * @param value
1687      *            A boolean which is the value.
1688      * @return this.
1689      * @throws JSONException
1690      *            If the value is non-finite number.
1691      * @throws NullPointerException
1692      *            If the key is <code>null</code>.
1693      */

1694     public JSONObject put(String key, boolean value) throws JSONException {
1695         return this.put(key, value ? Boolean.TRUE : Boolean.FALSE);
1696     }
1697
1698     /**
1699      * Put a key/value pair in the JSONObject, where the value will be a
1700      * JSONArray which is produced from a Collection.
1701      *
1702      * @param key
1703      *            A key string.
1704      * @param value
1705      *            A Collection value.
1706      * @return this.
1707      * @throws JSONException
1708      *            If the value is non-finite number.
1709      * @throws NullPointerException
1710      *            If the key is <code>null</code>.
1711      */

1712     public JSONObject put(String key, Collection<?> value) throws JSONException {
1713         return this.put(key, new JSONArray(value));
1714     }
1715
1716     /**
1717      * Put a key/double pair in the JSONObject.
1718      *
1719      * @param key
1720      *            A key string.
1721      * @param value
1722      *            A double which is the value.
1723      * @return this.
1724      * @throws JSONException
1725      *            If the value is non-finite number.
1726      * @throws NullPointerException
1727      *            If the key is <code>null</code>.
1728      */

1729     public JSONObject put(String key, double value) throws JSONException {
1730         return this.put(key, Double.valueOf(value));
1731     }
1732     
1733     /**
1734      * Put a key/float pair in the JSONObject.
1735      *
1736      * @param key
1737      *            A key string.
1738      * @param value
1739      *            A float which is the value.
1740      * @return this.
1741      * @throws JSONException
1742      *            If the value is non-finite number.
1743      * @throws NullPointerException
1744      *            If the key is <code>null</code>.
1745      */

1746     public JSONObject put(String key, float value) throws JSONException {
1747         return this.put(key, Float.valueOf(value));
1748     }
1749
1750     /**
1751      * Put a key/int pair in the JSONObject.
1752      *
1753      * @param key
1754      *            A key string.
1755      * @param value
1756      *            An int which is the value.
1757      * @return this.
1758      * @throws JSONException
1759      *            If the value is non-finite number.
1760      * @throws NullPointerException
1761      *            If the key is <code>null</code>.
1762      */

1763     public JSONObject put(String key, int value) throws JSONException {
1764         return this.put(key, Integer.valueOf(value));
1765     }
1766
1767     /**
1768      * Put a key/long pair in the JSONObject.
1769      *
1770      * @param key
1771      *            A key string.
1772      * @param value
1773      *            A long which is the value.
1774      * @return this.
1775      * @throws JSONException
1776      *            If the value is non-finite number.
1777      * @throws NullPointerException
1778      *            If the key is <code>null</code>.
1779      */

1780     public JSONObject put(String key, long value) throws JSONException {
1781         return this.put(key, Long.valueOf(value));
1782     }
1783
1784     /**
1785      * Put a key/value pair in the JSONObject, where the value will be a
1786      * JSONObject which is produced from a Map.
1787      *
1788      * @param key
1789      *            A key string.
1790      * @param value
1791      *            A Map value.
1792      * @return this.
1793      * @throws JSONException
1794      *            If the value is non-finite number.
1795      * @throws NullPointerException
1796      *            If the key is <code>null</code>.
1797      */

1798     public JSONObject put(String key, Map<?, ?> value) throws JSONException {
1799         return this.put(key, new JSONObject(value));
1800     }
1801
1802     /**
1803      * Put a key/value pair in the JSONObject. If the value is <code>null</code>, then the
1804      * key will be removed from the JSONObject if it is present.
1805      *
1806      * @param key
1807      *            A key string.
1808      * @param value
1809      *            An object which is the value. It should be of one of these
1810      *            types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
1811      *            String, or the JSONObject.NULL object.
1812      * @return this.
1813      * @throws JSONException
1814      *            If the value is non-finite number.
1815      * @throws NullPointerException
1816      *            If the key is <code>null</code>.
1817      */

1818     public JSONObject put(String key, Object value) throws JSONException {
1819         if (key == null) {
1820             throw new NullPointerException("Null key.");
1821         }
1822         if (value != null) {
1823             testValidity(value);
1824             this.map.put(key, value);
1825         } else {
1826             this.remove(key);
1827         }
1828         return this;
1829     }
1830
1831     /**
1832      * Put a key/value pair in the JSONObject, but only if the key and the value
1833      * are both non-null, and only if there is not already a member with that
1834      * name.
1835      *
1836      * @param key
1837      *            key to insert into
1838      * @param value
1839      *            value to insert
1840      * @return this.
1841      * @throws JSONException
1842      *             if the key is a duplicate
1843      */

1844     public JSONObject putOnce(String key, Object value) throws JSONException {
1845         if (key != null && value != null) {
1846             if (this.opt(key) != null) {
1847                 throw new JSONException("Duplicate key \"" + key + "\"");
1848             }
1849             return this.put(key, value);
1850         }
1851         return this;
1852     }
1853
1854     /**
1855      * Put a key/value pair in the JSONObject, but only if the key and the value
1856      * are both non-null.
1857      *
1858      * @param key
1859      *            A key string.
1860      * @param value
1861      *            An object which is the value. It should be of one of these
1862      *            types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
1863      *            String, or the JSONObject.NULL object.
1864      * @return this.
1865      * @throws JSONException
1866      *             If the value is a non-finite number.
1867      */

1868     public JSONObject putOpt(String key, Object value) throws JSONException {
1869         if (key != null && value != null) {
1870             return this.put(key, value);
1871         }
1872         return this;
1873     }
1874
1875     /**
1876      * Creates a JSONPointer using an initialization string and tries to 
1877      * match it to an item within this JSONObject. For example, given a
1878      * JSONObject initialized with this document:
1879      * <pre>
1880      * {
1881      *     "a":{"b":"c"}
1882      * }
1883      * </pre>
1884      * and this JSONPointer string: 
1885      * <pre>
1886      * "/a/b"
1887      * </pre>
1888      * Then this method will return the String "c".
1889      * A JSONPointerException may be thrown from code called by this method.
1890      *   
1891      * @param jsonPointer string that can be used to create a JSONPointer
1892      * @return the item matched by the JSONPointer, otherwise null
1893      */

1894     public Object query(String jsonPointer) {
1895         return query(new JSONPointer(jsonPointer));
1896     }
1897     /**
1898      * Uses a user initialized JSONPointer  and tries to 
1899      * match it to an item within this JSONObject. For example, given a
1900      * JSONObject initialized with this document:
1901      * <pre>
1902      * {
1903      *     "a":{"b":"c"}
1904      * }
1905      * </pre>
1906      * and this JSONPointer: 
1907      * <pre>
1908      * "/a/b"
1909      * </pre>
1910      * Then this method will return the String "c".
1911      * A JSONPointerException may be thrown from code called by this method.
1912      *   
1913      * @param jsonPointer string that can be used to create a JSONPointer
1914      * @return the item matched by the JSONPointer, otherwise null
1915      */

1916     public Object query(JSONPointer jsonPointer) {
1917         return jsonPointer.queryFrom(this);
1918     }
1919     
1920     /**
1921      * Queries and returns a value from this object using {@code jsonPointer}, or
1922      * returns null if the query fails due to a missing key.
1923      * 
1924      * @param jsonPointer the string representation of the JSON pointer
1925      * @return the queried value or {@code null}
1926      * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
1927      */

1928     public Object optQuery(String jsonPointer) {
1929         return optQuery(new JSONPointer(jsonPointer));
1930     }
1931     
1932     /**
1933      * Queries and returns a value from this object using {@code jsonPointer}, or
1934      * returns null if the query fails due to a missing key.
1935      * 
1936      * @param jsonPointer The JSON pointer
1937      * @return the queried value or {@code null}
1938      * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
1939      */

1940     public Object optQuery(JSONPointer jsonPointer) {
1941         try {
1942             return jsonPointer.queryFrom(this);
1943         } catch (JSONPointerException e) {
1944             return null;
1945         }
1946     }
1947
1948     /**
1949      * Produce a string in double quotes with backslash sequences in all the
1950      * right places. A backslash will be inserted within &lt;/, producing
1951      * &lt;\/, allowing JSON text to be delivered in HTML. In JSON text, a
1952      * string cannot contain a control character or an unescaped quote or
1953      * backslash.
1954      *
1955      * @param string
1956      *            A String
1957      * @return A String correctly formatted for insertion in a JSON text.
1958      */

1959     public static String quote(String string) {
1960         StringWriter sw = new StringWriter();
1961         synchronized (sw.getBuffer()) {
1962             try {
1963                 return quote(string, sw).toString();
1964             } catch (IOException ignored) {
1965                 // will never happen - we are writing to a string writer
1966                 return "";
1967             }
1968         }
1969     }
1970
1971     public static Writer quote(String string, Writer w) throws IOException {
1972         if (string == null || string.isEmpty()) {
1973             w.write("\"\"");
1974             return w;
1975         }
1976
1977         char b;
1978         char c = 0;
1979         String hhhh;
1980         int i;
1981         int len = string.length();
1982
1983         w.write('"');
1984         for (i = 0; i < len; i += 1) {
1985             b = c;
1986             c = string.charAt(i);
1987             switch (c) {
1988             case '\\':
1989             case '"':
1990                 w.write('\\');
1991                 w.write(c);
1992                 break;
1993             case '/':
1994                 if (b == '<') {
1995                     w.write('\\');
1996                 }
1997                 w.write(c);
1998                 break;
1999             case '\b':
2000                 w.write("\\b");
2001                 break;
2002             case '\t':
2003                 w.write("\\t");
2004                 break;
2005             case '\n':
2006                 w.write("\\n");
2007                 break;
2008             case '\f':
2009                 w.write("\\f");
2010                 break;
2011             case '\r':
2012                 w.write("\\r");
2013                 break;
2014             default:
2015                 if (c < ' ' || (c >= '\u0080' && c < '\u00a0')
2016                         || (c >= '\u2000' && c < '\u2100')) {
2017                     w.write("\\u");
2018                     hhhh = Integer.toHexString(c);
2019                     w.write("0000", 0, 4 - hhhh.length());
2020                     w.write(hhhh);
2021                 } else {
2022                     w.write(c);
2023                 }
2024             }
2025         }
2026         w.write('"');
2027         return w;
2028     }
2029
2030     /**
2031      * Remove a name and its value, if present.
2032      *
2033      * @param key
2034      *            The name to be removed.
2035      * @return The value that was associated with the name, or null if there was
2036      *         no value.
2037      */

2038     public Object remove(String key) {
2039         return this.map.remove(key);
2040     }
2041
2042     /**
2043      * Determine if two JSONObjects are similar.
2044      * They must contain the same set of names which must be associated with
2045      * similar values.
2046      *
2047      * @param other The other JSONObject
2048      * @return true if they are equal
2049      */

2050     public boolean similar(Object other) {
2051         try {
2052             if (!(other instanceof JSONObject)) {
2053                 return false;
2054             }
2055             if (!this.keySet().equals(((JSONObject)other).keySet())) {
2056                 return false;
2057             }
2058             for (final Entry<String,?> entry : this.entrySet()) {
2059                 String name = entry.getKey();
2060                 Object valueThis = entry.getValue();
2061                 Object valueOther = ((JSONObject)other).get(name);
2062                 if(valueThis == valueOther) {
2063                     continue;
2064                 }
2065                 if(valueThis == null) {
2066                     return false;
2067                 }
2068                 if (valueThis instanceof JSONObject) {
2069                     if (!((JSONObject)valueThis).similar(valueOther)) {
2070                         return false;
2071                     }
2072                 } else if (valueThis instanceof JSONArray) {
2073                     if (!((JSONArray)valueThis).similar(valueOther)) {
2074                         return false;
2075                     }
2076                 } else if (!valueThis.equals(valueOther)) {
2077                     return false;
2078                 }
2079             }
2080             return true;
2081         } catch (Throwable exception) {
2082             return false;
2083         }
2084     }
2085     
2086     /**
2087      * Tests if the value should be tried as a decimal. It makes no test if there are actual digits.
2088      * 
2089      * @param val value to test
2090      * @return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise.
2091      */

2092     protected static boolean isDecimalNotation(final String val) {
2093         return val.indexOf('.') > -1 || val.indexOf('e') > -1
2094                 || val.indexOf('E') > -1 || "-0".equals(val);
2095     }
2096     
2097     /**
2098      * Converts a string to a number using the narrowest possible type. Possible 
2099      * returns for this function are BigDecimal, Double, BigInteger, Long, and Integer.
2100      * When a Double is returned, it should always be a valid Double and not NaN or +-infinity.
2101      * 
2102      * @param val value to convert
2103      * @return Number representation of the value.
2104      * @throws NumberFormatException thrown if the value is not a valid number. A public
2105      *      caller should catch this and wrap it in a {@link JSONException} if applicable.
2106      */

2107     protected static Number stringToNumber(final String val) throws NumberFormatException {
2108         char initial = val.charAt(0);
2109         if ((initial >= '0' && initial <= '9') || initial == '-') {
2110             // decimal representation
2111             if (isDecimalNotation(val)) {
2112                 // Use a BigDecimal all the time so we keep the original
2113                 // representation. BigDecimal doesn't support -0.0, ensure we
2114                 // keep that by forcing a decimal.
2115                 try {
2116                     BigDecimal bd = new BigDecimal(val);
2117                     if(initial == '-' && BigDecimal.ZERO.compareTo(bd)==0) {
2118                         return Double.valueOf(-0.0);
2119                     }
2120                     return bd;
2121                 } catch (NumberFormatException retryAsDouble) {
2122                     // this is to support "Hex Floats" like this: 0x1.0P-1074
2123                     try {
2124                         Double d = Double.valueOf(val);
2125                         if(d.isNaN() || d.isInfinite()) {
2126                             throw new NumberFormatException("val ["+val+"] is not a valid number.");
2127                         }
2128                         return d;
2129                     } catch (NumberFormatException ignore) {
2130                         throw new NumberFormatException("val ["+val+"] is not a valid number.");
2131                     }
2132                 }
2133             }
2134             // block items like 00 01 etc. Java number parsers treat these as Octal.
2135             if(initial == '0' && val.length() > 1) {
2136                 char at1 = val.charAt(1);
2137                 if(at1 >= '0' && at1 <= '9') {
2138                     throw new NumberFormatException("val ["+val+"] is not a valid number.");
2139                 }
2140             } else if (initial == '-' && val.length() > 2) {
2141                 char at1 = val.charAt(1);
2142                 char at2 = val.charAt(2);
2143                 if(at1 == '0' && at2 >= '0' && at2 <= '9') {
2144                     throw new NumberFormatException("val ["+val+"] is not a valid number.");
2145                 }
2146             }
2147             // integer representation.
2148             // This will narrow any values to the smallest reasonable Object representation
2149             // (Integer, Long, or BigInteger)
2150             
2151             // BigInteger down conversion: We use a similar bitLenth compare as
2152             // BigInteger#intValueExact uses. Increases GC, but objects hold
2153             // only what they need. i.e. Less runtime overhead if the value is
2154             // long lived.
2155             BigInteger bi = new BigInteger(val);
2156             if(bi.bitLength() <= 31){
2157                 return Integer.valueOf(bi.intValue());
2158             }
2159             if(bi.bitLength() <= 63){
2160                 return Long.valueOf(bi.longValue());
2161             }
2162             return bi;
2163         }
2164         throw new NumberFormatException("val ["+val+"] is not a valid number.");
2165     }
2166
2167     /**
2168      * Try to convert a string into a number, boolean, or null. If the string
2169      * can't be converted, return the string.
2170      *
2171      * @param string
2172      *            A String. can not be null.
2173      * @return A simple JSON value.
2174      * @throws NullPointerException
2175      *             Thrown if the string is null.
2176      */

2177     // Changes to this method must be copied to the corresponding method in
2178     // the XML class to keep full support for Android
2179     public static Object stringToValue(String string) {
2180         if ("".equals(string)) {
2181             return string;
2182         }
2183
2184         // check JSON key words true/false/null
2185         if ("true".equalsIgnoreCase(string)) {
2186             return Boolean.TRUE;
2187         }
2188         if ("false".equalsIgnoreCase(string)) {
2189             return Boolean.FALSE;
2190         }
2191         if ("null".equalsIgnoreCase(string)) {
2192             return JSONObject.NULL;
2193         }
2194
2195         /*
2196          * If it might be a number, try converting it. If a number cannot be
2197          * produced, then the value will just be a string.
2198          */

2199
2200         char initial = string.charAt(0);
2201         if ((initial >= '0' && initial <= '9') || initial == '-') {
2202             try {
2203                 return stringToNumber(string);
2204             } catch (Exception ignore) {
2205             }
2206         }
2207         return string;
2208     }
2209
2210     /**
2211      * Throw an exception if the object is a NaN or infinite number.
2212      *
2213      * @param o
2214      *            The object to test.
2215      * @throws JSONException
2216      *             If o is a non-finite number.
2217      */

2218     public static void testValidity(Object o) throws JSONException {
2219         if (o != null) {
2220             if (o instanceof Double) {
2221                 if (((Double) o).isInfinite() || ((Double) o).isNaN()) {
2222                     throw new JSONException(
2223                             "JSON does not allow non-finite numbers.");
2224                 }
2225             } else if (o instanceof Float) {
2226                 if (((Float) o).isInfinite() || ((Float) o).isNaN()) {
2227                     throw new JSONException(
2228                             "JSON does not allow non-finite numbers.");
2229                 }
2230             }
2231         }
2232     }
2233
2234     /**
2235      * Produce a JSONArray containing the values of the members of this
2236      * JSONObject.
2237      *
2238      * @param names
2239      *            A JSONArray containing a list of key strings. This determines
2240      *            the sequence of the values in the result.
2241      * @return A JSONArray of values.
2242      * @throws JSONException
2243      *             If any of the values are non-finite numbers.
2244      */

2245     public JSONArray toJSONArray(JSONArray names) throws JSONException {
2246         if (names == null || names.isEmpty()) {
2247             return null;
2248         }
2249         JSONArray ja = new JSONArray();
2250         for (int i = 0; i < names.length(); i += 1) {
2251             ja.put(this.opt(names.getString(i)));
2252         }
2253         return ja;
2254     }
2255
2256     /**
2257      * Make a JSON text of this JSONObject. For compactness, no whitespace is
2258      * added. If this would not result in a syntactically correct JSON text,
2259      * then null will be returned instead.
2260      * <p><b>
2261      * Warning: This method assumes that the data structure is acyclical.
2262      * </b>
2263      * 
2264      * @return a printable, displayable, portable, transmittable representation
2265      *         of the object, beginning with <code>{</code>&nbsp;<small>(left
2266      *         brace)</small> and ending with <code>}</code>&nbsp;<small>(right
2267      *         brace)</small>.
2268      */

2269     @Override
2270     public String toString() {
2271         try {
2272             return this.toString(0);
2273         } catch (Exception e) {
2274             return null;
2275         }
2276     }
2277
2278     /**
2279      * Make a pretty-printed JSON text of this JSONObject.
2280      * 
2281      * <p>If <pre>{@code indentFactor > 0}</pre> and the {@link JSONObject}
2282      * has only one key, then the object will be output on a single line:
2283      * <pre>{@code {"key": 1}}</pre>
2284      * 
2285      * <p>If an object has 2 or more keys, then it will be output across
2286      * multiple lines: <pre>{@code {
2287      *  "key1": 1,
2288      *  "key2""value 2",
2289      *  "key3": 3
2290      * }}</pre>
2291      * <p><b>
2292      * Warning: This method assumes that the data structure is acyclical.
2293      * </b>
2294      *
2295      * @param indentFactor
2296      *            The number of spaces to add to each level of indentation.
2297      * @return a printable, displayable, portable, transmittable representation
2298      *         of the object, beginning with <code>{</code>&nbsp;<small>(left
2299      *         brace)</small> and ending with <code>}</code>&nbsp;<small>(right
2300      *         brace)</small>.
2301      * @throws JSONException
2302      *             If the object contains an invalid number.
2303      */

2304     public String toString(int indentFactor) throws JSONException {
2305         StringWriter w = new StringWriter();
2306         synchronized (w.getBuffer()) {
2307             return this.write(w, indentFactor, 0).toString();
2308         }
2309     }
2310
2311     /**
2312      * Make a JSON text of an Object value. If the object has an
2313      * value.toJSONString() method, then that method will be used to produce the
2314      * JSON text. The method is required to produce a strictly conforming text.
2315      * If the object does not contain a toJSONString method (which is the most
2316      * common case), then a text will be produced by other means. If the value
2317      * is an array or Collection, then a JSONArray will be made from it and its
2318      * toJSONString method will be called. If the value is a MAP, then a
2319      * JSONObject will be made from it and its toJSONString method will be
2320      * called. Otherwise, the value's toString method will be called, and the
2321      * result will be quoted.
2322      *
2323      * <p>
2324      * Warning: This method assumes that the data structure is acyclical.
2325      *
2326      * @param value
2327      *            The value to be serialized.
2328      * @return a printable, displayable, transmittable representation of the
2329      *         object, beginning with <code>{</code>&nbsp;<small>(left
2330      *         brace)</small> and ending with <code>}</code>&nbsp;<small>(right
2331      *         brace)</small>.
2332      * @throws JSONException
2333      *             If the value is or contains an invalid number.
2334      */

2335     public static String valueToString(Object value) throws JSONException {
2336         // moves the implementation to JSONWriter as:
2337         // 1. It makes more sense to be part of the writer class
2338         // 2. For Android support this method is not available. By implementing it in the Writer
2339         //    Android users can use the writer with the built in Android JSONObject implementation.
2340         return JSONWriter.valueToString(value);
2341     }
2342
2343     /**
2344      * Wrap an object, if necessary. If the object is <code>null</code>, return the NULL
2345      * object. If it is an array or collection, wrap it in a JSONArray. If it is
2346      * a map, wrap it in a JSONObject. If it is a standard property (Double,
2347      * String, et al) then it is already wrapped. Otherwise, if it comes from
2348      * one of the java packages, turn it into a string. And if it doesn't, try
2349      * to wrap it in a JSONObject. If the wrapping fails, then null is returned.
2350      *
2351      * @param object
2352      *            The object to wrap
2353      * @return The wrapped value
2354      */

2355     public static Object wrap(Object object) {
2356         try {
2357             if (object == null) {
2358                 return NULL;
2359             }
2360             if (object instanceof JSONObject || object instanceof JSONArray
2361                     || NULL.equals(object) || object instanceof JSONString
2362                     || object instanceof Byte || object instanceof Character
2363                     || object instanceof Short || object instanceof Integer
2364                     || object instanceof Long || object instanceof Boolean
2365                     || object instanceof Float || object instanceof Double
2366                     || object instanceof String || object instanceof BigInteger
2367                     || object instanceof BigDecimal || object instanceof Enum) {
2368                 return object;
2369             }
2370
2371             if (object instanceof Collection) {
2372                 Collection<?> coll = (Collection<?>) object;
2373                 return new JSONArray(coll);
2374             }
2375             if (object.getClass().isArray()) {
2376                 return new JSONArray(object);
2377             }
2378             if (object instanceof Map) {
2379                 Map<?, ?> map = (Map<?, ?>) object;
2380                 return new JSONObject(map);
2381             }
2382             Package objectPackage = object.getClass().getPackage();
2383             String objectPackageName = objectPackage != null ? objectPackage
2384                     .getName() : "";
2385             if (objectPackageName.startsWith("java.")
2386                     || objectPackageName.startsWith("javax.")
2387                     || object.getClass().getClassLoader() == null) {
2388                 return object.toString();
2389             }
2390             return new JSONObject(object);
2391         } catch (Exception exception) {
2392             return null;
2393         }
2394     }
2395
2396     /**
2397      * Write the contents of the JSONObject as JSON text to a writer. For
2398      * compactness, no whitespace is added.
2399      * <p><b>
2400      * Warning: This method assumes that the data structure is acyclical.
2401      * </b>
2402      * @param writer the writer object
2403      * @return The writer.
2404      * @throws JSONException if a called function has an error
2405      */

2406     public Writer write(Writer writer) throws JSONException {
2407         return this.write(writer, 0, 0);
2408     }
2409
2410     static final Writer writeValue(Writer writer, Object value,
2411             int indentFactor, int indent) throws JSONException, IOException {
2412         if (value == null || value.equals(null)) {
2413             writer.write("null");
2414         } else if (value instanceof JSONString) {
2415             Object o;
2416             try {
2417                 o = ((JSONString) value).toJSONString();
2418             } catch (Exception e) {
2419                 throw new JSONException(e);
2420             }
2421             writer.write(o != null ? o.toString() : quote(value.toString()));
2422         } else if (value instanceof Number) {
2423             // not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
2424             final String numberAsString = numberToString((Number) value);
2425             if(NUMBER_PATTERN.matcher(numberAsString).matches()) {
2426                 writer.write(numberAsString);
2427             } else {
2428                 // The Number value is not a valid JSON number.
2429                 // Instead we will quote it as a string
2430                 quote(numberAsString, writer);
2431             }
2432         } else if (value instanceof Boolean) {
2433             writer.write(value.toString());
2434         } else if (value instanceof Enum<?>) {
2435             writer.write(quote(((Enum<?>)value).name()));
2436         } else if (value instanceof JSONObject) {
2437             ((JSONObject) value).write(writer, indentFactor, indent);
2438         } else if (value instanceof JSONArray) {
2439             ((JSONArray) value).write(writer, indentFactor, indent);
2440         } else if (value instanceof Map) {
2441             Map<?, ?> map = (Map<?, ?>) value;
2442             new JSONObject(map).write(writer, indentFactor, indent);
2443         } else if (value instanceof Collection) {
2444             Collection<?> coll = (Collection<?>) value;
2445             new JSONArray(coll).write(writer, indentFactor, indent);
2446         } else if (value.getClass().isArray()) {
2447             new JSONArray(value).write(writer, indentFactor, indent);
2448         } else {
2449             quote(value.toString(), writer);
2450         }
2451         return writer;
2452     }
2453
2454     static final void indent(Writer writer, int indent) throws IOException {
2455         for (int i = 0; i < indent; i += 1) {
2456             writer.write(' ');
2457         }
2458     }
2459
2460     /**
2461      * Write the contents of the JSONObject as JSON text to a writer.
2462      * 
2463      * <p>If <pre>{@code indentFactor > 0}</pre> and the {@link JSONObject}
2464      * has only one key, then the object will be output on a single line:
2465      * <pre>{@code {"key": 1}}</pre>
2466      * 
2467      * <p>If an object has 2 or more keys, then it will be output across
2468      * multiple lines: <pre>{@code {
2469      *  "key1": 1,
2470      *  "key2""value 2",
2471      *  "key3": 3
2472      * }}</pre>
2473      * <p><b>
2474      * Warning: This method assumes that the data structure is acyclical.
2475      * </b>
2476      *
2477      * @param writer
2478      *            Writes the serialized JSON
2479      * @param indentFactor
2480      *            The number of spaces to add to each level of indentation.
2481      * @param indent
2482      *            The indentation of the top level.
2483      * @return The writer.
2484      * @throws JSONException if a called function has an error or a write error
2485      * occurs
2486      */

2487     public Writer write(Writer writer, int indentFactor, int indent)
2488             throws JSONException {
2489         try {
2490             boolean needsComma = false;
2491             final int length = this.length();
2492             writer.write('{');
2493
2494             if (length == 1) {
2495                 final Entry<String,?> entry = this.entrySet().iterator().next();
2496                 final String key = entry.getKey();
2497                 writer.write(quote(key));
2498                 writer.write(':');
2499                 if (indentFactor > 0) {
2500                     writer.write(' ');
2501                 }
2502                 try{
2503                     writeValue(writer, entry.getValue(), indentFactor, indent);
2504                 } catch (Exception e) {
2505                     throw new JSONException("Unable to write JSONObject value for key: " + key, e);
2506                 }
2507             } else if (length != 0) {
2508                 final int newIndent = indent + indentFactor;
2509                 for (final Entry<String,?> entry : this.entrySet()) {
2510                     if (needsComma) {
2511                         writer.write(',');
2512                     }
2513                     if (indentFactor > 0) {
2514                         writer.write('\n');
2515                     }
2516                     indent(writer, newIndent);
2517                     final String key = entry.getKey();
2518                     writer.write(quote(key));
2519                     writer.write(':');
2520                     if (indentFactor > 0) {
2521                         writer.write(' ');
2522                     }
2523                     try {
2524                         writeValue(writer, entry.getValue(), indentFactor, newIndent);
2525                     } catch (Exception e) {
2526                         throw new JSONException("Unable to write JSONObject value for key: " + key, e);
2527                     }
2528                     needsComma = true;
2529                 }
2530                 if (indentFactor > 0) {
2531                     writer.write('\n');
2532                 }
2533                 indent(writer, indent);
2534             }
2535             writer.write('}');
2536             return writer;
2537         } catch (IOException exception) {
2538             throw new JSONException(exception);
2539         }
2540     }
2541
2542     /**
2543      * Returns a java.util.Map containing all of the entries in this object.
2544      * If an entry in the object is a JSONArray or JSONObject it will also
2545      * be converted.
2546      * <p>
2547      * Warning: This method assumes that the data structure is acyclical.
2548      *
2549      * @return a java.util.Map containing the entries of this object
2550      */

2551     public Map<String, Object> toMap() {
2552         Map<String, Object> results = new HashMap<String, Object>();
2553         for (Entry<String, Object> entry : this.entrySet()) {
2554             Object value;
2555             if (entry.getValue() == null || NULL.equals(entry.getValue())) {
2556                 value = null;
2557             } else if (entry.getValue() instanceof JSONObject) {
2558                 value = ((JSONObject) entry.getValue()).toMap();
2559             } else if (entry.getValue() instanceof JSONArray) {
2560                 value = ((JSONArray) entry.getValue()).toList();
2561             } else {
2562                 value = entry.getValue();
2563             }
2564             results.put(entry.getKey(), value);
2565         }
2566         return results;
2567     }
2568     
2569     /**
2570      * Create a new JSONException in a common format for incorrect conversions.
2571      * @param key name of the key
2572      * @param valueType the type of value being coerced to
2573      * @param cause optional cause of the coercion failure
2574      * @return JSONException that can be thrown.
2575      */

2576     private static JSONException wrongValueFormatException(
2577             String key,
2578             String valueType,
2579             Throwable cause) {
2580         return new JSONException(
2581                 "JSONObject[" + quote(key) + "] is not a " + valueType + "."
2582                 , cause);
2583     }
2584     
2585     /**
2586      * Create a new JSONException in a common format for incorrect conversions.
2587      * @param key name of the key
2588      * @param valueType the type of value being coerced to
2589      * @param cause optional cause of the coercion failure
2590      * @return JSONException that can be thrown.
2591      */

2592     private static JSONException wrongValueFormatException(
2593             String key,
2594             String valueType,
2595             Object value,
2596             Throwable cause) {
2597         return new JSONException(
2598                 "JSONObject[" + quote(key) + "] is not a " + valueType + " (" + value + ")."
2599                 , cause);
2600     }
2601 }
2602