8deb6bae53082b6a6f20c35d50347a9346905291
[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 = 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         return key;
1554     }
1555
1556     /**
1557      * Searches the class hierarchy to see if the method or it's super
1558      * implementations and interfaces has the annotation.
1559      *
1560      * @param <A>
1561      *            type of the annotation
1562      *
1563      * @param m
1564      *            method to check
1565      * @param annotationClass
1566      *            annotation to look for
1567      * @return the {@link Annotation} if the annotation exists on the current method
1568      *         or one of it's super class definitions
1569      */
1570     private static <A extends Annotation> A getAnnotation(final Method m, final Class<A> annotationClass) {
1571         // if we have invalid data the result is null
1572         if (m == null || annotationClass == null) {
1573             return null;
1574         }
1575
1576         if (m.isAnnotationPresent(annotationClass)) {
1577             return m.getAnnotation(annotationClass);
1578         }
1579
1580         // if we've already reached the Object class, return null;
1581         Class<?> c = m.getDeclaringClass();
1582         if (c.getSuperclass() == null) {
1583             return null;
1584         }
1585
1586         // check directly implemented interfaces for the method being checked
1587         for (Class<?> i : c.getInterfaces()) {
1588             try {
1589                 Method im = i.getMethod(m.getName(), m.getParameterTypes());
1590                 return getAnnotation(im, annotationClass);
1591             } catch (final SecurityException ex) {
1592                 continue;
1593             } catch (final NoSuchMethodException ex) {
1594                 continue;
1595             }
1596         }
1597
1598         try {
1599             return getAnnotation(
1600                     c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()),
1601                     annotationClass);
1602         } catch (final SecurityException ex) {
1603             return null;
1604         } catch (final NoSuchMethodException ex) {
1605             return null;
1606         }
1607     }
1608
1609     /**
1610      * Searches the class hierarchy to see if the method or it's super
1611      * implementations and interfaces has the annotation. Returns the depth of the
1612      * annotation in the hierarchy.
1613      *
1614      * @param <A>
1615      *            type of the annotation
1616      *
1617      * @param m
1618      *            method to check
1619      * @param annotationClass
1620      *            annotation to look for
1621      * @return Depth of the annotation or -1 if the annotation is not on the method.
1622      */
1623     private static int getAnnotationDepth(final Method m, final Class<? extends Annotation> annotationClass) {
1624         // if we have invalid data the result is -1
1625         if (m == null || annotationClass == null) {
1626             return -1;
1627         }
1628
1629         if (m.isAnnotationPresent(annotationClass)) {
1630             return 1;
1631         }
1632
1633         // if we've already reached the Object class, return -1;
1634         Class<?> c = m.getDeclaringClass();
1635         if (c.getSuperclass() == null) {
1636             return -1;
1637         }
1638
1639         // check directly implemented interfaces for the method being checked
1640         for (Class<?> i : c.getInterfaces()) {
1641             try {
1642                 Method im = i.getMethod(m.getName(), m.getParameterTypes());
1643                 int d = getAnnotationDepth(im, annotationClass);
1644                 if (d > 0) {
1645                     // since the annotation was on the interface, add 1
1646                     return d + 1;
1647                 }
1648             } catch (final SecurityException ex) {
1649                 continue;
1650             } catch (final NoSuchMethodException ex) {
1651                 continue;
1652             }
1653         }
1654
1655         try {
1656             int d = getAnnotationDepth(
1657                     c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()),
1658                     annotationClass);
1659             if (d > 0) {
1660                 // since the annotation was on the superclass, add 1
1661                 return d + 1;
1662             }
1663             return -1;
1664         } catch (final SecurityException ex) {
1665             return -1;
1666         } catch (final NoSuchMethodException ex) {
1667             return -1;
1668         }
1669     }
1670
1671     /**
1672      * Put a key/boolean pair in the JSONObject.
1673      *
1674      * @param key
1675      *            A key string.
1676      * @param value
1677      *            A boolean which is the value.
1678      * @return this.
1679      * @throws JSONException
1680      *            If the value is non-finite number.
1681      * @throws NullPointerException
1682      *            If the key is <code>null</code>.
1683      */
1684     public JSONObject put(String key, boolean value) throws JSONException {
1685         return this.put(key, value ? Boolean.TRUE : Boolean.FALSE);
1686     }
1687
1688     /**
1689      * Put a key/value pair in the JSONObject, where the value will be a
1690      * JSONArray which is produced from a Collection.
1691      *
1692      * @param key
1693      *            A key string.
1694      * @param value
1695      *            A Collection value.
1696      * @return this.
1697      * @throws JSONException
1698      *            If the value is non-finite number.
1699      * @throws NullPointerException
1700      *            If the key is <code>null</code>.
1701      */
1702     public JSONObject put(String key, Collection<?> value) throws JSONException {
1703         return this.put(key, new JSONArray(value));
1704     }
1705
1706     /**
1707      * Put a key/double pair in the JSONObject.
1708      *
1709      * @param key
1710      *            A key string.
1711      * @param value
1712      *            A double which is the value.
1713      * @return this.
1714      * @throws JSONException
1715      *            If the value is non-finite number.
1716      * @throws NullPointerException
1717      *            If the key is <code>null</code>.
1718      */
1719     public JSONObject put(String key, double value) throws JSONException {
1720         return this.put(key, Double.valueOf(value));
1721     }
1722     
1723     /**
1724      * Put a key/float pair in the JSONObject.
1725      *
1726      * @param key
1727      *            A key string.
1728      * @param value
1729      *            A float which is the value.
1730      * @return this.
1731      * @throws JSONException
1732      *            If the value is non-finite number.
1733      * @throws NullPointerException
1734      *            If the key is <code>null</code>.
1735      */
1736     public JSONObject put(String key, float value) throws JSONException {
1737         return this.put(key, Float.valueOf(value));
1738     }
1739
1740     /**
1741      * Put a key/int pair in the JSONObject.
1742      *
1743      * @param key
1744      *            A key string.
1745      * @param value
1746      *            An int which is the value.
1747      * @return this.
1748      * @throws JSONException
1749      *            If the value is non-finite number.
1750      * @throws NullPointerException
1751      *            If the key is <code>null</code>.
1752      */
1753     public JSONObject put(String key, int value) throws JSONException {
1754         return this.put(key, Integer.valueOf(value));
1755     }
1756
1757     /**
1758      * Put a key/long pair in the JSONObject.
1759      *
1760      * @param key
1761      *            A key string.
1762      * @param value
1763      *            A long which is the value.
1764      * @return this.
1765      * @throws JSONException
1766      *            If the value is non-finite number.
1767      * @throws NullPointerException
1768      *            If the key is <code>null</code>.
1769      */
1770     public JSONObject put(String key, long value) throws JSONException {
1771         return this.put(key, Long.valueOf(value));
1772     }
1773
1774     /**
1775      * Put a key/value pair in the JSONObject, where the value will be a
1776      * JSONObject which is produced from a Map.
1777      *
1778      * @param key
1779      *            A key string.
1780      * @param value
1781      *            A Map value.
1782      * @return this.
1783      * @throws JSONException
1784      *            If the value is non-finite number.
1785      * @throws NullPointerException
1786      *            If the key is <code>null</code>.
1787      */
1788     public JSONObject put(String key, Map<?, ?> value) throws JSONException {
1789         return this.put(key, new JSONObject(value));
1790     }
1791
1792     /**
1793      * Put a key/value pair in the JSONObject. If the value is <code>null</code>, then the
1794      * key will be removed from the JSONObject if it is present.
1795      *
1796      * @param key
1797      *            A key string.
1798      * @param value
1799      *            An object which is the value. It should be of one of these
1800      *            types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
1801      *            String, or the JSONObject.NULL object.
1802      * @return this.
1803      * @throws JSONException
1804      *            If the value is non-finite number.
1805      * @throws NullPointerException
1806      *            If the key is <code>null</code>.
1807      */
1808     public JSONObject put(String key, Object value) throws JSONException {
1809         if (key == null) {
1810             throw new NullPointerException("Null key.");
1811         }
1812         if (value != null) {
1813             testValidity(value);
1814             this.map.put(key, value);
1815         } else {
1816             this.remove(key);
1817         }
1818         return this;
1819     }
1820
1821     /**
1822      * Put a key/value pair in the JSONObject, but only if the key and the value
1823      * are both non-null, and only if there is not already a member with that
1824      * name.
1825      *
1826      * @param key string
1827      * @param value object
1828      * @return this.
1829      * @throws JSONException
1830      *             if the key is a duplicate
1831      */
1832     public JSONObject putOnce(String key, Object value) throws JSONException {
1833         if (key != null && value != null) {
1834             if (this.opt(key) != null) {
1835                 throw new JSONException("Duplicate key \"" + key + "\"");
1836             }
1837             return this.put(key, value);
1838         }
1839         return this;
1840     }
1841
1842     /**
1843      * Put a key/value pair in the JSONObject, but only if the key and the value
1844      * are both non-null.
1845      *
1846      * @param key
1847      *            A key string.
1848      * @param value
1849      *            An object which is the value. It should be of one of these
1850      *            types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
1851      *            String, or the JSONObject.NULL object.
1852      * @return this.
1853      * @throws JSONException
1854      *             If the value is a non-finite number.
1855      */
1856     public JSONObject putOpt(String key, Object value) throws JSONException {
1857         if (key != null && value != null) {
1858             return this.put(key, value);
1859         }
1860         return this;
1861     }
1862
1863     /**
1864      * Creates a JSONPointer using an initialization string and tries to 
1865      * match it to an item within this JSONObject. For example, given a
1866      * JSONObject initialized with this document:
1867      * <pre>
1868      * {
1869      *     "a":{"b":"c"}
1870      * }
1871      * </pre>
1872      * and this JSONPointer string: 
1873      * <pre>
1874      * "/a/b"
1875      * </pre>
1876      * Then this method will return the String "c".
1877      * A JSONPointerException may be thrown from code called by this method.
1878      *   
1879      * @param jsonPointer string that can be used to create a JSONPointer
1880      * @return the item matched by the JSONPointer, otherwise null
1881      */
1882     public Object query(String jsonPointer) {
1883         return query(new JSONPointer(jsonPointer));
1884     }
1885     /**
1886      * Uses a user initialized JSONPointer  and tries to 
1887      * match it to an item within this JSONObject. For example, given a
1888      * JSONObject initialized with this document:
1889      * <pre>
1890      * {
1891      *     "a":{"b":"c"}
1892      * }
1893      * </pre>
1894      * and this JSONPointer: 
1895      * <pre>
1896      * "/a/b"
1897      * </pre>
1898      * Then this method will return the String "c".
1899      * A JSONPointerException may be thrown from code called by this method.
1900      *   
1901      * @param jsonPointer string that can be used to create a JSONPointer
1902      * @return the item matched by the JSONPointer, otherwise null
1903      */
1904     public Object query(JSONPointer jsonPointer) {
1905         return jsonPointer.queryFrom(this);
1906     }
1907     
1908     /**
1909      * Queries and returns a value from this object using {@code jsonPointer}, or
1910      * returns null if the query fails due to a missing key.
1911      * 
1912      * @param jsonPointer the string representation of the JSON pointer
1913      * @return the queried value or {@code null}
1914      * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
1915      */
1916     public Object optQuery(String jsonPointer) {
1917         return optQuery(new JSONPointer(jsonPointer));
1918     }
1919     
1920     /**
1921      * Queries and returns a value from this object using {@code jsonPointer}, or
1922      * returns null if the query fails due to a missing key.
1923      * 
1924      * @param jsonPointer The JSON pointer
1925      * @return the queried value or {@code null}
1926      * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
1927      */
1928     public Object optQuery(JSONPointer jsonPointer) {
1929         try {
1930             return jsonPointer.queryFrom(this);
1931         } catch (JSONPointerException e) {
1932             return null;
1933         }
1934     }
1935
1936     /**
1937      * Produce a string in double quotes with backslash sequences in all the
1938      * right places. A backslash will be inserted within </, producing <\/,
1939      * allowing JSON text to be delivered in HTML. In JSON text, a string cannot
1940      * contain a control character or an unescaped quote or backslash.
1941      *
1942      * @param string
1943      *            A String
1944      * @return A String correctly formatted for insertion in a JSON text.
1945      */
1946     public static String quote(String string) {
1947         StringWriter sw = new StringWriter();
1948         synchronized (sw.getBuffer()) {
1949             try {
1950                 return quote(string, sw).toString();
1951             } catch (IOException ignored) {
1952                 // will never happen - we are writing to a string writer
1953                 return "";
1954             }
1955         }
1956     }
1957
1958     public static Writer quote(String string, Writer w) throws IOException {
1959         if (string == null || string.isEmpty()) {
1960             w.write("\"\"");
1961             return w;
1962         }
1963
1964         char b;
1965         char c = 0;
1966         String hhhh;
1967         int i;
1968         int len = string.length();
1969
1970         w.write('"');
1971         for (i = 0; i < len; i += 1) {
1972             b = c;
1973             c = string.charAt(i);
1974             switch (c) {
1975             case '\\':
1976             case '"':
1977                 w.write('\\');
1978                 w.write(c);
1979                 break;
1980             case '/':
1981                 if (b == '<') {
1982                     w.write('\\');
1983                 }
1984                 w.write(c);
1985                 break;
1986             case '\b':
1987                 w.write("\\b");
1988                 break;
1989             case '\t':
1990                 w.write("\\t");
1991                 break;
1992             case '\n':
1993                 w.write("\\n");
1994                 break;
1995             case '\f':
1996                 w.write("\\f");
1997                 break;
1998             case '\r':
1999                 w.write("\\r");
2000                 break;
2001             default:
2002                 if (c < ' ' || (c >= '\u0080' && c < '\u00a0')
2003                         || (c >= '\u2000' && c < '\u2100')) {
2004                     w.write("\\u");
2005                     hhhh = Integer.toHexString(c);
2006                     w.write("0000", 0, 4 - hhhh.length());
2007                     w.write(hhhh);
2008                 } else {
2009                     w.write(c);
2010                 }
2011             }
2012         }
2013         w.write('"');
2014         return w;
2015     }
2016
2017     /**
2018      * Remove a name and its value, if present.
2019      *
2020      * @param key
2021      *            The name to be removed.
2022      * @return The value that was associated with the name, or null if there was
2023      *         no value.
2024      */
2025     public Object remove(String key) {
2026         return this.map.remove(key);
2027     }
2028
2029     /**
2030      * Determine if two JSONObjects are similar.
2031      * They must contain the same set of names which must be associated with
2032      * similar values.
2033      *
2034      * @param other The other JSONObject
2035      * @return true if they are equal
2036      */
2037     public boolean similar(Object other) {
2038         try {
2039             if (!(other instanceof JSONObject)) {
2040                 return false;
2041             }
2042             if (!this.keySet().equals(((JSONObject)other).keySet())) {
2043                 return false;
2044             }
2045             for (final Entry<String,?> entry : this.entrySet()) {
2046                 String name = entry.getKey();
2047                 Object valueThis = entry.getValue();
2048                 Object valueOther = ((JSONObject)other).get(name);
2049                 if(valueThis == valueOther) {
2050                         continue;
2051                 }
2052                 if(valueThis == null) {
2053                         return false;
2054                 }
2055                 if (valueThis instanceof JSONObject) {
2056                     if (!((JSONObject)valueThis).similar(valueOther)) {
2057                         return false;
2058                     }
2059                 } else if (valueThis instanceof JSONArray) {
2060                     if (!((JSONArray)valueThis).similar(valueOther)) {
2061                         return false;
2062                     }
2063                 } else if (!valueThis.equals(valueOther)) {
2064                     return false;
2065                 }
2066             }
2067             return true;
2068         } catch (Throwable exception) {
2069             return false;
2070         }
2071     }
2072     
2073     /**
2074      * Tests if the value should be tried as a decimal. It makes no test if there are actual digits.
2075      * 
2076      * @param val value to test
2077      * @return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise.
2078      */
2079     protected static boolean isDecimalNotation(final String val) {
2080         return val.indexOf('.') > -1 || val.indexOf('e') > -1
2081                 || val.indexOf('E') > -1 || "-0".equals(val);
2082     }
2083     
2084     /**
2085      * Converts a string to a number using the narrowest possible type. Possible 
2086      * returns for this function are BigDecimal, Double, BigInteger, Long, and Integer.
2087      * When a Double is returned, it should always be a valid Double and not NaN or +-infinity.
2088      * 
2089      * @param val value to convert
2090      * @return Number representation of the value.
2091      * @throws NumberFormatException thrown if the value is not a valid number. A public
2092      *      caller should catch this and wrap it in a {@link JSONException} if applicable.
2093      */
2094     protected static Number stringToNumber(final String val) throws NumberFormatException {
2095         char initial = val.charAt(0);
2096         if ((initial >= '0' && initial <= '9') || initial == '-') {
2097             // decimal representation
2098             if (isDecimalNotation(val)) {
2099                 // quick dirty way to see if we need a BigDecimal instead of a Double
2100                 // this only handles some cases of overflow or underflow
2101                 if (val.length()>14) {
2102                     return new BigDecimal(val);
2103                 }
2104                 final Double d = Double.valueOf(val);
2105                 if (d.isInfinite() || d.isNaN()) {
2106                     // if we can't parse it as a double, go up to BigDecimal
2107                     // this is probably due to underflow like 4.32e-678
2108                     // or overflow like 4.65e5324. The size of the string is small
2109                     // but can't be held in a Double.
2110                     return new BigDecimal(val);
2111                 }
2112                 return d;
2113             }
2114             // integer representation.
2115             // This will narrow any values to the smallest reasonable Object representation
2116             // (Integer, Long, or BigInteger)
2117             
2118             // string version
2119             // The compare string length method reduces GC,
2120             // but leads to smaller integers being placed in larger wrappers even though not
2121             // needed. i.e. 1,000,000,000 -> Long even though it's an Integer
2122             // 1,000,000,000,000,000,000 -> BigInteger even though it's a Long
2123             //if(val.length()<=9){
2124             //    return Integer.valueOf(val);
2125             //}
2126             //if(val.length()<=18){
2127             //    return Long.valueOf(val);
2128             //}
2129             //return new BigInteger(val);
2130             
2131             // BigInteger version: We use a similar bitLenth compare as
2132             // BigInteger#intValueExact uses. Increases GC, but objects hold
2133             // only what they need. i.e. Less runtime overhead if the value is
2134             // long lived. Which is the better tradeoff? This is closer to what's
2135             // in stringToValue.
2136             BigInteger bi = new BigInteger(val);
2137             if(bi.bitLength()<=31){
2138                 return Integer.valueOf(bi.intValue());
2139             }
2140             if(bi.bitLength()<=63){
2141                 return Long.valueOf(bi.longValue());
2142             }
2143             return bi;
2144         }
2145         throw new NumberFormatException("val ["+val+"] is not a valid number.");
2146     }
2147
2148     /**
2149      * Try to convert a string into a number, boolean, or null. If the string
2150      * can't be converted, return the string.
2151      *
2152      * @param string
2153      *            A String.
2154      * @return A simple JSON value.
2155      */
2156     // Changes to this method must be copied to the corresponding method in
2157     // the XML class to keep full support for Android
2158     public static Object stringToValue(String string) {
2159         if (string.equals("")) {
2160             return string;
2161         }
2162         if (string.equalsIgnoreCase("true")) {
2163             return Boolean.TRUE;
2164         }
2165         if (string.equalsIgnoreCase("false")) {
2166             return Boolean.FALSE;
2167         }
2168         if (string.equalsIgnoreCase("null")) {
2169             return JSONObject.NULL;
2170         }
2171
2172         /*
2173          * If it might be a number, try converting it. If a number cannot be
2174          * produced, then the value will just be a string.
2175          */
2176
2177         char initial = string.charAt(0);
2178         if ((initial >= '0' && initial <= '9') || initial == '-') {
2179             try {
2180                 // if we want full Big Number support this block can be replaced with:
2181                 // return stringToNumber(string);
2182                 if (isDecimalNotation(string)) {
2183                     Double d = Double.valueOf(string);
2184                     if (!d.isInfinite() && !d.isNaN()) {
2185                         return d;
2186                     }
2187                 } else {
2188                     Long myLong = Long.valueOf(string);
2189                     if (string.equals(myLong.toString())) {
2190                         if (myLong.longValue() == myLong.intValue()) {
2191                             return Integer.valueOf(myLong.intValue());
2192                         }
2193                         return myLong;
2194                     }
2195                 }
2196             } catch (Exception ignore) {
2197             }
2198         }
2199         return string;
2200     }
2201
2202     /**
2203      * Throw an exception if the object is a NaN or infinite number.
2204      *
2205      * @param o
2206      *            The object to test.
2207      * @throws JSONException
2208      *             If o is a non-finite number.
2209      */
2210     public static void testValidity(Object o) throws JSONException {
2211         if (o != null) {
2212             if (o instanceof Double) {
2213                 if (((Double) o).isInfinite() || ((Double) o).isNaN()) {
2214                     throw new JSONException(
2215                             "JSON does not allow non-finite numbers.");
2216                 }
2217             } else if (o instanceof Float) {
2218                 if (((Float) o).isInfinite() || ((Float) o).isNaN()) {
2219                     throw new JSONException(
2220                             "JSON does not allow non-finite numbers.");
2221                 }
2222             }
2223         }
2224     }
2225
2226     /**
2227      * Produce a JSONArray containing the values of the members of this
2228      * JSONObject.
2229      *
2230      * @param names
2231      *            A JSONArray containing a list of key strings. This determines
2232      *            the sequence of the values in the result.
2233      * @return A JSONArray of values.
2234      * @throws JSONException
2235      *             If any of the values are non-finite numbers.
2236      */
2237     public JSONArray toJSONArray(JSONArray names) throws JSONException {
2238         if (names == null || names.isEmpty()) {
2239             return null;
2240         }
2241         JSONArray ja = new JSONArray();
2242         for (int i = 0; i < names.length(); i += 1) {
2243             ja.put(this.opt(names.getString(i)));
2244         }
2245         return ja;
2246     }
2247
2248     /**
2249      * Make a JSON text of this JSONObject. For compactness, no whitespace is
2250      * added. If this would not result in a syntactically correct JSON text,
2251      * then null will be returned instead.
2252      * <p><b>
2253      * Warning: This method assumes that the data structure is acyclical.
2254      * </b>
2255      * 
2256      * @return a printable, displayable, portable, transmittable representation
2257      *         of the object, beginning with <code>{</code>&nbsp;<small>(left
2258      *         brace)</small> and ending with <code>}</code>&nbsp;<small>(right
2259      *         brace)</small>.
2260      */
2261     @Override
2262     public String toString() {
2263         try {
2264             return this.toString(0);
2265         } catch (Exception e) {
2266             return null;
2267         }
2268     }
2269
2270     /**
2271      * Make a pretty-printed JSON text of this JSONObject.
2272      * 
2273      * <p>If <code>indentFactor > 0</code> and the {@link JSONObject}
2274      * has only one key, then the object will be output on a single line:
2275      * <pre>{@code {"key": 1}}</pre>
2276      * 
2277      * <p>If an object has 2 or more keys, then it will be output across
2278      * multiple lines: <code><pre>{
2279      *  "key1": 1,
2280      *  "key2": "value 2",
2281      *  "key3": 3
2282      * }</pre></code>
2283      * <p><b>
2284      * Warning: This method assumes that the data structure is acyclical.
2285      * </b>
2286      *
2287      * @param indentFactor
2288      *            The number of spaces to add to each level of indentation.
2289      * @return a printable, displayable, portable, transmittable representation
2290      *         of the object, beginning with <code>{</code>&nbsp;<small>(left
2291      *         brace)</small> and ending with <code>}</code>&nbsp;<small>(right
2292      *         brace)</small>.
2293      * @throws JSONException
2294      *             If the object contains an invalid number.
2295      */
2296     public String toString(int indentFactor) throws JSONException {
2297         StringWriter w = new StringWriter();
2298         synchronized (w.getBuffer()) {
2299             return this.write(w, indentFactor, 0).toString();
2300         }
2301     }
2302
2303     /**
2304      * Make a JSON text of an Object value. If the object has an
2305      * value.toJSONString() method, then that method will be used to produce the
2306      * JSON text. The method is required to produce a strictly conforming text.
2307      * If the object does not contain a toJSONString method (which is the most
2308      * common case), then a text will be produced by other means. If the value
2309      * is an array or Collection, then a JSONArray will be made from it and its
2310      * toJSONString method will be called. If the value is a MAP, then a
2311      * JSONObject will be made from it and its toJSONString method will be
2312      * called. Otherwise, the value's toString method will be called, and the
2313      * result will be quoted.
2314      *
2315      * <p>
2316      * Warning: This method assumes that the data structure is acyclical.
2317      *
2318      * @param value
2319      *            The value to be serialized.
2320      * @return a printable, displayable, transmittable representation of the
2321      *         object, beginning with <code>{</code>&nbsp;<small>(left
2322      *         brace)</small> and ending with <code>}</code>&nbsp;<small>(right
2323      *         brace)</small>.
2324      * @throws JSONException
2325      *             If the value is or contains an invalid number.
2326      */
2327     public static String valueToString(Object value) throws JSONException {
2328         // moves the implementation to JSONWriter as:
2329         // 1. It makes more sense to be part of the writer class
2330         // 2. For Android support this method is not available. By implementing it in the Writer
2331         //    Android users can use the writer with the built in Android JSONObject implementation.
2332         return JSONWriter.valueToString(value);
2333     }
2334
2335     /**
2336      * Wrap an object, if necessary. If the object is <code>null</code>, return the NULL
2337      * object. If it is an array or collection, wrap it in a JSONArray. If it is
2338      * a map, wrap it in a JSONObject. If it is a standard property (Double,
2339      * String, et al) then it is already wrapped. Otherwise, if it comes from
2340      * one of the java packages, turn it into a string. And if it doesn't, try
2341      * to wrap it in a JSONObject. If the wrapping fails, then null is returned.
2342      *
2343      * @param object
2344      *            The object to wrap
2345      * @return The wrapped value
2346      */
2347     public static Object wrap(Object object) {
2348         try {
2349             if (object == null) {
2350                 return NULL;
2351             }
2352             if (object instanceof JSONObject || object instanceof JSONArray
2353                     || NULL.equals(object) || object instanceof JSONString
2354                     || object instanceof Byte || object instanceof Character
2355                     || object instanceof Short || object instanceof Integer
2356                     || object instanceof Long || object instanceof Boolean
2357                     || object instanceof Float || object instanceof Double
2358                     || object instanceof String || object instanceof BigInteger
2359                     || object instanceof BigDecimal || object instanceof Enum) {
2360                 return object;
2361             }
2362
2363             if (object instanceof Collection) {
2364                 Collection<?> coll = (Collection<?>) object;
2365                 return new JSONArray(coll);
2366             }
2367             if (object.getClass().isArray()) {
2368                 return new JSONArray(object);
2369             }
2370             if (object instanceof Map) {
2371                 Map<?, ?> map = (Map<?, ?>) object;
2372                 return new JSONObject(map);
2373             }
2374             Package objectPackage = object.getClass().getPackage();
2375             String objectPackageName = objectPackage != null ? objectPackage
2376                     .getName() : "";
2377             if (objectPackageName.startsWith("java.")
2378                     || objectPackageName.startsWith("javax.")
2379                     || object.getClass().getClassLoader() == null) {
2380                 return object.toString();
2381             }
2382             return new JSONObject(object);
2383         } catch (Exception exception) {
2384             return null;
2385         }
2386     }
2387
2388     /**
2389      * Write the contents of the JSONObject as JSON text to a writer. For
2390      * compactness, no whitespace is added.
2391      * <p><b>
2392      * Warning: This method assumes that the data structure is acyclical.
2393      * </b>
2394      * 
2395      * @return The writer.
2396      * @throws JSONException
2397      */
2398     public Writer write(Writer writer) throws JSONException {
2399         return this.write(writer, 0, 0);
2400     }
2401
2402     static final Writer writeValue(Writer writer, Object value,
2403             int indentFactor, int indent) throws JSONException, IOException {
2404         if (value == null || value.equals(null)) {
2405             writer.write("null");
2406         } else if (value instanceof JSONString) {
2407             Object o;
2408             try {
2409                 o = ((JSONString) value).toJSONString();
2410             } catch (Exception e) {
2411                 throw new JSONException(e);
2412             }
2413             writer.write(o != null ? o.toString() : quote(value.toString()));
2414         } else if (value instanceof Number) {
2415             // not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
2416             final String numberAsString = numberToString((Number) value);
2417             try {
2418                 // Use the BigDecimal constructor for its parser to validate the format.
2419                 @SuppressWarnings("unused")
2420                 BigDecimal testNum = new BigDecimal(numberAsString);
2421                 // Close enough to a JSON number that we will use it unquoted
2422                 writer.write(numberAsString);
2423             } catch (NumberFormatException ex){
2424                 // The Number value is not a valid JSON number.
2425                 // Instead we will quote it as a string
2426                 quote(numberAsString, writer);
2427             }
2428         } else if (value instanceof Boolean) {
2429             writer.write(value.toString());
2430         } else if (value instanceof Enum<?>) {
2431             writer.write(quote(((Enum<?>)value).name()));
2432         } else if (value instanceof JSONObject) {
2433             ((JSONObject) value).write(writer, indentFactor, indent);
2434         } else if (value instanceof JSONArray) {
2435             ((JSONArray) value).write(writer, indentFactor, indent);
2436         } else if (value instanceof Map) {
2437             Map<?, ?> map = (Map<?, ?>) value;
2438             new JSONObject(map).write(writer, indentFactor, indent);
2439         } else if (value instanceof Collection) {
2440             Collection<?> coll = (Collection<?>) value;
2441             new JSONArray(coll).write(writer, indentFactor, indent);
2442         } else if (value.getClass().isArray()) {
2443             new JSONArray(value).write(writer, indentFactor, indent);
2444         } else {
2445             quote(value.toString(), writer);
2446         }
2447         return writer;
2448     }
2449
2450     static final void indent(Writer writer, int indent) throws IOException {
2451         for (int i = 0; i < indent; i += 1) {
2452             writer.write(' ');
2453         }
2454     }
2455
2456     /**
2457      * Write the contents of the JSONObject as JSON text to a writer.
2458      * 
2459      * <p>If <code>indentFactor > 0</code> and the {@link JSONObject}
2460      * has only one key, then the object will be output on a single line:
2461      * <pre>{@code {"key": 1}}</pre>
2462      * 
2463      * <p>If an object has 2 or more keys, then it will be output across
2464      * multiple lines: <code><pre>{
2465      *  "key1": 1,
2466      *  "key2": "value 2",
2467      *  "key3": 3
2468      * }</pre></code>
2469      * <p><b>
2470      * Warning: This method assumes that the data structure is acyclical.
2471      * </b>
2472      *
2473      * @param writer
2474      *            Writes the serialized JSON
2475      * @param indentFactor
2476      *            The number of spaces to add to each level of indentation.
2477      * @param indent
2478      *            The indentation of the top level.
2479      * @return The writer.
2480      * @throws JSONException
2481      */
2482     public Writer write(Writer writer, int indentFactor, int indent)
2483             throws JSONException {
2484         try {
2485             boolean commanate = false;
2486             final int length = this.length();
2487             writer.write('{');
2488
2489             if (length == 1) {
2490                 final Entry<String,?> entry = this.entrySet().iterator().next();
2491                 final String key = entry.getKey();
2492                 writer.write(quote(key));
2493                 writer.write(':');
2494                 if (indentFactor > 0) {
2495                     writer.write(' ');
2496                 }
2497                 try{
2498                     writeValue(writer, entry.getValue(), indentFactor, indent);
2499                 } catch (Exception e) {
2500                     throw new JSONException("Unable to write JSONObject value for key: " + key, e);
2501                 }
2502             } else if (length != 0) {
2503                 final int newindent = indent + indentFactor;
2504                 for (final Entry<String,?> entry : this.entrySet()) {
2505                     if (commanate) {
2506                         writer.write(',');
2507                     }
2508                     if (indentFactor > 0) {
2509                         writer.write('\n');
2510                     }
2511                     indent(writer, newindent);
2512                     final String key = entry.getKey();
2513                     writer.write(quote(key));
2514                     writer.write(':');
2515                     if (indentFactor > 0) {
2516                         writer.write(' ');
2517                     }
2518                     try {
2519                         writeValue(writer, entry.getValue(), indentFactor, newindent);
2520                     } catch (Exception e) {
2521                         throw new JSONException("Unable to write JSONObject value for key: " + key, e);
2522                     }
2523                     commanate = true;
2524                 }
2525                 if (indentFactor > 0) {
2526                     writer.write('\n');
2527                 }
2528                 indent(writer, indent);
2529             }
2530             writer.write('}');
2531             return writer;
2532         } catch (IOException exception) {
2533             throw new JSONException(exception);
2534         }
2535     }
2536
2537     /**
2538      * Returns a java.util.Map containing all of the entries in this object.
2539      * If an entry in the object is a JSONArray or JSONObject it will also
2540      * be converted.
2541      * <p>
2542      * Warning: This method assumes that the data structure is acyclical.
2543      *
2544      * @return a java.util.Map containing the entries of this object
2545      */
2546     public Map<String, Object> toMap() {
2547         Map<String, Object> results = new HashMap<String, Object>();
2548         for (Entry<String, Object> entry : this.entrySet()) {
2549             Object value;
2550             if (entry.getValue() == null || NULL.equals(entry.getValue())) {
2551                 value = null;
2552             } else if (entry.getValue() instanceof JSONObject) {
2553                 value = ((JSONObject) entry.getValue()).toMap();
2554             } else if (entry.getValue() instanceof JSONArray) {
2555                 value = ((JSONArray) entry.getValue()).toList();
2556             } else {
2557                 value = entry.getValue();
2558             }
2559             results.put(entry.getKey(), value);
2560         }
2561         return results;
2562     }
2563 }