Skip to content

Commit 7afd932

Browse files
committed
Merge branch 'master' into gh-pages
2 parents f807731 + 26f4848 commit 7afd932

File tree

7 files changed

+136
-44
lines changed

7 files changed

+136
-44
lines changed

README.md

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ JSON in Java [package org.json]
33

44
[![Maven Central](https://img.shields.io/maven-central/v/org.json/json.svg)](https://mvnrepository.com/artifact/org.json/json)
55

6-
**[Click here if you just want the latest release jar file.](https://repo1.maven.org/maven2/org/json/json/20200518/json-20200518.jar)**
6+
**[Click here if you just want the latest release jar file.](https://repo1.maven.org/maven2/org/json/json/20201115/json-20201115.jar)**
77

88
# Overview
99

10-
[JSON](http://www.JSON.org/) is a light-weight language independent data interchange format.
10+
[JSON](http://www.JSON.org/) is a light-weight language-independent data interchange format.
1111

1212
The JSON-Java package is a reference implementation that demonstrates how to parse JSON documents into Java objects and how to generate new JSON documents from the Java classes.
1313

@@ -17,7 +17,7 @@ Project goals include:
1717
* Easy to build, use, and include in other projects
1818
* No external dependencies
1919
* Fast execution and low memory footprint
20-
* Maintain backwards compatibility
20+
* Maintain backward compatibility
2121
* Designed and tested to use on Java versions 1.6 - 1.11
2222

2323
The files in this package implement JSON encoders and decoders. The package can also convert between JSON and XML, HTTP headers, Cookies, and CDL.
@@ -26,7 +26,7 @@ The license includes this restriction: ["The software shall be used for good, no
2626

2727
**If you would like to contribute to this project**
2828

29-
Bug fixes, code improvements, and unit test coverage changes are welcome! Because this project is currrently in maintenance phase, the kinds of changes that can be accepted are limited. For more information, please read the [FAQ](https://github.com/stleary/JSON-java/wiki/FAQ).
29+
Bug fixes, code improvements, and unit test coverage changes are welcome! Because this project is currently in the maintenance phase, the kinds of changes that can be accepted are limited. For more information, please read the [FAQ](https://github.com/stleary/JSON-java/wiki/FAQ).
3030

3131
# Build Instructions
3232

@@ -61,7 +61,7 @@ public class Test {
6161
}
6262
````
6363

64-
*Excecute the Test file*
64+
*Execute the Test file*
6565
````
6666
java -cp .;json-java.jar Test
6767
````
@@ -73,14 +73,14 @@ java -cp .;json-java.jar Test
7373
````
7474

7575

76-
**Build tools for building the package and executing the unit tests**
76+
**Tools to build the package and execute the unit tests**
7777

78-
The test suite can be executed with Maven by running:
78+
Execute the test suite with Maven:
7979
```
8080
mvn clean test
8181
```
8282

83-
The test suite can be executed with Gradlew by running:
83+
Execute the test suite with Gradlew:
8484

8585
```
8686
gradlew clean build test
@@ -101,12 +101,12 @@ This package fully supports `Integer`, `Long`, and `Double` Java types. Partial
101101
for `BigInteger` and `BigDecimal` values in `JSONObject` and `JSONArray` objects is provided
102102
in the form of `get()`, `opt()`, and `put()` API methods.
103103

104-
Although 1.6 compatibility is currently supported, it is not a project goal and may be
104+
Although 1.6 compatibility is currently supported, it is not a project goal and might be
105105
removed in some future release.
106106

107107
In compliance with RFC8259 page 10 section 9, the parser is more lax with what is valid
108-
JSON than the Generator. For Example, the tab character (U+0009) is allowed when reading
109-
JSON Text strings, but when output by the Generator, tab is properly converted to \t in
108+
JSON then the Generator. For Example, the tab character (U+0009) is allowed when reading
109+
JSON Text strings, but when output by the Generator, the tab is properly converted to \t in
110110
the string. Other instances may occur where reading invalid JSON text does not cause an
111111
error to be generated. Malformed JSON Texts such as missing end " (quote) on strings or
112112
invalid number formats (1.2e6.3) will cause errors as such documents can not be read
@@ -119,7 +119,7 @@ Some notable exceptions that the JSON Parser in this library accepts are:
119119
* Numbers out of range for `Double` or `Long` are parsed as strings
120120

121121
Recent pull requests added a new method `putAll` on the JSONArray. The `putAll` method
122-
works similarly as other `put` mehtods in that it does not call `JSONObject.wrap` for items
122+
works similarly to other `put` methods in that it does not call `JSONObject.wrap` for items
123123
added. This can lead to inconsistent object representation in JSONArray structures.
124124

125125
For example, code like this will create a mixed JSONArray, some items wrapped, others
@@ -169,10 +169,10 @@ For example, <b>Cookie.java</b> is tested by <b>CookieTest.java</b>.
169169

170170
<b>General issues with unit testing are:</b><br>
171171
* Just writing tests to make coverage goals tends to result in poor tests.
172-
* Unit tests are a form of documentation - how a given method actually works is demonstrated by the test. So for a code reviewer or future developer looking at code a good test helps explain how a function is supposed to work according to the original author. This can be difficult if you are not the original developer.
172+
* Unit tests are a form of documentation - how a given method works is demonstrated by the test. So for a code reviewer or future developer looking at code a good test helps explain how a function is supposed to work according to the original author. This can be difficult if you are not the original developer.
173173
* It is difficult to evaluate unit tests in a vacuum. You also need to see the code being tested to understand if a test is good.
174-
* Without unit tests it is hard to feel confident about the quality of the code, especially when fixing bugs or refactoring. Good tests prevents regressions and keeps the intent of the code correct.
175-
* If you have unit test results along with pull requests, the reviewer has an easier time understanding your code and determining if the it works as intended.
174+
* Without unit tests, it is hard to feel confident about the quality of the code, especially when fixing bugs or refactoring. Good tests prevent regressions and keep the intent of the code correct.
175+
* If you have unit test results along with pull requests, the reviewer has an easier time understanding your code and determining if it works as intended.
176176

177177

178178
# Files
@@ -246,6 +246,8 @@ and artifactId "json". For example:
246246
[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)
247247

248248
~~~
249+
20201115 Recent commits and first release after project structure change
250+
249251
20200518 Recent commits and snapshot before project structure change
250252
251253
20190722 Recent commits
@@ -264,16 +266,12 @@ and artifactId "json". For example:
264266
it is not recommended for use.
265267
Java 1.6 compatability fixed, JSONArray.toList() and JSONObject.toMap(),
266268
RFC4180 compatibility, JSONPointer, some exception fixes, optional XML type conversion.
267-
Contains the latest code as of 7 Aug, 2016
269+
Contains the latest code as of 7 Aug 2016
268270
269-
20160212 Java 1.6 compatibility, OSGi bundle. Contains the latest code as of 12 Feb, 2016.
271+
20160212 Java 1.6 compatibility, OSGi bundle. Contains the latest code as of 12 Feb 2016.
270272
271-
20151123 JSONObject and JSONArray initialization with generics. Contains the
272-
latest code as of 23 Nov, 2015.
273+
20151123 JSONObject and JSONArray initialization with generics. Contains the latest code as of 23 Nov 2015.
273274
274275
20150729 Checkpoint for Maven central repository release. Contains the latest code
275-
as of 29 July, 2015.
276+
as of 29 July 2015.
276277
~~~
277-
278-
279-

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ repositories {
2323
}
2424

2525
dependencies {
26-
testImplementation 'junit:junit:4.12'
26+
testImplementation 'junit:junit:4.13.1'
2727
testImplementation 'com.jayway.jsonpath:json-path:2.1.0'
2828
testImplementation 'org.mockito:mockito-core:1.9.5'
2929
}

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
<dependency>
8181
<groupId>junit</groupId>
8282
<artifactId>junit</artifactId>
83-
<version>4.12</version>
83+
<version>4.13.1</version>
8484
<scope>test</scope>
8585
</dependency>
8686
<dependency>

src/main/java/org/json/JSONArray.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,14 @@ public int length() {
567567
return this.myArrayList.size();
568568
}
569569

570+
/**
571+
* Removes all of the elements from this JSONArray.
572+
* The JSONArray will be empty after this call returns.
573+
*/
574+
public void clear() {
575+
this.myArrayList.clear();
576+
}
577+
570578
/**
571579
* Get the optional object value associated with an index.
572580
*
@@ -1374,6 +1382,8 @@ public boolean similar(Object other) {
13741382
if (!((JSONArray)valueThis).similar(valueOther)) {
13751383
return false;
13761384
}
1385+
} else if (valueThis instanceof Number && valueOther instanceof Number) {
1386+
return JSONObject.isNumberSimilar((Number)valueThis, (Number)valueOther);
13771387
} else if (!valueThis.equals(valueOther)) {
13781388
return false;
13791389
}

src/main/java/org/json/JSONObject.java

Lines changed: 65 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,14 @@ public int length() {
973973
return this.map.size();
974974
}
975975

976+
/**
977+
* Removes all of the elements from this JSONObject.
978+
* The JSONObject will be empty after this call returns.
979+
*/
980+
public void clear() {
981+
this.map.clear();
982+
}
983+
976984
/**
977985
* Check if JSONObject is empty.
978986
*
@@ -1161,8 +1169,7 @@ static BigDecimal objectToBigDecimal(Object val, BigDecimal defaultValue) {
11611169
return new BigDecimal((BigInteger) val);
11621170
}
11631171
if (val instanceof Double || val instanceof Float){
1164-
final double d = ((Number) val).doubleValue();
1165-
if(Double.isNaN(d)) {
1172+
if (!numberIsFinite((Number)val)) {
11661173
return defaultValue;
11671174
}
11681175
return new BigDecimal(((Number) val).doubleValue());
@@ -1212,11 +1219,10 @@ static BigInteger objectToBigInteger(Object val, BigInteger defaultValue) {
12121219
return ((BigDecimal) val).toBigInteger();
12131220
}
12141221
if (val instanceof Double || val instanceof Float){
1215-
final double d = ((Number) val).doubleValue();
1216-
if(Double.isNaN(d)) {
1222+
if (!numberIsFinite((Number)val)) {
12171223
return defaultValue;
12181224
}
1219-
return new BigDecimal(d).toBigInteger();
1225+
return new BigDecimal(((Number) val).doubleValue()).toBigInteger();
12201226
}
12211227
if (val instanceof Long || val instanceof Integer
12221228
|| val instanceof Short || val instanceof Byte){
@@ -2073,6 +2079,8 @@ public boolean similar(Object other) {
20732079
if (!((JSONArray)valueThis).similar(valueOther)) {
20742080
return false;
20752081
}
2082+
} else if (valueThis instanceof Number && valueOther instanceof Number) {
2083+
return isNumberSimilar((Number)valueThis, (Number)valueOther);
20762084
} else if (!valueThis.equals(valueOther)) {
20772085
return false;
20782086
}
@@ -2083,6 +2091,55 @@ public boolean similar(Object other) {
20832091
}
20842092
}
20852093

2094+
/**
2095+
* Compares two numbers to see if they are similar.
2096+
*
2097+
* If either of the numbers are Double or Float instances, then they are checked to have
2098+
* a finite value. If either value is not finite (NaN or &#177;infinity), then this
2099+
* function will always return false. If both numbers are finite, they are first checked
2100+
* to be the same type and implement {@link Comparable}. If they do, then the actual
2101+
* {@link Comparable#compareTo(Object)} is called. If they are not the same type, or don't
2102+
* implement Comparable, then they are converted to {@link BigDecimal}s. Finally the
2103+
* BigDecimal values are compared using {@link BigDecimal#compareTo(BigDecimal)}.
2104+
*
2105+
* @param l the Left value to compare. Can not be <code>null</code>.
2106+
* @param r the right value to compare. Can not be <code>null</code>.
2107+
* @return true if the numbers are similar, false otherwise.
2108+
*/
2109+
static boolean isNumberSimilar(Number l, Number r) {
2110+
if (!numberIsFinite(l) || !numberIsFinite(r)) {
2111+
// non-finite numbers are never similar
2112+
return false;
2113+
}
2114+
2115+
// if the classes are the same and implement Comparable
2116+
// then use the built in compare first.
2117+
if(l.getClass().equals(r.getClass()) && l instanceof Comparable) {
2118+
@SuppressWarnings({ "rawtypes", "unchecked" })
2119+
int compareTo = ((Comparable)l).compareTo(r);
2120+
return compareTo==0;
2121+
}
2122+
2123+
// BigDecimal should be able to handle all of our number types that we support through
2124+
// documentation. Convert to BigDecimal first, then use the Compare method to
2125+
// decide equality.
2126+
final BigDecimal lBigDecimal = objectToBigDecimal(l, null);
2127+
final BigDecimal rBigDecimal = objectToBigDecimal(r, null);
2128+
if (lBigDecimal == null || rBigDecimal == null) {
2129+
return false;
2130+
}
2131+
return lBigDecimal.compareTo(rBigDecimal) == 0;
2132+
}
2133+
2134+
private static boolean numberIsFinite(Number n) {
2135+
if (n instanceof Double && (((Double) n).isInfinite() || ((Double) n).isNaN())) {
2136+
return false;
2137+
} else if (n instanceof Float && (((Float) n).isInfinite() || ((Float) n).isNaN())) {
2138+
return false;
2139+
}
2140+
return true;
2141+
}
2142+
20862143
/**
20872144
* Tests if the value should be tried as a decimal. It makes no test if there are actual digits.
20882145
*
@@ -2216,18 +2273,8 @@ public static Object stringToValue(String string) {
22162273
* If o is a non-finite number.
22172274
*/
22182275
public static void testValidity(Object o) throws JSONException {
2219-
if (o != null) {
2220-
if (o instanceof Double) {
2221-
if (((Double) o).isInfinite() || ((Double) o).isNaN()) {
2222-
throw new JSONException(
2223-
"JSON does not allow non-finite numbers.");
2224-
}
2225-
} else if (o instanceof Float) {
2226-
if (((Float) o).isInfinite() || ((Float) o).isNaN()) {
2227-
throw new JSONException(
2228-
"JSON does not allow non-finite numbers.");
2229-
}
2230-
}
2276+
if (o instanceof Number && !numberIsFinite((Number) o)) {
2277+
throw new JSONException("JSON does not allow non-finite numbers.");
22312278
}
22322279
}
22332280

@@ -2354,7 +2401,7 @@ public static String valueToString(Object value) throws JSONException {
23542401
*/
23552402
public static Object wrap(Object object) {
23562403
try {
2357-
if (object == null) {
2404+
if (NULL.equals(object)) {
23582405
return NULL;
23592406
}
23602407
if (object instanceof JSONObject || object instanceof JSONArray

src/test/java/org/json/junit/JSONArrayTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,4 +1254,19 @@ public void testJSONArrayPutAll() {
12541254
assertEquals("index " + i + " are equal", a1.get(i), a2.get(i));
12551255
}
12561256
}
1257+
1258+
/**
1259+
* Tests if calling JSONArray clear() method actually makes the JSONArray empty
1260+
*/
1261+
@Test(expected = JSONException.class)
1262+
public void jsonArrayClearMethodTest() {
1263+
//Adds random stuff to the JSONArray
1264+
JSONArray jsonArray = new JSONArray();
1265+
jsonArray.put(123);
1266+
jsonArray.put("456");
1267+
jsonArray.put(new JSONArray());
1268+
jsonArray.clear(); //Clears the JSONArray
1269+
assertTrue("expected jsonArray.length() == 0", jsonArray.length() == 0); //Check if its length is 0
1270+
jsonArray.getInt(0); //Should throws org.json.JSONException: JSONArray[0] not found
1271+
}
12571272
}

src/test/java/org/json/junit/JSONObjectTest.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,17 @@ public void verifySimilar() {
115115
.put("key2", 2)
116116
.put("key3", new String(string1));
117117

118-
assertFalse("Should eval to false", obj1.similar(obj2));
118+
JSONObject obj4 = new JSONObject()
119+
.put("key1", "abc")
120+
.put("key2", 2.0)
121+
.put("key3", new String(string1));
119122

123+
assertFalse("Should eval to false", obj1.similar(obj2));
124+
120125
assertTrue("Should eval to true", obj1.similar(obj3));
121126

127+
assertTrue("Should eval to true", obj1.similar(obj4));
128+
122129
}
123130

124131
@Test
@@ -3208,4 +3215,19 @@ public void testIssue548ObjectWithEmptyJsonArray() {
32083215
assertNotNull("'empty_json_array' should be an array", jsonObject.getJSONArray("empty_json_array"));
32093216
assertEquals("'empty_json_array' should have a length of 0", 0, jsonObject.getJSONArray("empty_json_array").length());
32103217
}
3218+
3219+
/**
3220+
* Tests if calling JSONObject clear() method actually makes the JSONObject empty
3221+
*/
3222+
@Test(expected = JSONException.class)
3223+
public void jsonObjectClearMethodTest() {
3224+
//Adds random stuff to the JSONObject
3225+
JSONObject jsonObject = new JSONObject();
3226+
jsonObject.put("key1", 123);
3227+
jsonObject.put("key2", "456");
3228+
jsonObject.put("key3", new JSONObject());
3229+
jsonObject.clear(); //Clears the JSONObject
3230+
assertTrue("expected jsonObject.length() == 0", jsonObject.length() == 0); //Check if its length is 0
3231+
jsonObject.getInt("key1"); //Should throws org.json.JSONException: JSONObject["asd"] not found
3232+
}
32113233
}

0 commit comments

Comments
 (0)