JSON writing fix, JColorChooser (mnemonic change) fix
[jalview.git] / srcjar / org / json / JSONObject.java
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
49 /**
50  * A JSONObject is an unordered collection of name/value pairs. Its external
51  * form is a string wrapped in curly braces with colons between the names and
52  * values, and commas between the values and names. The internal form is an
53  * object having <code>get</code> and <code>opt</code> methods for accessing
54  * the values by name, and <code>put</code> methods for adding or replacing
55  * values by name. The values can be any of these types: <code>Boolean</code>,
56  * <code>JSONArray</code>, <code>JSONObject</code>, <code>Number</code>,
57  * <code>String</code>, or the <code>JSONObject.NULL</code> object. A
58  * JSONObject constructor can be used to convert an external form JSON text
59  * into an internal form whose values can be retrieved with the
60  * <code>get</code> and <code>opt</code> methods, or to convert values into a
61  * JSON text using the <code>put</code> and <code>toString</code> methods. A
62  * <code>get</code> method returns a value if one can be found, and throws an
63  * exception if one cannot be found. An <code>opt</code> method returns a
64  * default value instead of throwing an exception, and so is useful for
65  * obtaining optional values.
66  * <p>
67  * The generic <code>get()</code> and <code>opt()</code> methods return an
68  * object, which you can cast or query for type. There are also typed
69  * <code>get</code> and <code>opt</code> methods that do type checking and type
70  * coercion for you. The opt methods differ from the get methods in that they
71  * do not throw. Instead, they return a specified value, such as null.
72  * <p>
73  * The <code>put</code> methods add or replace values in an object. For
74  * example,
75  *
76  * <pre>
77  * myString = new JSONObject()
78  *         .put(&quot;JSON&quot;, &quot;Hello, World!&quot;).toString();
79  * </pre>
80  *
81  * produces the string <code>{"JSON": "Hello, World"}</code>.
82  * <p>
83  * The texts produced by the <code>toString</code> methods strictly conform to
84  * the JSON syntax rules. The constructors are more forgiving in the texts they
85  * will accept:
86  * <ul>
87  * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just
88  * before the closing brace.</li>
89  * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single
90  * quote)</small>.</li>
91  * <li>Strings do not need to be quoted at all if they do not begin with a
92  * quote or single quote, and if they do not contain leading or trailing
93  * spaces, and if they do not contain any of these characters:
94  * <code>{ } [ ] / \ : , #</code> and if they do not look like numbers and
95  * if they are not the reserved words <code>true</code>, <code>false</code>,
96  * or <code>null</code>.</li>
97  * </ul>
98  *
99  * @author JSON.org
100  * @version 2016-08-15
101  */
102 public class JSONObject {
103     /**
104      * JSONObject.NULL is equivalent to the value that JavaScript calls null,
105      * whilst Java's null is equivalent to the value that JavaScript calls
106      * undefined.
107      */
108     private static final class Null {
109
110         /**
111          * There is only intended to be a single instance of the NULL object,
112          * so the clone method returns itself.
113          *
114          * @return NULL.
115          */
116         @Override
117         protected final Object clone() {
118             return this;
119         }
120
121         /**
122          * A Null object is equal to the null value and to itself.
123          *
124          * @param object
125          *            An object to test for nullness.
126          * @return true if the object parameter is the JSONObject.NULL object or
127          *         null.
128          */
129         @Override
130         public boolean equals(Object object) {
131             return object == null || object == this;
132         }
133         /**
134          * A Null object is equal to the null value and to itself.
135          *
136          * @return always returns 0.
137          */
138         @Override
139         public int hashCode() {
140             return 0;
141         }
142
143         /**
144          * Get the "null" string value.
145          *
146          * @return The string "null".
147          */
148         @Override
149         public String toString() {
150             return "null";
151         }
152     }
153
154     /**
155      * The map where the JSONObject's properties are kept.
156      */
157     private final Map<String, Object> map;
158
159     /**
160      * It is sometimes more convenient and less ambiguous to have a
161      * <code>NULL</code> object than to use Java's <code>null</code> value.
162      * <code>JSONObject.NULL.equals(null)</code> returns <code>true</code>.
163      * <code>JSONObject.NULL.toString()</code> returns <code>"null"</code>.
164      */
165     public static final Object NULL = new Null();
166
167     /**
168      * Construct an empty JSONObject.
169      */
170     public JSONObject() {
171         // HashMap is used on purpose to ensure that elements are unordered by 
172         // the specification.
173         // JSON tends to be a portable transfer format to allows the container 
174         // implementations to rearrange their items for a faster element 
175         // retrieval based on associative access.
176         // Therefore, an implementation mustn't rely on the order of the item.
177         this.map = new HashMap<String, Object>();
178     }
179
180     /**
181      * Construct a JSONObject from a subset of another JSONObject. An array of
182      * strings is used to identify the keys that should be copied. Missing keys
183      * are ignored.
184      *
185      * @param jo
186      *            A JSONObject.
187      * @param names
188      *            An array of strings.
189      */
190     public JSONObject(JSONObject jo, String[] names) {
191         this(names.length);
192         for (int i = 0; i < names.length; i += 1) {
193             try {
194                 this.putOnce(names[i], jo.opt(names[i]));
195             } catch (Exception ignore) {
196             }
197         }
198     }
199
200     /**
201      * Construct a JSONObject from a JSONTokener.
202      *
203      * @param x
204      *            A JSONTokener object containing the source string.
205      * @throws JSONException
206      *             If there is a syntax error in the source string or a
207      *             duplicated key.
208      */
209     public JSONObject(JSONTokener x) throws JSONException {
210         this();
211         char c;
212         String key;
213
214         if (x.nextClean() != '{') {
215             throw x.syntaxError("A JSONObject text must begin with '{'");
216         }
217         for (;;) {
218             c = x.nextClean();
219             switch (c) {
220             case 0:
221                 throw x.syntaxError("A JSONObject text must end with '}'");
222             case '}':
223                 return;
224             default:
225                 x.back();
226                 key = x.nextValue().toString();
227             }
228
229             // The key is followed by ':'.
230
231             c = x.nextClean();
232             if (c != ':') {
233                 throw x.syntaxError("Expected a ':' after a key");
234             }
235             
236             // Use syntaxError(..) to include error location
237             
238             if (key != null) {
239                 // Check if key exists
240                 if (this.opt(key) != null) {
241                     // key already exists
242                     throw x.syntaxError("Duplicate key \"" + key + "\"");
243                 }
244                 // Only add value if non-null
245                 Object value = x.nextValue();
246                 if (value!=null) {
247                     this.put(key, value);
248                 }
249             }
250
251             // Pairs are separated by ','.
252
253             switch (x.nextClean()) {
254             case ';':
255             case ',':
256                 if (x.nextClean() == '}') {
257                     return;
258                 }
259                 x.back();
260                 break;
261             case '}':
262                 return;
263             default:
264                 throw x.syntaxError("Expected a ',' or '}'");
265             }
266         }
267     }
268
269     /**
270      * Construct a JSONObject from a Map.
271      *
272      * @param m
273      *            A map object that can be used to initialize the contents of
274      *            the JSONObject.
275      * @throws JSONException
276      *            If a value in the map is non-finite number.
277      * @throws NullPointerException
278      *            If a key in the map is <code>null</code>
279      */
280     public JSONObject(Map<?, ?> m) {
281         if (m == null) {
282             this.map = new HashMap<String, Object>();
283         } else {
284             this.map = new HashMap<String, Object>(m.size());
285                 for (final Entry<?, ?> e : m.entrySet()) {
286                     if(e.getKey() == null) {
287                         throw new NullPointerException("Null key.");
288                     }
289                 final Object value = e.getValue();
290                 if (value != null) {
291                     this.map.put(String.valueOf(e.getKey()), wrap(value));
292                 }
293             }
294         }
295     }
296
297     /**
298      * Construct a JSONObject from an Object using bean getters. It reflects on
299      * all of the public methods of the object. For each of the methods with no
300      * parameters and a name starting with <code>"get"</code> or
301      * <code>"is"</code> followed by an uppercase letter, the method is invoked,
302      * and a key and the value returned from the getter method are put into the
303      * new JSONObject.
304      * <p>
305      * The key is formed by removing the <code>"get"</code> or <code>"is"</code>
306      * prefix. If the second remaining character is not upper case, then the
307      * first character is converted to lower case.
308      * <p>
309      * Methods that are <code>static</code>, return <code>void</code>,
310      * have parameters, or are "bridge" methods, are ignored.
311      * <p>
312      * For example, if an object has a method named <code>"getName"</code>, and
313      * if the result of calling <code>object.getName()</code> is
314      * <code>"Larry Fine"</code>, then the JSONObject will contain
315      * <code>"name": "Larry Fine"</code>.
316      * <p>
317      * The {@link JSONPropertyName} annotation can be used on a bean getter to
318      * override key name used in the JSONObject. For example, using the object
319      * above with the <code>getName</code> method, if we annotated it with:
320      * <pre>
321      * &#64;JSONPropertyName("FullName")
322      * public String getName() { return this.name; }
323      * </pre>
324      * The resulting JSON object would contain <code>"FullName": "Larry Fine"</code>
325      * <p>
326      * Similarly, the {@link JSONPropertyName} annotation can be used on non-
327      * <code>get</code> and <code>is</code> methods. We can also override key
328      * name used in the JSONObject as seen below even though the field would normally
329      * be ignored:
330      * <pre>
331      * &#64;JSONPropertyName("FullName")
332      * public String fullName() { return this.name; }
333      * </pre>
334      * The resulting JSON object would contain <code>"FullName": "Larry Fine"</code>
335      * <p>
336      * The {@link JSONPropertyIgnore} annotation can be used to force the bean property
337      * to not be serialized into JSON. If both {@link JSONPropertyIgnore} and
338      * {@link JSONPropertyName} are defined on the same method, a depth comparison is
339      * performed and the one closest to the concrete class being serialized is used.
340      * If both annotations are at the same level, then the {@link JSONPropertyIgnore}
341      * annotation takes precedent and the field is not serialized.
342      * For example, the following declaration would prevent the <code>getName</code>
343      * method from being serialized:
344      * <pre>
345      * &#64;JSONPropertyName("FullName")
346      * &#64;JSONPropertyIgnore 
347      * public String getName() { return this.name; }
348      * </pre>
349      * <p>
350      * 
351      * @param bean
352      *            An object that has getter methods that should be used to make
353      *            a JSONObject.
354      */
355     public JSONObject(Object bean) {
356         this();
357         this.populateMap(bean);
358     }
359
360     /**
361      * Construct a JSONObject from an Object, using reflection to find the
362      * public members. The resulting JSONObject's keys will be the strings from
363      * the names array, and the values will be the field values associated with
364      * those keys in the object. If a key is not found or not visible, then it
365      * will not be copied into the new JSONObject.
366      *
367      * @param object
368      *            An object that has fields that should be used to make a
369      *            JSONObject.
370      * @param names
371      *            An array of strings, the names of the fields to be obtained
372      *            from the object.
373      */
374     public JSONObject(Object object, String names[]) {
375         this(names.length);
376         Class<?> c = object.getClass();
377         for (int i = 0; i < names.length; i += 1) {
378             String name = names[i];
379             try {
380                 this.putOpt(name, c.getField(name).get(object));
381             } catch (Exception ignore) {
382             }
383         }
384     }
385
386     /**
387      * Construct a JSONObject from a source JSON text string. This is the most
388      * commonly used JSONObject constructor.
389      *
390      * @param source
391      *            A string beginning with <code>{</code>&nbsp;<small>(left
392      *            brace)</small> and ending with <code>}</code>
393      *            &nbsp;<small>(right brace)</small>.
394      * @exception JSONException
395      *                If there is a syntax error in the source string or a
396      *                duplicated key.
397      */
398     public JSONObject(String source) throws JSONException {
399         this(new JSONTokener(source));
400     }
401
402     /**
403      * Construct a JSONObject from a ResourceBundle.
404      *
405      * @param baseName
406      *            The ResourceBundle base name.
407      * @param locale
408      *            The Locale to load the ResourceBundle for.
409      * @throws JSONException
410      *             If any JSONExceptions are detected.
411      */
412     public JSONObject(String baseName, Locale locale) throws JSONException {
413         this();
414         ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale,
415                 Thread.currentThread().getContextClassLoader());
416
417 // Iterate through the keys in the bundle.
418
419         Enumeration<String> keys = bundle.getKeys();
420         while (keys.hasMoreElements()) {
421             Object key = keys.nextElement();
422             if (key != null) {
423
424 // Go through the path, ensuring that there is a nested JSONObject for each
425 // segment except the last. Add the value using the last segment's name into
426 // the deepest nested JSONObject.
427
428                 String[] path = ((String) key).split("\\.");
429                 int last = path.length - 1;
430                 JSONObject target = this;
431                 for (int i = 0; i < last; i += 1) {
432                     String segment = path[i];
433                     JSONObject nextTarget = target.optJSONObject(segment);
434                     if (nextTarget == null) {
435                         nextTarget = new JSONObject();
436                         target.put(segment, nextTarget);
437                     }
438                     target = nextTarget;
439                 }
440                 target.put(path[last], bundle.getString((String) key));
441             }
442         }
443     }
444     
445     /**
446      * Constructor to specify an initial capacity of the internal map. Useful for library 
447      * internal calls where we know, or at least can best guess, how big this JSONObject
448      * will be.
449      * 
450      * @param initialCapacity initial capacity of the internal map.
451      */
452     protected JSONObject(int initialCapacity){
453         this.map = new HashMap<String, Object>(initialCapacity);
454     }
455
456     /**
457      * Accumulate values under a key. It is similar to the put method except
458      * that if there is already an object stored under the key then a JSONArray
459      * is stored under the key to hold all of the accumulated values. If there
460      * is already a JSONArray, then the new value is appended to it. In
461      * contrast, the put method replaces the previous value.
462      *
463      * If only one value is accumulated that is not a JSONArray, then the result
464      * will be the same as using put. But if multiple values are accumulated,
465      * then the result will be like append.
466      *
467      * @param key
468      *            A key string.
469      * @param value
470      *            An object to be accumulated under the key.
471      * @return this.
472      * @throws JSONException
473      *            If the value is non-finite number.
474      * @throws NullPointerException
475      *            If the key is <code>null</code>.
476      */
477     public JSONObject accumulate(String key, Object value) throws JSONException {
478         testValidity(value);
479         Object object = this.opt(key);
480         if (object == null) {
481             this.put(key,
482                     value instanceof JSONArray ? new JSONArray().put(value)
483                             : value);
484         } else if (object instanceof JSONArray) {
485             ((JSONArray) object).put(value);
486         } else {
487             this.put(key, new JSONArray().put(object).put(value));
488         }
489         return this;
490     }
491
492     /**
493      * Append values to the array under a key. If the key does not exist in the
494      * JSONObject, then the key is put in the JSONObject with its value being a
495      * JSONArray containing the value parameter. If the key was already
496      * associated with a JSONArray, then the value parameter is appended to it.
497      *
498      * @param key
499      *            A key string.
500      * @param value
501      *            An object to be accumulated under the key.
502      * @return this.
503      * @throws JSONException
504      *            If the value is non-finite number or if the current value associated with
505      *             the key is not a JSONArray.
506      * @throws NullPointerException
507      *            If the key is <code>null</code>.
508      */
509     public JSONObject append(String key, Object value) throws JSONException {
510         testValidity(value);
511         Object object = this.opt(key);
512         if (object == null) {
513             this.put(key, new JSONArray().put(value));
514         } else if (object instanceof JSONArray) {
515             this.put(key, ((JSONArray) object).put(value));
516         } else {
517             throw new JSONException("JSONObject[" + key
518                     + "] is not a JSONArray.");
519         }
520         return this;
521     }
522
523     /**
524      * Produce a string from a double. The string "null" will be returned if the
525      * number is not finite.
526      *
527      * @param d
528      *            A double.
529      * @return A String.
530      */
531     public static String doubleToString(double d) {
532         if (Double.isInfinite(d) || Double.isNaN(d)) {
533             return "null";
534         }
535
536 // Shave off trailing zeros and decimal point, if possible.
537
538         String string = Double.toString(d);
539         if (string.indexOf('.') > 0 && string.indexOf('e') < 0
540                 && string.indexOf('E') < 0) {
541             while (string.endsWith("0")) {
542                 string = string.substring(0, string.length() - 1);
543             }
544             if (string.endsWith(".")) {
545                 string = string.substring(0, string.length() - 1);
546             }
547         }
548         return string;
549     }
550
551     /**
552      * Get the value object associated with a key.
553      *
554      * @param key
555      *            A key string.
556      * @return The object associated with the key.
557      * @throws JSONException
558      *             if the key is not found.
559      */
560     public Object get(String key) throws JSONException {
561         if (key == null) {
562             throw new JSONException("Null key.");
563         }
564         Object object = this.opt(key);
565         if (object == null) {
566             throw new JSONException("JSONObject[" + quote(key) + "] not found.");
567         }
568         return object;
569     }
570
571     /**
572     * Get the enum value associated with a key.
573     * 
574     * @param clazz
575     *           The type of enum to retrieve.
576     * @param key
577     *           A key string.
578     * @return The enum value associated with the key
579     * @throws JSONException
580     *             if the key is not found or if the value cannot be converted
581     *             to an enum.
582     */
583     public <E extends Enum<E>> E getEnum(Class<E> clazz, String key) throws JSONException {
584         E val = optEnum(clazz, key);
585         if(val==null) {
586             // JSONException should really take a throwable argument.
587             // If it did, I would re-implement this with the Enum.valueOf
588             // method and place any thrown exception in the JSONException
589             throw new JSONException("JSONObject[" + quote(key)
590                     + "] is not an enum of type " + quote(clazz.getSimpleName())
591                     + ".");
592         }
593         return val;
594     }
595
596     /**
597      * Get the boolean value associated with a key.
598      *
599      * @param key
600      *            A key string.
601      * @return The truth.
602      * @throws JSONException
603      *             if the value is not a Boolean or the String "true" or
604      *             "false".
605      */
606     public boolean getBoolean(String key) throws JSONException {
607         Object object = this.get(key);
608         if (object.equals(Boolean.FALSE)
609                 || (object instanceof String && ((String) object)
610                         .equalsIgnoreCase("false"))) {
611             return false;
612         } else if (object.equals(Boolean.TRUE)
613                 || (object instanceof String && ((String) object)
614                         .equalsIgnoreCase("true"))) {
615             return true;
616         }
617         throw new JSONException("JSONObject[" + quote(key)
618                 + "] is not a Boolean.");
619     }
620
621     /**
622      * Get the BigInteger value associated with a key.
623      *
624      * @param key
625      *            A key string.
626      * @return The numeric value.
627      * @throws JSONException
628      *             if the key is not found or if the value cannot 
629      *             be converted to BigInteger.
630      */
631     public BigInteger getBigInteger(String key) throws JSONException {
632         Object object = this.get(key);
633         try {
634             return new BigInteger(object.toString());
635         } catch (Exception e) {
636             throw new JSONException("JSONObject[" + quote(key)
637                     + "] could not be converted to BigInteger.", e);
638         }
639     }
640
641     /**
642      * Get the BigDecimal value associated with a key.
643      *
644      * @param key
645      *            A key string.
646      * @return The numeric value.
647      * @throws JSONException
648      *             if the key is not found or if the value
649      *             cannot be converted to BigDecimal.
650      */
651     public BigDecimal getBigDecimal(String key) throws JSONException {
652         Object object = this.get(key);
653         if (object instanceof BigDecimal) {
654             return (BigDecimal)object;
655         }
656         try {
657             return new BigDecimal(object.toString());
658         } catch (Exception e) {
659             throw new JSONException("JSONObject[" + quote(key)
660                     + "] could not be converted to BigDecimal.", e);
661         }
662     }
663
664     /**
665      * Get the double value associated with a key.
666      *
667      * @param key
668      *            A key string.
669      * @return The numeric value.
670      * @throws JSONException
671      *             if the key is not found or if the value is not a Number
672      *             object and cannot be converted to a number.
673      */
674     public double getDouble(String key) throws JSONException {
675         Object object = this.get(key);
676         try {
677             return object instanceof Number ? ((Number) object).doubleValue()
678                     : Double.parseDouble(object.toString());
679         } catch (Exception e) {
680             throw new JSONException("JSONObject[" + quote(key)
681                     + "] is not a number.", e);
682         }
683     }
684
685     /**
686      * Get the float value associated with a key.
687      *
688      * @param key
689      *            A key string.
690      * @return The numeric value.
691      * @throws JSONException
692      *             if the key is not found or if the value is not a Number
693      *             object and cannot be converted to a number.
694      */
695     public float getFloat(String key) throws JSONException {
696         Object object = this.get(key);
697         try {
698             return object instanceof Number ? ((Number) object).floatValue()
699                     : Float.parseFloat(object.toString());
700         } catch (Exception e) {
701             throw new JSONException("JSONObject[" + quote(key)
702                     + "] is not a number.", e);
703         }
704     }
705
706     /**
707      * Get the Number value associated with a key.
708      *
709      * @param key
710      *            A key string.
711      * @return The numeric value.
712      * @throws JSONException
713      *             if the key is not found or if the value is not a Number
714      *             object and cannot be converted to a number.
715      */
716     public Number getNumber(String key) throws JSONException {
717         Object object = this.get(key);
718         try {
719             if (object instanceof Number) {
720                 return (Number)object;
721             }
722             return stringToNumber(object.toString());
723         } catch (Exception e) {
724             throw new JSONException("JSONObject[" + quote(key)
725                     + "] is not a number.", e);
726         }
727     }
728
729     /**
730      * Get the int value associated with a key.
731      *
732      * @param key
733      *            A key string.
734      * @return The integer value.
735      * @throws JSONException
736      *             if the key is not found or if the value cannot be converted
737      *             to an integer.
738      */
739     public int getInt(String key) throws JSONException {
740         Object object = this.get(key);
741         try {
742             return object instanceof Number ? ((Number) object).intValue()
743                     : Integer.parseInt((String) object);
744         } catch (Exception e) {
745             throw new JSONException("JSONObject[" + quote(key)
746                     + "] is not an int.", e);
747         }
748     }
749
750     /**
751      * Get the JSONArray value associated with a key.
752      *
753      * @param key
754      *            A key string.
755      * @return A JSONArray which is the value.
756      * @throws JSONException
757      *             if the key is not found or if the value is not a JSONArray.
758      */
759     public JSONArray getJSONArray(String key) throws JSONException {
760         Object object = this.get(key);
761         if (object instanceof JSONArray) {
762             return (JSONArray) object;
763         }
764         throw new JSONException("JSONObject[" + quote(key)
765                 + "] is not a JSONArray.");
766     }
767
768     /**
769      * Get the JSONObject value associated with a key.
770      *
771      * @param key
772      *            A key string.
773      * @return A JSONObject which is the value.
774      * @throws JSONException
775      *             if the key is not found or if the value is not a JSONObject.
776      */
777     public JSONObject getJSONObject(String key) throws JSONException {
778         Object object = this.get(key);
779         if (object instanceof JSONObject) {
780             return (JSONObject) object;
781         }
782         throw new JSONException("JSONObject[" + quote(key)
783                 + "] is not a JSONObject.");
784     }
785
786     /**
787      * Get the long value associated with a key.
788      *
789      * @param key
790      *            A key string.
791      * @return The long value.
792      * @throws JSONException
793      *             if the key is not found or if the value cannot be converted
794      *             to a long.
795      */
796     public long getLong(String key) throws JSONException {
797         Object object = this.get(key);
798         try {
799             return object instanceof Number ? ((Number) object).longValue()
800                     : Long.parseLong((String) object);
801         } catch (Exception e) {
802             throw new JSONException("JSONObject[" + quote(key)
803                     + "] is not a long.", e);
804         }
805     }
806
807     /**
808      * Get an array of field names from a JSONObject.
809      *
810      * @return An array of field names, or null if there are no names.
811      */
812     public static String[] getNames(JSONObject jo) {
813         if (jo.isEmpty()) {
814             return null;
815         }
816         return jo.keySet().toArray(new String[jo.length()]);
817     }
818
819     /**
820      * Get an array of field names from an Object.
821      *
822      * @return An array of field names, or null if there are no names.
823      */
824     public static String[] getNames(Object object) {
825         if (object == null) {
826             return null;
827         }
828         Class<?> klass = object.getClass();
829         Field[] fields = klass.getFields();
830         int length = fields.length;
831         if (length == 0) {
832             return null;
833         }
834         String[] names = new String[length];
835         for (int i = 0; i < length; i += 1) {
836             names[i] = fields[i].getName();
837         }
838         return names;
839     }
840
841     /**
842      * Get the string associated with a key.
843      *
844      * @param key
845      *            A key string.
846      * @return A string which is the value.
847      * @throws JSONException
848      *             if there is no string value for the key.
849      */
850     public String getString(String key) throws JSONException {
851         Object object = this.get(key);
852         if (object instanceof String) {
853             return (String) object;
854         }
855         throw new JSONException("JSONObject[" + quote(key) + "] not a string.");
856     }
857
858     /**
859      * Determine if the JSONObject contains a specific key.
860      *
861      * @param key
862      *            A key string.
863      * @return true if the key exists in the JSONObject.
864      */
865     public boolean has(String key) {
866         return this.map.containsKey(key);
867     }
868
869     /**
870      * Increment a property of a JSONObject. If there is no such property,
871      * create one with a value of 1. If there is such a property, and if it is
872      * an Integer, Long, Double, or Float, then add one to it.
873      *
874      * @param key
875      *            A key string.
876      * @return this.
877      * @throws JSONException
878      *             If there is already a property with this name that is not an
879      *             Integer, Long, Double, or Float.
880      */
881     public JSONObject increment(String key) throws JSONException {
882         Object value = this.opt(key);
883         if (value == null) {
884             this.put(key, 1);
885         } else if (value instanceof BigInteger) {
886             this.put(key, ((BigInteger)value).add(BigInteger.ONE));
887         } else if (value instanceof BigDecimal) {
888             this.put(key, ((BigDecimal)value).add(BigDecimal.ONE));
889         } else if (value instanceof Integer) {
890             this.put(key, ((Integer) value).intValue() + 1);
891         } else if (value instanceof Long) {
892             this.put(key, ((Long) value).longValue() + 1L);
893         } else if (value instanceof Double) {
894             this.put(key, ((Double) value).doubleValue() + 1.0d);
895         } else if (value instanceof Float) {
896             this.put(key, ((Float) value).floatValue() + 1.0f);
897         } else {
898             throw new JSONException("Unable to increment [" + quote(key) + "].");
899         }
900         return this;
901     }
902
903     /**
904      * Determine if the value associated with the key is <code>null</code> or if there is no
905      * value.
906      *
907      * @param key
908      *            A key string.
909      * @return true if there is no value associated with the key or if the value
910      *        is the JSONObject.NULL object.
911      */
912     public boolean isNull(String key) {
913         return JSONObject.NULL.equals(this.opt(key));
914     }
915
916     /**
917      * Get an enumeration of the keys of the JSONObject. Modifying this key Set will also
918      * modify the JSONObject. Use with caution.
919      *
920      * @see Set#iterator()
921      * 
922      * @return An iterator of the keys.
923      */
924     public Iterator<String> keys() {
925         return this.keySet().iterator();
926     }
927
928     /**
929      * Get a set of keys of the JSONObject. Modifying this key Set will also modify the
930      * JSONObject. Use with caution.
931      *
932      * @see Map#keySet()
933      *
934      * @return A keySet.
935      */
936     public Set<String> keySet() {
937         return this.map.keySet();
938     }
939
940     /**
941      * Get a set of entries of the JSONObject. These are raw values and may not
942      * match what is returned by the JSONObject get* and opt* functions. Modifying 
943      * the returned EntrySet or the Entry objects contained therein will modify the
944      * backing JSONObject. This does not return a clone or a read-only view.
945      * 
946      * Use with caution.
947      *
948      * @see Map#entrySet()
949      *
950      * @return An Entry Set
951      */
952     protected Set<Entry<String, Object>> entrySet() {
953         return this.map.entrySet();
954     }
955
956     /**
957      * Get the number of keys stored in the JSONObject.
958      *
959      * @return The number of keys in the JSONObject.
960      */
961     public int length() {
962         return this.map.size();
963     }
964
965     /**
966      * Check if JSONObject is empty.
967      *
968      * @return true if JSONObject is empty, otherwise false.
969      */
970     public boolean isEmpty() {
971         return map.isEmpty();
972     }
973
974     /**
975      * Produce a JSONArray containing the names of the elements of this
976      * JSONObject.
977      *
978      * @return A JSONArray containing the key strings, or null if the JSONObject
979      *        is empty.
980      */
981     public JSONArray names() {
982         if(this.map.isEmpty()) {
983                 return null;
984         }
985         return new JSONArray(this.map.keySet());
986     }
987
988     /**
989      * Produce a string from a Number.
990      *
991      * @param number
992      *            A Number
993      * @return A String.
994      * @throws JSONException
995      *             If n is a non-finite number.
996      */
997     public static String numberToString(Number number) throws JSONException {
998         if (number == null) {
999             throw new JSONException("Null pointer");
1000         }
1001         testValidity(number);
1002
1003         // Shave off trailing zeros and decimal point, if possible.
1004
1005         String string = number.toString();
1006         if (string.indexOf('.') > 0 && string.indexOf('e') < 0
1007                 && string.indexOf('E') < 0) {
1008             while (string.endsWith("0")) {
1009                 string = string.substring(0, string.length() - 1);
1010             }
1011             if (string.endsWith(".")) {
1012                 string = string.substring(0, string.length() - 1);
1013             }
1014         }
1015         return string;
1016     }
1017
1018     /**
1019      * Get an optional value associated with a key.
1020      *
1021      * @param key
1022      *            A key string.
1023      * @return An object which is the value, or null if there is no value.
1024      */
1025     public Object opt(String key) {
1026         return key == null ? null : this.map.get(key);
1027     }
1028
1029     /**
1030      * Get the enum value associated with a key.
1031      * 
1032      * @param clazz
1033      *            The type of enum to retrieve.
1034      * @param key
1035      *            A key string.
1036      * @return The enum value associated with the key or null if not found
1037      */
1038     public <E extends Enum<E>> E optEnum(Class<E> clazz, String key) {
1039         return this.optEnum(clazz, key, null);
1040     }
1041
1042     /**
1043      * Get the enum value associated with a key.
1044      * 
1045      * @param clazz
1046      *            The type of enum to retrieve.
1047      * @param key
1048      *            A key string.
1049      * @param defaultValue
1050      *            The default in case the value is not found
1051      * @return The enum value associated with the key or defaultValue
1052      *            if the value is not found or cannot be assigned to <code>clazz</code>
1053      */
1054     public <E extends Enum<E>> E optEnum(Class<E> clazz, String key, E defaultValue) {
1055         try {
1056             Object val = this.opt(key);
1057             if (NULL.equals(val)) {
1058                 return defaultValue;
1059             }
1060             if (clazz.isAssignableFrom(val.getClass())) {
1061                 // we just checked it!
1062                 @SuppressWarnings("unchecked")
1063                 E myE = (E) val;
1064                 return myE;
1065             }
1066             return Enum.valueOf(clazz, val.toString());
1067         } catch (IllegalArgumentException e) {
1068             return defaultValue;
1069         } catch (NullPointerException e) {
1070             return defaultValue;
1071         }
1072     }
1073
1074     /**
1075      * Get an optional boolean associated with a key. It returns false if there
1076      * is no such key, or if the value is not Boolean.TRUE or the String "true".
1077      *
1078      * @param key
1079      *            A key string.
1080      * @return The truth.
1081      */
1082     public boolean optBoolean(String key) {
1083         return this.optBoolean(key, false);
1084     }
1085
1086     /**
1087      * Get an optional boolean associated with a key. It returns the
1088      * defaultValue if there is no such key, or if it is not a Boolean or the
1089      * String "true" or "false" (case insensitive).
1090      *
1091      * @param key
1092      *            A key string.
1093      * @param defaultValue
1094      *            The default.
1095      * @return The truth.
1096      */
1097     public boolean optBoolean(String key, boolean defaultValue) {
1098         Object val = this.opt(key);
1099         if (NULL.equals(val)) {
1100             return defaultValue;
1101         }
1102         if (val instanceof Boolean){
1103             return ((Boolean) val).booleanValue();
1104         }
1105         try {
1106             // we'll use the get anyway because it does string conversion.
1107             return this.getBoolean(key);
1108         } catch (Exception e) {
1109             return defaultValue;
1110         }
1111     }
1112
1113     /**
1114      * Get an optional BigDecimal associated with a key, or the defaultValue if
1115      * there is no such key or if its value is not a number. If the value is a
1116      * string, an attempt will be made to evaluate it as a number.
1117      *
1118      * @param key
1119      *            A key string.
1120      * @param defaultValue
1121      *            The default.
1122      * @return An object which is the value.
1123      */
1124     public BigDecimal optBigDecimal(String key, BigDecimal defaultValue) {
1125         Object val = this.opt(key);
1126         if (NULL.equals(val)) {
1127             return defaultValue;
1128         }
1129         if (val instanceof BigDecimal){
1130             return (BigDecimal) val;
1131         }
1132         if (val instanceof BigInteger){
1133             return new BigDecimal((BigInteger) val);
1134         }
1135         if (val instanceof Double || val instanceof Float){
1136             return new BigDecimal(((Number) val).doubleValue());
1137         }
1138         if (val instanceof Long || val instanceof Integer
1139                 || val instanceof Short || val instanceof Byte){
1140             return new BigDecimal(((Number) val).longValue());
1141         }
1142         // don't check if it's a string in case of unchecked Number subclasses
1143         try {
1144             return new BigDecimal(val.toString());
1145         } catch (Exception e) {
1146             return defaultValue;
1147         }
1148     }
1149
1150     /**
1151      * Get an optional BigInteger associated with a key, or the defaultValue if
1152      * there is no such key or if its value is not a number. If the value is a
1153      * string, an attempt will be made to evaluate it as a number.
1154      *
1155      * @param key
1156      *            A key string.
1157      * @param defaultValue
1158      *            The default.
1159      * @return An object which is the value.
1160      */
1161     public BigInteger optBigInteger(String key, BigInteger defaultValue) {
1162         Object val = this.opt(key);
1163         if (NULL.equals(val)) {
1164             return defaultValue;
1165         }
1166         if (val instanceof BigInteger){
1167             return (BigInteger) val;
1168         }
1169         if (val instanceof BigDecimal){
1170             return ((BigDecimal) val).toBigInteger();
1171         }
1172         if (val instanceof Double || val instanceof Float){
1173             return new BigDecimal(((Number) val).doubleValue()).toBigInteger();
1174         }
1175         if (val instanceof Long || val instanceof Integer
1176                 || val instanceof Short || val instanceof Byte){
1177             return BigInteger.valueOf(((Number) val).longValue());
1178         }
1179         // don't check if it's a string in case of unchecked Number subclasses
1180         try {
1181             // the other opt functions handle implicit conversions, i.e. 
1182             // jo.put("double",1.1d);
1183             // jo.optInt("double"); -- will return 1, not an error
1184             // this conversion to BigDecimal then to BigInteger is to maintain
1185             // that type cast support that may truncate the decimal.
1186             final String valStr = val.toString();
1187             if(isDecimalNotation(valStr)) {
1188                 return new BigDecimal(valStr).toBigInteger();
1189             }
1190             return new BigInteger(valStr);
1191         } catch (Exception e) {
1192             return defaultValue;
1193         }
1194     }
1195
1196     /**
1197      * Get an optional double associated with a key, or NaN if there is no such
1198      * key or if its value is not a number. If the value is a string, an attempt
1199      * will be made to evaluate it as a number.
1200      *
1201      * @param key
1202      *            A string which is the key.
1203      * @return An object which is the value.
1204      */
1205     public double optDouble(String key) {
1206         return this.optDouble(key, Double.NaN);
1207     }
1208
1209     /**
1210      * Get an optional double associated with a key, or the defaultValue if
1211      * there is no such key or if its value is not a number. If the value is a
1212      * string, an attempt will be made to evaluate it as a number.
1213      *
1214      * @param key
1215      *            A key string.
1216      * @param defaultValue
1217      *            The default.
1218      * @return An object which is the value.
1219      */
1220     public double optDouble(String key, double defaultValue) {
1221         Object val = this.opt(key);
1222         if (NULL.equals(val)) {
1223             return defaultValue;
1224         }
1225         if (val instanceof Number){
1226             return ((Number) val).doubleValue();
1227         }
1228         if (val instanceof String) {
1229             try {
1230                 return Double.parseDouble((String) val);
1231             } catch (Exception e) {
1232                 return defaultValue;
1233             }
1234         }
1235         return defaultValue;
1236     }
1237
1238     /**
1239      * Get the optional double value associated with an index. NaN is returned
1240      * if there is no value for the index, or if the value is not a number and
1241      * cannot be converted to a number.
1242      *
1243      * @param key
1244      *            A key string.
1245      * @return The value.
1246      */
1247     public float optFloat(String key) {
1248         return this.optFloat(key, Float.NaN);
1249     }
1250
1251     /**
1252      * Get the optional double value associated with an index. The defaultValue
1253      * is returned if there is no value for the index, or if the value is not a
1254      * number and cannot be converted to a number.
1255      *
1256      * @param key
1257      *            A key string.
1258      * @param defaultValue
1259      *            The default value.
1260      * @return The value.
1261      */
1262     public float optFloat(String key, float defaultValue) {
1263         Object val = this.opt(key);
1264         if (JSONObject.NULL.equals(val)) {
1265             return defaultValue;
1266         }
1267         if (val instanceof Number){
1268             return ((Number) val).floatValue();
1269         }
1270         if (val instanceof String) {
1271             try {
1272                 return Float.parseFloat((String) val);
1273             } catch (Exception e) {
1274                 return defaultValue;
1275             }
1276         }
1277         return defaultValue;
1278     }
1279
1280     /**
1281      * Get an optional int value associated with a key, or zero if there is no
1282      * such key or if the value is not a number. If the value is a string, an
1283      * attempt will be made to evaluate it as a number.
1284      *
1285      * @param key
1286      *            A key string.
1287      * @return An object which is the value.
1288      */
1289     public int optInt(String key) {
1290         return this.optInt(key, 0);
1291     }
1292
1293     /**
1294      * Get an optional int value associated with a key, or the default if there
1295      * is no such key or if the value is not a number. If the value is a string,
1296      * an attempt will be made to evaluate it as a number.
1297      *
1298      * @param key
1299      *            A key string.
1300      * @param defaultValue
1301      *            The default.
1302      * @return An object which is the value.
1303      */
1304     public int optInt(String key, int defaultValue) {
1305         Object val = this.opt(key);
1306         if (NULL.equals(val)) {
1307             return defaultValue;
1308         }
1309         if (val instanceof Number){
1310             return ((Number) val).intValue();
1311         }
1312         
1313         if (val instanceof String) {
1314             try {
1315                 return new BigDecimal((String) val).intValue();
1316             } catch (Exception e) {
1317                 return defaultValue;
1318             }
1319         }
1320         return defaultValue;
1321     }
1322
1323     /**
1324      * Get an optional JSONArray associated with a key. It returns null if there
1325      * is no such key, or if its value is not a JSONArray.
1326      *
1327      * @param key
1328      *            A key string.
1329      * @return A JSONArray which is the value.
1330      */
1331     public JSONArray optJSONArray(String key) {
1332         Object o = this.opt(key);
1333         return o instanceof JSONArray ? (JSONArray) o : null;
1334     }
1335
1336     /**
1337      * Get an optional JSONObject associated with a key. It returns null if
1338      * there is no such key, or if its value is not a JSONObject.
1339      *
1340      * @param key
1341      *            A key string.
1342      * @return A JSONObject which is the value.
1343      */
1344     public JSONObject optJSONObject(String key) {
1345         Object object = this.opt(key);
1346         return object instanceof JSONObject ? (JSONObject) object : null;
1347     }
1348
1349     /**
1350      * Get an optional long value associated with a key, or zero if there is no
1351      * such key or if the value is not a number. If the value is a string, an
1352      * attempt will be made to evaluate it as a number.
1353      *
1354      * @param key
1355      *            A key string.
1356      * @return An object which is the value.
1357      */
1358     public long optLong(String key) {
1359         return this.optLong(key, 0);
1360     }
1361
1362     /**
1363      * Get an optional long value associated with a key, or the default if there
1364      * is no such key or if the value is not a number. If the value is a string,
1365      * an attempt will be made to evaluate it as a number.
1366      *
1367      * @param key
1368      *            A key string.
1369      * @param defaultValue
1370      *            The default.
1371      * @return An object which is the value.
1372      */
1373     public long optLong(String key, long defaultValue) {
1374         Object val = this.opt(key);
1375         if (NULL.equals(val)) {
1376             return defaultValue;
1377         }
1378         if (val instanceof Number){
1379             return ((Number) val).longValue();
1380         }
1381         
1382         if (val instanceof String) {
1383             try {
1384                 return new BigDecimal((String) val).longValue();
1385             } catch (Exception e) {
1386                 return defaultValue;
1387             }
1388         }
1389         return defaultValue;
1390     }
1391     
1392     /**
1393      * Get an optional {@link Number} value associated with a key, or <code>null</code>
1394      * if there is no such key or if the value is not a number. If the value is a string,
1395      * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method
1396      * would be used in cases where type coercion of the number value is unwanted.
1397      *
1398      * @param key
1399      *            A key string.
1400      * @return An object which is the value.
1401      */
1402     public Number optNumber(String key) {
1403         return this.optNumber(key, null);
1404     }
1405
1406     /**
1407      * Get an optional {@link Number} value associated with a key, or the default if there
1408      * is no such key or if the value is not a number. If the value is a string,
1409      * an attempt will be made to evaluate it as a number. This method
1410      * would be used in cases where type coercion of the number value is unwanted.
1411      *
1412      * @param key
1413      *            A key string.
1414      * @param defaultValue
1415      *            The default.
1416      * @return An object which is the value.
1417      */
1418     public Number optNumber(String key, Number defaultValue) {
1419         Object val = this.opt(key);
1420         if (NULL.equals(val)) {
1421             return defaultValue;
1422         }
1423         if (val instanceof Number){
1424             return (Number) val;
1425         }
1426         
1427         if (val instanceof String) {
1428             try {
1429                 return stringToNumber((String) val);
1430             } catch (Exception e) {
1431                 return defaultValue;
1432             }
1433         }
1434         return defaultValue;
1435     }
1436     
1437     /**
1438      * Get an optional string associated with a key. It returns an empty string
1439      * if there is no such key. If the value is not a string and is not null,
1440      * then it is converted to a string.
1441      *
1442      * @param key
1443      *            A key string.
1444      * @return A string which is the value.
1445      */
1446     public String optString(String key) {
1447         return this.optString(key, "");
1448     }
1449
1450     /**
1451      * Get an optional string associated with a key. It returns the defaultValue
1452      * if there is no such key.
1453      *
1454      * @param key
1455      *            A key string.
1456      * @param defaultValue
1457      *            The default.
1458      * @return A string which is the value.
1459      */
1460     public String optString(String key, String defaultValue) {
1461         Object object = this.opt(key);
1462         return NULL.equals(object) ? defaultValue : object.toString();
1463     }
1464
1465     /**
1466      * Populates the internal map of the JSONObject with the bean properties. The
1467      * bean can not be recursive.
1468      *
1469      * @see JSONObject#JSONObject(Object)
1470      *
1471      * @param bean
1472      *            the bean
1473      */
1474     private void populateMap(Object bean) {
1475         Class<?> klass = bean.getClass();
1476
1477         // If klass is a System class then set includeSuperClass to false.
1478
1479         boolean includeSuperClass = klass.getClassLoader() != null;
1480
1481         Method[] methods = includeSuperClass ? klass.getMethods() : klass.getDeclaredMethods();
1482         for (final Method method : methods) {
1483             final int modifiers = method.getModifiers();
1484             if (Modifier.isPublic(modifiers)
1485                     && !Modifier.isStatic(modifiers)
1486                     && method.getParameterTypes().length == 0
1487                     && !method.isBridge()
1488                     && method.getReturnType() != Void.TYPE
1489                     && isValidMethodName(method.getName())) {
1490                 final String key = getKeyNameFromMethod(method);
1491                 if (key != null && !key.isEmpty()) {
1492                     try {
1493                         final Object result = method.invoke(bean);
1494                         if (result != null) {
1495                             this.map.put(key, wrap(result));
1496                             // we don't use the result anywhere outside of wrap
1497                             // if it's a resource we should be sure to close it
1498                             // after calling toString
1499                             if (result instanceof Closeable) {
1500                                 try {
1501                                     ((Closeable) result).close();
1502                                 } catch (IOException ignore) {
1503                                 }
1504                             }
1505                         }
1506                     } catch (IllegalAccessException ignore) {
1507                     } catch (IllegalArgumentException ignore) {
1508                     } catch (InvocationTargetException ignore) {
1509                     }
1510                 }
1511             }
1512         }
1513     }
1514
1515     private boolean isValidMethodName(String name) {
1516         return !"getClass".equals(name) && !"getDeclaringClass".equals(name);
1517     }
1518
1519     private String getKeyNameFromMethod(Method method) {
1520         final int ignoreDepth = -1;//getAnnotationDepth(method, JSONPropertyIgnore.class);
1521 //        if (ignoreDepth > 0) {
1522 //            final int forcedNameDepth = getAnnotationDepth(method, JSONPropertyName.class);
1523 //            if (forcedNameDepth < 0 || ignoreDepth <= forcedNameDepth) {
1524 //                // the hierarchy asked to ignore, and the nearest name override
1525 //                // was higher or non-existent
1526 //                return null;
1527 //            }
1528 //        }
1529 //        JSONPropertyName annotation = getAnnotation(method, JSONPropertyName.class);
1530 //        if (annotation != null && annotation.value() != null && !annotation.value().isEmpty()) {
1531 //            return annotation.value();
1532 //        }
1533         String key;
1534         final String name = method.getName();
1535         if (name.startsWith("get") && name.length() > 3) {
1536             key = name.substring(3);
1537         } else if (name.startsWith("is") && name.length() > 2) {
1538             key = name.substring(2);
1539         } else {
1540             return null;
1541         }
1542         // if the first letter in the key is not uppercase, then skip.
1543         // This is to maintain backwards compatibility before PR406
1544         // (https://github.com/stleary/JSON-java/pull/406/)
1545         if (Character.isLowerCase(key.charAt(0))) {
1546             return null;
1547         }
1548         if (key.length() == 1) {
1549             key = key.toLowerCase(Locale.ROOT);
1550         } else if (!Character.isUpperCase(key.charAt(1))) {
1551             key = key.substring(0, 1).toLowerCase(Locale.ROOT) + key.substring(1);
1552             /**
1553              * remove j2s signature
1554              * 
1555              * @j2sNative
1556              * 
1557              * key = key.split("$")[0];
1558              */
1559         }
1560         return key;
1561     }
1562
1563     /**
1564      * Searches the class hierarchy to see if the method or it's super
1565      * implementations and interfaces has the annotation.
1566      *
1567      * @param <A>
1568      *            type of the annotation
1569      *
1570      * @param m
1571      *            method to check
1572      * @param annotationClass
1573      *            annotation to look for
1574      * @return the {@link Annotation} if the annotation exists on the current method
1575      *         or one of it's super class definitions
1576      */
1577     private static <A extends Annotation> A getAnnotation(final Method m, final Class<A> annotationClass) {
1578         // if we have invalid data the result is null
1579         if (true || m == null || annotationClass == null) {
1580             return null;
1581         }
1582
1583 //        if (m.isAnnotationPresent(annotationClass)) {
1584 //            return m.getAnnotation(annotationClass);
1585 //        }
1586 //
1587 //        // if we've already reached the Object class, return null;
1588 //        Class<?> c = m.getDeclaringClass();
1589 //        if (c.getSuperclass() == null) {
1590 //            return null;
1591 //        }
1592 //
1593 //        // check directly implemented interfaces for the method being checked
1594 //        for (Class<?> i : c.getInterfaces()) {
1595 //            try {
1596 //                Method im = i.getMethod(m.getName(), m.getParameterTypes());
1597 //                return getAnnotation(im, annotationClass);
1598 //            } catch (final SecurityException ex) {
1599 //                continue;
1600 //            } catch (final NoSuchMethodException ex) {
1601 //                continue;
1602 //            }
1603 //        }
1604 //
1605 //        try {
1606 //            return getAnnotation(
1607 //                    c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()),
1608 //                    annotationClass);
1609 //        } catch (final SecurityException ex) {
1610 //            return null;
1611 //        } catch (final NoSuchMethodException ex) {
1612 //            return null;
1613 //        }
1614     }
1615
1616     /**
1617      * Searches the class hierarchy to see if the method or it's super
1618      * implementations and interfaces has the annotation. Returns the depth of the
1619      * annotation in the hierarchy.
1620      *
1621      * @param <A>
1622      *            type of the annotation
1623      *
1624      * @param m
1625      *            method to check
1626      * @param annotationClass
1627      *            annotation to look for
1628      * @return Depth of the annotation or -1 if the annotation is not on the method.
1629      */
1630     private static int getAnnotationDepth(final Method m, final Class<? extends Annotation> annotationClass) {
1631         // if we have invalid data the result is -1
1632         if (true || m == null || annotationClass == null) {
1633             return -1;
1634         }
1635
1636 //        if (m.isAnnotationPresent(annotationClass)) {
1637 //            return 1;
1638 //        }
1639 //
1640 //        // if we've already reached the Object class, return -1;
1641 //        Class<?> c = m.getDeclaringClass();
1642 //        if (c.getSuperclass() == null) {
1643 //            return -1;
1644 //        }
1645 //
1646 //        // check directly implemented interfaces for the method being checked
1647 //        for (Class<?> i : c.getInterfaces()) {
1648 //            try {
1649 //                Method im = i.getMethod(m.getName(), m.getParameterTypes());
1650 //                int d = getAnnotationDepth(im, annotationClass);
1651 //                if (d > 0) {
1652 //                    // since the annotation was on the interface, add 1
1653 //                    return d + 1;
1654 //                }
1655 //            } catch (final SecurityException ex) {
1656 //                continue;
1657 //            } catch (final NoSuchMethodException ex) {
1658 //                continue;
1659 //            }
1660 //        }
1661 //
1662 //        try {
1663 //            int d = getAnnotationDepth(
1664 //                    c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()),
1665 //                    annotationClass);
1666 //            if (d > 0) {
1667 //                // since the annotation was on the superclass, add 1
1668 //                return d + 1;
1669 //            }
1670 //            return -1;
1671 //        } catch (final SecurityException ex) {
1672 //            return -1;
1673 //        } catch (final NoSuchMethodException ex) {
1674 //            return -1;
1675 //        }
1676     }
1677
1678     /**
1679      * Put a key/boolean pair in the JSONObject.
1680      *
1681      * @param key
1682      *            A key string.
1683      * @param value
1684      *            A boolean which is the value.
1685      * @return this.
1686      * @throws JSONException
1687      *            If the value is non-finite number.
1688      * @throws NullPointerException
1689      *            If the key is <code>null</code>.
1690      */
1691     public JSONObject put(String key, boolean value) throws JSONException {
1692         return this.put(key, value ? Boolean.TRUE : Boolean.FALSE);
1693     }
1694
1695     /**
1696      * Put a key/value pair in the JSONObject, where the value will be a
1697      * JSONArray which is produced from a Collection.
1698      *
1699      * @param key
1700      *            A key string.
1701      * @param value
1702      *            A Collection value.
1703      * @return this.
1704      * @throws JSONException
1705      *            If the value is non-finite number.
1706      * @throws NullPointerException
1707      *            If the key is <code>null</code>.
1708      */
1709     public JSONObject put(String key, Collection<?> value) throws JSONException {
1710         return this.put(key, new JSONArray(value));
1711     }
1712
1713     /**
1714      * Put a key/double pair in the JSONObject.
1715      *
1716      * @param key
1717      *            A key string.
1718      * @param value
1719      *            A double which is the value.
1720      * @return this.
1721      * @throws JSONException
1722      *            If the value is non-finite number.
1723      * @throws NullPointerException
1724      *            If the key is <code>null</code>.
1725      */
1726     public JSONObject put(String key, double value) throws JSONException {
1727         return this.put(key, Double.valueOf(value));
1728     }
1729     
1730     /**
1731      * Put a key/float pair in the JSONObject.
1732      *
1733      * @param key
1734      *            A key string.
1735      * @param value
1736      *            A float which is the value.
1737      * @return this.
1738      * @throws JSONException
1739      *            If the value is non-finite number.
1740      * @throws NullPointerException
1741      *            If the key is <code>null</code>.
1742      */
1743     public JSONObject put(String key, float value) throws JSONException {
1744         return this.put(key, Float.valueOf(value));
1745     }
1746
1747     /**
1748      * Put a key/int pair in the JSONObject.
1749      *
1750      * @param key
1751      *            A key string.
1752      * @param value
1753      *            An int which is the value.
1754      * @return this.
1755      * @throws JSONException
1756      *            If the value is non-finite number.
1757      * @throws NullPointerException
1758      *            If the key is <code>null</code>.
1759      */
1760     public JSONObject put(String key, int value) throws JSONException {
1761         return this.put(key, Integer.valueOf(value));
1762     }
1763
1764     /**
1765      * Put a key/long pair in the JSONObject.
1766      *
1767      * @param key
1768      *            A key string.
1769      * @param value
1770      *            A long which is the value.
1771      * @return this.
1772      * @throws JSONException
1773      *            If the value is non-finite number.
1774      * @throws NullPointerException
1775      *            If the key is <code>null</code>.
1776      */
1777     public JSONObject put(String key, long value) throws JSONException {
1778         return this.put(key, Long.valueOf(value));
1779     }
1780
1781     /**
1782      * Put a key/value pair in the JSONObject, where the value will be a
1783      * JSONObject which is produced from a Map.
1784      *
1785      * @param key
1786      *            A key string.
1787      * @param value
1788      *            A Map value.
1789      * @return this.
1790      * @throws JSONException
1791      *            If the value is non-finite number.
1792      * @throws NullPointerException
1793      *            If the key is <code>null</code>.
1794      */
1795     public JSONObject put(String key, Map<?, ?> value) throws JSONException {
1796         return this.put(key, new JSONObject(value));
1797     }
1798
1799     /**
1800      * Put a key/value pair in the JSONObject. If the value is <code>null</code>, then the
1801      * key will be removed from the JSONObject if it is present.
1802      *
1803      * @param key
1804      *            A key string.
1805      * @param value
1806      *            An object which is the value. It should be of one of these
1807      *            types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
1808      *            String, or the JSONObject.NULL object.
1809      * @return this.
1810      * @throws JSONException
1811      *            If the value is non-finite number.
1812      * @throws NullPointerException
1813      *            If the key is <code>null</code>.
1814      */
1815     public JSONObject put(String key, Object value) throws JSONException {
1816         if (key == null) {
1817             throw new NullPointerException("Null key.");
1818         }
1819         if (value != null) {
1820             testValidity(value);
1821             this.map.put(key, value);
1822         } else {
1823             this.remove(key);
1824         }
1825         return this;
1826     }
1827
1828     /**
1829      * Put a key/value pair in the JSONObject, but only if the key and the value
1830      * are both non-null, and only if there is not already a member with that
1831      * name.
1832      *
1833      * @param key string
1834      * @param value object
1835      * @return this.
1836      * @throws JSONException
1837      *             if the key is a duplicate
1838      */
1839     public JSONObject putOnce(String key, Object value) throws JSONException {
1840         if (key != null && value != null) {
1841             if (this.opt(key) != null) {
1842                 throw new JSONException("Duplicate key \"" + key + "\"");
1843             }
1844             return this.put(key, value);
1845         }
1846         return this;
1847     }
1848
1849     /**
1850      * Put a key/value pair in the JSONObject, but only if the key and the value
1851      * are both non-null.
1852      *
1853      * @param key
1854      *            A key string.
1855      * @param value
1856      *            An object which is the value. It should be of one of these
1857      *            types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
1858      *            String, or the JSONObject.NULL object.
1859      * @return this.
1860      * @throws JSONException
1861      *             If the value is a non-finite number.
1862      */
1863     public JSONObject putOpt(String key, Object value) throws JSONException {
1864         if (key != null && value != null) {
1865             return this.put(key, value);
1866         }
1867         return this;
1868     }
1869
1870     /**
1871      * Creates a JSONPointer using an initialization string and tries to 
1872      * match it to an item within this JSONObject. For example, given a
1873      * JSONObject initialized with this document:
1874      * <pre>
1875      * {
1876      *     "a":{"b":"c"}
1877      * }
1878      * </pre>
1879      * and this JSONPointer string: 
1880      * <pre>
1881      * "/a/b"
1882      * </pre>
1883      * Then this method will return the String "c".
1884      * A JSONPointerException may be thrown from code called by this method.
1885      *   
1886      * @param jsonPointer string that can be used to create a JSONPointer
1887      * @return the item matched by the JSONPointer, otherwise null
1888      */
1889     public Object query(String jsonPointer) {
1890         return query(new JSONPointer(jsonPointer));
1891     }
1892     /**
1893      * Uses a user initialized JSONPointer  and tries to 
1894      * match it to an item within this JSONObject. For example, given a
1895      * JSONObject initialized with this document:
1896      * <pre>
1897      * {
1898      *     "a":{"b":"c"}
1899      * }
1900      * </pre>
1901      * and this JSONPointer: 
1902      * <pre>
1903      * "/a/b"
1904      * </pre>
1905      * Then this method will return the String "c".
1906      * A JSONPointerException may be thrown from code called by this method.
1907      *   
1908      * @param jsonPointer string that can be used to create a JSONPointer
1909      * @return the item matched by the JSONPointer, otherwise null
1910      */
1911     public Object query(JSONPointer jsonPointer) {
1912         return jsonPointer.queryFrom(this);
1913     }
1914     
1915     /**
1916      * Queries and returns a value from this object using {@code jsonPointer}, or
1917      * returns null if the query fails due to a missing key.
1918      * 
1919      * @param jsonPointer the string representation of the JSON pointer
1920      * @return the queried value or {@code null}
1921      * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
1922      */
1923     public Object optQuery(String jsonPointer) {
1924         return optQuery(new JSONPointer(jsonPointer));
1925     }
1926     
1927     /**
1928      * Queries and returns a value from this object using {@code jsonPointer}, or
1929      * returns null if the query fails due to a missing key.
1930      * 
1931      * @param jsonPointer The JSON pointer
1932      * @return the queried value or {@code null}
1933      * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
1934      */
1935     public Object optQuery(JSONPointer jsonPointer) {
1936         try {
1937             return jsonPointer.queryFrom(this);
1938         } catch (JSONPointerException e) {
1939             return null;
1940         }
1941     }
1942
1943     /**
1944      * Produce a string in double quotes with backslash sequences in all the
1945      * right places. A backslash will be inserted within </, producing <\/,
1946      * allowing JSON text to be delivered in HTML. In JSON text, a string cannot
1947      * contain a control character or an unescaped quote or backslash.
1948      *
1949      * @param string
1950      *            A String
1951      * @return A String correctly formatted for insertion in a JSON text.
1952      */
1953     public static String quote(String string) {
1954         StringWriter sw = new StringWriter();
1955         synchronized (sw.getBuffer()) {
1956             try {
1957                 return quote(string, sw).toString();
1958             } catch (IOException ignored) {
1959                 // will never happen - we are writing to a string writer
1960                 return "";
1961             }
1962         }
1963     }
1964
1965     public static Writer quote(String string, Writer w) throws IOException {
1966         if (string == null || string.isEmpty()) {
1967             w.write("\"\"");
1968             return w;
1969         }
1970
1971         char b;
1972         char c = 0;
1973         String hhhh;
1974         int i;
1975         int len = string.length();
1976
1977         w.write('"');
1978         for (i = 0; i < len; i += 1) {
1979             b = c;
1980             c = string.charAt(i);
1981             switch (c) {
1982             case '\\':
1983             case '"':
1984                 w.write('\\');
1985                 w.write(c);
1986                 break;
1987             case '/':
1988                 if (b == '<') {
1989                     w.write('\\');
1990                 }
1991                 w.write(c);
1992                 break;
1993             case '\b':
1994                 w.write("\\b");
1995                 break;
1996             case '\t':
1997                 w.write("\\t");
1998                 break;
1999             case '\n':
2000                 w.write("\\n");
2001                 break;
2002             case '\f':
2003                 w.write("\\f");
2004                 break;
2005             case '\r':
2006                 w.write("\\r");
2007                 break;
2008             default:
2009                 if (c < ' ' || (c >= '\u0080' && c < '\u00a0')
2010                         || (c >= '\u2000' && c < '\u2100')) {
2011                     w.write("\\u");
2012                     hhhh = Integer.toHexString(c);
2013                     w.write("0000", 0, 4 - hhhh.length());
2014                     w.write(hhhh);
2015                 } else {
2016                     w.write(c);
2017                 }
2018             }
2019         }
2020         w.write('"');
2021         return w;
2022     }
2023
2024     /**
2025      * Remove a name and its value, if present.
2026      *
2027      * @param key
2028      *            The name to be removed.
2029      * @return The value that was associated with the name, or null if there was
2030      *         no value.
2031      */
2032     public Object remove(String key) {
2033         return this.map.remove(key);
2034     }
2035
2036     /**
2037      * Determine if two JSONObjects are similar.
2038      * They must contain the same set of names which must be associated with
2039      * similar values.
2040      *
2041      * @param other The other JSONObject
2042      * @return true if they are equal
2043      */
2044     public boolean similar(Object other) {
2045         try {
2046             if (!(other instanceof JSONObject)) {
2047                 return false;
2048             }
2049             if (!this.keySet().equals(((JSONObject)other).keySet())) {
2050                 return false;
2051             }
2052             for (final Entry<String,?> entry : this.entrySet()) {
2053                 String name = entry.getKey();
2054                 Object valueThis = entry.getValue();
2055                 Object valueOther = ((JSONObject)other).get(name);
2056                 if(valueThis == valueOther) {
2057                         continue;
2058                 }
2059                 if(valueThis == null) {
2060                         return false;
2061                 }
2062                 if (valueThis instanceof JSONObject) {
2063                     if (!((JSONObject)valueThis).similar(valueOther)) {
2064                         return false;
2065                     }
2066                 } else if (valueThis instanceof JSONArray) {
2067                     if (!((JSONArray)valueThis).similar(valueOther)) {
2068                         return false;
2069                     }
2070                 } else if (!valueThis.equals(valueOther)) {
2071                     return false;
2072                 }
2073             }
2074             return true;
2075         } catch (Throwable exception) {
2076             return false;
2077         }
2078     }
2079     
2080     /**
2081      * Tests if the value should be tried as a decimal. It makes no test if there are actual digits.
2082      * 
2083      * @param val value to test
2084      * @return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise.
2085      */
2086     protected static boolean isDecimalNotation(final String val) {
2087         return val.indexOf('.') > -1 || val.indexOf('e') > -1
2088                 || val.indexOf('E') > -1 || "-0".equals(val);
2089     }
2090     
2091     /**
2092      * Converts a string to a number using the narrowest possible type. Possible 
2093      * returns for this function are BigDecimal, Double, BigInteger, Long, and Integer.
2094      * When a Double is returned, it should always be a valid Double and not NaN or +-infinity.
2095      * 
2096      * @param val value to convert
2097      * @return Number representation of the value.
2098      * @throws NumberFormatException thrown if the value is not a valid number. A public
2099      *      caller should catch this and wrap it in a {@link JSONException} if applicable.
2100      */
2101     protected static Number stringToNumber(final String val) throws NumberFormatException {
2102         char initial = val.charAt(0);
2103         if ((initial >= '0' && initial <= '9') || initial == '-') {
2104             // decimal representation
2105             if (isDecimalNotation(val)) {
2106                 // quick dirty way to see if we need a BigDecimal instead of a Double
2107                 // this only handles some cases of overflow or underflow
2108                 if (val.length()>14) {
2109                     return new BigDecimal(val);
2110                 }
2111                 final Double d = Double.valueOf(val);
2112                 if (d.isInfinite() || d.isNaN()) {
2113                     // if we can't parse it as a double, go up to BigDecimal
2114                     // this is probably due to underflow like 4.32e-678
2115                     // or overflow like 4.65e5324. The size of the string is small
2116                     // but can't be held in a Double.
2117                     return new BigDecimal(val);
2118                 }
2119                 return d;
2120             }
2121             // integer representation.
2122             // This will narrow any values to the smallest reasonable Object representation
2123             // (Integer, Long, or BigInteger)
2124             
2125             // string version
2126             // The compare string length method reduces GC,
2127             // but leads to smaller integers being placed in larger wrappers even though not
2128             // needed. i.e. 1,000,000,000 -> Long even though it's an Integer
2129             // 1,000,000,000,000,000,000 -> BigInteger even though it's a Long
2130             //if(val.length()<=9){
2131             //    return Integer.valueOf(val);
2132             //}
2133             //if(val.length()<=18){
2134             //    return Long.valueOf(val);
2135             //}
2136             //return new BigInteger(val);
2137             
2138             // BigInteger version: We use a similar bitLenth compare as
2139             // BigInteger#intValueExact uses. Increases GC, but objects hold
2140             // only what they need. i.e. Less runtime overhead if the value is
2141             // long lived. Which is the better tradeoff? This is closer to what's
2142             // in stringToValue.
2143             BigInteger bi = new BigInteger(val);
2144             if(bi.bitLength()<=31){
2145                 return Integer.valueOf(bi.intValue());
2146             }
2147             if(bi.bitLength()<=63){
2148                 return Long.valueOf(bi.longValue());
2149             }
2150             return bi;
2151         }
2152         throw new NumberFormatException("val ["+val+"] is not a valid number.");
2153     }
2154
2155     /**
2156      * Try to convert a string into a number, boolean, or null. If the string
2157      * can't be converted, return the string.
2158      *
2159      * @param string
2160      *            A String.
2161      * @return A simple JSON value.
2162      */
2163     // Changes to this method must be copied to the corresponding method in
2164     // the XML class to keep full support for Android
2165     public static Object stringToValue(String string) {
2166         if (string.equals("")) {
2167             return string;
2168         }
2169         if (string.equalsIgnoreCase("true")) {
2170             return Boolean.TRUE;
2171         }
2172         if (string.equalsIgnoreCase("false")) {
2173             return Boolean.FALSE;
2174         }
2175         if (string.equalsIgnoreCase("null")) {
2176             return JSONObject.NULL;
2177         }
2178
2179         /*
2180          * If it might be a number, try converting it. If a number cannot be
2181          * produced, then the value will just be a string.
2182          */
2183
2184         char initial = string.charAt(0);
2185         if ((initial >= '0' && initial <= '9') || initial == '-') {
2186             try {
2187                 // if we want full Big Number support this block can be replaced with:
2188                 // return stringToNumber(string);
2189                 if (isDecimalNotation(string)) {
2190                     Double d = Double.valueOf(string);
2191                     if (!d.isInfinite() && !d.isNaN()) {
2192                         return d;
2193                     }
2194                 } else {
2195                     Long myLong = Long.valueOf(string);
2196                     if (string.equals(myLong.toString())) {
2197                         if (myLong.longValue() == myLong.intValue()) {
2198                             return Integer.valueOf(myLong.intValue());
2199                         }
2200                         return myLong;
2201                     }
2202                 }
2203             } catch (Exception ignore) {
2204             }
2205         }
2206         return string;
2207     }
2208
2209     /**
2210      * Throw an exception if the object is a NaN or infinite number.
2211      *
2212      * @param o
2213      *            The object to test.
2214      * @throws JSONException
2215      *             If o is a non-finite number.
2216      */
2217     public static void testValidity(Object o) throws JSONException {
2218         if (o != null) {
2219             if (o instanceof Double) {
2220                 if (((Double) o).isInfinite() || ((Double) o).isNaN()) {
2221                     throw new JSONException(
2222                             "JSON does not allow non-finite numbers.");
2223                 }
2224             } else if (o instanceof Float) {
2225                 if (((Float) o).isInfinite() || ((Float) o).isNaN()) {
2226                     throw new JSONException(
2227                             "JSON does not allow non-finite numbers.");
2228                 }
2229             }
2230         }
2231     }
2232
2233     /**
2234      * Produce a JSONArray containing the values of the members of this
2235      * JSONObject.
2236      *
2237      * @param names
2238      *            A JSONArray containing a list of key strings. This determines
2239      *            the sequence of the values in the result.
2240      * @return A JSONArray of values.
2241      * @throws JSONException
2242      *             If any of the values are non-finite numbers.
2243      */
2244     public JSONArray toJSONArray(JSONArray names) throws JSONException {
2245         if (names == null || names.isEmpty()) {
2246             return null;
2247         }
2248         JSONArray ja = new JSONArray();
2249         for (int i = 0; i < names.length(); i += 1) {
2250             ja.put(this.opt(names.getString(i)));
2251         }
2252         return ja;
2253     }
2254
2255     /**
2256      * Make a JSON text of this JSONObject. For compactness, no whitespace is
2257      * added. If this would not result in a syntactically correct JSON text,
2258      * then null will be returned instead.
2259      * <p><b>
2260      * Warning: This method assumes that the data structure is acyclical.
2261      * </b>
2262      * 
2263      * @return a printable, displayable, portable, transmittable representation
2264      *         of the object, beginning with <code>{</code>&nbsp;<small>(left
2265      *         brace)</small> and ending with <code>}</code>&nbsp;<small>(right
2266      *         brace)</small>.
2267      */
2268     @Override
2269     public String toString() {
2270         try {
2271             return this.toString(0);
2272         } catch (Exception e) {
2273             return null;
2274         }
2275     }
2276
2277     /**
2278      * Make a pretty-printed JSON text of this JSONObject.
2279      * 
2280      * <p>If <code>indentFactor > 0</code> and the {@link JSONObject}
2281      * has only one key, then the object will be output on a single line:
2282      * <pre>{@code {"key": 1}}</pre>
2283      * 
2284      * <p>If an object has 2 or more keys, then it will be output across
2285      * multiple lines: <code><pre>{
2286      *  "key1": 1,
2287      *  "key2": "value 2",
2288      *  "key3": 3
2289      * }</pre></code>
2290      * <p><b>
2291      * Warning: This method assumes that the data structure is acyclical.
2292      * </b>
2293      *
2294      * @param indentFactor
2295      *            The number of spaces to add to each level of indentation.
2296      * @return a printable, displayable, portable, transmittable representation
2297      *         of the object, beginning with <code>{</code>&nbsp;<small>(left
2298      *         brace)</small> and ending with <code>}</code>&nbsp;<small>(right
2299      *         brace)</small>.
2300      * @throws JSONException
2301      *             If the object contains an invalid number.
2302      */
2303     public String toString(int indentFactor) throws JSONException {
2304         StringWriter w = new StringWriter();
2305         synchronized (w.getBuffer()) {
2306             return this.write(w, indentFactor, 0).toString();
2307         }
2308     }
2309
2310     /**
2311      * Make a JSON text of an Object value. If the object has an
2312      * value.toJSONString() method, then that method will be used to produce the
2313      * JSON text. The method is required to produce a strictly conforming text.
2314      * If the object does not contain a toJSONString method (which is the most
2315      * common case), then a text will be produced by other means. If the value
2316      * is an array or Collection, then a JSONArray will be made from it and its
2317      * toJSONString method will be called. If the value is a MAP, then a
2318      * JSONObject will be made from it and its toJSONString method will be
2319      * called. Otherwise, the value's toString method will be called, and the
2320      * result will be quoted.
2321      *
2322      * <p>
2323      * Warning: This method assumes that the data structure is acyclical.
2324      *
2325      * @param value
2326      *            The value to be serialized.
2327      * @return a printable, displayable, transmittable representation of the
2328      *         object, beginning with <code>{</code>&nbsp;<small>(left
2329      *         brace)</small> and ending with <code>}</code>&nbsp;<small>(right
2330      *         brace)</small>.
2331      * @throws JSONException
2332      *             If the value is or contains an invalid number.
2333      */
2334     public static String valueToString(Object value) throws JSONException {
2335         // moves the implementation to JSONWriter as:
2336         // 1. It makes more sense to be part of the writer class
2337         // 2. For Android support this method is not available. By implementing it in the Writer
2338         //    Android users can use the writer with the built in Android JSONObject implementation.
2339         return JSONWriter.valueToString(value);
2340     }
2341
2342     /**
2343      * Wrap an object, if necessary. If the object is <code>null</code>, return the NULL
2344      * object. If it is an array or collection, wrap it in a JSONArray. If it is
2345      * a map, wrap it in a JSONObject. If it is a standard property (Double,
2346      * String, et al) then it is already wrapped. Otherwise, if it comes from
2347      * one of the java packages, turn it into a string. And if it doesn't, try
2348      * to wrap it in a JSONObject. If the wrapping fails, then null is returned.
2349      *
2350      * @param object
2351      *            The object to wrap
2352      * @return The wrapped value
2353      */
2354     public static Object wrap(Object object) {
2355         try {
2356             if (object == null) {
2357                 return NULL;
2358             }
2359             if (object instanceof JSONObject || object instanceof JSONArray
2360                     || NULL.equals(object) || object instanceof JSONString
2361                     || object instanceof Byte || object instanceof Character
2362                     || object instanceof Short || object instanceof Integer
2363                     || object instanceof Long || object instanceof Boolean
2364                     || object instanceof Float || object instanceof Double
2365                     || object instanceof String || object instanceof BigInteger
2366                     || object instanceof BigDecimal || object instanceof Enum) {
2367                 return object;
2368             }
2369
2370             if (object instanceof Collection) {
2371                 Collection<?> coll = (Collection<?>) object;
2372                 return new JSONArray(coll);
2373             }
2374             if (object.getClass().isArray()) {
2375                 return new JSONArray(object);
2376             }
2377             if (object instanceof Map) {
2378                 Map<?, ?> map = (Map<?, ?>) object;
2379                 return new JSONObject(map);
2380             }
2381             Package objectPackage = object.getClass().getPackage();
2382             String objectPackageName = objectPackage != null ? objectPackage
2383                     .getName() : "";
2384             if (objectPackageName.startsWith("java.")
2385                     || objectPackageName.startsWith("javax.")
2386                     || object.getClass().getClassLoader() == null) {
2387                 return object.toString();
2388             }
2389             return new JSONObject(object);
2390         } catch (Exception exception) {
2391             return null;
2392         }
2393     }
2394
2395     /**
2396      * Write the contents of the JSONObject as JSON text to a writer. For
2397      * compactness, no whitespace is added.
2398      * <p><b>
2399      * Warning: This method assumes that the data structure is acyclical.
2400      * </b>
2401      * 
2402      * @return The writer.
2403      * @throws JSONException
2404      */
2405     public Writer write(Writer writer) throws JSONException {
2406         return this.write(writer, 0, 0);
2407     }
2408
2409     static final Writer writeValue(Writer writer, Object value,
2410             int indentFactor, int indent) throws JSONException, IOException {
2411         if (value == null || value.equals(null)) {
2412             writer.write("null");
2413         } else if (value instanceof JSONString) {
2414             Object o;
2415             try {
2416                 o = ((JSONString) value).toJSONString();
2417             } catch (Exception e) {
2418                 throw new JSONException(e);
2419             }
2420             writer.write(o != null ? o.toString() : quote(value.toString()));
2421         } else if (value instanceof Number) {
2422             // not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
2423             final String numberAsString = numberToString((Number) value);
2424             try {
2425                 // Use the BigDecimal constructor for its parser to validate the format.
2426                 @SuppressWarnings("unused")
2427                 BigDecimal testNum = new BigDecimal(numberAsString);
2428                 // Close enough to a JSON number that we will use it unquoted
2429                 writer.write(numberAsString);
2430             } catch (NumberFormatException ex){
2431                 // The Number value is not a valid JSON number.
2432                 // Instead we will quote it as a string
2433                 quote(numberAsString, writer);
2434             }
2435         } else if (value instanceof Boolean) {
2436             writer.write(value.toString());
2437         } else if (value instanceof Enum<?>) {
2438             writer.write(quote(((Enum<?>)value).name()));
2439         } else if (value instanceof JSONObject) {
2440             ((JSONObject) value).write(writer, indentFactor, indent);
2441         } else if (value instanceof JSONArray) {
2442             ((JSONArray) value).write(writer, indentFactor, indent);
2443         } else if (value instanceof Map) {
2444             Map<?, ?> map = (Map<?, ?>) value;
2445             new JSONObject(map).write(writer, indentFactor, indent);
2446         } else if (value instanceof Collection) {
2447             Collection<?> coll = (Collection<?>) value;
2448             new JSONArray(coll).write(writer, indentFactor, indent);
2449         } else if (value.getClass().isArray()) {
2450             new JSONArray(value).write(writer, indentFactor, indent);
2451         } else {
2452             quote(value.toString(), writer);
2453         }
2454         return writer;
2455     }
2456
2457     static final void indent(Writer writer, int indent) throws IOException {
2458         for (int i = 0; i < indent; i += 1) {
2459             writer.write(' ');
2460         }
2461     }
2462
2463     /**
2464      * Write the contents of the JSONObject as JSON text to a writer.
2465      * 
2466      * <p>If <code>indentFactor > 0</code> and the {@link JSONObject}
2467      * has only one key, then the object will be output on a single line:
2468      * <pre>{@code {"key": 1}}</pre>
2469      * 
2470      * <p>If an object has 2 or more keys, then it will be output across
2471      * multiple lines: <code><pre>{
2472      *  "key1": 1,
2473      *  "key2": "value 2",
2474      *  "key3": 3
2475      * }</pre></code>
2476      * <p><b>
2477      * Warning: This method assumes that the data structure is acyclical.
2478      * </b>
2479      *
2480      * @param writer
2481      *            Writes the serialized JSON
2482      * @param indentFactor
2483      *            The number of spaces to add to each level of indentation.
2484      * @param indent
2485      *            The indentation of the top level.
2486      * @return The writer.
2487      * @throws JSONException
2488      */
2489     public Writer write(Writer writer, int indentFactor, int indent)
2490             throws JSONException {
2491         try {
2492             boolean commanate = false;
2493             final int length = this.length();
2494             writer.write('{');
2495
2496             if (length == 1) {
2497                 final Entry<String,?> entry = this.entrySet().iterator().next();
2498                 final String key = entry.getKey();
2499                 writer.write(quote(key));
2500                 writer.write(':');
2501                 if (indentFactor > 0) {
2502                     writer.write(' ');
2503                 }
2504                 try{
2505                     writeValue(writer, entry.getValue(), indentFactor, indent);
2506                 } catch (Exception e) {
2507                     throw new JSONException("Unable to write JSONObject value for key: " + key, e);
2508                 }
2509             } else if (length != 0) {
2510                 final int newindent = indent + indentFactor;
2511                 for (final Entry<String,?> entry : this.entrySet()) {
2512                     if (commanate) {
2513                         writer.write(',');
2514                     }
2515                     if (indentFactor > 0) {
2516                         writer.write('\n');
2517                     }
2518                     indent(writer, newindent);
2519                     final String key = entry.getKey();
2520                     writer.write(quote(key));
2521                     writer.write(':');
2522                     if (indentFactor > 0) {
2523                         writer.write(' ');
2524                     }
2525                     try {
2526                         writeValue(writer, entry.getValue(), indentFactor, newindent);
2527                     } catch (Exception e) {
2528                         throw new JSONException("Unable to write JSONObject value for key: " + key, e);
2529                     }
2530                     commanate = true;
2531                 }
2532                 if (indentFactor > 0) {
2533                     writer.write('\n');
2534                 }
2535                 indent(writer, indent);
2536             }
2537             writer.write('}');
2538             return writer;
2539         } catch (IOException exception) {
2540             throw new JSONException(exception);
2541         }
2542     }
2543
2544     /**
2545      * Returns a java.util.Map containing all of the entries in this object.
2546      * If an entry in the object is a JSONArray or JSONObject it will also
2547      * be converted.
2548      * <p>
2549      * Warning: This method assumes that the data structure is acyclical.
2550      *
2551      * @return a java.util.Map containing the entries of this object
2552      */
2553     public Map<String, Object> toMap() {
2554         Map<String, Object> results = new HashMap<String, Object>();
2555         for (Entry<String, Object> entry : this.entrySet()) {
2556             Object value;
2557             if (entry.getValue() == null || NULL.equals(entry.getValue())) {
2558                 value = null;
2559             } else if (entry.getValue() instanceof JSONObject) {
2560                 value = ((JSONObject) entry.getValue()).toMap();
2561             } else if (entry.getValue() instanceof JSONArray) {
2562                 value = ((JSONArray) entry.getValue()).toList();
2563             } else {
2564                 value = entry.getValue();
2565             }
2566             results.put(entry.getKey(), value);
2567         }
2568         return results;
2569     }
2570 }