001 package net.sourceforge.javajson; 002 003 import java.io.InputStream; 004 import java.io.Reader; 005 import java.io.StringReader; 006 import java.util.ArrayList; 007 import java.util.Iterator; 008 import java.util.List; 009 010 import net.sourceforge.javajson.parser.ASTparse; 011 import net.sourceforge.javajson.parser.JsonParser; 012 import net.sourceforge.javajson.parser.ParseException; 013 import net.sourceforge.javajson.parser.TokenMgrError; 014 015 public class JsonArray implements Iterable<JsonValue> { 016 private List<JsonValue> list; 017 018 /** Parses a string to a json object. */ 019 public static JsonArray parse(String input) throws JsonException { 020 return parse(new StringReader(input)); 021 } 022 023 /** Parses a string to a json object. */ 024 public static JsonArray parse(Reader reader) throws JsonException { 025 try { 026 JsonParser parser = new JsonParser(reader); 027 ASTparse root = (ASTparse) parser.parse(); 028 return root.getJsonArray(); 029 } catch (ParseException pe) { 030 throw new JsonException(pe); 031 } catch (TokenMgrError error) { 032 throw new JsonException(error); 033 } 034 } 035 036 /** Parses a string to a json object. */ 037 public static JsonArray parse(InputStream is) throws JsonException { 038 try { 039 JsonParser parser = new JsonParser(is); 040 ASTparse root = (ASTparse) parser.parse(); 041 return root.getJsonArray(); 042 } catch (ParseException pe) { 043 throw new JsonException(pe); 044 } catch (TokenMgrError error) { 045 throw new JsonException(error); 046 } 047 } 048 049 public JsonArray() { 050 list = new ArrayList<JsonValue>(); 051 } 052 053 public JsonArray add(boolean value) { 054 list.add(new JsonValue(value)); 055 return this; 056 } 057 058 public JsonArray add(double value) { 059 list.add(new JsonValue(value)); 060 return this; 061 } 062 063 public JsonArray add(float value) { 064 list.add(new JsonValue(value)); 065 return this; 066 } 067 068 public JsonArray add(int value) { 069 list.add(new JsonValue(value)); 070 return this; 071 } 072 073 public JsonArray add(long value) { 074 list.add(new JsonValue(value)); 075 return this; 076 } 077 078 public JsonArray add(JsonArray value) { 079 list.add(new JsonValue(value)); 080 return this; 081 } 082 083 public JsonArray add(JsonObject value) { 084 list.add(new JsonValue(value)); 085 return this; 086 } 087 088 public JsonArray add(String value) { 089 list.add(new JsonValue(value)); 090 return this; 091 } 092 093 public JsonArray add(Object value) { 094 if (value instanceof Boolean) 095 add(((Boolean) value).booleanValue()); 096 else if (value instanceof Double) 097 add(((Double) value).doubleValue()); 098 else if (value instanceof Float) 099 add(((Float) value).floatValue()); 100 else if (value instanceof Integer) 101 add(((Integer) value).intValue()); 102 else if (value instanceof Long) 103 add(((Long) value).longValue()); 104 else if (value instanceof JsonArray) 105 add((JsonArray) value); 106 else if (value instanceof JsonObject) 107 add((JsonObject) value); 108 else if (value instanceof JsonValue) 109 list.add((JsonValue) value); 110 else if (value instanceof String) 111 add((String) value); 112 else if (value == null) 113 add((String) null); 114 else 115 throw new ClassCastException("Unrecognized class"); 116 return this; 117 } 118 119 /** 120 * @param index 121 * @throws ClassCastException 122 * if the value cannot be converted to a boolean 123 * @throws IndexOutOfBoundsException 124 * if its out of bounds 125 */ 126 public boolean getBoolean(int index) { 127 if (index >= 0 && index < list.size()) 128 return list.get(index).getBoolean(); 129 else 130 throw new IndexOutOfBoundsException(); 131 } 132 133 /** 134 * @throws ClassCastException 135 * if the value cannot be converted to a double 136 * @throws IndexOutOfBoundsException 137 * if its out of bounds 138 */ 139 public double getDouble(int index) { 140 if (index >= 0 && index < list.size()) 141 return list.get(index).getDouble(); 142 else 143 throw new IndexOutOfBoundsException(); 144 } 145 146 /** 147 * @throws ClassCastException 148 * if the value cannot be converted to a double 149 * @throws IndexOutOfBoundsException 150 * if its out of bounds 151 */ 152 public float getFloat(int index) { 153 if (index >= 0 && index < list.size()) 154 return list.get(index).getFloat(); 155 else 156 throw new IndexOutOfBoundsException(); 157 } 158 159 /** 160 * @throws ClassCastException 161 * if the value cannot be converted to a double 162 * @throws IndexOutOfBoundsException 163 * if its out of bounds 164 */ 165 public int getInt(int index) { 166 if (index >= 0 && index < list.size()) 167 return list.get(index).getInt(); 168 else 169 throw new IndexOutOfBoundsException(); 170 } 171 172 /** 173 * @throws ClassCastException 174 * if the value cannot be converted to a double 175 * @throws IndexOutOfBoundsException 176 * if its out of bounds 177 */ 178 public JsonArray getJsonArray(int index) { 179 if (index >= 0 && index < list.size()) 180 return list.get(index).getJsonArray(); 181 else 182 throw new IndexOutOfBoundsException(); 183 } 184 185 /** 186 * @throws ClassCastException 187 * if the value cannot be converted to a double 188 * @throws IndexOutOfBoundsException 189 * if its out of bounds 190 */ 191 public JsonObject getJsonObject(int index) { 192 if (index >= 0 && index < list.size()) 193 return list.get(index).getJsonObject(); 194 else 195 throw new IndexOutOfBoundsException(); 196 } 197 198 /** 199 * @throws ClassCastException 200 * if the value cannot be converted to a double 201 * @throws IndexOutOfBoundsException 202 * if its out of bounds 203 */ 204 public long getLong(int index) { 205 if (index >= 0 && index < list.size()) 206 return list.get(index).getLong(); 207 else 208 throw new IndexOutOfBoundsException(); 209 } 210 211 /** 212 * @throws IndexOutOfBoundsException 213 * if its out of bounds 214 */ 215 public String getString(int index) { 216 if (index >= 0 && index < list.size()) 217 return list.get(index).getString(); 218 else 219 throw new IndexOutOfBoundsException(); 220 } 221 222 /** 223 * Checks if the item at an index is a boolean. See 224 * {@link JsonValue#isBoolean()} for more information 225 * 226 * @param index 227 * The index of the array to check 228 * @return True if the object contains the item and is a boolean 229 * @throws IndexOutOfBoundsException 230 */ 231 public boolean isBoolean(int index) { 232 if (index >= 0 && index < list.size()) 233 return list.get(index).isBoolean(); 234 else 235 throw new IndexOutOfBoundsException(); 236 } 237 238 /** 239 * Checks if the item at an index is a double. See 240 * {@link JsonValue#isLong()} for more information 241 * 242 * @param index 243 * The index of the array to check 244 * @return True if the object contains the item and is a double 245 * @throws IndexOutOfBoundsException 246 */ 247 public boolean isDouble(int index) { 248 if (index >= 0 && index < list.size()) 249 return list.get(index).isDouble(); 250 else 251 throw new IndexOutOfBoundsException(); 252 } 253 254 /** 255 * Checks if the item at an index is a float. See 256 * {@link JsonValue#isLong()} for more information 257 * 258 * @param index 259 * The index of the array to check 260 * @return True if the object contains the item and is a float 261 * @throws IndexOutOfBoundsException 262 */ 263 public boolean isFloat(int index) { 264 if (index >= 0 && index < list.size()) 265 return list.get(index).isFloat(); 266 else 267 throw new IndexOutOfBoundsException(); 268 } 269 270 /** 271 * Checks if the item at an index is a int. See 272 * {@link JsonValue#isLong()} for more information 273 * 274 * @param index 275 * The index of the array to check 276 * @return True if the object contains the item and is a int 277 * @throws IndexOutOfBoundsException 278 */ 279 public boolean isInt(int index) { 280 if (index >= 0 && index < list.size()) 281 return list.get(index).isInt(); 282 else 283 throw new IndexOutOfBoundsException(); 284 } 285 286 /** 287 * Checks if the item at an index is an array. See 288 * {@link JsonValue#isJsonArray()} for more information 289 * 290 * @param index 291 * The index of the array to check 292 * @return True if the object contains the item and is a json array 293 * @throws IndexOutOfBoundsException 294 */ 295 public boolean isJsonArray(int index) { 296 if (index >= 0 && index < list.size()) 297 return list.get(index).isJsonArray(); 298 else 299 throw new IndexOutOfBoundsException(); 300 } 301 302 /** 303 * Checks if the item at an index is an object. See 304 * {@link JsonValue#isJsonObject()} for more information 305 * 306 * @param index 307 * The index of the array to check 308 * @return True if the object contains the item and is a json object 309 * @throws IndexOutOfBoundsException 310 */ 311 public boolean isJsonObject(int index) { 312 if (index >= 0 && index < list.size()) 313 return list.get(index).isJsonObject(); 314 else 315 throw new IndexOutOfBoundsException(); 316 } 317 318 /** 319 * Checks if the item at an index is a long. See 320 * {@link JsonValue#isLong()} for more information 321 * 322 * @param index 323 * The index of the array to check 324 * @return True if the object contains the item and is a long 325 * @throws IndexOutOfBoundsException 326 */ 327 public boolean isLong(int index) { 328 if (index >= 0 && index < list.size()) 329 return list.get(index).isLong(); 330 else 331 throw new IndexOutOfBoundsException(); 332 } 333 334 /** 335 * Checks if the item at an index is an string. See 336 * {@link JsonValue#isString()} for more information 337 * 338 * @param index 339 * The index of the array to check 340 * @return True if the object contains the item and is a json string 341 * @throws IndexOutOfBoundsException 342 */ 343 public boolean isString(int index) { 344 if (index >= 0 && index < list.size()) 345 return list.get(index).isString(); 346 else 347 throw new IndexOutOfBoundsException(); 348 } 349 350 /** 351 * Checks if the structure of this json array is similar to that of another 352 * array. It simply checks that each item exists in both objects (same 353 * length of array) and that subobjects (json object or json array) are also 354 * similar. 355 * 356 * @param obj 357 * @return 358 */ 359 public boolean isSimilar(JsonArray obj) { 360 if (obj == null) 361 return false; 362 363 if (obj.size() != size()) 364 return false; 365 366 for (int i = 0; i < size(); i++) { 367 if (!list.get(i).isSimilar(obj.list.get(i))) 368 return false; 369 } 370 371 return true; 372 } 373 374 public Iterator<JsonValue> iterator() { 375 return list.iterator(); 376 } 377 378 public int size() { 379 return list.size(); 380 } 381 382 @Override 383 public String toString() { 384 StringBuffer sb = new StringBuffer(); 385 boolean hadSome = false; 386 sb.append("["); 387 for (JsonValue val : list) { 388 if (hadSome) 389 sb.append(","); 390 sb.append(val); 391 hadSome = true; 392 } 393 sb.append("]"); 394 return sb.toString(); 395 } 396 397 /** 398 * Returns a nicely formatted string 399 * 400 * @param spacing 401 * @return 402 */ 403 public String toString(int spacing) { 404 return toString(spacing, 0); 405 } 406 407 /** 408 * Called by toString(int) to keep track of the spacing 409 * 410 * @param spacing 411 * @param margin 412 * @return 413 */ 414 protected String toString(int spacing, int margin) { 415 if (list.isEmpty()) 416 return "[]"; 417 else { 418 StringBuffer sb = new StringBuffer(); 419 boolean hadSome = false; 420 sb.append("[\n"); 421 for (JsonValue val : list) { 422 if (hadSome) 423 sb.append(",\n"); 424 sb.append(getSpaces(margin + spacing)); 425 sb.append(val.toString(spacing, margin + spacing)); 426 hadSome = true; 427 } 428 sb.append("\n"); 429 sb.append(getSpaces(margin)); 430 sb.append("]"); 431 432 return sb.toString(); 433 } 434 } 435 436 private String getSpaces(int spaces) { 437 StringBuffer sb = new StringBuffer(); 438 for (int i = 0; i < spaces; i++) 439 sb.append(" "); 440 return sb.toString(); 441 } 442 }