mirror of
https://github.com/stleary/JSON-java.git
synced 2026-01-24 00:03:17 -05:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbd8b18c4a | ||
|
|
f12fa9ba5f | ||
|
|
80e2ea2a80 | ||
|
|
2917104b53 | ||
|
|
9e0fc5e680 | ||
|
|
724fb888f7 | ||
|
|
eb806f4c14 | ||
|
|
5ff8b4cb08 | ||
|
|
5ef4f58ef1 | ||
|
|
413bb53b48 | ||
|
|
237376eca6 | ||
|
|
e0616a129e | ||
|
|
93ffca36c3 | ||
|
|
e477d7002b | ||
|
|
fb1db9341e | ||
|
|
adb0478f66 | ||
|
|
f58a0f4684 | ||
|
|
c11e09959c | ||
|
|
68f92eb395 | ||
|
|
34652a8706 | ||
|
|
a2d3b59394 | ||
|
|
c24be0e4ea | ||
|
|
88f65c5bea | ||
|
|
ebe69df8e4 | ||
|
|
2f2cd4dfc5 | ||
|
|
349a209df3 | ||
|
|
7851e9b2e8 | ||
|
|
7232a95c0b | ||
|
|
f96f505188 | ||
|
|
91107e3e82 | ||
|
|
4e8e24d49d | ||
|
|
f881b61c81 | ||
|
|
37582a44ad | ||
|
|
154cfda9aa | ||
|
|
45a7decba4 | ||
|
|
0c157cae75 |
@@ -25,6 +25,7 @@ SOFTWARE.
|
||||
*/
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Convert an HTTP header to a JSONObject and back.
|
||||
@@ -74,7 +75,7 @@ public class HTTP {
|
||||
String token;
|
||||
|
||||
token = x.nextToken();
|
||||
if (token.toUpperCase().startsWith("HTTP")) {
|
||||
if (token.toUpperCase(Locale.ROOT).startsWith("HTTP")) {
|
||||
|
||||
// Response
|
||||
|
||||
|
||||
139
JSONArray.java
139
JSONArray.java
@@ -78,7 +78,7 @@ import java.util.Map;
|
||||
* </ul>
|
||||
*
|
||||
* @author JSON.org
|
||||
* @version 2016-07-19
|
||||
* @version 2016-08/15
|
||||
*/
|
||||
public class JSONArray implements Iterable<Object> {
|
||||
|
||||
@@ -241,16 +241,12 @@ public class JSONArray implements Iterable<Object> {
|
||||
public double getDouble(int index) throws JSONException {
|
||||
Object object = this.get(index);
|
||||
try {
|
||||
if (object instanceof Number) {
|
||||
return ((Number) object).doubleValue();
|
||||
} else if (object instanceof String) {
|
||||
return Double.parseDouble((String) object);
|
||||
}
|
||||
return object instanceof Number ? ((Number) object).doubleValue()
|
||||
: Double.parseDouble((String) object);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
throw new JSONException("JSONArray[" + index + "] is not a number.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the enum value associated with an index.
|
||||
@@ -329,16 +325,12 @@ public class JSONArray implements Iterable<Object> {
|
||||
public int getInt(int index) throws JSONException {
|
||||
Object object = this.get(index);
|
||||
try {
|
||||
if (object instanceof Number) {
|
||||
return ((Number) object).intValue();
|
||||
} else if (object instanceof String) {
|
||||
return Integer.parseInt((String) object);
|
||||
}
|
||||
return object instanceof Number ? ((Number) object).intValue()
|
||||
: Integer.parseInt((String) object);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
throw new JSONException("JSONArray[" + index + "] is not a number.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JSONArray associated with an index.
|
||||
@@ -389,16 +381,12 @@ public class JSONArray implements Iterable<Object> {
|
||||
public long getLong(int index) throws JSONException {
|
||||
Object object = this.get(index);
|
||||
try {
|
||||
if (object instanceof Number) {
|
||||
return ((Number) object).longValue();
|
||||
} else if (object instanceof String) {
|
||||
return Long.parseLong((String) object);
|
||||
}
|
||||
return object instanceof Number ? ((Number) object).longValue()
|
||||
: Long.parseLong((String) object);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
throw new JSONException("JSONArray[" + index + "] is not a number.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string associated with an index.
|
||||
@@ -498,20 +486,11 @@ public class JSONArray implements Iterable<Object> {
|
||||
* @return The truth.
|
||||
*/
|
||||
public boolean optBoolean(int index, boolean defaultValue) {
|
||||
Object object = this.opt(index);
|
||||
if (JSONObject.NULL.equals(object)) {
|
||||
try {
|
||||
return this.getBoolean(index);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
if (object.equals(Boolean.FALSE)
|
||||
|| (object instanceof String && ((String) object)
|
||||
.equalsIgnoreCase("false"))) {
|
||||
return false;
|
||||
} else if (object.equals(Boolean.TRUE)
|
||||
|| (object instanceof String && ((String) object)
|
||||
.equalsIgnoreCase("true"))) {
|
||||
return true;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -539,21 +518,12 @@ public class JSONArray implements Iterable<Object> {
|
||||
* @return The value.
|
||||
*/
|
||||
public double optDouble(int index, double defaultValue) {
|
||||
Object object = this.opt(index);
|
||||
if (JSONObject.NULL.equals(object)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
if (object instanceof Number) {
|
||||
return ((Number) object).doubleValue();
|
||||
} else if (object instanceof String) {
|
||||
return Double.parseDouble((String) object);
|
||||
}
|
||||
return this.getDouble(index);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional int value associated with an index. Zero is returned if
|
||||
@@ -580,21 +550,12 @@ public class JSONArray implements Iterable<Object> {
|
||||
* @return The value.
|
||||
*/
|
||||
public int optInt(int index, int defaultValue) {
|
||||
Object object = this.opt(index);
|
||||
if (JSONObject.NULL.equals(object)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
if (object instanceof Number) {
|
||||
return ((Number) object).intValue();
|
||||
} else if (object instanceof String) {
|
||||
return Integer.parseInt((String) object);
|
||||
}
|
||||
return this.getInt(index);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the enum value associated with a key.
|
||||
@@ -654,12 +615,8 @@ public class JSONArray implements Iterable<Object> {
|
||||
* @return The value.
|
||||
*/
|
||||
public BigInteger optBigInteger(int index, BigInteger defaultValue) {
|
||||
Object object = this.opt(index);
|
||||
if (JSONObject.NULL.equals(object)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return new BigInteger(object.toString());
|
||||
return this.getBigInteger(index);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
@@ -677,12 +634,8 @@ public class JSONArray implements Iterable<Object> {
|
||||
* @return The value.
|
||||
*/
|
||||
public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) {
|
||||
Object object = this.opt(index);
|
||||
if (JSONObject.NULL.equals(object)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return new BigDecimal(object.toString());
|
||||
return this.getBigDecimal(index);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
@@ -740,21 +693,12 @@ public class JSONArray implements Iterable<Object> {
|
||||
* @return The value.
|
||||
*/
|
||||
public long optLong(int index, long defaultValue) {
|
||||
Object object = this.opt(index);
|
||||
if (JSONObject.NULL.equals(object)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
if (object instanceof Number) {
|
||||
return ((Number) object).longValue();
|
||||
} else if (object instanceof String) {
|
||||
return Long.parseLong((String) object);
|
||||
}
|
||||
return this.getLong(index);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the optional string value associated with an index. It returns an
|
||||
@@ -1036,7 +980,30 @@ public class JSONArray implements Iterable<Object> {
|
||||
* @return the item matched by the JSONPointer, otherwise null
|
||||
*/
|
||||
public Object query(String jsonPointer) {
|
||||
return new JSONPointer(jsonPointer).queryFrom(this);
|
||||
return query(new JSONPointer(jsonPointer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses a uaer initialized JSONPointer and tries to
|
||||
* match it to an item whithin this JSONArray. For example, given a
|
||||
* JSONArray initialized with this document:
|
||||
* <pre>
|
||||
* [
|
||||
* {"b":"c"}
|
||||
* ]
|
||||
* </pre>
|
||||
* and this JSONPointer:
|
||||
* <pre>
|
||||
* "/0/b"
|
||||
* </pre>
|
||||
* Then this method will return the String "c"
|
||||
* A JSONPointerException may be thrown from code called by this method.
|
||||
*
|
||||
* @param jsonPointer string that can be used to create a JSONPointer
|
||||
* @return the item matched by the JSONPointer, otherwise null
|
||||
*/
|
||||
public Object query(JSONPointer jsonPointer) {
|
||||
return jsonPointer.queryFrom(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1048,9 +1015,20 @@ public class JSONArray implements Iterable<Object> {
|
||||
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
||||
*/
|
||||
public Object optQuery(String jsonPointer) {
|
||||
JSONPointer pointer = new JSONPointer(jsonPointer);
|
||||
return optQuery(new JSONPointer(jsonPointer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries and returns a value from this object using {@code jsonPointer}, or
|
||||
* returns null if the query fails due to a missing key.
|
||||
*
|
||||
* @param The JSON pointer
|
||||
* @return the queried value or {@code null}
|
||||
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
||||
*/
|
||||
public Object optQuery(JSONPointer jsonPointer) {
|
||||
try {
|
||||
return pointer.queryFrom(this);
|
||||
return jsonPointer.queryFrom(this);
|
||||
} catch (JSONPointerException e) {
|
||||
return null;
|
||||
}
|
||||
@@ -1137,7 +1115,6 @@ public class JSONArray implements Iterable<Object> {
|
||||
* @return a printable, displayable, transmittable representation of the
|
||||
* array.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
return this.toString(0);
|
||||
|
||||
@@ -175,7 +175,7 @@ public class JSONML {
|
||||
if (!(token instanceof String)) {
|
||||
throw x.syntaxError("Missing value");
|
||||
}
|
||||
newjo.accumulate(attribute, keepStrings ? token :JSONObject.stringToValue((String)token));
|
||||
newjo.accumulate(attribute, keepStrings ? XML.unescape((String)token) :XML.stringToValue((String)token));
|
||||
token = null;
|
||||
} else {
|
||||
newjo.accumulate(attribute, "");
|
||||
@@ -226,7 +226,7 @@ public class JSONML {
|
||||
} else {
|
||||
if (ja != null) {
|
||||
ja.put(token instanceof String
|
||||
? keepStrings ? token :JSONObject.stringToValue((String)token)
|
||||
? keepStrings ? XML.unescape((String)token) :XML.stringToValue((String)token)
|
||||
: token);
|
||||
}
|
||||
}
|
||||
|
||||
198
JSONObject.java
198
JSONObject.java
@@ -93,7 +93,7 @@ import java.util.Set;
|
||||
* </ul>
|
||||
*
|
||||
* @author JSON.org
|
||||
* @version 2016-07-19
|
||||
* @version 2016-08-15
|
||||
*/
|
||||
public class JSONObject {
|
||||
/**
|
||||
@@ -577,16 +577,13 @@ public class JSONObject {
|
||||
public double getDouble(String key) throws JSONException {
|
||||
Object object = this.get(key);
|
||||
try {
|
||||
if (object instanceof Number) {
|
||||
return ((Number) object).doubleValue();
|
||||
} else if (object instanceof String) {
|
||||
return 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.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the int value associated with a key.
|
||||
@@ -601,15 +598,12 @@ public class JSONObject {
|
||||
public int getInt(String key) throws JSONException {
|
||||
Object object = this.get(key);
|
||||
try {
|
||||
if (object instanceof Number) {
|
||||
return ((Number) object).intValue();
|
||||
} else if (object instanceof String) {
|
||||
return 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.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -661,15 +655,12 @@ public class JSONObject {
|
||||
public long getLong(String key) throws JSONException {
|
||||
Object object = this.get(key);
|
||||
try {
|
||||
if (object instanceof Number) {
|
||||
return ((Number) object).longValue();
|
||||
} else if (object instanceof String) {
|
||||
return 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.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -942,20 +933,11 @@ public class JSONObject {
|
||||
* @return The truth.
|
||||
*/
|
||||
public boolean optBoolean(String key, boolean defaultValue) {
|
||||
Object object = this.get(key);
|
||||
if (NULL.equals(object)) {
|
||||
try {
|
||||
return this.getBoolean(key);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
if (object.equals(Boolean.FALSE)
|
||||
|| (object instanceof String && ((String) object)
|
||||
.equalsIgnoreCase("false"))) {
|
||||
return false;
|
||||
} else if (object.equals(Boolean.TRUE)
|
||||
|| (object instanceof String && ((String) object)
|
||||
.equalsIgnoreCase("true"))) {
|
||||
return true;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -983,12 +965,8 @@ public class JSONObject {
|
||||
* @return An object which is the value.
|
||||
*/
|
||||
public BigInteger optBigInteger(String key, BigInteger defaultValue) {
|
||||
Object object = this.get(key);
|
||||
if (NULL.equals(object)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return new BigInteger(object.toString());
|
||||
return this.getBigInteger(key);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
@@ -1006,12 +984,8 @@ public class JSONObject {
|
||||
* @return An object which is the value.
|
||||
*/
|
||||
public BigDecimal optBigDecimal(String key, BigDecimal defaultValue) {
|
||||
Object object = this.opt(key);
|
||||
if (NULL.equals(object)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return new BigDecimal(object.toString());
|
||||
return this.getBigDecimal(key);
|
||||
} catch (Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
@@ -1029,21 +1003,12 @@ public class JSONObject {
|
||||
* @return An object which is the value.
|
||||
*/
|
||||
public double optDouble(String key, double defaultValue) {
|
||||
Object object = this.get(key);
|
||||
if (NULL.equals(object)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
if (object instanceof Number) {
|
||||
return ((Number) object).doubleValue();
|
||||
} else if (object instanceof String) {
|
||||
return Double.parseDouble((String) object);
|
||||
}
|
||||
return this.getDouble(key);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional int value associated with a key, or zero if there is no
|
||||
@@ -1070,21 +1035,12 @@ public class JSONObject {
|
||||
* @return An object which is the value.
|
||||
*/
|
||||
public int optInt(String key, int defaultValue) {
|
||||
Object object = this.get(key);
|
||||
if (NULL.equals(object)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
if (object instanceof Number) {
|
||||
return ((Number) object).intValue();
|
||||
} else if (object instanceof String) {
|
||||
return Integer.parseInt((String) object);
|
||||
}
|
||||
return this.getInt(key);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional JSONArray associated with a key. It returns null if there
|
||||
@@ -1137,21 +1093,12 @@ public class JSONObject {
|
||||
* @return An object which is the value.
|
||||
*/
|
||||
public long optLong(String key, long defaultValue) {
|
||||
Object object = this.get(key);
|
||||
if (NULL.equals(object)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
if (object instanceof Number) {
|
||||
return ((Number) object).longValue();
|
||||
} else if (object instanceof String) {
|
||||
return Long.parseLong((String) object);
|
||||
}
|
||||
return this.getLong(key);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an optional string associated with a key. It returns an empty string
|
||||
@@ -1210,9 +1157,9 @@ public class JSONObject {
|
||||
&& Character.isUpperCase(key.charAt(0))
|
||||
&& method.getParameterTypes().length == 0) {
|
||||
if (key.length() == 1) {
|
||||
key = key.toLowerCase();
|
||||
key = key.toLowerCase(Locale.ROOT);
|
||||
} else if (!Character.isUpperCase(key.charAt(1))) {
|
||||
key = key.substring(0, 1).toLowerCase()
|
||||
key = key.substring(0, 1).toLowerCase(Locale.ROOT)
|
||||
+ key.substring(1);
|
||||
}
|
||||
|
||||
@@ -1412,7 +1359,29 @@ public class JSONObject {
|
||||
* @return the item matched by the JSONPointer, otherwise null
|
||||
*/
|
||||
public Object query(String jsonPointer) {
|
||||
return new JSONPointer(jsonPointer).queryFrom(this);
|
||||
return query(new JSONPointer(jsonPointer));
|
||||
}
|
||||
/**
|
||||
* Uses a uaer initialized JSONPointer and tries to
|
||||
* match it to an item within this JSONObject. For example, given a
|
||||
* JSONObject initialized with this document:
|
||||
* <pre>
|
||||
* {
|
||||
* "a":{"b":"c"}
|
||||
* }
|
||||
* </pre>
|
||||
* and this JSONPointer:
|
||||
* <pre>
|
||||
* "/a/b"
|
||||
* </pre>
|
||||
* Then this method will return the String "c".
|
||||
* A JSONPointerException may be thrown from code called by this method.
|
||||
*
|
||||
* @param jsonPointer string that can be used to create a JSONPointer
|
||||
* @return the item matched by the JSONPointer, otherwise null
|
||||
*/
|
||||
public Object query(JSONPointer jsonPointer) {
|
||||
return jsonPointer.queryFrom(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1424,9 +1393,20 @@ public class JSONObject {
|
||||
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
||||
*/
|
||||
public Object optQuery(String jsonPointer) {
|
||||
JSONPointer pointer = new JSONPointer(jsonPointer);
|
||||
return optQuery(new JSONPointer(jsonPointer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries and returns a value from this object using {@code jsonPointer}, or
|
||||
* returns null if the query fails due to a missing key.
|
||||
*
|
||||
* @param The JSON pointer
|
||||
* @return the queried value or {@code null}
|
||||
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
||||
*/
|
||||
public Object optQuery(JSONPointer jsonPointer) {
|
||||
try {
|
||||
return pointer.queryFrom(this);
|
||||
return jsonPointer.queryFrom(this);
|
||||
} catch (JSONPointerException e) {
|
||||
return null;
|
||||
}
|
||||
@@ -1746,7 +1726,18 @@ public class JSONObject {
|
||||
throw new JSONException("Bad value from toJSONString: " + object);
|
||||
}
|
||||
if (value instanceof Number) {
|
||||
return numberToString((Number) value);
|
||||
// not all Numbers may match actual JSON Numbers. i.e. Fractions or Complex
|
||||
final String numberAsString = numberToString((Number) value);
|
||||
try {
|
||||
// Use the BigDecimal constructor for it's parser to validate the format.
|
||||
new BigDecimal(numberAsString);
|
||||
// Close enough to a JSON number that we will return it unquoted
|
||||
return numberAsString;
|
||||
} catch (NumberFormatException ex){
|
||||
// The Number value is not a valid JSON number.
|
||||
// Instead we will quote it as a string
|
||||
return quote(numberAsString);
|
||||
}
|
||||
}
|
||||
if (value instanceof Boolean || value instanceof JSONObject
|
||||
|| value instanceof JSONArray) {
|
||||
@@ -1763,6 +1754,9 @@ public class JSONObject {
|
||||
if (value.getClass().isArray()) {
|
||||
return new JSONArray(value).toString();
|
||||
}
|
||||
if(value instanceof Enum<?>){
|
||||
return quote(((Enum<?>)value).name());
|
||||
}
|
||||
return quote(value.toString());
|
||||
}
|
||||
|
||||
@@ -1790,7 +1784,7 @@ public class JSONObject {
|
||||
|| object instanceof Long || object instanceof Boolean
|
||||
|| object instanceof Float || object instanceof Double
|
||||
|| object instanceof String || object instanceof BigInteger
|
||||
|| object instanceof BigDecimal) {
|
||||
|| object instanceof BigDecimal || object instanceof Enum) {
|
||||
return object;
|
||||
}
|
||||
|
||||
@@ -1836,6 +1830,32 @@ public class JSONObject {
|
||||
int indentFactor, int indent) throws JSONException, IOException {
|
||||
if (value == null || value.equals(null)) {
|
||||
writer.write("null");
|
||||
} else if (value instanceof JSONString) {
|
||||
Object o;
|
||||
try {
|
||||
o = ((JSONString) value).toJSONString();
|
||||
} catch (Exception e) {
|
||||
throw new JSONException(e);
|
||||
}
|
||||
writer.write(o != null ? o.toString() : quote(value.toString()));
|
||||
} else if (value instanceof Number) {
|
||||
// not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
|
||||
final String numberAsString = numberToString((Number) value);
|
||||
try {
|
||||
// Use the BigDecimal constructor for it's parser to validate the format.
|
||||
@SuppressWarnings("unused")
|
||||
BigDecimal testNum = new BigDecimal(numberAsString);
|
||||
// Close enough to a JSON number that we will use it unquoted
|
||||
writer.write(numberAsString);
|
||||
} catch (NumberFormatException ex){
|
||||
// The Number value is not a valid JSON number.
|
||||
// Instead we will quote it as a string
|
||||
quote(numberAsString, writer);
|
||||
}
|
||||
} else if (value instanceof Boolean) {
|
||||
writer.write(value.toString());
|
||||
} else if (value instanceof Enum<?>) {
|
||||
writer.write(quote(((Enum<?>)value).name()));
|
||||
} else if (value instanceof JSONObject) {
|
||||
((JSONObject) value).write(writer, indentFactor, indent);
|
||||
} else if (value instanceof JSONArray) {
|
||||
@@ -1848,18 +1868,6 @@ public class JSONObject {
|
||||
new JSONArray(coll).write(writer, indentFactor, indent);
|
||||
} else if (value.getClass().isArray()) {
|
||||
new JSONArray(value).write(writer, indentFactor, indent);
|
||||
} else if (value instanceof Number) {
|
||||
writer.write(numberToString((Number) value));
|
||||
} else if (value instanceof Boolean) {
|
||||
writer.write(value.toString());
|
||||
} else if (value instanceof JSONString) {
|
||||
Object o;
|
||||
try {
|
||||
o = ((JSONString) value).toJSONString();
|
||||
} catch (Exception e) {
|
||||
throw new JSONException(e);
|
||||
}
|
||||
writer.write(o != null ? o.toString() : quote(value.toString()));
|
||||
} else {
|
||||
quote(value.toString(), writer);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ public class JSONPointer {
|
||||
if (pointer == null) {
|
||||
throw new NullPointerException("pointer cannot be null");
|
||||
}
|
||||
if (pointer.isEmpty()) {
|
||||
if (pointer.isEmpty() || pointer.equals("#")) {
|
||||
refTokens = Collections.emptyList();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
/*
|
||||
Copyright (c) 2006 JSON.org
|
||||
@@ -50,11 +49,11 @@ SOFTWARE.
|
||||
* <p>
|
||||
* The first method called must be <code>array</code> or <code>object</code>.
|
||||
* There are no methods for adding commas or colons. JSONWriter adds them for
|
||||
* you. Objects and arrays can be nested up to 20 levels deep.
|
||||
* you. Objects and arrays can be nested up to 200 levels deep.
|
||||
* <p>
|
||||
* This can sometimes be easier than using a JSONObject to build a string.
|
||||
* @author JSON.org
|
||||
* @version 2015-12-09
|
||||
* @version 2016-08-08
|
||||
*/
|
||||
public class JSONWriter {
|
||||
private static final int maxdepth = 200;
|
||||
@@ -88,12 +87,12 @@ public class JSONWriter {
|
||||
/**
|
||||
* The writer that will receive the output.
|
||||
*/
|
||||
protected Writer writer;
|
||||
protected Appendable writer;
|
||||
|
||||
/**
|
||||
* Make a fresh JSONWriter. It can be used to build one JSON text.
|
||||
*/
|
||||
public JSONWriter(Writer w) {
|
||||
public JSONWriter(Appendable w) {
|
||||
this.comma = false;
|
||||
this.mode = 'i';
|
||||
this.stack = new JSONObject[maxdepth];
|
||||
@@ -114,9 +113,9 @@ public class JSONWriter {
|
||||
if (this.mode == 'o' || this.mode == 'a') {
|
||||
try {
|
||||
if (this.comma && this.mode == 'a') {
|
||||
this.writer.write(',');
|
||||
this.writer.append(',');
|
||||
}
|
||||
this.writer.write(string);
|
||||
this.writer.append(string);
|
||||
} catch (IOException e) {
|
||||
throw new JSONException(e);
|
||||
}
|
||||
@@ -163,7 +162,7 @@ public class JSONWriter {
|
||||
}
|
||||
this.pop(mode);
|
||||
try {
|
||||
this.writer.write(c);
|
||||
this.writer.append(c);
|
||||
} catch (IOException e) {
|
||||
throw new JSONException(e);
|
||||
}
|
||||
@@ -207,10 +206,10 @@ public class JSONWriter {
|
||||
try {
|
||||
this.stack[this.top - 1].putOnce(string, Boolean.TRUE);
|
||||
if (this.comma) {
|
||||
this.writer.write(',');
|
||||
this.writer.append(',');
|
||||
}
|
||||
this.writer.write(JSONObject.quote(string));
|
||||
this.writer.write(':');
|
||||
this.writer.append(JSONObject.quote(string));
|
||||
this.writer.append(':');
|
||||
this.comma = false;
|
||||
this.mode = 'o';
|
||||
return this;
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,3 +1,5 @@
|
||||
============================================================================
|
||||
|
||||
Copyright (c) 2002 JSON.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
||||
9
README
9
README
@@ -22,7 +22,7 @@ JSONObject.java: The JSONObject can parse text from a String or a JSONTokener
|
||||
to produce a map-like object. The object provides methods for manipulating its
|
||||
contents, and for producing a JSON compliant object serialization.
|
||||
|
||||
JSONArray.java: The JSONObject can parse text from a String or a JSONTokener
|
||||
JSONArray.java: The JSONArray can parse text from a String or a JSONTokener
|
||||
to produce a vector-like object. The object provides methods for manipulating
|
||||
its contents, and for producing a JSON compliant array serialization.
|
||||
|
||||
@@ -89,8 +89,13 @@ invalid number formats (1.2e6.3) will cause errors as such documents can not be
|
||||
reliably.
|
||||
|
||||
Release history:
|
||||
20170516 Roll up recent commits.
|
||||
|
||||
20160807 Java 1.6 compatability fixed, JSONArray.toList() and JSONObject.toMap(),
|
||||
20160810 Revert code that was breaking opt*() methods.
|
||||
|
||||
20160807 This release contains a bug in the JSONObject.opt*() and JSONArray.opt*() methods,
|
||||
it is not recommended for use.
|
||||
Java 1.6 compatability fixed, JSONArray.toList() and JSONObject.toMap(),
|
||||
RFC4180 compatibility, JSONPointer, some exception fixes, optional XML type conversion.
|
||||
Contains the latest code as of 7 Aug, 2016
|
||||
|
||||
|
||||
153
XML.java
153
XML.java
@@ -31,11 +31,10 @@ import java.util.Iterator;
|
||||
* covert a JSONObject into an XML text.
|
||||
*
|
||||
* @author JSON.org
|
||||
* @version 2016-01-30
|
||||
* @version 2016-08-10
|
||||
*/
|
||||
@SuppressWarnings("boxing")
|
||||
public class XML {
|
||||
|
||||
/** The Character '&'. */
|
||||
public static final Character AMP = '&';
|
||||
|
||||
@@ -63,6 +62,46 @@ public class XML {
|
||||
/** The Character '/'. */
|
||||
public static final Character SLASH = '/';
|
||||
|
||||
/**
|
||||
* Creates an iterator for navigating Code Points in a string instead of
|
||||
* characters. Once Java7 support is dropped, this can be replaced with
|
||||
* <code>
|
||||
* string.codePoints()
|
||||
* </code>
|
||||
* which is available in Java8 and above.
|
||||
*
|
||||
* @see <a href=
|
||||
* "http://stackoverflow.com/a/21791059/6030888">http://stackoverflow.com/a/21791059/6030888</a>
|
||||
*/
|
||||
private static Iterable<Integer> codePointIterator(final String string) {
|
||||
return new Iterable<Integer>() {
|
||||
@Override
|
||||
public Iterator<Integer> iterator() {
|
||||
return new Iterator<Integer>() {
|
||||
private int nextIndex = 0;
|
||||
private int length = string.length();
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return this.nextIndex < this.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer next() {
|
||||
int result = string.codePointAt(this.nextIndex);
|
||||
this.nextIndex += Character.charCount(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace special characters with XML escapes:
|
||||
*
|
||||
@@ -71,6 +110,7 @@ public class XML {
|
||||
* < <small>(less than)</small> is replaced by &lt;
|
||||
* > <small>(greater than)</small> is replaced by &gt;
|
||||
* " <small>(double quote)</small> is replaced by &quot;
|
||||
* ' <small>(single quote / apostrophe)</small> is replaced by &apos;
|
||||
* </pre>
|
||||
*
|
||||
* @param string
|
||||
@@ -79,9 +119,8 @@ public class XML {
|
||||
*/
|
||||
public static String escape(String string) {
|
||||
StringBuilder sb = new StringBuilder(string.length());
|
||||
for (int i = 0, length = string.length(); i < length; i++) {
|
||||
char c = string.charAt(i);
|
||||
switch (c) {
|
||||
for (final int cp : codePointIterator(string)) {
|
||||
switch (cp) {
|
||||
case '&':
|
||||
sb.append("&");
|
||||
break;
|
||||
@@ -98,6 +137,93 @@ public class XML {
|
||||
sb.append("'");
|
||||
break;
|
||||
default:
|
||||
if (mustEscape(cp)) {
|
||||
sb.append("&#x");
|
||||
sb.append(Integer.toHexString(cp));
|
||||
sb.append(";");
|
||||
} else {
|
||||
sb.appendCodePoint(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cp code point to test
|
||||
* @return true if the code point is not valid for an XML
|
||||
*/
|
||||
private static boolean mustEscape(int cp) {
|
||||
/* Valid range from https://www.w3.org/TR/REC-xml/#charsets
|
||||
*
|
||||
* #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
|
||||
*
|
||||
* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
|
||||
*/
|
||||
// isISOControl is true when (cp >= 0 && cp <= 0x1F) || (cp >= 0x7F && cp <= 0x9F)
|
||||
// all ISO control characters are out of range except tabs and new lines
|
||||
return (Character.isISOControl(cp)
|
||||
&& cp != 0x9
|
||||
&& cp != 0xA
|
||||
&& cp != 0xD
|
||||
) || !(
|
||||
// valid the range of acceptable characters that aren't control
|
||||
(cp >= 0x20 && cp <= 0xD7FF)
|
||||
|| (cp >= 0xE000 && cp <= 0xFFFD)
|
||||
|| (cp >= 0x10000 && cp <= 0x10FFFF)
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes XML escapes from the string.
|
||||
*
|
||||
* @param string
|
||||
* string to remove escapes from
|
||||
* @return string with converted entities
|
||||
*/
|
||||
public static String unescape(String string) {
|
||||
StringBuilder sb = new StringBuilder(string.length());
|
||||
for (int i = 0, length = string.length(); i < length; i++) {
|
||||
char c = string.charAt(i);
|
||||
if (c == '&') {
|
||||
final int semic = string.indexOf(';', i);
|
||||
if (semic > i) {
|
||||
final String entity = string.substring(i + 1, semic);
|
||||
if (entity.charAt(0) == '#') {
|
||||
int cp;
|
||||
if (entity.charAt(1) == 'x') {
|
||||
// hex encoded unicode
|
||||
cp = Integer.parseInt(entity.substring(2), 16);
|
||||
} else {
|
||||
// decimal encoded unicode
|
||||
cp = Integer.parseInt(entity.substring(1));
|
||||
}
|
||||
sb.appendCodePoint(cp);
|
||||
} else {
|
||||
if ("quot".equalsIgnoreCase(entity)) {
|
||||
sb.append('"');
|
||||
} else if ("amp".equalsIgnoreCase(entity)) {
|
||||
sb.append('&');
|
||||
} else if ("apos".equalsIgnoreCase(entity)) {
|
||||
sb.append('\'');
|
||||
} else if ("lt".equalsIgnoreCase(entity)) {
|
||||
sb.append('<');
|
||||
} else if ("gt".equalsIgnoreCase(entity)) {
|
||||
sb.append('>');
|
||||
} else {
|
||||
sb.append('&').append(entity).append(';');
|
||||
}
|
||||
}
|
||||
// skip past the entity we just parsed.
|
||||
i += entity.length() + 1;
|
||||
} else {
|
||||
// this shouldn't happen in most cases since the parser
|
||||
// errors on unclosed enties.
|
||||
sb.append(c);
|
||||
}
|
||||
} else {
|
||||
// not part of an entity
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
@@ -227,7 +353,6 @@ public class XML {
|
||||
if (token == null) {
|
||||
token = x.nextToken();
|
||||
}
|
||||
|
||||
// attribute = value
|
||||
if (token instanceof String) {
|
||||
string = (String) token;
|
||||
@@ -238,7 +363,7 @@ public class XML {
|
||||
throw x.syntaxError("Missing value");
|
||||
}
|
||||
jsonobject.accumulate(string,
|
||||
keepStrings ? token : JSONObject.stringToValue((String) token));
|
||||
keepStrings ? unescape((String)token) : stringToValue((String) token));
|
||||
token = null;
|
||||
} else {
|
||||
jsonobject.accumulate(string, "");
|
||||
@@ -270,7 +395,7 @@ public class XML {
|
||||
string = (String) token;
|
||||
if (string.length() > 0) {
|
||||
jsonobject.accumulate("content",
|
||||
keepStrings ? token : JSONObject.stringToValue(string));
|
||||
keepStrings ? unescape(string) : stringToValue(string));
|
||||
}
|
||||
|
||||
} else if (token == LT) {
|
||||
@@ -297,16 +422,18 @@ public class XML {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method has been deprecated in favor of the
|
||||
* {@link JSONObject.stringToValue(String)} method. Use it instead.
|
||||
* This method is the same as {@link JSONObject.stringToValue(String)}
|
||||
* except that this also tries to unescape String values.
|
||||
*
|
||||
* @deprecated Use {@link JSONObject#stringToValue(String)} instead.
|
||||
* @param string String to convert
|
||||
* @return JSON value of this string or the string
|
||||
*/
|
||||
@Deprecated
|
||||
public static Object stringToValue(String string) {
|
||||
return JSONObject.stringToValue(string);
|
||||
Object ret = JSONObject.stringToValue(string);
|
||||
if(ret instanceof String){
|
||||
return unescape((String)ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user