22 | 22 |
// Note: this class was written without inspecting the non-free org.json sourcecode.
|
23 | 23 |
|
24 | 24 |
/**
|
25 | |
* An indexed sequence of JSON-safe values.
|
|
25 |
* A dense indexed sequence of values. Values may be any mix of
|
|
26 |
* {@link JSONObject JSONObjects}, other {@link JSONArray JSONArrays}, Strings,
|
|
27 |
* Booleans, Integers, Longs, Doubles, {@code null} or {@link JSONObject#NULL}.
|
|
28 |
* Values may not be {@link Double#isNaN() NaNs}, {@link Double#isInfinite()
|
|
29 |
* infinities}, or of any type not listed here.
|
|
30 |
*
|
|
31 |
* <p>{@code JSONArray} has the same type coercion behavior and
|
|
32 |
* optional/mandatory accessors as {@link JSONObject}. See that class'
|
|
33 |
* documentation for details.
|
|
34 |
*
|
|
35 |
* <p><strong>Warning:</strong> this class represents null in two incompatible
|
|
36 |
* ways: the standard Java {@code null} reference, and the sentinel value {@link
|
|
37 |
* JSONObject#NULL}. In particular, {@code get()} fails if the requested index
|
|
38 |
* holds the null reference, but succeeds if it holds {@code JSONObject.NULL}.
|
|
39 |
*
|
|
40 |
* <p>Instances of this class are not thread safe. Although this class is
|
|
41 |
* nonfinal, it was not designed for inheritance and should not be subclassed.
|
|
42 |
* In particular, self-use by overridable methods is not specified. See
|
|
43 |
* <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
|
|
44 |
* prohibit it" for further information.
|
26 | 45 |
*/
|
27 | 46 |
public class JSONArray {
|
28 | 47 |
|
29 | 48 |
private final List<Object> values;
|
30 | 49 |
|
|
50 |
/**
|
|
51 |
* Creates a {@code JSONArray} with no values.
|
|
52 |
*/
|
31 | 53 |
public JSONArray() {
|
32 | 54 |
values = new ArrayList<Object>();
|
33 | 55 |
}
|
34 | 56 |
|
|
57 |
/**
|
|
58 |
* Creates a new {@code JSONArray} by copying all values from the given
|
|
59 |
* collection.
|
|
60 |
*
|
|
61 |
* @param copyFrom a collection whose values are of supported types.
|
|
62 |
* Unsupported values are not permitted and will yield an array in an
|
|
63 |
* inconsistent state.
|
|
64 |
*/
|
35 | 65 |
/* Accept a raw type for API compatibility */
|
36 | 66 |
public JSONArray(Collection copyFrom) {
|
37 | 67 |
this();
|
|
39 | 69 |
values.addAll(copyFromTyped);
|
40 | 70 |
}
|
41 | 71 |
|
|
72 |
/**
|
|
73 |
* Creates a new {@code JSONArray} with values from the next array in the
|
|
74 |
* tokener.
|
|
75 |
*
|
|
76 |
* @param readFrom a tokener whose nextValue() method will yield a
|
|
77 |
* {@code JSONArray}.
|
|
78 |
* @throws JSONException if the parse fails or doesn't yield a
|
|
79 |
* {@code JSONArray}.
|
|
80 |
*/
|
42 | 81 |
public JSONArray(JSONTokener readFrom) throws JSONException {
|
43 | 82 |
/*
|
44 | 83 |
* Getting the parser to populate this could get tricky. Instead, just
|
|
52 | 91 |
}
|
53 | 92 |
}
|
54 | 93 |
|
|
94 |
/**
|
|
95 |
* Creates a new {@code JSONArray} with values from the JSON string.
|
|
96 |
*
|
|
97 |
* @param json a JSON-encoded string containing an array.
|
|
98 |
* @throws JSONException if the parse fails or doesn't yield a {@code
|
|
99 |
* JSONArray}.
|
|
100 |
*/
|
55 | 101 |
public JSONArray(String json) throws JSONException {
|
56 | 102 |
this(new JSONTokener(json));
|
57 | 103 |
}
|
58 | 104 |
|
|
105 |
/**
|
|
106 |
* Returns the number of values in this array.
|
|
107 |
*/
|
59 | 108 |
public int length() {
|
60 | 109 |
return values.size();
|
61 | 110 |
}
|
62 | 111 |
|
|
112 |
/**
|
|
113 |
* Appends {@code value} to the end of this array.
|
|
114 |
*
|
|
115 |
* @return this array.
|
|
116 |
*/
|
63 | 117 |
public JSONArray put(boolean value) {
|
64 | 118 |
values.add(value);
|
65 | 119 |
return this;
|
66 | 120 |
}
|
67 | 121 |
|
|
122 |
/**
|
|
123 |
* Appends {@code value} to the end of this array.
|
|
124 |
*
|
|
125 |
* @param value a finite value. May not be {@link Double#isNaN() NaNs} or
|
|
126 |
* {@link Double#isInfinite() infinities}.
|
|
127 |
* @return this array.
|
|
128 |
*/
|
68 | 129 |
public JSONArray put(double value) throws JSONException {
|
69 | 130 |
values.add(JSON.checkDouble(value));
|
70 | 131 |
return this;
|
71 | 132 |
}
|
72 | 133 |
|
|
134 |
/**
|
|
135 |
* Appends {@code value} to the end of this array.
|
|
136 |
*
|
|
137 |
* @return this array.
|
|
138 |
*/
|
73 | 139 |
public JSONArray put(int value) {
|
74 | 140 |
values.add(value);
|
75 | 141 |
return this;
|
76 | 142 |
}
|
77 | 143 |
|
|
144 |
/**
|
|
145 |
* Appends {@code value} to the end of this array.
|
|
146 |
*
|
|
147 |
* @return this array.
|
|
148 |
*/
|
78 | 149 |
public JSONArray put(long value) {
|
79 | 150 |
values.add(value);
|
80 | 151 |
return this;
|
81 | 152 |
}
|
82 | 153 |
|
|
154 |
/**
|
|
155 |
* Appends {@code value} to the end of this array.
|
|
156 |
*
|
|
157 |
* @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
|
|
158 |
* Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
|
|
159 |
* not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
|
|
160 |
* infinities}. Unsupported values are not permitted and will cause the
|
|
161 |
* array to be in an inconsistent state.
|
|
162 |
* @return this array.
|
|
163 |
*/
|
83 | 164 |
public JSONArray put(Object value) {
|
84 | 165 |
values.add(value);
|
85 | 166 |
return this;
|
86 | 167 |
}
|
87 | 168 |
|
|
169 |
/**
|
|
170 |
* Sets the value at {@code index} to {@code value}, null padding this array
|
|
171 |
* to the required length if necessary. If a value already exists at {@code
|
|
172 |
* index}, it will be replaced.
|
|
173 |
*
|
|
174 |
* @return this array.
|
|
175 |
*/
|
88 | 176 |
public JSONArray put(int index, boolean value) throws JSONException {
|
89 | 177 |
return put(index, (Boolean) value);
|
90 | 178 |
}
|
91 | 179 |
|
|
180 |
/**
|
|
181 |
* Sets the value at {@code index} to {@code value}, null padding this array
|
|
182 |
* to the required length if necessary. If a value already exists at {@code
|
|
183 |
* index}, it will be replaced.
|
|
184 |
*
|
|
185 |
* @param value a finite value. May not be {@link Double#isNaN() NaNs} or
|
|
186 |
* {@link Double#isInfinite() infinities}.
|
|
187 |
* @return this array.
|
|
188 |
*/
|
92 | 189 |
public JSONArray put(int index, double value) throws JSONException {
|
93 | 190 |
return put(index, (Double) value);
|
94 | 191 |
}
|
95 | 192 |
|
|
193 |
/**
|
|
194 |
* Sets the value at {@code index} to {@code value}, null padding this array
|
|
195 |
* to the required length if necessary. If a value already exists at {@code
|
|
196 |
* index}, it will be replaced.
|
|
197 |
*
|
|
198 |
* @return this array.
|
|
199 |
*/
|
96 | 200 |
public JSONArray put(int index, int value) throws JSONException {
|
97 | 201 |
return put(index, (Integer) value);
|
98 | 202 |
}
|
99 | 203 |
|
|
204 |
/**
|
|
205 |
* Sets the value at {@code index} to {@code value}, null padding this array
|
|
206 |
* to the required length if necessary. If a value already exists at {@code
|
|
207 |
* index}, it will be replaced.
|
|
208 |
*
|
|
209 |
* @return this array.
|
|
210 |
*/
|
100 | 211 |
public JSONArray put(int index, long value) throws JSONException {
|
101 | 212 |
return put(index, (Long) value);
|
102 | 213 |
}
|
103 | 214 |
|
|
215 |
/**
|
|
216 |
* Sets the value at {@code index} to {@code value}, null padding this array
|
|
217 |
* to the required length if necessary. If a value already exists at {@code
|
|
218 |
* index}, it will be replaced.
|
|
219 |
*
|
|
220 |
* @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
|
|
221 |
* Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
|
|
222 |
* not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
|
|
223 |
* infinities}.
|
|
224 |
* @return this array.
|
|
225 |
*/
|
104 | 226 |
public JSONArray put(int index, Object value) throws JSONException {
|
105 | 227 |
if (value instanceof Number) {
|
106 | 228 |
// deviate from the original by checking all Numbers, not just floats & doubles
|
|
113 | 235 |
return this;
|
114 | 236 |
}
|
115 | 237 |
|
|
238 |
/**
|
|
239 |
* Returns true if this array has no value at {@code index}, or if its value
|
|
240 |
* is the {@code null} reference or {@link JSONObject#NULL}.
|
|
241 |
*/
|
116 | 242 |
public boolean isNull(int index) {
|
117 | 243 |
Object value = opt(index);
|
118 | 244 |
return value == null || value == JSONObject.NULL;
|
119 | 245 |
}
|
120 | 246 |
|
|
247 |
/**
|
|
248 |
* Returns the value at {@code index}.
|
|
249 |
*
|
|
250 |
* @throws JSONException if this array has no value at {@code index}, or if
|
|
251 |
* that value is the {@code null} reference. This method returns
|
|
252 |
* normally if the value is {@code JSONObject#NULL}.
|
|
253 |
*/
|
121 | 254 |
public Object get(int index) throws JSONException {
|
122 | 255 |
try {
|
123 | 256 |
Object value = values.get(index);
|
|
130 | 263 |
}
|
131 | 264 |
}
|
132 | 265 |
|
|
266 |
/**
|
|
267 |
* Returns the value at {@code index}, or null if the array has no value
|
|
268 |
* at {@code index}.
|
|
269 |
*/
|
133 | 270 |
public Object opt(int index) {
|
134 | 271 |
if (index < 0 || index >= values.size()) {
|
135 | 272 |
return null;
|
|
137 | 274 |
return values.get(index);
|
138 | 275 |
}
|
139 | 276 |
|
|
277 |
/**
|
|
278 |
* Returns the value at {@code index} if it exists and is a boolean or can
|
|
279 |
* be coerced to a boolean.
|
|
280 |
*
|
|
281 |
* @throws JSONException if the value at {@code index} doesn't exist or
|
|
282 |
* cannot be coerced to a boolean.
|
|
283 |
*/
|
140 | 284 |
public boolean getBoolean(int index) throws JSONException {
|
141 | 285 |
Object object = get(index);
|
142 | 286 |
Boolean result = JSON.toBoolean(object);
|
|
146 | 290 |
return result;
|
147 | 291 |
}
|
148 | 292 |
|
|
293 |
/**
|
|
294 |
* Returns the value at {@code index} if it exists and is a boolean or can
|
|
295 |
* be coerced to a boolean. Returns false otherwise.
|
|
296 |
*/
|
149 | 297 |
public boolean optBoolean(int index) {
|
150 | 298 |
return optBoolean(index, false);
|
151 | 299 |
}
|
152 | 300 |
|
|
301 |
/**
|
|
302 |
* Returns the value at {@code index} if it exists and is a boolean or can
|
|
303 |
* be coerced to a boolean. Returns {@code fallback} otherwise.
|
|
304 |
*/
|
153 | 305 |
public boolean optBoolean(int index, boolean fallback) {
|
154 | 306 |
Object object = opt(index);
|
155 | 307 |
Boolean result = JSON.toBoolean(object);
|
156 | 308 |
return result != null ? result : fallback;
|
157 | 309 |
}
|
158 | 310 |
|
|
311 |
/**
|
|
312 |
* Returns the value at {@code index} if it exists and is a double or can
|
|
313 |
* be coerced to a double.
|
|
314 |
*
|
|
315 |
* @throws JSONException if the value at {@code index} doesn't exist or
|
|
316 |
* cannot be coerced to a double.
|
|
317 |
*/
|
159 | 318 |
public double getDouble(int index) throws JSONException {
|
160 | 319 |
Object object = get(index);
|
161 | 320 |
Double result = JSON.toDouble(object);
|
|
165 | 324 |
return result;
|
166 | 325 |
}
|
167 | 326 |
|
|
327 |
/**
|
|
328 |
* Returns the value at {@code index} if it exists and is a double or can
|
|
329 |
* be coerced to a double. Returns {@code NaN} otherwise.
|
|
330 |
*/
|
168 | 331 |
public double optDouble(int index) {
|
169 | 332 |
return optDouble(index, Double.NaN);
|
170 | 333 |
}
|
171 | 334 |
|
|
335 |
/**
|
|
336 |
* Returns the value at {@code index} if it exists and is a double or can
|
|
337 |
* be coerced to a double. Returns {@code fallback} otherwise.
|
|
338 |
*/
|
172 | 339 |
public double optDouble(int index, double fallback) {
|
173 | 340 |
Object object = opt(index);
|
174 | 341 |
Double result = JSON.toDouble(object);
|
175 | 342 |
return result != null ? result : fallback;
|
176 | 343 |
}
|
177 | 344 |
|
|
345 |
/**
|
|
346 |
* Returns the value at {@code index} if it exists and is an int or
|
|
347 |
* can be coerced to an int.
|
|
348 |
*
|
|
349 |
* @throws JSONException if the value at {@code index} doesn't exist or
|
|
350 |
* cannot be coerced to a int.
|
|
351 |
*/
|
178 | 352 |
public int getInt(int index) throws JSONException {
|
179 | 353 |
Object object = get(index);
|
180 | 354 |
Integer result = JSON.toInteger(object);
|
|
184 | 358 |
return result;
|
185 | 359 |
}
|
186 | 360 |
|
|
361 |
/**
|
|
362 |
* Returns the value at {@code index} if it exists and is an int or
|
|
363 |
* can be coerced to an int. Returns 0 otherwise.
|
|
364 |
*/
|
187 | 365 |
public int optInt(int index) {
|
188 | 366 |
return optInt(index, 0);
|
189 | 367 |
}
|
190 | 368 |
|
|
369 |
/**
|
|
370 |
* Returns the value at {@code index} if it exists and is an int or
|
|
371 |
* can be coerced to an int. Returns {@code fallback} otherwise.
|
|
372 |
*/
|
191 | 373 |
public int optInt(int index, int fallback) {
|
192 | 374 |
Object object = opt(index);
|
193 | 375 |
Integer result = JSON.toInteger(object);
|
194 | 376 |
return result != null ? result : fallback;
|
195 | 377 |
}
|
196 | 378 |
|
|
379 |
/**
|
|
380 |
* Returns the value at {@code index} if it exists and is a long or
|
|
381 |
* can be coerced to a long.
|
|
382 |
*
|
|
383 |
* @throws JSONException if the value at {@code index} doesn't exist or
|
|
384 |
* cannot be coerced to a long.
|
|
385 |
*/
|
197 | 386 |
public long getLong(int index) throws JSONException {
|
198 | 387 |
Object object = get(index);
|
199 | 388 |
Long result = JSON.toLong(object);
|
|
203 | 392 |
return result;
|
204 | 393 |
}
|
205 | 394 |
|
|
395 |
/**
|
|
396 |
* Returns the value at {@code index} if it exists and is a long or
|
|
397 |
* can be coerced to a long. Returns 0 otherwise.
|
|
398 |
*/
|
206 | 399 |
public long optLong(int index) {
|
207 | 400 |
return optLong(index, 0L);
|
208 | 401 |
}
|
209 | 402 |
|
|
403 |
/**
|
|
404 |
* Returns the value at {@code index} if it exists and is a long or
|
|
405 |
* can be coerced to a long. Returns {@code fallback} otherwise.
|
|
406 |
*/
|
210 | 407 |
public long optLong(int index, long fallback) {
|
211 | 408 |
Object object = opt(index);
|
212 | 409 |
Long result = JSON.toLong(object);
|
213 | 410 |
return result != null ? result : fallback;
|
214 | 411 |
}
|
215 | 412 |
|
|
413 |
/**
|
|
414 |
* Returns the value at {@code index} if it exists, coercing it if
|
|
415 |
* necessary.
|
|
416 |
*
|
|
417 |
* @throws JSONException if no such value exists.
|
|
418 |
*/
|
216 | 419 |
public String getString(int index) throws JSONException {
|
217 | 420 |
Object object = get(index);
|
218 | 421 |
String result = JSON.toString(object);
|
|
222 | 425 |
return result;
|
223 | 426 |
}
|
224 | 427 |
|
|
428 |
/**
|
|
429 |
* Returns the value at {@code index} if it exists, coercing it if
|
|
430 |
* necessary. Returns the empty string if no such value exists.
|
|
431 |
*/
|
225 | 432 |
public String optString(int index) {
|
226 | 433 |
return optString(index, "");
|
227 | 434 |
}
|
228 | 435 |
|
|
436 |
/**
|
|
437 |
* Returns the value at {@code index} if it exists, coercing it if
|
|
438 |
* necessary. Returns {@code fallback} if no such value exists.
|
|
439 |
*/
|
229 | 440 |
public String optString(int index, String fallback) {
|
230 | 441 |
Object object = opt(index);
|
231 | 442 |
String result = JSON.toString(object);
|
232 | 443 |
return result != null ? result : fallback;
|
233 | 444 |
}
|
234 | 445 |
|
|
446 |
/**
|
|
447 |
* Returns the value at {@code index} if it exists and is a {@code
|
|
448 |
* JSONArray}.
|
|
449 |
*
|
|
450 |
* @throws JSONException if the value doesn't exist or is not a {@code
|
|
451 |
* JSONArray}.
|
|
452 |
*/
|
235 | 453 |
public JSONArray getJSONArray(int index) throws JSONException {
|
236 | 454 |
Object object = get(index);
|
237 | 455 |
if (object instanceof JSONArray) {
|
|
241 | 459 |
}
|
242 | 460 |
}
|
243 | 461 |
|
|
462 |
/**
|
|
463 |
* Returns the value at {@code index} if it exists and is a {@code
|
|
464 |
* JSONArray}. Returns null otherwise.
|
|
465 |
*/
|
244 | 466 |
public JSONArray optJSONArray(int index) {
|
245 | 467 |
Object object = opt(index);
|
246 | 468 |
return object instanceof JSONArray ? (JSONArray) object : null;
|
247 | 469 |
}
|
248 | 470 |
|
|
471 |
/**
|
|
472 |
* Returns the value at {@code index} if it exists and is a {@code
|
|
473 |
* JSONObject}.
|
|
474 |
*
|
|
475 |
* @throws JSONException if the value doesn't exist or is not a {@code
|
|
476 |
* JSONObject}.
|
|
477 |
*/
|
249 | 478 |
public JSONObject getJSONObject(int index) throws JSONException {
|
250 | 479 |
Object object = get(index);
|
251 | 480 |
if (object instanceof JSONObject) {
|
|
255 | 484 |
}
|
256 | 485 |
}
|
257 | 486 |
|
|
487 |
/**
|
|
488 |
* Returns the value at {@code index} if it exists and is a {@code
|
|
489 |
* JSONObject}. Returns null otherwise.
|
|
490 |
*/
|
258 | 491 |
public JSONObject optJSONObject(int index) {
|
259 | 492 |
Object object = opt(index);
|
260 | 493 |
return object instanceof JSONObject ? (JSONObject) object : null;
|
261 | 494 |
}
|
262 | 495 |
|
|
496 |
/**
|
|
497 |
* Returns a new object whose values are the values in this array, and whose
|
|
498 |
* names are the values in {@code names}. Names and values are paired up by
|
|
499 |
* index from 0 through to the shorter array's length. Names that are not
|
|
500 |
* strings will be coerced to strings. This method returns null if either
|
|
501 |
* array is empty.
|
|
502 |
*/
|
263 | 503 |
public JSONObject toJSONObject(JSONArray names) throws JSONException {
|
264 | 504 |
JSONObject result = new JSONObject();
|
265 | 505 |
int length = Math.min(names.length(), values.size());
|
|
273 | 513 |
return result;
|
274 | 514 |
}
|
275 | 515 |
|
|
516 |
/**
|
|
517 |
* Returns a new string by alternating this array's values with {@code
|
|
518 |
* separator}. This array's string values are quoted and have their special
|
|
519 |
* characters escaped. For example, the array containing the strings '12"
|
|
520 |
* pizza', 'taco' and 'soda' joined on '+' returns this:
|
|
521 |
* <pre>"12\" pizza"+"taco"+"soda"</pre>
|
|
522 |
*/
|
276 | 523 |
public String join(String separator) throws JSONException {
|
277 | 524 |
JSONStringer stringer = new JSONStringer();
|
278 | 525 |
stringer.open(JSONStringer.Scope.NULL, "");
|
|
286 | 533 |
return stringer.out.toString();
|
287 | 534 |
}
|
288 | 535 |
|
|
536 |
/**
|
|
537 |
* Encodes this array as a compact JSON string, such as:
|
|
538 |
* <pre>[94043,90210]</pre>
|
|
539 |
*/
|
289 | 540 |
@Override public String toString() {
|
290 | 541 |
try {
|
291 | 542 |
JSONStringer stringer = new JSONStringer();
|
|
296 | 547 |
}
|
297 | 548 |
}
|
298 | 549 |
|
|
550 |
/**
|
|
551 |
* Encodes this array as a human readable JSON string for debugging, such
|
|
552 |
* as:
|
|
553 |
* <pre>
|
|
554 |
* [
|
|
555 |
* 94043,
|
|
556 |
* 90210
|
|
557 |
* ]</pre>
|
|
558 |
*
|
|
559 |
* @param indentSpaces the number of spaces to indent for each level of
|
|
560 |
* nesting.
|
|
561 |
*/
|
299 | 562 |
public String toString(int indentSpaces) throws JSONException {
|
300 | 563 |
JSONStringer stringer = new JSONStringer(indentSpaces);
|
301 | 564 |
writeTo(stringer);
|