Added: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONArray.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONArray.java?rev=1220771&view=auto
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONArray.java
 (added)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONArray.java
 Mon Dec 19 14:34:44 2011
@@ -0,0 +1,1092 @@
+package org.apache.wicket.ajax.json;
+
+/*
+ Copyright (c) 2002 JSON.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ The Software shall be used for Good, not Evil.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+ */
+
+import java.io.IOException;
+import java.io.Writer;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * A JSONArray is an ordered sequence of values. Its external text form is a 
string wrapped in
+ * square brackets with commas separating the values. The internal form is an 
object having
+ * <code>get</code> and <code>opt</code> methods for accessing the values by 
index, and
+ * <code>put</code> methods for adding or replacing values. The values can be 
any of these types:
+ * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>, 
<code>Number</code>,
+ * <code>String</code>, or the <code>JSONObject.NULL object</code>.
+ * <p>
+ * The constructor can convert a JSON text into a Java object. The 
<code>toString</code> method
+ * converts to JSON text.
+ * <p>
+ * A <code>get</code> method returns a value if one can be found, and throws 
an exception if one
+ * cannot be found. An <code>opt</code> method returns a default value instead 
of throwing an
+ * exception, and so is useful for obtaining optional values.
+ * <p>
+ * The generic <code>get()</code> and <code>opt()</code> methods return an 
object which you can cast
+ * or query for type. There are also typed <code>get</code> and 
<code>opt</code> methods that do
+ * type checking and type coercion for you.
+ * <p>
+ * The texts produced by the <code>toString</code> methods strictly conform to 
JSON syntax rules.
+ * The constructors are more forgiving in the texts they will accept:
+ * <ul>
+ * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just 
before the closing
+ * bracket.</li>
+ * <li>The <code>null</code> value will be inserted when there is 
<code>,</code>
+ * &nbsp;<small>(comma)</small> elision.</li>
+ * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single 
quote)</small>.</li>
+ * <li>Strings do not need to be quoted at all if they do not begin with a 
quote or single quote,
+ * and if they do not contain leading or trailing spaces, and if they do not 
contain any of these
+ * characters: <code>{ } [ ] / \ : , = ; #</code> and if they do not look like 
numbers and if they
+ * are not the reserved words <code>true</code>, <code>false</code>, or 
<code>null</code>.</li>
+ * <li>Values can be separated by <code>;</code> <small>(semicolon)</small> as 
well as by
+ * <code>,</code> <small>(comma)</small>.</li>
+ * <li>Numbers may have the <code>0x-</code> <small>(hex)</small> prefix.</li>
+ * </ul>
+ * 
+ * @author JSON.org
+ * @version 2011-08-25
+ */
+public class JSONArray
+{
+
+
+       /**
+        * The arrayList where the JSONArray's properties are kept.
+        */
+       private ArrayList myArrayList;
+
+
+       /**
+        * Construct an empty JSONArray.
+        */
+       public JSONArray()
+       {
+               myArrayList = new ArrayList();
+       }
+
+       /**
+        * Construct a JSONArray from a JSONTokener.
+        * 
+        * @param x
+        *            A JSONTokener
+        * @throws JSONException
+        *             If there is a syntax error.
+        */
+       public JSONArray(JSONTokener x) throws JSONException
+       {
+               this();
+               if (x.nextClean() != '[')
+               {
+                       throw x.syntaxError("A JSONArray text must start with 
'['");
+               }
+               if (x.nextClean() != ']')
+               {
+                       x.back();
+                       for (;;)
+                       {
+                               if (x.nextClean() == ',')
+                               {
+                                       x.back();
+                                       myArrayList.add(JSONObject.NULL);
+                               }
+                               else
+                               {
+                                       x.back();
+                                       myArrayList.add(x.nextValue());
+                               }
+                               switch (x.nextClean())
+                               {
+                                       case ';' :
+                                       case ',' :
+                                               if (x.nextClean() == ']')
+                                               {
+                                                       return;
+                                               }
+                                               x.back();
+                                               break;
+                                       case ']' :
+                                               return;
+                                       default :
+                                               throw x.syntaxError("Expected a 
',' or ']'");
+                               }
+                       }
+               }
+       }
+
+
+       /**
+        * Construct a JSONArray from a source JSON text.
+        * 
+        * @param source
+        *            A string that begins with 
<code>[</code>&nbsp;<small>(left bracket)</small> and
+        *            ends with <code>]</code>&nbsp;<small>(right 
bracket)</small>.
+        * @throws JSONException
+        *             If there is a syntax error.
+        */
+       public JSONArray(String source) throws JSONException
+       {
+               this(new JSONTokener(source));
+       }
+
+
+       /**
+        * Construct a JSONArray from a Collection.
+        * 
+        * @param collection
+        *            A Collection.
+        */
+       public JSONArray(Collection collection)
+       {
+               myArrayList = new ArrayList();
+               if (collection != null)
+               {
+                       Iterator iter = collection.iterator();
+                       while (iter.hasNext())
+                       {
+                               myArrayList.add(JSONObject.wrap(iter.next()));
+                       }
+               }
+       }
+
+
+       /**
+        * Construct a JSONArray from an array
+        * 
+        * @throws JSONException
+        *             If not an array.
+        */
+       public JSONArray(Object array) throws JSONException
+       {
+               this();
+               if (array.getClass().isArray())
+               {
+                       int length = Array.getLength(array);
+                       for (int i = 0; i < length; i += 1)
+                       {
+                               this.put(JSONObject.wrap(Array.get(array, i)));
+                       }
+               }
+               else
+               {
+                       throw new JSONException(
+                               "JSONArray initial value should be a string or 
collection or array.");
+               }
+       }
+
+
+       /**
+        * Get the object value associated with an index.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return An object value.
+        * @throws JSONException
+        *             If there is no value for the index.
+        */
+       public Object get(int index) throws JSONException
+       {
+               Object object = opt(index);
+               if (object == null)
+               {
+                       throw new JSONException("JSONArray[" + index + "] not 
found.");
+               }
+               return object;
+       }
+
+
+       /**
+        * Get the boolean value associated with an index. The string values 
"true" and "false" are
+        * converted to boolean.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return The truth.
+        * @throws JSONException
+        *             If there is no value for the index or if the value is 
not convertible to boolean.
+        */
+       public boolean getBoolean(int index) throws JSONException
+       {
+               Object object = get(index);
+               if (object.equals(Boolean.FALSE) ||
+                       (object instanceof String && 
((String)object).equalsIgnoreCase("false")))
+               {
+                       return false;
+               }
+               else if (object.equals(Boolean.TRUE) ||
+                       (object instanceof String && 
((String)object).equalsIgnoreCase("true")))
+               {
+                       return true;
+               }
+               throw new JSONException("JSONArray[" + index + "] is not a 
boolean.");
+       }
+
+
+       /**
+        * Get the double value associated with an index.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return The value.
+        * @throws JSONException
+        *             If the key is not found or if the value cannot be 
converted to a number.
+        */
+       public double getDouble(int index) throws JSONException
+       {
+               Object object = get(index);
+               try
+               {
+                       return object instanceof Number ? 
((Number)object).doubleValue()
+                               : Double.parseDouble((String)object);
+               }
+               catch (Exception e)
+               {
+                       throw new JSONException("JSONArray[" + index + "] is 
not a number.");
+               }
+       }
+
+
+       /**
+        * Get the int value associated with an index.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return The value.
+        * @throws JSONException
+        *             If the key is not found or if the value is not a number.
+        */
+       public int getInt(int index) throws JSONException
+       {
+               Object object = get(index);
+               try
+               {
+                       return object instanceof Number ? 
((Number)object).intValue()
+                               : Integer.parseInt((String)object);
+               }
+               catch (Exception e)
+               {
+                       throw new JSONException("JSONArray[" + index + "] is 
not a number.");
+               }
+       }
+
+
+       /**
+        * Get the JSONArray associated with an index.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return A JSONArray value.
+        * @throws JSONException
+        *             If there is no value for the index. or if the value is 
not a JSONArray
+        */
+       public JSONArray getJSONArray(int index) throws JSONException
+       {
+               Object object = get(index);
+               if (object instanceof JSONArray)
+               {
+                       return (JSONArray)object;
+               }
+               throw new JSONException("JSONArray[" + index + "] is not a 
JSONArray.");
+       }
+
+
+       /**
+        * Get the JSONObject associated with an index.
+        * 
+        * @param index
+        *            subscript
+        * @return A JSONObject value.
+        * @throws JSONException
+        *             If there is no value for the index or if the value is 
not a JSONObject
+        */
+       public JSONObject getJSONObject(int index) throws JSONException
+       {
+               Object object = get(index);
+               if (object instanceof JSONObject)
+               {
+                       return (JSONObject)object;
+               }
+               throw new JSONException("JSONArray[" + index + "] is not a 
JSONObject.");
+       }
+
+
+       /**
+        * Get the long value associated with an index.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return The value.
+        * @throws JSONException
+        *             If the key is not found or if the value cannot be 
converted to a number.
+        */
+       public long getLong(int index) throws JSONException
+       {
+               Object object = get(index);
+               try
+               {
+                       return object instanceof Number ? 
((Number)object).longValue()
+                               : Long.parseLong((String)object);
+               }
+               catch (Exception e)
+               {
+                       throw new JSONException("JSONArray[" + index + "] is 
not a number.");
+               }
+       }
+
+
+       /**
+        * Get the string associated with an index.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return A string value.
+        * @throws JSONException
+        *             If there is no string value for the index.
+        */
+       public String getString(int index) throws JSONException
+       {
+               Object object = get(index);
+               if (object instanceof String)
+               {
+                       return (String)object;
+               }
+               throw new JSONException("JSONArray[" + index + "] not a 
string.");
+       }
+
+
+       /**
+        * Determine if the value is null.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return true if the value at the index is null, or if there is no 
value.
+        */
+       public boolean isNull(int index)
+       {
+               return JSONObject.NULL.equals(opt(index));
+       }
+
+
+       /**
+        * Make a string from the contents of this JSONArray. The 
<code>separator</code> string is
+        * inserted between each element. Warning: This method assumes that the 
data structure is
+        * acyclical.
+        * 
+        * @param separator
+        *            A string that will be inserted between the elements.
+        * @return a string.
+        * @throws JSONException
+        *             If the array contains an invalid number.
+        */
+       public String join(String separator) throws JSONException
+       {
+               int len = length();
+               StringBuffer sb = new StringBuffer();
+
+               for (int i = 0; i < len; i += 1)
+               {
+                       if (i > 0)
+                       {
+                               sb.append(separator);
+                       }
+                       sb.append(JSONObject.valueToString(myArrayList.get(i)));
+               }
+               return sb.toString();
+       }
+
+
+       /**
+        * Get the number of elements in the JSONArray, included nulls.
+        * 
+        * @return The length (or size).
+        */
+       public int length()
+       {
+               return myArrayList.size();
+       }
+
+
+       /**
+        * Get the optional object value associated with an index.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return An object value, or null if there is no object at that index.
+        */
+       public Object opt(int index)
+       {
+               return (index < 0 || index >= length()) ? null : 
myArrayList.get(index);
+       }
+
+
+       /**
+        * Get the optional boolean value associated with an index. It returns 
false if there is no
+        * value at that index, or if the value is not Boolean.TRUE or the 
String "true".
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return The truth.
+        */
+       public boolean optBoolean(int index)
+       {
+               return optBoolean(index, false);
+       }
+
+
+       /**
+        * Get the optional boolean value associated with an index. It returns 
the defaultValue if there
+        * is no value at that index or if it is not a Boolean or the String 
"true" or "false" (case
+        * insensitive).
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @param defaultValue
+        *            A boolean default.
+        * @return The truth.
+        */
+       public boolean optBoolean(int index, boolean defaultValue)
+       {
+               try
+               {
+                       return getBoolean(index);
+               }
+               catch (Exception e)
+               {
+                       return defaultValue;
+               }
+       }
+
+
+       /**
+        * Get the optional double value associated with an index. NaN is 
returned if there is no value
+        * for the index, or if the value is not a number and cannot be 
converted to a number.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return The value.
+        */
+       public double optDouble(int index)
+       {
+               return optDouble(index, Double.NaN);
+       }
+
+
+       /**
+        * Get the optional double value associated with an index. The 
defaultValue is returned if there
+        * is no value for the index, or if the value is not a number and 
cannot be converted to a
+        * number.
+        * 
+        * @param index
+        *            subscript
+        * @param defaultValue
+        *            The default value.
+        * @return The value.
+        */
+       public double optDouble(int index, double defaultValue)
+       {
+               try
+               {
+                       return getDouble(index);
+               }
+               catch (Exception e)
+               {
+                       return defaultValue;
+               }
+       }
+
+
+       /**
+        * Get the optional int value associated with an index. Zero is 
returned if there is no value
+        * for the index, or if the value is not a number and cannot be 
converted to a number.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return The value.
+        */
+       public int optInt(int index)
+       {
+               return optInt(index, 0);
+       }
+
+
+       /**
+        * Get the optional int value associated with an index. The 
defaultValue is returned if there is
+        * no value for the index, or if the value is not a number and cannot 
be converted to a number.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @param defaultValue
+        *            The default value.
+        * @return The value.
+        */
+       public int optInt(int index, int defaultValue)
+       {
+               try
+               {
+                       return getInt(index);
+               }
+               catch (Exception e)
+               {
+                       return defaultValue;
+               }
+       }
+
+
+       /**
+        * Get the optional JSONArray associated with an index.
+        * 
+        * @param index
+        *            subscript
+        * @return A JSONArray value, or null if the index has no value, or if 
the value is not a
+        *         JSONArray.
+        */
+       public JSONArray optJSONArray(int index)
+       {
+               Object o = opt(index);
+               return o instanceof JSONArray ? (JSONArray)o : null;
+       }
+
+
+       /**
+        * Get the optional JSONObject associated with an index. Null is 
returned if the key is not
+        * found, or null if the index has no value, or if the value is not a 
JSONObject.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return A JSONObject value.
+        */
+       public JSONObject optJSONObject(int index)
+       {
+               Object o = opt(index);
+               return o instanceof JSONObject ? (JSONObject)o : null;
+       }
+
+
+       /**
+        * Get the optional long value associated with an index. Zero is 
returned if there is no value
+        * for the index, or if the value is not a number and cannot be 
converted to a number.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return The value.
+        */
+       public long optLong(int index)
+       {
+               return optLong(index, 0);
+       }
+
+
+       /**
+        * Get the optional long value associated with an index. The 
defaultValue is returned if there
+        * is no value for the index, or if the value is not a number and 
cannot be converted to a
+        * number.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @param defaultValue
+        *            The default value.
+        * @return The value.
+        */
+       public long optLong(int index, long defaultValue)
+       {
+               try
+               {
+                       return getLong(index);
+               }
+               catch (Exception e)
+               {
+                       return defaultValue;
+               }
+       }
+
+
+       /**
+        * Get the optional string value associated with an index. It returns 
an empty string if there
+        * is no value at that index. If the value is not a string and is not 
null, then it is coverted
+        * to a string.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @return A String value.
+        */
+       public String optString(int index)
+       {
+               return optString(index, "");
+       }
+
+
+       /**
+        * Get the optional string associated with an index. The defaultValue 
is returned if the key is
+        * not found.
+        * 
+        * @param index
+        *            The index must be between 0 and length() - 1.
+        * @param defaultValue
+        *            The default value.
+        * @return A String value.
+        */
+       public String optString(int index, String defaultValue)
+       {
+               Object object = opt(index);
+               return JSONObject.NULL.equals(object) ? object.toString() : 
defaultValue;
+       }
+
+
+       /**
+        * Append a boolean value. This increases the array's length by one.
+        * 
+        * @param value
+        *            A boolean value.
+        * @return this.
+        */
+       public JSONArray put(boolean value)
+       {
+               put(value ? Boolean.TRUE : Boolean.FALSE);
+               return this;
+       }
+
+
+       /**
+        * Put a value in the JSONArray, where the value will be a JSONArray 
which is produced from a
+        * Collection.
+        * 
+        * @param value
+        *            A Collection value.
+        * @return this.
+        */
+       public JSONArray put(Collection value)
+       {
+               put(new JSONArray(value));
+               return this;
+       }
+
+
+       /**
+        * Append a double value. This increases the array's length by one.
+        * 
+        * @param value
+        *            A double value.
+        * @throws JSONException
+        *             if the value is not finite.
+        * @return this.
+        */
+       public JSONArray put(double value) throws JSONException
+       {
+               Double d = new Double(value);
+               JSONObject.testValidity(d);
+               put(d);
+               return this;
+       }
+
+
+       /**
+        * Append an int value. This increases the array's length by one.
+        * 
+        * @param value
+        *            An int value.
+        * @return this.
+        */
+       public JSONArray put(int value)
+       {
+               put(new Integer(value));
+               return this;
+       }
+
+
+       /**
+        * Append an long value. This increases the array's length by one.
+        * 
+        * @param value
+        *            A long value.
+        * @return this.
+        */
+       public JSONArray put(long value)
+       {
+               put(new Long(value));
+               return this;
+       }
+
+
+       /**
+        * Put a value in the JSONArray, where the value will be a JSONObject 
which is produced from a
+        * Map.
+        * 
+        * @param value
+        *            A Map value.
+        * @return this.
+        */
+       public JSONArray put(Map value)
+       {
+               put(new JSONObject(value));
+               return this;
+       }
+
+
+       /**
+        * Append an object value. This increases the array's length by one.
+        * 
+        * @param value
+        *            An object value. The value should be a Boolean, Double, 
Integer, JSONArray,
+        *            JSONObject, Long, or String, or the JSONObject.NULL 
object.
+        * @return this.
+        */
+       public JSONArray put(Object value)
+       {
+               myArrayList.add(value);
+               return this;
+       }
+
+
+       /**
+        * Put or replace a boolean value in the JSONArray. If the index is 
greater than the length of
+        * the JSONArray, then null elements will be added as necessary to pad 
it out.
+        * 
+        * @param index
+        *            The subscript.
+        * @param value
+        *            A boolean value.
+        * @return this.
+        * @throws JSONException
+        *             If the index is negative.
+        */
+       public JSONArray put(int index, boolean value) throws JSONException
+       {
+               put(index, value ? Boolean.TRUE : Boolean.FALSE);
+               return this;
+       }
+
+
+       /**
+        * Put a value in the JSONArray, where the value will be a JSONArray 
which is produced from a
+        * Collection.
+        * 
+        * @param index
+        *            The subscript.
+        * @param value
+        *            A Collection value.
+        * @return this.
+        * @throws JSONException
+        *             If the index is negative or if the value is not finite.
+        */
+       public JSONArray put(int index, Collection value) throws JSONException
+       {
+               put(index, new JSONArray(value));
+               return this;
+       }
+
+
+       /**
+        * Put or replace a double value. If the index is greater than the 
length of the JSONArray, then
+        * null elements will be added as necessary to pad it out.
+        * 
+        * @param index
+        *            The subscript.
+        * @param value
+        *            A double value.
+        * @return this.
+        * @throws JSONException
+        *             If the index is negative or if the value is not finite.
+        */
+       public JSONArray put(int index, double value) throws JSONException
+       {
+               put(index, new Double(value));
+               return this;
+       }
+
+
+       /**
+        * Put or replace an int value. If the index is greater than the length 
of the JSONArray, then
+        * null elements will be added as necessary to pad it out.
+        * 
+        * @param index
+        *            The subscript.
+        * @param value
+        *            An int value.
+        * @return this.
+        * @throws JSONException
+        *             If the index is negative.
+        */
+       public JSONArray put(int index, int value) throws JSONException
+       {
+               put(index, new Integer(value));
+               return this;
+       }
+
+
+       /**
+        * Put or replace a long value. If the index is greater than the length 
of the JSONArray, then
+        * null elements will be added as necessary to pad it out.
+        * 
+        * @param index
+        *            The subscript.
+        * @param value
+        *            A long value.
+        * @return this.
+        * @throws JSONException
+        *             If the index is negative.
+        */
+       public JSONArray put(int index, long value) throws JSONException
+       {
+               put(index, new Long(value));
+               return this;
+       }
+
+
+       /**
+        * Put a value in the JSONArray, where the value will be a JSONObject 
that is produced from a
+        * Map.
+        * 
+        * @param index
+        *            The subscript.
+        * @param value
+        *            The Map value.
+        * @return this.
+        * @throws JSONException
+        *             If the index is negative or if the the value is an 
invalid number.
+        */
+       public JSONArray put(int index, Map value) throws JSONException
+       {
+               put(index, new JSONObject(value));
+               return this;
+       }
+
+
+       /**
+        * Put or replace an object value in the JSONArray. If the index is 
greater than the length of
+        * the JSONArray, then null elements will be added as necessary to pad 
it out.
+        * 
+        * @param index
+        *            The subscript.
+        * @param value
+        *            The value to put into the array. The value should be a 
Boolean, Double, Integer,
+        *            JSONArray, JSONObject, Long, or String, or the 
JSONObject.NULL object.
+        * @return this.
+        * @throws JSONException
+        *             If the index is negative or if the the value is an 
invalid number.
+        */
+       public JSONArray put(int index, Object value) throws JSONException
+       {
+               JSONObject.testValidity(value);
+               if (index < 0)
+               {
+                       throw new JSONException("JSONArray[" + index + "] not 
found.");
+               }
+               if (index < length())
+               {
+                       myArrayList.set(index, value);
+               }
+               else
+               {
+                       while (index != length())
+                       {
+                               put(JSONObject.NULL);
+                       }
+                       put(value);
+               }
+               return this;
+       }
+
+
+       /**
+        * Remove an index and close the hole.
+        * 
+        * @param index
+        *            The index of the element to be removed.
+        * @return The value that was associated with the index, or null if 
there was no value.
+        */
+       public Object remove(int index)
+       {
+               Object o = opt(index);
+               myArrayList.remove(index);
+               return o;
+       }
+
+
+       /**
+        * Produce a JSONObject by combining a JSONArray of names with the 
values of this JSONArray.
+        * 
+        * @param names
+        *            A JSONArray containing a list of key strings. These will 
be paired with the
+        *            values.
+        * @return A JSONObject, or null if there are no names or if this 
JSONArray has no values.
+        * @throws JSONException
+        *             If any of the names are null.
+        */
+       public JSONObject toJSONObject(JSONArray names) throws JSONException
+       {
+               if (names == null || names.length() == 0 || length() == 0)
+               {
+                       return null;
+               }
+               JSONObject jo = new JSONObject();
+               for (int i = 0; i < names.length(); i += 1)
+               {
+                       jo.put(names.getString(i), opt(i));
+               }
+               return jo;
+       }
+
+
+       /**
+        * Make a JSON text of this JSONArray. For compactness, no unnecessary 
whitespace is added. If
+        * it is not possible to produce a syntactically correct JSON text then 
null will be returned
+        * instead. This could occur if the array contains an invalid number.
+        * <p>
+        * Warning: This method assumes that the data structure is acyclical.
+        * 
+        * @return a printable, displayable, transmittable representation of 
the array.
+        */
+       @Override
+       public String toString()
+       {
+               try
+               {
+                       return '[' + join(",") + ']';
+               }
+               catch (Exception e)
+               {
+                       return null;
+               }
+       }
+
+
+       /**
+        * Make a prettyprinted JSON text of this JSONArray. Warning: This 
method assumes that the data
+        * structure is acyclical.
+        * 
+        * @param indentFactor
+        *            The number of spaces to add to each level of indentation.
+        * @return a printable, displayable, transmittable representation of 
the object, beginning with
+        *         <code>[</code>&nbsp;<small>(left bracket)</small> and ending 
with <code>]</code>
+        *         &nbsp;<small>(right bracket)</small>.
+        * @throws JSONException
+        */
+       public String toString(int indentFactor) throws JSONException
+       {
+               return toString(indentFactor, 0);
+       }
+
+
+       /**
+        * Make a prettyprinted JSON text of this JSONArray. Warning: This 
method assumes that the data
+        * structure is acyclical.
+        * 
+        * @param indentFactor
+        *            The number of spaces to add to each level of indentation.
+        * @param indent
+        *            The indention of the top level.
+        * @return a printable, displayable, transmittable representation of 
the array.
+        * @throws JSONException
+        */
+       String toString(int indentFactor, int indent) throws JSONException
+       {
+               int len = length();
+               if (len == 0)
+               {
+                       return "[]";
+               }
+               int i;
+               StringBuffer sb = new StringBuffer("[");
+               if (len == 1)
+               {
+                       sb.append(JSONObject.valueToString(myArrayList.get(0), 
indentFactor, indent));
+               }
+               else
+               {
+                       int newindent = indent + indentFactor;
+                       sb.append('\n');
+                       for (i = 0; i < len; i += 1)
+                       {
+                               if (i > 0)
+                               {
+                                       sb.append(",\n");
+                               }
+                               for (int j = 0; j < newindent; j += 1)
+                               {
+                                       sb.append(' ');
+                               }
+                               
sb.append(JSONObject.valueToString(myArrayList.get(i), indentFactor, 
newindent));
+                       }
+                       sb.append('\n');
+                       for (i = 0; i < indent; i += 1)
+                       {
+                               sb.append(' ');
+                       }
+               }
+               sb.append(']');
+               return sb.toString();
+       }
+
+
+       /**
+        * Write the contents of the JSONArray as JSON text to a writer. For 
compactness, no whitespace
+        * is added.
+        * <p>
+        * Warning: This method assumes that the data structure is acyclical.
+        * 
+        * @return The writer.
+        * @throws JSONException
+        */
+       public Writer write(Writer writer) throws JSONException
+       {
+               try
+               {
+                       boolean b = false;
+                       int len = length();
+
+                       writer.write('[');
+
+                       for (int i = 0; i < len; i += 1)
+                       {
+                               if (b)
+                               {
+                                       writer.write(',');
+                               }
+                               Object v = myArrayList.get(i);
+                               if (v instanceof JSONObject)
+                               {
+                                       ((JSONObject)v).write(writer);
+                               }
+                               else if (v instanceof JSONArray)
+                               {
+                                       ((JSONArray)v).write(writer);
+                               }
+                               else
+                               {
+                                       
writer.write(JSONObject.valueToString(v));
+                               }
+                               b = true;
+                       }
+                       writer.write(']');
+                       return writer;
+               }
+               catch (IOException e)
+               {
+                       throw new JSONException(e);
+               }
+       }
+}
\ No newline at end of file

Propchange: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONArray.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONException.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONException.java?rev=1220771&view=auto
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONException.java
 (added)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONException.java
 Mon Dec 19 14:34:44 2011
@@ -0,0 +1,36 @@
+package org.apache.wicket.ajax.json;
+
+/**
+ * The JSONException is thrown by the JSON.org classes when things are amiss.
+ * 
+ * @author JSON.org
+ * @version 2010-12-24
+ */
+public class JSONException extends Exception
+{
+       private static final long serialVersionUID = 0;
+       private Throwable cause;
+
+       /**
+        * Constructs a JSONException with an explanatory message.
+        * 
+        * @param message
+        *            Detail about the reason for the exception.
+        */
+       public JSONException(String message)
+       {
+               super(message);
+       }
+
+       public JSONException(Throwable cause)
+       {
+               super(cause.getMessage());
+               this.cause = cause;
+       }
+
+       @Override
+       public Throwable getCause()
+       {
+               return cause;
+       }
+}

Propchange: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONException.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONML.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONML.java?rev=1220771&view=auto
==============================================================================
--- 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONML.java 
(added)
+++ 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONML.java 
Mon Dec 19 14:34:44 2011
@@ -0,0 +1,576 @@
+package org.apache.wicket.ajax.json;
+
+/*
+ Copyright (c) 2008 JSON.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ The Software shall be used for Good, not Evil.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+ */
+
+import java.util.Iterator;
+
+
+/**
+ * This provides static methods to convert an XML text into a JSONArray or 
JSONObject, and to covert
+ * a JSONArray or JSONObject into an XML text using the JsonML transform.
+ * 
+ * @author JSON.org
+ * @version 2011-10-05
+ */
+public class JSONML
+{
+
+       /**
+        * Parse XML values and store them in a JSONArray.
+        * 
+        * @param x
+        *            The XMLTokener containing the source string.
+        * @param arrayForm
+        *            true if array form, false if object form.
+        * @param ja
+        *            The JSONArray that is containing the current tag or null 
if we are at the
+        *            outermost level.
+        * @return A JSONArray if the value is the outermost tag, otherwise 
null.
+        * @throws JSONException
+        */
+       private static Object parse(XMLTokener x, boolean arrayForm, JSONArray 
ja) throws JSONException
+       {
+               String attribute;
+               char c;
+               String closeTag = null;
+               int i;
+               JSONArray newja = null;
+               JSONObject newjo = null;
+               Object token;
+               String tagName = null;
+
+// Test for and skip past these forms:
+// <!-- ... -->
+// <![ ... ]]>
+// <! ... >
+// <? ... ?>
+
+               while (true)
+               {
+                       if (!x.more())
+                       {
+                               throw x.syntaxError("Bad XML");
+                       }
+                       token = x.nextContent();
+                       if (token == XML.LT)
+                       {
+                               token = x.nextToken();
+                               if (token instanceof Character)
+                               {
+                                       if (token == XML.SLASH)
+                                       {
+
+// Close tag </
+
+                                               token = x.nextToken();
+                                               if (!(token instanceof String))
+                                               {
+                                                       throw new 
JSONException("Expected a closing name instead of '" + token +
+                                                               "'.");
+                                               }
+                                               if (x.nextToken() != XML.GT)
+                                               {
+                                                       throw 
x.syntaxError("Misshaped close tag");
+                                               }
+                                               return token;
+                                       }
+                                       else if (token == XML.BANG)
+                                       {
+
+// <!
+
+                                               c = x.next();
+                                               if (c == '-')
+                                               {
+                                                       if (x.next() == '-')
+                                                       {
+                                                               
x.skipPast("-->");
+                                                       }
+                                                       x.back();
+                                               }
+                                               else if (c == '[')
+                                               {
+                                                       token = x.nextToken();
+                                                       if 
(token.equals("CDATA") && x.next() == '[')
+                                                       {
+                                                               if (ja != null)
+                                                               {
+                                                                       
ja.put(x.nextCDATA());
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               throw 
x.syntaxError("Expected 'CDATA['");
+                                                       }
+                                               }
+                                               else
+                                               {
+                                                       i = 1;
+                                                       do
+                                                       {
+                                                               token = 
x.nextMeta();
+                                                               if (token == 
null)
+                                                               {
+                                                                       throw 
x.syntaxError("Missing '>' after '<!'.");
+                                                               }
+                                                               else if (token 
== XML.LT)
+                                                               {
+                                                                       i += 1;
+                                                               }
+                                                               else if (token 
== XML.GT)
+                                                               {
+                                                                       i -= 1;
+                                                               }
+                                                       }
+                                                       while (i > 0);
+                                               }
+                                       }
+                                       else if (token == XML.QUEST)
+                                       {
+
+// <?
+
+                                               x.skipPast("?>");
+                                       }
+                                       else
+                                       {
+                                               throw x.syntaxError("Misshaped 
tag");
+                                       }
+
+// Open tag <
+
+                               }
+                               else
+                               {
+                                       if (!(token instanceof String))
+                                       {
+                                               throw x.syntaxError("Bad 
tagName '" + token + "'.");
+                                       }
+                                       tagName = (String)token;
+                                       newja = new JSONArray();
+                                       newjo = new JSONObject();
+                                       if (arrayForm)
+                                       {
+                                               newja.put(tagName);
+                                               if (ja != null)
+                                               {
+                                                       ja.put(newja);
+                                               }
+                                       }
+                                       else
+                                       {
+                                               newjo.put("tagName", tagName);
+                                               if (ja != null)
+                                               {
+                                                       ja.put(newjo);
+                                               }
+                                       }
+                                       token = null;
+                                       for (;;)
+                                       {
+                                               if (token == null)
+                                               {
+                                                       token = x.nextToken();
+                                               }
+                                               if (token == null)
+                                               {
+                                                       throw 
x.syntaxError("Misshaped tag");
+                                               }
+                                               if (!(token instanceof String))
+                                               {
+                                                       break;
+                                               }
+
+// attribute = value
+
+                                               attribute = (String)token;
+                                               if (!arrayForm && (attribute == 
"tagName" || attribute == "childNode"))
+                                               {
+                                                       throw 
x.syntaxError("Reserved attribute.");
+                                               }
+                                               token = x.nextToken();
+                                               if (token == XML.EQ)
+                                               {
+                                                       token = x.nextToken();
+                                                       if (!(token instanceof 
String))
+                                                       {
+                                                               throw 
x.syntaxError("Missing value");
+                                                       }
+                                                       
newjo.accumulate(attribute, XML.stringToValue((String)token));
+                                                       token = null;
+                                               }
+                                               else
+                                               {
+                                                       
newjo.accumulate(attribute, "");
+                                               }
+                                       }
+                                       if (arrayForm && newjo.length() > 0)
+                                       {
+                                               newja.put(newjo);
+                                       }
+
+// Empty tag <.../>
+
+                                       if (token == XML.SLASH)
+                                       {
+                                               if (x.nextToken() != XML.GT)
+                                               {
+                                                       throw 
x.syntaxError("Misshaped tag");
+                                               }
+                                               if (ja == null)
+                                               {
+                                                       if (arrayForm)
+                                                       {
+                                                               return newja;
+                                                       }
+                                                       else
+                                                       {
+                                                               return newjo;
+                                                       }
+                                               }
+
+// Content, between <...> and </...>
+
+                                       }
+                                       else
+                                       {
+                                               if (token != XML.GT)
+                                               {
+                                                       throw 
x.syntaxError("Misshaped tag");
+                                               }
+                                               closeTag = (String)parse(x, 
arrayForm, newja);
+                                               if (closeTag != null)
+                                               {
+                                                       if 
(!closeTag.equals(tagName))
+                                                       {
+                                                               throw 
x.syntaxError("Mismatched '" + tagName + "' and '" +
+                                                                       
closeTag + "'");
+                                                       }
+                                                       tagName = null;
+                                                       if (!arrayForm && 
newja.length() > 0)
+                                                       {
+                                                               
newjo.put("childNodes", newja);
+                                                       }
+                                                       if (ja == null)
+                                                       {
+                                                               if (arrayForm)
+                                                               {
+                                                                       return 
newja;
+                                                               }
+                                                               else
+                                                               {
+                                                                       return 
newjo;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               if (ja != null)
+                               {
+                                       ja.put(token instanceof String ? 
XML.stringToValue((String)token) : token);
+                               }
+                       }
+               }
+       }
+
+
+       /**
+        * Convert a well-formed (but not necessarily valid) XML string into a 
JSONArray using the
+        * JsonML transform. Each XML tag is represented as a JSONArray in 
which the first element is
+        * the tag name. If the tag has attributes, then the second element 
will be JSONObject
+        * containing the name/value pairs. If the tag contains children, then 
strings and JSONArrays
+        * will represent the child tags. Comments, prologs, DTDs, and 
<code>&lt;[ [ ]]></code> are
+        * ignored.
+        * 
+        * @param string
+        *            The source string.
+        * @return A JSONArray containing the structured data from the XML 
string.
+        * @throws JSONException
+        */
+       public static JSONArray toJSONArray(String string) throws JSONException
+       {
+               return toJSONArray(new XMLTokener(string));
+       }
+
+
+       /**
+        * Convert a well-formed (but not necessarily valid) XML string into a 
JSONArray using the
+        * JsonML transform. Each XML tag is represented as a JSONArray in 
which the first element is
+        * the tag name. If the tag has attributes, then the second element 
will be JSONObject
+        * containing the name/value pairs. If the tag contains children, then 
strings and JSONArrays
+        * will represent the child content and tags. Comments, prologs, DTDs, 
and
+        * <code>&lt;[ [ ]]></code> are ignored.
+        * 
+        * @param x
+        *            An XMLTokener.
+        * @return A JSONArray containing the structured data from the XML 
string.
+        * @throws JSONException
+        */
+       public static JSONArray toJSONArray(XMLTokener x) throws JSONException
+       {
+               return (JSONArray)parse(x, true, null);
+       }
+
+
+       /**
+        * Convert a well-formed (but not necessarily valid) XML string into a 
JSONObject using the
+        * JsonML transform. Each XML tag is represented as a JSONObject with a 
"tagName" property. If
+        * the tag has attributes, then the attributes will be in the 
JSONObject as properties. If the
+        * tag contains children, the object will have a "childNodes" property 
which will be an array of
+        * strings and JsonML JSONObjects.
+        * 
+        * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
+        * 
+        * @param x
+        *            An XMLTokener of the XML source text.
+        * @return A JSONObject containing the structured data from the XML 
string.
+        * @throws JSONException
+        */
+       public static JSONObject toJSONObject(XMLTokener x) throws JSONException
+       {
+               return (JSONObject)parse(x, false, null);
+       }
+
+
+       /**
+        * Convert a well-formed (but not necessarily valid) XML string into a 
JSONObject using the
+        * JsonML transform. Each XML tag is represented as a JSONObject with a 
"tagName" property. If
+        * the tag has attributes, then the attributes will be in the 
JSONObject as properties. If the
+        * tag contains children, the object will have a "childNodes" property 
which will be an array of
+        * strings and JsonML JSONObjects.
+        * 
+        * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
+        * 
+        * @param string
+        *            The XML source text.
+        * @return A JSONObject containing the structured data from the XML 
string.
+        * @throws JSONException
+        */
+       public static JSONObject toJSONObject(String string) throws 
JSONException
+       {
+               return toJSONObject(new XMLTokener(string));
+       }
+
+
+       /**
+        * Reverse the JSONML transformation, making an XML text from a 
JSONArray.
+        * 
+        * @param ja
+        *            A JSONArray.
+        * @return An XML string.
+        * @throws JSONException
+        */
+       public static String toString(JSONArray ja) throws JSONException
+       {
+               int i;
+               JSONObject jo;
+               String key;
+               Iterator keys;
+               int length;
+               Object object;
+               StringBuffer sb = new StringBuffer();
+               String tagName;
+               String value;
+
+// Emit <tagName
+
+               tagName = ja.getString(0);
+               XML.noSpace(tagName);
+               tagName = XML.escape(tagName);
+               sb.append('<');
+               sb.append(tagName);
+
+               object = ja.opt(1);
+               if (object instanceof JSONObject)
+               {
+                       i = 2;
+                       jo = (JSONObject)object;
+
+// Emit the attributes
+
+                       keys = jo.keys();
+                       while (keys.hasNext())
+                       {
+                               key = keys.next().toString();
+                               XML.noSpace(key);
+                               value = jo.optString(key);
+                               if (value != null)
+                               {
+                                       sb.append(' ');
+                                       sb.append(XML.escape(key));
+                                       sb.append('=');
+                                       sb.append('"');
+                                       sb.append(XML.escape(value));
+                                       sb.append('"');
+                               }
+                       }
+               }
+               else
+               {
+                       i = 1;
+               }
+
+// Emit content in body
+
+               length = ja.length();
+               if (i >= length)
+               {
+                       sb.append('/');
+                       sb.append('>');
+               }
+               else
+               {
+                       sb.append('>');
+                       do
+                       {
+                               object = ja.get(i);
+                               i += 1;
+                               if (object != null)
+                               {
+                                       if (object instanceof String)
+                                       {
+                                               
sb.append(XML.escape(object.toString()));
+                                       }
+                                       else if (object instanceof JSONObject)
+                                       {
+                                               
sb.append(toString((JSONObject)object));
+                                       }
+                                       else if (object instanceof JSONArray)
+                                       {
+                                               
sb.append(toString((JSONArray)object));
+                                       }
+                               }
+                       }
+                       while (i < length);
+                       sb.append('<');
+                       sb.append('/');
+                       sb.append(tagName);
+                       sb.append('>');
+               }
+               return sb.toString();
+       }
+
+       /**
+        * Reverse the JSONML transformation, making an XML text from a 
JSONObject. The JSONObject must
+        * contain a "tagName" property. If it has children, then it must have 
a "childNodes" property
+        * containing an array of objects. The other properties are attributes 
with string values.
+        * 
+        * @param jo
+        *            A JSONObject.
+        * @return An XML string.
+        * @throws JSONException
+        */
+       public static String toString(JSONObject jo) throws JSONException
+       {
+               StringBuffer sb = new StringBuffer();
+               int i;
+               JSONArray ja;
+               String key;
+               Iterator keys;
+               int length;
+               Object object;
+               String tagName;
+               String value;
+
+// Emit <tagName
+
+               tagName = jo.optString("tagName");
+               if (tagName == null)
+               {
+                       return XML.escape(jo.toString());
+               }
+               XML.noSpace(tagName);
+               tagName = XML.escape(tagName);
+               sb.append('<');
+               sb.append(tagName);
+
+// Emit the attributes
+
+               keys = jo.keys();
+               while (keys.hasNext())
+               {
+                       key = keys.next().toString();
+                       if (!key.equals("tagName") && !key.equals("childNodes"))
+                       {
+                               XML.noSpace(key);
+                               value = jo.optString(key);
+                               if (value != null)
+                               {
+                                       sb.append(' ');
+                                       sb.append(XML.escape(key));
+                                       sb.append('=');
+                                       sb.append('"');
+                                       sb.append(XML.escape(value));
+                                       sb.append('"');
+                               }
+                       }
+               }
+
+// Emit content in body
+
+               ja = jo.optJSONArray("childNodes");
+               if (ja == null)
+               {
+                       sb.append('/');
+                       sb.append('>');
+               }
+               else
+               {
+                       sb.append('>');
+                       length = ja.length();
+                       for (i = 0; i < length; i += 1)
+                       {
+                               object = ja.get(i);
+                               if (object != null)
+                               {
+                                       if (object instanceof String)
+                                       {
+                                               
sb.append(XML.escape(object.toString()));
+                                       }
+                                       else if (object instanceof JSONObject)
+                                       {
+                                               
sb.append(toString((JSONObject)object));
+                                       }
+                                       else if (object instanceof JSONArray)
+                                       {
+                                               
sb.append(toString((JSONArray)object));
+                                       }
+                                       else
+                                       {
+                                               sb.append(object.toString());
+                                       }
+                               }
+                       }
+                       sb.append('<');
+                       sb.append('/');
+                       sb.append(tagName);
+                       sb.append('>');
+               }
+               return sb.toString();
+       }
+}
\ No newline at end of file

Propchange: 
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONML.java
------------------------------------------------------------------------------
    svn:executable = *


Reply via email to