mirror of
https://github.com/stleary/JSON-java.git
synced 2026-01-24 00:03:17 -05:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7299b201f4 | ||
|
|
8cc1e9830d | ||
|
|
c43e21ae73 | ||
|
|
d6ccc64c79 | ||
|
|
7844eb79cd | ||
|
|
5b531faa49 | ||
|
|
31ff8a2291 | ||
|
|
e33f463179 | ||
|
|
e77a77e841 | ||
|
|
26f48484fd | ||
|
|
efad1d73a7 | ||
|
|
c7130d577a | ||
|
|
d85eea53bb | ||
|
|
57ad94ef5e | ||
|
|
a57eff26d5 | ||
|
|
68883b9ff8 | ||
|
|
11e6b1af7e | ||
|
|
e4b76d6588 | ||
|
|
3a8193bea4 | ||
|
|
6bf2692a94 |
@@ -3,7 +3,7 @@ JSON in Java [package org.json]
|
|||||||
|
|
||||||
[](https://mvnrepository.com/artifact/org.json/json)
|
[](https://mvnrepository.com/artifact/org.json/json)
|
||||||
|
|
||||||
**[Click here if you just want the latest release jar file.](https://repo1.maven.org/maven2/org/json/json/20200518/json-20200518.jar)**
|
**[Click here if you just want the latest release jar file.](https://repo1.maven.org/maven2/org/json/json/20201115/json-20201115.jar)**
|
||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
|
|
||||||
@@ -246,6 +246,8 @@ and artifactId "json". For example:
|
|||||||
[https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav](https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav)
|
[https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav](https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav)
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
|
20210307 Recent commits and potentially breaking fix to JSONPointer
|
||||||
|
|
||||||
20201115 Recent commits and first release after project structure change
|
20201115 Recent commits and first release after project structure change
|
||||||
|
|
||||||
20200518 Recent commits and snapshot before project structure change
|
20200518 Recent commits and snapshot before project structure change
|
||||||
|
|||||||
@@ -13,17 +13,14 @@ apply plugin: 'maven-publish'
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
|
mavenCentral()
|
||||||
maven {
|
maven {
|
||||||
url = uri('https://oss.sonatype.org/content/repositories/snapshots')
|
url = uri('https://oss.sonatype.org/content/repositories/snapshots')
|
||||||
}
|
}
|
||||||
|
|
||||||
maven {
|
|
||||||
url = uri('http://repo.maven.apache.org/maven2')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.13.1'
|
||||||
testImplementation 'com.jayway.jsonpath:json-path:2.1.0'
|
testImplementation 'com.jayway.jsonpath:json-path:2.1.0'
|
||||||
testImplementation 'org.mockito:mockito-core:1.9.5'
|
testImplementation 'org.mockito:mockito-core:1.9.5'
|
||||||
}
|
}
|
||||||
|
|||||||
4
pom.xml
4
pom.xml
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<groupId>org.json</groupId>
|
<groupId>org.json</groupId>
|
||||||
<artifactId>json</artifactId>
|
<artifactId>json</artifactId>
|
||||||
<version>v20200429-SNAPSHOT</version>
|
<version>20210307</version>
|
||||||
<packaging>bundle</packaging>
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
<name>JSON in Java</name>
|
<name>JSON in Java</name>
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.12</version>
|
<version>4.13.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -567,6 +567,14 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
return this.myArrayList.size();
|
return this.myArrayList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all of the elements from this JSONArray.
|
||||||
|
* The JSONArray will be empty after this call returns.
|
||||||
|
*/
|
||||||
|
public void clear() {
|
||||||
|
this.myArrayList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the optional object value associated with an index.
|
* Get the optional object value associated with an index.
|
||||||
*
|
*
|
||||||
@@ -1374,6 +1382,8 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
if (!((JSONArray)valueThis).similar(valueOther)) {
|
if (!((JSONArray)valueThis).similar(valueOther)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (valueThis instanceof Number && valueOther instanceof Number) {
|
||||||
|
return JSONObject.isNumberSimilar((Number)valueThis, (Number)valueOther);
|
||||||
} else if (!valueThis.equals(valueOther)) {
|
} else if (!valueThis.equals(valueOther)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,10 +151,10 @@ public class JSONObject {
|
|||||||
return "null";
|
return "null";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regular Expression Pattern that matches JSON Numbers. This is primarily used for
|
* Regular Expression Pattern that matches JSON Numbers. This is primarily used for
|
||||||
* output to guarantee that we are always writing valid JSON.
|
* output to guarantee that we are always writing valid JSON.
|
||||||
*/
|
*/
|
||||||
static final Pattern NUMBER_PATTERN = Pattern.compile("-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?");
|
static final Pattern NUMBER_PATTERN = Pattern.compile("-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?");
|
||||||
|
|
||||||
@@ -175,10 +175,10 @@ public class JSONObject {
|
|||||||
* Construct an empty JSONObject.
|
* Construct an empty JSONObject.
|
||||||
*/
|
*/
|
||||||
public JSONObject() {
|
public JSONObject() {
|
||||||
// HashMap is used on purpose to ensure that elements are unordered by
|
// HashMap is used on purpose to ensure that elements are unordered by
|
||||||
// the specification.
|
// the specification.
|
||||||
// JSON tends to be a portable transfer format to allows the container
|
// JSON tends to be a portable transfer format to allows the container
|
||||||
// implementations to rearrange their items for a faster element
|
// implementations to rearrange their items for a faster element
|
||||||
// retrieval based on associative access.
|
// retrieval based on associative access.
|
||||||
// Therefore, an implementation mustn't rely on the order of the item.
|
// Therefore, an implementation mustn't rely on the order of the item.
|
||||||
this.map = new HashMap<String, Object>();
|
this.map = new HashMap<String, Object>();
|
||||||
@@ -239,9 +239,9 @@ public class JSONObject {
|
|||||||
if (c != ':') {
|
if (c != ':') {
|
||||||
throw x.syntaxError("Expected a ':' after a key");
|
throw x.syntaxError("Expected a ':' after a key");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use syntaxError(..) to include error location
|
// Use syntaxError(..) to include error location
|
||||||
|
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
// Check if key exists
|
// Check if key exists
|
||||||
if (this.opt(key) != null) {
|
if (this.opt(key) != null) {
|
||||||
@@ -350,11 +350,11 @@ public class JSONObject {
|
|||||||
* method from being serialized:
|
* method from being serialized:
|
||||||
* <pre>
|
* <pre>
|
||||||
* @JSONPropertyName("FullName")
|
* @JSONPropertyName("FullName")
|
||||||
* @JSONPropertyIgnore
|
* @JSONPropertyIgnore
|
||||||
* public String getName() { return this.name; }
|
* public String getName() { return this.name; }
|
||||||
* </pre>
|
* </pre>
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* @param bean
|
* @param bean
|
||||||
* An object that has getter methods that should be used to make
|
* An object that has getter methods that should be used to make
|
||||||
* a JSONObject.
|
* a JSONObject.
|
||||||
@@ -448,12 +448,12 @@ public class JSONObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor to specify an initial capacity of the internal map. Useful for library
|
* Constructor to specify an initial capacity of the internal map. Useful for library
|
||||||
* internal calls where we know, or at least can best guess, how big this JSONObject
|
* internal calls where we know, or at least can best guess, how big this JSONObject
|
||||||
* will be.
|
* will be.
|
||||||
*
|
*
|
||||||
* @param initialCapacity initial capacity of the internal map.
|
* @param initialCapacity initial capacity of the internal map.
|
||||||
*/
|
*/
|
||||||
protected JSONObject(int initialCapacity){
|
protected JSONObject(int initialCapacity){
|
||||||
@@ -576,7 +576,7 @@ public class JSONObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the enum value associated with a key.
|
* Get the enum value associated with a key.
|
||||||
*
|
*
|
||||||
* @param <E>
|
* @param <E>
|
||||||
* Enum Type
|
* Enum Type
|
||||||
* @param clazz
|
* @param clazz
|
||||||
@@ -630,7 +630,7 @@ public class JSONObject {
|
|||||||
* A key string.
|
* A key string.
|
||||||
* @return The numeric value.
|
* @return The numeric value.
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
* if the key is not found or if the value cannot
|
* if the key is not found or if the value cannot
|
||||||
* be converted to BigInteger.
|
* be converted to BigInteger.
|
||||||
*/
|
*/
|
||||||
public BigInteger getBigInteger(String key) throws JSONException {
|
public BigInteger getBigInteger(String key) throws JSONException {
|
||||||
@@ -929,7 +929,7 @@ public class JSONObject {
|
|||||||
* modify the JSONObject. Use with caution.
|
* modify the JSONObject. Use with caution.
|
||||||
*
|
*
|
||||||
* @see Set#iterator()
|
* @see Set#iterator()
|
||||||
*
|
*
|
||||||
* @return An iterator of the keys.
|
* @return An iterator of the keys.
|
||||||
*/
|
*/
|
||||||
public Iterator<String> keys() {
|
public Iterator<String> keys() {
|
||||||
@@ -950,10 +950,10 @@ public class JSONObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a set of entries of the JSONObject. These are raw values and may not
|
* Get a set of entries of the JSONObject. These are raw values and may not
|
||||||
* match what is returned by the JSONObject get* and opt* functions. Modifying
|
* match what is returned by the JSONObject get* and opt* functions. Modifying
|
||||||
* the returned EntrySet or the Entry objects contained therein will modify the
|
* the returned EntrySet or the Entry objects contained therein will modify the
|
||||||
* backing JSONObject. This does not return a clone or a read-only view.
|
* backing JSONObject. This does not return a clone or a read-only view.
|
||||||
*
|
*
|
||||||
* Use with caution.
|
* Use with caution.
|
||||||
*
|
*
|
||||||
* @see Map#entrySet()
|
* @see Map#entrySet()
|
||||||
@@ -973,6 +973,14 @@ public class JSONObject {
|
|||||||
return this.map.size();
|
return this.map.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all of the elements from this JSONObject.
|
||||||
|
* The JSONObject will be empty after this call returns.
|
||||||
|
*/
|
||||||
|
public void clear() {
|
||||||
|
this.map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if JSONObject is empty.
|
* Check if JSONObject is empty.
|
||||||
*
|
*
|
||||||
@@ -1039,7 +1047,7 @@ public class JSONObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the enum value associated with a key.
|
* Get the enum value associated with a key.
|
||||||
*
|
*
|
||||||
* @param <E>
|
* @param <E>
|
||||||
* Enum Type
|
* Enum Type
|
||||||
* @param clazz
|
* @param clazz
|
||||||
@@ -1054,7 +1062,7 @@ public class JSONObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the enum value associated with a key.
|
* Get the enum value associated with a key.
|
||||||
*
|
*
|
||||||
* @param <E>
|
* @param <E>
|
||||||
* Enum Type
|
* Enum Type
|
||||||
* @param clazz
|
* @param clazz
|
||||||
@@ -1148,7 +1156,7 @@ public class JSONObject {
|
|||||||
* @param val value to convert
|
* @param val value to convert
|
||||||
* @param defaultValue default value to return is the conversion doesn't work or is null.
|
* @param defaultValue default value to return is the conversion doesn't work or is null.
|
||||||
* @return BigDecimal conversion of the original value, or the defaultValue if unable
|
* @return BigDecimal conversion of the original value, or the defaultValue if unable
|
||||||
* to convert.
|
* to convert.
|
||||||
*/
|
*/
|
||||||
static BigDecimal objectToBigDecimal(Object val, BigDecimal defaultValue) {
|
static BigDecimal objectToBigDecimal(Object val, BigDecimal defaultValue) {
|
||||||
if (NULL.equals(val)) {
|
if (NULL.equals(val)) {
|
||||||
@@ -1161,8 +1169,7 @@ public class JSONObject {
|
|||||||
return new BigDecimal((BigInteger) val);
|
return new BigDecimal((BigInteger) val);
|
||||||
}
|
}
|
||||||
if (val instanceof Double || val instanceof Float){
|
if (val instanceof Double || val instanceof Float){
|
||||||
final double d = ((Number) val).doubleValue();
|
if (!numberIsFinite((Number)val)) {
|
||||||
if(Double.isNaN(d)) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
return new BigDecimal(((Number) val).doubleValue());
|
return new BigDecimal(((Number) val).doubleValue());
|
||||||
@@ -1199,7 +1206,7 @@ public class JSONObject {
|
|||||||
* @param val value to convert
|
* @param val value to convert
|
||||||
* @param defaultValue default value to return is the conversion doesn't work or is null.
|
* @param defaultValue default value to return is the conversion doesn't work or is null.
|
||||||
* @return BigInteger conversion of the original value, or the defaultValue if unable
|
* @return BigInteger conversion of the original value, or the defaultValue if unable
|
||||||
* to convert.
|
* to convert.
|
||||||
*/
|
*/
|
||||||
static BigInteger objectToBigInteger(Object val, BigInteger defaultValue) {
|
static BigInteger objectToBigInteger(Object val, BigInteger defaultValue) {
|
||||||
if (NULL.equals(val)) {
|
if (NULL.equals(val)) {
|
||||||
@@ -1212,11 +1219,10 @@ public class JSONObject {
|
|||||||
return ((BigDecimal) val).toBigInteger();
|
return ((BigDecimal) val).toBigInteger();
|
||||||
}
|
}
|
||||||
if (val instanceof Double || val instanceof Float){
|
if (val instanceof Double || val instanceof Float){
|
||||||
final double d = ((Number) val).doubleValue();
|
if (!numberIsFinite((Number)val)) {
|
||||||
if(Double.isNaN(d)) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
return new BigDecimal(d).toBigInteger();
|
return new BigDecimal(((Number) val).doubleValue()).toBigInteger();
|
||||||
}
|
}
|
||||||
if (val instanceof Long || val instanceof Integer
|
if (val instanceof Long || val instanceof Integer
|
||||||
|| val instanceof Short || val instanceof Byte){
|
|| val instanceof Short || val instanceof Byte){
|
||||||
@@ -1224,7 +1230,7 @@ public class JSONObject {
|
|||||||
}
|
}
|
||||||
// don't check if it's a string in case of unchecked Number subclasses
|
// don't check if it's a string in case of unchecked Number subclasses
|
||||||
try {
|
try {
|
||||||
// the other opt functions handle implicit conversions, i.e.
|
// the other opt functions handle implicit conversions, i.e.
|
||||||
// jo.put("double",1.1d);
|
// jo.put("double",1.1d);
|
||||||
// jo.optInt("double"); -- will return 1, not an error
|
// jo.optInt("double"); -- will return 1, not an error
|
||||||
// this conversion to BigDecimal then to BigInteger is to maintain
|
// this conversion to BigDecimal then to BigInteger is to maintain
|
||||||
@@ -1398,10 +1404,10 @@ public class JSONObject {
|
|||||||
if (val == null) {
|
if (val == null) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return val.longValue();
|
return val.longValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an optional {@link Number} value associated with a key, or <code>null</code>
|
* Get an optional {@link Number} value associated with a key, or <code>null</code>
|
||||||
* if there is no such key or if the value is not a number. If the value is a string,
|
* if there is no such key or if the value is not a number. If the value is a string,
|
||||||
@@ -1436,14 +1442,14 @@ public class JSONObject {
|
|||||||
if (val instanceof Number){
|
if (val instanceof Number){
|
||||||
return (Number) val;
|
return (Number) val;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return stringToNumber(val.toString());
|
return stringToNumber(val.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an optional string associated with a key. It returns an empty 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,
|
* if there is no such key. If the value is not a string and is not null,
|
||||||
@@ -1552,7 +1558,7 @@ public class JSONObject {
|
|||||||
// if the first letter in the key is not uppercase, then skip.
|
// if the first letter in the key is not uppercase, then skip.
|
||||||
// This is to maintain backwards compatibility before PR406
|
// This is to maintain backwards compatibility before PR406
|
||||||
// (https://github.com/stleary/JSON-java/pull/406/)
|
// (https://github.com/stleary/JSON-java/pull/406/)
|
||||||
if (Character.isLowerCase(key.charAt(0))) {
|
if (key.length() == 0 || Character.isLowerCase(key.charAt(0))) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (key.length() == 1) {
|
if (key.length() == 1) {
|
||||||
@@ -1729,7 +1735,7 @@ public class JSONObject {
|
|||||||
public JSONObject put(String key, double value) throws JSONException {
|
public JSONObject put(String key, double value) throws JSONException {
|
||||||
return this.put(key, Double.valueOf(value));
|
return this.put(key, Double.valueOf(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put a key/float pair in the JSONObject.
|
* Put a key/float pair in the JSONObject.
|
||||||
*
|
*
|
||||||
@@ -1873,7 +1879,7 @@ public class JSONObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a JSONPointer using an initialization string and tries to
|
* Creates a JSONPointer using an initialization string and tries to
|
||||||
* match it to an item within this JSONObject. For example, given a
|
* match it to an item within this JSONObject. For example, given a
|
||||||
* JSONObject initialized with this document:
|
* JSONObject initialized with this document:
|
||||||
* <pre>
|
* <pre>
|
||||||
@@ -1881,13 +1887,13 @@ public class JSONObject {
|
|||||||
* "a":{"b":"c"}
|
* "a":{"b":"c"}
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
* and this JSONPointer string:
|
* and this JSONPointer string:
|
||||||
* <pre>
|
* <pre>
|
||||||
* "/a/b"
|
* "/a/b"
|
||||||
* </pre>
|
* </pre>
|
||||||
* Then this method will return the String "c".
|
* Then this method will return the String "c".
|
||||||
* A JSONPointerException may be thrown from code called by this method.
|
* A JSONPointerException may be thrown from code called by this method.
|
||||||
*
|
*
|
||||||
* @param jsonPointer string that can be used to create a JSONPointer
|
* @param jsonPointer string that can be used to create a JSONPointer
|
||||||
* @return the item matched by the JSONPointer, otherwise null
|
* @return the item matched by the JSONPointer, otherwise null
|
||||||
*/
|
*/
|
||||||
@@ -1895,7 +1901,7 @@ public class JSONObject {
|
|||||||
return query(new JSONPointer(jsonPointer));
|
return query(new JSONPointer(jsonPointer));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Uses a user initialized JSONPointer and tries to
|
* Uses a user initialized JSONPointer and tries to
|
||||||
* match it to an item within this JSONObject. For example, given a
|
* match it to an item within this JSONObject. For example, given a
|
||||||
* JSONObject initialized with this document:
|
* JSONObject initialized with this document:
|
||||||
* <pre>
|
* <pre>
|
||||||
@@ -1903,24 +1909,24 @@ public class JSONObject {
|
|||||||
* "a":{"b":"c"}
|
* "a":{"b":"c"}
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
* and this JSONPointer:
|
* and this JSONPointer:
|
||||||
* <pre>
|
* <pre>
|
||||||
* "/a/b"
|
* "/a/b"
|
||||||
* </pre>
|
* </pre>
|
||||||
* Then this method will return the String "c".
|
* Then this method will return the String "c".
|
||||||
* A JSONPointerException may be thrown from code called by this method.
|
* A JSONPointerException may be thrown from code called by this method.
|
||||||
*
|
*
|
||||||
* @param jsonPointer string that can be used to create a JSONPointer
|
* @param jsonPointer string that can be used to create a JSONPointer
|
||||||
* @return the item matched by the JSONPointer, otherwise null
|
* @return the item matched by the JSONPointer, otherwise null
|
||||||
*/
|
*/
|
||||||
public Object query(JSONPointer jsonPointer) {
|
public Object query(JSONPointer jsonPointer) {
|
||||||
return jsonPointer.queryFrom(this);
|
return jsonPointer.queryFrom(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queries and returns a value from this object using {@code jsonPointer}, or
|
* Queries and returns a value from this object using {@code jsonPointer}, or
|
||||||
* returns null if the query fails due to a missing key.
|
* returns null if the query fails due to a missing key.
|
||||||
*
|
*
|
||||||
* @param jsonPointer the string representation of the JSON pointer
|
* @param jsonPointer the string representation of the JSON pointer
|
||||||
* @return the queried value or {@code null}
|
* @return the queried value or {@code null}
|
||||||
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
||||||
@@ -1928,11 +1934,11 @@ public class JSONObject {
|
|||||||
public Object optQuery(String jsonPointer) {
|
public Object optQuery(String jsonPointer) {
|
||||||
return optQuery(new JSONPointer(jsonPointer));
|
return optQuery(new JSONPointer(jsonPointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queries and returns a value from this object using {@code jsonPointer}, or
|
* Queries and returns a value from this object using {@code jsonPointer}, or
|
||||||
* returns null if the query fails due to a missing key.
|
* returns null if the query fails due to a missing key.
|
||||||
*
|
*
|
||||||
* @param jsonPointer The JSON pointer
|
* @param jsonPointer The JSON pointer
|
||||||
* @return the queried value or {@code null}
|
* @return the queried value or {@code null}
|
||||||
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
||||||
@@ -2073,6 +2079,8 @@ public class JSONObject {
|
|||||||
if (!((JSONArray)valueThis).similar(valueOther)) {
|
if (!((JSONArray)valueThis).similar(valueOther)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (valueThis instanceof Number && valueOther instanceof Number) {
|
||||||
|
return isNumberSimilar((Number)valueThis, (Number)valueOther);
|
||||||
} else if (!valueThis.equals(valueOther)) {
|
} else if (!valueThis.equals(valueOther)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2082,10 +2090,59 @@ public class JSONObject {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two numbers to see if they are similar.
|
||||||
|
*
|
||||||
|
* If either of the numbers are Double or Float instances, then they are checked to have
|
||||||
|
* a finite value. If either value is not finite (NaN or ±infinity), then this
|
||||||
|
* function will always return false. If both numbers are finite, they are first checked
|
||||||
|
* to be the same type and implement {@link Comparable}. If they do, then the actual
|
||||||
|
* {@link Comparable#compareTo(Object)} is called. If they are not the same type, or don't
|
||||||
|
* implement Comparable, then they are converted to {@link BigDecimal}s. Finally the
|
||||||
|
* BigDecimal values are compared using {@link BigDecimal#compareTo(BigDecimal)}.
|
||||||
|
*
|
||||||
|
* @param l the Left value to compare. Can not be <code>null</code>.
|
||||||
|
* @param r the right value to compare. Can not be <code>null</code>.
|
||||||
|
* @return true if the numbers are similar, false otherwise.
|
||||||
|
*/
|
||||||
|
static boolean isNumberSimilar(Number l, Number r) {
|
||||||
|
if (!numberIsFinite(l) || !numberIsFinite(r)) {
|
||||||
|
// non-finite numbers are never similar
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the classes are the same and implement Comparable
|
||||||
|
// then use the built in compare first.
|
||||||
|
if(l.getClass().equals(r.getClass()) && l instanceof Comparable) {
|
||||||
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
int compareTo = ((Comparable)l).compareTo(r);
|
||||||
|
return compareTo==0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BigDecimal should be able to handle all of our number types that we support through
|
||||||
|
// documentation. Convert to BigDecimal first, then use the Compare method to
|
||||||
|
// decide equality.
|
||||||
|
final BigDecimal lBigDecimal = objectToBigDecimal(l, null);
|
||||||
|
final BigDecimal rBigDecimal = objectToBigDecimal(r, null);
|
||||||
|
if (lBigDecimal == null || rBigDecimal == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return lBigDecimal.compareTo(rBigDecimal) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean numberIsFinite(Number n) {
|
||||||
|
if (n instanceof Double && (((Double) n).isInfinite() || ((Double) n).isNaN())) {
|
||||||
|
return false;
|
||||||
|
} else if (n instanceof Float && (((Float) n).isInfinite() || ((Float) n).isNaN())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if the value should be tried as a decimal. It makes no test if there are actual digits.
|
* Tests if the value should be tried as a decimal. It makes no test if there are actual digits.
|
||||||
*
|
*
|
||||||
* @param val value to test
|
* @param val value to test
|
||||||
* @return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise.
|
* @return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise.
|
||||||
*/
|
*/
|
||||||
@@ -2093,12 +2150,12 @@ public class JSONObject {
|
|||||||
return val.indexOf('.') > -1 || val.indexOf('e') > -1
|
return val.indexOf('.') > -1 || val.indexOf('e') > -1
|
||||||
|| val.indexOf('E') > -1 || "-0".equals(val);
|
|| val.indexOf('E') > -1 || "-0".equals(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a string to a number using the narrowest possible type. Possible
|
* Converts a string to a number using the narrowest possible type. Possible
|
||||||
* returns for this function are BigDecimal, Double, BigInteger, Long, and Integer.
|
* returns for this function are BigDecimal, Double, BigInteger, Long, and Integer.
|
||||||
* When a Double is returned, it should always be a valid Double and not NaN or +-infinity.
|
* When a Double is returned, it should always be a valid Double and not NaN or +-infinity.
|
||||||
*
|
*
|
||||||
* @param val value to convert
|
* @param val value to convert
|
||||||
* @return Number representation of the value.
|
* @return Number representation of the value.
|
||||||
* @throws NumberFormatException thrown if the value is not a valid number. A public
|
* @throws NumberFormatException thrown if the value is not a valid number. A public
|
||||||
@@ -2147,7 +2204,7 @@ public class JSONObject {
|
|||||||
// integer representation.
|
// integer representation.
|
||||||
// This will narrow any values to the smallest reasonable Object representation
|
// This will narrow any values to the smallest reasonable Object representation
|
||||||
// (Integer, Long, or BigInteger)
|
// (Integer, Long, or BigInteger)
|
||||||
|
|
||||||
// BigInteger down conversion: We use a similar bitLenth compare as
|
// BigInteger down conversion: We use a similar bitLenth compare as
|
||||||
// BigInteger#intValueExact uses. Increases GC, but objects hold
|
// BigInteger#intValueExact uses. Increases GC, but objects hold
|
||||||
// only what they need. i.e. Less runtime overhead if the value is
|
// only what they need. i.e. Less runtime overhead if the value is
|
||||||
@@ -2216,18 +2273,8 @@ public class JSONObject {
|
|||||||
* If o is a non-finite number.
|
* If o is a non-finite number.
|
||||||
*/
|
*/
|
||||||
public static void testValidity(Object o) throws JSONException {
|
public static void testValidity(Object o) throws JSONException {
|
||||||
if (o != null) {
|
if (o instanceof Number && !numberIsFinite((Number) o)) {
|
||||||
if (o instanceof Double) {
|
throw new JSONException("JSON does not allow non-finite numbers.");
|
||||||
if (((Double) o).isInfinite() || ((Double) o).isNaN()) {
|
|
||||||
throw new JSONException(
|
|
||||||
"JSON does not allow non-finite numbers.");
|
|
||||||
}
|
|
||||||
} else if (o instanceof Float) {
|
|
||||||
if (((Float) o).isInfinite() || ((Float) o).isNaN()) {
|
|
||||||
throw new JSONException(
|
|
||||||
"JSON does not allow non-finite numbers.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2260,7 +2307,7 @@ public class JSONObject {
|
|||||||
* <p><b>
|
* <p><b>
|
||||||
* Warning: This method assumes that the data structure is acyclical.
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
* </b>
|
* </b>
|
||||||
*
|
*
|
||||||
* @return a printable, displayable, portable, transmittable representation
|
* @return a printable, displayable, portable, transmittable representation
|
||||||
* of the object, beginning with <code>{</code> <small>(left
|
* of the object, beginning with <code>{</code> <small>(left
|
||||||
* brace)</small> and ending with <code>}</code> <small>(right
|
* brace)</small> and ending with <code>}</code> <small>(right
|
||||||
@@ -2277,11 +2324,11 @@ public class JSONObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a pretty-printed JSON text of this JSONObject.
|
* Make a pretty-printed JSON text of this JSONObject.
|
||||||
*
|
*
|
||||||
* <p>If <pre>{@code indentFactor > 0}</pre> and the {@link JSONObject}
|
* <p>If <pre>{@code indentFactor > 0}</pre> and the {@link JSONObject}
|
||||||
* has only one key, then the object will be output on a single line:
|
* has only one key, then the object will be output on a single line:
|
||||||
* <pre>{@code {"key": 1}}</pre>
|
* <pre>{@code {"key": 1}}</pre>
|
||||||
*
|
*
|
||||||
* <p>If an object has 2 or more keys, then it will be output across
|
* <p>If an object has 2 or more keys, then it will be output across
|
||||||
* multiple lines: <pre>{@code {
|
* multiple lines: <pre>{@code {
|
||||||
* "key1": 1,
|
* "key1": 1,
|
||||||
@@ -2354,7 +2401,7 @@ public class JSONObject {
|
|||||||
*/
|
*/
|
||||||
public static Object wrap(Object object) {
|
public static Object wrap(Object object) {
|
||||||
try {
|
try {
|
||||||
if (object == null) {
|
if (NULL.equals(object)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (object instanceof JSONObject || object instanceof JSONArray
|
if (object instanceof JSONObject || object instanceof JSONArray
|
||||||
@@ -2459,11 +2506,11 @@ public class JSONObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the contents of the JSONObject as JSON text to a writer.
|
* Write the contents of the JSONObject as JSON text to a writer.
|
||||||
*
|
*
|
||||||
* <p>If <pre>{@code indentFactor > 0}</pre> and the {@link JSONObject}
|
* <p>If <pre>{@code indentFactor > 0}</pre> and the {@link JSONObject}
|
||||||
* has only one key, then the object will be output on a single line:
|
* has only one key, then the object will be output on a single line:
|
||||||
* <pre>{@code {"key": 1}}</pre>
|
* <pre>{@code {"key": 1}}</pre>
|
||||||
*
|
*
|
||||||
* <p>If an object has 2 or more keys, then it will be output across
|
* <p>If an object has 2 or more keys, then it will be output across
|
||||||
* multiple lines: <pre>{@code {
|
* multiple lines: <pre>{@code {
|
||||||
* "key1": 1,
|
* "key1": 1,
|
||||||
@@ -2565,7 +2612,7 @@ public class JSONObject {
|
|||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new JSONException in a common format for incorrect conversions.
|
* Create a new JSONException in a common format for incorrect conversions.
|
||||||
* @param key name of the key
|
* @param key name of the key
|
||||||
@@ -2581,7 +2628,7 @@ public class JSONObject {
|
|||||||
"JSONObject[" + quote(key) + "] is not a " + valueType + "."
|
"JSONObject[" + quote(key) + "] is not a " + valueType + "."
|
||||||
, cause);
|
, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new JSONException in a common format for incorrect conversions.
|
* Create a new JSONException in a common format for incorrect conversions.
|
||||||
* @param key name of the key
|
* @param key name of the key
|
||||||
|
|||||||
@@ -187,10 +187,11 @@ public class JSONPointer {
|
|||||||
this.refTokens = new ArrayList<String>(refTokens);
|
this.refTokens = new ArrayList<String>(refTokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://tools.ietf.org/html/rfc6901#section-3
|
||||||
|
*/
|
||||||
private static String unescape(String token) {
|
private static String unescape(String token) {
|
||||||
return token.replace("~1", "/").replace("~0", "~")
|
return token.replace("~1", "/").replace("~0", "~");
|
||||||
.replace("\\\"", "\"")
|
|
||||||
.replace("\\\\", "\\");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -263,16 +264,15 @@ public class JSONPointer {
|
|||||||
/**
|
/**
|
||||||
* Escapes path segment values to an unambiguous form.
|
* Escapes path segment values to an unambiguous form.
|
||||||
* The escape char to be inserted is '~'. The chars to be escaped
|
* The escape char to be inserted is '~'. The chars to be escaped
|
||||||
* are ~, which maps to ~0, and /, which maps to ~1. Backslashes
|
* are ~, which maps to ~0, and /, which maps to ~1.
|
||||||
* and double quote chars are also escaped.
|
|
||||||
* @param token the JSONPointer segment value to be escaped
|
* @param token the JSONPointer segment value to be escaped
|
||||||
* @return the escaped value for the token
|
* @return the escaped value for the token
|
||||||
|
*
|
||||||
|
* @see https://tools.ietf.org/html/rfc6901#section-3
|
||||||
*/
|
*/
|
||||||
private static String escape(String token) {
|
private static String escape(String token) {
|
||||||
return token.replace("~", "~0")
|
return token.replace("~", "~0")
|
||||||
.replace("/", "~1")
|
.replace("/", "~1");
|
||||||
.replace("\\", "\\\\")
|
|
||||||
.replace("\"", "\\\"");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1254,4 +1254,19 @@ public class JSONArrayTest {
|
|||||||
assertEquals("index " + i + " are equal", a1.get(i), a2.get(i));
|
assertEquals("index " + i + " are equal", a1.get(i), a2.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if calling JSONArray clear() method actually makes the JSONArray empty
|
||||||
|
*/
|
||||||
|
@Test(expected = JSONException.class)
|
||||||
|
public void jsonArrayClearMethodTest() {
|
||||||
|
//Adds random stuff to the JSONArray
|
||||||
|
JSONArray jsonArray = new JSONArray();
|
||||||
|
jsonArray.put(123);
|
||||||
|
jsonArray.put("456");
|
||||||
|
jsonArray.put(new JSONArray());
|
||||||
|
jsonArray.clear(); //Clears the JSONArray
|
||||||
|
assertTrue("expected jsonArray.length() == 0", jsonArray.length() == 0); //Check if its length is 0
|
||||||
|
jsonArray.getInt(0); //Should throws org.json.JSONException: JSONArray[0] not found
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,10 +115,17 @@ public class JSONObjectTest {
|
|||||||
.put("key2", 2)
|
.put("key2", 2)
|
||||||
.put("key3", new String(string1));
|
.put("key3", new String(string1));
|
||||||
|
|
||||||
assertFalse("Should eval to false", obj1.similar(obj2));
|
JSONObject obj4 = new JSONObject()
|
||||||
|
.put("key1", "abc")
|
||||||
|
.put("key2", 2.0)
|
||||||
|
.put("key3", new String(string1));
|
||||||
|
|
||||||
|
assertFalse("Should eval to false", obj1.similar(obj2));
|
||||||
|
|
||||||
assertTrue("Should eval to true", obj1.similar(obj3));
|
assertTrue("Should eval to true", obj1.similar(obj3));
|
||||||
|
|
||||||
|
assertTrue("Should eval to true", obj1.similar(obj4));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -3208,4 +3215,19 @@ public class JSONObjectTest {
|
|||||||
assertNotNull("'empty_json_array' should be an array", jsonObject.getJSONArray("empty_json_array"));
|
assertNotNull("'empty_json_array' should be an array", jsonObject.getJSONArray("empty_json_array"));
|
||||||
assertEquals("'empty_json_array' should have a length of 0", 0, jsonObject.getJSONArray("empty_json_array").length());
|
assertEquals("'empty_json_array' should have a length of 0", 0, jsonObject.getJSONArray("empty_json_array").length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if calling JSONObject clear() method actually makes the JSONObject empty
|
||||||
|
*/
|
||||||
|
@Test(expected = JSONException.class)
|
||||||
|
public void jsonObjectClearMethodTest() {
|
||||||
|
//Adds random stuff to the JSONObject
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("key1", 123);
|
||||||
|
jsonObject.put("key2", "456");
|
||||||
|
jsonObject.put("key3", new JSONObject());
|
||||||
|
jsonObject.clear(); //Clears the JSONObject
|
||||||
|
assertTrue("expected jsonObject.length() == 0", jsonObject.length() == 0); //Check if its length is 0
|
||||||
|
jsonObject.getInt("key1"); //Should throws org.json.JSONException: JSONObject["asd"] not found
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,14 +117,24 @@ public class JSONPointerTest {
|
|||||||
assertSame(document.get("m~n"), query("/m~0n"));
|
assertSame(document.get("m~n"), query("/m~0n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We pass backslashes as-is
|
||||||
|
*
|
||||||
|
* @see https://tools.ietf.org/html/rfc6901#section-3
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void backslashEscaping() {
|
public void backslashHandling() {
|
||||||
assertSame(document.get("i\\j"), query("/i\\\\j"));
|
assertSame(document.get("i\\j"), query("/i\\j"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We pass quotations as-is
|
||||||
|
*
|
||||||
|
* @see https://tools.ietf.org/html/rfc6901#section-3
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void quotationEscaping() {
|
public void quotationHandling() {
|
||||||
assertSame(document.get("k\"l"), query("/k\\\\\\\"l"));
|
assertSame(document.get("k\"l"), query("/k\"l"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -189,7 +199,7 @@ public class JSONPointerTest {
|
|||||||
.append("\"")
|
.append("\"")
|
||||||
.append(0)
|
.append(0)
|
||||||
.build();
|
.build();
|
||||||
assertEquals("/obj/other~0key/another~1key/\\\"/0", pointer.toString());
|
assertEquals("/obj/other~0key/another~1key/\"/0", pointer.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user