001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 * 027 * This file is based on: 028 * org.json.JSONArray 029 * from the JSON in Java implementation. 030 * 031 * Copyright (c) 2002 JSON.org 032 * 033 * Permission is hereby granted, free of charge, to any person obtaining a copy 034 * of this software and associated documentation files (the "Software"), to deal 035 * in the Software without restriction, including without limitation the rights 036 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 037 * copies of the Software, and to permit persons to whom the Software is 038 * furnished to do so, subject to the following conditions: 039 * 040 * The above copyright notice and this permission notice shall be included in all 041 * copies or substantial portions of the Software. 042 * 043 * The Software shall be used for Good, not Evil. 044 * 045 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 046 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 047 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 048 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 049 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 050 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 051 * SOFTWARE. 052 */ 053 054package org.opencms.json; 055 056import java.io.IOException; 057import java.io.Writer; 058import java.lang.reflect.Array; 059import java.util.ArrayList; 060import java.util.Collection; 061import java.util.Iterator; 062import java.util.Map; 063 064/** 065 * A JSONArray is an ordered sequence of values. Its external text form is a 066 * string wrapped in square brackets with commas separating the values. The 067 * internal form is an object having <code>get</code> and <code>opt</code> 068 * methods for accessing the values by index, and <code>put</code> methods for 069 * adding or replacing values. The values can be any of these types: 070 * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>, 071 * <code>Number</code>, <code>String</code>, or the 072 * <code>JSONObject.NULL object</code>. 073 * <p> 074 * The constructor can convert a JSON text into a Java object. The 075 * <code>toString</code> method converts to JSON text. 076 * <p> 077 * A <code>get</code> method returns a value if one can be found, and throws an 078 * exception if one cannot be found. An <code>opt</code> method returns a 079 * default value instead of throwing an exception, and so is useful for 080 * obtaining optional values. 081 * <p> 082 * The generic <code>get()</code> and <code>opt()</code> methods return an 083 * object which you can cast or query for type. There are also typed 084 * <code>get</code> and <code>opt</code> methods that do type checking and type 085 * coersion for you. 086 * <p> 087 * The texts produced by the <code>toString</code> methods strictly conform to 088 * JSON syntax rules. The constructors are more forgiving in the texts they will 089 * accept: 090 * <ul> 091 * <li>An extra <code>,</code> <small>(comma)</small> may appear just 092 * before the closing bracket.</li> 093 * <li>The <code>null</code> value will be inserted when there 094 * is <code>,</code> <small>(comma)</small> elision.</li> 095 * <li>Strings may be quoted with <code>'</code> <small>(single 096 * quote)</small>.</li> 097 * <li>Strings do not need to be quoted at all if they do not begin with a quote 098 * or single quote, and if they do not contain leading or trailing spaces, 099 * and if they do not contain any of these characters: 100 * <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers 101 * and if they are not the reserved words <code>true</code>, 102 * <code>false</code>, or <code>null</code>.</li> 103 * <li>Values can be separated by <code>;</code> <small>(semicolon)</small> as 104 * well as by <code>,</code> <small>(comma)</small>.</li> 105 * <li>Numbers may have the <code>0-</code> <small>(octal)</small> or 106 * <code>0x-</code> <small>(hex)</small> prefix.</li> 107 * <li>Comments written in the slashshlash, slashstar, and hash conventions 108 * will be ignored.</li> 109 * </ul> 110 111 */ 112public class JSONArray { 113 114 /** 115 * The arrayList where the JSONArray's properties are kept. 116 */ 117 private ArrayList<Object> m_myArrayList; 118 119 /** 120 * Construct an empty JSONArray.<p> 121 */ 122 public JSONArray() { 123 124 m_myArrayList = new ArrayList<Object>(); 125 } 126 127 /** 128 * Construct a JSONArray from a Collection.<p> 129 * 130 * @param collection a Collection. 131 */ 132 public JSONArray(Collection<?> collection) { 133 134 m_myArrayList = (collection == null) ? new ArrayList<Object>() : new ArrayList<Object>(collection); 135 } 136 137 /** 138 * Construct a JSONArray from a collection of beans.<p> 139 * 140 * The collection should have Java Beans.<p> 141 * 142 * @param collection a collection 143 * @param includeSuperClass tell whether to include the super class properties 144 */ 145 146 public JSONArray(Collection<Object> collection, boolean includeSuperClass) { 147 148 m_myArrayList = new ArrayList<Object>(); 149 if (collection != null) { 150 for (Iterator<Object> iter = collection.iterator(); iter.hasNext();) { 151 m_myArrayList.add(new JSONObject(iter.next(), includeSuperClass)); 152 } 153 } 154 } 155 156 /** 157 * Construct a JSONArray from a JSONTokener.<p> 158 * 159 * @param x a JSONTokener 160 * @throws JSONException if there is a syntax error 161 */ 162 public JSONArray(JSONTokener x) 163 throws JSONException { 164 165 this(); 166 char c = x.nextClean(); 167 char q; 168 if (c == '[') { 169 q = ']'; 170 } else if (c == '(') { 171 q = ')'; 172 } else { 173 throw x.syntaxError("A JSONArray text must start with '['"); 174 } 175 if (x.nextClean() == ']') { 176 return; 177 } 178 x.back(); 179 for (;;) { 180 if (x.nextClean() == ',') { 181 x.back(); 182 m_myArrayList.add(null); 183 } else { 184 x.back(); 185 m_myArrayList.add(x.nextValue()); 186 } 187 c = x.nextClean(); 188 switch (c) { 189 case ';': 190 case ',': 191 if (x.nextClean() == ']') { 192 return; 193 } 194 x.back(); 195 break; 196 case ']': 197 case ')': 198 if (q != c) { 199 throw x.syntaxError("Expected a '" + new Character(q) + "'"); 200 } 201 return; 202 default: 203 throw x.syntaxError("Expected a ',' or ']'"); 204 } 205 } 206 } 207 208 /** 209 * Construct a JSONArray from an array.<p> 210 * 211 * @param array an array 212 * @throws JSONException if not an array 213 */ 214 public JSONArray(Object array) 215 throws JSONException { 216 217 this(); 218 if (array.getClass().isArray()) { 219 int length = Array.getLength(array); 220 for (int i = 0; i < length; i += 1) { 221 this.put(Array.get(array, i)); 222 } 223 } else { 224 throw new JSONException("JSONArray initial value should be a string or collection or array."); 225 } 226 } 227 228 /** 229 * Construct a JSONArray from an array with a bean.<p> 230 * 231 * The array should have Java Beans.<p> 232 * 233 * @param array an array 234 * @param includeSuperClass tell whether to include the super class properties 235 * @throws JSONException if not an array 236 */ 237 public JSONArray(Object array, boolean includeSuperClass) 238 throws JSONException { 239 240 this(); 241 if (array.getClass().isArray()) { 242 int length = Array.getLength(array); 243 for (int i = 0; i < length; i += 1) { 244 this.put(new JSONObject(Array.get(array, i), includeSuperClass)); 245 } 246 } else { 247 throw new JSONException("JSONArray initial value should be a string or collection or array."); 248 } 249 } 250 251 /** 252 * Construct a JSONArray from a source JSON text.<p> 253 * 254 * @param source a string that begins with 255 * <code>[</code> <small>(left bracket)</small> 256 * and ends with <code>]</code> <small>(right bracket)</small> 257 * @throws JSONException if there is a syntax error 258 */ 259 public JSONArray(String source) 260 throws JSONException { 261 262 this(new JSONTokener(source)); 263 } 264 265 /** 266 * Check if this array contains the given string value.<p> 267 * 268 * @param value the value to check 269 * 270 * @return <code>true</code> if found, <code>false</code> if not 271 */ 272 public boolean containsString(String value) { 273 274 return m_myArrayList.contains(value); 275 } 276 277 /** 278 * Get the object value associated with an index.<p> 279 * 280 * @param index the index must be between 0 and length() - 1 281 * @return an object value 282 * @throws JSONException if there is no value for the index 283 */ 284 public Object get(int index) throws JSONException { 285 286 Object o = opt(index); 287 if (o == null) { 288 throw new JSONException("JSONArray[" + index + "] not found."); 289 } 290 return o; 291 } 292 293 /** 294 * Get the boolean value associated with an index.<p> 295 * 296 * The string values "true" and "false" are converted to boolean.<p> 297 * 298 * @param index the index must be between 0 and length() - 1 299 * @return the truth 300 * @throws JSONException if there is no value for the index or if the value is not convertable to boolean 301 */ 302 public boolean getBoolean(int index) throws JSONException { 303 304 Object o = get(index); 305 if (o.equals(Boolean.FALSE) || ((o instanceof String) && ((String)o).equalsIgnoreCase("false"))) { 306 return false; 307 } else if (o.equals(Boolean.TRUE) || ((o instanceof String) && ((String)o).equalsIgnoreCase("true"))) { 308 return true; 309 } 310 throw new JSONException("JSONArray[" + index + "] is not a Boolean."); 311 } 312 313 /** 314 * Get the double value associated with an index.<p> 315 * 316 * @param index the index must be between 0 and length() - 1 317 * @return the value 318 * @throws JSONException if the key is not found or if the value cannot be converted to a number 319 */ 320 public double getDouble(int index) throws JSONException { 321 322 Object o = get(index); 323 try { 324 return o instanceof Number ? ((Number)o).doubleValue() : Double.valueOf((String)o).doubleValue(); 325 } catch (Exception e) { 326 throw new JSONException("JSONArray[" + index + "] is not a number."); 327 } 328 } 329 330 /** 331 * Get the int value associated with an index.<p> 332 * 333 * @param index the index must be between 0 and length() - 1 334 * @return the value 335 * @throws JSONException if the key is not found or if the value cannot be converted to a number 336 */ 337 public int getInt(int index) throws JSONException { 338 339 Object o = get(index); 340 return o instanceof Number ? ((Number)o).intValue() : (int)getDouble(index); 341 } 342 343 /** 344 * Get the JSONArray associated with an index.<p> 345 * 346 * @param index the index must be between 0 and length() - 1 347 * @return a JSONArray value 348 * @throws JSONException if there is no value for the index or if the value is not a JSONArray 349 */ 350 public JSONArray getJSONArray(int index) throws JSONException { 351 352 Object o = get(index); 353 if (o instanceof JSONArray) { 354 return (JSONArray)o; 355 } 356 throw new JSONException("JSONArray[" + index + "] is not a JSONArray."); 357 } 358 359 /** 360 * Get the JSONObject associated with an index.<p> 361 * 362 * @param index the index must be between 0 and length() - 1 363 * @return a JSONObject value 364 * @throws JSONException if there is no value for the index or if the value is not a JSONObject 365 */ 366 public JSONObject getJSONObject(int index) throws JSONException { 367 368 Object o = get(index); 369 if (o instanceof JSONObject) { 370 return (JSONObject)o; 371 } 372 throw new JSONException("JSONArray[" + index + "] is not a JSONObject."); 373 } 374 375 /** 376 * Get the long value associated with an index.<p> 377 * 378 * @param index the index must be between 0 and length() - 1 379 * @return the value 380 * @throws JSONException if the key is not found or if the value cannot be converted to a number 381 */ 382 public long getLong(int index) throws JSONException { 383 384 Object o = get(index); 385 return o instanceof Number ? ((Number)o).longValue() : (long)getDouble(index); 386 } 387 388 /** 389 * Get the string associated with an index.<p> 390 * 391 * @param index the index must be between 0 and length() - 1 392 * @return a string value 393 * @throws JSONException if there is no value for the index 394 */ 395 public String getString(int index) throws JSONException { 396 397 return get(index).toString(); 398 } 399 400 /** 401 * Determine if the value is null.<p> 402 * 403 * @param index the index must be between 0 and length() - 1 404 * @return true if the value at the index is null, or if there is no value 405 */ 406 public boolean isNull(int index) { 407 408 return JSONObject.NULL.equals(opt(index)); 409 } 410 411 /** 412 * Make a string from the contents of this JSONArray.<p> 413 * 414 * The <code>separator</code> string is inserted between each element.<p> 415 * 416 * Warning: This method assumes that the data structure is acyclical.<p> 417 * 418 * @param separator a string that will be inserted between the elements 419 * @return a string 420 * @throws JSONException if the array contains an invalid number 421 */ 422 public String join(String separator) throws JSONException { 423 424 int len = length(); 425 StringBuffer sb = new StringBuffer(); 426 427 for (int i = 0; i < len; i += 1) { 428 if (i > 0) { 429 sb.append(separator); 430 } 431 sb.append(JSONObject.valueToString(m_myArrayList.get(i))); 432 } 433 return sb.toString(); 434 } 435 436 /** 437 * Get the number of elements in the JSONArray, included nulls.<p> 438 * 439 * @return the length (or size) 440 */ 441 public int length() { 442 443 return m_myArrayList.size(); 444 } 445 446 /** 447 * Get the optional object value associated with an index.<p> 448 * 449 * @param index the index must be between 0 and length() - 1 450 * @return an object value, or null if there is no object at that index 451 */ 452 public Object opt(int index) { 453 454 return ((index < 0) || (index >= length())) ? null : m_myArrayList.get(index); 455 } 456 457 /** 458 * Get the optional boolean value associated with an index.<p> 459 * 460 * It returns false if there is no value at that index, 461 * or if the value is not Boolean.TRUE or the String "true".<p> 462 * 463 * @param index the index must be between 0 and length() - 1 464 * @return the truth 465 */ 466 public boolean optBoolean(int index) { 467 468 return optBoolean(index, false); 469 } 470 471 /** 472 * Get the optional boolean value associated with an index.<p> 473 * 474 * It returns the defaultValue if there is no value at that index or if 475 * it is not a Boolean or the String "true" or "false" (case insensitive).<p> 476 * 477 * @param index the index must be between 0 and length() - 1 478 * @param defaultValue a boolean default 479 * @return the truth 480 */ 481 public boolean optBoolean(int index, boolean defaultValue) { 482 483 try { 484 return getBoolean(index); 485 } catch (Exception e) { 486 return defaultValue; 487 } 488 } 489 490 /** 491 * Get the optional double value associated with an index.<p> 492 * 493 * NaN is returned if there is no value for the index, 494 * or if the value is not a number and cannot be converted to a number.<p> 495 * 496 * @param index the index must be between 0 and length() - 1 497 * @return the value 498 */ 499 public double optDouble(int index) { 500 501 return optDouble(index, Double.NaN); 502 } 503 504 /** 505 * Get the optional double value associated with an index.<p> 506 * 507 * The defaultValue is returned if there is no value for the index, 508 * or if the value is not a number and cannot be converted to a number.<p> 509 * 510 * @param index the index must be between 0 and length() - 1 511 * @param defaultValue the default value 512 * @return the value 513 */ 514 public double optDouble(int index, double defaultValue) { 515 516 try { 517 return getDouble(index); 518 } catch (Exception e) { 519 return defaultValue; 520 } 521 } 522 523 /** 524 * Get the optional int value associated with an index.<p> 525 * 526 * Zero is returned if there is no value for the index, 527 * or if the value is not a number and cannot be converted to a number.<p> 528 * 529 * @param index the index must be between 0 and length() - 1 530 * @return the value 531 */ 532 public int optInt(int index) { 533 534 return optInt(index, 0); 535 } 536 537 /** 538 * Get the optional int value associated with an index.<p> 539 * 540 * The defaultValue is returned if there is no value for the index, 541 * or if the value is not a number and cannot be converted to a number.<p> 542 * 543 * @param index the index must be between 0 and length() - 1 544 * @param defaultValue the default value 545 * @return the value 546 */ 547 public int optInt(int index, int defaultValue) { 548 549 try { 550 return getInt(index); 551 } catch (Exception e) { 552 return defaultValue; 553 } 554 } 555 556 /** 557 * Get the optional JSONArray associated with an index.<p> 558 * 559 * @param index the index must be between 0 and length() - 1 560 * @return aA JSONArray value, or null if the index has no value, or if the value is not a JSONArray 561 */ 562 public JSONArray optJSONArray(int index) { 563 564 Object o = opt(index); 565 return o instanceof JSONArray ? (JSONArray)o : null; 566 } 567 568 /** 569 * Get the optional JSONObject associated with an index.<p> 570 * 571 * Null is returned if the key is not found, or null if the index has 572 * no value, or if the value is not a JSONObject.<p> 573 * 574 * @param index the index must be between 0 and length() - 1 575 * @return a JSONObject value 576 */ 577 public JSONObject optJSONObject(int index) { 578 579 Object o = opt(index); 580 return o instanceof JSONObject ? (JSONObject)o : null; 581 } 582 583 /** 584 * Get the optional long value associated with an index.<p> 585 * 586 * Zero is returned if there is no value for the index, 587 * or if the value is not a number and cannot be converted to a number.<p> 588 * 589 * @param index the index must be between 0 and length() - 1 590 * @return the value 591 */ 592 public long optLong(int index) { 593 594 return optLong(index, 0); 595 } 596 597 /** 598 * Get the optional long value associated with an index.<p> 599 * 600 * The defaultValue is returned if there is no value for the index, 601 * or if the value is not a number and cannot be converted to a number.<p> 602 * 603 * @param index the index must be between 0 and length() - 1 604 * @param defaultValue the default value 605 * @return the value 606 */ 607 public long optLong(int index, long defaultValue) { 608 609 try { 610 return getLong(index); 611 } catch (Exception e) { 612 return defaultValue; 613 } 614 } 615 616 /** 617 * Get the optional string value associated with an index.<p> 618 * 619 * It returns an empty string if there is no value at that index. If the value 620 * is not a string and is not null, then it is coverted to a string.<p> 621 * 622 * @param index the index must be between 0 and length() - 1 623 * @return a String value 624 */ 625 public String optString(int index) { 626 627 return optString(index, ""); 628 } 629 630 /** 631 * Get the optional string associated with an index.<p> 632 * 633 * The defaultValue is returned if the key is not found.<p> 634 * 635 * @param index tThe index must be between 0 and length() - 1 636 * @param defaultValue the default value 637 * @return a String value 638 */ 639 public String optString(int index, String defaultValue) { 640 641 Object o = opt(index); 642 return o != null ? o.toString() : defaultValue; 643 } 644 645 /** 646 * Append a boolean value. This increases the array's length by one.<p> 647 * 648 * @param value a boolean value 649 * @return this 650 */ 651 public JSONArray put(boolean value) { 652 653 put(value ? Boolean.TRUE : Boolean.FALSE); 654 return this; 655 } 656 657 /** 658 * Put a value in the JSONArray, where the value will be a 659 * JSONArray which is produced from a Collection.<p> 660 * 661 * @param value a Collection value 662 * @return this 663 */ 664 public JSONArray put(Collection<Object> value) { 665 666 put(new JSONArray(value)); 667 return this; 668 } 669 670 /** 671 * Append a double value. This increases the array's length by one.<p> 672 * 673 * @param value a double value 674 * @throws JSONException if the value is not finite 675 * @return this 676 */ 677 public JSONArray put(double value) throws JSONException { 678 679 Double d = new Double(value); 680 JSONObject.testValidity(d); 681 put(d); 682 return this; 683 } 684 685 /** 686 * Append an int value. This increases the array's length by one.<p> 687 * 688 * @param value an int value 689 * @return this 690 */ 691 public JSONArray put(int value) { 692 693 put(new Integer(value)); 694 return this; 695 } 696 697 /** 698 * Put or replace a boolean value in the JSONArray. If the index is greater 699 * than the length of the JSONArray, then null elements will be added as 700 * necessary to pad it out.<p> 701 * 702 * @param index the index 703 * @param value a boolean value 704 * @return this 705 * @throws JSONException if the index is negative 706 */ 707 public JSONArray put(int index, boolean value) throws JSONException { 708 709 put(index, value ? Boolean.TRUE : Boolean.FALSE); 710 return this; 711 } 712 713 /** 714 * Put a value in the JSONArray, where the value will be a 715 * JSONArray which is produced from a Collection.<p> 716 * 717 * @param index the index must be between 0 and length() - 1 718 * @param value a Collection value 719 * @return this 720 * @throws JSONException if the index is negative or if the value is 721 * not finite 722 */ 723 public JSONArray put(int index, Collection<Object> value) throws JSONException { 724 725 put(index, new JSONArray(value)); 726 return this; 727 } 728 729 /** 730 * Put or replace a double value. If the index is greater than the length of 731 * the JSONArray, then null elements will be added as necessary to pad 732 * it out.<p> 733 * 734 * @param index the index 735 * @param value a double value 736 * @return this 737 * @throws JSONException if the index is negative or if the value is 738 * not finite 739 */ 740 public JSONArray put(int index, double value) throws JSONException { 741 742 put(index, new Double(value)); 743 return this; 744 } 745 746 /** 747 * Put or replace an int value. If the index is greater than the length of 748 * the JSONArray, then null elements will be added as necessary to pad 749 * it out.<p> 750 * 751 * @param index the index 752 * @param value an int value 753 * @return this 754 * @throws JSONException if the index is negative 755 */ 756 public JSONArray put(int index, int value) throws JSONException { 757 758 put(index, new Integer(value)); 759 return this; 760 } 761 762 /** 763 * Put or replace a long value. If the index is greater than the length of 764 * the JSONArray, then null elements will be added as necessary to pad 765 * it out.<p> 766 * 767 * @param index the index 768 * @param value a long value 769 * @return this 770 * @throws JSONException if the index is negative 771 */ 772 public JSONArray put(int index, long value) throws JSONException { 773 774 put(index, new Long(value)); 775 return this; 776 } 777 778 /** 779 * Put a value in the JSONArray, where the value will be a 780 * JSONObject which is produced from a Map.<p> 781 * 782 * @param index the index must be between 0 and length() - 1 783 * @param value the Map value 784 * @return this 785 * @throws JSONException if the index is negative or if the the value is 786 * an invalid number 787 */ 788 public JSONArray put(int index, Map<?, ?> value) throws JSONException { 789 790 put(index, new JSONObject(value)); 791 return this; 792 } 793 794 /** 795 * Put or replace an object value in the JSONArray. If the index is greater 796 * than the length of the JSONArray, then null elements will be added as 797 * necessary to pad it out.<p> 798 * 799 * @param index the index 800 * @param value the value to put into the array. The value should be a 801 * Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the 802 * JSONObject.NULL object 803 * @return this 804 * @throws JSONException if the index is negative or if the the value is 805 * an invalid number 806 */ 807 public JSONArray put(int index, Object value) throws JSONException { 808 809 JSONObject.testValidity(value); 810 if (index < 0) { 811 throw new JSONException("JSONArray[" + index + "] not found."); 812 } 813 if (index < length()) { 814 m_myArrayList.set(index, value); 815 } else { 816 while (index != length()) { 817 put(JSONObject.NULL); 818 } 819 put(value); 820 } 821 return this; 822 } 823 824 /** 825 * Append an long value. This increases the array's length by one.<p> 826 * 827 * @param value a long value 828 * @return this 829 */ 830 public JSONArray put(long value) { 831 832 put(new Long(value)); 833 return this; 834 } 835 836 /** 837 * Put a value in the JSONArray, where the value will be a 838 * JSONObject which is produced from a Map.<p> 839 * 840 * @param value a Map value 841 * @return this 842 */ 843 public JSONArray put(Map<?, ?> value) { 844 845 put(new JSONObject(value)); 846 return this; 847 } 848 849 /** 850 * Append an object value. This increases the array's length by one.<p> 851 * 852 * @param value an object value. The value should be a 853 * Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the 854 * JSONObject.NULL object 855 * @return this 856 */ 857 public JSONArray put(Object value) { 858 859 m_myArrayList.add(value); 860 return this; 861 } 862 863 /** 864 * Produce a JSONObject by combining a JSONArray of names with the values 865 * of this JSONArray.<p> 866 * 867 * @param names a JSONArray containing a list of key strings. These will be 868 * paired with the values 869 * @return a JSONObject, or null if there are no names or if this JSONArray 870 * has no values 871 * @throws JSONException if any of the names are null 872 */ 873 public JSONObject toJSONObject(JSONArray names) throws JSONException { 874 875 if ((names == null) || (names.length() == 0) || (length() == 0)) { 876 return null; 877 } 878 JSONObject jo = new JSONObject(); 879 for (int i = 0; i < names.length(); i += 1) { 880 jo.put(names.getString(i), opt(i)); 881 } 882 return jo; 883 } 884 885 /** 886 * Make a JSON text of this JSONArray.<p> 887 * 888 * For compactness, no unnecessary whitespace is added. If it is not possible to produce a 889 * syntactically correct JSON text then null will be returned instead. This 890 * could occur if the array contains an invalid number.<p> 891 * 892 * Warning: This method assumes that the data structure is acyclical.<p> 893 * 894 * @return a printable, displayable, transmittable representation of the array 895 */ 896 @Override 897 public String toString() { 898 899 try { 900 return '[' + join(",") + ']'; 901 } catch (Exception e) { 902 return null; 903 } 904 } 905 906 /** 907 * Make a pretty printed JSON text of this JSONArray.<p> 908 * 909 * Warning: This method assumes that the data structure is acyclical.<p> 910 * 911 * @param indentFactor the number of spaces to add to each level of 912 * indentation 913 * @return a printable, displayable, transmittable 914 * representation of the object, beginning 915 * with <code>[</code> <small>(left bracket)</small> and ending 916 * with <code>]</code> <small>(right bracket)</small> 917 * @throws JSONException if something goes wrong 918 */ 919 public String toString(int indentFactor) throws JSONException { 920 921 return toString(indentFactor, 0); 922 } 923 924 /** 925 * Write the contents of the JSONArray as JSON text to a writer.<p> 926 * 927 * For compactness, no whitespace is added. 928 * <p> 929 * Warning: This method assumes that the data structure is acyclical.<p> 930 * 931 * @param writer the writer to write the contents to 932 * @return the writer 933 * @throws JSONException if something goes wrong 934 */ 935 public Writer write(Writer writer) throws JSONException { 936 937 try { 938 boolean b = false; 939 int len = length(); 940 941 writer.write('['); 942 943 for (int i = 0; i < len; i += 1) { 944 if (b) { 945 writer.write(','); 946 } 947 Object v = m_myArrayList.get(i); 948 if (v instanceof JSONObject) { 949 ((JSONObject)v).write(writer); 950 } else if (v instanceof JSONArray) { 951 ((JSONArray)v).write(writer); 952 } else { 953 writer.write(JSONObject.valueToString(v)); 954 } 955 b = true; 956 } 957 writer.write(']'); 958 return writer; 959 } catch (IOException e) { 960 throw new JSONException(e); 961 } 962 } 963 964 /** 965 * Make a pretty printed JSON text of this JSONArray.<p> 966 * 967 * Warning: This method assumes that the data structure is acyclical.<p> 968 * 969 * @param indentFactor the number of spaces to add to each level of 970 * indentation 971 * @param indent the indention of the top level 972 * @return a printable, displayable, transmittable 973 * representation of the array 974 * @throws JSONException if something goes wrong 975 */ 976 String toString(int indentFactor, int indent) throws JSONException { 977 978 int len = length(); 979 if (len == 0) { 980 return "[]"; 981 } 982 int i; 983 StringBuffer sb = new StringBuffer("["); 984 if (len == 1) { 985 sb.append(JSONObject.valueToString(m_myArrayList.get(0), indentFactor, indent)); 986 } else { 987 int newindent = indent + indentFactor; 988 sb.append('\n'); 989 for (i = 0; i < len; i += 1) { 990 if (i > 0) { 991 sb.append(",\n"); 992 } 993 for (int j = 0; j < newindent; j += 1) { 994 sb.append(' '); 995 } 996 sb.append(JSONObject.valueToString(m_myArrayList.get(i), indentFactor, newindent)); 997 } 998 sb.append('\n'); 999 for (i = 0; i < indent; i += 1) { 1000 sb.append(' '); 1001 } 1002 } 1003 sb.append(']'); 1004 return sb.toString(); 1005 } 1006}