diff --git a/CDL.java b/CDL.java
index 0fc3cf828..8520e862d 100755
--- a/CDL.java
+++ b/CDL.java
@@ -26,7 +26,7 @@ of this software and associated documentation files (the "Software"), to deal
/**
* This provides static methods to convert comma delimited text into a
- * JSONArray, and to covert a JSONArray into comma delimited text. Comma
+ * JSONArray, and to convert a JSONArray into comma delimited text. Comma
* delimited text is a very popular format for data interchange. It is
* understood by most database, spreadsheet, and organizer programs.
*
@@ -41,7 +41,7 @@ of this software and associated documentation files (the "Software"), to deal
* The names for the elements in the JSONObjects can be taken from the names
* in the first row.
* @author JSON.org
- * @version 2012-11-13
+ * @version 2015-05-01
*/
public class CDL {
@@ -142,7 +142,7 @@ public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x)
* @return A string ending in NEWLINE.
*/
public static String rowToString(JSONArray ja) {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (int i = 0; i < ja.length(); i += 1) {
if (i > 0) {
sb.append(',');
diff --git a/Cookie.java b/Cookie.java
index 9cf5ce2c5..1867dbd74 100755
--- a/Cookie.java
+++ b/Cookie.java
@@ -1,169 +1,169 @@
-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 2010-12-24
- */
-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 length = s.length();
- for (int i = 0; i < length; 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 name;
- JSONObject jo = new JSONObject();
- Object value;
- JSONTokener x = new JSONTokener(string);
- jo.put("name", x.nextTo('='));
- x.next('=');
- jo.put("value", x.nextTo(';'));
- x.next();
- while (x.more()) {
- name = unescape(x.nextTo("=;"));
- if (x.next() != '=') {
- if (name.equals("secure")) {
- value = Boolean.TRUE;
- } else {
- throw x.syntaxError("Missing '=' in cookie parameter.");
- }
- } else {
- value = unescape(x.nextTo(';'));
- x.next();
- }
- jo.put(name, value);
- }
- return jo;
- }
-
-
- /**
- * 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 jo A JSONObject
- * @return A cookie specification string
- * @throws JSONException
- */
- public static String toString(JSONObject jo) throws JSONException {
- StringBuffer sb = new StringBuffer();
-
- sb.append(escape(jo.getString("name")));
- sb.append("=");
- sb.append(escape(jo.getString("value")));
- if (jo.has("expires")) {
- sb.append(";expires=");
- sb.append(jo.getString("expires"));
- }
- if (jo.has("domain")) {
- sb.append(";domain=");
- sb.append(escape(jo.getString("domain")));
- }
- if (jo.has("path")) {
- sb.append(";path=");
- sb.append(escape(jo.getString("path")));
- }
- if (jo.optBoolean("secure")) {
- sb.append(";secure");
- }
- return sb.toString();
- }
-
- /**
- * Convert %hh sequences to single characters, and
- * convert plus to space.
- * @param string A string that may contain
- * + (plus) and
- * %hh sequences.
- * @return The unescaped string.
- */
- public static String unescape(String string) {
- int length = string.length();
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < length; ++i) {
- char c = string.charAt(i);
- if (c == '+') {
- c = ' ';
- } else if (c == '%' && i + 2 < length) {
- int d = JSONTokener.dehexchar(string.charAt(i + 1));
- int e = JSONTokener.dehexchar(string.charAt(i + 2));
- if (d >= 0 && e >= 0) {
- c = (char)(d * 16 + e);
- i += 2;
- }
- }
- sb.append(c);
- }
- return sb.toString();
- }
-}
+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 2014-05-03
+ */
+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();
+ int length = s.length();
+ StringBuilder sb = new StringBuilder(length);
+ for (int i = 0; i < length; 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 name;
+ JSONObject jo = new JSONObject();
+ Object value;
+ JSONTokener x = new JSONTokener(string);
+ jo.put("name", x.nextTo('='));
+ x.next('=');
+ jo.put("value", x.nextTo(';'));
+ x.next();
+ while (x.more()) {
+ name = unescape(x.nextTo("=;"));
+ if (x.next() != '=') {
+ if (name.equals("secure")) {
+ value = Boolean.TRUE;
+ } else {
+ throw x.syntaxError("Missing '=' in cookie parameter.");
+ }
+ } else {
+ value = unescape(x.nextTo(';'));
+ x.next();
+ }
+ jo.put(name, value);
+ }
+ return jo;
+ }
+
+
+ /**
+ * 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 jo A JSONObject
+ * @return A cookie specification string
+ * @throws JSONException
+ */
+ public static String toString(JSONObject jo) throws JSONException {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(escape(jo.getString("name")));
+ sb.append("=");
+ sb.append(escape(jo.getString("value")));
+ if (jo.has("expires")) {
+ sb.append(";expires=");
+ sb.append(jo.getString("expires"));
+ }
+ if (jo.has("domain")) {
+ sb.append(";domain=");
+ sb.append(escape(jo.getString("domain")));
+ }
+ if (jo.has("path")) {
+ sb.append(";path=");
+ sb.append(escape(jo.getString("path")));
+ }
+ if (jo.optBoolean("secure")) {
+ sb.append(";secure");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Convert %hh sequences to single characters, and
+ * convert plus to space.
+ * @param string A string that may contain
+ * + (plus) and
+ * %hh sequences.
+ * @return The unescaped string.
+ */
+ public static String unescape(String string) {
+ int length = string.length();
+ StringBuilder sb = new StringBuilder(length);
+ for (int i = 0; i < length; ++i) {
+ char c = string.charAt(i);
+ if (c == '+') {
+ c = ' ';
+ } else if (c == '%' && i + 2 < length) {
+ int d = JSONTokener.dehexchar(string.charAt(i + 1));
+ int e = JSONTokener.dehexchar(string.charAt(i + 2));
+ if (d >= 0 && e >= 0) {
+ c = (char)(d * 16 + e);
+ i += 2;
+ }
+ }
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+}
diff --git a/CookieList.java b/CookieList.java
index 7f4fe0751..b716fd7e3 100755
--- a/CookieList.java
+++ b/CookieList.java
@@ -1,90 +1,89 @@
-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 2010-12-24
- */
-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 jo = new JSONObject();
- JSONTokener x = new JSONTokener(string);
- while (x.more()) {
- String name = Cookie.unescape(x.nextTo('='));
- x.next('=');
- jo.put(name, Cookie.unescape(x.nextTo(';')));
- x.next();
- }
- return jo;
- }
-
-
- /**
- * 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 jo A JSONObject
- * @return A cookie list string
- * @throws JSONException
- */
- public static String toString(JSONObject jo) throws JSONException {
- boolean b = false;
- Iterator keys = jo.keys();
- String string;
- StringBuffer sb = new StringBuffer();
- while (keys.hasNext()) {
- string = keys.next().toString();
- if (!jo.isNull(string)) {
- if (b) {
- sb.append(';');
- }
- sb.append(Cookie.escape(string));
- sb.append("=");
- sb.append(Cookie.escape(jo.getString(string)));
- b = true;
- }
- }
- return sb.toString();
- }
-}
+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 2014-05-03
+ */
+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 jo = new JSONObject();
+ JSONTokener x = new JSONTokener(string);
+ while (x.more()) {
+ String name = Cookie.unescape(x.nextTo('='));
+ x.next('=');
+ jo.put(name, Cookie.unescape(x.nextTo(';')));
+ x.next();
+ }
+ return jo;
+ }
+
+ /**
+ * 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 jo A JSONObject
+ * @return A cookie list string
+ * @throws JSONException
+ */
+ public static String toString(JSONObject jo) throws JSONException {
+ boolean b = false;
+ Iterator keys = jo.keys();
+ String string;
+ StringBuilder sb = new StringBuilder();
+ while (keys.hasNext()) {
+ string = keys.next();
+ if (!jo.isNull(string)) {
+ if (b) {
+ sb.append(';');
+ }
+ sb.append(Cookie.escape(string));
+ sb.append("=");
+ sb.append(Cookie.escape(jo.getString(string)));
+ b = true;
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/HTTP.java b/HTTP.java
index 43d04a804..648f4dad7 100755
--- a/HTTP.java
+++ b/HTTP.java
@@ -29,7 +29,7 @@ of this software and associated documentation files (the "Software"), to deal
/**
* Convert an HTTP header to a JSONObject and back.
* @author JSON.org
- * @version 2010-12-24
+ * @version 2014-05-03
*/
public class HTTP {
@@ -125,9 +125,9 @@ public static JSONObject toJSONObject(String string) throws JSONException {
* information.
*/
public static String toString(JSONObject jo) throws JSONException {
- Iterator keys = jo.keys();
- String string;
- StringBuffer sb = new StringBuffer();
+ Iterator keys = jo.keys();
+ String string;
+ StringBuilder sb = new StringBuilder();
if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
sb.append(jo.getString("HTTP-Version"));
sb.append(' ');
@@ -147,7 +147,7 @@ public static String toString(JSONObject jo) throws JSONException {
}
sb.append(CRLF);
while (keys.hasNext()) {
- string = keys.next().toString();
+ string = keys.next();
if (!"HTTP-Version".equals(string) && !"Status-Code".equals(string) &&
!"Reason-Phrase".equals(string) && !"Method".equals(string) &&
!"Request-URI".equals(string) && !jo.isNull(string)) {
diff --git a/HTTPTokener.java b/HTTPTokener.java
index ed41744a0..b2489b68d 100755
--- a/HTTPTokener.java
+++ b/HTTPTokener.java
@@ -28,7 +28,7 @@ of this software and associated documentation files (the "Software"), to deal
* The HTTPTokener extends the JSONTokener to provide additional methods
* for the parsing of HTTP headers.
* @author JSON.org
- * @version 2012-11-13
+ * @version 2014-05-03
*/
public class HTTPTokener extends JSONTokener {
@@ -49,7 +49,7 @@ public HTTPTokener(String string) {
public String nextToken() throws JSONException {
char c;
char q;
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
do {
c = next();
} while (Character.isWhitespace(c));
diff --git a/JSONArray.java b/JSONArray.java
index 7c71d8db4..b1334db25 100644
--- a/JSONArray.java
+++ b/JSONArray.java
@@ -28,6 +28,7 @@ of this software and associated documentation files (the "Software"), to deal
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Array;
+import java.math.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@@ -69,28 +70,26 @@ of this software and associated documentation files (the "Software"), to deal
* 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
+ * { } [ ] / \ : , # 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) .
*
*
* @author JSON.org
- * @version 2012-11-13
+ * @version 2015-07-06
*/
-public class JSONArray {
+public class JSONArray implements Iterable {
/**
* The arrayList where the JSONArray's properties are kept.
*/
- private final ArrayList myArrayList;
+ private final ArrayList myArrayList;
/**
* Construct an empty JSONArray.
*/
public JSONArray() {
- this.myArrayList = new ArrayList();
+ this.myArrayList = new ArrayList();
}
/**
@@ -117,7 +116,6 @@ public JSONArray(JSONTokener x) throws JSONException {
this.myArrayList.add(x.nextValue());
}
switch (x.nextClean()) {
- case ';':
case ',':
if (x.nextClean() == ']') {
return;
@@ -153,10 +151,10 @@ public JSONArray(String source) throws JSONException {
* @param collection
* A Collection.
*/
- public JSONArray(Collection collection) {
- this.myArrayList = new ArrayList();
+ public JSONArray(Collection collection) {
+ this.myArrayList = new ArrayList();
if (collection != null) {
- Iterator iter = collection.iterator();
+ Iterator iter = collection.iterator();
while (iter.hasNext()) {
this.myArrayList.add(JSONObject.wrap(iter.next()));
}
@@ -182,6 +180,11 @@ public JSONArray(Object array) throws JSONException {
}
}
+ @Override
+ public Iterator iterator() {
+ return myArrayList.iterator();
+ }
+
/**
* Get the object value associated with an index.
*
@@ -244,6 +247,46 @@ public double getDouble(int index) throws JSONException {
}
}
+ /**
+ * Get the BigDecimal 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 BigDecimal.
+ */
+ public BigDecimal getBigDecimal (int index) throws JSONException {
+ Object object = this.get(index);
+ try {
+ return new BigDecimal(object.toString());
+ } catch (Exception e) {
+ throw new JSONException("JSONArray[" + index +
+ "] could not convert to BigDecimal.");
+ }
+ }
+
+ /**
+ * Get the BigInteger 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 BigInteger.
+ */
+ public BigInteger getBigInteger (int index) throws JSONException {
+ Object object = this.get(index);
+ try {
+ return new BigInteger(object.toString());
+ } catch (Exception e) {
+ throw new JSONException("JSONArray[" + index +
+ "] could not convert to BigInteger.");
+ }
+ }
+
/**
* Get the int value associated with an index.
*
@@ -360,7 +403,7 @@ public boolean isNull(int index) {
*/
public String join(String separator) throws JSONException {
int len = this.length();
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i += 1) {
if (i > 0) {
@@ -488,6 +531,44 @@ public int optInt(int index, int defaultValue) {
}
}
+ /**
+ * Get the optional BigInteger 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 BigInteger optBigInteger(int index, BigInteger defaultValue) {
+ try {
+ return this.getBigInteger(index);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Get the optional BigDecimal 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 BigDecimal optBigDecimal(int index, BigDecimal defaultValue) {
+ try {
+ return this.getBigDecimal(index);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
/**
* Get the optional JSONArray associated with an index.
*
@@ -596,7 +677,7 @@ public JSONArray put(boolean value) {
* A Collection value.
* @return this.
*/
- public JSONArray put(Collection value) {
+ public JSONArray put(Collection value) {
this.put(new JSONArray(value));
return this;
}
@@ -649,7 +730,7 @@ public JSONArray put(long value) {
* A Map value.
* @return this.
*/
- public JSONArray put(Map value) {
+ public JSONArray put(Map value) {
this.put(new JSONObject(value));
return this;
}
@@ -698,7 +779,7 @@ public JSONArray put(int index, boolean value) throws JSONException {
* @throws JSONException
* If the index is negative or if the value is not finite.
*/
- public JSONArray put(int index, Collection value) throws JSONException {
+ public JSONArray put(int index, Collection value) throws JSONException {
this.put(index, new JSONArray(value));
return this;
}
@@ -770,7 +851,7 @@ public JSONArray put(int index, long value) 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 {
+ public JSONArray put(int index, Map value) throws JSONException {
this.put(index, new JSONObject(value));
return this;
}
@@ -816,9 +897,42 @@ public JSONArray put(int index, Object value) throws JSONException {
* was no value.
*/
public Object remove(int index) {
- Object o = this.opt(index);
- this.myArrayList.remove(index);
- return o;
+ return index >= 0 && index < this.length()
+ ? this.myArrayList.remove(index)
+ : null;
+ }
+
+ /**
+ * Determine if two JSONArrays are similar.
+ * They must contain similar sequences.
+ *
+ * @param other The other JSONArray
+ * @return true if they are equal
+ */
+ public boolean similar(Object other) {
+ if (!(other instanceof JSONArray)) {
+ return false;
+ }
+ int len = this.length();
+ if (len != ((JSONArray)other).length()) {
+ return false;
+ }
+ for (int i = 0; i < len; i += 1) {
+ Object valueThis = this.get(i);
+ Object valueOther = ((JSONArray)other).get(i);
+ if (valueThis instanceof JSONObject) {
+ if (!((JSONObject)valueThis).similar(valueOther)) {
+ return false;
+ }
+ } else if (valueThis instanceof JSONArray) {
+ if (!((JSONArray)valueThis).similar(valueOther)) {
+ return false;
+ }
+ } else if (!valueThis.equals(valueOther)) {
+ return false;
+ }
+ }
+ return true;
}
/**
diff --git a/JSONException.java b/JSONException.java
index 971547e63..6fef51943 100755
--- a/JSONException.java
+++ b/JSONException.java
@@ -4,7 +4,7 @@
* The JSONException is thrown by the JSON.org classes when things are amiss.
*
* @author JSON.org
- * @version 2013-02-10
+ * @version 2014-05-03
*/
public class JSONException extends RuntimeException {
private static final long serialVersionUID = 0;
@@ -22,6 +22,7 @@ public JSONException(String message) {
/**
* Constructs a new JSONException with the specified cause.
+ * @param cause The cause.
*/
public JSONException(Throwable cause) {
super(cause.getMessage());
@@ -32,9 +33,10 @@ public JSONException(Throwable cause) {
* Returns the cause of this exception or null if the cause is nonexistent
* or unknown.
*
- * @returns the cause of this exception or null if the cause is nonexistent
+ * @return the cause of this exception or null if the cause is nonexistent
* or unknown.
*/
+ @Override
public Throwable getCause() {
return this.cause;
}
diff --git a/JSONML.java b/JSONML.java
index 4be686351..42027cb00 100755
--- a/JSONML.java
+++ b/JSONML.java
@@ -33,7 +33,7 @@ of this software and associated documentation files (the "Software"), to deal
* the JsonML transform.
*
* @author JSON.org
- * @version 2012-03-28
+ * @version 2014-05-03
*/
public class JSONML {
@@ -53,12 +53,12 @@ private static Object parse(
) throws JSONException {
String attribute;
char c;
- String closeTag = null;
+ String closeTag = null;
int i;
JSONArray newja = null;
JSONObject newjo = null;
Object token;
- String tagName = null;
+ String tagName = null;
// Test for and skip past these forms:
//
@@ -312,15 +312,15 @@ public static JSONObject toJSONObject(String string) throws JSONException {
* @throws JSONException
*/
public static String toString(JSONArray ja) throws JSONException {
- int i;
- JSONObject jo;
- String key;
- Iterator keys;
- int length;
- Object object;
- StringBuffer sb = new StringBuffer();
- String tagName;
- String value;
+ int i;
+ JSONObject jo;
+ String key;
+ Iterator keys;
+ int length;
+ Object object;
+ StringBuilder sb = new StringBuilder();
+ String tagName;
+ String value;
// Emit = length) {
@@ -373,6 +373,8 @@ public static String toString(JSONArray ja) throws JSONException {
sb.append(toString((JSONObject)object));
} else if (object instanceof JSONArray) {
sb.append(toString((JSONArray)object));
+ } else {
+ sb.append(object.toString());
}
}
} while (i < length);
@@ -394,15 +396,15 @@ public static String toString(JSONArray ja) throws JSONException {
* @throws JSONException
*/
public static String toString(JSONObject jo) throws JSONException {
- StringBuffer sb = new StringBuffer();
- int i;
- JSONArray ja;
- String key;
- Iterator keys;
- int length;
- Object object;
- String tagName;
- String value;
+ StringBuilder sb = new StringBuilder();
+ int i;
+ JSONArray ja;
+ String key;
+ Iterator keys;
+ int length;
+ Object object;
+ String tagName;
+ String value;
//Emit 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,
+ * 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.
+ * 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
- * coercion for you. The opt methods differ from the get methods in that they do
- * not throw. Instead, they return a specified value, such as null.
+ * coercion for you. The opt methods differ from the get methods in that they
+ * do not throw. Instead, they return a specified value, such as null.
*
- * The put methods add or replace values in an object. For example,
+ * The put methods add or replace values in an object. For
+ * example,
*
*
- * myString = new JSONObject().put("JSON", "Hello, World!").toString();
+ * myString = new JSONObject()
+ * .put("JSON", "Hello, World!").toString();
*
*
* produces the string {"JSON": "Hello, World"}.
@@ -78,63 +83,52 @@ of this software and associated documentation files (the "Software"), to deal
* 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) .
+ * 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.
*
*
* @author JSON.org
- * @version 2012-12-01
+ * @version 2015-07-06
*/
public class JSONObject {
- /**
- * The maximum number of keys in the key pool.
- */
- private static final int keyPoolSize = 100;
-
- /**
- * Key pooling is like string interning, but without permanently tying up
- * memory. To help conserve memory, storage of duplicated key strings in
- * JSONObjects will be avoided by using a key pool to manage unique key
- * string objects. This is used by JSONObject.put(string, object).
- */
- private static HashMap keyPool = new HashMap(keyPoolSize);
-
/**
* 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 {
+ 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.
+ *
+ * @return NULL.
*/
+ @Override
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.
+ *
+ * @param object
+ * An object to test for nullness.
+ * @return true if the object parameter is the JSONObject.NULL object or
+ * null.
*/
+ @Override
public boolean equals(Object object) {
return object == null || object == this;
}
/**
* Get the "null" string value.
+ *
* @return The string "null".
*/
public String toString() {
@@ -142,12 +136,10 @@ public String toString() {
}
}
-
/**
* The map where the JSONObject's properties are kept.
*/
- private final Map map;
-
+ private final Map map;
/**
* It is sometimes more convenient and less ambiguous to have a
@@ -157,23 +149,26 @@ public String toString() {
*/
public static final Object NULL = new Null();
-
/**
* Construct an empty JSONObject.
*/
public JSONObject() {
- this.map = new HashMap();
+ this.map = 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.
+ * 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.
* @throws JSONException
- * @exception JSONException If a value is a non-finite number or if a name is duplicated.
+ * @exception JSONException
+ * If a value is a non-finite number or if a name is
+ * duplicated.
*/
public JSONObject(JSONObject jo, String[] names) {
this();
@@ -185,12 +180,14 @@ public JSONObject(JSONObject jo, String[] names) {
}
}
-
/**
* 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
- * or a duplicated key.
+ *
+ * @param x
+ * A JSONTokener object containing the source string.
+ * @throws JSONException
+ * If there is a syntax error in the source string or a
+ * duplicated key.
*/
public JSONObject(JSONTokener x) throws JSONException {
this();
@@ -212,19 +209,15 @@ public JSONObject(JSONTokener x) throws JSONException {
key = x.nextValue().toString();
}
-// The key is followed by ':'. We will also tolerate '=' or '=>'.
+// The key is followed by ':'.
c = x.nextClean();
- if (c == '=') {
- if (x.next() != '>') {
- x.back();
- }
- } else if (c != ':') {
+ if (c != ':') {
throw x.syntaxError("Expected a ':' after a key");
}
this.putOnce(key, x.nextValue());
-// Pairs are separated by ','. We will also tolerate ';'.
+// Pairs are separated by ','.
switch (x.nextClean()) {
case ';':
@@ -242,68 +235,71 @@ public JSONObject(JSONTokener x) throws JSONException {
}
}
-
/**
* Construct a JSONObject from a Map.
*
- * @param map A map object that can be used to initialize the contents of
- * the JSONObject.
+ * @param map
+ * A map object that can be used to initialize the contents of
+ * the JSONObject.
* @throws JSONException
*/
- public JSONObject(Map map) {
- this.map = new HashMap();
+ public JSONObject(Map map) {
+ this.map = new HashMap();
if (map != null) {
- Iterator i = map.entrySet().iterator();
+ Iterator> i = map.entrySet().iterator();
while (i.hasNext()) {
- Map.Entry e = (Map.Entry)i.next();
- Object value = e.getValue();
+ Entry entry = i.next();
+ Object value = entry.getValue();
if (value != null) {
- this.map.put(e.getKey(), wrap(value));
+ this.map.put(entry.getKey(), wrap(value));
}
}
}
}
-
/**
- * 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.
+ * 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.
+ * 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".
+ * 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.
+ * @param bean
+ * An object that has getter methods that should be used to make
+ * a JSONObject.
*/
public JSONObject(Object bean) {
this();
this.populateMap(bean);
}
-
/**
* 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 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();
+ Class> c = object.getClass();
for (int i = 0; i < names.length; i += 1) {
String name = names[i];
try {
@@ -313,26 +309,31 @@ public JSONObject(Object object, String names[]) {
}
}
-
/**
- * 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 or a duplicated key.
+ * 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 or a
+ * duplicated key.
*/
public JSONObject(String source) throws JSONException {
this(new JSONTokener(source));
}
-
/**
* Construct a JSONObject from a ResourceBundle.
- * @param baseName The ResourceBundle base name.
- * @param locale The Locale to load the ResourceBundle for.
- * @throws JSONException If any JSONExceptions are detected.
+ *
+ * @param baseName
+ * The ResourceBundle base name.
+ * @param locale
+ * The Locale to load the ResourceBundle for.
+ * @throws JSONException
+ * If any JSONExceptions are detected.
*/
public JSONObject(String baseName, Locale locale) throws JSONException {
this();
@@ -341,16 +342,16 @@ public JSONObject(String baseName, Locale locale) throws JSONException {
// Iterate through the keys in the bundle.
- Enumeration keys = bundle.getKeys();
+ Enumeration keys = bundle.getKeys();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
- if (key instanceof String) {
+ if (key != null) {
// Go through the path, ensuring that there is a nested JSONObject for each
// segment except the last. Add the value using the last segment's name into
// the deepest nested JSONObject.
- String[] path = ((String)key).split("\\.");
+ String[] path = ((String) key).split("\\.");
int last = path.length - 1;
JSONObject target = this;
for (int i = 0; i < last; i += 1) {
@@ -362,57 +363,59 @@ public JSONObject(String baseName, Locale locale) throws JSONException {
}
target = nextTarget;
}
- target.put(path[last], bundle.getString((String)key));
+ target.put(path[last], bundle.getString((String) key));
}
}
}
-
/**
* 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.
- *
- * If only one value is accumulated that is not a JSONArray, then the
- * result will be the same as using put. But if multiple values are
- * accumulated, then the result will be like append.
- * @param key A key string.
- * @param value An object to be accumulated under the key.
+ * 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.
+ *
+ * If only one value is accumulated that is not a JSONArray, then the result
+ * will be the same as using put. But if multiple values are accumulated,
+ * then the result will be like append.
+ *
+ * @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.
+ * @throws JSONException
+ * If the value is an invalid number or if the key is null.
*/
- public JSONObject accumulate(
- String key,
- Object value
- ) throws JSONException {
+ public JSONObject accumulate(String key, Object value) throws JSONException {
testValidity(value);
Object object = this.opt(key);
if (object == null) {
- this.put(key, value instanceof JSONArray
- ? new JSONArray().put(value)
- : value);
+ this.put(key,
+ value instanceof JSONArray ? new JSONArray().put(value)
+ : value);
} else if (object instanceof JSONArray) {
- ((JSONArray)object).put(value);
+ ((JSONArray) object).put(value);
} else {
this.put(key, new JSONArray().put(object).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.
+ *
+ * @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.
+ * @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);
@@ -420,19 +423,20 @@ public JSONObject append(String key, Object value) throws JSONException {
if (object == null) {
this.put(key, new JSONArray().put(value));
} else if (object instanceof JSONArray) {
- this.put(key, ((JSONArray)object).put(value));
+ this.put(key, ((JSONArray) object).put(value));
} else {
- throw new JSONException("JSONObject[" + key +
- "] is not a JSONArray.");
+ 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.
+ * 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.
*/
public static String doubleToString(double d) {
@@ -443,8 +447,8 @@ public static String doubleToString(double d) {
// Shave off trailing zeros and decimal point, if possible.
String string = Double.toString(d);
- if (string.indexOf('.') > 0 && string.indexOf('e') < 0 &&
- string.indexOf('E') < 0) {
+ if (string.indexOf('.') > 0 && string.indexOf('e') < 0
+ && string.indexOf('E') < 0) {
while (string.endsWith("0")) {
string = string.substring(0, string.length() - 1);
}
@@ -455,13 +459,14 @@ public static String doubleToString(double d) {
return string;
}
-
/**
* 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.
+ * @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 {
if (key == null) {
@@ -469,135 +474,175 @@ public Object get(String key) throws JSONException {
}
Object object = this.opt(key);
if (object == null) {
- throw new JSONException("JSONObject[" + quote(key) +
- "] not found.");
+ throw new JSONException("JSONObject[" + quote(key) + "] not found.");
}
return object;
}
-
/**
* 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".
+ * @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 object = this.get(key);
- if (object.equals(Boolean.FALSE) ||
- (object instanceof String &&
- ((String)object).equalsIgnoreCase("false"))) {
+ if (object.equals(Boolean.FALSE)
+ || (object instanceof String && ((String) object)
+ .equalsIgnoreCase("false"))) {
return false;
- } else if (object.equals(Boolean.TRUE) ||
- (object instanceof String &&
- ((String)object).equalsIgnoreCase("true"))) {
+ } else if (object.equals(Boolean.TRUE)
+ || (object instanceof String && ((String) object)
+ .equalsIgnoreCase("true"))) {
return true;
}
- throw new JSONException("JSONObject[" + quote(key) +
- "] is not a Boolean.");
+ throw new JSONException("JSONObject[" + quote(key)
+ + "] is not a Boolean.");
+ }
+
+ /**
+ * Get the BigInteger 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 cannot
+ * be converted to BigInteger.
+ */
+ public BigInteger getBigInteger(String key) throws JSONException {
+ Object object = this.get(key);
+ try {
+ return new BigInteger(object.toString());
+ } catch (Exception e) {
+ throw new JSONException("JSONObject[" + quote(key)
+ + "] could not be converted to BigInteger.");
+ }
}
+ /**
+ * Get the BigDecimal 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
+ * cannot be converted to BigDecimal.
+ */
+ public BigDecimal getBigDecimal(String key) throws JSONException {
+ Object object = this.get(key);
+ try {
+ return new BigDecimal(object.toString());
+ } catch (Exception e) {
+ throw new JSONException("JSONObject[" + quote(key)
+ + "] could not be converted to BigDecimal.");
+ }
+ }
/**
* 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.
+ *
+ * @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 object = this.get(key);
try {
- return object instanceof Number
- ? ((Number)object).doubleValue()
- : Double.parseDouble((String)object);
+ return object instanceof Number ? ((Number) object).doubleValue()
+ : Double.parseDouble((String) object);
} catch (Exception e) {
- throw new JSONException("JSONObject[" + quote(key) +
- "] is not a number.");
+ throw new JSONException("JSONObject[" + quote(key)
+ + "] is not a number.");
}
}
-
/**
* Get the int value associated with a key.
*
- * @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.
+ * @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 object = this.get(key);
try {
- return object instanceof Number
- ? ((Number)object).intValue()
- : Integer.parseInt((String)object);
+ return object instanceof Number ? ((Number) object).intValue()
+ : Integer.parseInt((String) object);
} catch (Exception e) {
- throw new JSONException("JSONObject[" + quote(key) +
- "] is not an int.");
+ throw new JSONException("JSONObject[" + quote(key)
+ + "] is not an int.");
}
}
-
/**
* 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.
+ * @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 object = this.get(key);
if (object instanceof JSONArray) {
- return (JSONArray)object;
+ return (JSONArray) object;
}
- throw new JSONException("JSONObject[" + quote(key) +
- "] is not a JSONArray.");
+ 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.
+ * @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 object = this.get(key);
if (object instanceof JSONObject) {
- return (JSONObject)object;
+ return (JSONObject) object;
}
- throw new JSONException("JSONObject[" + quote(key) +
- "] is not a JSONObject.");
+ throw new JSONException("JSONObject[" + quote(key)
+ + "] is not a JSONObject.");
}
-
/**
* Get the long value associated with a key.
*
- * @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.
+ * @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 object = this.get(key);
try {
- return object instanceof Number
- ? ((Number)object).longValue()
- : Long.parseLong((String)object);
+ return object instanceof Number ? ((Number) object).longValue()
+ : Long.parseLong((String) object);
} catch (Exception e) {
- throw new JSONException("JSONObject[" + quote(key) +
- "] is not a long.");
+ throw new JSONException("JSONObject[" + quote(key)
+ + "] is not a long.");
}
}
-
/**
* Get an array of field names from a JSONObject.
*
@@ -608,17 +653,16 @@ public static String[] getNames(JSONObject jo) {
if (length == 0) {
return null;
}
- Iterator iterator = jo.keys();
+ Iterator iterator = jo.keys();
String[] names = new String[length];
int i = 0;
while (iterator.hasNext()) {
- names[i] = (String)iterator.next();
+ names[i] = iterator.next();
i += 1;
}
return names;
}
-
/**
* Get an array of field names from an Object.
*
@@ -628,7 +672,7 @@ public static String[] getNames(Object object) {
if (object == null) {
return null;
}
- Class klass = object.getClass();
+ Class> klass = object.getClass();
Field[] fields = klass.getFields();
int length = fields.length;
if (length == 0) {
@@ -641,94 +685,99 @@ public static String[] getNames(Object object) {
return names;
}
-
/**
* Get the string associated with a key.
*
- * @param key A key string.
- * @return A string which is the value.
- * @throws JSONException if there is no string value for the key.
+ * @param key
+ * A key string.
+ * @return A string which is the value.
+ * @throws JSONException
+ * if there is no string value for the key.
*/
public String getString(String key) throws JSONException {
Object object = this.get(key);
if (object instanceof String) {
- return (String)object;
+ return (String) object;
}
- throw new JSONException("JSONObject[" + quote(key) +
- "] not a string.");
+ throw new JSONException("JSONObject[" + quote(key) + "] not a string.");
}
-
/**
* Determine if the JSONObject contains a specific key.
- * @param key A key string.
- * @return true if the key exists in the JSONObject.
+ *
+ * @param key
+ * A key string.
+ * @return true if the key exists in the JSONObject.
*/
public boolean has(String key) {
return this.map.containsKey(key);
}
-
/**
* Increment a property of a JSONObject. If there is no such property,
- * create one with a value of 1. If there is such a property, and if
- * it is an Integer, Long, Double, or Float, then add one to it.
- * @param key A key string.
+ * create one with a value of 1. If there is such a property, and if it is
+ * an Integer, Long, Double, or Float, then add one to it.
+ *
+ * @param key
+ * A key string.
* @return this.
- * @throws JSONException If there is already a property with this name
- * that is not an Integer, Long, Double, or Float.
+ * @throws JSONException
+ * If there is already a property with this name that is not an
+ * Integer, Long, Double, or Float.
*/
public JSONObject increment(String key) throws JSONException {
Object value = this.opt(key);
if (value == null) {
this.put(key, 1);
+ } else if (value instanceof BigInteger) {
+ this.put(key, ((BigInteger)value).add(BigInteger.ONE));
+ } else if (value instanceof BigDecimal) {
+ this.put(key, ((BigDecimal)value).add(BigDecimal.ONE));
} else if (value instanceof Integer) {
- this.put(key, ((Integer)value).intValue() + 1);
+ this.put(key, (Integer) value + 1);
} else if (value instanceof Long) {
- this.put(key, ((Long)value).longValue() + 1);
+ this.put(key, (Long) value + 1);
} else if (value instanceof Double) {
- this.put(key, ((Double)value).doubleValue() + 1);
+ this.put(key, (Double) value + 1);
} else if (value instanceof Float) {
- this.put(key, ((Float)value).floatValue() + 1);
+ this.put(key, (Float) value + 1);
} else {
throw new JSONException("Unable to increment [" + quote(key) + "].");
}
return this;
}
-
/**
- * 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.
+ * 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(this.opt(key));
}
-
/**
* Get an enumeration of the keys of the JSONObject.
*
* @return An iterator of the keys.
*/
- public Iterator keys() {
+ public Iterator keys() {
return this.keySet().iterator();
}
-
/**
* Get a set of keys of the JSONObject.
*
* @return A keySet.
*/
- public Set keySet() {
+ public Set keySet() {
return this.map.keySet();
}
-
/**
* Get the number of keys stored in the JSONObject.
*
@@ -738,16 +787,16 @@ public int length() {
return this.map.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.
+ * is empty.
*/
public JSONArray names() {
JSONArray ja = new JSONArray();
- Iterator keys = this.keys();
+ Iterator keys = this.keys();
while (keys.hasNext()) {
ja.put(keys.next());
}
@@ -756,12 +805,14 @@ public JSONArray names() {
/**
* Produce a string from a Number.
- * @param number A Number
+ *
+ * @param number
+ * A Number
* @return A String.
- * @throws JSONException If n is a non-finite number.
+ * @throws JSONException
+ * If n is a non-finite number.
*/
- public static String numberToString(Number number)
- throws JSONException {
+ public static String numberToString(Number number) throws JSONException {
if (number == null) {
throw new JSONException("Null pointer");
}
@@ -770,8 +821,8 @@ public static String numberToString(Number number)
// Shave off trailing zeros and decimal point, if possible.
String string = number.toString();
- if (string.indexOf('.') > 0 && string.indexOf('e') < 0 &&
- string.indexOf('E') < 0) {
+ if (string.indexOf('.') > 0 && string.indexOf('e') < 0
+ && string.indexOf('E') < 0) {
while (string.endsWith("0")) {
string = string.substring(0, string.length() - 1);
}
@@ -782,38 +833,39 @@ public static String numberToString(Number number)
return string;
}
-
/**
* 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.
+ *
+ * @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.map.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".
+ * 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.
+ * @param key
+ * A key string.
+ * @return The truth.
*/
public boolean optBoolean(String key) {
return this.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).
+ * 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.
+ * @param key
+ * A key string.
+ * @param defaultValue
+ * The default.
+ * @return The truth.
*/
public boolean optBoolean(String key, boolean defaultValue) {
try {
@@ -823,30 +875,67 @@ public boolean optBoolean(String key, boolean defaultValue) {
}
}
-
/**
- * 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.
+ * 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.
+ * @param key
+ * A string which is the key.
+ * @return An object which is the value.
*/
public double optDouble(String key) {
return this.optDouble(key, Double.NaN);
}
+ /**
+ * Get an optional BigInteger 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 BigInteger optBigInteger(String key, BigInteger defaultValue) {
+ try {
+ return this.getBigInteger(key);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Get an optional BigDecimal 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 BigDecimal optBigDecimal(String key, BigDecimal defaultValue) {
+ try {
+ return this.getBigDecimal(key);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
/**
- * 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.
+ * 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.
+ * @param key
+ * A key string.
+ * @param defaultValue
+ * The default.
+ * @return An object which is the value.
*/
public double optDouble(String key, double defaultValue) {
try {
@@ -856,30 +945,29 @@ public double optDouble(String key, double 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.
+ * 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.
+ * @param key
+ * A key string.
+ * @return An object which is the value.
*/
public int optInt(String key) {
return this.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.
+ * 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.
+ * @param key
+ * A key string.
+ * @param defaultValue
+ * The default.
+ * @return An object which is the value.
*/
public int optInt(String key, int defaultValue) {
try {
@@ -889,58 +977,55 @@ public int optInt(String key, int 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.
+ * 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.
+ * @param key
+ * A key string.
+ * @return A JSONArray which is the value.
*/
public JSONArray optJSONArray(String key) {
Object o = this.opt(key);
- return o instanceof JSONArray ? (JSONArray)o : null;
+ 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.
+ * 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.
+ * @param key
+ * A key string.
+ * @return A JSONObject which is the value.
*/
public JSONObject optJSONObject(String key) {
Object object = this.opt(key);
- return object instanceof JSONObject ? (JSONObject)object : null;
+ return object instanceof JSONObject ? (JSONObject) object : 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.
+ * 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.
+ * @param key
+ * A key string.
+ * @return An object which is the value.
*/
public long optLong(String key) {
return this.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.
+ * 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.
+ * @param key
+ * A key string.
+ * @param defaultValue
+ * The default.
+ * @return An object which is the value.
*/
public long optLong(String key, long defaultValue) {
try {
@@ -950,44 +1035,43 @@ public long optLong(String key, long 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 converted to a string.
+ * 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 converted to a string.
*
- * @param key A key string.
- * @return A string which is the value.
+ * @param key
+ * A key string.
+ * @return A string which is the value.
*/
public String optString(String key) {
return this.optString(key, "");
}
-
/**
- * Get an optional string associated with a key.
- * It returns the defaultValue if there is no such 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.
+ * @param key
+ * A key string.
+ * @param defaultValue
+ * The default.
+ * @return A string which is the value.
*/
public String optString(String key, String defaultValue) {
Object object = this.opt(key);
return NULL.equals(object) ? defaultValue : object.toString();
}
-
private void populateMap(Object bean) {
- Class klass = bean.getClass();
+ Class> klass = bean.getClass();
// If klass is a System class then set includeSuperClass to false.
boolean includeSuperClass = klass.getClassLoader() != null;
- Method[] methods = includeSuperClass
- ? klass.getMethods()
- : klass.getDeclaredMethods();
+ Method[] methods = includeSuperClass ? klass.getMethods() : klass
+ .getDeclaredMethods();
for (int i = 0; i < methods.length; i += 1) {
try {
Method method = methods[i];
@@ -995,8 +1079,8 @@ private void populateMap(Object bean) {
String name = method.getName();
String key = "";
if (name.startsWith("get")) {
- if ("getClass".equals(name) ||
- "getDeclaringClass".equals(name)) {
+ if ("getClass".equals(name)
+ || "getDeclaringClass".equals(name)) {
key = "";
} else {
key = name.substring(3);
@@ -1004,17 +1088,17 @@ private void populateMap(Object bean) {
} 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() > 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);
+ key = key.substring(0, 1).toLowerCase()
+ + key.substring(1);
}
- Object result = method.invoke(bean, (Object[])null);
+ Object result = method.invoke(bean, (Object[]) null);
if (result != null) {
this.map.put(key, wrap(result));
}
@@ -1025,118 +1109,122 @@ private void populateMap(Object bean) {
}
}
-
/**
* Put a key/boolean pair in the JSONObject.
*
- * @param key A key string.
- * @param value A boolean which is the value.
+ * @param key
+ * A key string.
+ * @param value
+ * A boolean which is the value.
* @return this.
- * @throws JSONException If the key is null.
+ * @throws JSONException
+ * If the key is null.
*/
public JSONObject put(String key, boolean value) throws JSONException {
this.put(key, value ? Boolean.TRUE : Boolean.FALSE);
return this;
}
-
/**
* 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.
+ *
+ * @param key
+ * A key string.
+ * @param value
+ * A Collection value.
+ * @return this.
* @throws JSONException
*/
- public JSONObject put(String key, Collection value) throws JSONException {
+ public JSONObject put(String key, Collection value) throws JSONException {
this.put(key, new JSONArray(value));
return this;
}
-
/**
* Put a key/double pair in the JSONObject.
*
- * @param key A key string.
- * @param value A double which is the value.
+ * @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.
+ * @throws JSONException
+ * If the key is null or if the number is invalid.
*/
public JSONObject put(String key, double value) throws JSONException {
this.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.
+ * @param key
+ * A key string.
+ * @param value
+ * An int which is the value.
* @return this.
- * @throws JSONException If the key is null.
+ * @throws JSONException
+ * If the key is null.
*/
public JSONObject put(String key, int value) throws JSONException {
this.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.
+ * @param key
+ * A key string.
+ * @param value
+ * A long which is the value.
* @return this.
- * @throws JSONException If the key is null.
+ * @throws JSONException
+ * If the key is null.
*/
public JSONObject put(String key, long value) throws JSONException {
this.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.
+ *
+ * @param key
+ * A key string.
+ * @param value
+ * A Map value.
+ * @return this.
* @throws JSONException
*/
- public JSONObject put(String key, Map value) throws JSONException {
+ public JSONObject put(String key, Map value) throws JSONException {
this.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.
+ * 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.
+ * @throws JSONException
+ * If the value is non-finite number or if the key is null.
*/
public JSONObject put(String key, Object value) throws JSONException {
- String pooled;
if (key == null) {
- throw new JSONException("Null key.");
+ throw new NullPointerException("Null key.");
}
if (value != null) {
testValidity(value);
- pooled = (String)keyPool.get(key);
- if (pooled == null) {
- if (keyPool.size() >= keyPoolSize) {
- keyPool = new HashMap(keyPoolSize);
- }
- keyPool.put(key, key);
- } else {
- key = pooled;
- }
this.map.put(key, value);
} else {
this.remove(key);
@@ -1144,15 +1232,16 @@ public JSONObject put(String key, Object value) throws JSONException {
return this;
}
-
/**
- * Put a key/value pair in the JSONObject, but only if the key and the
- * value are both non-null, and only if there is not already a member
- * with that name.
- * @param key
- * @param value
- * @return his.
- * @throws JSONException if the key is a duplicate
+ * Put a key/value pair in the JSONObject, but only if the key and the value
+ * are both non-null, and only if there is not already a member with that
+ * name.
+ *
+ * @param key string
+ * @param value object
+ * @return this.
+ * @throws JSONException
+ * if the key is a duplicate
*/
public JSONObject putOnce(String key, Object value) throws JSONException {
if (key != null && value != null) {
@@ -1164,16 +1253,19 @@ public JSONObject putOnce(String key, Object value) throws JSONException {
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.
+ * 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.
+ * @throws JSONException
+ * If the value is a non-finite number.
*/
public JSONObject putOpt(String key, Object value) throws JSONException {
if (key != null && value != null) {
@@ -1182,14 +1274,15 @@ public JSONObject putOpt(String key, Object value) throws JSONException {
return this;
}
-
/**
* Produce a string in double quotes with backslash sequences in all the
* right places. A backslash will be inserted within , producing <\/,
- * allowing JSON text to be delivered in HTML. In JSON text, a string
- * cannot contain a control character or an unescaped quote or backslash.
- * @param string A String
- * @return A String correctly formatted for insertion in a JSON text.
+ * allowing JSON text to be delivered in HTML. In JSON text, a string cannot
+ * contain a control character or an unescaped quote or backslash.
+ *
+ * @param string
+ * A String
+ * @return A String correctly formatted for insertion in a JSON text.
*/
public static String quote(String string) {
StringWriter sw = new StringWriter();
@@ -1264,18 +1357,62 @@ public static Writer quote(String string, Writer w) throws IOException {
/**
* 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.
+ *
+ * @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.map.remove(key);
}
+ /**
+ * Determine if two JSONObjects are similar.
+ * They must contain the same set of names which must be associated with
+ * similar values.
+ *
+ * @param other The other JSONObject
+ * @return true if they are equal
+ */
+ public boolean similar(Object other) {
+ try {
+ if (!(other instanceof JSONObject)) {
+ return false;
+ }
+ Set set = this.keySet();
+ if (!set.equals(((JSONObject)other).keySet())) {
+ return false;
+ }
+ Iterator iterator = set.iterator();
+ while (iterator.hasNext()) {
+ String name = iterator.next();
+ Object valueThis = this.get(name);
+ Object valueOther = ((JSONObject)other).get(name);
+ if (valueThis instanceof JSONObject) {
+ if (!((JSONObject)valueThis).similar(valueOther)) {
+ return false;
+ }
+ } else if (valueThis instanceof JSONArray) {
+ if (!((JSONArray)valueThis).similar(valueOther)) {
+ return false;
+ }
+ } else if (!valueThis.equals(valueOther)) {
+ return false;
+ }
+ }
+ return true;
+ } catch (Throwable exception) {
+ return false;
+ }
+ }
+
/**
* Try to convert a string into a number, boolean, or null. If the string
* can't be converted, return the string.
- * @param string A String.
+ *
+ * @param string
+ * A String.
* @return A simple JSON value.
*/
public static Object stringToValue(String string) {
@@ -1294,66 +1431,69 @@ public static Object stringToValue(String string) {
}
/*
- * If it might be a number, try converting it.
- * If a number cannot be produced, then the value will just
- * be a string. Note that the plus and implied string
- * conventions are non-standard. A JSON parser may accept
- * non-JSON forms as long as it accepts all correct JSON forms.
+ * If it might be a number, try converting it. If a number cannot be
+ * produced, then the value will just be a string.
*/
char b = string.charAt(0);
- if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') {
+ if ((b >= '0' && b <= '9') || b == '-') {
try {
- if (string.indexOf('.') > -1 ||
- string.indexOf('e') > -1 || string.indexOf('E') > -1) {
+ if (string.indexOf('.') > -1 || string.indexOf('e') > -1
+ || string.indexOf('E') > -1) {
d = Double.valueOf(string);
if (!d.isInfinite() && !d.isNaN()) {
return d;
}
} else {
Long myLong = new Long(string);
- if (myLong.longValue() == myLong.intValue()) {
- return new Integer(myLong.intValue());
- } else {
- return myLong;
+ if (string.equals(myLong.toString())) {
+ if (myLong == myLong.intValue()) {
+ return myLong.intValue();
+ } else {
+ return myLong;
+ }
}
}
- } catch (Exception ignore) {
+ } catch (Exception ignore) {
}
}
return string;
}
-
/**
* Throw an exception if the object is a NaN or infinite number.
- * @param o The object to test.
- * @throws JSONException If o is a non-finite number.
+ *
+ * @param o
+ * The object to test.
+ * @throws JSONException
+ * If o is a non-finite number.
*/
public static void testValidity(Object o) throws JSONException {
if (o != null) {
if (o instanceof Double) {
- if (((Double)o).isInfinite() || ((Double)o).isNaN()) {
+ if (((Double) o).isInfinite() || ((Double) o).isNaN()) {
throw new JSONException(
- "JSON does not allow non-finite numbers.");
+ "JSON does not allow non-finite numbers.");
}
} else if (o instanceof Float) {
- if (((Float)o).isInfinite() || ((Float)o).isNaN()) {
+ if (((Float) o).isInfinite() || ((Float) o).isNaN()) {
throw new JSONException(
- "JSON does not allow non-finite numbers.");
+ "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.
+ *
+ * @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.
+ * @throws JSONException
+ * If any of the values are non-finite numbers.
*/
public JSONArray toJSONArray(JSONArray names) throws JSONException {
if (names == null || names.length() == 0) {
@@ -1367,16 +1507,16 @@ public JSONArray toJSONArray(JSONArray names) throws JSONException {
}
/**
- * Make a JSON text of this JSONObject. For compactness, no whitespace
- * is added. If this would not result in a syntactically correct JSON text,
+ * 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) .
+ * @return a printable, displayable, portable, transmittable representation
+ * of the object, beginning with { (left
+ * brace) and ending with } (right
+ * brace) .
*/
public String toString() {
try {
@@ -1386,18 +1526,19 @@ public String toString() {
}
}
-
/**
* 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.
+ *
+ * @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 {
StringWriter w = new StringWriter();
@@ -1408,24 +1549,27 @@ public String toString(int indentFactor) throws JSONException {
/**
* 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.
+ * 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.
+ *
+ * @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.
*/
public static String valueToString(Object value) throws JSONException {
if (value == null || value.equals(null)) {
@@ -1434,27 +1578,31 @@ public static String valueToString(Object value) throws JSONException {
if (value instanceof JSONString) {
Object object;
try {
- object = ((JSONString)value).toJSONString();
+ object = ((JSONString) value).toJSONString();
} catch (Exception e) {
throw new JSONException(e);
}
if (object instanceof String) {
- return (String)object;
+ return (String) object;
}
throw new JSONException("Bad value from toJSONString: " + object);
}
if (value instanceof Number) {
return numberToString((Number) value);
}
- if (value instanceof Boolean || value instanceof JSONObject ||
- value instanceof JSONArray) {
+ if (value instanceof Boolean || value instanceof JSONObject
+ || value instanceof JSONArray) {
return value.toString();
}
if (value instanceof Map) {
- return new JSONObject((Map)value).toString();
+ @SuppressWarnings("unchecked")
+ Map map = (Map) value;
+ return new JSONObject(map).toString();
}
if (value instanceof Collection) {
- return new JSONArray((Collection)value).toString();
+ @SuppressWarnings("unchecked")
+ Collection coll = (Collection) value;
+ return new JSONArray(coll).toString();
}
if (value.getClass().isArray()) {
return new JSONArray(value).toString();
@@ -1462,73 +1610,73 @@ public static String valueToString(Object value) throws JSONException {
return quote(value.toString());
}
- /**
- * Wrap an object, if necessary. If the object is null, return the NULL
- * object. If it is an array or collection, wrap it in a JSONArray. If
- * it is a map, wrap it in a JSONObject. If it is a standard property
- * (Double, String, et al) then it is already wrapped. Otherwise, if it
- * comes from one of the java packages, turn it into a string. And if
- * it doesn't, try to wrap it in a JSONObject. If the wrapping fails,
- * then null is returned.
- *
- * @param object The object to wrap
- * @return The wrapped value
- */
- public static Object wrap(Object object) {
- try {
- if (object == null) {
- return NULL;
- }
- if (object instanceof JSONObject || object instanceof JSONArray ||
- NULL.equals(object) || object instanceof JSONString ||
- object instanceof Byte || object instanceof Character ||
- object instanceof Short || object instanceof Integer ||
- object instanceof Long || object instanceof Boolean ||
- object instanceof Float || object instanceof Double ||
- object instanceof String) {
- return object;
- }
-
- if (object instanceof Collection) {
- return new JSONArray((Collection)object);
- }
- if (object.getClass().isArray()) {
- return new JSONArray(object);
- }
- if (object instanceof Map) {
- return new JSONObject((Map)object);
- }
- Package objectPackage = object.getClass().getPackage();
- String objectPackageName = objectPackage != null
- ? objectPackage.getName()
- : "";
- if (
- objectPackageName.startsWith("java.") ||
- objectPackageName.startsWith("javax.") ||
- object.getClass().getClassLoader() == null
- ) {
- return object.toString();
- }
- return new JSONObject(object);
- } catch(Exception exception) {
- return null;
- }
- }
-
-
- /**
- * 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 {
- return this.write(writer, 0, 0);
+ /**
+ * Wrap an object, if necessary. If the object is null, return the NULL
+ * object. If it is an array or collection, wrap it in a JSONArray. If it is
+ * a map, wrap it in a JSONObject. If it is a standard property (Double,
+ * String, et al) then it is already wrapped. Otherwise, if it comes from
+ * one of the java packages, turn it into a string. And if it doesn't, try
+ * to wrap it in a JSONObject. If the wrapping fails, then null is returned.
+ *
+ * @param object
+ * The object to wrap
+ * @return The wrapped value
+ */
+ public static Object wrap(Object object) {
+ try {
+ if (object == null) {
+ return NULL;
+ }
+ if (object instanceof JSONObject || object instanceof JSONArray
+ || NULL.equals(object) || object instanceof JSONString
+ || object instanceof Byte || object instanceof Character
+ || object instanceof Short || object instanceof Integer
+ || object instanceof Long || object instanceof Boolean
+ || object instanceof Float || object instanceof Double
+ || object instanceof String || object instanceof BigInteger
+ || object instanceof BigDecimal) {
+ return object;
+ }
+
+ if (object instanceof Collection) {
+ @SuppressWarnings("unchecked")
+ Collection coll = (Collection) object;
+ return new JSONArray(coll);
+ }
+ if (object.getClass().isArray()) {
+ return new JSONArray(object);
+ }
+ if (object instanceof Map) {
+ @SuppressWarnings("unchecked")
+ Map map = (Map) object;
+ return new JSONObject(map);
+ }
+ Package objectPackage = object.getClass().getPackage();
+ String objectPackageName = objectPackage != null ? objectPackage
+ .getName() : "";
+ if (objectPackageName.startsWith("java.")
+ || objectPackageName.startsWith("javax.")
+ || object.getClass().getClassLoader() == null) {
+ return object.toString();
+ }
+ return new JSONObject(object);
+ } catch (Exception exception) {
+ return null;
+ }
}
+ /**
+ * 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 {
+ return this.write(writer, 0, 0);
+ }
static final Writer writeValue(Writer writer, Object value,
int indentFactor, int indent) throws JSONException, IOException {
@@ -1539,9 +1687,13 @@ static final Writer writeValue(Writer writer, Object value,
} else if (value instanceof JSONArray) {
((JSONArray) value).write(writer, indentFactor, indent);
} else if (value instanceof Map) {
- new JSONObject((Map) value).write(writer, indentFactor, indent);
+ @SuppressWarnings("unchecked")
+ Map map = (Map) value;
+ new JSONObject(map).write(writer, indentFactor, indent);
} else if (value instanceof Collection) {
- new JSONArray((Collection) value).write(writer, indentFactor,
+ @SuppressWarnings("unchecked")
+ Collection coll = (Collection) value;
+ new JSONArray(coll).write(writer, indentFactor,
indent);
} else if (value.getClass().isArray()) {
new JSONArray(value).write(writer, indentFactor, indent);
@@ -1583,7 +1735,7 @@ Writer write(Writer writer, int indentFactor, int indent)
try {
boolean commanate = false;
final int length = this.length();
- Iterator keys = this.keys();
+ Iterator keys = this.keys();
writer.write('{');
if (length == 1) {
@@ -1610,8 +1762,7 @@ Writer write(Writer writer, int indentFactor, int indent)
if (indentFactor > 0) {
writer.write(' ');
}
- writeValue(writer, this.map.get(key), indentFactor,
- newindent);
+ writeValue(writer, this.map.get(key), indentFactor, newindent);
commanate = true;
}
if (indentFactor > 0) {
@@ -1624,5 +1775,5 @@ Writer write(Writer writer, int indentFactor, int indent)
} catch (IOException exception) {
throw new JSONException(exception);
}
- }
+ }
}
diff --git a/JSONTokener.java b/JSONTokener.java
index 13c84f1f5..32548ed9f 100644
--- a/JSONTokener.java
+++ b/JSONTokener.java
@@ -36,7 +36,7 @@ of this software and associated documentation files (the "Software"), to deal
* it. It is used by the JSONObject and JSONArray constructors to parse
* JSON source strings.
* @author JSON.org
- * @version 2012-02-16
+ * @version 2014-05-03
*/
public class JSONTokener {
@@ -69,6 +69,7 @@ public JSONTokener(Reader reader) {
/**
* Construct a JSONTokener from an InputStream.
+ * @param inputStream The source.
*/
public JSONTokener(InputStream inputStream) throws JSONException {
this(new InputStreamReader(inputStream));
@@ -250,7 +251,7 @@ public char nextClean() throws JSONException {
*/
public String nextString(char quote) throws JSONException {
char c;
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (;;) {
c = this.next();
switch (c) {
@@ -306,7 +307,7 @@ public String nextString(char quote) throws JSONException {
* @return A string.
*/
public String nextTo(char delimiter) throws JSONException {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (;;) {
char c = this.next();
if (c == delimiter || c == 0 || c == '\n' || c == '\r') {
@@ -328,7 +329,7 @@ public String nextTo(char delimiter) throws JSONException {
*/
public String nextTo(String delimiters) throws JSONException {
char c;
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (;;) {
c = this.next();
if (delimiters.indexOf(c) >= 0 || c == 0 ||
@@ -375,7 +376,7 @@ public Object nextValue() throws JSONException {
* formatting character.
*/
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
sb.append(c);
c = this.next();
@@ -414,10 +415,9 @@ public char skipTo(char to) throws JSONException {
return c;
}
} while (c != to);
- } catch (IOException exc) {
- throw new JSONException(exc);
+ } catch (IOException exception) {
+ throw new JSONException(exception);
}
-
this.back();
return c;
}
diff --git a/JSONWriter.java b/JSONWriter.java
index 855b2bdb1..07bbc8cfa 100755
--- a/JSONWriter.java
+++ b/JSONWriter.java
@@ -269,7 +269,7 @@ private void pop(char c) throws JSONException {
/**
* Push an array or object scope.
- * @param c The scope to open.
+ * @param jo The scope to open.
* @throws JSONException If nesting is too deep.
*/
private void push(JSONObject jo) throws JSONException {
diff --git a/None.java b/None.java
deleted file mode 100644
index 1dda8bc69..000000000
--- a/None.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.json;
-
-public interface None {
- /**
- * Negative One
- */
- public static final int none = -1;
-
-}
diff --git a/Property.java b/Property.java
new file mode 100644
index 000000000..73ddb1287
--- /dev/null
+++ b/Property.java
@@ -0,0 +1,72 @@
+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.Enumeration;
+import java.util.Iterator;
+import java.util.Properties;
+
+/**
+ * Converts a Property file data into JSONObject and back.
+ * @author JSON.org
+ * @version 2015-05-05
+ */
+public class Property {
+ /**
+ * Converts a property file object into a JSONObject. The property file object is a table of name value pairs.
+ * @param properties java.util.Properties
+ * @return JSONObject
+ * @throws JSONException
+ */
+ public static JSONObject toJSONObject(java.util.Properties properties) throws JSONException {
+ JSONObject jo = new JSONObject();
+ if (properties != null && !properties.isEmpty()) {
+ Enumeration> enumProperties = properties.propertyNames();
+ while(enumProperties.hasMoreElements()) {
+ String name = (String)enumProperties.nextElement();
+ jo.put(name, properties.getProperty(name));
+ }
+ }
+ return jo;
+ }
+
+ /**
+ * Converts the JSONObject into a property file object.
+ * @param jo JSONObject
+ * @return java.util.Properties
+ * @throws JSONException
+ */
+ public static Properties toProperties(JSONObject jo) throws JSONException {
+ Properties properties = new Properties();
+ if (jo != null) {
+ Iterator keys = jo.keys();
+ while (keys.hasNext()) {
+ String name = keys.next();
+ properties.put(name, jo.getString(name));
+ }
+ }
+ return properties;
+ }
+}
diff --git a/README b/README
index b77c71a21..925141f9e 100755
--- a/README
+++ b/README
@@ -1,9 +1,14 @@
JSON in Java [package org.json]
+This package needs a new owner. I have not used it in over a decade, and I do
+not have time to maintain programs that I do not use.
+
+If you think you can give this package a good home, please contact me.
+
Douglas Crockford
douglas@crockford.com
-2011-02-02
+2015-02-06
JSON is a light-weight, language independent, data interchange format.
@@ -21,7 +26,7 @@ The license includes this restriction: "The software shall be used for good,
not evil." If your conscience cannot live with that, then choose a different
package.
-The package compiles on Java 1.2 thru Java 1.4.
+The package compiles on Java 1.8.
JSONObject.java: The JSONObject can parse text from a String or a JSONTokener
@@ -66,3 +71,5 @@ XML.java: XML provides support for converting between JSON and XML.
JSONML.java: JSONML provides support for converting between JSONML and XML.
XMLTokener.java: XMLTokener extends JSONTokener for parsing XML text.
+
+Unit tests are maintained in a separate project. Contributing developers can test JSON-java pull requests with the code in this project: https://github.com/stleary/JSON-Java-unit-test
diff --git a/README.md b/README.md
index c1a24f11e..5acef50d0 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-# JSON-java
+# DEPRECATED fork of JSON-java
-This repository is a fork of the original [JSON-java](https://github.com/douglascrockford/JSON-java) repository by Douglas Crockford. This repository only adds two files, build.xml and build.properties, which allow for the ant build system to compile this code into a jar file. The jar file produced by this project is used for JSON parsing in the [GIS Tools for Hadoop](http://github.com/Esri/gis-tools-for-hadoop) and [Spatial Framework for Hadoop](http://github.com/Esri/spatial-framework-for-hadoop) projects.
+This repository is a fork of the original [JSON-java](https://github.com/douglascrockford/JSON-java) repository by Douglas Crockford. This repository only adds two files, build.xml and build.properties, which allow for the ant build system to compile this code into a jar file. The jar file produced by this project was used for JSON parsing in the [GIS Tools for Hadoop](http://github.com/Esri/gis-tools-for-hadoop) and [Spatial Framework for Hadoop](http://github.com/Esri/spatial-framework-for-hadoop) projects.
Other JSON library implementations may be found at: [JSON.org](http://www.json.org).
diff --git a/XML.java b/XML.java
index d49784d6d..07090abe3 100755
--- a/XML.java
+++ b/XML.java
@@ -26,41 +26,40 @@ of this software and associated documentation files (the "Software"), to deal
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 2012-10-26
+ * @version 2014-05-03
*/
public class XML {
/** The Character '&'. */
- public static final Character AMP = new Character('&');
+ public static final Character AMP = '&';
/** The Character '''. */
- public static final Character APOS = new Character('\'');
+ public static final Character APOS = '\'';
/** The Character '!'. */
- public static final Character BANG = new Character('!');
+ public static final Character BANG = '!';
/** The Character '='. */
- public static final Character EQ = new Character('=');
+ public static final Character EQ = '=';
/** The Character '>'. */
- public static final Character GT = new Character('>');
+ public static final Character GT = '>';
/** The Character '<'. */
- public static final Character LT = new Character('<');
+ public static final Character LT = '<';
/** The Character '?'. */
- public static final Character QUEST = new Character('?');
+ public static final Character QUEST = '?';
/** The Character '"'. */
- public static final Character QUOT = new Character('"');
+ public static final Character QUOT = '"';
/** The Character '/'. */
- public static final Character SLASH = new Character('/');
+ public static final Character SLASH = '/';
/**
* Replace special characters with XML escapes:
@@ -74,7 +73,7 @@ public class XML {
* @return The escaped string.
*/
public static String escape(String string) {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder(string.length());
for (int i = 0, length = string.length(); i < length; i++) {
char c = string.charAt(i);
switch (c) {
@@ -103,7 +102,7 @@ public static String escape(String string) {
/**
* Throw an exception if the string contains whitespace.
* Whitespace is not allowed in tagNames and attributes.
- * @param string
+ * @param string A string.
* @throws JSONException
*/
public static void noSpace(String string) throws JSONException {
@@ -301,9 +300,6 @@ private static boolean parse(XMLTokener x, JSONObject context,
* @return A simple JSON value.
*/
public static Object stringToValue(String string) {
- if ("".equals(string)) {
- return string;
- }
if ("true".equalsIgnoreCase(string)) {
return Boolean.TRUE;
}
@@ -313,36 +309,26 @@ public static Object stringToValue(String string) {
if ("null".equalsIgnoreCase(string)) {
return JSONObject.NULL;
}
- if ("0".equals(string)) {
- return new Integer(0);
- }
-// If it might be a number, try converting it. If that doesn't work,
-// return the string.
+// If it might be a number, try converting it, first as a Long, and then as a
+// Double. If that doesn't work, return the string.
try {
char initial = string.charAt(0);
- boolean negative = false;
- if (initial == '-') {
- initial = string.charAt(1);
- negative = true;
- }
- if (initial == '0' && string.charAt(negative ? 2 : 1) == '0') {
- return string;
- }
- if ((initial >= '0' && initial <= '9')) {
- if (string.indexOf('.') >= 0) {
- return Double.valueOf(string);
- } else if (string.indexOf('e') < 0 && string.indexOf('E') < 0) {
- Long myLong = new Long(string);
- if (myLong.longValue() == myLong.intValue()) {
- return new Integer(myLong.intValue());
- } else {
- return myLong;
- }
+ if (initial == '-' || (initial >= '0' && initial <= '9')) {
+ Long value = new Long(string);
+ if (value.toString().equals(string)) {
+ return value;
}
}
} catch (Exception ignore) {
+ try {
+ Double value = new Double(string);
+ if (value.toString().equals(string)) {
+ return value;
+ }
+ } catch (Exception ignoreAlso) {
+ }
}
return string;
}
@@ -392,15 +378,15 @@ public static String toString(Object object) throws JSONException {
*/
public static String toString(Object object, String tagName)
throws JSONException {
- StringBuffer sb = new StringBuffer();
- int i;
- JSONArray ja;
- JSONObject jo;
- String key;
- Iterator keys;
- int length;
- String string;
- Object value;
+ StringBuilder sb = new StringBuilder();
+ int i;
+ JSONArray ja;
+ JSONObject jo;
+ String key;
+ Iterator keys;
+ int length;
+ String string;
+ Object value;
if (object instanceof JSONObject) {
// Emit
@@ -416,16 +402,12 @@ public static String toString(Object object, String tagName)
jo = (JSONObject)object;
keys = jo.keys();
while (keys.hasNext()) {
- key = keys.next().toString();
+ key = keys.next();
value = jo.opt(key);
if (value == null) {
value = "";
}
- if (value instanceof String) {
- string = (String)value;
- } else {
- string = null;
- }
+ string = value instanceof String ? (String)value : null;
// Emit content in body
diff --git a/XMLTokener.java b/XMLTokener.java
index be15ebeba..d3197653c 100755
--- a/XMLTokener.java
+++ b/XMLTokener.java
@@ -28,7 +28,7 @@ of this software and associated documentation files (the "Software"), to deal
* The XMLTokener extends the JSONTokener to provide additional methods
* for the parsing of XML texts.
* @author JSON.org
- * @version 2012-11-13
+ * @version 2014-05-03
*/
public class XMLTokener extends JSONTokener {
@@ -36,10 +36,10 @@ 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;
+ public static final java.util.HashMap entity;
static {
- entity = new java.util.HashMap(8);
+ entity = new java.util.HashMap(8);
entity.put("amp", XML.AMP);
entity.put("apos", XML.APOS);
entity.put("gt", XML.GT);
@@ -63,7 +63,7 @@ public XMLTokener(String s) {
public String nextCDATA() throws JSONException {
char c;
int i;
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (;;) {
c = next();
if (end()) {
@@ -91,7 +91,7 @@ public String nextCDATA() throws JSONException {
*/
public Object nextContent() throws JSONException {
char c;
- StringBuffer sb;
+ StringBuilder sb;
do {
c = next();
} while (Character.isWhitespace(c));
@@ -101,7 +101,7 @@ public Object nextContent() throws JSONException {
if (c == '<') {
return XML.LT;
}
- sb = new StringBuffer();
+ sb = new StringBuilder();
for (;;) {
if (c == '<' || c == 0) {
back();
@@ -125,7 +125,7 @@ public Object nextContent() throws JSONException {
* @throws JSONException If missing ';' in XML entity.
*/
public Object nextEntity(char ampersand) throws JSONException {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
for (;;) {
char c = next();
if (Character.isLetterOrDigit(c) || c == '#') {
@@ -219,7 +219,7 @@ public Object nextMeta() throws JSONException {
public Object nextToken() throws JSONException {
char c;
char q;
- StringBuffer sb;
+ StringBuilder sb;
do {
c = next();
} while (Character.isWhitespace(c));
@@ -244,7 +244,7 @@ public Object nextToken() throws JSONException {
case '"':
case '\'':
q = c;
- sb = new StringBuffer();
+ sb = new StringBuilder();
for (;;) {
c = next();
if (c == 0) {
@@ -263,7 +263,7 @@ public Object nextToken() throws JSONException {
// Name
- sb = new StringBuffer();
+ sb = new StringBuilder();
for (;;) {
sb.append(c);
c = next();