[6484] | 1 | package org.json;
|
---|
| 2 |
|
---|
| 3 | /*
|
---|
| 4 | Copyright (c) 2002 JSON.org
|
---|
| 5 |
|
---|
| 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:
|
---|
| 12 |
|
---|
| 13 | The above copyright notice and this permission notice shall be included in all
|
---|
| 14 | copies or substantial portions of the Software.
|
---|
| 15 |
|
---|
| 16 | The Software shall be used for Good, not Evil.
|
---|
| 17 |
|
---|
| 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
|
---|
| 24 | SOFTWARE.
|
---|
| 25 | */
|
---|
| 26 |
|
---|
| 27 | import java.io.IOException;
|
---|
| 28 | import java.io.StringWriter;
|
---|
| 29 | import java.io.Writer;
|
---|
| 30 | import java.lang.reflect.Array;
|
---|
| 31 | import java.util.ArrayList;
|
---|
| 32 | import java.util.Collection;
|
---|
| 33 | import java.util.Iterator;
|
---|
| 34 | import java.util.Map;
|
---|
| 35 |
|
---|
| 36 | /**
|
---|
| 37 | * A JSONArray is an ordered sequence of values. Its external text form is a
|
---|
| 38 | * string wrapped in square brackets with commas separating the values. The
|
---|
| 39 | * internal form is an object having <code>get</code> and <code>opt</code>
|
---|
| 40 | * methods for accessing the values by index, and <code>put</code> methods for
|
---|
| 41 | * adding or replacing values. The values can be any of these types:
|
---|
| 42 | * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
|
---|
| 43 | * <code>Number</code>, <code>String</code>, or the
|
---|
| 44 | * <code>JSONObject.NULL object</code>.
|
---|
| 45 | * <p>
|
---|
| 46 | * The constructor can convert a JSON text into a Java object. The
|
---|
| 47 | * <code>toString</code> method converts to JSON text.
|
---|
| 48 | * <p>
|
---|
| 49 | * A <code>get</code> method returns a value if one can be found, and throws an
|
---|
| 50 | * exception if one cannot be found. An <code>opt</code> method returns a
|
---|
| 51 | * default value instead of throwing an exception, and so is useful for
|
---|
| 52 | * obtaining optional values.
|
---|
| 53 | * <p>
|
---|
| 54 | * The generic <code>get()</code> and <code>opt()</code> methods return an
|
---|
| 55 | * object which you can cast or query for type. There are also typed
|
---|
| 56 | * <code>get</code> and <code>opt</code> methods that do type checking and type
|
---|
| 57 | * coercion for you.
|
---|
| 58 | * <p>
|
---|
| 59 | * The texts produced by the <code>toString</code> methods strictly conform to
|
---|
| 60 | * JSON syntax rules. The constructors are more forgiving in the texts they will
|
---|
| 61 | * accept:
|
---|
| 62 | * <ul>
|
---|
| 63 | * <li>An extra <code>,</code> <small>(comma)</small> may appear just
|
---|
| 64 | * before the closing bracket.</li>
|
---|
| 65 | * <li>The <code>null</code> value will be inserted when there is <code>,</code>
|
---|
| 66 | * <small>(comma)</small> elision.</li>
|
---|
| 67 | * <li>Strings may be quoted with <code>'</code> <small>(single
|
---|
| 68 | * quote)</small>.</li>
|
---|
| 69 | * <li>Strings do not need to be quoted at all if they do not begin with a quote
|
---|
| 70 | * or single quote, and if they do not contain leading or trailing spaces, and
|
---|
| 71 | * if they do not contain any of these characters:
|
---|
| 72 | * <code>{ } [ ] / \ : , #</code> and if they do not look like numbers and
|
---|
| 73 | * if they are not the reserved words <code>true</code>, <code>false</code>, or
|
---|
| 74 | * <code>null</code>.</li>
|
---|
| 75 | * </ul>
|
---|
| 76 | *
|
---|
| 77 | * @author JSON.org
|
---|
| 78 | * @version 2013-04-18
|
---|
| 79 | */
|
---|
| 80 | public class JSONArray {
|
---|
| 81 |
|
---|
| 82 | /**
|
---|
| 83 | * The arrayList where the JSONArray's properties are kept.
|
---|
| 84 | */
|
---|
[6615] | 85 | private final ArrayList<Object> myArrayList;
|
---|
[6484] | 86 |
|
---|
| 87 | /**
|
---|
| 88 | * Construct an empty JSONArray.
|
---|
| 89 | */
|
---|
| 90 | public JSONArray() {
|
---|
[6615] | 91 | this.myArrayList = new ArrayList<Object>();
|
---|
[6484] | 92 | }
|
---|
| 93 |
|
---|
| 94 | /**
|
---|
| 95 | * Construct a JSONArray from a JSONTokener.
|
---|
| 96 | *
|
---|
| 97 | * @param x
|
---|
| 98 | * A JSONTokener
|
---|
| 99 | * @throws JSONException
|
---|
| 100 | * If there is a syntax error.
|
---|
| 101 | */
|
---|
| 102 | public JSONArray(JSONTokener x) throws JSONException {
|
---|
| 103 | this();
|
---|
| 104 | if (x.nextClean() != '[') {
|
---|
| 105 | throw x.syntaxError("A JSONArray text must start with '['");
|
---|
| 106 | }
|
---|
| 107 | if (x.nextClean() != ']') {
|
---|
| 108 | x.back();
|
---|
| 109 | for (;;) {
|
---|
| 110 | if (x.nextClean() == ',') {
|
---|
| 111 | x.back();
|
---|
| 112 | this.myArrayList.add(JSONObject.NULL);
|
---|
| 113 | } else {
|
---|
| 114 | x.back();
|
---|
| 115 | this.myArrayList.add(x.nextValue());
|
---|
| 116 | }
|
---|
| 117 | switch (x.nextClean()) {
|
---|
| 118 | case ',':
|
---|
| 119 | if (x.nextClean() == ']') {
|
---|
| 120 | return;
|
---|
| 121 | }
|
---|
| 122 | x.back();
|
---|
| 123 | break;
|
---|
| 124 | case ']':
|
---|
| 125 | return;
|
---|
| 126 | default:
|
---|
| 127 | throw x.syntaxError("Expected a ',' or ']'");
|
---|
| 128 | }
|
---|
| 129 | }
|
---|
| 130 | }
|
---|
| 131 | }
|
---|
| 132 |
|
---|
| 133 | /**
|
---|
| 134 | * Construct a JSONArray from a source JSON text.
|
---|
| 135 | *
|
---|
| 136 | * @param source
|
---|
| 137 | * A string that begins with <code>[</code> <small>(left
|
---|
| 138 | * bracket)</small> and ends with <code>]</code>
|
---|
| 139 | * <small>(right bracket)</small>.
|
---|
| 140 | * @throws JSONException
|
---|
| 141 | * If there is a syntax error.
|
---|
| 142 | */
|
---|
| 143 | public JSONArray(String source) throws JSONException {
|
---|
| 144 | this(new JSONTokener(source));
|
---|
| 145 | }
|
---|
| 146 |
|
---|
| 147 | /**
|
---|
| 148 | * Construct a JSONArray from a Collection.
|
---|
| 149 | *
|
---|
| 150 | * @param collection
|
---|
| 151 | * A Collection.
|
---|
| 152 | */
|
---|
[6615] | 153 | public JSONArray(Collection<?> collection) {
|
---|
| 154 | this.myArrayList = new ArrayList<Object>();
|
---|
[6484] | 155 | if (collection != null) {
|
---|
[6615] | 156 | Iterator<?> iter = collection.iterator();
|
---|
[6484] | 157 | while (iter.hasNext()) {
|
---|
| 158 | this.myArrayList.add(JSONObject.wrap(iter.next()));
|
---|
| 159 | }
|
---|
| 160 | }
|
---|
| 161 | }
|
---|
| 162 |
|
---|
| 163 | /**
|
---|
| 164 | * Construct a JSONArray from an array
|
---|
| 165 | *
|
---|
| 166 | * @throws JSONException
|
---|
| 167 | * If not an array.
|
---|
| 168 | */
|
---|
| 169 | public JSONArray(Object array) throws JSONException {
|
---|
| 170 | this();
|
---|
| 171 | if (array.getClass().isArray()) {
|
---|
| 172 | int length = Array.getLength(array);
|
---|
| 173 | for (int i = 0; i < length; i += 1) {
|
---|
| 174 | this.put(JSONObject.wrap(Array.get(array, i)));
|
---|
| 175 | }
|
---|
| 176 | } else {
|
---|
| 177 | throw new JSONException(
|
---|
| 178 | "JSONArray initial value should be a string or collection or array.");
|
---|
| 179 | }
|
---|
| 180 | }
|
---|
| 181 |
|
---|
| 182 | /**
|
---|
| 183 | * Get the object value associated with an index.
|
---|
| 184 | *
|
---|
| 185 | * @param index
|
---|
| 186 | * The index must be between 0 and length() - 1.
|
---|
| 187 | * @return An object value.
|
---|
| 188 | * @throws JSONException
|
---|
| 189 | * If there is no value for the index.
|
---|
| 190 | */
|
---|
| 191 | public Object get(int index) throws JSONException {
|
---|
| 192 | Object object = this.opt(index);
|
---|
| 193 | if (object == null) {
|
---|
| 194 | throw new JSONException("JSONArray[" + index + "] not found.");
|
---|
| 195 | }
|
---|
| 196 | return object;
|
---|
| 197 | }
|
---|
| 198 |
|
---|
| 199 | /**
|
---|
| 200 | * Get the boolean value associated with an index. The string values "true"
|
---|
| 201 | * and "false" are converted to boolean.
|
---|
| 202 | *
|
---|
| 203 | * @param index
|
---|
| 204 | * The index must be between 0 and length() - 1.
|
---|
| 205 | * @return The truth.
|
---|
| 206 | * @throws JSONException
|
---|
| 207 | * If there is no value for the index or if the value is not
|
---|
| 208 | * convertible to boolean.
|
---|
| 209 | */
|
---|
| 210 | public boolean getBoolean(int index) throws JSONException {
|
---|
| 211 | Object object = this.get(index);
|
---|
| 212 | if (object.equals(Boolean.FALSE)
|
---|
| 213 | || (object instanceof String && ((String) object)
|
---|
| 214 | .equalsIgnoreCase("false"))) {
|
---|
| 215 | return false;
|
---|
| 216 | } else if (object.equals(Boolean.TRUE)
|
---|
| 217 | || (object instanceof String && ((String) object)
|
---|
| 218 | .equalsIgnoreCase("true"))) {
|
---|
| 219 | return true;
|
---|
| 220 | }
|
---|
| 221 | throw new JSONException("JSONArray[" + index + "] is not a boolean.");
|
---|
| 222 | }
|
---|
| 223 |
|
---|
| 224 | /**
|
---|
| 225 | * Get the double value associated with an index.
|
---|
| 226 | *
|
---|
| 227 | * @param index
|
---|
| 228 | * The index must be between 0 and length() - 1.
|
---|
| 229 | * @return The value.
|
---|
| 230 | * @throws JSONException
|
---|
| 231 | * If the key is not found or if the value cannot be converted
|
---|
| 232 | * to a number.
|
---|
| 233 | */
|
---|
| 234 | public double getDouble(int index) throws JSONException {
|
---|
| 235 | Object object = this.get(index);
|
---|
| 236 | try {
|
---|
| 237 | return object instanceof Number ? ((Number) object).doubleValue()
|
---|
| 238 | : Double.parseDouble((String) object);
|
---|
| 239 | } catch (Exception e) {
|
---|
| 240 | throw new JSONException("JSONArray[" + index + "] is not a number.");
|
---|
| 241 | }
|
---|
| 242 | }
|
---|
| 243 |
|
---|
| 244 | /**
|
---|
| 245 | * Get the int value associated with an index.
|
---|
| 246 | *
|
---|
| 247 | * @param index
|
---|
| 248 | * The index must be between 0 and length() - 1.
|
---|
| 249 | * @return The value.
|
---|
| 250 | * @throws JSONException
|
---|
| 251 | * If the key is not found or if the value is not a number.
|
---|
| 252 | */
|
---|
| 253 | public int getInt(int index) throws JSONException {
|
---|
| 254 | Object object = this.get(index);
|
---|
| 255 | try {
|
---|
| 256 | return object instanceof Number ? ((Number) object).intValue()
|
---|
| 257 | : Integer.parseInt((String) object);
|
---|
| 258 | } catch (Exception e) {
|
---|
| 259 | throw new JSONException("JSONArray[" + index + "] is not a number.");
|
---|
| 260 | }
|
---|
| 261 | }
|
---|
| 262 |
|
---|
| 263 | /**
|
---|
| 264 | * Get the JSONArray associated with an index.
|
---|
| 265 | *
|
---|
| 266 | * @param index
|
---|
| 267 | * The index must be between 0 and length() - 1.
|
---|
| 268 | * @return A JSONArray value.
|
---|
| 269 | * @throws JSONException
|
---|
| 270 | * If there is no value for the index. or if the value is not a
|
---|
| 271 | * JSONArray
|
---|
| 272 | */
|
---|
| 273 | public JSONArray getJSONArray(int index) throws JSONException {
|
---|
| 274 | Object object = this.get(index);
|
---|
| 275 | if (object instanceof JSONArray) {
|
---|
| 276 | return (JSONArray) object;
|
---|
| 277 | }
|
---|
| 278 | throw new JSONException("JSONArray[" + index + "] is not a JSONArray.");
|
---|
| 279 | }
|
---|
| 280 |
|
---|
| 281 | /**
|
---|
| 282 | * Get the JSONObject associated with an index.
|
---|
| 283 | *
|
---|
| 284 | * @param index
|
---|
| 285 | * subscript
|
---|
| 286 | * @return A JSONObject value.
|
---|
| 287 | * @throws JSONException
|
---|
| 288 | * If there is no value for the index or if the value is not a
|
---|
| 289 | * JSONObject
|
---|
| 290 | */
|
---|
| 291 | public JSONObject getJSONObject(int index) throws JSONException {
|
---|
| 292 | Object object = this.get(index);
|
---|
| 293 | if (object instanceof JSONObject) {
|
---|
| 294 | return (JSONObject) object;
|
---|
| 295 | }
|
---|
| 296 | throw new JSONException("JSONArray[" + index + "] is not a JSONObject.");
|
---|
| 297 | }
|
---|
| 298 |
|
---|
| 299 | /**
|
---|
| 300 | * Get the long value associated with an index.
|
---|
| 301 | *
|
---|
| 302 | * @param index
|
---|
| 303 | * The index must be between 0 and length() - 1.
|
---|
| 304 | * @return The value.
|
---|
| 305 | * @throws JSONException
|
---|
| 306 | * If the key is not found or if the value cannot be converted
|
---|
| 307 | * to a number.
|
---|
| 308 | */
|
---|
| 309 | public long getLong(int index) throws JSONException {
|
---|
| 310 | Object object = this.get(index);
|
---|
| 311 | try {
|
---|
| 312 | return object instanceof Number ? ((Number) object).longValue()
|
---|
| 313 | : Long.parseLong((String) object);
|
---|
| 314 | } catch (Exception e) {
|
---|
| 315 | throw new JSONException("JSONArray[" + index + "] is not a number.");
|
---|
| 316 | }
|
---|
| 317 | }
|
---|
| 318 |
|
---|
| 319 | /**
|
---|
| 320 | * Get the string associated with an index.
|
---|
| 321 | *
|
---|
| 322 | * @param index
|
---|
| 323 | * The index must be between 0 and length() - 1.
|
---|
| 324 | * @return A string value.
|
---|
| 325 | * @throws JSONException
|
---|
| 326 | * If there is no string value for the index.
|
---|
| 327 | */
|
---|
| 328 | public String getString(int index) throws JSONException {
|
---|
| 329 | Object object = this.get(index);
|
---|
| 330 | if (object instanceof String) {
|
---|
| 331 | return (String) object;
|
---|
| 332 | }
|
---|
| 333 | throw new JSONException("JSONArray[" + index + "] not a string.");
|
---|
| 334 | }
|
---|
| 335 |
|
---|
| 336 | /**
|
---|
| 337 | * Determine if the value is null.
|
---|
| 338 | *
|
---|
| 339 | * @param index
|
---|
| 340 | * The index must be between 0 and length() - 1.
|
---|
| 341 | * @return true if the value at the index is null, or if there is no value.
|
---|
| 342 | */
|
---|
| 343 | public boolean isNull(int index) {
|
---|
| 344 | return JSONObject.NULL.equals(this.opt(index));
|
---|
| 345 | }
|
---|
| 346 |
|
---|
| 347 | /**
|
---|
| 348 | * Make a string from the contents of this JSONArray. The
|
---|
| 349 | * <code>separator</code> string is inserted between each element. Warning:
|
---|
| 350 | * This method assumes that the data structure is acyclical.
|
---|
| 351 | *
|
---|
| 352 | * @param separator
|
---|
| 353 | * A string that will be inserted between the elements.
|
---|
| 354 | * @return a string.
|
---|
| 355 | * @throws JSONException
|
---|
| 356 | * If the array contains an invalid number.
|
---|
| 357 | */
|
---|
| 358 | public String join(String separator) throws JSONException {
|
---|
| 359 | int len = this.length();
|
---|
| 360 | StringBuffer sb = new StringBuffer();
|
---|
| 361 |
|
---|
| 362 | for (int i = 0; i < len; i += 1) {
|
---|
| 363 | if (i > 0) {
|
---|
| 364 | sb.append(separator);
|
---|
| 365 | }
|
---|
| 366 | sb.append(JSONObject.valueToString(this.myArrayList.get(i)));
|
---|
| 367 | }
|
---|
| 368 | return sb.toString();
|
---|
| 369 | }
|
---|
| 370 |
|
---|
| 371 | /**
|
---|
| 372 | * Get the number of elements in the JSONArray, included nulls.
|
---|
| 373 | *
|
---|
| 374 | * @return The length (or size).
|
---|
| 375 | */
|
---|
| 376 | public int length() {
|
---|
| 377 | return this.myArrayList.size();
|
---|
| 378 | }
|
---|
| 379 |
|
---|
| 380 | /**
|
---|
| 381 | * Get the optional object value associated with an index.
|
---|
| 382 | *
|
---|
| 383 | * @param index
|
---|
| 384 | * The index must be between 0 and length() - 1.
|
---|
| 385 | * @return An object value, or null if there is no object at that index.
|
---|
| 386 | */
|
---|
| 387 | public Object opt(int index) {
|
---|
| 388 | return (index < 0 || index >= this.length()) ? null : this.myArrayList
|
---|
| 389 | .get(index);
|
---|
| 390 | }
|
---|
| 391 |
|
---|
| 392 | /**
|
---|
| 393 | * Get the optional boolean value associated with an index. It returns false
|
---|
| 394 | * if there is no value at that index, or if the value is not Boolean.TRUE
|
---|
| 395 | * or the String "true".
|
---|
| 396 | *
|
---|
| 397 | * @param index
|
---|
| 398 | * The index must be between 0 and length() - 1.
|
---|
| 399 | * @return The truth.
|
---|
| 400 | */
|
---|
| 401 | public boolean optBoolean(int index) {
|
---|
| 402 | return this.optBoolean(index, false);
|
---|
| 403 | }
|
---|
| 404 |
|
---|
| 405 | /**
|
---|
| 406 | * Get the optional boolean value associated with an index. It returns the
|
---|
| 407 | * defaultValue if there is no value at that index or if it is not a Boolean
|
---|
| 408 | * or the String "true" or "false" (case insensitive).
|
---|
| 409 | *
|
---|
| 410 | * @param index
|
---|
| 411 | * The index must be between 0 and length() - 1.
|
---|
| 412 | * @param defaultValue
|
---|
| 413 | * A boolean default.
|
---|
| 414 | * @return The truth.
|
---|
| 415 | */
|
---|
| 416 | public boolean optBoolean(int index, boolean defaultValue) {
|
---|
| 417 | try {
|
---|
| 418 | return this.getBoolean(index);
|
---|
| 419 | } catch (Exception e) {
|
---|
| 420 | return defaultValue;
|
---|
| 421 | }
|
---|
| 422 | }
|
---|
| 423 |
|
---|
| 424 | /**
|
---|
| 425 | * Get the optional double value associated with an index. NaN is returned
|
---|
| 426 | * if there is no value for the index, or if the value is not a number and
|
---|
| 427 | * cannot be converted to a number.
|
---|
| 428 | *
|
---|
| 429 | * @param index
|
---|
| 430 | * The index must be between 0 and length() - 1.
|
---|
| 431 | * @return The value.
|
---|
| 432 | */
|
---|
| 433 | public double optDouble(int index) {
|
---|
| 434 | return this.optDouble(index, Double.NaN);
|
---|
| 435 | }
|
---|
| 436 |
|
---|
| 437 | /**
|
---|
| 438 | * Get the optional double value associated with an index. The defaultValue
|
---|
| 439 | * is returned if there is no value for the index, or if the value is not a
|
---|
| 440 | * number and cannot be converted to a number.
|
---|
| 441 | *
|
---|
| 442 | * @param index
|
---|
| 443 | * subscript
|
---|
| 444 | * @param defaultValue
|
---|
| 445 | * The default value.
|
---|
| 446 | * @return The value.
|
---|
| 447 | */
|
---|
| 448 | public double optDouble(int index, double defaultValue) {
|
---|
| 449 | try {
|
---|
| 450 | return this.getDouble(index);
|
---|
| 451 | } catch (Exception e) {
|
---|
| 452 | return defaultValue;
|
---|
| 453 | }
|
---|
| 454 | }
|
---|
| 455 |
|
---|
| 456 | /**
|
---|
| 457 | * Get the optional int value associated with an index. Zero is returned if
|
---|
| 458 | * there is no value for the index, or if the value is not a number and
|
---|
| 459 | * cannot be converted to a number.
|
---|
| 460 | *
|
---|
| 461 | * @param index
|
---|
| 462 | * The index must be between 0 and length() - 1.
|
---|
| 463 | * @return The value.
|
---|
| 464 | */
|
---|
| 465 | public int optInt(int index) {
|
---|
| 466 | return this.optInt(index, 0);
|
---|
| 467 | }
|
---|
| 468 |
|
---|
| 469 | /**
|
---|
| 470 | * Get the optional int value associated with an index. The defaultValue is
|
---|
| 471 | * returned if there is no value for the index, or if the value is not a
|
---|
| 472 | * number and cannot be converted to a number.
|
---|
| 473 | *
|
---|
| 474 | * @param index
|
---|
| 475 | * The index must be between 0 and length() - 1.
|
---|
| 476 | * @param defaultValue
|
---|
| 477 | * The default value.
|
---|
| 478 | * @return The value.
|
---|
| 479 | */
|
---|
| 480 | public int optInt(int index, int defaultValue) {
|
---|
| 481 | try {
|
---|
| 482 | return this.getInt(index);
|
---|
| 483 | } catch (Exception e) {
|
---|
| 484 | return defaultValue;
|
---|
| 485 | }
|
---|
| 486 | }
|
---|
| 487 |
|
---|
| 488 | /**
|
---|
| 489 | * Get the optional JSONArray associated with an index.
|
---|
| 490 | *
|
---|
| 491 | * @param index
|
---|
| 492 | * subscript
|
---|
| 493 | * @return A JSONArray value, or null if the index has no value, or if the
|
---|
| 494 | * value is not a JSONArray.
|
---|
| 495 | */
|
---|
| 496 | public JSONArray optJSONArray(int index) {
|
---|
| 497 | Object o = this.opt(index);
|
---|
| 498 | return o instanceof JSONArray ? (JSONArray) o : null;
|
---|
| 499 | }
|
---|
| 500 |
|
---|
| 501 | /**
|
---|
| 502 | * Get the optional JSONObject associated with an index. Null is returned if
|
---|
| 503 | * the key is not found, or null if the index has no value, or if the value
|
---|
| 504 | * is not a JSONObject.
|
---|
| 505 | *
|
---|
| 506 | * @param index
|
---|
| 507 | * The index must be between 0 and length() - 1.
|
---|
| 508 | * @return A JSONObject value.
|
---|
| 509 | */
|
---|
| 510 | public JSONObject optJSONObject(int index) {
|
---|
| 511 | Object o = this.opt(index);
|
---|
| 512 | return o instanceof JSONObject ? (JSONObject) o : null;
|
---|
| 513 | }
|
---|
| 514 |
|
---|
| 515 | /**
|
---|
| 516 | * Get the optional long value associated with an index. Zero is returned if
|
---|
| 517 | * there is no value for the index, or if the value is not a number and
|
---|
| 518 | * cannot be converted to a number.
|
---|
| 519 | *
|
---|
| 520 | * @param index
|
---|
| 521 | * The index must be between 0 and length() - 1.
|
---|
| 522 | * @return The value.
|
---|
| 523 | */
|
---|
| 524 | public long optLong(int index) {
|
---|
| 525 | return this.optLong(index, 0);
|
---|
| 526 | }
|
---|
| 527 |
|
---|
| 528 | /**
|
---|
| 529 | * Get the optional long value associated with an index. The defaultValue is
|
---|
| 530 | * returned if there is no value for the index, or if the value is not a
|
---|
| 531 | * number and cannot be converted to a number.
|
---|
| 532 | *
|
---|
| 533 | * @param index
|
---|
| 534 | * The index must be between 0 and length() - 1.
|
---|
| 535 | * @param defaultValue
|
---|
| 536 | * The default value.
|
---|
| 537 | * @return The value.
|
---|
| 538 | */
|
---|
| 539 | public long optLong(int index, long defaultValue) {
|
---|
| 540 | try {
|
---|
| 541 | return this.getLong(index);
|
---|
| 542 | } catch (Exception e) {
|
---|
| 543 | return defaultValue;
|
---|
| 544 | }
|
---|
| 545 | }
|
---|
| 546 |
|
---|
| 547 | /**
|
---|
| 548 | * Get the optional string value associated with an index. It returns an
|
---|
| 549 | * empty string if there is no value at that index. If the value is not a
|
---|
| 550 | * string and is not null, then it is coverted to a string.
|
---|
| 551 | *
|
---|
| 552 | * @param index
|
---|
| 553 | * The index must be between 0 and length() - 1.
|
---|
| 554 | * @return A String value.
|
---|
| 555 | */
|
---|
| 556 | public String optString(int index) {
|
---|
| 557 | return this.optString(index, "");
|
---|
| 558 | }
|
---|
| 559 |
|
---|
| 560 | /**
|
---|
| 561 | * Get the optional string associated with an index. The defaultValue is
|
---|
| 562 | * returned if the key is not found.
|
---|
| 563 | *
|
---|
| 564 | * @param index
|
---|
| 565 | * The index must be between 0 and length() - 1.
|
---|
| 566 | * @param defaultValue
|
---|
| 567 | * The default value.
|
---|
| 568 | * @return A String value.
|
---|
| 569 | */
|
---|
| 570 | public String optString(int index, String defaultValue) {
|
---|
| 571 | Object object = this.opt(index);
|
---|
| 572 | return JSONObject.NULL.equals(object) ? defaultValue : object
|
---|
| 573 | .toString();
|
---|
| 574 | }
|
---|
| 575 |
|
---|
| 576 | /**
|
---|
| 577 | * Append a boolean value. This increases the array's length by one.
|
---|
| 578 | *
|
---|
| 579 | * @param value
|
---|
| 580 | * A boolean value.
|
---|
| 581 | * @return this.
|
---|
| 582 | */
|
---|
| 583 | public JSONArray put(boolean value) {
|
---|
| 584 | this.put(value ? Boolean.TRUE : Boolean.FALSE);
|
---|
| 585 | return this;
|
---|
| 586 | }
|
---|
| 587 |
|
---|
| 588 | /**
|
---|
| 589 | * Put a value in the JSONArray, where the value will be a JSONArray which
|
---|
| 590 | * is produced from a Collection.
|
---|
| 591 | *
|
---|
| 592 | * @param value
|
---|
| 593 | * A Collection value.
|
---|
| 594 | * @return this.
|
---|
| 595 | */
|
---|
[6615] | 596 | public JSONArray put(Collection<?> value) {
|
---|
[6484] | 597 | this.put(new JSONArray(value));
|
---|
| 598 | return this;
|
---|
| 599 | }
|
---|
| 600 |
|
---|
| 601 | /**
|
---|
| 602 | * Append a double value. This increases the array's length by one.
|
---|
| 603 | *
|
---|
| 604 | * @param value
|
---|
| 605 | * A double value.
|
---|
| 606 | * @throws JSONException
|
---|
| 607 | * if the value is not finite.
|
---|
| 608 | * @return this.
|
---|
| 609 | */
|
---|
| 610 | public JSONArray put(double value) throws JSONException {
|
---|
| 611 | Double d = new Double(value);
|
---|
| 612 | JSONObject.testValidity(d);
|
---|
| 613 | this.put(d);
|
---|
| 614 | return this;
|
---|
| 615 | }
|
---|
| 616 |
|
---|
| 617 | /**
|
---|
| 618 | * Append an int value. This increases the array's length by one.
|
---|
| 619 | *
|
---|
| 620 | * @param value
|
---|
| 621 | * An int value.
|
---|
| 622 | * @return this.
|
---|
| 623 | */
|
---|
| 624 | public JSONArray put(int value) {
|
---|
| 625 | this.put(new Integer(value));
|
---|
| 626 | return this;
|
---|
| 627 | }
|
---|
| 628 |
|
---|
| 629 | /**
|
---|
| 630 | * Append an long value. This increases the array's length by one.
|
---|
| 631 | *
|
---|
| 632 | * @param value
|
---|
| 633 | * A long value.
|
---|
| 634 | * @return this.
|
---|
| 635 | */
|
---|
| 636 | public JSONArray put(long value) {
|
---|
| 637 | this.put(new Long(value));
|
---|
| 638 | return this;
|
---|
| 639 | }
|
---|
| 640 |
|
---|
| 641 | /**
|
---|
| 642 | * Put a value in the JSONArray, where the value will be a JSONObject which
|
---|
| 643 | * is produced from a Map.
|
---|
| 644 | *
|
---|
| 645 | * @param value
|
---|
| 646 | * A Map value.
|
---|
| 647 | * @return this.
|
---|
| 648 | */
|
---|
[6615] | 649 | public JSONArray put(Map<?, ?> value) {
|
---|
[6484] | 650 | this.put(new JSONObject(value));
|
---|
| 651 | return this;
|
---|
| 652 | }
|
---|
| 653 |
|
---|
| 654 | /**
|
---|
| 655 | * Append an object value. This increases the array's length by one.
|
---|
| 656 | *
|
---|
| 657 | * @param value
|
---|
| 658 | * An object value. The value should be a Boolean, Double,
|
---|
| 659 | * Integer, JSONArray, JSONObject, Long, or String, or the
|
---|
| 660 | * JSONObject.NULL object.
|
---|
| 661 | * @return this.
|
---|
| 662 | */
|
---|
| 663 | public JSONArray put(Object value) {
|
---|
| 664 | this.myArrayList.add(value);
|
---|
| 665 | return this;
|
---|
| 666 | }
|
---|
| 667 |
|
---|
| 668 | /**
|
---|
| 669 | * Put or replace a boolean value in the JSONArray. If the index is greater
|
---|
| 670 | * than the length of the JSONArray, then null elements will be added as
|
---|
| 671 | * necessary to pad it out.
|
---|
| 672 | *
|
---|
| 673 | * @param index
|
---|
| 674 | * The subscript.
|
---|
| 675 | * @param value
|
---|
| 676 | * A boolean value.
|
---|
| 677 | * @return this.
|
---|
| 678 | * @throws JSONException
|
---|
| 679 | * If the index is negative.
|
---|
| 680 | */
|
---|
| 681 | public JSONArray put(int index, boolean value) throws JSONException {
|
---|
| 682 | this.put(index, value ? Boolean.TRUE : Boolean.FALSE);
|
---|
| 683 | return this;
|
---|
| 684 | }
|
---|
| 685 |
|
---|
| 686 | /**
|
---|
| 687 | * Put a value in the JSONArray, where the value will be a JSONArray which
|
---|
| 688 | * is produced from a Collection.
|
---|
| 689 | *
|
---|
| 690 | * @param index
|
---|
| 691 | * The subscript.
|
---|
| 692 | * @param value
|
---|
| 693 | * A Collection value.
|
---|
| 694 | * @return this.
|
---|
| 695 | * @throws JSONException
|
---|
| 696 | * If the index is negative or if the value is not finite.
|
---|
| 697 | */
|
---|
[6615] | 698 | public JSONArray put(int index, Collection<?> value) throws JSONException {
|
---|
[6484] | 699 | this.put(index, new JSONArray(value));
|
---|
| 700 | return this;
|
---|
| 701 | }
|
---|
| 702 |
|
---|
| 703 | /**
|
---|
| 704 | * Put or replace a double value. If the index is greater than the length of
|
---|
| 705 | * the JSONArray, then null elements will be added as necessary to pad it
|
---|
| 706 | * out.
|
---|
| 707 | *
|
---|
| 708 | * @param index
|
---|
| 709 | * The subscript.
|
---|
| 710 | * @param value
|
---|
| 711 | * A double value.
|
---|
| 712 | * @return this.
|
---|
| 713 | * @throws JSONException
|
---|
| 714 | * If the index is negative or if the value is not finite.
|
---|
| 715 | */
|
---|
| 716 | public JSONArray put(int index, double value) throws JSONException {
|
---|
| 717 | this.put(index, new Double(value));
|
---|
| 718 | return this;
|
---|
| 719 | }
|
---|
| 720 |
|
---|
| 721 | /**
|
---|
| 722 | * Put or replace an int value. If the index is greater than the length of
|
---|
| 723 | * the JSONArray, then null elements will be added as necessary to pad it
|
---|
| 724 | * out.
|
---|
| 725 | *
|
---|
| 726 | * @param index
|
---|
| 727 | * The subscript.
|
---|
| 728 | * @param value
|
---|
| 729 | * An int value.
|
---|
| 730 | * @return this.
|
---|
| 731 | * @throws JSONException
|
---|
| 732 | * If the index is negative.
|
---|
| 733 | */
|
---|
| 734 | public JSONArray put(int index, int value) throws JSONException {
|
---|
| 735 | this.put(index, new Integer(value));
|
---|
| 736 | return this;
|
---|
| 737 | }
|
---|
| 738 |
|
---|
| 739 | /**
|
---|
| 740 | * Put or replace a long value. If the index is greater than the length of
|
---|
| 741 | * the JSONArray, then null elements will be added as necessary to pad it
|
---|
| 742 | * out.
|
---|
| 743 | *
|
---|
| 744 | * @param index
|
---|
| 745 | * The subscript.
|
---|
| 746 | * @param value
|
---|
| 747 | * A long value.
|
---|
| 748 | * @return this.
|
---|
| 749 | * @throws JSONException
|
---|
| 750 | * If the index is negative.
|
---|
| 751 | */
|
---|
| 752 | public JSONArray put(int index, long value) throws JSONException {
|
---|
| 753 | this.put(index, new Long(value));
|
---|
| 754 | return this;
|
---|
| 755 | }
|
---|
| 756 |
|
---|
| 757 | /**
|
---|
| 758 | * Put a value in the JSONArray, where the value will be a JSONObject that
|
---|
| 759 | * is produced from a Map.
|
---|
| 760 | *
|
---|
| 761 | * @param index
|
---|
| 762 | * The subscript.
|
---|
| 763 | * @param value
|
---|
| 764 | * The Map value.
|
---|
| 765 | * @return this.
|
---|
| 766 | * @throws JSONException
|
---|
| 767 | * If the index is negative or if the the value is an invalid
|
---|
| 768 | * number.
|
---|
| 769 | */
|
---|
[6615] | 770 | public JSONArray put(int index, Map<?, ?> value) throws JSONException {
|
---|
[6484] | 771 | this.put(index, new JSONObject(value));
|
---|
| 772 | return this;
|
---|
| 773 | }
|
---|
| 774 |
|
---|
| 775 | /**
|
---|
| 776 | * Put or replace an object value in the JSONArray. If the index is greater
|
---|
| 777 | * than the length of the JSONArray, then null elements will be added as
|
---|
| 778 | * necessary to pad it out.
|
---|
| 779 | *
|
---|
| 780 | * @param index
|
---|
| 781 | * The subscript.
|
---|
| 782 | * @param value
|
---|
| 783 | * The value to put into the array. The value should be a
|
---|
| 784 | * Boolean, Double, Integer, JSONArray, JSONObject, Long, or
|
---|
| 785 | * String, or the JSONObject.NULL object.
|
---|
| 786 | * @return this.
|
---|
| 787 | * @throws JSONException
|
---|
| 788 | * If the index is negative or if the the value is an invalid
|
---|
| 789 | * number.
|
---|
| 790 | */
|
---|
| 791 | public JSONArray put(int index, Object value) throws JSONException {
|
---|
| 792 | JSONObject.testValidity(value);
|
---|
| 793 | if (index < 0) {
|
---|
| 794 | throw new JSONException("JSONArray[" + index + "] not found.");
|
---|
| 795 | }
|
---|
| 796 | if (index < this.length()) {
|
---|
| 797 | this.myArrayList.set(index, value);
|
---|
| 798 | } else {
|
---|
| 799 | while (index != this.length()) {
|
---|
| 800 | this.put(JSONObject.NULL);
|
---|
| 801 | }
|
---|
| 802 | this.put(value);
|
---|
| 803 | }
|
---|
| 804 | return this;
|
---|
| 805 | }
|
---|
| 806 |
|
---|
| 807 | /**
|
---|
| 808 | * Remove an index and close the hole.
|
---|
| 809 | *
|
---|
| 810 | * @param index
|
---|
| 811 | * The index of the element to be removed.
|
---|
| 812 | * @return The value that was associated with the index, or null if there
|
---|
| 813 | * was no value.
|
---|
| 814 | */
|
---|
| 815 | public Object remove(int index) {
|
---|
| 816 | Object o = this.opt(index);
|
---|
| 817 | this.myArrayList.remove(index);
|
---|
| 818 | return o;
|
---|
| 819 | }
|
---|
| 820 |
|
---|
| 821 | /**
|
---|
| 822 | * Produce a JSONObject by combining a JSONArray of names with the values of
|
---|
| 823 | * this JSONArray.
|
---|
| 824 | *
|
---|
| 825 | * @param names
|
---|
| 826 | * A JSONArray containing a list of key strings. These will be
|
---|
| 827 | * paired with the values.
|
---|
| 828 | * @return A JSONObject, or null if there are no names or if this JSONArray
|
---|
| 829 | * has no values.
|
---|
| 830 | * @throws JSONException
|
---|
| 831 | * If any of the names are null.
|
---|
| 832 | */
|
---|
| 833 | public JSONObject toJSONObject(JSONArray names) throws JSONException {
|
---|
| 834 | if (names == null || names.length() == 0 || this.length() == 0) {
|
---|
| 835 | return null;
|
---|
| 836 | }
|
---|
| 837 | JSONObject jo = new JSONObject();
|
---|
| 838 | for (int i = 0; i < names.length(); i += 1) {
|
---|
| 839 | jo.put(names.getString(i), this.opt(i));
|
---|
| 840 | }
|
---|
| 841 | return jo;
|
---|
| 842 | }
|
---|
| 843 |
|
---|
| 844 | /**
|
---|
| 845 | * Make a JSON text of this JSONArray. For compactness, no unnecessary
|
---|
| 846 | * whitespace is added. If it is not possible to produce a syntactically
|
---|
| 847 | * correct JSON text then null will be returned instead. This could occur if
|
---|
| 848 | * the array contains an invalid number.
|
---|
| 849 | * <p>
|
---|
| 850 | * Warning: This method assumes that the data structure is acyclical.
|
---|
| 851 | *
|
---|
| 852 | * @return a printable, displayable, transmittable representation of the
|
---|
| 853 | * array.
|
---|
| 854 | */
|
---|
| 855 | public String toString() {
|
---|
| 856 | try {
|
---|
| 857 | return this.toString(0);
|
---|
| 858 | } catch (Exception e) {
|
---|
| 859 | return null;
|
---|
| 860 | }
|
---|
| 861 | }
|
---|
| 862 |
|
---|
| 863 | /**
|
---|
| 864 | * Make a prettyprinted JSON text of this JSONArray. Warning: This method
|
---|
| 865 | * assumes that the data structure is acyclical.
|
---|
| 866 | *
|
---|
| 867 | * @param indentFactor
|
---|
| 868 | * The number of spaces to add to each level of indentation.
|
---|
| 869 | * @return a printable, displayable, transmittable representation of the
|
---|
| 870 | * object, beginning with <code>[</code> <small>(left
|
---|
| 871 | * bracket)</small> and ending with <code>]</code>
|
---|
| 872 | * <small>(right bracket)</small>.
|
---|
| 873 | * @throws JSONException
|
---|
| 874 | */
|
---|
| 875 | public String toString(int indentFactor) throws JSONException {
|
---|
| 876 | StringWriter sw = new StringWriter();
|
---|
| 877 | synchronized (sw.getBuffer()) {
|
---|
| 878 | return this.write(sw, indentFactor, 0).toString();
|
---|
| 879 | }
|
---|
| 880 | }
|
---|
| 881 |
|
---|
| 882 | /**
|
---|
| 883 | * Write the contents of the JSONArray as JSON text to a writer. For
|
---|
| 884 | * compactness, no whitespace is added.
|
---|
| 885 | * <p>
|
---|
| 886 | * Warning: This method assumes that the data structure is acyclical.
|
---|
| 887 | *
|
---|
| 888 | * @return The writer.
|
---|
| 889 | * @throws JSONException
|
---|
| 890 | */
|
---|
| 891 | public Writer write(Writer writer) throws JSONException {
|
---|
| 892 | return this.write(writer, 0, 0);
|
---|
| 893 | }
|
---|
| 894 |
|
---|
| 895 | /**
|
---|
| 896 | * Write the contents of the JSONArray as JSON text to a writer. For
|
---|
| 897 | * compactness, no whitespace is added.
|
---|
| 898 | * <p>
|
---|
| 899 | * Warning: This method assumes that the data structure is acyclical.
|
---|
| 900 | *
|
---|
| 901 | * @param indentFactor
|
---|
| 902 | * The number of spaces to add to each level of indentation.
|
---|
| 903 | * @param indent
|
---|
| 904 | * The indention of the top level.
|
---|
| 905 | * @return The writer.
|
---|
| 906 | * @throws JSONException
|
---|
| 907 | */
|
---|
| 908 | Writer write(Writer writer, int indentFactor, int indent)
|
---|
| 909 | throws JSONException {
|
---|
| 910 | try {
|
---|
| 911 | boolean commanate = false;
|
---|
| 912 | int length = this.length();
|
---|
| 913 | writer.write('[');
|
---|
| 914 |
|
---|
| 915 | if (length == 1) {
|
---|
| 916 | JSONObject.writeValue(writer, this.myArrayList.get(0),
|
---|
| 917 | indentFactor, indent);
|
---|
| 918 | } else if (length != 0) {
|
---|
| 919 | final int newindent = indent + indentFactor;
|
---|
| 920 |
|
---|
| 921 | for (int i = 0; i < length; i += 1) {
|
---|
| 922 | if (commanate) {
|
---|
| 923 | writer.write(',');
|
---|
| 924 | }
|
---|
| 925 | if (indentFactor > 0) {
|
---|
| 926 | writer.write('\n');
|
---|
| 927 | }
|
---|
| 928 | JSONObject.indent(writer, newindent);
|
---|
| 929 | JSONObject.writeValue(writer, this.myArrayList.get(i),
|
---|
| 930 | indentFactor, newindent);
|
---|
| 931 | commanate = true;
|
---|
| 932 | }
|
---|
| 933 | if (indentFactor > 0) {
|
---|
| 934 | writer.write('\n');
|
---|
| 935 | }
|
---|
| 936 | JSONObject.indent(writer, indent);
|
---|
| 937 | }
|
---|
| 938 | writer.write(']');
|
---|
| 939 | return writer;
|
---|
| 940 | } catch (IOException e) {
|
---|
| 941 | throw new JSONException(e);
|
---|
| 942 | }
|
---|
| 943 | }
|
---|
| 944 | }
|
---|