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