You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2012/05/18 13:39:32 UTC
[5/7] Update JSON2 classes
http://git-wip-us.apache.org/repos/asf/wicket/blob/0c01d793/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONString.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONString.java b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONString.java
index 61a91b0..00f24d6 100755
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONString.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONString.java
@@ -1,18 +1,19 @@
package org.apache.wicket.ajax.json;
/**
- * The <code>JSONString</code> interface allows a <code>toJSONString()</code> method so that a class
- * can change the behavior of <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>,
- * and <code>JSONWriter.value(</code>Object<code>)</code>. The <code>toJSONString</code> method will
- * be used instead of the default behavior of using the Object's <code>toString()</code> method and
- * quoting the result.
+ * The <code>JSONString</code> interface allows a <code>toJSONString()</code>
+ * method so that a class can change the behavior of
+ * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>,
+ * and <code>JSONWriter.value(</code>Object<code>)</code>. The
+ * <code>toJSONString</code> method will be used instead of the default behavior
+ * of using the Object's <code>toString()</code> method and quoting the result.
*/
-public interface JSONString
-{
- /**
- * The <code>toJSONString</code> method allows a class to produce its own JSON serialization.
- *
- * @return A strictly syntactically correct JSON text.
- */
- public String toJSONString();
+public interface JSONString {
+ /**
+ * The <code>toJSONString</code> method allows a class to produce its own JSON
+ * serialization.
+ *
+ * @return A strictly syntactically correct JSON text.
+ */
+ public String toJSONString();
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/0c01d793/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONStringer.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONStringer.java b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONStringer.java
index 178e6a6..15eb62b 100755
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONStringer.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONStringer.java
@@ -1,82 +1,78 @@
package org.apache.wicket.ajax.json;
/*
- Copyright (c) 2006 JSON.org
+Copyright (c) 2006 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:
+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 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 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.
- */
+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.StringWriter;
/**
- * JSONStringer provides a quick and convenient way of producing JSON text. The texts produced
- * strictly conform to JSON syntax rules. No whitespace is added, so the results are ready for
- * transmission or storage. Each instance of JSONStringer can produce one JSON text.
+ * JSONStringer provides a quick and convenient way of producing JSON text.
+ * The texts produced strictly conform to JSON syntax rules. No whitespace is
+ * added, so the results are ready for transmission or storage. Each instance of
+ * JSONStringer can produce one JSON text.
* <p>
- * A JSONStringer instance provides a <code>value</code> method for appending values to the text,
- * and a <code>key</code> method for adding keys before values in objects. There are
- * <code>array</code> and <code>endArray</code> methods that make and bound array values, and
- * <code>object</code> and <code>endObject</code> methods which make and bound object values. All of
- * these methods return the JSONWriter instance, permitting cascade style. For example,
- *
- * <pre>
- * myString = new JSONStringer().object().key("JSON").value("Hello, World!").endObject().toString();
- * </pre>
- *
- * which produces the string
- *
- * <pre>
- * {"JSON":"Hello, World!"}
- * </pre>
+ * A JSONStringer instance provides a <code>value</code> method for appending
+ * values to the
+ * text, and a <code>key</code>
+ * method for adding keys before values in objects. There are <code>array</code>
+ * and <code>endArray</code> methods that make and bound array values, and
+ * <code>object</code> and <code>endObject</code> methods which make and bound
+ * object values. All of these methods return the JSONWriter instance,
+ * permitting cascade style. For example, <pre>
+ * myString = new JSONStringer()
+ * .object()
+ * .key("JSON")
+ * .value("Hello, World!")
+ * .endObject()
+ * .toString();</pre> which produces the string <pre>
+ * {"JSON":"Hello, World!"}</pre>
* <p>
- * The first method called must be <code>array</code> or <code>object</code>. There are no methods
- * for adding commas or colons. JSONStringer adds them for you. Objects and arrays can be nested up
- * to 20 levels deep.
+ * The first method called must be <code>array</code> or <code>object</code>.
+ * There are no methods for adding commas or colons. JSONStringer adds them for
+ * you. Objects and arrays can be nested up to 20 levels deep.
* <p>
* This can sometimes be easier than using a JSONObject to build a string.
- *
* @author JSON.org
* @version 2008-09-18
*/
-public class JSONStringer extends JSONWriter
-{
- /**
- * Make a fresh JSONStringer. It can be used to build one JSON text.
- */
- public JSONStringer()
- {
- super(new StringWriter());
- }
+public class JSONStringer extends JSONWriter {
+ /**
+ * Make a fresh JSONStringer. It can be used to build one JSON text.
+ */
+ public JSONStringer() {
+ super(new StringWriter());
+ }
- /**
- * Return the JSON text. This method is used to obtain the product of the JSONStringer instance.
- * It will return <code>null</code> if there was a problem in the construction of the JSON text
- * (such as the calls to <code>array</code> were not properly balanced with calls to
- * <code>endArray</code>).
- *
- * @return The JSON text.
- */
- @Override
- public String toString()
- {
- return mode == 'd' ? writer.toString() : null;
- }
+ /**
+ * Return the JSON text. This method is used to obtain the product of the
+ * JSONStringer instance. It will return <code>null</code> if there was a
+ * problem in the construction of the JSON text (such as the calls to
+ * <code>array</code> were not properly balanced with calls to
+ * <code>endArray</code>).
+ * @return The JSON text.
+ */
+ public String toString() {
+ return this.mode == 'd' ? this.writer.toString() : null;
+ }
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/0c01d793/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONTokener.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONTokener.java b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONTokener.java
index 5717bdf..16c7542 100755
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONTokener.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONTokener.java
@@ -8,510 +8,439 @@ import java.io.Reader;
import java.io.StringReader;
/*
- 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.
- */
+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.
+*/
/**
- * A JSONTokener takes a source string and extracts characters and tokens from it. It is used by the
- * JSONObject and JSONArray constructors to parse JSON source strings.
- *
+ * A JSONTokener takes a source string and extracts characters and tokens from
+ * it. It is used by the JSONObject and JSONArray constructors to parse
+ * JSON source strings.
* @author JSON.org
- * @version 2010-12-24
+ * @version 2012-02-16
*/
-public class JSONTokener
-{
-
- private int character;
- private boolean eof;
- private int index;
- private int line;
- private char previous;
- private Reader reader;
- private boolean usePrevious;
-
-
- /**
- * Construct a JSONTokener from a Reader.
- *
- * @param reader
- * A reader.
- */
- public JSONTokener(Reader reader)
- {
- this.reader = reader.markSupported() ? reader : new BufferedReader(reader);
- eof = false;
- usePrevious = false;
- previous = 0;
- index = 0;
- character = 1;
- line = 1;
- }
-
-
- /**
- * Construct a JSONTokener from an InputStream.
- */
- public JSONTokener(InputStream inputStream) throws JSONException
- {
- this(new InputStreamReader(inputStream));
- }
-
-
- /**
- * Construct a JSONTokener from a string.
- *
- * @param s
- * A source string.
- */
- public JSONTokener(String s)
- {
- this(new StringReader(s));
- }
-
-
- /**
- * Back up one character. This provides a sort of lookahead capability, so that you can test for
- * a digit or letter before attempting to parse the next number or identifier.
- */
- public void back() throws JSONException
- {
- if (usePrevious || index <= 0)
- {
- throw new JSONException("Stepping back two steps is not supported");
- }
- index -= 1;
- character -= 1;
- usePrevious = true;
- eof = false;
- }
-
-
- /**
- * Get the hex value of a character (base16).
- *
- * @param c
- * A character between '0' and '9' or between 'A' and 'F' or between 'a' and 'f'.
- * @return An int between 0 and 15, or -1 if c was not a hex digit.
- */
- public static int dehexchar(char c)
- {
- if (c >= '0' && c <= '9')
- {
- return c - '0';
- }
- if (c >= 'A' && c <= 'F')
- {
- return c - ('A' - 10);
- }
- if (c >= 'a' && c <= 'f')
- {
- return c - ('a' - 10);
- }
- return -1;
- }
-
- public boolean end()
- {
- return eof && !usePrevious;
- }
-
-
- /**
- * Determine if the source string still contains characters that next() can consume.
- *
- * @return true if not yet at the end of the source.
- */
- public boolean more() throws JSONException
- {
- next();
- if (end())
- {
- return false;
- }
- back();
- return true;
- }
-
-
- /**
- * Get the next character in the source string.
- *
- * @return The next character, or 0 if past the end of the source string.
- */
- public char next() throws JSONException
- {
- int c;
- if (usePrevious)
- {
- usePrevious = false;
- c = previous;
- }
- else
- {
- try
- {
- c = reader.read();
- }
- catch (IOException exception)
- {
- throw new JSONException(exception);
- }
-
- if (c <= 0)
- { // End of stream
- eof = true;
- c = 0;
- }
- }
- index += 1;
- if (previous == '\r')
- {
- line += 1;
- character = c == '\n' ? 0 : 1;
- }
- else if (c == '\n')
- {
- line += 1;
- character = 0;
- }
- else
- {
- character += 1;
- }
- previous = (char)c;
- return previous;
- }
-
-
- /**
- * Consume the next character, and check that it matches a specified character.
- *
- * @param c
- * The character to match.
- * @return The character.
- * @throws JSONException
- * if the character does not match.
- */
- public char next(char c) throws JSONException
- {
- char n = next();
- if (n != c)
- {
- throw syntaxError("Expected '" + c + "' and instead saw '" + n + "'");
- }
- return n;
- }
-
-
- /**
- * Get the next n characters.
- *
- * @param n
- * The number of characters to take.
- * @return A string of n characters.
- * @throws JSONException
- * Substring bounds error if there are not n characters remaining in the source
- * string.
- */
- public String next(int n) throws JSONException
- {
- if (n == 0)
- {
- return "";
- }
-
- char[] chars = new char[n];
- int pos = 0;
-
- while (pos < n)
- {
- chars[pos] = next();
- if (end())
- {
- throw syntaxError("Substring bounds error");
- }
- pos += 1;
- }
- return new String(chars);
- }
-
-
- /**
- * Get the next char in the string, skipping whitespace.
- *
- * @throws JSONException
- * @return A character, or 0 if there are no more characters.
- */
- public char nextClean() throws JSONException
- {
- for (;;)
- {
- char c = next();
- if (c == 0 || c > ' ')
- {
- return c;
- }
- }
- }
-
-
- /**
- * Return the characters up to the next close quote character. Backslash processing is done. The
- * formal JSON format does not allow strings in single quotes, but an implementation is allowed
- * to accept them.
- *
- * @param quote
- * The quoting character, either <code>"</code> <small>(double quote)</small> or
- * <code>'</code> <small>(single quote)</small>.
- * @return A String.
- * @throws JSONException
- * Unterminated string.
- */
- public String nextString(char quote) throws JSONException
- {
- char c;
- StringBuffer sb = new StringBuffer();
- for (;;)
- {
- c = next();
- switch (c)
- {
- case 0 :
- case '\n' :
- case '\r' :
- throw syntaxError("Unterminated string");
- case '\\' :
- c = next();
- switch (c)
- {
- case 'b' :
- sb.append('\b');
- break;
- case 't' :
- sb.append('\t');
- break;
- case 'n' :
- sb.append('\n');
- break;
- case 'f' :
- sb.append('\f');
- break;
- case 'r' :
- sb.append('\r');
- break;
- case 'u' :
- sb.append((char)Integer.parseInt(next(4), 16));
- break;
- case '"' :
- case '\'' :
- case '\\' :
- case '/' :
- sb.append(c);
- break;
- default :
- throw syntaxError("Illegal escape.");
- }
- break;
- default :
- if (c == quote)
- {
- return sb.toString();
- }
- sb.append(c);
- }
- }
- }
-
-
- /**
- * Get the text up but not including the specified character or the end of line, whichever comes
- * first.
- *
- * @param delimiter
- * A delimiter character.
- * @return A string.
- */
- public String nextTo(char delimiter) throws JSONException
- {
- StringBuffer sb = new StringBuffer();
- for (;;)
- {
- char c = next();
- if (c == delimiter || c == 0 || c == '\n' || c == '\r')
- {
- if (c != 0)
- {
- back();
- }
- return sb.toString().trim();
- }
- sb.append(c);
- }
- }
-
-
- /**
- * Get the text up but not including one of the specified delimiter characters or the end of
- * line, whichever comes first.
- *
- * @param delimiters
- * A set of delimiter characters.
- * @return A string, trimmed.
- */
- public String nextTo(String delimiters) throws JSONException
- {
- char c;
- StringBuffer sb = new StringBuffer();
- for (;;)
- {
- c = next();
- if (delimiters.indexOf(c) >= 0 || c == 0 || c == '\n' || c == '\r')
- {
- if (c != 0)
- {
- back();
- }
- return sb.toString().trim();
- }
- sb.append(c);
- }
- }
-
-
- /**
- * Get the next value. The value can be a Boolean, Double, Integer, JSONArray, JSONObject, Long,
- * or String, or the JSONObject.NULL object.
- *
- * @throws JSONException
- * If syntax error.
- *
- * @return An object.
- */
- public Object nextValue() throws JSONException
- {
- char c = nextClean();
- String string;
-
- switch (c)
- {
- case '"' :
- case '\'' :
- return nextString(c);
- case '{' :
- back();
- return new JSONObject(this);
- case '[' :
- back();
- return new JSONArray(this);
- }
-
- /*
- * Handle unquoted text. This could be the values true, false, or null, or it can be a
- * number. An implementation (such as this one) is allowed to also accept non-standard
- * forms.
- *
- * Accumulate characters until we reach the end of the text or a formatting character.
- */
-
- StringBuffer sb = new StringBuffer();
- while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0)
- {
- sb.append(c);
- c = next();
- }
- back();
-
- string = sb.toString().trim();
- if (string.equals(""))
- {
- throw syntaxError("Missing value");
- }
- return JSONObject.stringToValue(string);
- }
-
-
- /**
- * Skip characters until the next character is the requested character. If the requested
- * character is not found, no characters are skipped.
- *
- * @param to
- * A character to skip to.
- * @return The requested character, or zero if the requested character is not found.
- */
- public char skipTo(char to) throws JSONException
- {
- char c;
- try
- {
- int startIndex = index;
- int startCharacter = character;
- int startLine = line;
- reader.mark(Integer.MAX_VALUE);
- do
- {
- c = next();
- if (c == 0)
- {
- reader.reset();
- index = startIndex;
- character = startCharacter;
- line = startLine;
- return c;
- }
- }
- while (c != to);
- }
- catch (IOException exc)
- {
- throw new JSONException(exc);
- }
-
- back();
- return c;
- }
-
-
- /**
- * Make a JSONException to signal a syntax error.
- *
- * @param message
- * The error message.
- * @return A JSONException object, suitable for throwing
- */
- public JSONException syntaxError(String message)
- {
- return new JSONException(message + toString());
- }
-
-
- /**
- * Make a printable string of this JSONTokener.
- *
- * @return " at {index} [character {character} line {line}]"
- */
- @Override
- public String toString()
- {
- return " at " + index + " [character " + character + " line " + line + "]";
- }
-}
\ No newline at end of file
+public class JSONTokener {
+
+ private long character;
+ private boolean eof;
+ private long index;
+ private long line;
+ private char previous;
+ private Reader reader;
+ private boolean usePrevious;
+
+
+ /**
+ * Construct a JSONTokener from a Reader.
+ *
+ * @param reader A reader.
+ */
+ public JSONTokener(Reader reader) {
+ this.reader = reader.markSupported()
+ ? reader
+ : new BufferedReader(reader);
+ this.eof = false;
+ this.usePrevious = false;
+ this.previous = 0;
+ this.index = 0;
+ this.character = 1;
+ this.line = 1;
+ }
+
+
+ /**
+ * Construct a JSONTokener from an InputStream.
+ */
+ public JSONTokener(InputStream inputStream) throws JSONException {
+ this(new InputStreamReader(inputStream));
+ }
+
+
+ /**
+ * Construct a JSONTokener from a string.
+ *
+ * @param s A source string.
+ */
+ public JSONTokener(String s) {
+ this(new StringReader(s));
+ }
+
+
+ /**
+ * Back up one character. This provides a sort of lookahead capability,
+ * so that you can test for a digit or letter before attempting to parse
+ * the next number or identifier.
+ */
+ public void back() throws JSONException {
+ if (this.usePrevious || this.index <= 0) {
+ throw new JSONException("Stepping back two steps is not supported");
+ }
+ this.index -= 1;
+ this.character -= 1;
+ this.usePrevious = true;
+ this.eof = false;
+ }
+
+
+ /**
+ * Get the hex value of a character (base16).
+ * @param c A character between '0' and '9' or between 'A' and 'F' or
+ * between 'a' and 'f'.
+ * @return An int between 0 and 15, or -1 if c was not a hex digit.
+ */
+ public static int dehexchar(char c) {
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ }
+ if (c >= 'A' && c <= 'F') {
+ return c - ('A' - 10);
+ }
+ if (c >= 'a' && c <= 'f') {
+ return c - ('a' - 10);
+ }
+ return -1;
+ }
+
+ public boolean end() {
+ return this.eof && !this.usePrevious;
+ }
+
+
+ /**
+ * Determine if the source string still contains characters that next()
+ * can consume.
+ * @return true if not yet at the end of the source.
+ */
+ public boolean more() throws JSONException {
+ this.next();
+ if (this.end()) {
+ return false;
+ }
+ this.back();
+ return true;
+ }
+
+
+ /**
+ * Get the next character in the source string.
+ *
+ * @return The next character, or 0 if past the end of the source string.
+ */
+ public char next() throws JSONException {
+ int c;
+ if (this.usePrevious) {
+ this.usePrevious = false;
+ c = this.previous;
+ } else {
+ try {
+ c = this.reader.read();
+ } catch (IOException exception) {
+ throw new JSONException(exception);
+ }
+
+ if (c <= 0) { // End of stream
+ this.eof = true;
+ c = 0;
+ }
+ }
+ this.index += 1;
+ if (this.previous == '\r') {
+ this.line += 1;
+ this.character = c == '\n' ? 0 : 1;
+ } else if (c == '\n') {
+ this.line += 1;
+ this.character = 0;
+ } else {
+ this.character += 1;
+ }
+ this.previous = (char) c;
+ return this.previous;
+ }
+
+
+ /**
+ * Consume the next character, and check that it matches a specified
+ * character.
+ * @param c The character to match.
+ * @return The character.
+ * @throws JSONException if the character does not match.
+ */
+ public char next(char c) throws JSONException {
+ char n = this.next();
+ if (n != c) {
+ throw this.syntaxError("Expected '" + c + "' and instead saw '" +
+ n + "'");
+ }
+ return n;
+ }
+
+
+ /**
+ * Get the next n characters.
+ *
+ * @param n The number of characters to take.
+ * @return A string of n characters.
+ * @throws JSONException
+ * Substring bounds error if there are not
+ * n characters remaining in the source string.
+ */
+ public String next(int n) throws JSONException {
+ if (n == 0) {
+ return "";
+ }
+
+ char[] chars = new char[n];
+ int pos = 0;
+
+ while (pos < n) {
+ chars[pos] = this.next();
+ if (this.end()) {
+ throw this.syntaxError("Substring bounds error");
+ }
+ pos += 1;
+ }
+ return new String(chars);
+ }
+
+
+ /**
+ * Get the next char in the string, skipping whitespace.
+ * @throws JSONException
+ * @return A character, or 0 if there are no more characters.
+ */
+ public char nextClean() throws JSONException {
+ for (;;) {
+ char c = this.next();
+ if (c == 0 || c > ' ') {
+ return c;
+ }
+ }
+ }
+
+
+ /**
+ * Return the characters up to the next close quote character.
+ * Backslash processing is done. The formal JSON format does not
+ * allow strings in single quotes, but an implementation is allowed to
+ * accept them.
+ * @param quote The quoting character, either
+ * <code>"</code> <small>(double quote)</small> or
+ * <code>'</code> <small>(single quote)</small>.
+ * @return A String.
+ * @throws JSONException Unterminated string.
+ */
+ public String nextString(char quote) throws JSONException {
+ char c;
+ StringBuffer sb = new StringBuffer();
+ for (;;) {
+ c = this.next();
+ switch (c) {
+ case 0:
+ case '\n':
+ case '\r':
+ throw this.syntaxError("Unterminated string");
+ case '\\':
+ c = this.next();
+ switch (c) {
+ case 'b':
+ sb.append('\b');
+ break;
+ case 't':
+ sb.append('\t');
+ break;
+ case 'n':
+ sb.append('\n');
+ break;
+ case 'f':
+ sb.append('\f');
+ break;
+ case 'r':
+ sb.append('\r');
+ break;
+ case 'u':
+ sb.append((char)Integer.parseInt(this.next(4), 16));
+ break;
+ case '"':
+ case '\'':
+ case '\\':
+ case '/':
+ sb.append(c);
+ break;
+ default:
+ throw this.syntaxError("Illegal escape.");
+ }
+ break;
+ default:
+ if (c == quote) {
+ return sb.toString();
+ }
+ sb.append(c);
+ }
+ }
+ }
+
+
+ /**
+ * Get the text up but not including the specified character or the
+ * end of line, whichever comes first.
+ * @param delimiter A delimiter character.
+ * @return A string.
+ */
+ public String nextTo(char delimiter) throws JSONException {
+ StringBuffer sb = new StringBuffer();
+ for (;;) {
+ char c = this.next();
+ if (c == delimiter || c == 0 || c == '\n' || c == '\r') {
+ if (c != 0) {
+ this.back();
+ }
+ return sb.toString().trim();
+ }
+ sb.append(c);
+ }
+ }
+
+
+ /**
+ * Get the text up but not including one of the specified delimiter
+ * characters or the end of line, whichever comes first.
+ * @param delimiters A set of delimiter characters.
+ * @return A string, trimmed.
+ */
+ public String nextTo(String delimiters) throws JSONException {
+ char c;
+ StringBuffer sb = new StringBuffer();
+ for (;;) {
+ c = this.next();
+ if (delimiters.indexOf(c) >= 0 || c == 0 ||
+ c == '\n' || c == '\r') {
+ if (c != 0) {
+ this.back();
+ }
+ return sb.toString().trim();
+ }
+ sb.append(c);
+ }
+ }
+
+
+ /**
+ * Get the next value. The value can be a Boolean, Double, Integer,
+ * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
+ * @throws JSONException If syntax error.
+ *
+ * @return An object.
+ */
+ public Object nextValue() throws JSONException {
+ char c = this.nextClean();
+ String string;
+
+ switch (c) {
+ case '"':
+ case '\'':
+ return this.nextString(c);
+ case '{':
+ this.back();
+ return new JSONObject(this);
+ case '[':
+ this.back();
+ return new JSONArray(this);
+ }
+
+ /*
+ * Handle unquoted text. This could be the values true, false, or
+ * null, or it can be a number. An implementation (such as this one)
+ * is allowed to also accept non-standard forms.
+ *
+ * Accumulate characters until we reach the end of the text or a
+ * formatting character.
+ */
+
+ StringBuffer sb = new StringBuffer();
+ while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
+ sb.append(c);
+ c = this.next();
+ }
+ this.back();
+
+ string = sb.toString().trim();
+ if ("".equals(string)) {
+ throw this.syntaxError("Missing value");
+ }
+ return JSONObject.stringToValue(string);
+ }
+
+
+ /**
+ * Skip characters until the next character is the requested character.
+ * If the requested character is not found, no characters are skipped.
+ * @param to A character to skip to.
+ * @return The requested character, or zero if the requested character
+ * is not found.
+ */
+ public char skipTo(char to) throws JSONException {
+ char c;
+ try {
+ long startIndex = this.index;
+ long startCharacter = this.character;
+ long startLine = this.line;
+ this.reader.mark(1000000);
+ do {
+ c = this.next();
+ if (c == 0) {
+ this.reader.reset();
+ this.index = startIndex;
+ this.character = startCharacter;
+ this.line = startLine;
+ return c;
+ }
+ } while (c != to);
+ } catch (IOException exc) {
+ throw new JSONException(exc);
+ }
+
+ this.back();
+ return c;
+ }
+
+
+ /**
+ * Make a JSONException to signal a syntax error.
+ *
+ * @param message The error message.
+ * @return A JSONException object, suitable for throwing
+ */
+ public JSONException syntaxError(String message) {
+ return new JSONException(message + this.toString());
+ }
+
+
+ /**
+ * Make a printable string of this JSONTokener.
+ *
+ * @return " at {index} [character {character} line {line}]"
+ */
+ public String toString() {
+ return " at " + this.index + " [character " + this.character + " line " +
+ this.line + "]";
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/0c01d793/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONWriter.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONWriter.java b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONWriter.java
index 2ebece6..7762383 100755
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONWriter.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/json/JSONWriter.java
@@ -4,380 +4,324 @@ import java.io.IOException;
import java.io.Writer;
/*
- Copyright (c) 2006 JSON.org
+Copyright (c) 2006 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:
+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 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 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.
- */
+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.
+*/
/**
- * JSONWriter provides a quick and convenient way of producing JSON text. The texts produced
- * strictly conform to JSON syntax rules. No whitespace is added, so the results are ready for
- * transmission or storage. Each instance of JSONWriter can produce one JSON text.
+ * JSONWriter provides a quick and convenient way of producing JSON text.
+ * The texts produced strictly conform to JSON syntax rules. No whitespace is
+ * added, so the results are ready for transmission or storage. Each instance of
+ * JSONWriter can produce one JSON text.
* <p>
- * A JSONWriter instance provides a <code>value</code> method for appending values to the text, and
- * a <code>key</code> method for adding keys before values in objects. There are <code>array</code>
- * and <code>endArray</code> methods that make and bound array values, and <code>object</code> and
- * <code>endObject</code> methods which make and bound object values. All of these methods return
- * the JSONWriter instance, permitting a cascade style. For example,
- *
- * <pre>
- * new JSONWriter(myWriter).object().key("JSON").value("Hello, World!").endObject();
- * </pre>
- *
- * which writes
- *
- * <pre>
- * {"JSON":"Hello, World!"}
- * </pre>
+ * A JSONWriter instance provides a <code>value</code> method for appending
+ * values to the
+ * text, and a <code>key</code>
+ * method for adding keys before values in objects. There are <code>array</code>
+ * and <code>endArray</code> methods that make and bound array values, and
+ * <code>object</code> and <code>endObject</code> methods which make and bound
+ * object values. All of these methods return the JSONWriter instance,
+ * permitting a cascade style. For example, <pre>
+ * new JSONWriter(myWriter)
+ * .object()
+ * .key("JSON")
+ * .value("Hello, World!")
+ * .endObject();</pre> which writes <pre>
+ * {"JSON":"Hello, World!"}</pre>
* <p>
- * The first method called must be <code>array</code> or <code>object</code>. There are no methods
- * for adding commas or colons. JSONWriter adds them for you. Objects and arrays can be nested up to
- * 20 levels deep.
+ * The first method called must be <code>array</code> or <code>object</code>.
+ * There are no methods for adding commas or colons. JSONWriter adds them for
+ * you. Objects and arrays can be nested up to 20 levels deep.
* <p>
* This can sometimes be easier than using a JSONObject to build a string.
- *
* @author JSON.org
- * @version 2011-11-14
+ * @version 2011-11-24
*/
-public class JSONWriter
-{
- private static final int maxdepth = 200;
+public class JSONWriter {
+ private static final int maxdepth = 200;
- /**
- * The comma flag determines if a comma should be output before the next value.
- */
- private boolean comma;
+ /**
+ * The comma flag determines if a comma should be output before the next
+ * value.
+ */
+ private boolean comma;
- /**
- * The current mode. Values: 'a' (array), 'd' (done), 'i' (initial), 'k' (key), 'o' (object).
- */
- protected char mode;
+ /**
+ * The current mode. Values:
+ * 'a' (array),
+ * 'd' (done),
+ * 'i' (initial),
+ * 'k' (key),
+ * 'o' (object).
+ */
+ protected char mode;
- /**
- * The object/array stack.
- */
- private final JSONObject stack[];
+ /**
+ * The object/array stack.
+ */
+ private final JSONObject stack[];
- /**
- * The stack top index. A value of 0 indicates that the stack is empty.
- */
- private int top;
+ /**
+ * The stack top index. A value of 0 indicates that the stack is empty.
+ */
+ private int top;
- /**
- * The writer that will receive the output.
- */
- protected Writer writer;
+ /**
+ * The writer that will receive the output.
+ */
+ protected Writer writer;
- /**
- * Make a fresh JSONWriter. It can be used to build one JSON text.
- */
- public JSONWriter(Writer w)
- {
- comma = false;
- mode = 'i';
- stack = new JSONObject[maxdepth];
- top = 0;
- writer = w;
- }
+ /**
+ * Make a fresh JSONWriter. It can be used to build one JSON text.
+ */
+ public JSONWriter(Writer w) {
+ this.comma = false;
+ this.mode = 'i';
+ this.stack = new JSONObject[maxdepth];
+ this.top = 0;
+ this.writer = w;
+ }
- /**
- * Append a value.
- *
- * @param string
- * A string value.
- * @return this
- * @throws JSONException
- * If the value is out of sequence.
- */
- private JSONWriter append(String string) throws JSONException
- {
- if (string == null)
- {
- throw new JSONException("Null pointer");
- }
- if (mode == 'o' || mode == 'a')
- {
- try
- {
- if (comma && mode == 'a')
- {
- writer.write(',');
- }
- writer.write(string);
- }
- catch (IOException e)
- {
- throw new JSONException(e);
- }
- if (mode == 'o')
- {
- mode = 'k';
- }
- comma = true;
- return this;
- }
- throw new JSONException("Value out of sequence.");
- }
+ /**
+ * Append a value.
+ * @param string A string value.
+ * @return this
+ * @throws JSONException If the value is out of sequence.
+ */
+ private JSONWriter append(String string) throws JSONException {
+ if (string == null) {
+ throw new JSONException("Null pointer");
+ }
+ if (this.mode == 'o' || this.mode == 'a') {
+ try {
+ if (this.comma && this.mode == 'a') {
+ this.writer.write(',');
+ }
+ this.writer.write(string);
+ } catch (IOException e) {
+ throw new JSONException(e);
+ }
+ if (this.mode == 'o') {
+ this.mode = 'k';
+ }
+ this.comma = true;
+ return this;
+ }
+ throw new JSONException("Value out of sequence.");
+ }
- /**
- * Begin appending a new array. All values until the balancing <code>endArray</code> will be
- * appended to this array. The <code>endArray</code> method must be called to mark the array's
- * end.
- *
- * @return this
- * @throws JSONException
- * If the nesting is too deep, or if the object is started in the wrong place (for
- * example as a key or after the end of the outermost array or object).
- */
- public JSONWriter array() throws JSONException
- {
- if (mode == 'i' || mode == 'o' || mode == 'a')
- {
- push(null);
- append("[");
- comma = false;
- return this;
- }
- throw new JSONException("Misplaced array.");
- }
+ /**
+ * Begin appending a new array. All values until the balancing
+ * <code>endArray</code> will be appended to this array. The
+ * <code>endArray</code> method must be called to mark the array's end.
+ * @return this
+ * @throws JSONException If the nesting is too deep, or if the object is
+ * started in the wrong place (for example as a key or after the end of the
+ * outermost array or object).
+ */
+ public JSONWriter array() throws JSONException {
+ if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {
+ this.push(null);
+ this.append("[");
+ this.comma = false;
+ return this;
+ }
+ throw new JSONException("Misplaced array.");
+ }
- /**
- * End something.
- *
- * @param mode
- * Mode
- * @param c
- * Closing character
- * @return this
- * @throws JSONException
- * If unbalanced.
- */
- private JSONWriter end(char mode, char c) throws JSONException
- {
- if (this.mode != mode)
- {
- throw new JSONException(mode == 'a' ? "Misplaced endArray." : "Misplaced endObject.");
- }
- pop(mode);
- try
- {
- writer.write(c);
- }
- catch (IOException e)
- {
- throw new JSONException(e);
- }
- comma = true;
- return this;
- }
+ /**
+ * End something.
+ * @param mode Mode
+ * @param c Closing character
+ * @return this
+ * @throws JSONException If unbalanced.
+ */
+ private JSONWriter end(char mode, char c) throws JSONException {
+ if (this.mode != mode) {
+ throw new JSONException(mode == 'a'
+ ? "Misplaced endArray."
+ : "Misplaced endObject.");
+ }
+ this.pop(mode);
+ try {
+ this.writer.write(c);
+ } catch (IOException e) {
+ throw new JSONException(e);
+ }
+ this.comma = true;
+ return this;
+ }
- /**
- * End an array. This method most be called to balance calls to <code>array</code>.
- *
- * @return this
- * @throws JSONException
- * If incorrectly nested.
- */
- public JSONWriter endArray() throws JSONException
- {
- return end('a', ']');
- }
+ /**
+ * End an array. This method most be called to balance calls to
+ * <code>array</code>.
+ * @return this
+ * @throws JSONException If incorrectly nested.
+ */
+ public JSONWriter endArray() throws JSONException {
+ return this.end('a', ']');
+ }
- /**
- * End an object. This method most be called to balance calls to <code>object</code>.
- *
- * @return this
- * @throws JSONException
- * If incorrectly nested.
- */
- public JSONWriter endObject() throws JSONException
- {
- return end('k', '}');
- }
+ /**
+ * End an object. This method most be called to balance calls to
+ * <code>object</code>.
+ * @return this
+ * @throws JSONException If incorrectly nested.
+ */
+ public JSONWriter endObject() throws JSONException {
+ return this.end('k', '}');
+ }
- /**
- * Append a key. The key will be associated with the next value. In an object, every value must
- * be preceded by a key.
- *
- * @param string
- * A key string.
- * @return this
- * @throws JSONException
- * If the key is out of place. For example, keys do not belong in arrays or if the
- * key is null.
- */
- public JSONWriter key(String string) throws JSONException
- {
- if (string == null)
- {
- throw new JSONException("Null key.");
- }
- if (mode == 'k')
- {
- try
- {
- stack[top - 1].putOnce(string, Boolean.TRUE);
- if (comma)
- {
- writer.write(',');
- }
- writer.write(JSONObject.quote(string));
- writer.write(':');
- comma = false;
- mode = 'o';
- return this;
- }
- catch (IOException e)
- {
- throw new JSONException(e);
- }
- }
- throw new JSONException("Misplaced key.");
- }
+ /**
+ * Append a key. The key will be associated with the next value. In an
+ * object, every value must be preceded by a key.
+ * @param string A key string.
+ * @return this
+ * @throws JSONException If the key is out of place. For example, keys
+ * do not belong in arrays or if the key is null.
+ */
+ public JSONWriter key(String string) throws JSONException {
+ if (string == null) {
+ throw new JSONException("Null key.");
+ }
+ if (this.mode == 'k') {
+ try {
+ this.stack[this.top - 1].putOnce(string, Boolean.TRUE);
+ if (this.comma) {
+ this.writer.write(',');
+ }
+ this.writer.write(JSONObject.quote(string));
+ this.writer.write(':');
+ this.comma = false;
+ this.mode = 'o';
+ return this;
+ } catch (IOException e) {
+ throw new JSONException(e);
+ }
+ }
+ throw new JSONException("Misplaced key.");
+ }
- /**
- * Begin appending a new object. All keys and values until the balancing <code>endObject</code>
- * will be appended to this object. The <code>endObject</code> method must be called to mark the
- * object's end.
- *
- * @return this
- * @throws JSONException
- * If the nesting is too deep, or if the object is started in the wrong place (for
- * example as a key or after the end of the outermost array or object).
- */
- public JSONWriter object() throws JSONException
- {
- if (mode == 'i')
- {
- mode = 'o';
- }
- if (mode == 'o' || mode == 'a')
- {
- append("{");
- push(new JSONObject());
- comma = false;
- return this;
- }
- throw new JSONException("Misplaced object.");
+ /**
+ * Begin appending a new object. All keys and values until the balancing
+ * <code>endObject</code> will be appended to this object. The
+ * <code>endObject</code> method must be called to mark the object's end.
+ * @return this
+ * @throws JSONException If the nesting is too deep, or if the object is
+ * started in the wrong place (for example as a key or after the end of the
+ * outermost array or object).
+ */
+ public JSONWriter object() throws JSONException {
+ if (this.mode == 'i') {
+ this.mode = 'o';
+ }
+ if (this.mode == 'o' || this.mode == 'a') {
+ this.append("{");
+ this.push(new JSONObject());
+ this.comma = false;
+ return this;
+ }
+ throw new JSONException("Misplaced object.");
- }
+ }
- /**
- * Pop an array or object scope.
- *
- * @param c
- * The scope to close.
- * @throws JSONException
- * If nesting is wrong.
- */
- private void pop(char c) throws JSONException
- {
- if (top <= 0)
- {
- throw new JSONException("Nesting error.");
- }
- char m = stack[top - 1] == null ? 'a' : 'k';
- if (m != c)
- {
- throw new JSONException("Nesting error.");
- }
- top -= 1;
- mode = top == 0 ? 'd' : stack[top - 1] == null ? 'a' : 'k';
- }
+ /**
+ * Pop an array or object scope.
+ * @param c The scope to close.
+ * @throws JSONException If nesting is wrong.
+ */
+ private void pop(char c) throws JSONException {
+ if (this.top <= 0) {
+ throw new JSONException("Nesting error.");
+ }
+ char m = this.stack[this.top - 1] == null ? 'a' : 'k';
+ if (m != c) {
+ throw new JSONException("Nesting error.");
+ }
+ this.top -= 1;
+ this.mode = this.top == 0
+ ? 'd'
+ : this.stack[this.top - 1] == null
+ ? 'a'
+ : 'k';
+ }
- /**
- * Push an array or object scope.
- *
- * @param c
- * The scope to open.
- * @throws JSONException
- * If nesting is too deep.
- */
- private void push(JSONObject jo) throws JSONException
- {
- if (top >= maxdepth)
- {
- throw new JSONException("Nesting too deep.");
- }
- stack[top] = jo;
- mode = jo == null ? 'a' : 'k';
- top += 1;
- }
+ /**
+ * Push an array or object scope.
+ * @param c The scope to open.
+ * @throws JSONException If nesting is too deep.
+ */
+ private void push(JSONObject jo) throws JSONException {
+ if (this.top >= maxdepth) {
+ throw new JSONException("Nesting too deep.");
+ }
+ this.stack[this.top] = jo;
+ this.mode = jo == null ? 'a' : 'k';
+ this.top += 1;
+ }
- /**
- * Append either the value <code>true</code> or the value <code>false</code>.
- *
- * @param b
- * A boolean.
- * @return this
- * @throws JSONException
- */
- public JSONWriter value(boolean b) throws JSONException
- {
- return append(b ? "true" : "false");
- }
+ /**
+ * Append either the value <code>true</code> or the value
+ * <code>false</code>.
+ * @param b A boolean.
+ * @return this
+ * @throws JSONException
+ */
+ public JSONWriter value(boolean b) throws JSONException {
+ return this.append(b ? "true" : "false");
+ }
- /**
- * Append a double value.
- *
- * @param d
- * A double.
- * @return this
- * @throws JSONException
- * If the number is not finite.
- */
- public JSONWriter value(double d) throws JSONException
- {
- return this.value(new Double(d));
- }
+ /**
+ * Append a double value.
+ * @param d A double.
+ * @return this
+ * @throws JSONException If the number is not finite.
+ */
+ public JSONWriter value(double d) throws JSONException {
+ return this.value(new Double(d));
+ }
- /**
- * Append a long value.
- *
- * @param l
- * A long.
- * @return this
- * @throws JSONException
- */
- public JSONWriter value(long l) throws JSONException
- {
- return append(Long.toString(l));
- }
+ /**
+ * Append a long value.
+ * @param l A long.
+ * @return this
+ * @throws JSONException
+ */
+ public JSONWriter value(long l) throws JSONException {
+ return this.append(Long.toString(l));
+ }
- /**
- * Append an object value.
- *
- * @param object
- * The object to append. It can be null, or a Boolean, Number, String, JSONObject, or
- * JSONArray, or an object that implements JSONString.
- * @return this
- * @throws JSONException
- * If the value is out of sequence.
- */
- public JSONWriter value(Object object) throws JSONException
- {
- return append(JSONObject.valueToString(object));
- }
+ /**
+ * Append an object value.
+ * @param object The object to append. It can be null, or a Boolean, Number,
+ * String, JSONObject, or JSONArray, or an object that implements JSONString.
+ * @return this
+ * @throws JSONException If the value is out of sequence.
+ */
+ public JSONWriter value(Object object) throws JSONException {
+ return this.append(JSONObject.valueToString(object));
+ }
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/0c01d793/wicket-core/src/main/java/org/apache/wicket/ajax/json/README
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/json/README b/wicket-core/src/main/java/org/apache/wicket/ajax/json/README
new file mode 100644
index 0000000..6a06271
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/json/README
@@ -0,0 +1,2 @@
+These classes are copied from https://github.com/douglascrockford/JSON-java.
+Last update: May 18 2012
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/0c01d793/wicket-core/src/main/java/org/apache/wicket/ajax/json/XML.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/json/XML.java b/wicket-core/src/main/java/org/apache/wicket/ajax/json/XML.java
index 19ff462..b8705d6 100755
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/json/XML.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/json/XML.java
@@ -1,636 +1,508 @@
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.
- */
+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.util.Iterator;
/**
- * This provides static methods to convert an XML text into a JSONObject, and to covert a JSONObject
- * into an XML text.
- *
+ * This provides static methods to convert an XML text into a JSONObject,
+ * and to covert a JSONObject into an XML text.
* @author JSON.org
* @version 2011-02-11
*/
-public class XML
-{
-
- /** The Character '&'. */
- public static final Character AMP = new Character('&');
-
- /** The Character '''. */
- public static final Character APOS = new Character('\'');
-
- /** The Character '!'. */
- public static final Character BANG = new Character('!');
-
- /** The Character '='. */
- public static final Character EQ = new Character('=');
-
- /** The Character '>'. */
- public static final Character GT = new Character('>');
-
-/** The Character '<'. */
- public static final Character LT = new Character('<');
-
- /** The Character '?'. */
- public static final Character QUEST = new Character('?');
-
- /** The Character '"'. */
- public static final Character QUOT = new Character('"');
-
- /** The Character '/'. */
- public static final Character SLASH = new Character('/');
-
- /**
- * Replace special characters with XML escapes:
- *
- * <pre>
- * & <small>(ampersand)</small> is replaced by &amp;
- * < <small>(less than)</small> is replaced by &lt;
- * > <small>(greater than)</small> is replaced by &gt;
- * " <small>(double quote)</small> is replaced by &quot;
- * </pre>
- *
- * @param string
- * The string to be escaped.
- * @return The escaped string.
- */
- public static String escape(String string)
- {
- StringBuffer sb = new StringBuffer();
- for (int i = 0, length = string.length(); i < length; i++)
- {
- char c = string.charAt(i);
- switch (c)
- {
- case '&' :
- sb.append("&");
- break;
- case '<' :
- sb.append("<");
- break;
- case '>' :
- sb.append(">");
- break;
- case '"' :
- sb.append(""");
- break;
- case '\'' :
- sb.append("'");
- break;
- default :
- sb.append(c);
- }
- }
- return sb.toString();
- }
-
- /**
- * Throw an exception if the string contains whitespace. Whitespace is not allowed in tagNames
- * and attributes.
- *
- * @param string
- * @throws JSONException
- */
- public static void noSpace(String string) throws JSONException
- {
- int i, length = string.length();
- if (length == 0)
- {
- throw new JSONException("Empty string.");
- }
- for (i = 0; i < length; i += 1)
- {
- if (Character.isWhitespace(string.charAt(i)))
- {
- throw new JSONException("'" + string + "' contains a space character.");
- }
- }
- }
-
- /**
- * Scan the content following the named tag, attaching it to the context.
- *
- * @param x
- * The XMLTokener containing the source string.
- * @param context
- * The JSONObject that will include the new material.
- * @param name
- * The tag name.
- * @return true if the close tag is processed.
- * @throws JSONException
- */
- private static boolean parse(XMLTokener x, JSONObject context, String name)
- throws JSONException
- {
- char c;
- int i;
- JSONObject jsonobject = null;
- String string;
- String tagName;
- Object token;
+public class XML {
+
+ /** The Character '&'. */
+ public static final Character AMP = new Character('&');
+
+ /** The Character '''. */
+ public static final Character APOS = new Character('\'');
+
+ /** The Character '!'. */
+ public static final Character BANG = new Character('!');
+
+ /** The Character '='. */
+ public static final Character EQ = new Character('=');
+
+ /** The Character '>'. */
+ public static final Character GT = new Character('>');
+
+ /** The Character '<'. */
+ public static final Character LT = new Character('<');
+
+ /** The Character '?'. */
+ public static final Character QUEST = new Character('?');
+
+ /** The Character '"'. */
+ public static final Character QUOT = new Character('"');
+
+ /** The Character '/'. */
+ public static final Character SLASH = new Character('/');
+
+ /**
+ * Replace special characters with XML escapes:
+ * <pre>
+ * & <small>(ampersand)</small> is replaced by &amp;
+ * < <small>(less than)</small> is replaced by &lt;
+ * > <small>(greater than)</small> is replaced by &gt;
+ * " <small>(double quote)</small> is replaced by &quot;
+ * </pre>
+ * @param string The string to be escaped.
+ * @return The escaped string.
+ */
+ public static String escape(String string) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0, length = string.length(); i < length; i++) {
+ char c = string.charAt(i);
+ switch (c) {
+ case '&':
+ sb.append("&");
+ break;
+ case '<':
+ sb.append("<");
+ break;
+ case '>':
+ sb.append(">");
+ break;
+ case '"':
+ sb.append(""");
+ break;
+ case '\'':
+ sb.append("'");
+ break;
+ default:
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Throw an exception if the string contains whitespace.
+ * Whitespace is not allowed in tagNames and attributes.
+ * @param string
+ * @throws JSONException
+ */
+ public static void noSpace(String string) throws JSONException {
+ int i, length = string.length();
+ if (length == 0) {
+ throw new JSONException("Empty string.");
+ }
+ for (i = 0; i < length; i += 1) {
+ if (Character.isWhitespace(string.charAt(i))) {
+ throw new JSONException("'" + string +
+ "' contains a space character.");
+ }
+ }
+ }
+
+ /**
+ * Scan the content following the named tag, attaching it to the context.
+ * @param x The XMLTokener containing the source string.
+ * @param context The JSONObject that will include the new material.
+ * @param name The tag name.
+ * @return true if the close tag is processed.
+ * @throws JSONException
+ */
+ private static boolean parse(XMLTokener x, JSONObject context,
+ String name) throws JSONException {
+ char c;
+ int i;
+ JSONObject jsonobject = null;
+ String string;
+ String tagName;
+ Object token;
// Test for and skip past these forms:
-// <!-- ... -->
-// <! ... >
-// <![ ... ]]>
-// <? ... ?>
+// <!-- ... -->
+// <! ... >
+// <![ ... ]]>
+// <? ... ?>
// Report errors for these forms:
-// <>
-// <=
-// <<
+// <>
+// <=
+// <<
- token = x.nextToken();
+ token = x.nextToken();
// <!
- if (token == BANG)
- {
- c = x.next();
- if (c == '-')
- {
- if (x.next() == '-')
- {
- x.skipPast("-->");
- return false;
- }
- x.back();
- }
- else if (c == '[')
- {
- token = x.nextToken();
- if (token.equals("CDATA"))
- {
- if (x.next() == '[')
- {
- string = x.nextCDATA();
- if (string.length() > 0)
- {
- context.accumulate("content", string);
- }
- return false;
- }
- }
- throw x.syntaxError("Expected 'CDATA['");
- }
- i = 1;
- do
- {
- token = x.nextMeta();
- if (token == null)
- {
- throw x.syntaxError("Missing '>' after '<!'.");
- }
- else if (token == LT)
- {
- i += 1;
- }
- else if (token == GT)
- {
- i -= 1;
- }
- }
- while (i > 0);
- return false;
- }
- else if (token == QUEST)
- {
+ if (token == BANG) {
+ c = x.next();
+ if (c == '-') {
+ if (x.next() == '-') {
+ x.skipPast("-->");
+ return false;
+ }
+ x.back();
+ } else if (c == '[') {
+ token = x.nextToken();
+ if ("CDATA".equals(token)) {
+ if (x.next() == '[') {
+ string = x.nextCDATA();
+ if (string.length() > 0) {
+ context.accumulate("content", string);
+ }
+ return false;
+ }
+ }
+ throw x.syntaxError("Expected 'CDATA['");
+ }
+ i = 1;
+ do {
+ token = x.nextMeta();
+ if (token == null) {
+ throw x.syntaxError("Missing '>' after '<!'.");
+ } else if (token == LT) {
+ i += 1;
+ } else if (token == GT) {
+ i -= 1;
+ }
+ } while (i > 0);
+ return false;
+ } else if (token == QUEST) {
// <?
- x.skipPast("?>");
- return false;
- }
- else if (token == SLASH)
- {
+ x.skipPast("?>");
+ return false;
+ } else if (token == SLASH) {
// Close tag </
- token = x.nextToken();
- if (name == null)
- {
- throw x.syntaxError("Mismatched close tag " + token);
- }
- if (!token.equals(name))
- {
- throw x.syntaxError("Mismatched " + name + " and " + token);
- }
- if (x.nextToken() != GT)
- {
- throw x.syntaxError("Misshaped close tag");
- }
- return true;
-
- }
- else if (token instanceof Character)
- {
- throw x.syntaxError("Misshaped tag");
+ token = x.nextToken();
+ if (name == null) {
+ throw x.syntaxError("Mismatched close tag " + token);
+ }
+ if (!token.equals(name)) {
+ throw x.syntaxError("Mismatched " + name + " and " + token);
+ }
+ if (x.nextToken() != GT) {
+ throw x.syntaxError("Misshaped close tag");
+ }
+ return true;
+
+ } else if (token instanceof Character) {
+ throw x.syntaxError("Misshaped tag");
// Open tag <
- }
- else
- {
- tagName = (String)token;
- token = null;
- jsonobject = new JSONObject();
- for (;;)
- {
- if (token == null)
- {
- token = x.nextToken();
- }
+ } else {
+ tagName = (String)token;
+ token = null;
+ jsonobject = new JSONObject();
+ for (;;) {
+ if (token == null) {
+ token = x.nextToken();
+ }
// attribute = value
- if (token instanceof String)
- {
- string = (String)token;
- token = x.nextToken();
- if (token == EQ)
- {
- token = x.nextToken();
- if (!(token instanceof String))
- {
- throw x.syntaxError("Missing value");
- }
- jsonobject.accumulate(string, XML.stringToValue((String)token));
- token = null;
- }
- else
- {
- jsonobject.accumulate(string, "");
- }
+ if (token instanceof String) {
+ string = (String)token;
+ token = x.nextToken();
+ if (token == EQ) {
+ token = x.nextToken();
+ if (!(token instanceof String)) {
+ throw x.syntaxError("Missing value");
+ }
+ jsonobject.accumulate(string,
+ XML.stringToValue((String)token));
+ token = null;
+ } else {
+ jsonobject.accumulate(string, "");
+ }
// Empty tag <.../>
- }
- else if (token == SLASH)
- {
- if (x.nextToken() != GT)
- {
- throw x.syntaxError("Misshaped tag");
- }
- if (jsonobject.length() > 0)
- {
- context.accumulate(tagName, jsonobject);
- }
- else
- {
- context.accumulate(tagName, "");
- }
- return false;
+ } else if (token == SLASH) {
+ if (x.nextToken() != GT) {
+ throw x.syntaxError("Misshaped tag");
+ }
+ if (jsonobject.length() > 0) {
+ context.accumulate(tagName, jsonobject);
+ } else {
+ context.accumulate(tagName, "");
+ }
+ return false;
// Content, between <...> and </...>
- }
- else if (token == GT)
- {
- for (;;)
- {
- token = x.nextContent();
- if (token == null)
- {
- if (tagName != null)
- {
- throw x.syntaxError("Unclosed tag " + tagName);
- }
- return false;
- }
- else if (token instanceof String)
- {
- string = (String)token;
- if (string.length() > 0)
- {
- jsonobject.accumulate("content", XML.stringToValue(string));
- }
+ } else if (token == GT) {
+ for (;;) {
+ token = x.nextContent();
+ if (token == null) {
+ if (tagName != null) {
+ throw x.syntaxError("Unclosed tag " + tagName);
+ }
+ return false;
+ } else if (token instanceof String) {
+ string = (String)token;
+ if (string.length() > 0) {
+ jsonobject.accumulate("content",
+ XML.stringToValue(string));
+ }
// Nested element
- }
- else if (token == LT)
- {
- if (parse(x, jsonobject, tagName))
- {
- if (jsonobject.length() == 0)
- {
- context.accumulate(tagName, "");
- }
- else if (jsonobject.length() == 1 &&
- jsonobject.opt("content") != null)
- {
- context.accumulate(tagName, jsonobject.opt("content"));
- }
- else
- {
- context.accumulate(tagName, jsonobject);
- }
- return false;
- }
- }
- }
- }
- else
- {
- throw x.syntaxError("Misshaped tag");
- }
- }
- }
- }
-
-
- /**
- * Try to convert a string into a number, boolean, or null. If the string can't be converted,
- * return the string. This is much less ambitious than JSONObject.stringToValue, especially
- * because it does not attempt to convert plus forms, octal forms, hex forms, or E forms lacking
- * decimal points.
- *
- * @param string
- * A String.
- * @return A simple JSON value.
- */
- public static Object stringToValue(String string)
- {
- if (string.equals(""))
- {
- return string;
- }
- if (string.equalsIgnoreCase("true"))
- {
- return Boolean.TRUE;
- }
- if (string.equalsIgnoreCase("false"))
- {
- return Boolean.FALSE;
- }
- if (string.equalsIgnoreCase("null"))
- {
- return JSONObject.NULL;
- }
- if (string.equals("0"))
- {
- return new Integer(0);
- }
-
-// If it might be a number, try converting it. If that doesn't work,
+ } else if (token == LT) {
+ if (parse(x, jsonobject, tagName)) {
+ if (jsonobject.length() == 0) {
+ context.accumulate(tagName, "");
+ } else if (jsonobject.length() == 1 &&
+ jsonobject.opt("content") != null) {
+ context.accumulate(tagName,
+ jsonobject.opt("content"));
+ } else {
+ context.accumulate(tagName, jsonobject);
+ }
+ return false;
+ }
+ }
+ }
+ } else {
+ throw x.syntaxError("Misshaped tag");
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Try to convert a string into a number, boolean, or null. If the string
+ * can't be converted, return the string. This is much less ambitious than
+ * JSONObject.stringToValue, especially because it does not attempt to
+ * convert plus forms, octal forms, hex forms, or E forms lacking decimal
+ * points.
+ * @param string A String.
+ * @return A simple JSON value.
+ */
+ public static Object stringToValue(String string) {
+ if ("".equals(string)) {
+ return string;
+ }
+ if ("true".equalsIgnoreCase(string)) {
+ return Boolean.TRUE;
+ }
+ if ("false".equalsIgnoreCase(string)) {
+ return Boolean.FALSE;
+ }
+ if ("null".equalsIgnoreCase(string)) {
+ return JSONObject.NULL;
+ }
+ if ("0".equals(string)) {
+ return new Integer(0);
+ }
+
+// If it might be a number, try converting it. If that doesn't work,
// return the string.
- try
- {
- char initial = string.charAt(0);
- boolean negative = false;
- if (initial == '-')
- {
- initial = string.charAt(1);
- negative = true;
- }
- if (initial == '0' && string.charAt(negative ? 2 : 1) == '0')
- {
- return string;
- }
- if ((initial >= '0' && initial <= '9'))
- {
- if (string.indexOf('.') >= 0)
- {
- return Double.valueOf(string);
- }
- else if (string.indexOf('e') < 0 && string.indexOf('E') < 0)
- {
- Long myLong = new Long(string);
- if (myLong.longValue() == myLong.intValue())
- {
- return new Integer(myLong.intValue());
- }
- else
- {
- return myLong;
- }
- }
- }
- }
- catch (Exception ignore)
- {
- }
- return string;
- }
-
-
- /**
- * Convert a well-formed (but not necessarily valid) XML string into a JSONObject. Some
- * information may be lost in this transformation because JSON is a data format and XML is a
- * document format. XML uses elements, attributes, and content text, while JSON uses unordered
- * collections of name/value pairs and arrays of values. JSON does not does not like to
- * distinguish between elements and attributes. Sequences of similar elements are represented as
- * JSONArrays. Content text may be placed in a "content" member. Comments, prologs, DTDs, and
- * <code><[ [ ]]></code> are ignored.
- *
- * @param string
- * The source string.
- * @return A JSONObject containing the structured data from the XML string.
- * @throws JSONException
- */
- public static JSONObject toJSONObject(String string) throws JSONException
- {
- JSONObject jo = new JSONObject();
- XMLTokener x = new XMLTokener(string);
- while (x.more() && x.skipPast("<"))
- {
- parse(x, jo, null);
- }
- return jo;
- }
-
-
- /**
- * Convert a JSONObject into a well-formed, element-normal XML string.
- *
- * @param object
- * A JSONObject.
- * @return A string.
- * @throws JSONException
- */
- public static String toString(Object object) throws JSONException
- {
- return toString(object, null);
- }
-
-
- /**
- * Convert a JSONObject into a well-formed, element-normal XML string.
- *
- * @param object
- * A JSONObject.
- * @param tagName
- * The optional name of the enclosing tag.
- * @return A string.
- * @throws JSONException
- */
- public static String toString(Object object, String tagName) throws JSONException
- {
- StringBuffer sb = new StringBuffer();
- int i;
- JSONArray ja;
- JSONObject jo;
- String key;
- Iterator keys;
- int length;
- String string;
- Object value;
- if (object instanceof JSONObject)
- {
+ try {
+ char initial = string.charAt(0);
+ boolean negative = false;
+ if (initial == '-') {
+ initial = string.charAt(1);
+ negative = true;
+ }
+ if (initial == '0' && string.charAt(negative ? 2 : 1) == '0') {
+ return string;
+ }
+ if ((initial >= '0' && initial <= '9')) {
+ if (string.indexOf('.') >= 0) {
+ return Double.valueOf(string);
+ } else if (string.indexOf('e') < 0 && string.indexOf('E') < 0) {
+ Long myLong = new Long(string);
+ if (myLong.longValue() == myLong.intValue()) {
+ return new Integer(myLong.intValue());
+ } else {
+ return myLong;
+ }
+ }
+ }
+ } catch (Exception ignore) {
+ }
+ return string;
+ }
+
+
+ /**
+ * Convert a well-formed (but not necessarily valid) XML string into a
+ * JSONObject. Some information may be lost in this transformation
+ * because JSON is a data format and XML is a document format. XML uses
+ * elements, attributes, and content text, while JSON uses unordered
+ * collections of name/value pairs and arrays of values. JSON does not
+ * does not like to distinguish between elements and attributes.
+ * Sequences of similar elements are represented as JSONArrays. Content
+ * text may be placed in a "content" member. Comments, prologs, DTDs, and
+ * <code><[ [ ]]></code> are ignored.
+ * @param string The source string.
+ * @return A JSONObject containing the structured data from the XML string.
+ * @throws JSONException
+ */
+ public static JSONObject toJSONObject(String string) throws JSONException {
+ JSONObject jo = new JSONObject();
+ XMLTokener x = new XMLTokener(string);
+ while (x.more() && x.skipPast("<")) {
+ parse(x, jo, null);
+ }
+ return jo;
+ }
+
+
+ /**
+ * Convert a JSONObject into a well-formed, element-normal XML string.
+ * @param object A JSONObject.
+ * @return A string.
+ * @throws JSONException
+ */
+ public static String toString(Object object) throws JSONException {
+ return toString(object, null);
+ }
+
+
+ /**
+ * Convert a JSONObject into a well-formed, element-normal XML string.
+ * @param object A JSONObject.
+ * @param tagName The optional name of the enclosing tag.
+ * @return A string.
+ * @throws JSONException
+ */
+ public static String toString(Object object, String tagName)
+ throws JSONException {
+ StringBuffer sb = new StringBuffer();
+ int i;
+ JSONArray ja;
+ JSONObject jo;
+ String key;
+ Iterator keys;
+ int length;
+ String string;
+ Object value;
+ if (object instanceof JSONObject) {
// Emit <tagName>
- if (tagName != null)
- {
- sb.append('<');
- sb.append(tagName);
- sb.append('>');
- }
+ if (tagName != null) {
+ sb.append('<');
+ sb.append(tagName);
+ sb.append('>');
+ }
// Loop thru the keys.
- jo = (JSONObject)object;
- keys = jo.keys();
- while (keys.hasNext())
- {
- key = keys.next().toString();
- value = jo.opt(key);
- if (value == null)
- {
- value = "";
- }
- if (value instanceof String)
- {
- string = (String)value;
- }
- else
- {
- string = null;
- }
+ jo = (JSONObject)object;
+ keys = jo.keys();
+ while (keys.hasNext()) {
+ key = keys.next().toString();
+ value = jo.opt(key);
+ if (value == null) {
+ value = "";
+ }
+ if (value instanceof String) {
+ string = (String)value;
+ } else {
+ string = null;
+ }
// Emit content in body
- if (key.equals("content"))
- {
- if (value instanceof JSONArray)
- {
- ja = (JSONArray)value;
- length = ja.length();
- for (i = 0; i < length; i += 1)
- {
- if (i > 0)
- {
- sb.append('\n');
- }
- sb.append(escape(ja.get(i).toString()));
- }
- }
- else
- {
- sb.append(escape(value.toString()));
- }
+ if ("content".equals(key)) {
+ if (value instanceof JSONArray) {
+ ja = (JSONArray)value;
+ length = ja.length();
+ for (i = 0; i < length; i += 1) {
+ if (i > 0) {
+ sb.append('\n');
+ }
+ sb.append(escape(ja.get(i).toString()));
+ }
+ } else {
+ sb.append(escape(value.toString()));
+ }
// Emit an array of similar keys
- }
- else if (value instanceof JSONArray)
- {
- ja = (JSONArray)value;
- length = ja.length();
- for (i = 0; i < length; i += 1)
- {
- value = ja.get(i);
- if (value instanceof JSONArray)
- {
- sb.append('<');
- sb.append(key);
- sb.append('>');
- sb.append(toString(value));
- sb.append("</");
- sb.append(key);
- sb.append('>');
- }
- else
- {
- sb.append(toString(value, key));
- }
- }
- }
- else if (value.equals(""))
- {
- sb.append('<');
- sb.append(key);
- sb.append("/>");
+ } else if (value instanceof JSONArray) {
+ ja = (JSONArray)value;
+ length = ja.length();
+ for (i = 0; i < length; i += 1) {
+ value = ja.get(i);
+ if (value instanceof JSONArray) {
+ sb.append('<');
+ sb.append(key);
+ sb.append('>');
+ sb.append(toString(value));
+ sb.append("</");
+ sb.append(key);
+ sb.append('>');
+ } else {
+ sb.append(toString(value, key));
+ }
+ }
+ } else if ("".equals(value)) {
+ sb.append('<');
+ sb.append(key);
+ sb.append("/>");
// Emit a new tag <k>
- }
- else
- {
- sb.append(toString(value, key));
- }
- }
- if (tagName != null)
- {
+ } else {
+ sb.append(toString(value, key));
+ }
+ }
+ if (tagName != null) {
// Emit the </tagname> close tag
- sb.append("</");
- sb.append(tagName);
- sb.append('>');
- }
- return sb.toString();
+ sb.append("</");
+ sb.append(tagName);
+ sb.append('>');
+ }
+ return sb.toString();
// XML does not have good support for arrays. If an array appears in a place
// where XML is lacking, synthesize an <array> element.
- }
- else
- {
- if (object.getClass().isArray())
- {
- object = new JSONArray(object);
- }
- if (object instanceof JSONArray)
- {
- ja = (JSONArray)object;
- length = ja.length();
- for (i = 0; i < length; i += 1)
- {
- sb.append(toString(ja.opt(i), tagName == null ? "array" : tagName));
- }
- return sb.toString();
- }
- else
- {
- string = (object == null) ? "null" : escape(object.toString());
- return (tagName == null) ? "\"" + string + "\"" : (string.length() == 0) ? "<" +
- tagName + "/>" : "<" + tagName + ">" + string + "</" + tagName + ">";
- }
- }
- }
+ } else {
+ if (object.getClass().isArray()) {
+ object = new JSONArray(object);
+ }
+ if (object instanceof JSONArray) {
+ ja = (JSONArray)object;
+ length = ja.length();
+ for (i = 0; i < length; i += 1) {
+ sb.append(toString(ja.opt(i), tagName == null ? "array" : tagName));
+ }
+ return sb.toString();
+ } else {
+ string = (object == null) ? "null" : escape(object.toString());
+ return (tagName == null) ? "\"" + string + "\"" :
+ (string.length() == 0) ? "<" + tagName + "/>" :
+ "<" + tagName + ">" + string + "</" + tagName + ">";
+ }
+ }
+ }
}
\ No newline at end of file