From 2b985bf45a500984119efaa50ae632fda98c5b02 Mon Sep 17 00:00:00 2001 From: Stefano Mazzocchi Date: Mon, 8 Feb 2010 20:46:27 +0000 Subject: [PATCH] moving json support in its own jar (code was taken today directly from json.org and compiled and packaged by me) git-svn-id: http://google-refine.googlecode.com/svn/trunk@70 7d457c2a-affb-35e4-300a-418c747d4874 --- .classpath | 1 + lib-src/json-20100208-sources.jar | Bin 0 -> 53791 bytes lib/json-20100208.jar | Bin 0 -> 47013 bytes src/main/java/org/json/CDL.java | 261 ---- src/main/java/org/json/Cookie.java | 169 --- src/main/java/org/json/CookieList.java | 90 -- src/main/java/org/json/HTTP.java | 163 --- src/main/java/org/json/HTTPTokener.java | 77 -- src/main/java/org/json/JSONArray.java | 900 ------------- src/main/java/org/json/JSONException.java | 27 - src/main/java/org/json/JSONML.java | 297 ----- src/main/java/org/json/JSONObject.java | 1390 --------------------- src/main/java/org/json/JSONString.java | 18 - src/main/java/org/json/JSONStringer.java | 78 -- src/main/java/org/json/JSONTokener.java | 463 ------- src/main/java/org/json/JSONWriter.java | 318 ----- src/main/java/org/json/Test.java | 553 -------- src/main/java/org/json/XML.java | 404 ------ src/main/java/org/json/XMLTokener.java | 293 ----- 19 files changed, 1 insertion(+), 5501 deletions(-) create mode 100644 lib-src/json-20100208-sources.jar create mode 100644 lib/json-20100208.jar delete mode 100644 src/main/java/org/json/CDL.java delete mode 100644 src/main/java/org/json/Cookie.java delete mode 100644 src/main/java/org/json/CookieList.java delete mode 100644 src/main/java/org/json/HTTP.java delete mode 100644 src/main/java/org/json/HTTPTokener.java delete mode 100644 src/main/java/org/json/JSONArray.java delete mode 100644 src/main/java/org/json/JSONException.java delete mode 100644 src/main/java/org/json/JSONML.java delete mode 100644 src/main/java/org/json/JSONObject.java delete mode 100644 src/main/java/org/json/JSONString.java delete mode 100644 src/main/java/org/json/JSONStringer.java delete mode 100644 src/main/java/org/json/JSONTokener.java delete mode 100644 src/main/java/org/json/JSONWriter.java delete mode 100644 src/main/java/org/json/Test.java delete mode 100644 src/main/java/org/json/XML.java delete mode 100644 src/main/java/org/json/XMLTokener.java diff --git a/.classpath b/.classpath index 9a0d3bcc3..7664318e6 100644 --- a/.classpath +++ b/.classpath @@ -10,5 +10,6 @@ + diff --git a/lib-src/json-20100208-sources.jar b/lib-src/json-20100208-sources.jar new file mode 100644 index 0000000000000000000000000000000000000000..031edca3db122eb6703a3fdb8dc26f2201adddf1 GIT binary patch literal 53791 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 Q`m}Wf4qUp!WZJv`0{YW+>Hq)$ literal 0 HcmV?d00001 diff --git a/lib/json-20100208.jar b/lib/json-20100208.jar new file mode 100644 index 0000000000000000000000000000000000000000..7a73fe438ea45dd1915ceb72479e940c0093bbe2 GIT binary patch literal 47013 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 - * Each row of text represents a row in a table or a data record. Each row - * ends with a NEWLINE character. Each row contains one or more values. - * Values are separated by commas. A value can contain any character except - * for comma, unless is is wrapped in single quotes or double quotes. - *

- * The first row usually contains the names of the columns. - *

- * A comma delimited list can be converted into a JSONArray of JSONObjects. - * The names for the elements in the JSONObjects can be taken from the names - * in the first row. - * @author JSON.org - * @version 2 - */ -public class CDL { - - /** - * Get the next value. The value can be wrapped in quotes. The value can - * be empty. - * @param x A JSONTokener of the source text. - * @return The value string, or null if empty. - * @throws JSONException if the quoted string is badly formed. - */ - private static String getValue(JSONTokener x) throws JSONException { - char c; - do { - c = x.next(); - } while (c <= ' ' && c != 0); - switch (c) { - case 0: - return null; - case '"': - case '\'': - return x.nextString(c); - case ',': - x.back(); - return ""; - default: - x.back(); - return x.nextTo(','); - } - } - - /** - * Produce a JSONArray of strings from a row of comma delimited values. - * @param x A JSONTokener of the source text. - * @return A JSONArray of strings. - * @throws JSONException - */ - public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException { - JSONArray ja = new JSONArray(); - for (;;) { - String value = getValue(x); - if (value == null) { - return null; - } - ja.put(value); - for (;;) { - char c = x.next(); - if (c == ',') { - break; - } - if (c != ' ') { - if (c == '\n' || c == '\r' || c == 0) { - return ja; - } - throw x.syntaxError("Bad character '" + c + "' (" + - (int)c + ")."); - } - } - } - } - - /** - * Produce a JSONObject from a row of comma delimited text, using a - * parallel JSONArray of strings to provides the names of the elements. - * @param names A JSONArray of names. This is commonly obtained from the - * first row of a comma delimited text file using the rowToJSONArray - * method. - * @param x A JSONTokener of the source text. - * @return A JSONObject combining the names and values. - * @throws JSONException - */ - public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x) - throws JSONException { - JSONArray ja = rowToJSONArray(x); - return ja != null ? ja.toJSONObject(names) : null; - } - - /** - * Produce a JSONArray of JSONObjects from a comma delimited text string, - * using the first row as a source of names. - * @param string The comma delimited text. - * @return A JSONArray of JSONObjects. - * @throws JSONException - */ - public static JSONArray toJSONArray(String string) throws JSONException { - return toJSONArray(new JSONTokener(string)); - } - - /** - * Produce a JSONArray of JSONObjects from a comma delimited text string, - * using the first row as a source of names. - * @param x The JSONTokener containing the comma delimited text. - * @return A JSONArray of JSONObjects. - * @throws JSONException - */ - public static JSONArray toJSONArray(JSONTokener x) throws JSONException { - return toJSONArray(rowToJSONArray(x), x); - } - - /** - * Produce a JSONArray of JSONObjects from a comma delimited text string - * using a supplied JSONArray as the source of element names. - * @param names A JSONArray of strings. - * @param string The comma delimited text. - * @return A JSONArray of JSONObjects. - * @throws JSONException - */ - public static JSONArray toJSONArray(JSONArray names, String string) - throws JSONException { - return toJSONArray(names, new JSONTokener(string)); - } - - /** - * Produce a JSONArray of JSONObjects from a comma delimited text string - * using a supplied JSONArray as the source of element names. - * @param names A JSONArray of strings. - * @param x A JSONTokener of the source text. - * @return A JSONArray of JSONObjects. - * @throws JSONException - */ - public static JSONArray toJSONArray(JSONArray names, JSONTokener x) - throws JSONException { - if (names == null || names.length() == 0) { - return null; - } - JSONArray ja = new JSONArray(); - for (;;) { - JSONObject jo = rowToJSONObject(names, x); - if (jo == null) { - break; - } - ja.put(jo); - } - if (ja.length() == 0) { - return null; - } - return ja; - } - - - /** - * Produce a comma delimited text row from a JSONArray. Values containing - * the comma character will be quoted. - * @param ja A JSONArray of strings. - * @return A string ending in NEWLINE. - */ - public static String rowToString(JSONArray ja) { - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < ja.length(); i += 1) { - if (i > 0) { - sb.append(','); - } - Object o = ja.opt(i); - if (o != null) { - String s = o.toString(); - if (s.indexOf(',') >= 0) { - if (s.indexOf('"') >= 0) { - sb.append('\''); - sb.append(s); - sb.append('\''); - } else { - sb.append('"'); - sb.append(s); - sb.append('"'); - } - } else { - sb.append(s); - } - } - } - sb.append('\n'); - return sb.toString(); - - } - - /** - * Produce a comma delimited text from a JSONArray of JSONObjects. The - * first row will be a list of names obtained by inspecting the first - * JSONObject. - * @param ja A JSONArray of JSONObjects. - * @return A comma delimited text. - * @throws JSONException - */ - public static String toString(JSONArray ja) throws JSONException { - JSONObject jo = ja.optJSONObject(0); - if (jo != null) { - JSONArray names = jo.names(); - if (names != null) { - return rowToString(names) + toString(names, ja); - } - } - return null; - } - - /** - * Produce a comma delimited text from a JSONArray of JSONObjects using - * a provided list of names. The list of names is not included in the - * output. - * @param names A JSONArray of strings. - * @param ja A JSONArray of JSONObjects. - * @return A comma delimited text. - * @throws JSONException - */ - public static String toString(JSONArray names, JSONArray ja) - throws JSONException { - if (names == null || names.length() == 0) { - return null; - } - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < ja.length(); i += 1) { - JSONObject jo = ja.optJSONObject(i); - if (jo != null) { - sb.append(rowToString(jo.toJSONArray(names))); - } - } - return sb.toString(); - } -} diff --git a/src/main/java/org/json/Cookie.java b/src/main/java/org/json/Cookie.java deleted file mode 100644 index bb05ebc15..000000000 --- a/src/main/java/org/json/Cookie.java +++ /dev/null @@ -1,169 +0,0 @@ -package org.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. -*/ - -/** - * Convert a web browser cookie specification to a JSONObject and back. - * JSON and Cookies are both notations for name/value pairs. - * @author JSON.org - * @version 2 - */ -public class Cookie { - - /** - * Produce a copy of a string in which the characters '+', '%', '=', ';' - * and control characters are replaced with "%hh". This is a gentle form - * of URL encoding, attempting to cause as little distortion to the - * string as possible. The characters '=' and ';' are meta characters in - * cookies. By convention, they are escaped using the URL-encoding. This is - * only a convention, not a standard. Often, cookies are expected to have - * encoded values. We encode '=' and ';' because we must. We encode '%' and - * '+' because they are meta characters in URL encoding. - * @param string The source string. - * @return The escaped result. - */ - public static String escape(String string) { - char c; - String s = string.trim(); - StringBuffer sb = new StringBuffer(); - int len = s.length(); - for (int i = 0; i < len; i += 1) { - c = s.charAt(i); - if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') { - sb.append('%'); - sb.append(Character.forDigit((char)((c >>> 4) & 0x0f), 16)); - sb.append(Character.forDigit((char)(c & 0x0f), 16)); - } else { - sb.append(c); - } - } - return sb.toString(); - } - - - /** - * Convert a cookie specification string into a JSONObject. The string - * will contain a name value pair separated by '='. The name and the value - * will be unescaped, possibly converting '+' and '%' sequences. The - * cookie properties may follow, separated by ';', also represented as - * name=value (except the secure property, which does not have a value). - * The name will be stored under the key "name", and the value will be - * stored under the key "value". This method does not do checking or - * validation of the parameters. It only converts the cookie string into - * a JSONObject. - * @param string The cookie specification string. - * @return A JSONObject containing "name", "value", and possibly other - * members. - * @throws JSONException - */ - public static JSONObject toJSONObject(String string) throws JSONException { - String n; - JSONObject o = new JSONObject(); - Object v; - JSONTokener x = new JSONTokener(string); - o.put("name", x.nextTo('=')); - x.next('='); - o.put("value", x.nextTo(';')); - x.next(); - while (x.more()) { - n = unescape(x.nextTo("=;")); - if (x.next() != '=') { - if (n.equals("secure")) { - v = Boolean.TRUE; - } else { - throw x.syntaxError("Missing '=' in cookie parameter."); - } - } else { - v = unescape(x.nextTo(';')); - x.next(); - } - o.put(n, v); - } - return o; - } - - - /** - * Convert a JSONObject into a cookie specification string. The JSONObject - * must contain "name" and "value" members. - * If the JSONObject contains "expires", "domain", "path", or "secure" - * members, they will be appended to the cookie specification string. - * All other members are ignored. - * @param o A JSONObject - * @return A cookie specification string - * @throws JSONException - */ - public static String toString(JSONObject o) throws JSONException { - StringBuffer sb = new StringBuffer(); - - sb.append(escape(o.getString("name"))); - sb.append("="); - sb.append(escape(o.getString("value"))); - if (o.has("expires")) { - sb.append(";expires="); - sb.append(o.getString("expires")); - } - if (o.has("domain")) { - sb.append(";domain="); - sb.append(escape(o.getString("domain"))); - } - if (o.has("path")) { - sb.append(";path="); - sb.append(escape(o.getString("path"))); - } - if (o.optBoolean("secure")) { - sb.append(";secure"); - } - return sb.toString(); - } - - /** - * Convert %hh sequences to single characters, and - * convert plus to space. - * @param s A string that may contain - * + (plus) and - * %hh sequences. - * @return The unescaped string. - */ - public static String unescape(String s) { - int len = s.length(); - StringBuffer b = new StringBuffer(); - for (int i = 0; i < len; ++i) { - char c = s.charAt(i); - if (c == '+') { - c = ' '; - } else if (c == '%' && i + 2 < len) { - int d = JSONTokener.dehexchar(s.charAt(i + 1)); - int e = JSONTokener.dehexchar(s.charAt(i + 2)); - if (d >= 0 && e >= 0) { - c = (char)(d * 16 + e); - i += 2; - } - } - b.append(c); - } - return b.toString(); - } -} diff --git a/src/main/java/org/json/CookieList.java b/src/main/java/org/json/CookieList.java deleted file mode 100644 index 30bbb3670..000000000 --- a/src/main/java/org/json/CookieList.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.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.util.Iterator; - -/** - * Convert a web browser cookie list string to a JSONObject and back. - * @author JSON.org - * @version 2 - */ -public class CookieList { - - /** - * Convert a cookie list into a JSONObject. A cookie list is a sequence - * of name/value pairs. The names are separated from the values by '='. - * The pairs are separated by ';'. The names and the values - * will be unescaped, possibly converting '+' and '%' sequences. - * - * To add a cookie to a cooklist, - * cookielistJSONObject.put(cookieJSONObject.getString("name"), - * cookieJSONObject.getString("value")); - * @param string A cookie list string - * @return A JSONObject - * @throws JSONException - */ - public static JSONObject toJSONObject(String string) throws JSONException { - JSONObject o = new JSONObject(); - JSONTokener x = new JSONTokener(string); - while (x.more()) { - String name = Cookie.unescape(x.nextTo('=')); - x.next('='); - o.put(name, Cookie.unescape(x.nextTo(';'))); - x.next(); - } - return o; - } - - - /** - * Convert a JSONObject into a cookie list. A cookie list is a sequence - * of name/value pairs. The names are separated from the values by '='. - * The pairs are separated by ';'. The characters '%', '+', '=', and ';' - * in the names and values are replaced by "%hh". - * @param o A JSONObject - * @return A cookie list string - * @throws JSONException - */ - public static String toString(JSONObject o) throws JSONException { - boolean b = false; - Iterator keys = o.keys(); - String s; - StringBuffer sb = new StringBuffer(); - while (keys.hasNext()) { - s = keys.next().toString(); - if (!o.isNull(s)) { - if (b) { - sb.append(';'); - } - sb.append(Cookie.escape(s)); - sb.append("="); - sb.append(Cookie.escape(o.getString(s))); - b = true; - } - } - return sb.toString(); - } -} diff --git a/src/main/java/org/json/HTTP.java b/src/main/java/org/json/HTTP.java deleted file mode 100644 index d3b62f835..000000000 --- a/src/main/java/org/json/HTTP.java +++ /dev/null @@ -1,163 +0,0 @@ -package org.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.util.Iterator; - -/** - * Convert an HTTP header to a JSONObject and back. - * @author JSON.org - * @version 2 - */ -public class HTTP { - - /** Carriage return/line feed. */ - public static final String CRLF = "\r\n"; - - /** - * Convert an HTTP header string into a JSONObject. It can be a request - * header or a response header. A request header will contain - *

{
-     *    Method: "POST" (for example),
-     *    "Request-URI": "/" (for example),
-     *    "HTTP-Version": "HTTP/1.1" (for example)
-     * }
- * A response header will contain - *
{
-     *    "HTTP-Version": "HTTP/1.1" (for example),
-     *    "Status-Code": "200" (for example),
-     *    "Reason-Phrase": "OK" (for example)
-     * }
- * In addition, the other parameters in the header will be captured, using - * the HTTP field names as JSON names, so that
-     *    Date: Sun, 26 May 2002 18:06:04 GMT
-     *    Cookie: Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s
-     *    Cache-Control: no-cache
- * become - *
{...
-     *    Date: "Sun, 26 May 2002 18:06:04 GMT",
-     *    Cookie: "Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s",
-     *    "Cache-Control": "no-cache",
-     * ...}
- * It does no further checking or conversion. It does not parse dates. - * It does not do '%' transforms on URLs. - * @param string An HTTP header string. - * @return A JSONObject containing the elements and attributes - * of the XML string. - * @throws JSONException - */ - public static JSONObject toJSONObject(String string) throws JSONException { - JSONObject o = new JSONObject(); - HTTPTokener x = new HTTPTokener(string); - String t; - - t = x.nextToken(); - if (t.toUpperCase().startsWith("HTTP")) { - -// Response - - o.put("HTTP-Version", t); - o.put("Status-Code", x.nextToken()); - o.put("Reason-Phrase", x.nextTo('\0')); - x.next(); - - } else { - -// Request - - o.put("Method", t); - o.put("Request-URI", x.nextToken()); - o.put("HTTP-Version", x.nextToken()); - } - -// Fields - - while (x.more()) { - String name = x.nextTo(':'); - x.next(':'); - o.put(name, x.nextTo('\0')); - x.next(); - } - return o; - } - - - /** - * Convert a JSONObject into an HTTP header. A request header must contain - *
{
-     *    Method: "POST" (for example),
-     *    "Request-URI": "/" (for example),
-     *    "HTTP-Version": "HTTP/1.1" (for example)
-     * }
- * A response header must contain - *
{
-     *    "HTTP-Version": "HTTP/1.1" (for example),
-     *    "Status-Code": "200" (for example),
-     *    "Reason-Phrase": "OK" (for example)
-     * }
- * Any other members of the JSONObject will be output as HTTP fields. - * The result will end with two CRLF pairs. - * @param o A JSONObject - * @return An HTTP header string. - * @throws JSONException if the object does not contain enough - * information. - */ - public static String toString(JSONObject o) throws JSONException { - Iterator keys = o.keys(); - String s; - StringBuffer sb = new StringBuffer(); - if (o.has("Status-Code") && o.has("Reason-Phrase")) { - sb.append(o.getString("HTTP-Version")); - sb.append(' '); - sb.append(o.getString("Status-Code")); - sb.append(' '); - sb.append(o.getString("Reason-Phrase")); - } else if (o.has("Method") && o.has("Request-URI")) { - sb.append(o.getString("Method")); - sb.append(' '); - sb.append('"'); - sb.append(o.getString("Request-URI")); - sb.append('"'); - sb.append(' '); - sb.append(o.getString("HTTP-Version")); - } else { - throw new JSONException("Not enough material for an HTTP header."); - } - sb.append(CRLF); - while (keys.hasNext()) { - s = keys.next().toString(); - if (!s.equals("HTTP-Version") && !s.equals("Status-Code") && - !s.equals("Reason-Phrase") && !s.equals("Method") && - !s.equals("Request-URI") && !o.isNull(s)) { - sb.append(s); - sb.append(": "); - sb.append(o.getString(s)); - sb.append(CRLF); - } - } - sb.append(CRLF); - return sb.toString(); - } -} diff --git a/src/main/java/org/json/HTTPTokener.java b/src/main/java/org/json/HTTPTokener.java deleted file mode 100644 index f2a6ba72b..000000000 --- a/src/main/java/org/json/HTTPTokener.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.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. -*/ - -/** - * The HTTPTokener extends the JSONTokener to provide additional methods - * for the parsing of HTTP headers. - * @author JSON.org - * @version 2 - */ -public class HTTPTokener extends JSONTokener { - - /** - * Construct an XMLTokener from a string. - * @param s A source string. - */ - public HTTPTokener(String s) { - super(s); - } - - - /** - * Get the next token or string. This is used in parsing HTTP headers. - * @throws JSONException - * @return A String. - */ - public String nextToken() throws JSONException { - char c; - char q; - StringBuffer sb = new StringBuffer(); - do { - c = next(); - } while (Character.isWhitespace(c)); - if (c == '"' || c == '\'') { - q = c; - for (;;) { - c = next(); - if (c < ' ') { - throw syntaxError("Unterminated string."); - } - if (c == q) { - return sb.toString(); - } - sb.append(c); - } - } - for (;;) { - if (c == 0 || Character.isWhitespace(c)) { - return sb.toString(); - } - sb.append(c); - c = next(); - } - } -} diff --git a/src/main/java/org/json/JSONArray.java b/src/main/java/org/json/JSONArray.java deleted file mode 100644 index 5f0f79960..000000000 --- a/src/main/java/org/json/JSONArray.java +++ /dev/null @@ -1,900 +0,0 @@ -package org.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.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 get and opt - * methods for accessing the values by index, and put methods for - * adding or replacing values. The values can be any of these types: - * Boolean, JSONArray, JSONObject, - * Number, String, or the - * JSONObject.NULL object. - *

- * The constructor can convert a JSON text into a Java object. The - * toString method converts to JSON text. - *

- * A get method returns a value if one can be found, and throws an - * exception if one cannot be found. An opt method returns a - * default value instead of throwing an exception, and so is useful for - * obtaining optional values. - *

- * The generic get() and opt() methods return an - * object which you can cast or query for type. There are also typed - * get and opt methods that do type checking and type - * coersion for you. - *

- * The texts produced by the toString methods strictly conform to - * JSON syntax rules. The constructors are more forgiving in the texts they will - * accept: - *

    - *
  • An extra , (comma) may appear just - * before the closing bracket.
  • - *
  • The null value will be inserted when there - * is , (comma) elision.
  • - *
  • Strings may be quoted with ' (single - * quote).
  • - *
  • 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: - * { } [ ] / \ : , = ; # and if they do not look like numbers - * and if they are not the reserved words true, - * false, or null.
  • - *
  • Values can be separated by ; (semicolon) as - * well as by , (comma).
  • - *
  • Numbers may have the 0- (octal) or - * 0x- (hex) prefix.
  • - *
  • Comments written in the slashshlash, slashstar, and hash conventions - * will be ignored.
  • - *
- - * @author JSON.org - * @version 2 - */ -public class JSONArray { - - - /** - * The arrayList where the JSONArray's properties are kept. - */ - private ArrayList myArrayList; - - - /** - * Construct an empty JSONArray. - */ - public JSONArray() { - this.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(); - char c = x.nextClean(); - char q; - if (c == '[') { - q = ']'; - } else if (c == '(') { - q = ')'; - } else { - throw x.syntaxError("A JSONArray text must start with '['"); - } - if (x.nextClean() == ']') { - return; - } - x.back(); - for (;;) { - if (x.nextClean() == ',') { - x.back(); - this.myArrayList.add(null); - } else { - x.back(); - this.myArrayList.add(x.nextValue()); - } - c = x.nextClean(); - switch (c) { - case ';': - case ',': - if (x.nextClean() == ']') { - return; - } - x.back(); - break; - case ']': - case ')': - if (q != c) { - throw x.syntaxError("Expected a '" + new Character(q) + "'"); - } - return; - default: - throw x.syntaxError("Expected a ',' or ']'"); - } - } - } - - - /** - * Construct a JSONArray from a source JSON text. - * @param source A string that begins with - * [ (left bracket) - * and ends with ] (right bracket). - * @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) { - this.myArrayList = (collection == null) ? - new ArrayList() : - new ArrayList(collection); - } - - - /** - * 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(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 o = opt(index); - if (o == null) { - throw new JSONException("JSONArray[" + index + "] not found."); - } - return o; - } - - - /** - * 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 convertable to boolean. - */ - public boolean getBoolean(int index) throws JSONException { - Object o = get(index); - if (o.equals(Boolean.FALSE) || - (o instanceof String && - ((String)o).equalsIgnoreCase("false"))) { - return false; - } else if (o.equals(Boolean.TRUE) || - (o instanceof String && - ((String)o).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 o = get(index); - try { - return o instanceof Number ? - ((Number)o).doubleValue() : - Double.valueOf((String)o).doubleValue(); - } 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 cannot - * be converted to a number. - * if the value cannot be converted to a number. - */ - public int getInt(int index) throws JSONException { - Object o = get(index); - return o instanceof Number ? - ((Number)o).intValue() : (int)getDouble(index); - } - - - /** - * 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 o = get(index); - if (o instanceof JSONArray) { - return (JSONArray)o; - } - 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 o = get(index); - if (o instanceof JSONObject) { - return (JSONObject)o; - } - 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 o = get(index); - return o instanceof Number ? - ((Number)o).longValue() : (long)getDouble(index); - } - - - /** - * 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 value for the index. - */ - public String getString(int index) throws JSONException { - return get(index).toString(); - } - - - /** - * 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 - * separator 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(this.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 this.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 : this.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 o = opt(index); - return o != null ? o.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) { - this.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 which 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()) { - this.myArrayList.set(index, value); - } else { - while (index != length()) { - put(JSONObject.NULL); - } - put(value); - } - return this; - } - - - /** - * 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), this.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. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return a printable, displayable, transmittable - * representation of the array. - */ - 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 [ (left bracket) and ending - * with ] (right bracket). - * @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(this.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(this.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. - *

- * 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 = this.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 diff --git a/src/main/java/org/json/JSONException.java b/src/main/java/org/json/JSONException.java deleted file mode 100644 index 535168f66..000000000 --- a/src/main/java/org/json/JSONException.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.json; - -/** - * The JSONException is thrown by the JSON.org classes then things are amiss. - * @author JSON.org - * @version 2 - */ -public class JSONException extends Exception { - 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 t) { - super(t.getMessage()); - this.cause = t; - } - - public Throwable getCause() { - return this.cause; - } -} diff --git a/src/main/java/org/json/JSONML.java b/src/main/java/org/json/JSONML.java deleted file mode 100644 index 1e3579a0d..000000000 --- a/src/main/java/org/json/JSONML.java +++ /dev/null @@ -1,297 +0,0 @@ -package org.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 JSONObject, - * and to covert a JSONObject into an XML text. - * @author JSON.org - * @version 2 - */ -public class JSONML { - - /** - * Parse XML values and store them in a JSONArray. - * @param x The XMLTokener containing the source string. - * @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 JSONArray parse(XMLTokener x, JSONArray ja) throws JSONException { - char c; - int i; - String s; - Object t; - -// Test for and skip past these forms: -// -// -// -// -// Report errors for these forms: -// <> -// <= -// << - - while (true) { - t = x.nextContent(); - if (t == XML.LT) { - t = x.nextToken(); - if (t instanceof Character) { - -// "); - } - x.back(); - } else if (c == '[') { - t = x.nextToken(); - if (t.equals("CDATA") && x.next() == '[') { - x.nextCDATA(); - } else { - throw x.syntaxError("Expected 'CDATA['"); - } - } else { - i = 1; - do { - t = x.nextMeta(); - if (t == null) { - throw x.syntaxError("Missing '>' after ' 0); - } - } else if (t == XML.QUEST) { - -// "); - } else if (t == XML.SLASH) { - -// Close tag 0) { - newja.put(attributes); - } - -// Empty tag <.../> - - if (t == XML.SLASH) { - if (x.nextToken() != XML.GT) { - throw x.syntaxError("Misshaped tag"); - } - if (ja == null) { - return newja; - } - -// Content, between <...> and - - } else if (t == XML.GT) { - parse(x, newja); - if (ja == null) { - return newja; - } - } else { - throw x.syntaxError("Misshaped tag"); - } - } - } else { - if (ja != null) { - ja.put(t); - } - } - } - } - - - /** - * 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 - * properties, 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 <[ [ ]]> 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 - * properties, 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 <[ [ ]]> 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 parse(x, null); - } - - - /** - * Reverse the JSONML transformation, making an XML text from a JSONArray. - * @param ja A JSONArray. - * @param b A string buffer in which to build the text. - * @throws JSONException - */ - private static void stringify(JSONArray ja, StringBuffer b) - throws JSONException { - int i; - JSONObject jo; - String k; - Iterator keys; - int len; - Object o; - Object v; - -// Emit - - b.append('<'); - b.append(ja.get(0)); - o = ja.opt(1); - if (o instanceof JSONObject) { - -// Loop thru the attributes. - - jo = (JSONObject)o; - keys = jo.keys(); - while (keys.hasNext()) { - k = keys.next().toString(); - v = jo.get(k).toString(); - b.append(' '); - b.append(k); - b.append("=\""); - b.append(XML.escape((String)v)); - b.append('"'); - } - i = 2; - } else { - i = 1; - } - len = ja.length(); - - if (i >= len) { - b.append("/>"); - } else { - b.append('>'); - while (i < len) { - v = ja.get(i); - if (v instanceof JSONArray) { - stringify((JSONArray)v, b); - } else { - b.append(XML.escape(v.toString())); - } - i += 1; - } - b.append("'); - } - } - - /** - * 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 { - StringBuffer b = new StringBuffer(); - stringify(ja, b); - return b.toString(); - } -} \ No newline at end of file diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java deleted file mode 100644 index a2402d7b5..000000000 --- a/src/main/java/org/json/JSONObject.java +++ /dev/null @@ -1,1390 +0,0 @@ -package org.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.util.Collection; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.TreeSet; - -/** - * A JSONObject is an unordered collection of name/value pairs. Its - * external form is a string wrapped in curly braces with colons between the - * names and values, and commas between the values and names. The internal form - * is an object having get and opt methods for - * accessing the values by name, and put methods for adding or - * replacing values by name. The values can be any of these types: - * Boolean, JSONArray, JSONObject, - * Number, String, or the JSONObject.NULL - * object. A JSONObject constructor can be used to convert an external form - * JSON text into an internal form whose values can be retrieved with the - * get and opt methods, or to convert values into a - * JSON text using the put and toString methods. - * A get method returns a value if one can be found, and throws an - * exception if one cannot be found. An opt method returns a - * default value instead of throwing an exception, and so is useful for - * obtaining optional values. - *

- * The generic get() and opt() methods return an - * object, which you can cast or query for type. There are also typed - * get and opt methods that do type checking and type - * coersion for you. - *

- * The put methods adds values to an object. For example,

- *     myString = new JSONObject().put("JSON", "Hello, World!").toString();
- * produces the string {"JSON": "Hello, World"}. - *

- * The texts produced by the toString methods strictly conform to - * the JSON sysntax rules. - * The constructors are more forgiving in the texts they will accept: - *

    - *
  • An extra , (comma) may appear just - * before the closing brace.
  • - *
  • Strings may be quoted with ' (single - * quote).
  • - *
  • 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: - * { } [ ] / \ : , = ; # and if they do not look like numbers - * and if they are not the reserved words true, - * false, or null.
  • - *
  • Keys can be followed by = or => as well as - * by :.
  • - *
  • Values can be followed by ; (semicolon) as - * well as by , (comma).
  • - *
  • Numbers may have the 0- (octal) or - * 0x- (hex) prefix.
  • - *
  • Comments written in the slashshlash, slashstar, and hash conventions - * will be ignored.
  • - *
- * @author JSON.org - * @version 2 - */ -public class JSONObject { - - /** - * JSONObject.NULL is equivalent to the value that JavaScript calls null, - * whilst Java's null is equivalent to the value that JavaScript calls - * undefined. - */ - private static final class Null { - - /** - * There is only intended to be a single instance of the NULL object, - * so the clone method returns itself. - * @return NULL. - */ - protected final Object clone() { - return this; - } - - - /** - * A Null object is equal to the null value and to itself. - * @param object An object to test for nullness. - * @return true if the object parameter is the JSONObject.NULL object - * or null. - */ - public boolean equals(Object object) { - return object == null || object == this; - } - - - /** - * Get the "null" string value. - * @return The string "null". - */ - public String toString() { - return "null"; - } - } - - - /** - * The hash map where the JSONObject's properties are kept. - */ - private HashMap myHashMap; - - - /** - * It is sometimes more convenient and less ambiguous to have a - * NULL object than to use Java's null value. - * JSONObject.NULL.equals(null) returns true. - * JSONObject.NULL.toString() returns "null". - */ - public static final Object NULL = new Null(); - - - /** - * Construct an empty JSONObject. - */ - public JSONObject() { - this.myHashMap = new HashMap(); - } - - - /** - * Construct a JSONObject from a subset of another JSONObject. - * An array of strings is used to identify the keys that should be copied. - * Missing keys are ignored. - * @param jo A JSONObject. - * @param names An array of strings. - * @exception JSONException If a value is a non-finite number. - */ - public JSONObject(JSONObject jo, String[] names) throws JSONException { - this(); - for (int i = 0; i < names.length; i += 1) { - putOpt(names[i], jo.opt(names[i])); - } - } - - - /** - * Construct a JSONObject from a JSONTokener. - * @param x A JSONTokener object containing the source string. - * @throws JSONException If there is a syntax error in the source string. - */ - public JSONObject(JSONTokener x) throws JSONException { - this(); - char c; - String key; - - if (x.nextClean() != '{') { - throw x.syntaxError("A JSONObject text must begin with '{'"); - } - for (;;) { - c = x.nextClean(); - switch (c) { - case 0: - throw x.syntaxError("A JSONObject text must end with '}'"); - case '}': - return; - default: - x.back(); - key = x.nextValue().toString(); - } - - /* - * The key is followed by ':'. We will also tolerate '=' or '=>'. - */ - - c = x.nextClean(); - if (c == '=') { - if (x.next() != '>') { - x.back(); - } - } else if (c != ':') { - throw x.syntaxError("Expected a ':' after a key"); - } - put(key, x.nextValue()); - - /* - * Pairs are separated by ','. We will also tolerate ';'. - */ - - switch (x.nextClean()) { - case ';': - case ',': - if (x.nextClean() == '}') { - return; - } - x.back(); - break; - case '}': - return; - default: - throw x.syntaxError("Expected a ',' or '}'"); - } - } - } - - - /** - * Construct a JSONObject from a Map. - * @param map A map object that can be used to initialize the contents of - * the JSONObject. - */ - public JSONObject(Map map) { - this.myHashMap = (map == null) ? - new HashMap() : - new HashMap(map); - } - - - /** - * Construct a JSONObject from an Object using bean getters. - * It reflects on all of the public methods of the object. - * For each of the methods with no parameters and a name starting - * with "get" or "is" followed by an uppercase letter, - * the method is invoked, and a key and the value returned from the getter method - * are put into the new JSONObject. - * - * The key is formed by removing the "get" or "is" prefix. If the second remaining - * character is not upper case, then the first - * character is converted to lower case. - * - * For example, if an object has a method named "getName", and - * if the result of calling object.getName() is "Larry Fine", - * then the JSONObject will contain "name": "Larry Fine". - * - * @param bean An object that has getter methods that should be used - * to make a JSONObject. - */ - public JSONObject(Object bean) { - this(); - Class klass = bean.getClass(); - Method[] methods = klass.getMethods(); - for (int i = 0; i < methods.length; i += 1) { - try { - Method method = methods[i]; - String name = method.getName(); - String key = ""; - if (name.startsWith("get")) { - key = name.substring(3); - } else if (name.startsWith("is")) { - key = name.substring(2); - } - if (key.length() > 0 && - Character.isUpperCase(key.charAt(0)) && - method.getParameterTypes().length == 0) { - if (key.length() == 1) { - key = key.toLowerCase(); - } else if (!Character.isUpperCase(key.charAt(1))) { - key = key.substring(0, 1).toLowerCase() + - key.substring(1); - } - this.put(key, method.invoke(bean, (Object[])null)); - } - } catch (Exception e) { - /* forget about it */ - } - } - } - - /** - * Construct a JSONObject from an Object, using reflection to find the - * public members. The resulting JSONObject's keys will be the strings - * from the names array, and the values will be the field values associated - * with those keys in the object. If a key is not found or not visible, - * then it will not be copied into the new JSONObject. - * @param object An object that has fields that should be used to make a - * JSONObject. - * @param names An array of strings, the names of the fields to be obtained - * from the object. - */ - public JSONObject(Object object, String names[]) { - this(); - Class c = object.getClass(); - for (int i = 0; i < names.length; i += 1) { - String name = names[i]; - try { - Field field = c.getField(name); - Object value = field.get(object); - this.put(name, value); - } catch (Exception e) { - /* forget about it */ - } - } - } - - - /** - * Construct a JSONObject from a source JSON text string. - * This is the most commonly used JSONObject constructor. - * @param source A string beginning - * with { (left brace) and ending - * with } (right brace). - * @exception JSONException If there is a syntax error in the source string. - */ - public JSONObject(String source) throws JSONException { - this(new JSONTokener(source)); - } - - - /** - * Accumulate values under a key. It is similar to the put method except - * that if there is already an object stored under the key then a - * JSONArray is stored under the key to hold all of the accumulated values. - * If there is already a JSONArray, then the new value is appended to it. - * In contrast, the put method replaces the previous value. - * @param key A key string. - * @param value An object to be accumulated under the key. - * @return this. - * @throws JSONException If the value is an invalid number - * or if the key is null. - */ - public JSONObject accumulate(String key, Object value) - throws JSONException { - testValidity(value); - Object o = opt(key); - if (o == null) { - put(key, value instanceof JSONArray ? - new JSONArray().put(value) : - value); - } else if (o instanceof JSONArray) { - ((JSONArray)o).put(value); - } else { - put(key, new JSONArray().put(o).put(value)); - } - return this; - } - - - /** - * Append values to the array under a key. If the key does not exist in the - * JSONObject, then the key is put in the JSONObject with its value being a - * JSONArray containing the value parameter. If the key was already - * associated with a JSONArray, then the value parameter is appended to it. - * @param key A key string. - * @param value An object to be accumulated under the key. - * @return this. - * @throws JSONException If the key is null or if the current value - * associated with the key is not a JSONArray. - */ - public JSONObject append(String key, Object value) - throws JSONException { - testValidity(value); - Object o = opt(key); - if (o == null) { - put(key, new JSONArray().put(value)); - } else if (o instanceof JSONArray) { - put(key, ((JSONArray)o).put(value)); - } else { - throw new JSONException("JSONObject[" + key + - "] is not a JSONArray."); - } - return this; - } - - - /** - * Produce a string from a double. The string "null" will be returned if - * the number is not finite. - * @param d A double. - * @return A String. - */ - static public String doubleToString(double d) { - if (Double.isInfinite(d) || Double.isNaN(d)) { - return "null"; - } - -// Shave off trailing zeros and decimal point, if possible. - - String s = Double.toString(d); - if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) { - while (s.endsWith("0")) { - s = s.substring(0, s.length() - 1); - } - if (s.endsWith(".")) { - s = s.substring(0, s.length() - 1); - } - } - return s; - } - - - /** - * Get the value object associated with a key. - * - * @param key A key string. - * @return The object associated with the key. - * @throws JSONException if the key is not found. - */ - public Object get(String key) throws JSONException { - Object o = opt(key); - if (o == null) { - throw new JSONException("JSONObject[" + quote(key) + - "] not found."); - } - return o; - } - - - /** - * Get the boolean value associated with a key. - * - * @param key A key string. - * @return The truth. - * @throws JSONException - * if the value is not a Boolean or the String "true" or "false". - */ - public boolean getBoolean(String key) throws JSONException { - Object o = get(key); - if (o.equals(Boolean.FALSE) || - (o instanceof String && - ((String)o).equalsIgnoreCase("false"))) { - return false; - } else if (o.equals(Boolean.TRUE) || - (o instanceof String && - ((String)o).equalsIgnoreCase("true"))) { - return true; - } - throw new JSONException("JSONObject[" + quote(key) + - "] is not a Boolean."); - } - - - /** - * Get the double value associated with a key. - * @param key A key string. - * @return The numeric value. - * @throws JSONException if the key is not found or - * if the value is not a Number object and cannot be converted to a number. - */ - public double getDouble(String key) throws JSONException { - Object o = get(key); - try { - return o instanceof Number ? - ((Number)o).doubleValue() : - Double.valueOf((String)o).doubleValue(); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + - "] is not a number."); - } - } - - - /** - * Get the int value associated with a key. If the number value is too - * large for an int, it will be clipped. - * - * @param key A key string. - * @return The integer value. - * @throws JSONException if the key is not found or if the value cannot - * be converted to an integer. - */ - public int getInt(String key) throws JSONException { - Object o = get(key); - return o instanceof Number ? - ((Number)o).intValue() : (int)getDouble(key); - } - - - /** - * Get the JSONArray value associated with a key. - * - * @param key A key string. - * @return A JSONArray which is the value. - * @throws JSONException if the key is not found or - * if the value is not a JSONArray. - */ - public JSONArray getJSONArray(String key) throws JSONException { - Object o = get(key); - if (o instanceof JSONArray) { - return (JSONArray)o; - } - throw new JSONException("JSONObject[" + quote(key) + - "] is not a JSONArray."); - } - - - /** - * Get the JSONObject value associated with a key. - * - * @param key A key string. - * @return A JSONObject which is the value. - * @throws JSONException if the key is not found or - * if the value is not a JSONObject. - */ - public JSONObject getJSONObject(String key) throws JSONException { - Object o = get(key); - if (o instanceof JSONObject) { - return (JSONObject)o; - } - throw new JSONException("JSONObject[" + quote(key) + - "] is not a JSONObject."); - } - - - /** - * Get the long value associated with a key. If the number value is too - * long for a long, it will be clipped. - * - * @param key A key string. - * @return The long value. - * @throws JSONException if the key is not found or if the value cannot - * be converted to a long. - */ - public long getLong(String key) throws JSONException { - Object o = get(key); - return o instanceof Number ? - ((Number)o).longValue() : (long)getDouble(key); - } - - - /** - * Get an array of field names from a JSONObject. - * - * @return An array of field names, or null if there are no names. - */ - public static String[] getNames(JSONObject jo) { - int length = jo.length(); - if (length == 0) { - return null; - } - Iterator i = jo.keys(); - String[] names = new String[length]; - int j = 0; - while (i.hasNext()) { - names[j] = (String)i.next(); - j += 1; - } - return names; - } - - - /** - * Get an array of field names from an Object. - * - * @return An array of field names, or null if there are no names. - */ - public static String[] getNames(Object object) { - if (object == null) { - return null; - } - Class klass = object.getClass(); - Field[] fields = klass.getFields(); - int length = fields.length; - if (length == 0) { - return null; - } - String[] names = new String[length]; - for (int i = 0; i < length; i += 1) { - names[i] = fields[i].getName(); - } - return names; - } - - - /** - * Get the string associated with a key. - * - * @param key A key string. - * @return A string which is the value. - * @throws JSONException if the key is not found. - */ - public String getString(String key) throws JSONException { - return get(key).toString(); - } - - - /** - * Determine if the JSONObject contains a specific key. - * @param key A key string. - * @return true if the key exists in the JSONObject. - */ - public boolean has(String key) { - return this.myHashMap.containsKey(key); - } - - - /** - * Determine if the value associated with the key is null or if there is - * no value. - * @param key A key string. - * @return true if there is no value associated with the key or if - * the value is the JSONObject.NULL object. - */ - public boolean isNull(String key) { - return JSONObject.NULL.equals(opt(key)); - } - - - /** - * Get an enumeration of the keys of the JSONObject. - * - * @return An iterator of the keys. - */ - public Iterator keys() { - return this.myHashMap.keySet().iterator(); - } - - - /** - * Get the number of keys stored in the JSONObject. - * - * @return The number of keys in the JSONObject. - */ - public int length() { - return this.myHashMap.size(); - } - - - /** - * Produce a JSONArray containing the names of the elements of this - * JSONObject. - * @return A JSONArray containing the key strings, or null if the JSONObject - * is empty. - */ - public JSONArray names() { - JSONArray ja = new JSONArray(); - Iterator keys = keys(); - while (keys.hasNext()) { - ja.put(keys.next()); - } - return ja.length() == 0 ? null : ja; - } - - /** - * Produce a string from a Number. - * @param n A Number - * @return A String. - * @throws JSONException If n is a non-finite number. - */ - static public String numberToString(Number n) - throws JSONException { - if (n == null) { - throw new JSONException("Null pointer"); - } - testValidity(n); - -// Shave off trailing zeros and decimal point, if possible. - - String s = n.toString(); - if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) { - while (s.endsWith("0")) { - s = s.substring(0, s.length() - 1); - } - if (s.endsWith(".")) { - s = s.substring(0, s.length() - 1); - } - } - return s; - } - - - /** - * Get an optional value associated with a key. - * @param key A key string. - * @return An object which is the value, or null if there is no value. - */ - public Object opt(String key) { - return key == null ? null : this.myHashMap.get(key); - } - - - /** - * Get an optional boolean associated with a key. - * It returns false if there is no such key, or if the value is not - * Boolean.TRUE or the String "true". - * - * @param key A key string. - * @return The truth. - */ - public boolean optBoolean(String key) { - return optBoolean(key, false); - } - - - /** - * Get an optional boolean associated with a key. - * It returns the defaultValue if there is no such key, or if it is not - * a Boolean or the String "true" or "false" (case insensitive). - * - * @param key A key string. - * @param defaultValue The default. - * @return The truth. - */ - public boolean optBoolean(String key, boolean defaultValue) { - try { - return getBoolean(key); - } catch (Exception e) { - return defaultValue; - } - } - - - /** - * Put a key/value pair in the JSONObject, where the value will be a - * JSONArray which is produced from a Collection. - * @param key A key string. - * @param value A Collection value. - * @return this. - * @throws JSONException - */ - public JSONObject put(String key, Collection value) throws JSONException { - put(key, new JSONArray(value)); - return this; - } - - - /** - * Get an optional double associated with a key, - * or NaN if there is no such key or if its value is not a number. - * If the value is a string, an attempt will be made to evaluate it as - * a number. - * - * @param key A string which is the key. - * @return An object which is the value. - */ - public double optDouble(String key) { - return optDouble(key, Double.NaN); - } - - - /** - * Get an optional double associated with a key, or the - * defaultValue if there is no such key or if its value is not a number. - * If the value is a string, an attempt will be made to evaluate it as - * a number. - * - * @param key A key string. - * @param defaultValue The default. - * @return An object which is the value. - */ - public double optDouble(String key, double defaultValue) { - try { - Object o = opt(key); - return o instanceof Number ? ((Number)o).doubleValue() : - new Double((String)o).doubleValue(); - } catch (Exception e) { - return defaultValue; - } - } - - - /** - * Get an optional int value associated with a key, - * or zero if there is no such key or if the value is not a number. - * If the value is a string, an attempt will be made to evaluate it as - * a number. - * - * @param key A key string. - * @return An object which is the value. - */ - public int optInt(String key) { - return optInt(key, 0); - } - - - /** - * Get an optional int value associated with a key, - * or the default if there is no such key or if the value is not a number. - * If the value is a string, an attempt will be made to evaluate it as - * a number. - * - * @param key A key string. - * @param defaultValue The default. - * @return An object which is the value. - */ - public int optInt(String key, int defaultValue) { - try { - return getInt(key); - } catch (Exception e) { - return defaultValue; - } - } - - - /** - * Get an optional JSONArray associated with a key. - * It returns null if there is no such key, or if its value is not a - * JSONArray. - * - * @param key A key string. - * @return A JSONArray which is the value. - */ - public JSONArray optJSONArray(String key) { - Object o = opt(key); - return o instanceof JSONArray ? (JSONArray)o : null; - } - - - /** - * Get an optional JSONObject associated with a key. - * It returns null if there is no such key, or if its value is not a - * JSONObject. - * - * @param key A key string. - * @return A JSONObject which is the value. - */ - public JSONObject optJSONObject(String key) { - Object o = opt(key); - return o instanceof JSONObject ? (JSONObject)o : null; - } - - - /** - * Get an optional long value associated with a key, - * or zero if there is no such key or if the value is not a number. - * If the value is a string, an attempt will be made to evaluate it as - * a number. - * - * @param key A key string. - * @return An object which is the value. - */ - public long optLong(String key) { - return optLong(key, 0); - } - - - /** - * Get an optional long value associated with a key, - * or the default if there is no such key or if the value is not a number. - * If the value is a string, an attempt will be made to evaluate it as - * a number. - * - * @param key A key string. - * @param defaultValue The default. - * @return An object which is the value. - */ - public long optLong(String key, long defaultValue) { - try { - return getLong(key); - } catch (Exception e) { - return defaultValue; - } - } - - - /** - * Get an optional string associated with a key. - * It returns an empty string if there is no such key. If the value is not - * a string and is not null, then it is coverted to a string. - * - * @param key A key string. - * @return A string which is the value. - */ - public String optString(String key) { - return optString(key, ""); - } - - - /** - * Get an optional string associated with a key. - * It returns the defaultValue if there is no such key. - * - * @param key A key string. - * @param defaultValue The default. - * @return A string which is the value. - */ - public String optString(String key, String defaultValue) { - Object o = opt(key); - return o != null ? o.toString() : defaultValue; - } - - - /** - * Put a key/boolean pair in the JSONObject. - * - * @param key A key string. - * @param value A boolean which is the value. - * @return this. - * @throws JSONException If the key is null. - */ - public JSONObject put(String key, boolean value) throws JSONException { - put(key, value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - - /** - * Put a key/double pair in the JSONObject. - * - * @param key A key string. - * @param value A double which is the value. - * @return this. - * @throws JSONException If the key is null or if the number is invalid. - */ - public JSONObject put(String key, double value) throws JSONException { - put(key, new Double(value)); - return this; - } - - - /** - * Put a key/int pair in the JSONObject. - * - * @param key A key string. - * @param value An int which is the value. - * @return this. - * @throws JSONException If the key is null. - */ - public JSONObject put(String key, int value) throws JSONException { - put(key, new Integer(value)); - return this; - } - - - /** - * Put a key/long pair in the JSONObject. - * - * @param key A key string. - * @param value A long which is the value. - * @return this. - * @throws JSONException If the key is null. - */ - public JSONObject put(String key, long value) throws JSONException { - put(key, new Long(value)); - return this; - } - - - /** - * Put a key/value pair in the JSONObject, where the value will be a - * JSONObject which is produced from a Map. - * @param key A key string. - * @param value A Map value. - * @return this. - * @throws JSONException - */ - public JSONObject put(String key, Map value) throws JSONException { - put(key, new JSONObject(value)); - return this; - } - - - /** - * Put a key/value pair in the JSONObject. If the value is null, - * then the key will be removed from the JSONObject if it is present. - * @param key A key string. - * @param value An object which is the value. It should be of one of these - * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, - * or the JSONObject.NULL object. - * @return this. - * @throws JSONException If the value is non-finite number - * or if the key is null. - */ - public JSONObject put(String key, Object value) throws JSONException { - if (key == null) { - throw new JSONException("Null key."); - } - if (value != null) { - testValidity(value); - this.myHashMap.put(key, value); - } else { - remove(key); - } - return this; - } - - - /** - * Put a key/value pair in the JSONObject, but only if the - * key and the value are both non-null. - * @param key A key string. - * @param value An object which is the value. It should be of one of these - * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, - * or the JSONObject.NULL object. - * @return this. - * @throws JSONException If the value is a non-finite number. - */ - public JSONObject putOpt(String key, Object value) throws JSONException { - if (key != null && value != null) { - put(key, value); - } - return this; - } - - - /** - * Produce a string in double quotes with backslash sequences in all the - * right places. A backslash will be inserted within = '\u0080' && c < '\u00a0') || - (c >= '\u2000' && c < '\u2100')) { - t = "000" + Integer.toHexString(c); - sb.append("\\u" + t.substring(t.length() - 4)); - } else { - sb.append(c); - } - } - } - sb.append('"'); - return sb.toString(); - } - - /** - * Remove a name and its value, if present. - * @param key The name to be removed. - * @return The value that was associated with the name, - * or null if there was no value. - */ - public Object remove(String key) { - return this.myHashMap.remove(key); - } - - /** - * Get an enumeration of the keys of the JSONObject. - * The keys will be sorted alphabetically. - * - * @return An iterator of the keys. - */ - public Iterator sortedKeys() { - return new TreeSet(this.myHashMap.keySet()).iterator(); - } - - /** - * Throw an exception if the object is an NaN or infinite number. - * @param o The object to test. - * @throws JSONException If o is a non-finite number. - */ - static void testValidity(Object o) throws JSONException { - if (o != null) { - if (o instanceof Double) { - if (((Double)o).isInfinite() || ((Double)o).isNaN()) { - throw new JSONException( - "JSON does not allow non-finite numbers."); - } - } else if (o instanceof Float) { - if (((Float)o).isInfinite() || ((Float)o).isNaN()) { - throw new JSONException( - "JSON does not allow non-finite numbers."); - } - } - } - } - - - /** - * Produce a JSONArray containing the values of the members of this - * JSONObject. - * @param names A JSONArray containing a list of key strings. This - * determines the sequence of the values in the result. - * @return A JSONArray of values. - * @throws JSONException If any of the values are non-finite numbers. - */ - public JSONArray toJSONArray(JSONArray names) throws JSONException { - if (names == null || names.length() == 0) { - return null; - } - JSONArray ja = new JSONArray(); - for (int i = 0; i < names.length(); i += 1) { - ja.put(this.opt(names.getString(i))); - } - return ja; - } - - /** - * Make a JSON text of this JSONObject. For compactness, no whitespace - * is added. If this would not result in a syntactically correct JSON text, - * then null will be returned instead. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return a printable, displayable, portable, transmittable - * representation of the object, beginning - * with { (left brace) and ending - * with } (right brace). - */ - public String toString() { - try { - Iterator keys = keys(); - StringBuffer sb = new StringBuffer("{"); - - while (keys.hasNext()) { - if (sb.length() > 1) { - sb.append(','); - } - Object o = keys.next(); - sb.append(quote(o.toString())); - sb.append(':'); - sb.append(valueToString(this.myHashMap.get(o))); - } - sb.append('}'); - return sb.toString(); - } catch (Exception e) { - return null; - } - } - - - /** - * Make a prettyprinted JSON text of this JSONObject. - *

- * 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, portable, transmittable - * representation of the object, beginning - * with { (left brace) and ending - * with } (right brace). - * @throws JSONException If the object contains an invalid number. - */ - public String toString(int indentFactor) throws JSONException { - return toString(indentFactor, 0); - } - - - /** - * Make a prettyprinted JSON text of this JSONObject. - *

- * 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 indentation of the top level. - * @return a printable, displayable, transmittable - * representation of the object, beginning - * with { (left brace) and ending - * with } (right brace). - * @throws JSONException If the object contains an invalid number. - */ - String toString(int indentFactor, int indent) throws JSONException { - int j; - int n = length(); - if (n == 0) { - return "{}"; - } - Iterator keys = sortedKeys(); - StringBuffer sb = new StringBuffer("{"); - int newindent = indent + indentFactor; - Object o; - if (n == 1) { - o = keys.next(); - sb.append(quote(o.toString())); - sb.append(": "); - sb.append(valueToString(this.myHashMap.get(o), indentFactor, - indent)); - } else { - while (keys.hasNext()) { - o = keys.next(); - if (sb.length() > 1) { - sb.append(",\n"); - } else { - sb.append('\n'); - } - for (j = 0; j < newindent; j += 1) { - sb.append(' '); - } - sb.append(quote(o.toString())); - sb.append(": "); - sb.append(valueToString(this.myHashMap.get(o), indentFactor, - newindent)); - } - if (sb.length() > 1) { - sb.append('\n'); - for (j = 0; j < indent; j += 1) { - sb.append(' '); - } - } - } - sb.append('}'); - return sb.toString(); - } - - - /** - * Make a JSON text of an Object value. If the object has an - * value.toJSONString() method, then that method will be used to produce - * the JSON text. The method is required to produce a strictly - * conforming text. If the object does not contain a toJSONString - * method (which is the most common case), then a text will be - * produced by other means. If the value is an array or Collection, - * then a JSONArray will be made from it and its toJSONString method - * will be called. If the value is a MAP, then a JSONObject will be made - * from it and its toJSONString method will be called. Otherwise, the - * value's toString method will be called, and the result will be quoted. - * - *

- * Warning: This method assumes that the data structure is acyclical. - * @param value The value to be serialized. - * @return a printable, displayable, transmittable - * representation of the object, beginning - * with { (left brace) and ending - * with } (right brace). - * @throws JSONException If the value is or contains an invalid number. - */ - static String valueToString(Object value) throws JSONException { - if (value == null || value.equals(null)) { - return "null"; - } - if (value instanceof JSONString) { - Object o; - try { - o = ((JSONString)value).toJSONString(); - } catch (Exception e) { - throw new JSONException(e); - } - if (o instanceof String) { - return (String)o; - } - throw new JSONException("Bad value from toJSONString: " + o); - } - if (value instanceof Number) { - return numberToString((Number) value); - } - if (value instanceof Boolean || value instanceof JSONObject || - value instanceof JSONArray) { - return value.toString(); - } - if (value instanceof Map) { - return new JSONObject((Map)value).toString(); - } - if (value instanceof Collection) { - return new JSONArray((Collection)value).toString(); - } - if (value.getClass().isArray()) { - return new JSONArray(value).toString(); - } - return quote(value.toString()); - } - - - /** - * Make a prettyprinted JSON text of an object value. - *

- * Warning: This method assumes that the data structure is acyclical. - * @param value The value to be serialized. - * @param indentFactor The number of spaces to add to each level of - * indentation. - * @param indent The indentation of the top level. - * @return a printable, displayable, transmittable - * representation of the object, beginning - * with { (left brace) and ending - * with } (right brace). - * @throws JSONException If the object contains an invalid number. - */ - static String valueToString(Object value, int indentFactor, int indent) - throws JSONException { - if (value == null || value.equals(null)) { - return "null"; - } - try { - if (value instanceof JSONString) { - Object o = ((JSONString)value).toJSONString(); - if (o instanceof String) { - return (String)o; - } - } - } catch (Exception e) { - /* forget about it */ - } - if (value instanceof Number) { - return numberToString((Number) value); - } - if (value instanceof Boolean) { - return value.toString(); - } - if (value instanceof JSONObject) { - return ((JSONObject)value).toString(indentFactor, indent); - } - if (value instanceof JSONArray) { - return ((JSONArray)value).toString(indentFactor, indent); - } - if (value instanceof Map) { - return new JSONObject((Map)value).toString(indentFactor, indent); - } - if (value instanceof Collection) { - return new JSONArray((Collection)value).toString(indentFactor, indent); - } - if (value.getClass().isArray()) { - return new JSONArray(value).toString(indentFactor, indent); - } - return quote(value.toString()); - } - - - /** - * Write the contents of the JSONObject as JSON text to a writer. - * For compactness, no whitespace is added. - *

- * 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; - Iterator keys = keys(); - writer.write('{'); - - while (keys.hasNext()) { - if (b) { - writer.write(','); - } - Object k = keys.next(); - writer.write(quote(k.toString())); - writer.write(':'); - Object v = this.myHashMap.get(k); - if (v instanceof JSONObject) { - ((JSONObject)v).write(writer); - } else if (v instanceof JSONArray) { - ((JSONArray)v).write(writer); - } else { - writer.write(valueToString(v)); - } - b = true; - } - writer.write('}'); - return writer; - } catch (IOException e) { - throw new JSONException(e); - } - } -} \ No newline at end of file diff --git a/src/main/java/org/json/JSONString.java b/src/main/java/org/json/JSONString.java deleted file mode 100644 index 7f4f65b67..000000000 --- a/src/main/java/org/json/JSONString.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.json; -/** - * The JSONString interface allows a toJSONString() - * method so that a class can change the behavior of - * JSONObject.toString(), JSONArray.toString(), - * and JSONWriter.value(Object). The - * toJSONString method will be used instead of the default behavior - * of using the Object's toString() method and quoting the result. - */ -public interface JSONString { - /** - * The toJSONString method allows a class to produce its own JSON - * serialization. - * - * @return A strictly syntactically correct JSON text. - */ - public String toJSONString(); -} diff --git a/src/main/java/org/json/JSONStringer.java b/src/main/java/org/json/JSONStringer.java deleted file mode 100644 index b68efa41a..000000000 --- a/src/main/java/org/json/JSONStringer.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.json; - -/* -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: - -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.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. - *

- * A JSONStringer instance provides a value method for appending - * values to the - * text, and a key - * method for adding keys before values in objects. There are array - * and endArray methods that make and bound array values, and - * object and endObject methods which make and bound - * object values. All of these methods return the JSONWriter instance, - * permitting cascade style. For example,

- * myString = new JSONStringer()
- *     .object()
- *         .key("JSON")
- *         .value("Hello, World!")
- *     .endObject()
- *     .toString();
which produces the string
- * {"JSON":"Hello, World!"}
- *

- * The first method called must be array or object. - * 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. - *

- * This can sometimes be easier than using a JSONObject to build a string. - * @author JSON.org - * @version 2 - */ -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 null if there was a - * problem in the construction of the JSON text (such as the calls to - * array were not properly balanced with calls to - * endArray). - * @return The JSON text. - */ - public String toString() { - return this.mode == 'd' ? this.writer.toString() : null; - } -} diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java deleted file mode 100644 index f7af8cafb..000000000 --- a/src/main/java/org/json/JSONTokener.java +++ /dev/null @@ -1,463 +0,0 @@ -package org.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. -*/ - -/** - * 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 2 - */ -public class JSONTokener { - - /** - * The index of the next character. - */ - private int myIndex; - - - /** - * The source string being tokenized. - */ - private String mySource; - - - /** - * Construct a JSONTokener from a string. - * - * @param s A source string. - */ - public JSONTokener(String s) { - this.myIndex = 0; - this.mySource = 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() { - if (this.myIndex > 0) { - this.myIndex -= 1; - } - } - - - - /** - * 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; - } - - - /** - * 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() { - return this.myIndex < this.mySource.length(); - } - - - /** - * 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() { - if (more()) { - char c = this.mySource.charAt(this.myIndex); - this.myIndex += 1; - return c; - } - return 0; - } - - - /** - * 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 { - int i = this.myIndex; - int j = i + n; - if (j >= this.mySource.length()) { - throw syntaxError("Substring bounds error"); - } - this.myIndex += n; - return this.mySource.substring(i, j); - } - - - /** - * Get the next char in the string, skipping whitespace - * and comments (slashslash, slashstar, and hash). - * @throws JSONException - * @return A character, or 0 if there are no more characters. - */ - public char nextClean() throws JSONException { - for (;;) { - char c = next(); - if (c == '/') { - switch (next()) { - case '/': - do { - c = next(); - } while (c != '\n' && c != '\r' && c != 0); - break; - case '*': - for (;;) { - c = next(); - if (c == 0) { - throw syntaxError("Unclosed comment"); - } - if (c == '*') { - if (next() == '/') { - break; - } - back(); - } - } - break; - default: - back(); - return '/'; - } - } else if (c == '#') { - do { - c = next(); - } while (c != '\n' && c != '\r' && c != 0); - } else 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 - * " (double quote) or - * ' (single quote). - * @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 'x' : - sb.append((char) Integer.parseInt(next(2), 16)); - break; - default: - sb.append(c); - } - 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 d A delimiter character. - * @return A string. - */ - public String nextTo(char d) { - StringBuffer sb = new StringBuffer(); - for (;;) { - char c = next(); - if (c == d || 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 delimeter - * 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) { - 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 s; - - switch (c) { - case '"': - case '\'': - return nextString(c); - case '{': - back(); - return new JSONObject(this); - case '[': - 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(); - char b = c; - while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) { - sb.append(c); - c = next(); - } - back(); - - /* - * If it is true, false, or null, return the proper value. - */ - - s = sb.toString().trim(); - if (s.equals("")) { - throw syntaxError("Missing value"); - } - if (s.equalsIgnoreCase("true")) { - return Boolean.TRUE; - } - if (s.equalsIgnoreCase("false")) { - return Boolean.FALSE; - } - if (s.equalsIgnoreCase("null")) { - return JSONObject.NULL; - } - - /* - * If it might be a number, try converting it. We support the 0- and 0x- - * conventions. If a number cannot be produced, then the value will just - * be a string. Note that the 0-, 0x-, plus, and implied string - * conventions are non-standard. A JSON parser is free to accept - * non-JSON forms as long as it accepts all correct JSON forms. - */ - - if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') { - if (b == '0') { - if (s.length() > 2 && - (s.charAt(1) == 'x' || s.charAt(1) == 'X')) { - try { - return new Integer(Integer.parseInt(s.substring(2), - 16)); - } catch (Exception e) { - /* Ignore the error */ - } - } else { - try { - return new Integer(Integer.parseInt(s, 8)); - } catch (Exception e) { - /* Ignore the error */ - } - } - } - try { - return new Integer(s); - } catch (Exception e) { - try { - return new Long(s); - } catch (Exception f) { - try { - return new Double(s); - } catch (Exception g) { - return s; - } - } - } - } - return s; - } - - - /** - * 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) { - char c; - int index = this.myIndex; - do { - c = next(); - if (c == 0) { - this.myIndex = index; - return c; - } - } while (c != to); - back(); - return c; - } - - - /** - * Skip characters until past the requested string. - * If it is not found, we are left at the end of the source. - * @param to A string to skip past. - */ - public boolean skipPast(String to) { - this.myIndex = this.mySource.indexOf(to, this.myIndex); - if (this.myIndex < 0) { - this.myIndex = this.mySource.length(); - return false; - } - this.myIndex += to.length(); - return true; - - } - - - /** - * 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 character [this.myIndex] of [this.mySource]" - */ - public String toString() { - return " at character " + this.myIndex + " of " + this.mySource; - } -} \ No newline at end of file diff --git a/src/main/java/org/json/JSONWriter.java b/src/main/java/org/json/JSONWriter.java deleted file mode 100644 index e1cd2e9be..000000000 --- a/src/main/java/org/json/JSONWriter.java +++ /dev/null @@ -1,318 +0,0 @@ -package org.json; - -import java.io.IOException; -import java.io.Writer; - -/* -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: - -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. -*/ - -/** - * 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. - *

- * A JSONWriter instance provides a value method for appending - * values to the - * text, and a key - * method for adding keys before values in objects. There are array - * and endArray methods that make and bound array values, and - * object and endObject methods which make and bound - * object values. All of these methods return the JSONWriter instance, - * permitting a cascade style. For example,

- * new JSONWriter(myWriter)
- *     .object()
- *         .key("JSON")
- *         .value("Hello, World!")
- *     .endObject();
which writes
- * {"JSON":"Hello, World!"}
- *

- * The first method called must be array or object. - * 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. - *

-     * & (ampersand) is replaced by &amp;
-     * < (less than) is replaced by &lt;
-     * > (greater than) is replaced by &gt;
-     * " (double quote) is replaced by &quot;
-     * 
- * @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, len = string.length(); i < len; i++) { - char c = string.charAt(i); - switch (c) { - case '&': - sb.append("&"); - break; - case '<': - sb.append("<"); - break; - case '>': - sb.append(">"); - break; - case '"': - sb.append("""); - break; - default: - sb.append(c); - } - } - return sb.toString(); - } - - /** - * 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; - String n; - JSONObject o = null; - String s; - Object t; - -// Test for and skip past these forms: -// -// -// -// -// Report errors for these forms: -// <> -// <= -// << - - t = x.nextToken(); - -// "); - return false; - } - x.back(); - } else if (c == '[') { - t = x.nextToken(); - if (t.equals("CDATA")) { - if (x.next() == '[') { - s = x.nextCDATA(); - if (s.length() > 0) { - context.accumulate("content", s); - } - return false; - } - } - throw x.syntaxError("Expected 'CDATA['"); - } - i = 1; - do { - t = x.nextMeta(); - if (t == null) { - throw x.syntaxError("Missing '>' after ' 0); - return false; - } else if (t == QUEST) { - -// "); - return false; - } else if (t == SLASH) { - -// Close tag - - } else if (t == SLASH) { - if (x.nextToken() != GT) { - throw x.syntaxError("Misshaped tag"); - } - context.accumulate(n, o); - return false; - -// Content, between <...> and - - } else if (t == GT) { - for (;;) { - t = x.nextContent(); - if (t == null) { - if (n != null) { - throw x.syntaxError("Unclosed tag " + n); - } - return false; - } else if (t instanceof String) { - s = (String)t; - if (s.length() > 0) { - o.accumulate("content", s); - } - -// Nested element - - } else if (t == LT) { - if (parse(x, o, n)) { - if (o.length() == 0) { - context.accumulate(n, ""); - } else if (o.length() == 1 && - o.opt("content") != null) { - context.accumulate(n, o.opt("content")); - } else { - context.accumulate(n, o); - } - return false; - } - } - } - } else { - throw x.syntaxError("Misshaped tag"); - } - } - } - } - - - /** - * 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 - * <[ [ ]]> 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 o = new JSONObject(); - XMLTokener x = new XMLTokener(string); - while (x.more() && x.skipPast("<")) { - parse(x, o, null); - } - return o; - } - - - /** - * Convert a JSONObject into a well-formed, element-normal XML string. - * @param o A JSONObject. - * @return A string. - * @throws JSONException - */ - public static String toString(Object o) throws JSONException { - return toString(o, null); - } - - - /** - * Convert a JSONObject into a well-formed, element-normal XML string. - * @param o A JSONObject. - * @param tagName The optional name of the enclosing tag. - * @return A string. - * @throws JSONException - */ - public static String toString(Object o, String tagName) - throws JSONException { - StringBuffer b = new StringBuffer(); - int i; - JSONArray ja; - JSONObject jo; - String k; - Iterator keys; - int len; - String s; - Object v; - if (o instanceof JSONObject) { - -// Emit - - if (tagName != null) { - b.append('<'); - b.append(tagName); - b.append('>'); - } - -// Loop thru the keys. - - jo = (JSONObject)o; - keys = jo.keys(); - while (keys.hasNext()) { - k = keys.next().toString(); - v = jo.get(k); - if (v instanceof String) { - s = (String)v; - } else { - s = null; - } - -// Emit content in body - - if (k.equals("content")) { - if (v instanceof JSONArray) { - ja = (JSONArray)v; - len = ja.length(); - for (i = 0; i < len; i += 1) { - if (i > 0) { - b.append('\n'); - } - b.append(escape(ja.get(i).toString())); - } - } else { - b.append(escape(v.toString())); - } - -// Emit an array of similar keys - - } else if (v instanceof JSONArray) { - ja = (JSONArray)v; - len = ja.length(); - for (i = 0; i < len; i += 1) { - b.append(toString(ja.get(i), k)); - } - } else if (v.equals("")) { - b.append('<'); - b.append(k); - b.append("/>"); - -// Emit a new tag - - } else { - b.append(toString(v, k)); - } - } - if (tagName != null) { - -// Emit the close tag - - b.append("'); - } - return b.toString(); - -// XML does not have good support for arrays. If an array appears in a place -// where XML is lacking, synthesize an element. - - } else if (o instanceof JSONArray) { - ja = (JSONArray)o; - len = ja.length(); - for (i = 0; i < len; ++i) { - b.append(toString( - ja.opt(i), (tagName == null) ? "array" : tagName)); - } - return b.toString(); - } else { - s = (o == null) ? "null" : escape(o.toString()); - return (tagName == null) ? "\"" + s + "\"" : - (s.length() == 0) ? "<" + tagName + "/>" : - "<" + tagName + ">" + s + ""; - } - } -} \ No newline at end of file diff --git a/src/main/java/org/json/XMLTokener.java b/src/main/java/org/json/XMLTokener.java deleted file mode 100644 index 1998d42b7..000000000 --- a/src/main/java/org/json/XMLTokener.java +++ /dev/null @@ -1,293 +0,0 @@ -package org.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. -*/ - -/** - * The XMLTokener extends the JSONTokener to provide additional methods - * for the parsing of XML texts. - * @author JSON.org - * @version 2 - */ -public class XMLTokener extends JSONTokener { - - - /** The table of entity values. It initially contains Character values for - * amp, apos, gt, lt, quot. - */ - public static final java.util.HashMap entity; - - static { - entity = new java.util.HashMap(8); - entity.put("amp", XML.AMP); - entity.put("apos", XML.APOS); - entity.put("gt", XML.GT); - entity.put("lt", XML.LT); - entity.put("quot", XML.QUOT); - } - - /** - * Construct an XMLTokener from a string. - * @param s A source string. - */ - public XMLTokener(String s) { - super(s); - } - - /** - * Get the text in the CDATA block. - * @return The string up to the ]]>. - * @throws JSONException If the ]]> is not found. - */ - public String nextCDATA() throws JSONException { - char c; - int i; - StringBuffer sb = new StringBuffer(); - for (;;) { - c = next(); - if (c == 0) { - throw syntaxError("Unclosed CDATA"); - } - sb.append(c); - i = sb.length() - 3; - if (i >= 0 && sb.charAt(i) == ']' && - sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') { - sb.setLength(i); - return sb.toString(); - } - } - } - - - /** - * Get the next XML outer token, trimming whitespace. There are two kinds - * of tokens: the '<' character which begins a markup tag, and the content - * text between markup tags. - * - * @return A string, or a '<' Character, or null if there is no more - * source text. - * @throws JSONException - */ - public Object nextContent() throws JSONException { - char c; - StringBuffer sb; - do { - c = next(); - } while (Character.isWhitespace(c)); - if (c == 0) { - return null; - } - if (c == '<') { - return XML.LT; - } - sb = new StringBuffer(); - for (;;) { - if (c == '<' || c == 0) { - back(); - return sb.toString().trim(); - } - if (c == '&') { - sb.append(nextEntity(c)); - } else { - sb.append(c); - } - c = next(); - } - } - - - /** - * Return the next entity. These entities are translated to Characters: - * & ' > < ". - * @param a An ampersand character. - * @return A Character or an entity String if the entity is not recognized. - * @throws JSONException If missing ';' in XML entity. - */ - public Object nextEntity(char a) throws JSONException { - StringBuffer sb = new StringBuffer(); - for (;;) { - char c = next(); - if (Character.isLetterOrDigit(c) || c == '#') { - sb.append(Character.toLowerCase(c)); - } else if (c == ';') { - break; - } else { - throw syntaxError("Missing ';' in XML entity: &" + sb); - } - } - String s = sb.toString(); - Object e = entity.get(s); - return e != null ? e : a + s + ";"; - } - - - /** - * Returns the next XML meta token. This is used for skipping over - * and structures. - * @return Syntax characters (< > / = ! ?) are returned as - * Character, and strings and names are returned as Boolean. We don't care - * what the values actually are. - * @throws JSONException If a string is not properly closed or if the XML - * is badly structured. - */ - public Object nextMeta() throws JSONException { - char c; - char q; - do { - c = next(); - } while (Character.isWhitespace(c)); - switch (c) { - case 0: - throw syntaxError("Misshaped meta tag"); - case '<': - return XML.LT; - case '>': - return XML.GT; - case '/': - return XML.SLASH; - case '=': - return XML.EQ; - case '!': - return XML.BANG; - case '?': - return XML.QUEST; - case '"': - case '\'': - q = c; - for (;;) { - c = next(); - if (c == 0) { - throw syntaxError("Unterminated string"); - } - if (c == q) { - return Boolean.TRUE; - } - } - default: - for (;;) { - c = next(); - if (Character.isWhitespace(c)) { - return Boolean.TRUE; - } - switch (c) { - case 0: - case '<': - case '>': - case '/': - case '=': - case '!': - case '?': - case '"': - case '\'': - back(); - return Boolean.TRUE; - } - } - } - } - - - /** - * Get the next XML Token. These tokens are found inside of angle - * brackets. It may be one of these characters: / > = ! ? or it - * may be a string wrapped in single quotes or double quotes, or it may be a - * name. - * @return a String or a Character. - * @throws JSONException If the XML is not well formed. - */ - public Object nextToken() throws JSONException { - char c; - char q; - StringBuffer sb; - do { - c = next(); - } while (Character.isWhitespace(c)); - switch (c) { - case 0: - throw syntaxError("Misshaped element"); - case '<': - throw syntaxError("Misplaced '<'"); - case '>': - return XML.GT; - case '/': - return XML.SLASH; - case '=': - return XML.EQ; - case '!': - return XML.BANG; - case '?': - return XML.QUEST; - -// Quoted string - - case '"': - case '\'': - q = c; - sb = new StringBuffer(); - for (;;) { - c = next(); - if (c == 0) { - throw syntaxError("Unterminated string"); - } - if (c == q) { - return sb.toString(); - } - if (c == '&') { - sb.append(nextEntity(c)); - } else { - sb.append(c); - } - } - default: - -// Name - - sb = new StringBuffer(); - for (;;) { - sb.append(c); - c = next(); - if (Character.isWhitespace(c)) { - return sb.toString(); - } - switch (c) { - case 0: - return sb.toString(); - case '>': - case '/': - case '=': - case '!': - case '?': - case '[': - case ']': - back(); - return sb.toString(); - case '<': - case '"': - case '\'': - throw syntaxError("Bad character in a name"); - } - } - } - } -}

- * This can sometimes be easier than using a JSONObject to build a string. - * @author JSON.org - * @version 2 - */ -public class JSONWriter { - private static final int maxdepth = 20; - - /** - * 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 object/array stack. - */ - private char stack[]; - - /** - * 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; - - /** - * 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 char[maxdepth]; - this.top = 0; - this.writer = w; - } - - /** - * Append a value. - * @param s A string value. - * @return this - * @throws JSONException If the value is out of sequence. - */ - private JSONWriter append(String s) throws JSONException { - if (s == 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(s); - } 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 - * endArray will be appended to this array. The - * endArray 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('a'); - this.append("["); - this.comma = false; - return this; - } - throw new JSONException("Misplaced array."); - } - - /** - * End something. - * @param m Mode - * @param c Closing character - * @return this - * @throws JSONException If unbalanced. - */ - private JSONWriter end(char m, char c) throws JSONException { - if (this.mode != m) { - throw new JSONException(m == 'o' ? "Misplaced endObject." : - "Misplaced endArray."); - } - this.pop(m); - 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 - * array. - * @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 - * object. - * @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 s 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 s) throws JSONException { - if (s == null) { - throw new JSONException("Null key."); - } - if (this.mode == 'k') { - try { - if (this.comma) { - this.writer.write(','); - } - this.writer.write(JSONObject.quote(s)); - 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 - * endObject will be appended to this object. The - * endObject 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('k'); - 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 (this.top <= 0 || this.stack[this.top - 1] != c) { - throw new JSONException("Nesting error."); - } - this.top -= 1; - this.mode = this.top == 0 ? 'd' : this.stack[this.top - 1]; - } - - /** - * Push an array or object scope. - * @param c The scope to open. - * @throws JSONException If nesting is too deep. - */ - private void push(char c) throws JSONException { - if (this.top >= maxdepth) { - throw new JSONException("Nesting too deep."); - } - this.stack[this.top] = c; - this.mode = c; - this.top += 1; - } - - - /** - * Append either the value true or the value - * false. - * @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 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 o The object to append. It can be null, or a Boolean, Number, - * String, JSONObject, or JSONArray, or an object with a toJSONString() - * method. - * @return this - * @throws JSONException If the value is out of sequence. - */ - public JSONWriter value(Object o) throws JSONException { - return this.append(JSONObject.valueToString(o)); - } -} diff --git a/src/main/java/org/json/Test.java b/src/main/java/org/json/Test.java deleted file mode 100644 index 7092352c1..000000000 --- a/src/main/java/org/json/Test.java +++ /dev/null @@ -1,553 +0,0 @@ -package org.json; - -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.io.StringWriter; - -/** - * Test class. This file is not formally a member of the org.json library. - * It is just a casual test tool. - */ -public class Test { - - /** - * Entry point. - * @param args - */ - public static void main(String args[]) { - Iterator it; - JSONArray a; - JSONObject j; - JSONStringer jj; - String s; - -/** - * Obj is a typical class that implements JSONString. It also - * provides some beanie methods that can be used to - * construct a JSONObject. It also demonstrates constructing - * a JSONObject with an array of names. - */ - class Obj implements JSONString { - public String aString; - public double aNumber; - public boolean aBoolean; - - public Obj(String string, double n, boolean b) { - this.aString = string; - this.aNumber = n; - this.aBoolean = b; - } - - public double getNumber() { - return this.aNumber; - } - - public String getString() { - return this.aString; - } - - public boolean isBoolean() { - return this.aBoolean; - } - - public String getBENT() { - return "All uppercase key"; - } - - public String getX() { - return "x"; - } - - public String toJSONString() { - return "{" + JSONObject.quote(this.aString) + ":" + - JSONObject.doubleToString(this.aNumber) + "}"; - } - public String toString() { - return this.getString() + " " + this.getNumber() + " " + - this.isBoolean() + "." + this.getBENT() + " " + this.getX(); - } - } - - Obj obj = new Obj("A beany object", 42, true); - - try { - j = XML.toJSONObject(" Ignore the stuff past the end. "); - System.out.println(j.toString()); - - j = new JSONObject(obj); - System.out.println(j.toString()); - - jj = new JSONStringer(); - s = jj - .object() - .key("foo") - .value("bar") - .key("baz") - .array() - .object() - .key("quux") - .value("Thanks, Josh!") - .endObject() - .endArray() - .key("obj keys") - .value(JSONObject.getNames(obj)) - .endObject() - .toString(); - System.out.println(s); - - System.out.println(new JSONStringer() - .object() - .key("a") - .array() - .array() - .array() - .value("b") - .endArray() - .endArray() - .endArray() - .endObject() - .toString()); - - jj = new JSONStringer(); - jj.array(); - jj.value(1); - jj.array(); - jj.value(null); - jj.array(); - jj.object(); - jj.key("empty-array").array().endArray(); - jj.key("answer").value(42); - jj.key("null").value(null); - jj.key("false").value(false); - jj.key("true").value(true); - jj.key("big").value(123456789e+88); - jj.key("small").value(123456789e-88); - jj.key("empty-object").object().endObject(); - jj.key("long"); - jj.value(9223372036854775807L); - jj.endObject(); - jj.value("two"); - jj.endArray(); - jj.value(true); - jj.endArray(); - jj.value(98.6); - jj.value(-100.0); - jj.object(); - jj.endObject(); - jj.object(); - jj.key("one"); - jj.value(1.00); - jj.endObject(); - jj.value(obj); - jj.endArray(); - System.out.println(jj.toString()); - - System.out.println(new JSONArray(jj.toString()).toString(4)); - - int ar[] = {1, 2, 3}; - JSONArray ja = new JSONArray(ar); - System.out.println(ja.toString()); - - String sa[] = {"aString", "aNumber", "aBoolean"}; - j = new JSONObject(obj, sa); - j.put("Testing JSONString interface", obj); - System.out.println(j.toString(4)); - - j = new JSONObject("{slashes: '///', closetag: '', backslash:'\\\\', ei: {quotes: '\"\\''},eo: {a: '\"quoted\"', b:\"don't\"}, quotes: [\"'\", '\"']}"); - System.out.println(j.toString(2)); - System.out.println(XML.toString(j)); - System.out.println(""); - - j = new JSONObject( - "/*comment*/{foo: [true, false,9876543210, 0.0, 1.00000001, 1.000000000001, 1.00000000000000001," + - " .00000000000000001, 2.00, 0.1, 2e100, -32,[],{}, \"string\"], " + - " to : null, op : 'Good'," + - "ten:10} postfix comment"); - j.put("String", "98.6"); - j.put("JSONObject", new JSONObject()); - j.put("JSONArray", new JSONArray()); - j.put("int", 57); - j.put("double", 123456789012345678901234567890.); - j.put("true", true); - j.put("false", false); - j.put("null", JSONObject.NULL); - j.put("bool", "true"); - j.put("zero", -0.0); - j.put("\\u2028", "\u2028"); - j.put("\\u2029", "\u2029"); - a = j.getJSONArray("foo"); - a.put(666); - a.put(2001.99); - a.put("so \"fine\"."); - a.put("so ."); - a.put(true); - a.put(false); - a.put(new JSONArray()); - a.put(new JSONObject()); - j.put("keys", JSONObject.getNames(j)); - System.out.println(j.toString(4)); - System.out.println(XML.toString(j)); - - System.out.println("String: " + j.getDouble("String")); - System.out.println(" bool: " + j.getBoolean("bool")); - System.out.println(" to: " + j.getString("to")); - System.out.println(" true: " + j.getString("true")); - System.out.println(" foo: " + j.getJSONArray("foo")); - System.out.println(" op: " + j.getString("op")); - System.out.println(" ten: " + j.getInt("ten")); - System.out.println(" oops: " + j.optBoolean("oops")); - - s = "First \u0009<content> This is \"content\". 3 JSON does not preserve the sequencing of elements and contents. III T H R E EContent text is an implied structure in XML. JSON does not have implied structure:7everything is explicit.!]]>"; - j = XML.toJSONObject(s); - System.out.println(j.toString(2)); - System.out.println(XML.toString(j)); - System.out.println(""); - - ja = JSONML.toJSONArray(s); - System.out.println(ja.toString(4)); - System.out.println(JSONML.toString(ja)); - System.out.println(""); - - s = "unodostresquatrocinqoseis"; - ja = JSONML.toJSONArray(s); - System.out.println(ja.toString(4)); - System.out.println(JSONML.toString(ja)); - System.out.println(""); - - s = " "; - j = XML.toJSONObject(s); - - System.out.println(j.toString(2)); - System.out.println(XML.toString(j)); - System.out.println(""); - ja = JSONML.toJSONArray(s); - System.out.println(ja.toString(4)); - System.out.println(JSONML.toString(ja)); - System.out.println(""); - - j = XML.toJSONObject("Sample BookThis is chapter 1. It is not very long or interesting.This is chapter 2. Although it is longer than chapter 1, it is not any more interesting."); - System.out.println(j.toString(2)); - System.out.println(XML.toString(j)); - System.out.println(""); - - j = XML.toJSONObject(""); - System.out.println(j.toString(2)); - System.out.println(XML.toString(j)); - System.out.println(""); - - j = XML.toJSONObject(" Fred fbs0001 Scerbo B "); - System.out.println(j.toString(2)); - System.out.println(XML.toString(j)); - System.out.println(""); - - j = XML.toJSONObject("Repository Address Special Collections LibraryABC UniversityMain Library, 40 Circle DriveOurtown, Pennsylvania17654 USA"); - System.out.println(j.toString()); - System.out.println(XML.toString(j)); - System.out.println(""); - - j = XML.toJSONObject("deluxe&"toot"&toot;Aeksbonusbonus2"); - System.out.println(j.toString(2)); - System.out.println(XML.toString(j)); - System.out.println(""); - - j = HTTP.toJSONObject("GET / HTTP/1.0\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*\nAccept-Language: en-us\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 98; Win 9x 4.90; T312461; Q312461)\nHost: www.nokko.com\nConnection: keep-alive\nAccept-encoding: gzip, deflate\n"); - System.out.println(j.toString(2)); - System.out.println(HTTP.toString(j)); - System.out.println(""); - - j = HTTP.toJSONObject("HTTP/1.1 200 Oki Doki\nDate: Sun, 26 May 2002 17:38:52 GMT\nServer: Apache/1.3.23 (Unix) mod_perl/1.26\nKeep-Alive: timeout=15, max=100\nConnection: Keep-Alive\nTransfer-Encoding: chunked\nContent-Type: text/html\n"); - System.out.println(j.toString(2)); - System.out.println(HTTP.toString(j)); - System.out.println(""); - - j = new JSONObject("{nix: null, nux: false, null: 'null', 'Request-URI': '/', Method: 'GET', 'HTTP-Version': 'HTTP/1.0'}"); - System.out.println(j.toString(2)); - System.out.println("isNull: " + j.isNull("nix")); - System.out.println(" has: " + j.has("nix")); - System.out.println(XML.toString(j)); - System.out.println(HTTP.toString(j)); - System.out.println(""); - - j = XML.toJSONObject(""+"\n\n"+""+ - ""+ - "GOOGLEKEY '+search+' 0 10 true false latin1 latin1"+ - ""+ - ""); - System.out.println(j.toString(2)); - System.out.println(XML.toString(j)); - System.out.println(""); - - j = new JSONObject("{Envelope: {Body: {\"ns1:doGoogleSearch\": {oe: \"latin1\", filter: true, q: \"'+search+'\", key: \"GOOGLEKEY\", maxResults: 10, \"SOAP-ENV:encodingStyle\": \"http://schemas.xmlsoap.org/soap/encoding/\", start: 0, ie: \"latin1\", safeSearch:false, \"xmlns:ns1\": \"urn:GoogleSearch\"}}}}"); - System.out.println(j.toString(2)); - System.out.println(XML.toString(j)); - System.out.println(""); - - j = CookieList.toJSONObject(" f%oo = b+l=ah ; o;n%40e = t.wo "); - System.out.println(j.toString(2)); - System.out.println(CookieList.toString(j)); - System.out.println(""); - - j = Cookie.toJSONObject("f%oo=blah; secure ;expires = April 24, 2002"); - System.out.println(j.toString(2)); - System.out.println(Cookie.toString(j)); - System.out.println(""); - - j = new JSONObject("{script: 'It is not allowed in HTML to send a close script tag in a stringso we insert a backslash before the /'}"); - System.out.println(j.toString()); - System.out.println(""); - - JSONTokener jt = new JSONTokener("{op:'test', to:'session', pre:1}{op:'test', to:'session', pre:2}"); - j = new JSONObject(jt); - System.out.println(j.toString()); - System.out.println("pre: " + j.optInt("pre")); - int i = jt.skipTo('{'); - System.out.println(i); - j = new JSONObject(jt); - System.out.println(j.toString()); - System.out.println(""); - - a = CDL.toJSONArray("No quotes, 'Single Quotes', \"Double Quotes\"\n1,'2',\"3\"\n,'It is \"good,\"', \"It works.\"\n\n"); - - System.out.println(CDL.toString(a)); - System.out.println(""); - System.out.println(a.toString(4)); - System.out.println(""); - - a = new JSONArray(" [\"\", next is an implied null , , ok,] "); - System.out.println(a.toString()); - System.out.println(""); - System.out.println(XML.toString(a)); - System.out.println(""); - - j = new JSONObject("{ fun => with non-standard forms ; forgiving => This package can be used to parse formats that are similar to but not stricting conforming to JSON; why=To make it easier to migrate existing data to JSON,one = [[1.00]]; uno=[[{1=>1}]];'+':+6e66 ;pluses=+++;empty = '' , 'double':0.666,true: TRUE, false: FALSE, null=NULL;[true] = [[!,@;*]]; string=> o. k. ; # comment\r oct=0666; hex=0x666; dec=666; o=0999; noh=0x0x}"); - System.out.println(j.toString(4)); - System.out.println(""); - if (j.getBoolean("true") && !j.getBoolean("false")) { - System.out.println("It's all good"); - } - - System.out.println(""); - j = new JSONObject(j, new String[]{"dec", "oct", "hex", "missing"}); - System.out.println(j.toString(4)); - - System.out.println(""); - System.out.println(new JSONStringer().array().value(a).value(j).endArray()); - - j = new JSONObject("{string: \"98.6\", long: 2147483648, int: 2147483647, longer: 9223372036854775807, double: 9223372036854775808}"); - System.out.println(j.toString(4)); - - System.out.println("\ngetInt"); - System.out.println("int " + j.getInt("int")); - System.out.println("long " + j.getInt("long")); - System.out.println("longer " + j.getInt("longer")); - System.out.println("double " + j.getInt("double")); - System.out.println("string " + j.getInt("string")); - - System.out.println("\ngetLong"); - System.out.println("int " + j.getLong("int")); - System.out.println("long " + j.getLong("long")); - System.out.println("longer " + j.getLong("longer")); - System.out.println("double " + j.getLong("double")); - System.out.println("string " + j.getLong("string")); - - System.out.println("\ngetDouble"); - System.out.println("int " + j.getDouble("int")); - System.out.println("long " + j.getDouble("long")); - System.out.println("longer " + j.getDouble("longer")); - System.out.println("double " + j.getDouble("double")); - System.out.println("string " + j.getDouble("string")); - - j.put("good sized", 9223372036854775807L); - System.out.println(j.toString(4)); - - a = new JSONArray("[2147483647, 2147483648, 9223372036854775807, 9223372036854775808]"); - System.out.println(a.toString(4)); - - System.out.println("\nKeys: "); - it = j.keys(); - while (it.hasNext()) { - s = (String)it.next(); - System.out.println(s + ": " + j.getString(s)); - } - - - System.out.println("\naccumulate: "); - j = new JSONObject(); - j.accumulate("stooge", "Curly"); - j.accumulate("stooge", "Larry"); - j.accumulate("stooge", "Moe"); - a = j.getJSONArray("stooge"); - a.put(5, "Shemp"); - System.out.println(j.toString(4)); - - System.out.println("\nwrite:"); - System.out.println(j.write(new StringWriter())); - - s = "122333"; - j = XML.toJSONObject(s); - System.out.println(j.toString(4)); - System.out.println(XML.toString(j)); - - s = "Content of the first chapterContent of the second chapter Content of the first subchapter Content of the second subchapterThird Chapter"; - j = XML.toJSONObject(s); - System.out.println(j.toString(4)); - System.out.println(XML.toString(j)); - - Collection c = null; - Map m = null; - - j = new JSONObject(m); - a = new JSONArray(c); - j.append("stooge", "Joe DeRita"); - j.append("stooge", "Shemp"); - j.accumulate("stooges", "Curly"); - j.accumulate("stooges", "Larry"); - j.accumulate("stooges", "Moe"); - j.accumulate("stoogearray", j.get("stooges")); - j.put("map", m); - j.put("collection", c); - j.put("array", a); - a.put(m); - a.put(c); - System.out.println(j.toString(4)); - - s = "{plist=Apple; AnimalSmells = { pig = piggish; lamb = lambish; worm = wormy; }; AnimalSounds = { pig = oink; lamb = baa; worm = baa; Lisa = \"Why is the worm talking like a lamb?\" } ; AnimalColors = { pig = pink; lamb = black; worm = pink; } } "; - j = new JSONObject(s); - System.out.println(j.toString(4)); - - s = " (\"San Francisco\", \"New York\", \"Seoul\", \"London\", \"Seattle\", \"Shanghai\")"; - a = new JSONArray(s); - System.out.println(a.toString()); - - s = "The content of b and The content of cdoremi"; - j = XML.toJSONObject(s); - - System.out.println(j.toString(2)); - System.out.println(XML.toString(j)); - System.out.println(""); - ja = JSONML.toJSONArray(s); - System.out.println(ja.toString(4)); - System.out.println(JSONML.toString(ja)); - System.out.println(""); - - - System.out.println("\nTesting Exceptions: "); - - System.out.print("Exception: "); - try { - a = new JSONArray(); - a.put(Double.NEGATIVE_INFINITY); - a.put(Double.NaN); - System.out.println(a.toString()); - } catch (Exception e) { - System.out.println(e); - } - System.out.print("Exception: "); - try { - System.out.println(j.getDouble("stooge")); - } catch (Exception e) { - System.out.println(e); - } - System.out.print("Exception: "); - try { - System.out.println(j.getDouble("howard")); - } catch (Exception e) { - System.out.println(e); - } - System.out.print("Exception: "); - try { - System.out.println(j.put(null, "howard")); - } catch (Exception e) { - System.out.println(e); - } - System.out.print("Exception: "); - try { - System.out.println(a.getDouble(0)); - } catch (Exception e) { - System.out.println(e); - } - System.out.print("Exception: "); - try { - System.out.println(a.get(-1)); - } catch (Exception e) { - System.out.println(e); - } - System.out.print("Exception: "); - try { - System.out.println(a.put(Double.NaN)); - } catch (Exception e) { - System.out.println(e); - } - System.out.print("Exception: "); - try { - j = XML.toJSONObject(" "); - } catch (Exception e) { - System.out.println(e); - } - System.out.print("Exception: "); - try { - j = XML.toJSONObject(" "); - } catch (Exception e) { - System.out.println(e); - } - System.out.print("Exception: "); - try { - j = XML.toJSONObject("'. */ - 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: - *