4
Copyright (c) 2002 JSON.org
6
Permission is hereby granted, free of charge, to any person obtaining a copy
7
of this software and associated documentation files (the "Software"), to deal
8
in the Software without restriction, including without limitation the rights
9
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
copies of the Software, and to permit persons to whom the Software is
11
furnished to do so, subject to the following conditions:
13
The above copyright notice and this permission notice shall be included in all
14
copies or substantial portions of the Software.
16
The Software shall be used for Good, not Evil.
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
import java.io.IOException;
28
import java.io.Writer;
29
import java.util.Enumeration;
30
import java.util.Hashtable;
31
import java.util.Vector;
34
* A JSONObject is an unordered collection of name/value pairs. Its
35
* external form is a string wrapped in curly braces with colons between the
36
* names and values, and commas between the values and names. The internal form
37
* is an object having <code>get</code> and <code>opt</code> methods for
38
* accessing the values by name, and <code>put</code> methods for adding or
39
* replacing values by name. The values can be any of these types:
40
* <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
41
* <code>Number</code>, <code>String</code>, or the <code>JSONObject.NULL</code>
42
* object. A JSONObject constructor can be used to convert an external form
43
* JSON text into an internal form whose values can be retrieved with the
44
* <code>get</code> and <code>opt</code> methods, or to convert values into a
45
* JSON text using the <code>put</code> and <code>toString</code> methods.
46
* A <code>get</code> method returns a value if one can be found, and throws an
47
* exception if one cannot be found. An <code>opt</code> method returns a
48
* default value instead of throwing an exception, and so is useful for
49
* obtaining optional values.
51
* The generic <code>get()</code> and <code>opt()</code> methods return an
52
* object, which you can cast or query for type. There are also typed
53
* <code>get</code> and <code>opt</code> methods that do type checking and type
56
* The <code>put</code> methods adds values to an object. For example, <pre>
57
* myString = new JSONObject().put("JSON", "Hello, World!").toString();</pre>
58
* produces the string <code>{"JSON": "Hello, World"}</code>.
60
* The texts produced by the <code>toString</code> methods strictly conform to
61
* the JSON sysntax rules.
62
* The constructors are more forgiving in the texts they will accept:
64
* <li>An extra <code>,</code> <small>(comma)</small> may appear just
65
* before the closing brace.</li>
66
* <li>Strings may be quoted with <code>'</code> <small>(single
67
* quote)</small>.</li>
68
* <li>Strings do not need to be quoted at all if they do not begin with a quote
69
* or single quote, and if they do not contain leading or trailing spaces,
70
* and if they do not contain any of these characters:
71
* <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers
72
* and if they are not the reserved words <code>true</code>,
73
* <code>false</code>, or <code>null</code>.</li>
74
* <li>Keys can be followed by <code>=</code> or <code>=></code> as well as
75
* by <code>:</code>.</li>
76
* <li>Values can be followed by <code>;</code> <small>(semicolon)</small> as
77
* well as by <code>,</code> <small>(comma)</small>.</li>
78
* <li>Numbers may have the <code>0-</code> <small>(octal)</small> or
79
* <code>0x-</code> <small>(hex)</small> prefix.</li>
80
* <li>Comments written in the slashshlash, slashstar, and hash conventions
81
* will be ignored.</li>
86
public class JSONObject {
89
public static final Boolean TRUE = new Boolean(true);
90
public static final Boolean FALSE = new Boolean(false);
94
* JSONObject.NULL is equivalent to the value that JavaScript calls null,
95
* whilst Java's null is equivalent to the value that JavaScript calls
98
private static final class Null {
101
* There is only intended to be a single instance of the NULL object,
102
* so the clone method returns itself.
105
protected final Object clone() {
111
* A Null object is equal to the null value and to itself.
112
* @param object An object to test for nullness.
113
* @return true if the object parameter is the JSONObject.NULL object
116
public boolean equals(Object object) {
117
return object == null || object == this;
122
* Get the "null" string value.
123
* @return The string "null".
125
public String toString() {
132
* The hash map where the JSONObject's properties are kept.
134
private Hashtable myHashMap;
138
* It is sometimes more convenient and less ambiguous to have a
139
* <code>NULL</code> object than to use Java's <code>null</code> value.
140
* <code>JSONObject.NULL.equals(null)</code> returns <code>true</code>.
141
* <code>JSONObject.NULL.toString()</code> returns <code>"null"</code>.
143
public static final Object NULL = new Null();
146
* Construct an empty JSONObject.
148
public JSONObject() {
149
this.myHashMap = new Hashtable();
155
//# * Construct a JSONObject from a subset of another JSONObject.
156
//# * An array of strings is used to identify the keys that should be copied.
157
//# * Missing keys are ignored.
158
//# * @param jo A JSONObject.
159
//# * @param sa An array of strings.
160
//# * @exception JSONException If a value is a non-finite number.
162
//# public JSONObject(JSONObject jo, String[] sa) throws JSONException {
164
//# for (int i = 0; i < sa.length; i += 1) {
165
//# putOpt(sa[i], jo.opt(sa[i]));
171
* Construct a JSONObject from a JSONTokener.
172
* @param x A JSONTokener object containing the source string.
173
* @throws JSONException If there is a syntax error in the source string.
175
public JSONObject(JSONTokener x) throws JSONException {
180
if (x.nextClean() != '{') {
181
throw x.syntaxError("A JSONObject text must begin with '{'");
187
throw x.syntaxError("A JSONObject text must end with '}'");
192
key = x.nextValue().toString();
196
* The key is followed by ':'. We will also tolerate '=' or '=>'.
201
if (x.next() != '>') {
204
} else if (c != ':') {
205
throw x.syntaxError("Expected a ':' after a key");
207
put(key, x.nextValue());
210
* Pairs are separated by ','. We will also tolerate ';'.
213
switch (x.nextClean()) {
216
if (x.nextClean() == '}') {
224
throw x.syntaxError("Expected a ',' or '}'");
232
//# * Construct a JSONObject from a Map.
233
//# * @param map A map object that can be used to initialize the contents of
234
//# * the JSONObject.
236
//# public JSONObject(Hashtable map) {
237
//# if (map == null) {
238
//# this.myHashMap = new Hashtable();
240
//# this.myHashMap = new Hashtable(map.size());
241
//# Enumeration keys = map.keys();
242
//# while (keys.hasMoreElements()) {
243
//# Object key = keys.nextElement();
244
//# this.myHashMap.put(key, map.get(key));
251
* Construct a JSONObject from a string.
252
* This is the most commonly used JSONObject constructor.
253
* @param string A string beginning
254
* with <code>{</code> <small>(left brace)</small> and ending
255
* with <code>}</code> <small>(right brace)</small>.
256
* @exception JSONException If there is a syntax error in the source string.
258
public JSONObject(String string) throws JSONException {
259
this(new JSONTokener(string));
264
* Accumulate values under a key. It is similar to the put method except
265
* that if there is already an object stored under the key then a
266
* JSONArray is stored under the key to hold all of the accumulated values.
267
* If there is already a JSONArray, then the new value is appended to it.
268
* In contrast, the put method replaces the previous value.
269
* @param key A key string.
270
* @param value An object to be accumulated under the key.
272
* @throws JSONException If the value is an invalid number
273
* or if the key is null.
275
public JSONObject accumulate(String key, Object value)
276
throws JSONException {
281
} else if (o instanceof JSONArray) {
282
((JSONArray)o).put(value);
284
put(key, new JSONArray().put(o).put(value));
291
//# * Append values to the array under a key. If the key does not exist in the
292
//# * JSONObject, then the key is put in the JSONObject with its value being a
293
//# * JSONArray containing the value parameter. If the key was already
294
//# * associated with a JSONArray, then the value parameter is appended to it.
295
//# * @param key A key string.
296
//# * @param value An object to be accumulated under the key.
298
//# * @throws JSONException If the key is null or if the current value
299
//# * associated with the key is not a JSONArray.
301
//# public JSONObject append(String key, Object value)
302
//# throws JSONException {
303
//# testValidity(value);
304
//# Object o = opt(key);
306
//# put(key, new JSONArray().put(value));
307
//# } else if (o instanceof JSONArray) {
308
//# throw new JSONException("JSONObject[" + key +
309
//# "] is not a JSONArray.");
311
//# put(key, new JSONArray().put(o).put(value));
319
//# * Produce a string from a double. The string "null" will be returned if
320
//# * the number is not finite.
321
//# * @param d A double.
322
//# * @return A String.
324
//# static public String doubleToString(double d) {
325
//# if (Double.isInfinite(d) || Double.isNaN(d)) {
329
//# // Shave off trailing zeros and decimal point, if possible.
331
//# String s = Double.toString(d);
332
//# if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) {
333
//# while (s.endsWith("0")) {
334
//# s = s.substring(0, s.length() - 1);
336
//# if (s.endsWith(".")) {
337
//# s = s.substring(0, s.length() - 1);
345
* Get the value object associated with a key.
347
* @param key A key string.
348
* @return The object associated with the key.
349
* @throws JSONException if the key is not found.
351
public Object get(String key) throws JSONException {
354
throw new JSONException("JSONObject[" + quote(key) +
362
* Get the boolean value associated with a key.
364
* @param key A key string.
366
* @throws JSONException
367
* if the value is not a Boolean or the String "true" or "false".
369
public boolean getBoolean(String key) throws JSONException {
372
//# if (o.equals(Boolean.FALSE) ||
374
if (o.equals(FALSE) ||
376
(o instanceof String &&
377
((String)o).toLowerCase().equals("false"))) {
380
//# } else if (o.equals(Boolean.TRUE) ||
382
} else if (o.equals(TRUE) ||
384
(o instanceof String &&
385
((String)o).toLowerCase().equals("true"))) {
388
throw new JSONException("JSONObject[" + quote(key) +
389
"] is not a Boolean.");
394
//# * Get the double value associated with a key.
395
//# * @param key A key string.
396
//# * @return The numeric value.
397
//# * @throws JSONException if the key is not found or
398
//# * if the value is not a Number object and cannot be converted to a number.
400
//# public double getDouble(String key) throws JSONException {
401
//# Object o = get(key);
402
//# if (o instanceof Byte) {
403
//# return (double) ((Byte)o).byteValue();
404
//# } else if (o instanceof Short) {
405
//# return (double) ((Short)o).shortValue();
406
//# } else if (o instanceof Integer) {
407
//# return (double) ((Integer)o).intValue();
408
//# } else if (o instanceof Long) {
409
//# return (double) ((Long)o).longValue();
410
//# } else if (o instanceof Float) {
411
//# return (double) ((Float)o).floatValue();
412
//# } else if (o instanceof Double) {
413
//# return ((Double)o).doubleValue();
414
//# } else if (o instanceof String) {
416
//# return Double.valueOf((String)o).doubleValue();
417
//# } catch (Exception e) {
418
//# throw new JSONException("JSONObject[" + quote(key) +
419
//# "] is not a number.");
422
//# throw new JSONException("JSONObject[" + quote(key) +
423
//# "] is not a number.");
429
* Get the int value associated with a key. If the number value is too
430
* large for an int, it will be clipped.
432
* @param key A key string.
433
* @return The integer value.
434
* @throws JSONException if the key is not found or if the value cannot
435
* be converted to an integer.
437
public int getInt(String key) throws JSONException {
439
if (o instanceof Byte) {
440
return ((Byte)o).byteValue();
441
} else if (o instanceof Short) {
442
return ((Short)o).shortValue();
443
} else if (o instanceof Integer) {
444
return ((Integer)o).intValue();
445
} else if (o instanceof Long) {
446
return (int) ((Long)o).longValue();
448
//# } else if (o instanceof Float) {
449
//# return (int) ((Float)o).floatValue();
450
//# } else if (o instanceof Double) {
451
//# return (int) ((Double)o).doubleValue();
452
//# } else if (o instanceof String) {
453
//# return (int) getDouble(key);
456
throw new JSONException("JSONObject[" + quote(key) +
457
"] is not a number.");
462
* Get the JSONArray value associated with a key.
464
* @param key A key string.
465
* @return A JSONArray which is the value.
466
* @throws JSONException if the key is not found or
467
* if the value is not a JSONArray.
469
public JSONArray getJSONArray(String key) throws JSONException {
471
if (o instanceof JSONArray) {
474
throw new JSONException("JSONObject[" + quote(key) +
475
"] is not a JSONArray.");
479
* Get the JSONObject value associated with a key.
481
* @param key A key string.
482
* @return A JSONObject which is the value.
483
* @throws JSONException if the key is not found or
484
* if the value is not a JSONObject.
486
public JSONObject getJSONObject(String key) throws JSONException {
488
if (o instanceof JSONObject) {
489
return (JSONObject)o;
491
throw new JSONException("JSONObject[" + quote(key) +
492
"] is not a JSONObject.");
496
* Get the long value associated with a key. If the number value is too
497
* long for a long, it will be clipped.
499
* @param key A key string.
500
* @return The long value.
501
* @throws JSONException if the key is not found or if the value cannot
502
* be converted to a long.
504
public long getLong(String key) throws JSONException {
506
if (o instanceof Byte) {
507
return ((Byte)o).byteValue();
508
} else if (o instanceof Short) {
509
return ((Short)o).shortValue();
510
} else if (o instanceof Integer) {
511
return ((Integer)o).intValue();
512
} else if (o instanceof Long) {
513
return ((Long)o).longValue();
515
//# } else if (o instanceof Float) {
516
//# return (long) ((Float)o).floatValue();
517
//# } else if (o instanceof Double) {
518
//# return (long) ((Double)o).doubleValue();
519
//# } else if (o instanceof String) {
520
//# return (long) getDouble(key);
523
throw new JSONException("JSONObject[" + quote(key) +
524
"] is not a number.");
528
* Get the string associated with a key.
530
* @param key A key string.
531
* @return A string which is the value.
532
* @throws JSONException if the key is not found.
534
public String getString(String key) throws JSONException {
535
return get(key).toString();
539
* Determine if the JSONObject contains a specific key.
540
* @param key A key string.
541
* @return true if the key exists in the JSONObject.
543
public boolean has(String key) {
544
return this.myHashMap.containsKey(key);
549
* Determine if the value associated with the key is null or if there is
551
* @param key A key string.
552
* @return true if there is no value associated with the key or if
553
* the value is the JSONObject.NULL object.
555
public boolean isNull(String key) {
556
return JSONObject.NULL.equals(opt(key));
561
* Get an enumeration of the keys of the JSONObject.
563
* @return An iterator of the keys.
565
public Enumeration keys() {
566
return this.myHashMap.keys();
571
* Get the number of keys stored in the JSONObject.
573
* @return The number of keys in the JSONObject.
575
public int length() {
576
return this.myHashMap.size();
581
* Produce a JSONArray containing the names of the elements of this
583
* @return A JSONArray containing the key strings, or null if the JSONObject
586
public JSONArray names() {
587
JSONArray ja = new JSONArray();
588
Enumeration keys = keys();
589
while (keys.hasMoreElements()) {
590
ja.put(keys.nextElement());
592
return ja.length() == 0 ? null : ja;
597
* Shave off trailing zeros and decimal point, if possible.
599
static public String trimNumber(String s) {
600
if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) {
601
while (s.endsWith("0")) {
602
s = s.substring(0, s.length() - 1);
604
if (s.endsWith(".")) {
605
s = s.substring(0, s.length() - 1);
612
* Produce a string from a Number.
615
* @throws JSONException If n is a non-finite number.
617
static public String numberToString(Object n)
618
throws JSONException {
620
throw new JSONException("Null pointer");
623
return trimNumber(n.toString());
627
* Get an optional value associated with a key.
628
* @param key A key string.
629
* @return An object which is the value, or null if there is no value.
631
public Object opt(String key) {
632
return key == null ? null : this.myHashMap.get(key);
637
* Get an optional boolean associated with a key.
638
* It returns false if there is no such key, or if the value is not
639
* Boolean.TRUE or the String "true".
641
* @param key A key string.
644
public boolean optBoolean(String key) {
645
return optBoolean(key, false);
650
* Get an optional boolean associated with a key.
651
* It returns the defaultValue if there is no such key, or if it is not
652
* a Boolean or the String "true" or "false" (case insensitive).
654
* @param key A key string.
655
* @param defaultValue The default.
658
public boolean optBoolean(String key, boolean defaultValue) {
660
return getBoolean(key);
661
} catch (Exception e) {
668
* Put a key/value pair in the JSONObject, where the value will be a
669
* JSONArray which is produced from a Collection.
670
* @param key A key string.
671
* @param value A Collection value.
673
* @throws JSONException
675
public JSONObject put(String key, Vector value) throws JSONException {
676
put(key, new JSONArray(value));
683
//# * Get an optional double associated with a key,
684
//# * or NaN if there is no such key or if its value is not a number.
685
//# * If the value is a string, an attempt will be made to evaluate it as
688
//# * @param key A string which is the key.
689
//# * @return An object which is the value.
691
//# public double optDouble(String key) {
692
//# return optDouble(key, Double.NaN);
698
//# * Get an optional double associated with a key, or the
699
//# * defaultValue if there is no such key or if its value is not a number.
700
//# * If the value is a string, an attempt will be made to evaluate it as
703
//# * @param key A key string.
704
//# * @param defaultValue The default.
705
//# * @return An object which is the value.
707
//# public double optDouble(String key, double defaultValue) {
709
//# Object o = opt(key);
710
//# return Double.parseDouble((String)o);
711
//# } catch (Exception e) {
712
//# return defaultValue;
718
* Get an optional int value associated with a key,
719
* or zero if there is no such key or if the value is not a number.
720
* If the value is a string, an attempt will be made to evaluate it as
723
* @param key A key string.
724
* @return An object which is the value.
726
public int optInt(String key) {
727
return optInt(key, 0);
732
* Get an optional int value associated with a key,
733
* or the default if there is no such key or if the value is not a number.
734
* If the value is a string, an attempt will be made to evaluate it as
737
* @param key A key string.
738
* @param defaultValue The default.
739
* @return An object which is the value.
741
public int optInt(String key, int defaultValue) {
744
} catch (Exception e) {
751
* Get an optional JSONArray associated with a key.
752
* It returns null if there is no such key, or if its value is not a
755
* @param key A key string.
756
* @return A JSONArray which is the value.
758
public JSONArray optJSONArray(String key) {
760
return o instanceof JSONArray ? (JSONArray)o : null;
765
* Get an optional JSONObject associated with a key.
766
* It returns null if there is no such key, or if its value is not a
769
* @param key A key string.
770
* @return A JSONObject which is the value.
772
public JSONObject optJSONObject(String key) {
774
return o instanceof JSONObject ? (JSONObject)o : null;
779
* Get an optional long value associated with a key,
780
* or zero if there is no such key or if the value is not a number.
781
* If the value is a string, an attempt will be made to evaluate it as
784
* @param key A key string.
785
* @return An object which is the value.
787
public long optLong(String key) {
788
return optLong(key, 0);
793
* Get an optional long value associated with a key,
794
* or the default if there is no such key or if the value is not a number.
795
* If the value is a string, an attempt will be made to evaluate it as
798
* @param key A key string.
799
* @param defaultValue The default.
800
* @return An object which is the value.
802
public long optLong(String key, long defaultValue) {
805
} catch (Exception e) {
812
* Get an optional string associated with a key.
813
* It returns an empty string if there is no such key. If the value is not
814
* a string and is not null, then it is coverted to a string.
816
* @param key A key string.
817
* @return A string which is the value.
819
public String optString(String key) {
820
return optString(key, "");
825
* Get an optional string associated with a key.
826
* It returns the defaultValue if there is no such key.
828
* @param key A key string.
829
* @param defaultValue The default.
830
* @return A string which is the value.
832
public String optString(String key, String defaultValue) {
834
return o != null ? o.toString() : defaultValue;
839
* Put a key/boolean pair in the JSONObject.
841
* @param key A key string.
842
* @param value A boolean which is the value.
844
* @throws JSONException If the key is null.
846
public JSONObject put(String key, boolean value) throws JSONException {
848
//# put(key, value ? Boolean.TRUE : Boolean.FALSE);
850
put(key, value ? TRUE : FALSE);
858
//# * Put a key/double pair in the JSONObject.
860
//# * @param key A key string.
861
//# * @param value A double which is the value.
863
//# * @throws JSONException If the key is null or if the number is invalid.
865
//# public JSONObject put(String key, double value) throws JSONException {
866
//# put(key, new Double(value));
872
* Put a key/int pair in the JSONObject.
874
* @param key A key string.
875
* @param value An int which is the value.
877
* @throws JSONException If the key is null.
879
public JSONObject put(String key, int value) throws JSONException {
880
put(key, new Integer(value));
886
* Put a key/long pair in the JSONObject.
888
* @param key A key string.
889
* @param value A long which is the value.
891
* @throws JSONException If the key is null.
893
public JSONObject put(String key, long value) throws JSONException {
894
put(key, new Long(value));
901
//# * Put a key/value pair in the JSONObject, where the value will be a
902
//# * JSONObject which is produced from a Map.
903
//# * @param key A key string.
904
//# * @param value A Map value.
906
//# * @throws JSONException
908
//# public JSONObject put(String key, Hashtable value) throws JSONException {
909
//# put(key, new JSONObject(value));
915
* Put a key/value pair in the JSONObject. If the value is null,
916
* then the key will be removed from the JSONObject if it is present.
917
* @param key A key string.
918
* @param value An object which is the value. It should be of one of these
919
* types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String,
920
* or the JSONObject.NULL object.
922
* @throws JSONException If the value is non-finite number
923
* or if the key is null.
925
public JSONObject put(String key, Object value) throws JSONException {
927
throw new JSONException("Null key.");
931
this.myHashMap.put(key, value);
939
* Put a key/value pair in the JSONObject, but only if the
940
* key and the value are both non-null.
941
* @param key A key string.
942
* @param value An object which is the value. It should be of one of these
943
* types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String,
944
* or the JSONObject.NULL object.
946
* @throws JSONException If the value is a non-finite number.
948
public JSONObject putOpt(String key, Object value) throws JSONException {
949
if (key != null && value != null) {
956
* Produce a string in double quotes with backslash sequences in all the
957
* right places. A backslash will be inserted within </, allowing JSON
958
* text to be delivered in HTML. In JSON text, a string cannot contain a
959
* control character or an unescaped quote or backslash.
960
* @param string A String
961
* @return A String correctly formatted for insertion in a JSON text.
963
public static String quote(String string) {
964
if (string == null || string.length() == 0) {
971
int len = string.length();
972
StringBuffer sb = new StringBuffer(len + 4);
976
for (i = 0; i < len; i += 1) {
978
c = string.charAt(i);
1008
t = "000" + Integer.toHexString(c);
1009
sb.append("\\u" + t.substring(t.length() - 4));
1016
return sb.toString();
1020
* Remove a name and its value, if present.
1021
* @param key The name to be removed.
1022
* @return The value that was associated with the name,
1023
* or null if there was no value.
1025
public Object remove(String key) {
1026
return this.myHashMap.remove(key);
1030
* Throw an exception if the object is an NaN or infinite number.
1031
* @param o The object to test.
1032
* @throws JSONException If o is a non-finite number.
1034
static void testValidity(Object o) throws JSONException {
1037
//# if (o instanceof Double) {
1038
//# if (((Double)o).isInfinite() || ((Double)o).isNaN()) {
1039
//# throw new JSONException(
1040
//# "JSON does not allow non-finite numbers");
1042
//# } else if (o instanceof Float) {
1043
//# if (((Float)o).isInfinite() || ((Float)o).isNaN()) {
1044
//# throw new JSONException(
1045
//# "JSON does not allow non-finite numbers.");
1053
* Produce a JSONArray containing the values of the members of this
1055
* @param names A JSONArray containing a list of key strings. This
1056
* determines the sequence of the values in the result.
1057
* @return A JSONArray of values.
1058
* @throws JSONException If any of the values are non-finite numbers.
1060
public JSONArray toJSONArray(JSONArray names) throws JSONException {
1061
if (names == null || names.length() == 0) {
1064
JSONArray ja = new JSONArray();
1065
for (int i = 0; i < names.length(); i += 1) {
1066
ja.put(this.opt(names.getString(i)));
1072
* Make a JSON text of this JSONObject. For compactness, no whitespace
1073
* is added. If this would not result in a syntactically correct JSON text,
1074
* then null will be returned instead.
1076
* Warning: This method assumes that the data structure is acyclical.
1078
* @return a printable, displayable, portable, transmittable
1079
* representation of the object, beginning
1080
* with <code>{</code> <small>(left brace)</small> and ending
1081
* with <code>}</code> <small>(right brace)</small>.
1083
public String toString() {
1085
Enumeration keys = keys();
1086
StringBuffer sb = new StringBuffer("{");
1088
while (keys.hasMoreElements()) {
1089
if (sb.length() > 1) {
1092
Object o = keys.nextElement();
1093
sb.append(quote(o.toString()));
1095
sb.append(valueToString(this.myHashMap.get(o)));
1098
return sb.toString();
1099
} catch (Exception e) {
1106
* Make a prettyprinted JSON text of this JSONObject.
1108
* Warning: This method assumes that the data structure is acyclical.
1109
* @param indentFactor The number of spaces to add to each level of
1111
* @return a printable, displayable, portable, transmittable
1112
* representation of the object, beginning
1113
* with <code>{</code> <small>(left brace)</small> and ending
1114
* with <code>}</code> <small>(right brace)</small>.
1115
* @throws JSONException If the object contains an invalid number.
1117
public String toString(int indentFactor) throws JSONException {
1118
return toString(indentFactor, 0);
1123
* Make a prettyprinted JSON text of this JSONObject.
1125
* Warning: This method assumes that the data structure is acyclical.
1126
* @param indentFactor The number of spaces to add to each level of
1128
* @param indent The indentation of the top level.
1129
* @return a printable, displayable, transmittable
1130
* representation of the object, beginning
1131
* with <code>{</code> <small>(left brace)</small> and ending
1132
* with <code>}</code> <small>(right brace)</small>.
1133
* @throws JSONException If the object contains an invalid number.
1135
String toString(int indentFactor, int indent) throws JSONException {
1141
Enumeration keys = keys();
1142
StringBuffer sb = new StringBuffer("{");
1143
int newindent = indent + indentFactor;
1146
o = keys.nextElement();
1147
sb.append(quote(o.toString()));
1149
sb.append(valueToString(this.myHashMap.get(o), indentFactor,
1152
while (keys.hasMoreElements()) {
1153
o = keys.nextElement();
1154
if (sb.length() > 1) {
1159
for (i = 0; i < newindent; i += 1) {
1162
sb.append(quote(o.toString()));
1164
sb.append(valueToString(this.myHashMap.get(o), indentFactor,
1167
if (sb.length() > 1) {
1169
for (i = 0; i < indent; i += 1) {
1175
return sb.toString();
1180
* Make a JSON text of an Object value. If the object has an
1181
* value.toJSONString() method, then that method will be used to produce
1182
* the JSON text. The method is required to produce a strictly
1183
* conforming text. If the object does not contain a toJSONString
1184
* method (which is the most common case), then a text will be
1185
* produced by the rules.
1187
* Warning: This method assumes that the data structure is acyclical.
1188
* @param value The value to be serialized.
1189
* @return a printable, displayable, transmittable
1190
* representation of the object, beginning
1191
* with <code>{</code> <small>(left brace)</small> and ending
1192
* with <code>}</code> <small>(right brace)</small>.
1193
* @throws JSONException If the value is or contains an invalid number.
1195
static String valueToString(Object value) throws JSONException {
1196
if (value == null || value.equals(null)) {
1199
if (value instanceof JSONString) {
1202
o = ((JSONString)value).toJSONString();
1203
} catch (Exception e) {
1204
throw new JSONException(e);
1206
if (o instanceof String) {
1209
throw new JSONException("Bad value from toJSONString: " + o);
1212
//# if (value instanceof Float || value instanceof Double ||
1216
value instanceof Byte || value instanceof Short ||
1217
value instanceof Integer || value instanceof Long) {
1218
return numberToString(value);
1220
if (value instanceof Boolean || value instanceof JSONObject ||
1221
value instanceof JSONArray) {
1222
return value.toString();
1224
return quote(value.toString());
1229
* Make a prettyprinted JSON text of an object value.
1231
* Warning: This method assumes that the data structure is acyclical.
1232
* @param value The value to be serialized.
1233
* @param indentFactor The number of spaces to add to each level of
1235
* @param indent The indentation of the top level.
1236
* @return a printable, displayable, transmittable
1237
* representation of the object, beginning
1238
* with <code>{</code> <small>(left brace)</small> and ending
1239
* with <code>}</code> <small>(right brace)</small>.
1240
* @throws JSONException If the object contains an invalid number.
1242
static String valueToString(Object value, int indentFactor, int indent)
1243
throws JSONException {
1244
if (value == null || value.equals(null)) {
1248
if (value instanceof JSONString) {
1249
Object o = ((JSONString)value).toJSONString();
1250
if (o instanceof String) {
1254
} catch (Exception e) {
1255
/* forget about it */
1258
//# if (value instanceof Float || value instanceof Double ||
1262
value instanceof Byte || value instanceof Short ||
1263
value instanceof Integer || value instanceof Long) {
1264
return numberToString(value);
1266
if (value instanceof Boolean) {
1267
return value.toString();
1269
if (value instanceof JSONObject) {
1270
return ((JSONObject)value).toString(indentFactor, indent);
1272
if (value instanceof JSONArray) {
1273
return ((JSONArray)value).toString(indentFactor, indent);
1275
return quote(value.toString());
1280
* Write the contents of the JSONObject as JSON text to a writer.
1281
* For compactness, no whitespace is added.
1283
* Warning: This method assumes that the data structure is acyclical.
1285
* @return The writer.
1286
* @throws JSONException
1288
public Writer write(Writer writer) throws JSONException {
1291
Enumeration keys = keys();
1294
while (keys.hasMoreElements()) {
1298
Object k = keys.nextElement();
1299
writer.write(quote(k.toString()));
1301
Object v = this.myHashMap.get(k);
1302
if (v instanceof JSONObject) {
1303
((JSONObject)v).write(writer);
1304
} else if (v instanceof JSONArray) {
1305
((JSONArray)v).write(writer);
1307
writer.write(valueToString(v));
1313
} catch (IOException e) {
1314
throw new JSONException(e);
b'\\ No newline at end of file'
4
Copyright (c) 2002 JSON.org
6
Permission is hereby granted, free of charge, to any person obtaining a copy
7
of this software and associated documentation files (the "Software"), to deal
8
in the Software without restriction, including without limitation the rights
9
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
copies of the Software, and to permit persons to whom the Software is
11
furnished to do so, subject to the following conditions:
13
The above copyright notice and this permission notice shall be included in all
14
copies or substantial portions of the Software.
16
The Software shall be used for Good, not Evil.
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
import java.io.IOException;
28
import java.io.Writer;
29
import java.util.Enumeration;
30
import java.util.Hashtable;
31
import java.util.Vector;
34
* A JSONObject is an unordered collection of name/value pairs. Its
35
* external form is a string wrapped in curly braces with colons between the
36
* names and values, and commas between the values and names. The internal form
37
* is an object having <code>get</code> and <code>opt</code> methods for
38
* accessing the values by name, and <code>put</code> methods for adding or
39
* replacing values by name. The values can be any of these types:
40
* <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
41
* <code>Number</code>, <code>String</code>, or the <code>JSONObject.NULL</code>
42
* object. A JSONObject constructor can be used to convert an external form
43
* JSON text into an internal form whose values can be retrieved with the
44
* <code>get</code> and <code>opt</code> methods, or to convert values into a
45
* JSON text using the <code>put</code> and <code>toString</code> methods.
46
* A <code>get</code> method returns a value if one can be found, and throws an
47
* exception if one cannot be found. An <code>opt</code> method returns a
48
* default value instead of throwing an exception, and so is useful for
49
* obtaining optional values.
51
* The generic <code>get()</code> and <code>opt()</code> methods return an
52
* object, which you can cast or query for type. There are also typed
53
* <code>get</code> and <code>opt</code> methods that do type checking and type
56
* The <code>put</code> methods adds values to an object. For example, <pre>
57
* myString = new JSONObject().put("JSON", "Hello, World!").toString();</pre>
58
* produces the string <code>{"JSON": "Hello, World"}</code>.
60
* The texts produced by the <code>toString</code> methods strictly conform to
61
* the JSON sysntax rules.
62
* The constructors are more forgiving in the texts they will accept:
64
* <li>An extra <code>,</code> <small>(comma)</small> may appear just
65
* before the closing brace.</li>
66
* <li>Strings may be quoted with <code>'</code> <small>(single
67
* quote)</small>.</li>
68
* <li>Strings do not need to be quoted at all if they do not begin with a quote
69
* or single quote, and if they do not contain leading or trailing spaces,
70
* and if they do not contain any of these characters:
71
* <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers
72
* and if they are not the reserved words <code>true</code>,
73
* <code>false</code>, or <code>null</code>.</li>
74
* <li>Keys can be followed by <code>=</code> or <code>=></code> as well as
75
* by <code>:</code>.</li>
76
* <li>Values can be followed by <code>;</code> <small>(semicolon)</small> as
77
* well as by <code>,</code> <small>(comma)</small>.</li>
78
* <li>Numbers may have the <code>0-</code> <small>(octal)</small> or
79
* <code>0x-</code> <small>(hex)</small> prefix.</li>
80
* <li>Comments written in the slashshlash, slashstar, and hash conventions
81
* will be ignored.</li>
86
public class JSONObject {
89
//@ public static final Boolean TRUE = new Boolean(true);
90
//@ public static final Boolean FALSE = new Boolean(false);
94
* JSONObject.NULL is equivalent to the value that JavaScript calls null,
95
* whilst Java's null is equivalent to the value that JavaScript calls
98
private static final class Null {
101
* There is only intended to be a single instance of the NULL object,
102
* so the clone method returns itself.
105
protected final Object clone() {
111
* A Null object is equal to the null value and to itself.
112
* @param object An object to test for nullness.
113
* @return true if the object parameter is the JSONObject.NULL object
116
public boolean equals(Object object) {
117
return object == null || object == this;
122
* Get the "null" string value.
123
* @return The string "null".
125
public String toString() {
132
* The hash map where the JSONObject's properties are kept.
134
private Hashtable myHashMap;
138
* It is sometimes more convenient and less ambiguous to have a
139
* <code>NULL</code> object than to use Java's <code>null</code> value.
140
* <code>JSONObject.NULL.equals(null)</code> returns <code>true</code>.
141
* <code>JSONObject.NULL.toString()</code> returns <code>"null"</code>.
143
public static final Object NULL = new Null();
146
* Construct an empty JSONObject.
148
public JSONObject() {
149
this.myHashMap = new Hashtable();
155
//@ * Construct a JSONObject from a subset of another JSONObject.
156
//@ * An array of strings is used to identify the keys that should be copied.
157
//@ * Missing keys are ignored.
158
//@ * @param jo A JSONObject.
159
//@ * @param sa An array of strings.
160
//@ * @exception JSONException If a value is a non-finite number.
162
//@ public JSONObject(JSONObject jo, String[] sa) throws JSONException {
164
//@ for (int i = 0; i < sa.length; i += 1) {
165
//@ putOpt(sa[i], jo.opt(sa[i]));
171
* Construct a JSONObject from a JSONTokener.
172
* @param x A JSONTokener object containing the source string.
173
* @throws JSONException If there is a syntax error in the source string.
175
public JSONObject(JSONTokener x) throws JSONException {
180
if (x.nextClean() != '{') {
181
throw x.syntaxError("A JSONObject text must begin with '{'");
187
throw x.syntaxError("A JSONObject text must end with '}'");
192
key = x.nextValue().toString();
196
* The key is followed by ':'. We will also tolerate '=' or '=>'.
201
if (x.next() != '>') {
204
} else if (c != ':') {
205
throw x.syntaxError("Expected a ':' after a key");
207
put(key, x.nextValue());
210
* Pairs are separated by ','. We will also tolerate ';'.
213
switch (x.nextClean()) {
216
if (x.nextClean() == '}') {
224
throw x.syntaxError("Expected a ',' or '}'");
232
//@ * Construct a JSONObject from a Map.
233
//@ * @param map A map object that can be used to initialize the contents of
234
//@ * the JSONObject.
236
//@ public JSONObject(Hashtable map) {
237
//@ if (map == null) {
238
//@ this.myHashMap = new Hashtable();
240
//@ this.myHashMap = new Hashtable(map.size());
241
//@ Enumeration keys = map.keys();
242
//@ while (keys.hasMoreElements()) {
243
//@ Object key = keys.nextElement();
244
//@ this.myHashMap.put(key, map.get(key));
251
* Construct a JSONObject from a string.
252
* This is the most commonly used JSONObject constructor.
253
* @param string A string beginning
254
* with <code>{</code> <small>(left brace)</small> and ending
255
* with <code>}</code> <small>(right brace)</small>.
256
* @exception JSONException If there is a syntax error in the source string.
258
public JSONObject(String string) throws JSONException {
259
this(new JSONTokener(string));
264
* Accumulate values under a key. It is similar to the put method except
265
* that if there is already an object stored under the key then a
266
* JSONArray is stored under the key to hold all of the accumulated values.
267
* If there is already a JSONArray, then the new value is appended to it.
268
* In contrast, the put method replaces the previous value.
269
* @param key A key string.
270
* @param value An object to be accumulated under the key.
272
* @throws JSONException If the value is an invalid number
273
* or if the key is null.
275
public JSONObject accumulate(String key, Object value)
276
throws JSONException {
281
} else if (o instanceof JSONArray) {
282
((JSONArray)o).put(value);
284
put(key, new JSONArray().put(o).put(value));
291
//@ * Append values to the array under a key. If the key does not exist in the
292
//@ * JSONObject, then the key is put in the JSONObject with its value being a
293
//@ * JSONArray containing the value parameter. If the key was already
294
//@ * associated with a JSONArray, then the value parameter is appended to it.
295
//@ * @param key A key string.
296
//@ * @param value An object to be accumulated under the key.
298
//@ * @throws JSONException If the key is null or if the current value
299
//@ * associated with the key is not a JSONArray.
301
//@ public JSONObject append(String key, Object value)
302
//@ throws JSONException {
303
//@ testValidity(value);
304
//@ Object o = opt(key);
306
//@ put(key, new JSONArray().put(value));
307
//@ } else if (o instanceof JSONArray) {
308
//@ throw new JSONException("JSONObject[" + key +
309
//@ "] is not a JSONArray.");
311
//@ put(key, new JSONArray().put(o).put(value));
319
* Produce a string from a double. The string "null" will be returned if
320
* the number is not finite.
324
static public String doubleToString(double d) {
325
if (Double.isInfinite(d) || Double.isNaN(d)) {
329
// Shave off trailing zeros and decimal point, if possible.
331
String s = Double.toString(d);
332
if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) {
333
while (s.endsWith("0")) {
334
s = s.substring(0, s.length() - 1);
336
if (s.endsWith(".")) {
337
s = s.substring(0, s.length() - 1);
345
* Get the value object associated with a key.
347
* @param key A key string.
348
* @return The object associated with the key.
349
* @throws JSONException if the key is not found.
351
public Object get(String key) throws JSONException {
354
throw new JSONException("JSONObject[" + quote(key) +
362
* Get the boolean value associated with a key.
364
* @param key A key string.
366
* @throws JSONException
367
* if the value is not a Boolean or the String "true" or "false".
369
public boolean getBoolean(String key) throws JSONException {
372
if (o.equals(Boolean.FALSE) ||
374
//@ if (o.equals(FALSE) ||
376
(o instanceof String &&
377
((String)o).toLowerCase().equals("false"))) {
380
} else if (o.equals(Boolean.TRUE) ||
382
//@ } else if (o.equals(TRUE) ||
384
(o instanceof String &&
385
((String)o).toLowerCase().equals("true"))) {
388
throw new JSONException("JSONObject[" + quote(key) +
389
"] is not a Boolean.");
394
* Get the double value associated with a key.
395
* @param key A key string.
396
* @return The numeric value.
397
* @throws JSONException if the key is not found or
398
* if the value is not a Number object and cannot be converted to a number.
400
public double getDouble(String key) throws JSONException {
402
if (o instanceof Byte) {
403
return (double) ((Byte)o).byteValue();
404
} else if (o instanceof Short) {
405
return (double) ((Short)o).shortValue();
406
} else if (o instanceof Integer) {
407
return (double) ((Integer)o).intValue();
408
} else if (o instanceof Long) {
409
return (double) ((Long)o).longValue();
410
} else if (o instanceof Float) {
411
return (double) ((Float)o).floatValue();
412
} else if (o instanceof Double) {
413
return ((Double)o).doubleValue();
414
} else if (o instanceof String) {
416
return Double.valueOf((String)o).doubleValue();
417
} catch (Exception e) {
418
throw new JSONException("JSONObject[" + quote(key) +
419
"] is not a number.");
422
throw new JSONException("JSONObject[" + quote(key) +
423
"] is not a number.");
429
* Get the int value associated with a key. If the number value is too
430
* large for an int, it will be clipped.
432
* @param key A key string.
433
* @return The integer value.
434
* @throws JSONException if the key is not found or if the value cannot
435
* be converted to an integer.
437
public int getInt(String key) throws JSONException {
439
if (o instanceof Byte) {
440
return ((Byte)o).byteValue();
441
} else if (o instanceof Short) {
442
return ((Short)o).shortValue();
443
} else if (o instanceof Integer) {
444
return ((Integer)o).intValue();
445
} else if (o instanceof Long) {
446
return (int) ((Long)o).longValue();
448
} else if (o instanceof Float) {
449
return (int) ((Float)o).floatValue();
450
} else if (o instanceof Double) {
451
return (int) ((Double)o).doubleValue();
452
} else if (o instanceof String) {
453
return (int) getDouble(key);
456
throw new JSONException("JSONObject[" + quote(key) +
457
"] is not a number.");
462
* Get the JSONArray value associated with a key.
464
* @param key A key string.
465
* @return A JSONArray which is the value.
466
* @throws JSONException if the key is not found or
467
* if the value is not a JSONArray.
469
public JSONArray getJSONArray(String key) throws JSONException {
471
if (o instanceof JSONArray) {
474
throw new JSONException("JSONObject[" + quote(key) +
475
"] is not a JSONArray.");
479
* Get the JSONObject value associated with a key.
481
* @param key A key string.
482
* @return A JSONObject which is the value.
483
* @throws JSONException if the key is not found or
484
* if the value is not a JSONObject.
486
public JSONObject getJSONObject(String key) throws JSONException {
488
if (o instanceof JSONObject) {
489
return (JSONObject)o;
491
throw new JSONException("JSONObject[" + quote(key) +
492
"] is not a JSONObject.");
496
* Get the long value associated with a key. If the number value is too
497
* long for a long, it will be clipped.
499
* @param key A key string.
500
* @return The long value.
501
* @throws JSONException if the key is not found or if the value cannot
502
* be converted to a long.
504
public long getLong(String key) throws JSONException {
506
if (o instanceof Byte) {
507
return ((Byte)o).byteValue();
508
} else if (o instanceof Short) {
509
return ((Short)o).shortValue();
510
} else if (o instanceof Integer) {
511
return ((Integer)o).intValue();
512
} else if (o instanceof Long) {
513
return ((Long)o).longValue();
515
} else if (o instanceof Float) {
516
return (long) ((Float)o).floatValue();
517
} else if (o instanceof Double) {
518
return (long) ((Double)o).doubleValue();
519
} else if (o instanceof String) {
520
return (long) getDouble(key);
523
throw new JSONException("JSONObject[" + quote(key) +
524
"] is not a number.");
528
* Get the string associated with a key.
530
* @param key A key string.
531
* @return A string which is the value.
532
* @throws JSONException if the key is not found.
534
public String getString(String key) throws JSONException {
535
return get(key).toString();
539
* Determine if the JSONObject contains a specific key.
540
* @param key A key string.
541
* @return true if the key exists in the JSONObject.
543
public boolean has(String key) {
544
return this.myHashMap.containsKey(key);
549
* Determine if the value associated with the key is null or if there is
551
* @param key A key string.
552
* @return true if there is no value associated with the key or if
553
* the value is the JSONObject.NULL object.
555
public boolean isNull(String key) {
556
return JSONObject.NULL.equals(opt(key));
561
* Get an enumeration of the keys of the JSONObject.
563
* @return An iterator of the keys.
565
public Enumeration keys() {
566
return this.myHashMap.keys();
571
* Get the number of keys stored in the JSONObject.
573
* @return The number of keys in the JSONObject.
575
public int length() {
576
return this.myHashMap.size();
581
* Produce a JSONArray containing the names of the elements of this
583
* @return A JSONArray containing the key strings, or null if the JSONObject
586
public JSONArray names() {
587
JSONArray ja = new JSONArray();
588
Enumeration keys = keys();
589
while (keys.hasMoreElements()) {
590
ja.put(keys.nextElement());
592
return ja.length() == 0 ? null : ja;
597
* Shave off trailing zeros and decimal point, if possible.
599
static public String trimNumber(String s) {
600
if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) {
601
while (s.endsWith("0")) {
602
s = s.substring(0, s.length() - 1);
604
if (s.endsWith(".")) {
605
s = s.substring(0, s.length() - 1);
612
* Produce a string from a Number.
615
* @throws JSONException If n is a non-finite number.
617
static public String numberToString(Object n)
618
throws JSONException {
620
throw new JSONException("Null pointer");
623
return trimNumber(n.toString());
627
* Get an optional value associated with a key.
628
* @param key A key string.
629
* @return An object which is the value, or null if there is no value.
631
public Object opt(String key) {
632
return key == null ? null : this.myHashMap.get(key);
637
* Get an optional boolean associated with a key.
638
* It returns false if there is no such key, or if the value is not
639
* Boolean.TRUE or the String "true".
641
* @param key A key string.
644
public boolean optBoolean(String key) {
645
return optBoolean(key, false);
650
* Get an optional boolean associated with a key.
651
* It returns the defaultValue if there is no such key, or if it is not
652
* a Boolean or the String "true" or "false" (case insensitive).
654
* @param key A key string.
655
* @param defaultValue The default.
658
public boolean optBoolean(String key, boolean defaultValue) {
660
return getBoolean(key);
661
} catch (Exception e) {
668
* Put a key/value pair in the JSONObject, where the value will be a
669
* JSONArray which is produced from a Collection.
670
* @param key A key string.
671
* @param value A Collection value.
673
* @throws JSONException
675
public JSONObject put(String key, Vector value) throws JSONException {
676
put(key, new JSONArray(value));
683
* Get an optional double associated with a key,
684
* or NaN if there is no such key or if its value is not a number.
685
* If the value is a string, an attempt will be made to evaluate it as
688
* @param key A string which is the key.
689
* @return An object which is the value.
691
public double optDouble(String key) {
692
return optDouble(key, Double.NaN);
698
* Get an optional double associated with a key, or the
699
* defaultValue if there is no such key or if its value is not a number.
700
* If the value is a string, an attempt will be made to evaluate it as
703
* @param key A key string.
704
* @param defaultValue The default.
705
* @return An object which is the value.
707
public double optDouble(String key, double defaultValue) {
710
return Double.parseDouble((String)o);
711
} catch (Exception e) {
718
* Get an optional int value associated with a key,
719
* or zero if there is no such key or if the value is not a number.
720
* If the value is a string, an attempt will be made to evaluate it as
723
* @param key A key string.
724
* @return An object which is the value.
726
public int optInt(String key) {
727
return optInt(key, 0);
732
* Get an optional int value associated with a key,
733
* or the default if there is no such key or if the value is not a number.
734
* If the value is a string, an attempt will be made to evaluate it as
737
* @param key A key string.
738
* @param defaultValue The default.
739
* @return An object which is the value.
741
public int optInt(String key, int defaultValue) {
744
} catch (Exception e) {
751
* Get an optional JSONArray associated with a key.
752
* It returns null if there is no such key, or if its value is not a
755
* @param key A key string.
756
* @return A JSONArray which is the value.
758
public JSONArray optJSONArray(String key) {
760
return o instanceof JSONArray ? (JSONArray)o : null;
765
* Get an optional JSONObject associated with a key.
766
* It returns null if there is no such key, or if its value is not a
769
* @param key A key string.
770
* @return A JSONObject which is the value.
772
public JSONObject optJSONObject(String key) {
774
return o instanceof JSONObject ? (JSONObject)o : null;
779
* Get an optional long value associated with a key,
780
* or zero if there is no such key or if the value is not a number.
781
* If the value is a string, an attempt will be made to evaluate it as
784
* @param key A key string.
785
* @return An object which is the value.
787
public long optLong(String key) {
788
return optLong(key, 0);
793
* Get an optional long value associated with a key,
794
* or the default if there is no such key or if the value is not a number.
795
* If the value is a string, an attempt will be made to evaluate it as
798
* @param key A key string.
799
* @param defaultValue The default.
800
* @return An object which is the value.
802
public long optLong(String key, long defaultValue) {
805
} catch (Exception e) {
812
* Get an optional string associated with a key.
813
* It returns an empty string if there is no such key. If the value is not
814
* a string and is not null, then it is coverted to a string.
816
* @param key A key string.
817
* @return A string which is the value.
819
public String optString(String key) {
820
return optString(key, "");
825
* Get an optional string associated with a key.
826
* It returns the defaultValue if there is no such key.
828
* @param key A key string.
829
* @param defaultValue The default.
830
* @return A string which is the value.
832
public String optString(String key, String defaultValue) {
834
return o != null ? o.toString() : defaultValue;
839
* Put a key/boolean pair in the JSONObject.
841
* @param key A key string.
842
* @param value A boolean which is the value.
844
* @throws JSONException If the key is null.
846
public JSONObject put(String key, boolean value) throws JSONException {
848
put(key, value ? Boolean.TRUE : Boolean.FALSE);
850
//@ put(key, value ? TRUE : FALSE);
858
* Put a key/double pair in the JSONObject.
860
* @param key A key string.
861
* @param value A double which is the value.
863
* @throws JSONException If the key is null or if the number is invalid.
865
public JSONObject put(String key, double value) throws JSONException {
866
put(key, new Double(value));
872
* Put a key/int pair in the JSONObject.
874
* @param key A key string.
875
* @param value An int which is the value.
877
* @throws JSONException If the key is null.
879
public JSONObject put(String key, int value) throws JSONException {
880
put(key, new Integer(value));
886
* Put a key/long pair in the JSONObject.
888
* @param key A key string.
889
* @param value A long which is the value.
891
* @throws JSONException If the key is null.
893
public JSONObject put(String key, long value) throws JSONException {
894
put(key, new Long(value));
901
//@ * Put a key/value pair in the JSONObject, where the value will be a
902
//@ * JSONObject which is produced from a Map.
903
//@ * @param key A key string.
904
//@ * @param value A Map value.
906
//@ * @throws JSONException
908
//@ public JSONObject put(String key, Hashtable value) throws JSONException {
909
//@ put(key, new JSONObject(value));
915
* Put a key/value pair in the JSONObject. If the value is null,
916
* then the key will be removed from the JSONObject if it is present.
917
* @param key A key string.
918
* @param value An object which is the value. It should be of one of these
919
* types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String,
920
* or the JSONObject.NULL object.
922
* @throws JSONException If the value is non-finite number
923
* or if the key is null.
925
public JSONObject put(String key, Object value) throws JSONException {
927
throw new JSONException("Null key.");
931
this.myHashMap.put(key, value);
939
* Put a key/value pair in the JSONObject, but only if the
940
* key and the value are both non-null.
941
* @param key A key string.
942
* @param value An object which is the value. It should be of one of these
943
* types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String,
944
* or the JSONObject.NULL object.
946
* @throws JSONException If the value is a non-finite number.
948
public JSONObject putOpt(String key, Object value) throws JSONException {
949
if (key != null && value != null) {
956
* Produce a string in double quotes with backslash sequences in all the
957
* right places. A backslash will be inserted within </, allowing JSON
958
* text to be delivered in HTML. In JSON text, a string cannot contain a
959
* control character or an unescaped quote or backslash.
960
* @param string A String
961
* @return A String correctly formatted for insertion in a JSON text.
963
public static String quote(String string) {
964
if (string == null || string.length() == 0) {
971
int len = string.length();
972
StringBuffer sb = new StringBuffer(len + 4);
976
for (i = 0; i < len; i += 1) {
978
c = string.charAt(i);
1008
t = "000" + Integer.toHexString(c);
1009
sb.append("\\u" + t.substring(t.length() - 4));
1016
return sb.toString();
1020
* Remove a name and its value, if present.
1021
* @param key The name to be removed.
1022
* @return The value that was associated with the name,
1023
* or null if there was no value.
1025
public Object remove(String key) {
1026
return this.myHashMap.remove(key);
1030
* Throw an exception if the object is an NaN or infinite number.
1031
* @param o The object to test.
1032
* @throws JSONException If o is a non-finite number.
1034
static void testValidity(Object o) throws JSONException {
1037
if (o instanceof Double) {
1038
if (((Double)o).isInfinite() || ((Double)o).isNaN()) {
1039
throw new JSONException(
1040
"JSON does not allow non-finite numbers");
1042
} else if (o instanceof Float) {
1043
if (((Float)o).isInfinite() || ((Float)o).isNaN()) {
1044
throw new JSONException(
1045
"JSON does not allow non-finite numbers.");
1053
* Produce a JSONArray containing the values of the members of this
1055
* @param names A JSONArray containing a list of key strings. This
1056
* determines the sequence of the values in the result.
1057
* @return A JSONArray of values.
1058
* @throws JSONException If any of the values are non-finite numbers.
1060
public JSONArray toJSONArray(JSONArray names) throws JSONException {
1061
if (names == null || names.length() == 0) {
1064
JSONArray ja = new JSONArray();
1065
for (int i = 0; i < names.length(); i += 1) {
1066
ja.put(this.opt(names.getString(i)));
1072
* Make a JSON text of this JSONObject. For compactness, no whitespace
1073
* is added. If this would not result in a syntactically correct JSON text,
1074
* then null will be returned instead.
1076
* Warning: This method assumes that the data structure is acyclical.
1078
* @return a printable, displayable, portable, transmittable
1079
* representation of the object, beginning
1080
* with <code>{</code> <small>(left brace)</small> and ending
1081
* with <code>}</code> <small>(right brace)</small>.
1083
public String toString() {
1085
Enumeration keys = keys();
1086
StringBuffer sb = new StringBuffer("{");
1088
while (keys.hasMoreElements()) {
1089
if (sb.length() > 1) {
1092
Object o = keys.nextElement();
1093
sb.append(quote(o.toString()));
1095
sb.append(valueToString(this.myHashMap.get(o)));
1098
return sb.toString();
1099
} catch (Exception e) {
1106
* Make a prettyprinted JSON text of this JSONObject.
1108
* Warning: This method assumes that the data structure is acyclical.
1109
* @param indentFactor The number of spaces to add to each level of
1111
* @return a printable, displayable, portable, transmittable
1112
* representation of the object, beginning
1113
* with <code>{</code> <small>(left brace)</small> and ending
1114
* with <code>}</code> <small>(right brace)</small>.
1115
* @throws JSONException If the object contains an invalid number.
1117
public String toString(int indentFactor) throws JSONException {
1118
return toString(indentFactor, 0);
1123
* Make a prettyprinted JSON text of this JSONObject.
1125
* Warning: This method assumes that the data structure is acyclical.
1126
* @param indentFactor The number of spaces to add to each level of
1128
* @param indent The indentation of the top level.
1129
* @return a printable, displayable, transmittable
1130
* representation of the object, beginning
1131
* with <code>{</code> <small>(left brace)</small> and ending
1132
* with <code>}</code> <small>(right brace)</small>.
1133
* @throws JSONException If the object contains an invalid number.
1135
String toString(int indentFactor, int indent) throws JSONException {
1141
Enumeration keys = keys();
1142
StringBuffer sb = new StringBuffer("{");
1143
int newindent = indent + indentFactor;
1146
o = keys.nextElement();
1147
sb.append(quote(o.toString()));
1149
sb.append(valueToString(this.myHashMap.get(o), indentFactor,
1152
while (keys.hasMoreElements()) {
1153
o = keys.nextElement();
1154
if (sb.length() > 1) {
1159
for (i = 0; i < newindent; i += 1) {
1162
sb.append(quote(o.toString()));
1164
sb.append(valueToString(this.myHashMap.get(o), indentFactor,
1167
if (sb.length() > 1) {
1169
for (i = 0; i < indent; i += 1) {
1175
return sb.toString();
1180
* Make a JSON text of an Object value. If the object has an
1181
* value.toJSONString() method, then that method will be used to produce
1182
* the JSON text. The method is required to produce a strictly
1183
* conforming text. If the object does not contain a toJSONString
1184
* method (which is the most common case), then a text will be
1185
* produced by the rules.
1187
* Warning: This method assumes that the data structure is acyclical.
1188
* @param value The value to be serialized.
1189
* @return a printable, displayable, transmittable
1190
* representation of the object, beginning
1191
* with <code>{</code> <small>(left brace)</small> and ending
1192
* with <code>}</code> <small>(right brace)</small>.
1193
* @throws JSONException If the value is or contains an invalid number.
1195
static String valueToString(Object value) throws JSONException {
1196
if (value == null || value.equals(null)) {
1199
if (value instanceof JSONString) {
1202
o = ((JSONString)value).toJSONString();
1203
} catch (Exception e) {
1204
throw new JSONException(e);
1206
if (o instanceof String) {
1209
throw new JSONException("Bad value from toJSONString: " + o);
1212
if (value instanceof Float || value instanceof Double ||
1216
value instanceof Byte || value instanceof Short ||
1217
value instanceof Integer || value instanceof Long) {
1218
return numberToString(value);
1220
if (value instanceof Boolean || value instanceof JSONObject ||
1221
value instanceof JSONArray) {
1222
return value.toString();
1224
return quote(value.toString());
1229
* Make a prettyprinted JSON text of an object value.
1231
* Warning: This method assumes that the data structure is acyclical.
1232
* @param value The value to be serialized.
1233
* @param indentFactor The number of spaces to add to each level of
1235
* @param indent The indentation of the top level.
1236
* @return a printable, displayable, transmittable
1237
* representation of the object, beginning
1238
* with <code>{</code> <small>(left brace)</small> and ending
1239
* with <code>}</code> <small>(right brace)</small>.
1240
* @throws JSONException If the object contains an invalid number.
1242
static String valueToString(Object value, int indentFactor, int indent)
1243
throws JSONException {
1244
if (value == null || value.equals(null)) {
1248
if (value instanceof JSONString) {
1249
Object o = ((JSONString)value).toJSONString();
1250
if (o instanceof String) {
1254
} catch (Exception e) {
1255
/* forget about it */
1258
if (value instanceof Float || value instanceof Double ||
1262
value instanceof Byte || value instanceof Short ||
1263
value instanceof Integer || value instanceof Long) {
1264
return numberToString(value);
1266
if (value instanceof Boolean) {
1267
return value.toString();
1269
if (value instanceof JSONObject) {
1270
return ((JSONObject)value).toString(indentFactor, indent);
1272
if (value instanceof JSONArray) {
1273
return ((JSONArray)value).toString(indentFactor, indent);
1275
return quote(value.toString());
1280
* Write the contents of the JSONObject as JSON text to a writer.
1281
* For compactness, no whitespace is added.
1283
* Warning: This method assumes that the data structure is acyclical.
1285
* @return The writer.
1286
* @throws JSONException
1288
public Writer write(Writer writer) throws JSONException {
1291
Enumeration keys = keys();
1294
while (keys.hasMoreElements()) {
1298
Object k = keys.nextElement();
1299
writer.write(quote(k.toString()));
1301
Object v = this.myHashMap.get(k);
1302
if (v instanceof JSONObject) {
1303
((JSONObject)v).write(writer);
1304
} else if (v instanceof JSONArray) {
1305
((JSONArray)v).write(writer);
1307
writer.write(valueToString(v));
1313
} catch (IOException e) {
1314
throw new JSONException(e);