From 89f16ad0af9f7c1097a4336c8fda02afd4b87563 Mon Sep 17 00:00:00 2001 From: Scott Paffrath <33729384+spaffrath@users.noreply.github.com> Date: Fri, 5 Aug 2022 11:00:33 -0700 Subject: [PATCH 01/48] Issue 682 JSONString similarity --- src/main/java/org/json/JSONArray.java | 4 ++++ src/main/java/org/json/JSONObject.java | 4 ++++ .../java/org/json/junit/JSONArrayTest.java | 24 +++++++++++++++++++ .../java/org/json/junit/JSONObjectTest.java | 22 +++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/src/main/java/org/json/JSONArray.java b/src/main/java/org/json/JSONArray.java index 2b33e1d..7f09114 100644 --- a/src/main/java/org/json/JSONArray.java +++ b/src/main/java/org/json/JSONArray.java @@ -1386,6 +1386,10 @@ public class JSONArray implements Iterable { if (!JSONObject.isNumberSimilar((Number)valueThis, (Number)valueOther)) { return false; } + } else if (valueThis instanceof JSONString && valueOther instanceof JSONString) { + if (!((JSONString) valueThis).toJSONString().equals(((JSONString) valueOther).toJSONString())) { + return false; + } } else if (!valueThis.equals(valueOther)) { return false; } diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java index ea549e3..859b3e5 100644 --- a/src/main/java/org/json/JSONObject.java +++ b/src/main/java/org/json/JSONObject.java @@ -2142,6 +2142,10 @@ public class JSONObject { if (!isNumberSimilar((Number)valueThis, (Number)valueOther)) { return false; } + } else if (valueThis instanceof JSONString && valueOther instanceof JSONString) { + if (!((JSONString) valueThis).toJSONString().equals(((JSONString) valueOther).toJSONString())) { + return false; + } } else if (!valueThis.equals(valueOther)) { return false; } diff --git a/src/test/java/org/json/junit/JSONArrayTest.java b/src/test/java/org/json/junit/JSONArrayTest.java index 987891e..959954b 100644 --- a/src/test/java/org/json/junit/JSONArrayTest.java +++ b/src/test/java/org/json/junit/JSONArrayTest.java @@ -26,6 +26,7 @@ SOFTWARE. import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -49,7 +50,9 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONPointerException; +import org.json.JSONString; import org.json.JSONTokener; +import org.json.junit.data.MyJsonString; import org.junit.Test; import com.jayway.jsonpath.Configuration; @@ -1298,4 +1301,25 @@ public class JSONArrayTest { assertNotNull(json_input); fail("Excepected Exception."); } + + @Test + public void testIssue682SimilarityOfJSONString() { + JSONArray ja1 = new JSONArray() + .put(new MyJsonString()) + .put(2); + JSONArray ja2 = new JSONArray() + .put(new MyJsonString()) + .put(2); + assertTrue(ja1.similar(ja2)); + + JSONArray ja3 = new JSONArray() + .put(new JSONString() { + @Override + public String toJSONString() { + return "\"different value\""; + } + }) + .put(2); + assertFalse(ja1.similar(ja3)); + } } diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index 2ba58bf..d244f2f 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -57,6 +57,7 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONPointerException; +import org.json.JSONString; import org.json.JSONTokener; import org.json.XML; import org.json.junit.data.BrokenToString; @@ -3398,4 +3399,25 @@ public class JSONObjectTest { assertNotNull(json_input); fail("Excepected Exception."); } + + @Test + public void testIssue682SimilarityOfJSONString() { + JSONObject jo1 = new JSONObject() + .put("a", new MyJsonString()) + .put("b", 2); + JSONObject jo2 = new JSONObject() + .put("a", new MyJsonString()) + .put("b", 2); + assertTrue(jo1.similar(jo2)); + + JSONObject jo3 = new JSONObject() + .put("a", new JSONString() { + @Override + public String toJSONString() { + return "\"different value\""; + } + }) + .put("b", 2); + assertFalse(jo1.similar(jo3)); + } } -- Gitee From b4036e6a8e0b10fbec9d59a52e4f64508a3b3870 Mon Sep 17 00:00:00 2001 From: stleary Date: Sat, 13 Aug 2022 12:50:10 -0500 Subject: [PATCH 02/48] pipeline-fix-1 remove v7 build from pipeline --- .github/workflows/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index ce91174..08352a0 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -42,7 +42,7 @@ jobs: strategy: matrix: # build against supported Java LTS versions: - java: [ 1.7, 8, 11 ] + java: [ 8, 11 ] name: Java ${{ matrix.java }} steps: - uses: actions/checkout@v2 -- Gitee From e0534b3ec75fb6dbaddb3c16b0fd6c0aabd6d6ee Mon Sep 17 00:00:00 2001 From: stleary Date: Sat, 20 Aug 2022 16:14:34 -0500 Subject: [PATCH 03/48] initial attempt to test for inconsistent map types in JSONObject --- src/main/java/org/json/JSONObject.java | 4 + .../java/org/json/junit/JSONArrayTest.java | 78 ++++- .../java/org/json/junit/JSONObjectTest.java | 331 ++++++++++++------ src/test/java/org/json/junit/Util.java | 103 +++++- 4 files changed, 393 insertions(+), 123 deletions(-) diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java index ea549e3..782f8a4 100644 --- a/src/main/java/org/json/JSONObject.java +++ b/src/main/java/org/json/JSONObject.java @@ -166,6 +166,10 @@ public class JSONObject { */ private final Map map; + public Class getMapType() { + return map.getClass(); + } + /** * It is sometimes more convenient and less ambiguous to have a * NULL object than to use Java's null value. diff --git a/src/test/java/org/json/junit/JSONArrayTest.java b/src/test/java/org/json/junit/JSONArrayTest.java index 987891e..946f407 100644 --- a/src/test/java/org/json/junit/JSONArrayTest.java +++ b/src/test/java/org/json/junit/JSONArrayTest.java @@ -237,6 +237,10 @@ public class JSONArrayTest { assertTrue( "The RAW Collection should give me the same as the Typed Collection", expected.similar(jaObj)); + Util.checkJSONArrayMaps(expected); + Util.checkJSONArrayMaps(jaObj); + Util.checkJSONArrayMaps(jaRaw); + Util.checkJSONArrayMaps(jaInt); } /** @@ -275,6 +279,7 @@ public class JSONArrayTest { myList.get(i), jsonArray.getString(myInts.length + i)); } + Util.checkJSONArrayMaps(jsonArray); } /** @@ -308,6 +313,9 @@ public class JSONArrayTest { assertTrue( "The RAW Collection should give me the same as the Typed Collection", expected.similar(jaInt)); + Util.checkJSONArraysMaps(new ArrayList(Arrays.asList( + jaRaw, jaObj, jaInt + ))); } @@ -351,6 +359,9 @@ public class JSONArrayTest { assertTrue( "The RAW Collection should give me the same as the Typed Collection", expected.similar(jaObjObj)); + Util.checkJSONArraysMaps(new ArrayList(Arrays.asList( + expected, jaRaw, jaStrObj, jaStrInt, jaObjObj + ))); } /** @@ -397,6 +408,7 @@ public class JSONArrayTest { new Long(-1).equals(jsonArray.getLong(12))); assertTrue("Array value null", jsonArray.isNull(-1)); + Util.checkJSONArrayMaps(jsonArray); } /** @@ -463,6 +475,7 @@ public class JSONArrayTest { assertEquals("Expected an exception message", "JSONArray[5] is not a String (class java.math.BigDecimal : 0.002345).",e.getMessage()); } + Util.checkJSONArrayMaps(jsonArray); } /** @@ -499,6 +512,7 @@ public class JSONArrayTest { assertTrue("expected value4", "value4".equals(jsonArray.query("/10/key4"))); assertTrue("expected 0", Integer.valueOf(0).equals(jsonArray.query("/11"))); assertTrue("expected \"-1\"", "-1".equals(jsonArray.query("/12"))); + Util.checkJSONArrayMaps(jsonArray); } /** @@ -512,6 +526,9 @@ public class JSONArrayTest { assertTrue("expected JSONArray length 13. instead found "+jsonArray.length(), jsonArray.length() == 13); JSONArray nestedJsonArray = jsonArray.getJSONArray(9); assertTrue("expected JSONArray length 1", nestedJsonArray.length() == 1); + Util.checkJSONArraysMaps(new ArrayList(Arrays.asList( + jsonArray, nestedJsonArray + ))); } /** @@ -587,6 +604,10 @@ public class JSONArrayTest { "hello".equals(jsonArray.optString(4))); assertTrue("Array opt string default implicit", "".equals(jsonArray.optString(-1))); + Util.checkJSONArraysMaps(new ArrayList(Arrays.asList( + jsonArray, nestedJsonArray + ))); + Util.checkJSONObjectMaps(nestedJsonObject); } /** @@ -601,7 +622,9 @@ public class JSONArrayTest { assertTrue("unexpected optLong value",ja.optLong(0,0)==123); assertTrue("unexpected optDouble value",ja.optDouble(0,0.0)==123.0); assertTrue("unexpected optBigInteger value",ja.optBigInteger(0,BigInteger.ZERO).compareTo(new BigInteger("123"))==0); - assertTrue("unexpected optBigDecimal value",ja.optBigDecimal(0,BigDecimal.ZERO).compareTo(new BigDecimal("123"))==0); } + assertTrue("unexpected optBigDecimal value",ja.optBigDecimal(0,BigDecimal.ZERO).compareTo(new BigDecimal("123"))==0); + Util.checkJSONArrayMaps(ja); + } /** * Exercise the JSONArray.put(value) method with various parameters @@ -677,6 +700,8 @@ public class JSONArrayTest { assertTrue("expected 2 items in [9]", ((List)(JsonPath.read(doc, "$[9]"))).size() == 2); assertTrue("expected 1", Integer.valueOf(1).equals(jsonArray.query("/9/0"))); assertTrue("expected 2", Integer.valueOf(2).equals(jsonArray.query("/9/1"))); + Util.checkJSONArrayMaps(jsonArray); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -756,6 +781,8 @@ public class JSONArrayTest { assertTrue("expected 2", Integer.valueOf(2).equals(jsonArray.query("/9/1"))); assertTrue("expected 1 item in [10]", ((Map)(JsonPath.read(doc, "$[10]"))).size() == 1); assertTrue("expected v1", "v1".equals(jsonArray.query("/10/k1"))); + Util.checkJSONObjectMaps(jsonObject); + Util.checkJSONArrayMaps(jsonArray); } /** @@ -772,6 +799,7 @@ public class JSONArrayTest { jsonArray.remove(0); assertTrue("array should be empty", null == jsonArray.remove(5)); assertTrue("jsonArray should be empty", jsonArray.isEmpty()); + Util.checkJSONArrayMaps(jsonArray); } /** @@ -811,6 +839,12 @@ public class JSONArrayTest { otherJsonArray.put("world"); assertTrue("arrays values differ", !jsonArray.similar(otherJsonArray)); + Util.checkJSONArraysMaps(new ArrayList(Arrays.asList( + jsonArray, otherJsonArray + ))); + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jsonObject, otherJsonObject + ))); } /** @@ -894,6 +928,7 @@ public class JSONArrayTest { for (String s : jsonArray4Strs) { list.contains(s); } + Util.checkJSONArrayMaps(jsonArray); } /** @@ -905,6 +940,9 @@ public class JSONArrayTest { JSONArray jsonArray = new JSONArray(); assertTrue("toJSONObject should return null", null == jsonArray.toJSONObject(names)); + Util.checkJSONArraysMaps(new ArrayList(Arrays.asList( + names, jsonArray + ))); } /** @@ -926,6 +964,7 @@ public class JSONArrayTest { assertTrue("expected 5", Integer.valueOf(5).equals(jsonArray.query("/4"))); assertTrue("expected 6", Integer.valueOf(6).equals(jsonArray.query("/5"))); assertTrue("expected 7", Integer.valueOf(7).equals(jsonArray.query("/6"))); + Util.checkJSONArrayMaps(jsonArray); } /** @@ -968,6 +1007,10 @@ public class JSONArrayTest { assertTrue("Array value string long", new Long(-1).equals(Long.parseLong((String) it.next()))); assertTrue("should be at end of array", !it.hasNext()); + Util.checkJSONArraysMaps(new ArrayList(Arrays.asList( + jsonArray, nestedJsonArray + ))); + Util.checkJSONObjectMaps(nestedJsonObject); } @Test(expected = JSONPointerException.class) @@ -1010,6 +1053,7 @@ public class JSONArrayTest { } finally { stringWriter.close(); } + Util.checkJSONArrayMaps(jsonArray); } /** @@ -1069,9 +1113,11 @@ public class JSONArrayTest { && actualStr.contains("\"key2\": false") && actualStr.contains("\"key3\": 3.14") ); + Util.checkJSONArrayMaps(finalArray); } finally { stringWriter.close(); } + Util.checkJSONArrayMaps(jsonArray); } /** @@ -1182,6 +1228,7 @@ public class JSONArrayTest { // assert that the new list is mutable assertTrue("Removing an entry should succeed", list.remove(2) != null); assertTrue("List should have 2 elements", list.size() == 2); + Util.checkJSONArrayMaps(jsonArray); } /** @@ -1190,13 +1237,13 @@ public class JSONArrayTest { */ @Test public void testJSONArrayInt() { - assertNotNull(new JSONArray(0)); - assertNotNull(new JSONArray(5)); - // Check Size -> Even though the capacity of the JSONArray can be specified using a positive - // integer but the length of JSONArray always reflects upon the items added into it. - assertEquals(0l, new JSONArray(10).length()); + assertNotNull(new JSONArray(0)); + assertNotNull(new JSONArray(5)); + // Check Size -> Even though the capacity of the JSONArray can be specified using a positive + // integer but the length of JSONArray always reflects upon the items added into it. + // assertEquals(0l, new JSONArray(10).length()); try { - assertNotNull("Should throw an exception", new JSONArray(-1)); + assertNotNull("Should throw an exception", new JSONArray(-1)); } catch (JSONException e) { assertEquals("Expected an exception message", "JSONArray initial capacity cannot be negative.", @@ -1223,8 +1270,8 @@ public class JSONArrayTest { ((Collection)o).add("test"); ((Collection)o).add(false); try { - a = new JSONArray(o); - assertNull("Should error", a); + JSONArray a0 = new JSONArray(o); + assertNull("Should error", a0); } catch (JSONException ex) { } @@ -1232,10 +1279,11 @@ public class JSONArrayTest { // this is required for backwards compatibility o = a; try { - a = new JSONArray(o); - assertNull("Should error", a); + JSONArray a1 = new JSONArray(o); + assertNull("Should error", a1); } catch (JSONException ex) { } + Util.checkJSONArrayMaps(a); } /** @@ -1252,6 +1300,9 @@ public class JSONArrayTest { for(int i = 0; i < a1.length(); i++) { assertEquals("index " + i + " are equal", a1.get(i), a2.get(i)); } + Util.checkJSONArraysMaps(new ArrayList(Arrays.asList( + a1, a2 + ))); } /** @@ -1269,6 +1320,9 @@ public class JSONArrayTest { for(int i = 0; i < a1.length(); i++) { assertEquals("index " + i + " are equal", a1.get(i), a2.get(i)); } + Util.checkJSONArraysMaps(new ArrayList(Arrays.asList( + a1, a2 + ))); } /** @@ -1284,6 +1338,7 @@ public class JSONArrayTest { 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 + Util.checkJSONArrayMaps(jsonArray); } /** @@ -1297,5 +1352,6 @@ public class JSONArrayTest { JSONArray json_input = new JSONArray(tokener); assertNotNull(json_input); fail("Excepected Exception."); + Util.checkJSONArrayMaps(json_input); } } diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index 2ba58bf..3681148 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -41,14 +41,7 @@ import java.io.StringReader; import java.io.StringWriter; import java.math.BigDecimal; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; @@ -80,6 +73,7 @@ import org.json.junit.data.Singleton; import org.json.junit.data.SingletonEnum; import org.json.junit.data.WeirdList; import org.junit.Test; +import org.json.junit.Util; import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.JsonPath; @@ -140,8 +134,12 @@ public class JSONObjectTest { JSONObject first = new JSONObject("{\"a\": 1, \"b\": 2, \"c\": 3}"); JSONObject second = new JSONObject("{\"a\": 1, \"b\": 2.0, \"c\": 4}"); assertFalse("first-second should eval to false", first.similar(second)); + List jsonObjects = new ArrayList( + Arrays.asList(obj1, obj2, obj3, obj4, obj5) + ); + Util.checkJSONObjectsMaps(jsonObjects); } - + @Test public void timeNumberParsing() { // test data to use @@ -214,7 +212,9 @@ public class JSONObjectTest { */ @Test(expected=NullPointerException.class) public void jsonObjectByNullBean() { - assertNull("Expected an exception",new JSONObject((MyBean)null)); + JSONObject jsonObject = new JSONObject((MyBean)null); + assertNull("Expected an exception", jsonObject); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -232,6 +232,7 @@ public class JSONObjectTest { assertTrue("expected value1", textStr.contains("\"value1\"")); assertTrue("expected key2", textStr.contains("\"key2\"")); assertTrue("expected 42", textStr.contains("42")); + Util.checkJSONObjectMaps(jsonObject); } @Test @@ -252,6 +253,7 @@ public class JSONObjectTest { final String actualString = json.optString("key"); assert str.equals(actualString) : "Incorrect key value. Got " + actualString + " expected " + str; + Util.checkJSONObjectMaps(json); } /** @@ -261,6 +263,7 @@ public class JSONObjectTest { public void emptyJsonObject() { JSONObject jsonObject = new JSONObject(); assertTrue("jsonObject should be empty", jsonObject.isEmpty()); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -291,6 +294,7 @@ public class JSONObjectTest { assertTrue("expected \"nullKey\":null", JSONObject.NULL.equals(jsonObjectByName.query("/nullKey"))); assertTrue("expected \"stringKey\":\"hello world!\"", "hello world!".equals(jsonObjectByName.query("/stringKey"))); assertTrue("expected \"doubleKey\":-23.45e67", new BigDecimal("-23.45e67").equals(jsonObjectByName.query("/doubleKey"))); + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList(jsonObject, jsonObjectByName))); } /** @@ -304,6 +308,7 @@ public class JSONObjectTest { Map map = null; JSONObject jsonObject = new JSONObject(map); assertTrue("jsonObject should be empty", jsonObject.isEmpty()); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -329,6 +334,7 @@ public class JSONObjectTest { assertTrue("expected \"stringKey\":\"hello world!\"", "hello world!".equals(jsonObject.query("/stringKey"))); assertTrue("expected \"escapeStringKey\":\"h\be\tllo w\u1234orld!\"", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/escapeStringKey"))); assertTrue("expected \"doubleKey\":-23.45e67", Double.valueOf("-23.45e67").equals(jsonObject.query("/doubleKey"))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -367,6 +373,9 @@ public class JSONObjectTest { assertTrue( "The RAW Collection should give me the same as the Typed Collection", expected.similar(jaObjObj)); + Util.checkJSONObjectsMaps(new ArrayList( + Arrays.asList(jaRaw, jaStrObj, jaStrInt, jaObjObj)) + ); } /** @@ -384,8 +393,8 @@ public class JSONObjectTest { * The only getter is getNumber (key=number), whose return value is * BigDecimal(42). */ - JSONObject jsonObject = new JSONObject(new MyNumberContainer()); - String actual = jsonObject.toString(); + JSONObject jsonObject0 = new JSONObject(new MyNumberContainer()); + String actual = jsonObject0.toString(); String expected = "{\"myNumber\":{\"number\":42}}"; assertEquals("Equal", expected , actual); @@ -397,9 +406,9 @@ public class JSONObjectTest { * The MyNumber.toString() method is responsible for * returning a reasonable value: the string '42'. */ - jsonObject = new JSONObject(); - jsonObject.put("myNumber", new MyNumber()); - actual = jsonObject.toString(); + JSONObject jsonObject1 = new JSONObject(); + jsonObject1.put("myNumber", new MyNumber()); + actual = jsonObject1.toString(); expected = "{\"myNumber\":42}"; assertEquals("Equal", expected , actual); @@ -411,8 +420,8 @@ public class JSONObjectTest { * wrap() inserts the value as a string. That is why 42 comes back * wrapped in quotes. */ - jsonObject = new JSONObject(Collections.singletonMap("myNumber", new AtomicInteger(42))); - actual = jsonObject.toString(); + JSONObject jsonObject2 = new JSONObject(Collections.singletonMap("myNumber", new AtomicInteger(42))); + actual = jsonObject2.toString(); expected = "{\"myNumber\":\"42\"}"; assertEquals("Equal", expected , actual); @@ -422,9 +431,9 @@ public class JSONObjectTest { * AtomicInteger is recognized as a Number, and converted via * numberToString() into the unquoted string '42'. */ - jsonObject = new JSONObject(); - jsonObject.put("myNumber", new AtomicInteger(42)); - actual = jsonObject.toString(); + JSONObject jsonObject3 = new JSONObject(); + jsonObject3.put("myNumber", new AtomicInteger(42)); + actual = jsonObject3.toString(); expected = "{\"myNumber\":42}"; assertEquals("Equal", expected , actual); @@ -435,11 +444,11 @@ public class JSONObjectTest { * bean and inserted into a contained JSONObject. It has 2 getters, * for numerator and denominator. */ - jsonObject = new JSONObject(Collections.singletonMap("myNumber", new Fraction(4,2))); - assertEquals(1, jsonObject.length()); - assertEquals(2, ((JSONObject)(jsonObject.get("myNumber"))).length()); - assertEquals("Numerator", BigInteger.valueOf(4) , jsonObject.query("/myNumber/numerator")); - assertEquals("Denominator", BigInteger.valueOf(2) , jsonObject.query("/myNumber/denominator")); + JSONObject jsonObject4 = new JSONObject(Collections.singletonMap("myNumber", new Fraction(4,2))); + assertEquals(1, jsonObject4.length()); + assertEquals(2, ((JSONObject)(jsonObject4.get("myNumber"))).length()); + assertEquals("Numerator", BigInteger.valueOf(4) , jsonObject4.query("/myNumber/numerator")); + assertEquals("Denominator", BigInteger.valueOf(2) , jsonObject4.query("/myNumber/denominator")); /** * JSONObject.put() inserts the Fraction directly into the @@ -449,11 +458,15 @@ public class JSONObjectTest { * BigDecimal sanity check fails, so writeValue() defaults * to returning a safe JSON quoted string. Pretty slick! */ - jsonObject = new JSONObject(); - jsonObject.put("myNumber", new Fraction(4,2)); - actual = jsonObject.toString(); + JSONObject jsonObject5 = new JSONObject(); + jsonObject5.put("myNumber", new Fraction(4,2)); + actual = jsonObject5.toString(); expected = "{\"myNumber\":\"4/2\"}"; // valid JSON, bug fixed assertEquals("Equal", expected , actual); + + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jsonObject0, jsonObject1, jsonObject2, jsonObject3, jsonObject4, jsonObject5 + ))); } /** @@ -488,6 +501,10 @@ public class JSONObjectTest { assertTrue( "The RAW Collection should give me the same as the Typed Collection", expected.similar(jaInt)); + + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jaRaw, jaObj, jaInt + ))); } @@ -531,6 +548,10 @@ public class JSONObjectTest { assertTrue( "The RAW Collection should give me the same as the Typed Collection", expected.similar(jaObjObj)); + + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jaRaw, jaStrObj, jaStrInt, jaStrObj + ))); } @@ -553,6 +574,7 @@ public class JSONObjectTest { assertTrue("expected 2 top level items", ((Map)(JsonPath.read(doc, "$"))).size() == 2); assertTrue("expected 0 key1 items", ((Map)(JsonPath.read(doc, "$.key1"))).size() == 0); assertTrue("expected \"key2\":java.lang.Exception","java.lang.Exception".equals(jsonObject.query("/key2"))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -580,6 +602,7 @@ public class JSONObjectTest { assertTrue("expected \"escapeStringKey\":\"h\be\tllo w\u1234orld!\"", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/escapeStringKey"))); assertTrue("expected \"intKey\":42", Long.valueOf("42").equals(jsonObject.query("/intKey"))); assertTrue("expected \"doubleKey\":-23.45e67", Double.valueOf("-23.45e67").equals(jsonObject.query("/doubleKey"))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -620,6 +643,7 @@ public class JSONObjectTest { assertTrue("expected 2 callbacks items", ((List)(JsonPath.read(doc, "$.callbacks"))).size() == 2); assertTrue("expected 0 handler items", ((Map)(JsonPath.read(doc, "$.callbacks[0].handler"))).size() == 0); assertTrue("expected 0 callbacks[1] items", ((Map)(JsonPath.read(doc, "$.callbacks[1]"))).size() == 0); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -655,6 +679,7 @@ public class JSONObjectTest { // InterfaceField replaces someFloat property name via user-defined annotation assertTrue("Overridden String field name (InterfaceField) should have been found", jsonObject.has("InterfaceField")); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -705,6 +730,7 @@ public class JSONObjectTest { // property name able was replaced by Getable via user-defined annotation assertTrue("Overridden boolean field name (Getable) should have been found", jsonObject.has("Getable")); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -725,6 +751,7 @@ public class JSONObjectTest { assertTrue("expected 2 top level items", ((Map)(JsonPath.read(doc, "$"))).size() == 2); assertTrue("expected \"publicString\":\"abc\"", "abc".equals(jsonObject.query("/publicString"))); assertTrue("expected \"publicInt\":42", Integer.valueOf(42).equals(jsonObject.query("/publicInt"))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -746,6 +773,7 @@ public class JSONObjectTest { assertTrue("expected 2 farewells items", ((Map)(JsonPath.read(doc, "$.farewells"))).size() == 2); assertTrue("expected \"later\":\"Later, \"", "Later, ".equals(jsonObject.query("/farewells/later"))); assertTrue("expected \"world\":\"World!\"", "Alligator!".equals(jsonObject.query("/farewells/gator"))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -778,6 +806,7 @@ public class JSONObjectTest { assertTrue("expected h\be\tllo w\u1234orld!", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/myArray/3"))); assertTrue("expected 42", Integer.valueOf(42).equals(jsonObject.query("/myArray/4"))); assertTrue("expected -23.45e7", Double.valueOf(-23.45e7).equals(jsonObject.query("/myArray/5"))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -809,6 +838,7 @@ public class JSONObjectTest { assertTrue("expected h\be\tllo w\u1234orld!", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/myArray/3"))); assertTrue("expected 42", Integer.valueOf(42).equals(jsonObject.query("/myArray/4"))); assertTrue("expected -23.45e7", Double.valueOf(-23.45e7).equals(jsonObject.query("/myArray/5"))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -944,6 +974,7 @@ public class JSONObjectTest { JSONObject jsonObjectInner = jsonObject.getJSONObject("objectKey"); assertTrue("objectKey should be JSONObject", jsonObjectInner.get("myKey").equals("myVal")); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -1006,6 +1037,7 @@ public class JSONObjectTest { obj = jsonObject.get( "largeExponent" ); assertTrue("largeExponent should evaluate as a BigDecimal", new BigDecimal("-23.45e2327").equals(obj)); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -1054,6 +1086,7 @@ public class JSONObjectTest { jsonObject.get("floatIdentifier").equals(Double.valueOf(0.1))); assertTrue("doubleIdentifier currently evaluates to double 0.1", jsonObject.get("doubleIdentifier").equals(Double.valueOf(0.1))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -1205,6 +1238,7 @@ public class JSONObjectTest { "JSONObject[\"stringKey\"] is not a JSONObject (class java.lang.String : hello world!).", e.getMessage()); } + Util.checkJSONObjectMaps(jsonObject); } /** @@ -1232,6 +1266,7 @@ public class JSONObjectTest { assertTrue("3.0 can still be interpreted as a double", deserialized.getDouble(key30) == 3.0); assertTrue("3.1 remains a double", deserialized.getDouble(key31) == 3.1); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -1247,9 +1282,9 @@ public class JSONObjectTest { * value is stored. This should be fixed. */ BigInteger bigInteger = new BigInteger("123456789012345678901234567890"); - JSONObject jsonObject = new JSONObject(bigInteger); - Object obj = jsonObject.get("lowestSetBit"); - assertTrue("JSONObject only has 1 value", jsonObject.length() == 1); + JSONObject jsonObject0 = new JSONObject(bigInteger); + Object obj = jsonObject0.get("lowestSetBit"); + assertTrue("JSONObject only has 1 value", jsonObject0.length() == 1); assertTrue("JSONObject parses BigInteger as the Integer lowestBitSet", obj instanceof Integer); assertTrue("this bigInteger lowestBitSet happens to be 1", @@ -1262,57 +1297,57 @@ public class JSONObjectTest { */ BigDecimal bigDecimal = new BigDecimal( "123456789012345678901234567890.12345678901234567890123456789"); - jsonObject = new JSONObject(bigDecimal); - assertTrue("large bigDecimal is not stored", jsonObject.isEmpty()); + JSONObject jsonObject1 = new JSONObject(bigDecimal); + assertTrue("large bigDecimal is not stored", jsonObject1.isEmpty()); /** * JSONObject put(String, Object) method stores and serializes * bigInt and bigDec correctly. Nothing needs to change. */ - jsonObject = new JSONObject(); - jsonObject.put("bigInt", bigInteger); + JSONObject jsonObject2 = new JSONObject(); + jsonObject2.put("bigInt", bigInteger); assertTrue("jsonObject.put() handles bigInt correctly", - jsonObject.get("bigInt").equals(bigInteger)); + jsonObject2.get("bigInt").equals(bigInteger)); assertTrue("jsonObject.getBigInteger() handles bigInt correctly", - jsonObject.getBigInteger("bigInt").equals(bigInteger)); + jsonObject2.getBigInteger("bigInt").equals(bigInteger)); assertTrue("jsonObject.optBigInteger() handles bigInt correctly", - jsonObject.optBigInteger("bigInt", BigInteger.ONE).equals(bigInteger)); + jsonObject2.optBigInteger("bigInt", BigInteger.ONE).equals(bigInteger)); assertTrue("jsonObject serializes bigInt correctly", - jsonObject.toString().equals("{\"bigInt\":123456789012345678901234567890}")); + jsonObject2.toString().equals("{\"bigInt\":123456789012345678901234567890}")); assertTrue("BigInteger as BigDecimal", - jsonObject.getBigDecimal("bigInt").equals(new BigDecimal(bigInteger))); + jsonObject2.getBigDecimal("bigInt").equals(new BigDecimal(bigInteger))); - jsonObject = new JSONObject(); - jsonObject.put("bigDec", bigDecimal); + JSONObject jsonObject3 = new JSONObject(); + jsonObject3.put("bigDec", bigDecimal); assertTrue("jsonObject.put() handles bigDec correctly", - jsonObject.get("bigDec").equals(bigDecimal)); + jsonObject3.get("bigDec").equals(bigDecimal)); assertTrue("jsonObject.getBigDecimal() handles bigDec correctly", - jsonObject.getBigDecimal("bigDec").equals(bigDecimal)); + jsonObject3.getBigDecimal("bigDec").equals(bigDecimal)); assertTrue("jsonObject.optBigDecimal() handles bigDec correctly", - jsonObject.optBigDecimal("bigDec", BigDecimal.ONE).equals(bigDecimal)); + jsonObject3.optBigDecimal("bigDec", BigDecimal.ONE).equals(bigDecimal)); assertTrue("jsonObject serializes bigDec correctly", - jsonObject.toString().equals( + jsonObject3.toString().equals( "{\"bigDec\":123456789012345678901234567890.12345678901234567890123456789}")); assertTrue("BigDecimal as BigInteger", - jsonObject.getBigInteger("bigDec").equals(bigDecimal.toBigInteger())); + jsonObject3.getBigInteger("bigDec").equals(bigDecimal.toBigInteger())); /** * exercise some exceptions */ try { // bigInt key does not exist - jsonObject.getBigDecimal("bigInt"); + jsonObject3.getBigDecimal("bigInt"); fail("expected an exeption"); } catch (JSONException ignored) {} - obj = jsonObject.optBigDecimal("bigInt", BigDecimal.ONE); + obj = jsonObject3.optBigDecimal("bigInt", BigDecimal.ONE); assertTrue("expected BigDecimal", obj.equals(BigDecimal.ONE)); - jsonObject.put("stringKey", "abc"); + jsonObject3.put("stringKey", "abc"); try { - jsonObject.getBigDecimal("stringKey"); + jsonObject3.getBigDecimal("stringKey"); fail("expected an exeption"); } catch (JSONException ignored) {} - obj = jsonObject.optBigInteger("bigDec", BigInteger.ONE); + obj = jsonObject3.optBigInteger("bigDec", BigInteger.ONE); assertTrue("expected BigInteger", obj instanceof BigInteger); assertEquals(bigDecimal.toBigInteger(), obj); @@ -1345,79 +1380,79 @@ public class JSONObjectTest { // bigInt map ctor Map map = new HashMap(); map.put("bigInt", bigInteger); - jsonObject = new JSONObject(map); - String actualFromMapStr = jsonObject.toString(); + JSONObject jsonObject4 = new JSONObject(map); + String actualFromMapStr = jsonObject4.toString(); assertTrue("bigInt in map (or array or bean) is a string", actualFromMapStr.equals( "{\"bigInt\":123456789012345678901234567890}")); // bigInt put - jsonObject = new JSONObject(); - jsonObject.put("bigInt", bigInteger); - String actualFromPutStr = jsonObject.toString(); + JSONObject jsonObject5 = new JSONObject(); + jsonObject5.put("bigInt", bigInteger); + String actualFromPutStr = jsonObject5.toString(); assertTrue("bigInt from put is a number", actualFromPutStr.equals( "{\"bigInt\":123456789012345678901234567890}")); // bigDec map ctor map = new HashMap(); map.put("bigDec", bigDecimal); - jsonObject = new JSONObject(map); - actualFromMapStr = jsonObject.toString(); + JSONObject jsonObject6 = new JSONObject(map); + actualFromMapStr = jsonObject6.toString(); assertTrue("bigDec in map (or array or bean) is a bigDec", actualFromMapStr.equals( "{\"bigDec\":123456789012345678901234567890.12345678901234567890123456789}")); // bigDec put - jsonObject = new JSONObject(); - jsonObject.put("bigDec", bigDecimal); - actualFromPutStr = jsonObject.toString(); + JSONObject jsonObject7 = new JSONObject(); + jsonObject7.put("bigDec", bigDecimal); + actualFromPutStr = jsonObject7.toString(); assertTrue("bigDec from put is a number", actualFromPutStr.equals( "{\"bigDec\":123456789012345678901234567890.12345678901234567890123456789}")); // bigInt,bigDec put - JSONArray jsonArray = new JSONArray(); - jsonArray.put(bigInteger); - jsonArray.put(bigDecimal); - actualFromPutStr = jsonArray.toString(); + JSONArray jsonArray0 = new JSONArray(); + jsonArray0.put(bigInteger); + jsonArray0.put(bigDecimal); + actualFromPutStr = jsonArray0.toString(); assertTrue("bigInt, bigDec from put is a number", actualFromPutStr.equals( "[123456789012345678901234567890,123456789012345678901234567890.12345678901234567890123456789]")); - assertTrue("getBigInt is bigInt", jsonArray.getBigInteger(0).equals(bigInteger)); - assertTrue("getBigDec is bigDec", jsonArray.getBigDecimal(1).equals(bigDecimal)); - assertTrue("optBigInt is bigInt", jsonArray.optBigInteger(0, BigInteger.ONE).equals(bigInteger)); - assertTrue("optBigDec is bigDec", jsonArray.optBigDecimal(1, BigDecimal.ONE).equals(bigDecimal)); - jsonArray.put(Boolean.TRUE); + assertTrue("getBigInt is bigInt", jsonArray0.getBigInteger(0).equals(bigInteger)); + assertTrue("getBigDec is bigDec", jsonArray0.getBigDecimal(1).equals(bigDecimal)); + assertTrue("optBigInt is bigInt", jsonArray0.optBigInteger(0, BigInteger.ONE).equals(bigInteger)); + assertTrue("optBigDec is bigDec", jsonArray0.optBigDecimal(1, BigDecimal.ONE).equals(bigDecimal)); + jsonArray0.put(Boolean.TRUE); try { - jsonArray.getBigInteger(2); + jsonArray0.getBigInteger(2); fail("should not be able to get big int"); } catch (Exception ignored) {} try { - jsonArray.getBigDecimal(2); + jsonArray0.getBigDecimal(2); fail("should not be able to get big dec"); } catch (Exception ignored) {} - assertTrue("optBigInt is default", jsonArray.optBigInteger(2, BigInteger.ONE).equals(BigInteger.ONE)); - assertTrue("optBigDec is default", jsonArray.optBigDecimal(2, BigDecimal.ONE).equals(BigDecimal.ONE)); + assertTrue("optBigInt is default", jsonArray0.optBigInteger(2, BigInteger.ONE).equals(BigInteger.ONE)); + assertTrue("optBigDec is default", jsonArray0.optBigDecimal(2, BigDecimal.ONE).equals(BigDecimal.ONE)); // bigInt,bigDec list ctor List list = new ArrayList(); list.add(bigInteger); list.add(bigDecimal); - jsonArray = new JSONArray(list); - String actualFromListStr = jsonArray.toString(); + JSONArray jsonArray1 = new JSONArray(list); + String actualFromListStr = jsonArray1.toString(); assertTrue("bigInt, bigDec in list is a bigInt, bigDec", actualFromListStr.equals( "[123456789012345678901234567890,123456789012345678901234567890.12345678901234567890123456789]")); // bigInt bean ctor MyBigNumberBean myBigNumberBean = mock(MyBigNumberBean.class); when(myBigNumberBean.getBigInteger()).thenReturn(new BigInteger("123456789012345678901234567890")); - jsonObject = new JSONObject(myBigNumberBean); - String actualFromBeanStr = jsonObject.toString(); + JSONObject jsonObject8 = new JSONObject(myBigNumberBean); + String actualFromBeanStr = jsonObject8.toString(); // can't do a full string compare because mockery adds an extra key/value assertTrue("bigInt from bean ctor is a bigInt", actualFromBeanStr.contains("123456789012345678901234567890")); // bigDec bean ctor myBigNumberBean = mock(MyBigNumberBean.class); when(myBigNumberBean.getBigDecimal()).thenReturn(new BigDecimal("123456789012345678901234567890.12345678901234567890123456789")); - jsonObject = new JSONObject(myBigNumberBean); - actualFromBeanStr = jsonObject.toString(); + jsonObject8 = new JSONObject(myBigNumberBean); + actualFromBeanStr = jsonObject8.toString(); // can't do a full string compare because mockery adds an extra key/value assertTrue("bigDec from bean ctor is a bigDec", actualFromBeanStr.contains("123456789012345678901234567890.12345678901234567890123456789")); @@ -1426,7 +1461,12 @@ public class JSONObjectTest { assertTrue("wrap() returns big num",obj.equals(bigInteger)); obj = JSONObject.wrap(bigDecimal); assertTrue("wrap() returns string",obj.equals(bigDecimal)); - + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jsonObject0, jsonObject1, jsonObject2, jsonObject3, jsonObject4, + jsonObject5, jsonObject6, jsonObject7, jsonObject8 + ))); + Util.checkJSONArrayMaps(jsonArray0, jsonObject0.getMapType()); + Util.checkJSONArrayMaps(jsonArray1, jsonObject0.getMapType()); } /** @@ -1438,7 +1478,6 @@ public class JSONObjectTest { */ @Test public void jsonObjectNames() { - JSONObject jsonObject; // getNames() from null JSONObject assertTrue("null names from null Object", @@ -1449,16 +1488,16 @@ public class JSONObjectTest { null == JSONObject.getNames(new MyJsonString())); // getNames from new JSONOjbect - jsonObject = new JSONObject(); - String [] names = JSONObject.getNames(jsonObject); + JSONObject jsonObject0 = new JSONObject(); + String [] names = JSONObject.getNames(jsonObject0); assertTrue("names should be null", names == null); // getNames() from empty JSONObject String emptyStr = "{}"; - jsonObject = new JSONObject(emptyStr); + JSONObject jsonObject1 = new JSONObject(emptyStr); assertTrue("empty JSONObject should have null names", - null == JSONObject.getNames(jsonObject)); + null == JSONObject.getNames(jsonObject1)); // getNames() from JSONObject String str = @@ -1467,13 +1506,13 @@ public class JSONObjectTest { "\"falseKey\":false,"+ "\"stringKey\":\"hello world!\","+ "}"; - jsonObject = new JSONObject(str); - names = JSONObject.getNames(jsonObject); - JSONArray jsonArray = new JSONArray(names); + JSONObject jsonObject2 = new JSONObject(str); + names = JSONObject.getNames(jsonObject2); + JSONArray jsonArray0 = new JSONArray(names); // validate JSON Object doc = Configuration.defaultConfiguration().jsonProvider() - .parse(jsonArray.toString()); + .parse(jsonArray0.toString()); List docList = JsonPath.read(doc, "$"); assertTrue("expected 3 items", docList.size() == 3); assertTrue( @@ -1494,9 +1533,9 @@ public class JSONObjectTest { names = JSONObject.getNames(myEnumField); // validate JSON - jsonArray = new JSONArray(names); + JSONArray jsonArray1 = new JSONArray(names); doc = Configuration.defaultConfiguration().jsonProvider() - .parse(jsonArray.toString()); + .parse(jsonArray1.toString()); docList = JsonPath.read(doc, "$"); assertTrue("expected 3 items", docList.size() == 3); assertTrue( @@ -1518,9 +1557,9 @@ public class JSONObjectTest { names = JSONObject.getNames(myPublicClass); // validate JSON - jsonArray = new JSONArray(names); + JSONArray jsonArray2 = new JSONArray(names); doc = Configuration.defaultConfiguration().jsonProvider() - .parse(jsonArray.toString()); + .parse(jsonArray2.toString()); docList = JsonPath.read(doc, "$"); assertTrue("expected 2 items", docList.size() == 2); assertTrue( @@ -1529,6 +1568,12 @@ public class JSONObjectTest { assertTrue( "expected to find publicInt", ((List) JsonPath.read(doc, "$[?(@=='publicInt')]")).size() == 1); + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jsonObject0, jsonObject1, jsonObject2 + ))); + Util.checkJSONArrayMaps(jsonArray0, jsonObject0.getMapType()); + Util.checkJSONArrayMaps(jsonArray1, jsonObject0.getMapType()); + Util.checkJSONArrayMaps(jsonArray2, jsonObject0.getMapType()); } /** @@ -1540,6 +1585,8 @@ public class JSONObjectTest { JSONObject jsonObject = new JSONObject(); JSONArray jsonArray = jsonObject.names(); assertTrue("jsonArray should be null", jsonArray == null); + Util.checkJSONObjectMaps(jsonObject); + Util.checkJSONArrayMaps(jsonArray, jsonObject.getMapType()); } /** @@ -1564,6 +1611,8 @@ public class JSONObjectTest { assertTrue("expected to find trueKey", ((List) JsonPath.read(doc, "$[?(@=='trueKey')]")).size() == 1); assertTrue("expected to find falseKey", ((List) JsonPath.read(doc, "$[?(@=='falseKey')]")).size() == 1); assertTrue("expected to find stringKey", ((List) JsonPath.read(doc, "$[?(@=='stringKey')]")).size() == 1); + Util.checkJSONObjectMaps(jsonObject); + Util.checkJSONArrayMaps(jsonArray, jsonObject.getMapType()); } /** @@ -1682,7 +1731,9 @@ public class JSONObjectTest { // this.put(key, new Float((Float) value + 1)); // Probably it would be better to deprecate the method and remove some day, while convenient processing the "payload" is not // really in the scope of a JSON-library (IMHO.) - + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jsonObject, inc + ))); } /** @@ -1780,6 +1831,12 @@ public class JSONObjectTest { JSONObject bCompareArrayJsonObject = new JSONObject(bCompareArrayStr); assertTrue("different nested JSONArrays should not be similar", !aCompareArrayJsonObject.similar(bCompareArrayJsonObject)); + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jsonObject, expectedJsonObject, aCompareValueJsonObject, + aCompareArrayJsonObject, aCompareObjectJsonObject, aCompareArrayJsonObject, + bCompareValueJsonObject, bCompareArrayJsonObject, bCompareObjectJsonObject, + bCompareArrayJsonObject + ))); } /** @@ -1815,6 +1872,7 @@ public class JSONObjectTest { assertTrue("expected myVal2", "myVal2".equals(jsonObject.query("/objectKey/myKey2"))); assertTrue("expected myVal3", "myVal3".equals(jsonObject.query("/objectKey/myKey3"))); assertTrue("expected myVal4", "myVal4".equals(jsonObject.query("/objectKey/myKey4"))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -1888,6 +1946,9 @@ public class JSONObjectTest { JSONObject jo = new JSONObject().put("TABLE", new JSONObject().put("yhoo", new JSONObject())); assertEquals("toString(2)","{\"TABLE\": {\"yhoo\": {}}}", jo.toString(2)); + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jsonObject, jo + ))); } /** @@ -1909,6 +1970,7 @@ public class JSONObjectTest { assertTrue("expected 1 top level item", ((Map)(JsonPath.read(doc, "$"))).size() == 1); assertTrue("expected 1 key item", ((Map)(JsonPath.read(doc, "$.key"))).size() == 1); assertTrue("expected def", "def".equals(jsonObject.query("/key/abc"))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -1931,6 +1993,7 @@ public class JSONObjectTest { assertTrue("expected 1 top level item", ((Map)(JsonPath.read(doc, "$"))).size() == 1); assertTrue("expected 1 key item", ((List)(JsonPath.read(doc, "$.key"))).size() == 1); assertTrue("expected abc", "abc".equals(jsonObject.query("/key/0"))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -1978,7 +2041,9 @@ public class JSONObjectTest { jsonArray.toString().equals(JSONObject.valueToString(collection))); Integer[] array = { new Integer(1), new Integer(2), new Integer(3) }; assertTrue("array valueToString() incorrect", - jsonArray.toString().equals(JSONObject.valueToString(array))); + jsonArray.toString().equals(JSONObject.valueToString(array))); + Util.checkJSONObjectMaps(jsonObject); + Util.checkJSONArrayMaps(jsonArray, jsonObject.getMapType()); } /** @@ -2082,6 +2147,11 @@ public class JSONObjectTest { assertTrue("expected val1", "val1".equals(mapJsonObject.query("/key1"))); assertTrue("expected val2", "val2".equals(mapJsonObject.query("/key2"))); assertTrue("expected val3", "val3".equals(mapJsonObject.query("/key3"))); + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jsonObject, mapJsonObject + ))); + Util.checkJSONArrayMaps(jsonArray, jsonObject.getMapType()); + Util.checkJSONArrayMaps(integerArrayJsonArray, jsonObject.getMapType()); } @@ -2096,6 +2166,7 @@ public class JSONObjectTest { try { JSONObject jo = new JSONObject(source); assertTrue("Expected "+charString+"("+i+") in the JSON Object but did not find it.",charString.equals(jo.getString("key"))); + Util.checkJSONObjectMaps(jo); } catch (JSONException ex) { assertTrue("Only \\0 (U+0000), \\n (U+000A), and \\r (U+000D) should cause an error. Instead "+charString+"("+i+") caused an error", i=='\0' || i=='\n' || i=='\r' @@ -2395,6 +2466,7 @@ public class JSONObjectTest { assertTrue("jsonObject should be empty", jsonObject.isEmpty()); jsonObject.putOnce(null, ""); assertTrue("jsonObject should be empty", jsonObject.isEmpty()); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -2430,6 +2502,7 @@ public class JSONObjectTest { 42l == jsonObject.optNumber("myKey", Long.valueOf(42)).longValue()); assertTrue("optString() should return default string", "hi".equals(jsonObject.optString("hiKey", "hi"))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -2466,6 +2539,7 @@ public class JSONObjectTest { 42l == jsonObject.optNumber("myKey", Long.valueOf(42)).longValue()); assertTrue("optString() should return default string", "hi".equals(jsonObject.optString("hiKey", "hi"))); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -2484,6 +2558,7 @@ public class JSONObjectTest { assertTrue("unexpected optBigDecimal value",jo.optBigDecimal("int",BigDecimal.ZERO).compareTo(new BigDecimal("123"))==0); assertTrue("unexpected optBigDecimal value",jo.optBigDecimal("int",BigDecimal.ZERO).compareTo(new BigDecimal("123"))==0); assertTrue("unexpected optNumber value",jo.optNumber("int",BigInteger.ZERO).longValue()==123l); + Util.checkJSONObjectMaps(jo); } /** @@ -2518,6 +2593,7 @@ public class JSONObjectTest { assertNotEquals((int)Double.parseDouble("19007199254740993.35481234487103587486413587843213584"), jo.optInt("largeNumberStr")); assertEquals(19007199254740992l, (long)Double.parseDouble("19007199254740993.35481234487103587486413587843213584")); assertEquals(2147483647, (int)Double.parseDouble("19007199254740993.35481234487103587486413587843213584")); + Util.checkJSONObjectMaps(jo); } /** @@ -2540,6 +2616,7 @@ public class JSONObjectTest { assertNull(jo.optBigDecimal("nullVal", null)); assertEquals(jo.optBigDecimal("float", null),jo.getBigDecimal("float")); assertEquals(jo.optBigDecimal("double", null),jo.getBigDecimal("double")); + Util.checkJSONObjectMaps(jo); } /** @@ -2560,6 +2637,7 @@ public class JSONObjectTest { assertEquals(new BigInteger("1234"),jo.optBigInteger("bigInteger", null)); assertEquals(new BigInteger("1234"),jo.optBigInteger("bigDecimal", null)); assertNull(jo.optBigDecimal("nullVal", null)); + Util.checkJSONObjectMaps(jo); } /** @@ -2577,8 +2655,9 @@ public class JSONObjectTest { JSONObject jsonObjectPutNull = new JSONObject(str); jsonObjectPutNull.put("myKey", (Object) null); assertTrue("jsonObject should be empty", jsonObjectPutNull.isEmpty()); - - + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jsonObjectRemove, jsonObjectPutNull + ))); } /** @@ -2663,6 +2742,7 @@ public class JSONObjectTest { } finally { stringWriter.close(); } + Util.checkJSONObjectMaps(jsonObject); } /** @@ -2745,7 +2825,7 @@ public class JSONObjectTest { writer.close(); } catch (Exception e) {} } - + Util.checkJSONObjectMaps(jsonObject); } @@ -2813,6 +2893,7 @@ public class JSONObjectTest { stringWriter.close(); } catch (Exception e) {} } + Util.checkJSONObjectMaps(jsonObject); } /** @@ -2855,6 +2936,7 @@ public class JSONObjectTest { JSONObject aJsonObject = new JSONObject(str); assertTrue("Same JSONObject should be equal to itself", aJsonObject.equals(aJsonObject)); + Util.checkJSONObjectMaps(aJsonObject); } /** @@ -2940,6 +3022,9 @@ public class JSONObjectTest { "null".equals(sJONull)); String sNull = XML.toString(jsonObjectNull); assertTrue("null should emit an empty string", "".equals(sNull)); + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jsonObjectJONull, jsonObjectNull + ))); } @Test(expected = JSONPointerException.class) @@ -3037,6 +3122,7 @@ public class JSONObjectTest { // assert that the new map is mutable assertTrue("Removing a key should succeed", map.remove("key3") != null); assertTrue("Map should have 2 elements", map.size() == 2); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -3061,6 +3147,9 @@ public class JSONObjectTest { // ensure our original jo hasn't changed. assertEquals(0, jo.get("someInt")); assertEquals(null, jo.opt("someString")); + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jo, jo2 + ))); } /** @@ -3085,6 +3174,9 @@ public class JSONObjectTest { // ensure our original jo hasn't changed. assertEquals(0, jo.get("someInt")); assertEquals(null, jo.opt("someString")); + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + jo, jo2 + ))); } /** @@ -3100,6 +3192,7 @@ public class JSONObjectTest { assertEquals("Expected the getter to only be called once", 1, bean.genericGetCounter); assertEquals(0, bean.genericSetCounter); + Util.checkJSONObjectMaps(jo); } /** @@ -3115,6 +3208,7 @@ public class JSONObjectTest { assertEquals("Expected the getter to only be called once", 1, bean.genericGetCounter); assertEquals(0, bean.genericSetCounter); + Util.checkJSONObjectMaps(jo); } /** @@ -3133,6 +3227,7 @@ public class JSONObjectTest { assertEquals("Expected 1 key to be mapped. Instead found: "+jo.keySet().toString(), 1, jo.length()); assertNotNull(jo.get("ALL")); + Util.checkJSONObjectMaps(jo); } /** @@ -3150,6 +3245,8 @@ public class JSONObjectTest { BigDecimal wantedValue = BigDecimal.valueOf(value); assertEquals(current, wantedValue); + Util.checkJSONObjectMaps(jsonObject); + Util.checkJSONArrayMaps(array, jsonObject.getMapType()); } /** @@ -3163,6 +3260,7 @@ public class JSONObjectTest { 1, jo.length()); assertTrue(jo.get("closeable") instanceof JSONObject); assertTrue(jo.getJSONObject("closeable").has("string")); + Util.checkJSONObjectMaps(jo); } @Test(expected=NullPointerException.class) @@ -3289,9 +3387,12 @@ public class JSONObjectTest { ObjC.setRef(ObjA); ObjB.setRef(ObjA); ObjB.setRef2(ObjA); - new JSONObject(ObjC); - new JSONObject(ObjB); - new JSONObject(ObjA); + JSONObject j0 = new JSONObject(ObjC); + JSONObject j1 = new JSONObject(ObjB); + JSONObject j2 = new JSONObject(ObjA); + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + j0, j1, j2 + ))); } @Test public void testLongRepeatObjectNotRecursive() { @@ -3307,17 +3408,21 @@ public class JSONObjectTest { ObjB.setRef2(ObjD); ObjA.setRef(ObjD); ObjD.setRef(ObjE); - new JSONObject(ObjC); - new JSONObject(ObjB); - new JSONObject(ObjA); - new JSONObject(ObjD); - new JSONObject(ObjE); + JSONObject j0 = new JSONObject(ObjC); + JSONObject j1 = new JSONObject(ObjB); + JSONObject j2 = new JSONObject(ObjA); + JSONObject j3 = new JSONObject(ObjD); + JSONObject j4 = new JSONObject(ObjE); + Util.checkJSONObjectsMaps(new ArrayList(Arrays.asList( + j0, j1, j2, j3, j4 + ))); } @Test(expected=JSONException.class) public void testRecursiveEquals() { RecursiveBeanEquals a = new RecursiveBeanEquals("same"); a.setRef(a); - new JSONObject(a); + JSONObject j0 = new JSONObject(a); + Util.checkJSONObjectMaps(j0); } @Test public void testNotRecursiveEquals() { @@ -3326,7 +3431,8 @@ public class JSONObjectTest { RecursiveBeanEquals c = new RecursiveBeanEquals("same"); a.setRef(b); b.setRef(c); - new JSONObject(a); + JSONObject j0 = new JSONObject(a); + Util.checkJSONObjectMaps(j0); } @@ -3336,6 +3442,7 @@ public class JSONObjectTest { assertTrue("missing expected key 'empty_json_array'", jsonObject.has("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()); + Util.checkJSONObjectMaps(jsonObject); } /** @@ -3351,6 +3458,7 @@ public class JSONObjectTest { 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 + Util.checkJSONObjectMaps(jsonObject); } /** @@ -3364,6 +3472,7 @@ public class JSONObjectTest { JSONObject json_input = new JSONObject(input); assertNotNull(json_input); fail("Excepected Exception."); + Util.checkJSONObjectMaps(json_input); } /** @@ -3373,7 +3482,7 @@ public class JSONObjectTest { public void issue654IncorrectNestingNoKey1() { JSONObject json_input = new JSONObject("{{\"a\":0}}"); assertNotNull(json_input); - fail("Excepected Exception."); + fail("Expected Exception."); } /** diff --git a/src/test/java/org/json/junit/Util.java b/src/test/java/org/json/junit/Util.java index 8dc27dd..a4d0e22 100644 --- a/src/test/java/org/json/junit/Util.java +++ b/src/test/java/org/json/junit/Util.java @@ -78,7 +78,6 @@ public class Util { * or something else. * @param value created by the code to be tested * @param expectedValue created specifically for comparing - * @param key key to the jsonObject entry to be compared */ private static void compareActualVsExpectedObjects(Object value, Object expectedValue) { @@ -117,4 +116,106 @@ public class Util { ); } } + + /** + * Asserts that all JSONObject maps are the same as the default ctor + * @param jsonObjects list of objects to be tested + */ + public static void checkJSONObjectsMaps(List jsonObjects) { + if (jsonObjects == null || jsonObjects.size() == 0) { + return; + } + Class mapType = new JSONObject().getMapType(); + for (JSONObject jsonObject : jsonObjects) { + if (jsonObject != null) { + assertTrue(mapType == jsonObject.getMapType()); + checkJSONObjectMaps(jsonObject, mapType); + } + } + } + + /** + * Asserts that all JSONObject maps are the same as the default ctor + * @param jsonObject the object to be tested + */ + public static void checkJSONObjectMaps(JSONObject jsonObject) { + if (jsonObject != null) { + checkJSONObjectMaps(jsonObject, jsonObject.getMapType()); + } + } + + /** + * Asserts that all JSONObject maps are the same as mapType + * @param jsonObject object to be tested + * @param mapType mapType to test against + */ + public static void checkJSONObjectMaps(JSONObject jsonObject, Class mapType) { + if (mapType == null) { + mapType = new JSONObject().getMapType(); + } + Set keys = jsonObject.keySet(); + for (String key : keys) { + Object val = jsonObject.get(key); + if (val instanceof JSONObject) { + JSONObject jsonObjectVal = (JSONObject) val; + assertTrue(mapType == ((JSONObject) val).getMapType()); + checkJSONObjectMaps(jsonObjectVal, mapType); + } else if (val instanceof JSONArray) { + JSONArray jsonArrayVal = (JSONArray)val; + checkJSONArrayMaps(jsonArrayVal, mapType); + } + } + } + + /** + * Asserts that all JSONObject maps in the JSONArray object match the default map + * @param jsonArrays list of JSONArray objects to be tested + */ + public static void checkJSONArraysMaps(List jsonArrays) { + if (jsonArrays == null || jsonArrays.size() == 0) { + return; + } + Class mapType = new JSONObject().getMapType(); + for (JSONArray jsonArray : jsonArrays) { + if (jsonArray != null) { + checkJSONArrayMaps(jsonArray, mapType); + } + } + } + + /** + * Asserts that all JSONObject maps in the JSONArray object match mapType + * @param jsonArray object to be tested + * @param mapType map type to be tested against + */ + public static void checkJSONArrayMaps(JSONArray jsonArray, Class mapType) { + if (jsonArray == null) { + return; + } + if (mapType == null) { + mapType = new JSONObject().getMapType(); + } + Iterator it = jsonArray.iterator(); + while (it.hasNext()) { + Object val = it.next(); + if (val instanceof JSONObject) { + JSONObject jsonObjectVal = (JSONObject)val; + checkJSONObjectMaps(jsonObjectVal, mapType); + } else if (val instanceof JSONArray) { + JSONArray jsonArrayVal = (JSONArray)val; + checkJSONArrayMaps(jsonArrayVal, mapType); + } + } + } + + /** + * Asserts that all JSONObject maps nested in the JSONArray match + * the default mapType + * @param jsonArray the object to be tested + */ + public static void checkJSONArrayMaps(JSONArray jsonArray) { + if (jsonArray != null) { + checkJSONArrayMaps(jsonArray, null); + } + } } -- Gitee From 3eecd67a3b4f84c7f2c498613de9dbdec0b227ad Mon Sep 17 00:00:00 2001 From: Joshua Schwartz Date: Tue, 23 Aug 2022 15:00:01 -0500 Subject: [PATCH 04/48] Fix typo --- Examples.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples.md b/Examples.md index 3f45e78..8f28461 100644 --- a/Examples.md +++ b/Examples.md @@ -218,7 +218,7 @@ import java.util.Properties; } ```

Part 2: Conversion methods

-

We don't need to have a JSON docuemnt to work. This project also admits conversions from other type of files.

+

We don't need to have a JSON document to work. This project also admits conversions from other type of files.

Secondly, we can also convert from JSON to those type of files.

Extra: Conversion to JSONArray

-- Gitee From 6daabb43ab2d32974f2a8ea79d713f67f4c22d30 Mon Sep 17 00:00:00 2001 From: stleary Date: Tue, 23 Aug 2022 20:00:25 -0500 Subject: [PATCH 05/48] update-copyright - Replace copyright and license restrictions with Public Domain --- LICENSE | 23 +--------------- README.md | 2 -- pom.xml | 27 ++----------------- src/main/java/org/json/CDL.java | 22 +-------------- src/main/java/org/json/Cookie.java | 22 +-------------- src/main/java/org/json/CookieList.java | 22 +-------------- src/main/java/org/json/HTTP.java | 22 +-------------- src/main/java/org/json/HTTPTokener.java | 22 +-------------- src/main/java/org/json/JSONArray.java | 22 +-------------- src/main/java/org/json/JSONException.java | 22 +-------------- src/main/java/org/json/JSONML.java | 22 +-------------- src/main/java/org/json/JSONObject.java | 27 +++---------------- src/main/java/org/json/JSONPointer.java | 22 +-------------- .../java/org/json/JSONPointerException.java | 22 +-------------- .../java/org/json/JSONPropertyIgnore.java | 22 +-------------- src/main/java/org/json/JSONPropertyName.java | 22 +-------------- src/main/java/org/json/JSONString.java | 22 +-------------- src/main/java/org/json/JSONStringer.java | 22 +-------------- src/main/java/org/json/JSONTokener.java | 22 +-------------- src/main/java/org/json/JSONWriter.java | 22 +-------------- src/main/java/org/json/Property.java | 22 +-------------- src/main/java/org/json/XML.java | 22 +-------------- .../java/org/json/XMLParserConfiguration.java | 22 +-------------- src/main/java/org/json/XMLTokener.java | 22 +-------------- .../java/org/json/XMLXsiTypeConverter.java | 22 +-------------- src/test/java/org/json/junit/CDLTest.java | 22 +-------------- .../java/org/json/junit/CookieListTest.java | 22 +-------------- src/test/java/org/json/junit/CookieTest.java | 22 +-------------- src/test/java/org/json/junit/EnumTest.java | 22 +-------------- src/test/java/org/json/junit/HTTPTest.java | 22 +-------------- .../java/org/json/junit/JSONArrayTest.java | 22 +-------------- src/test/java/org/json/junit/JSONMLTest.java | 22 +-------------- .../org/json/junit/JSONObjectLocaleTest.java | 22 +-------------- .../java/org/json/junit/JSONObjectTest.java | 22 +-------------- .../java/org/json/junit/JSONPointerTest.java | 22 +-------------- .../java/org/json/junit/JSONStringTest.java | 22 +-------------- .../java/org/json/junit/JSONStringerTest.java | 22 +-------------- .../java/org/json/junit/JSONTokenerTest.java | 22 +-------------- .../java/org/json/junit/PropertyTest.java | 22 +-------------- src/test/java/org/json/junit/Util.java | 22 +-------------- .../org/json/junit/XMLConfigurationTest.java | 22 +-------------- src/test/java/org/json/junit/XMLTest.java | 22 +-------------- 42 files changed, 44 insertions(+), 871 deletions(-) diff --git a/LICENSE b/LICENSE index 6cfb9b2..2ef9799 100644 --- a/LICENSE +++ b/LICENSE @@ -1,23 +1,2 @@ - -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. diff --git a/README.md b/README.md index 69869cd..9d1ead9 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,6 @@ Project goals include: The files in this package implement JSON encoders and decoders. The package can also convert between JSON and XML, HTTP headers, Cookies, and CDL. -The license includes this restriction: ["The software shall be used for good, not evil."](https://en.wikipedia.org/wiki/Douglas_Crockford#%22Good,_not_Evil%22) If your conscience cannot live with that, then choose a different package. - # If you would like to contribute to this project For more information on contributions, please see [CONTRIBUTING.md](https://github.com/stleary/JSON-java/blob/master/docs/CONTRIBUTING.md) diff --git a/pom.xml b/pom.xml index e4a3503..1a93b34 100644 --- a/pom.xml +++ b/pom.xml @@ -18,10 +18,6 @@ This is a reference implementation. There is a large number of JSON packages in Java. Perhaps someday the Java community will standardize on one. Until then, choose carefully. - - The license includes this restriction: "The software shall be used for good, - not evil." If your conscience cannot live with that, then choose a different - package. https://github.com/douglascrockford/JSON-java @@ -39,28 +35,9 @@ - The JSON License - http://json.org/license.html + Public Domain + https://github.com/stleary/JSON-java/blob/master/LICENSE repo - Copyright (c) 2002 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - associated documentation files (the "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - following conditions: - - The above copyright notice and this permission notice shall be included in all copies or substantial - portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT - LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/src/main/java/org/json/CDL.java b/src/main/java/org/json/CDL.java index f12cfc0..848831d 100644 --- a/src/main/java/org/json/CDL.java +++ b/src/main/java/org/json/CDL.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ /** diff --git a/src/main/java/org/json/Cookie.java b/src/main/java/org/json/Cookie.java index 1c5fb78..7a7e028 100644 --- a/src/main/java/org/json/Cookie.java +++ b/src/main/java/org/json/Cookie.java @@ -3,27 +3,7 @@ package org.json; import java.util.Locale; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ /** diff --git a/src/main/java/org/json/CookieList.java b/src/main/java/org/json/CookieList.java index 83b2630..8ad8b58 100644 --- a/src/main/java/org/json/CookieList.java +++ b/src/main/java/org/json/CookieList.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ /** diff --git a/src/main/java/org/json/HTTP.java b/src/main/java/org/json/HTTP.java index cc01167..6fee6ba 100644 --- a/src/main/java/org/json/HTTP.java +++ b/src/main/java/org/json/HTTP.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import java.util.Locale; diff --git a/src/main/java/org/json/HTTPTokener.java b/src/main/java/org/json/HTTPTokener.java index 16c7081..48cad31 100644 --- a/src/main/java/org/json/HTTPTokener.java +++ b/src/main/java/org/json/HTTPTokener.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ /** diff --git a/src/main/java/org/json/JSONArray.java b/src/main/java/org/json/JSONArray.java index 2b33e1d..18e57e6 100644 --- a/src/main/java/org/json/JSONArray.java +++ b/src/main/java/org/json/JSONArray.java @@ -1,27 +1,7 @@ package org.json; /* - Copyright (c) 2002 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. +Public Domain. */ import java.io.IOException; diff --git a/src/main/java/org/json/JSONException.java b/src/main/java/org/json/JSONException.java index ab7ff77..02c29f3 100644 --- a/src/main/java/org/json/JSONException.java +++ b/src/main/java/org/json/JSONException.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ /** diff --git a/src/main/java/org/json/JSONML.java b/src/main/java/org/json/JSONML.java index aafdf72..2f9b840 100644 --- a/src/main/java/org/json/JSONML.java +++ b/src/main/java/org/json/JSONML.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2008 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ /** diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java index 782f8a4..9f6ee5f 100644 --- a/src/main/java/org/json/JSONObject.java +++ b/src/main/java/org/json/JSONObject.java @@ -1,31 +1,10 @@ package org.json; -import java.io.Closeable; - /* - Copyright (c) 2002 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ +Public Domain. +*/ +import java.io.Closeable; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; diff --git a/src/main/java/org/json/JSONPointer.java b/src/main/java/org/json/JSONPointer.java index f1f7f33..963fdec 100644 --- a/src/main/java/org/json/JSONPointer.java +++ b/src/main/java/org/json/JSONPointer.java @@ -10,27 +10,7 @@ import java.util.Collections; import java.util.List; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ /** diff --git a/src/main/java/org/json/JSONPointerException.java b/src/main/java/org/json/JSONPointerException.java index 0ce1aeb..a0e128c 100644 --- a/src/main/java/org/json/JSONPointerException.java +++ b/src/main/java/org/json/JSONPointerException.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ /** diff --git a/src/main/java/org/json/JSONPropertyIgnore.java b/src/main/java/org/json/JSONPropertyIgnore.java index 682de74..7c5fa53 100644 --- a/src/main/java/org/json/JSONPropertyIgnore.java +++ b/src/main/java/org/json/JSONPropertyIgnore.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2018 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static java.lang.annotation.ElementType.METHOD; diff --git a/src/main/java/org/json/JSONPropertyName.java b/src/main/java/org/json/JSONPropertyName.java index a1bcd58..a66f4ad 100644 --- a/src/main/java/org/json/JSONPropertyName.java +++ b/src/main/java/org/json/JSONPropertyName.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2018 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static java.lang.annotation.ElementType.METHOD; diff --git a/src/main/java/org/json/JSONString.java b/src/main/java/org/json/JSONString.java index bcd9a81..cd8d184 100644 --- a/src/main/java/org/json/JSONString.java +++ b/src/main/java/org/json/JSONString.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ /** diff --git a/src/main/java/org/json/JSONStringer.java b/src/main/java/org/json/JSONStringer.java index d2a4dfb..2f6cf9e 100644 --- a/src/main/java/org/json/JSONStringer.java +++ b/src/main/java/org/json/JSONStringer.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2006 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import java.io.StringWriter; diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java index 7f0c86a..8c98c77 100644 --- a/src/main/java/org/json/JSONTokener.java +++ b/src/main/java/org/json/JSONTokener.java @@ -8,27 +8,7 @@ import java.io.Reader; import java.io.StringReader; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ /** diff --git a/src/main/java/org/json/JSONWriter.java b/src/main/java/org/json/JSONWriter.java index dafb1b2..11f4a5c 100644 --- a/src/main/java/org/json/JSONWriter.java +++ b/src/main/java/org/json/JSONWriter.java @@ -5,27 +5,7 @@ import java.util.Collection; import java.util.Map; /* -Copyright (c) 2006 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ /** diff --git a/src/main/java/org/json/Property.java b/src/main/java/org/json/Property.java index 7caeebb..83694c0 100644 --- a/src/main/java/org/json/Property.java +++ b/src/main/java/org/json/Property.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import java.util.Enumeration; diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java index 33838a1..69782cb 100644 --- a/src/main/java/org/json/XML.java +++ b/src/main/java/org/json/XML.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2015 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import java.io.Reader; diff --git a/src/main/java/org/json/XMLParserConfiguration.java b/src/main/java/org/json/XMLParserConfiguration.java index a1fd63e..9f00710 100644 --- a/src/main/java/org/json/XMLParserConfiguration.java +++ b/src/main/java/org/json/XMLParserConfiguration.java @@ -1,26 +1,6 @@ package org.json; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import java.util.Collections; diff --git a/src/main/java/org/json/XMLTokener.java b/src/main/java/org/json/XMLTokener.java index 3bbd382..957498c 100644 --- a/src/main/java/org/json/XMLTokener.java +++ b/src/main/java/org/json/XMLTokener.java @@ -1,27 +1,7 @@ package org.json; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import java.io.Reader; diff --git a/src/main/java/org/json/XMLXsiTypeConverter.java b/src/main/java/org/json/XMLXsiTypeConverter.java index 0f8a8c3..0011eff 100644 --- a/src/main/java/org/json/XMLXsiTypeConverter.java +++ b/src/main/java/org/json/XMLXsiTypeConverter.java @@ -1,26 +1,6 @@ package org.json; /* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ /** diff --git a/src/test/java/org/json/junit/CDLTest.java b/src/test/java/org/json/junit/CDLTest.java index b8bdede..f3364fb 100644 --- a/src/test/java/org/json/junit/CDLTest.java +++ b/src/test/java/org/json/junit/CDLTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.*; diff --git a/src/test/java/org/json/junit/CookieListTest.java b/src/test/java/org/json/junit/CookieListTest.java index c3f647f..0af9640 100644 --- a/src/test/java/org/json/junit/CookieListTest.java +++ b/src/test/java/org/json/junit/CookieListTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.*; diff --git a/src/test/java/org/json/junit/CookieTest.java b/src/test/java/org/json/junit/CookieTest.java index 7e7b62b..edd8a7e 100644 --- a/src/test/java/org/json/junit/CookieTest.java +++ b/src/test/java/org/json/junit/CookieTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.*; diff --git a/src/test/java/org/json/junit/EnumTest.java b/src/test/java/org/json/junit/EnumTest.java index 6867123..1496a63 100644 --- a/src/test/java/org/json/junit/EnumTest.java +++ b/src/test/java/org/json/junit/EnumTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.assertEquals; diff --git a/src/test/java/org/json/junit/HTTPTest.java b/src/test/java/org/json/junit/HTTPTest.java index 8182b60..703d5ad 100644 --- a/src/test/java/org/json/junit/HTTPTest.java +++ b/src/test/java/org/json/junit/HTTPTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.*; diff --git a/src/test/java/org/json/junit/JSONArrayTest.java b/src/test/java/org/json/junit/JSONArrayTest.java index 946f407..e98259c 100644 --- a/src/test/java/org/json/junit/JSONArrayTest.java +++ b/src/test/java/org/json/junit/JSONArrayTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.assertEquals; diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java index 390cbd8..34bc9f0 100644 --- a/src/test/java/org/json/junit/JSONMLTest.java +++ b/src/test/java/org/json/junit/JSONMLTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.*; diff --git a/src/test/java/org/json/junit/JSONObjectLocaleTest.java b/src/test/java/org/json/junit/JSONObjectLocaleTest.java index 5112bf5..1cdaf74 100755 --- a/src/test/java/org/json/junit/JSONObjectLocaleTest.java +++ b/src/test/java/org/json/junit/JSONObjectLocaleTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.*; diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index 3681148..32f4a42 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.assertEquals; diff --git a/src/test/java/org/json/junit/JSONPointerTest.java b/src/test/java/org/json/junit/JSONPointerTest.java index 4ea7434..d88803e 100644 --- a/src/test/java/org/json/junit/JSONPointerTest.java +++ b/src/test/java/org/json/junit/JSONPointerTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.assertEquals; diff --git a/src/test/java/org/json/junit/JSONStringTest.java b/src/test/java/org/json/junit/JSONStringTest.java index a199611..b4fee3e 100644 --- a/src/test/java/org/json/junit/JSONStringTest.java +++ b/src/test/java/org/json/junit/JSONStringTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.*; diff --git a/src/test/java/org/json/junit/JSONStringerTest.java b/src/test/java/org/json/junit/JSONStringerTest.java index a99db3b..0ecb9d6 100644 --- a/src/test/java/org/json/junit/JSONStringerTest.java +++ b/src/test/java/org/json/junit/JSONStringerTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.*; diff --git a/src/test/java/org/json/junit/JSONTokenerTest.java b/src/test/java/org/json/junit/JSONTokenerTest.java index e8e0f98..da716b8 100644 --- a/src/test/java/org/json/junit/JSONTokenerTest.java +++ b/src/test/java/org/json/junit/JSONTokenerTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.assertEquals; diff --git a/src/test/java/org/json/junit/PropertyTest.java b/src/test/java/org/json/junit/PropertyTest.java index e1a9b8d..eee482f 100644 --- a/src/test/java/org/json/junit/PropertyTest.java +++ b/src/test/java/org/json/junit/PropertyTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import java.util.*; diff --git a/src/test/java/org/json/junit/Util.java b/src/test/java/org/json/junit/Util.java index a4d0e22..b676045 100644 --- a/src/test/java/org/json/junit/Util.java +++ b/src/test/java/org/json/junit/Util.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.*; diff --git a/src/test/java/org/json/junit/XMLConfigurationTest.java b/src/test/java/org/json/junit/XMLConfigurationTest.java index 2ab06be..f9d24a6 100755 --- a/src/test/java/org/json/junit/XMLConfigurationTest.java +++ b/src/test/java/org/json/junit/XMLConfigurationTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.assertEquals; diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 0155472..906924d 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -1,27 +1,7 @@ package org.json.junit; /* -Copyright (c) 2020 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Public Domain. */ import static org.junit.Assert.assertEquals; -- Gitee From a30d71fdca1a2bf3c1d1d15038cb904d01ad6264 Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Sat, 24 Sep 2022 16:11:12 -0500 Subject: [PATCH 06/48] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d1ead9..5181b8b 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ JSON in Java [package org.json] [![Maven Central](https://img.shields.io/maven-central/v/org.json/json.svg)](https://mvnrepository.com/artifact/org.json/json) -**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20220320/json-20220320.jar)** +**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20220924/json-20220924.jar)** # Overview -- Gitee From a6bdd081eb673509e73b712bd0936e0e52409aea Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Sat, 24 Sep 2022 16:13:11 -0500 Subject: [PATCH 07/48] Update RELEASES.md --- docs/RELEASES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/RELEASES.md b/docs/RELEASES.md index 149525d..0d49331 100644 --- a/docs/RELEASES.md +++ b/docs/RELEASES.md @@ -5,6 +5,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) ~~~ +20220924 New License - public domain, and some minor updates + 20220320 Wrap StackOverflow with JSONException 20211205 Recent commits and some bug fixes for similar() -- Gitee From 8439039da75eb539efb21a04442cfa8330740bda Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Sat, 24 Sep 2022 16:25:18 -0500 Subject: [PATCH 08/48] Update pom.xml For the 20220924 release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1a93b34..4ef85a8 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.json json - 20220320 + 20220924 bundle JSON in Java -- Gitee From 1915aab7c4bcaefb973e99889e4126320b1e2263 Mon Sep 17 00:00:00 2001 From: hendrixjoseph Date: Tue, 4 Oct 2022 14:32:41 -0400 Subject: [PATCH 09/48] create unit tests for various number formats --- .../org/json/junit/JSONObjectNumberTest.java | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/test/java/org/json/junit/JSONObjectNumberTest.java diff --git a/src/test/java/org/json/junit/JSONObjectNumberTest.java b/src/test/java/org/json/junit/JSONObjectNumberTest.java new file mode 100644 index 0000000..f6e13c6 --- /dev/null +++ b/src/test/java/org/json/junit/JSONObjectNumberTest.java @@ -0,0 +1,126 @@ +package org.json.junit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collection; + +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +@RunWith(value = Parameterized.class) +public class JSONObjectNumberTest { + private final String objectString; + private Integer value = 50; + + @Parameters(name = "{index}: {0}") + public static Collection data() { + return Arrays.asList(new Object[][]{ + {"{value:50}", 1}, + {"{value:50.0}", 1}, + {"{value:5e1}", 1}, + {"{value:5E1}", 1}, + {"{value:5e1}", 1}, + {"{value:'50'}", 1}, + {"{value:-50}", -1}, + {"{value:-50.0}", -1}, + {"{value:-5e1}", -1}, + {"{value:-5E1}", -1}, + {"{value:-5e1}", -1}, + {"{value:'-50'}", -1} + // JSON does not support octal or hex numbers; + // see https://stackoverflow.com/a/52671839/6323312 + // "{value:062}", // octal 50 + // "{value:0x32}" // hex 50 + }); + } + + public JSONObjectNumberTest(String objectString, int resultIsNegative) { + this.objectString = objectString; + this.value *= resultIsNegative; + } + + private JSONObject object; + + @Before + public void setJsonObject() { + object = new JSONObject(objectString); + } + + @Test + public void testGetNumber() { + assertEquals(value.intValue(), object.getNumber("value").intValue()); + } + + @Test + public void testGetBigDecimal() { + assertTrue(BigDecimal.valueOf(value).compareTo(object.getBigDecimal("value")) == 0); + } + + @Test + public void testGetBigInteger() { + assertEquals(BigInteger.valueOf(value), object.getBigInteger("value")); + } + + @Test + public void testGetFloat() { + assertEquals(value.floatValue(), object.getFloat("value"), 0.0f); + } + + @Test + public void testGetDouble() { + assertEquals(value.doubleValue(), object.getDouble("value"), 0.0d); + } + + @Test + public void testGetInt() { + assertEquals(value.intValue(), object.getInt("value")); + } + + @Test + public void testGetLong() { + assertEquals(value.longValue(), object.getLong("value")); + } + + @Test + public void testOptNumber() { + assertEquals(value.intValue(), object.optNumber("value").intValue()); + } + + @Test + public void testOptBigDecimal() { + assertTrue(BigDecimal.valueOf(value).compareTo(object.optBigDecimal("value", null)) == 0); + } + + @Test + public void testOptBigInteger() { + assertEquals(BigInteger.valueOf(value), object.optBigInteger("value", null)); + } + + @Test + public void testOptFloat() { + assertEquals(value.floatValue(), object.optFloat("value"), 0.0f); + } + + @Test + public void testOptDouble() { + assertEquals(value.doubleValue(), object.optDouble("value"), 0.0d); + } + + @Test + public void testOptInt() { + assertEquals(value.intValue(), object.optInt("value")); + } + + @Test + public void testOptLong() { + assertEquals(value.longValue(), object.optLong("value")); + } +} -- Gitee From 61801c623e8fe51827b1e03a5ffebcebbb708994 Mon Sep 17 00:00:00 2001 From: TheCommandBlock <95651685+InACommandBlock@users.noreply.github.com> Date: Thu, 6 Oct 2022 00:48:34 +0200 Subject: [PATCH 10/48] Minor Adjustments Example.md Added syntax highlighting, standardised indentation --- Examples.md | 560 ++++++++++++++++++++++++++-------------------------- 1 file changed, 280 insertions(+), 280 deletions(-) diff --git a/Examples.md b/Examples.md index 8f28461..2671d1d 100644 --- a/Examples.md +++ b/Examples.md @@ -1,7 +1,7 @@

Examples

Imports used in the examples:

-``` +```java import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -14,208 +14,208 @@ import java.util.Properties;

Using JSONArray

-``` - private static void JSONExampleArray1() { - //We create a JSONObject from a String containing an array using JSONArray - //Firstly, we declare an Array in a String - - String arrayStr = - "["+"true,"+"false,"+ "\"true\","+ "\"false\","+"\"hello\","+"23.45e-4,"+ - "\"23.45\","+"42,"+"\"43\","+"["+"\"world\""+"],"+ - "{"+ - "\"key1\":\"value1\","+ - "\"key2\":\"value2\","+ - "\"key3\":\"value3\","+ - "\"key4\":\"value4\""+ - "},"+ - "0,"+"\"-1\""+ - "]"; - - //Then, we initializate the JSONArray thanks to its constructor - - JSONArray array = new JSONArray(arrayStr); - System.out.println("Values array: "+ array); - - //We convert that array into a JSONObject, but first, we need the labels, so we need another JSONArray with the labels. - //Here we will use an auxiliary function to get one for the example. - - JSONArray list = listNumberArray(array.length()); - System.out.println("Label Array: "+ list.toString()); - //Now, we construct the JSONObject using both the value array and the label array. - JSONObject object = array.toJSONObject(list); - System.out.println("Final JSONOBject: " + object); - } +```java +private static void JSONExampleArray1() { + //We create a JSONObject from a String containing an array using JSONArray + //Firstly, we declare an Array in a String + + String arrayStr = + "["+"true,"+"false,"+ "\"true\","+ "\"false\","+"\"hello\","+"23.45e-4,"+ + "\"23.45\","+"42,"+"\"43\","+"["+"\"world\""+"],"+ + "{"+ + "\"key1\":\"value1\","+ + "\"key2\":\"value2\","+ + "\"key3\":\"value3\","+ + "\"key4\":\"value4\""+ + "},"+ + "0,"+"\"-1\""+ + "]"; + + //Then, we initializate the JSONArray thanks to its constructor + + JSONArray array = new JSONArray(arrayStr); + System.out.println("Values array: "+ array); + + //We convert that array into a JSONObject, but first, we need the labels, so we need another JSONArray with the labels. + //Here we will use an auxiliary function to get one for the example. + + JSONArray list = listNumberArray(array.length()); + System.out.println("Label Array: "+ list.toString()); + //Now, we construct the JSONObject using both the value array and the label array. + JSONObject object = array.toJSONObject(list); + System.out.println("Final JSONOBject: " + object); +} - //This method creates an JSONArray of labels in which those are generated by their positions +//This method creates an JSONArray of labels in which those are generated by their positions - private static JSONArray listNumberArray(int max){ - JSONArray res = new JSONArray(); - for (int i=0; iUsing JSONStringer -``` - private static void JSONExampleStringer() { +```java +private static void JSONExampleStringer() { - //We initializate the JSONStringer + //We initializate the JSONStringer - JSONStringer jsonStringer = new JSONStringer(); + JSONStringer jsonStringer = new JSONStringer(); - //Now we start the process of adding elements with .object() + //Now we start the process of adding elements with .object() - jsonStringer.object(); + jsonStringer.object(); - //We can now add elements as keys and values with .values () and .key() + //We can now add elements as keys and values with .values () and .key() - jsonStringer.key("trueValue").value(true); - jsonStringer.key("falseValue").value(false); - jsonStringer.key("nullValue").value(null); - jsonStringer.key("stringValue").value("hello world!"); - jsonStringer.key("complexStringValue").value("h\be\tllo w\u1234orld!"); - jsonStringer.key("intValue").value(42); - jsonStringer.key("doubleValue").value(-23.45e67); + jsonStringer.key("trueValue").value(true); + jsonStringer.key("falseValue").value(false); + jsonStringer.key("nullValue").value(null); + jsonStringer.key("stringValue").value("hello world!"); + jsonStringer.key("complexStringValue").value("h\be\tllo w\u1234orld!"); + jsonStringer.key("intValue").value(42); + jsonStringer.key("doubleValue").value(-23.45e67); - //We end this prcedure with .ednObject + //We end this prcedure with .ednObject - jsonStringer.endObject(); + jsonStringer.endObject(); - //Once we have a JSONStringer, we convert it to JSONObject generating a String and using JSONObject's contructor. + //Once we have a JSONStringer, we convert it to JSONObject generating a String and using JSONObject's contructor. - String str = jsonStringer.toString(); - JSONObject jsonObject = new JSONObject(str); - - System.out.println("Final JSONOBject: " + jsonObject); - } + String str = jsonStringer.toString(); + JSONObject jsonObject = new JSONObject(str); + + System.out.println("Final JSONOBject: " + jsonObject); +} ```

Using JSONObject

-``` - private static void JSONExampleObject1() { +```java +private static void JSONExampleObject1() { - //We can create a JSONObject from a String with the class builder + //We can create a JSONObject from a String with the class builder - String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}"; - JSONObject example = new JSONObject(string); - System.out.println("Final JSONObject: " + example); - - } -``` + String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}"; + JSONObject example = new JSONObject(string); + System.out.println("Final JSONObject: " + example); + +} ``` - private static void JSONExampleObject2() { +```java +private static void JSONExampleObject2() { - //We can also create a JSONObject directly without messing around with any of the other functions. + //We can also create a JSONObject directly without messing around with any of the other functions. - JSONObject example = new JSONObject(); + JSONObject example = new JSONObject(); - //Now we add the keys and values in a similar way as the Stringer method - example.put("key", "value"); + //Now we add the keys and values in a similar way as the Stringer method + example.put("key", "value"); - //As you can see, the first entry is the key and the second would be its associeted value. + //As you can see, the first entry is the key and the second would be its associeted value. - example.put("key2", 5); - example.put("key3", -23.45e67); - example.put("trueValue", true); + example.put("key2", 5); + example.put("key3", -23.45e67); + example.put("trueValue", true); - //We can't add null values thougth + //We can't add null values thougth - //example.put("nullValue", null); //This is not possible - - System.out.println("Final JSONOBject: " + example); - } -``` + //example.put("nullValue", null); //This is not possible + + System.out.println("Final JSONOBject: " + example); +} ``` - private static void JSONExampleObject3() { +```java +private static void JSONExampleObject3() { - //We can also create a JSONObject with a Java Map - //YoU will need a Map whose keys are Strings. The values can be whatever you want + //We can also create a JSONObject with a Java Map + //YoU will need a Map whose keys are Strings. The values can be whatever you want - Map map = new HashMap(); - - map.put("key1", 1.0); - map.put("key2", -23.45e67); - - //We create the JSONObject with the map with its class builder + Map map = new HashMap(); - JSONObject example = new JSONObject(map); - System.out.println("Final JSONOBject: " + example); - } + map.put("key1", 1.0); + map.put("key2", -23.45e67); + + //We create the JSONObject with the map with its class builder + + JSONObject example = new JSONObject(map); + System.out.println("Final JSONOBject: " + example); +} ```

Using JSONWriter

-``` - private static void JSONExamplWriter() { - - //This method works in a very similar way to Object and Stringer in the construction of the JSON. - //The difference is that it needs a Java object called "Appendable" like StringBuilder - - StringBuilder write = new StringBuilder(); - JSONWriter jsonWriter = new JSONWriter(write); - - //We behave now the same way as Stringer - - jsonWriter.object(); - - jsonWriter.key("trueValue").value(true); - jsonWriter.key("falseValue").value(false); - jsonWriter.key("nullValue").value(null); - jsonWriter.key("stringValue").value("hello world!"); - jsonWriter.key("complexStringValue").value("h\be\tllo w\u1234orld!"); - jsonWriter.key("intValue").value(42); - jsonWriter.key("doubleValue").value(-23.45e67); - - jsonWriter.endObject(); - - //The resoult should be in the "write" object - - System.out.println("JSON: " + write.toString()); - - //The difference is that we don't get a JSONObject in this one. - - - } +```java +private static void JSONExamplWriter() { + + //This method works in a very similar way to Object and Stringer in the construction of the JSON. + //The difference is that it needs a Java object called "Appendable" like StringBuilder + + StringBuilder write = new StringBuilder(); + JSONWriter jsonWriter = new JSONWriter(write); + + //We behave now the same way as Stringer + + jsonWriter.object(); + + jsonWriter.key("trueValue").value(true); + jsonWriter.key("falseValue").value(false); + jsonWriter.key("nullValue").value(null); + jsonWriter.key("stringValue").value("hello world!"); + jsonWriter.key("complexStringValue").value("h\be\tllo w\u1234orld!"); + jsonWriter.key("intValue").value(42); + jsonWriter.key("doubleValue").value(-23.45e67); + + jsonWriter.endObject(); + + //The resoult should be in the "write" object + + System.out.println("JSON: " + write.toString()); + + //The difference is that we don't get a JSONObject in this one. + + +} ``` -``` - private static void JSONExampleTokener() { +```java +private static void JSONExampleTokener() { - //A partir de una String podemos crear un JSONTokener, que lo podemos usar alternativamente para JSONArray,JSONObject + //A partir de una String podemos crear un JSONTokener, que lo podemos usar alternativamente para JSONArray,JSONObject - String string = "this is not a valid JSON string"; - JSONTokener token = new JSONTokener(string); - - //Now you can use the token in JSONObject and Array the same way as a String + String string = "this is not a valid JSON string"; + JSONTokener token = new JSONTokener(string); - JSONObject object = new JSONObject(token); - JSONArray array = new JSONArray(token); - - } + //Now you can use the token in JSONObject and Array the same way as a String + + JSONObject object = new JSONObject(token); + JSONArray array = new JSONArray(token); + +} ```

Part 2: Conversion methods

We don't need to have a JSON document to work. This project also admits conversions from other type of files.

@@ -223,144 +223,144 @@ import java.util.Properties;

Extra: Conversion to JSONArray

-``` - private static void JSONObjectToArray() { - //We start with a JSONObject - - String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}"; - - JSONObject example = new JSONObject(string); - - //We need a list of key strings like the reverse operation - - JSONArray keyStrings = listNumberArray(example.length()); - - //Then we convert to the Array using both elelements - - JSONArray array = example.toJSONArray(keyStrings); - - System.out.println("Final JSONArray: " + array); - } +```java +private static void JSONObjectToArray() { + //We start with a JSONObject + + String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}"; + + JSONObject example = new JSONObject(string); + + //We need a list of key strings like the reverse operation + + JSONArray keyStrings = listNumberArray(example.length()); + + //Then we convert to the Array using both elelements + + JSONArray array = example.toJSONArray(keyStrings); + + System.out.println("Final JSONArray: " + array); +} ```

XML Conversions

-``` - private static void XMLToExampleConversion() { +```java +private static void XMLToExampleConversion() { - //We start with a JSONObject - - String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}"; - JSONObject example = new JSONObject(string); + //We start with a JSONObject - //We obtain a String with XML format with toString() + String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}"; + JSONObject example = new JSONObject(string); - String output = XML.toString(example); - System.out.println("Final XML: " + output); - } + //We obtain a String with XML format with toString() + + String output = XML.toString(example); + System.out.println("Final XML: " + output); +} ``` -``` - private static void XMLFromExampleConversion() { +```java +private static void XMLFromExampleConversion() { - //We start with a string with the XML format + //We start with a string with the XML format - String string = "<0>value<1>5<2>-2.345E+68<3>true"; + String string = "<0>value<1>5<2>-2.345E+68<3>true"; - //We obtain a JSONObject with toJSONOBject() + //We obtain a JSONObject with toJSONOBject() - JSONObject output = XML.toJSONObject(string); - - System.out.println("Final JSONObject: " + output); - } + JSONObject output = XML.toJSONObject(string); + + System.out.println("Final JSONObject: " + output); +} ```

Cookie Conversions

-``` - private static void CookieToExampleConversion() { +```java +private static void CookieToExampleConversion() { - //We start with a JSONObject - //The JSONOBject needs to entries that gives the cookie a name and gives the field "name" a name too. - //The Cokkie format doesn't support booleans + //We start with a JSONObject + //The JSONOBject needs to entries that gives the cookie a name and gives the field "name" a name too. + //The Cokkie format doesn't support booleans - String string = "{\"name\":\"Cookie-Name\",\"value\":\"name\",\"1\":5,\"2\":-2.345E68,\"3\":'true'}"; - JSONObject example = new JSONObject(string); - - //We obtain a String with Cookie format with toString() + String string = "{\"name\":\"Cookie-Name\",\"value\":\"name\",\"1\":5,\"2\":-2.345E68,\"3\":'true'}"; + JSONObject example = new JSONObject(string); - String output = Cookie.toString(example); - System.out.println("Final Cookie: " + output); - } -``` + //We obtain a String with Cookie format with toString() + + String output = Cookie.toString(example); + System.out.println("Final Cookie: " + output); +} ``` - private static void CookieFromExampleConversion() { +```java +private static void CookieFromExampleConversion() { - //We start with a string with the Cookie format + //We start with a string with the Cookie format - String string = "Cookie-Name=name;1=5;2=-2.345E%2b68;3=true"; + String string = "Cookie-Name=name;1=5;2=-2.345E%2b68;3=true"; - //We obtain a JSONObject with toJSONOBject() + //We obtain a JSONObject with toJSONOBject() - JSONObject output = Cookie.toJSONObject(string); - System.out.println("Final JSONObject: " + output); - } + JSONObject output = Cookie.toJSONObject(string); + System.out.println("Final JSONObject: " + output); +} ```

HTTP Conversions

-``` - private static void HTTPToExampleConversion() { +```java +private static void HTTPToExampleConversion() { - //We start with a JSONObject - //The JSONObject must have the minimun header for a HTTP request or header + //We start with a JSONObject + //The JSONObject must have the minimun header for a HTTP request or header - String string = "{\"Method\":\"POST\",\"Request-URI\":'/',\"HTTP-Version\":'HTTP/1.1',\"Value1\":true,\"Value2\":2,\"Value3\":-2.345E68}"; + String string = "{\"Method\":\"POST\",\"Request-URI\":'/',\"HTTP-Version\":'HTTP/1.1',\"Value1\":true,\"Value2\":2,\"Value3\":-2.345E68}"; - JSONObject example = new JSONObject(string); + JSONObject example = new JSONObject(string); - //We obtain a String with HTTP format with toString() + //We obtain a String with HTTP format with toString() - String output = HTTP.toString(example); - System.out.println("Final HTTP: " + output); - } + String output = HTTP.toString(example); + System.out.println("Final HTTP: " + output); +} ``` -``` - private static void HTTPFromExampleConversion() { +```java +private static void HTTPFromExampleConversion() { - //We start with a string with the HTTP format + //We start with a string with the HTTP format - String string = "Final HTTP: POST '/' HTTP/1.1 Value3: -2.345E+68 Value1: true Value2: 2"; + String string = "Final HTTP: POST '/' HTTP/1.1 Value3: -2.345E+68 Value1: true Value2: 2"; - //We obtain a JSONObject with toJSONOBject() + //We obtain a JSONObject with toJSONOBject() - JSONObject output = HTTP.toJSONObject(string); - System.out.println("Final JSONObject: " + output); - } + JSONObject output = HTTP.toJSONObject(string); + System.out.println("Final JSONObject: " + output); +} ```

CDL Conversions

-``` +```java private static void CDLToExampleConversion() { - //We start with some JSONObjects with the same values in the keys but different values in the "values" + //We start with some JSONObjects with the same values in the keys but different values in the "values" + + String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}"; + JSONObject example = new JSONObject(string); - String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}"; - JSONObject example = new JSONObject(string); - - String string2 = "{\"0\":\"value2\",\"1\":6,\"2\":-8.345E68,\"3\":false}"; - JSONObject example2 = new JSONObject(string2); - - //We need now a JSONArray with those JSONObjects + String string2 = "{\"0\":\"value2\",\"1\":6,\"2\":-8.345E68,\"3\":false}"; + JSONObject example2 = new JSONObject(string2); - JSONArray array = new JSONArray(); - array.put(example); - array.put(example2); + //We need now a JSONArray with those JSONObjects - //We obtain a String with XML format with toString() + JSONArray array = new JSONArray(); + array.put(example); + array.put(example2); - String output = CDL.toString(array); - System.out.println("Final CDL: \r\n" + output); - } -``` + //We obtain a String with XML format with toString() + + String output = CDL.toString(array); + System.out.println("Final CDL: \r\n" + output); +} ``` +```java private static void CDLFromExampleConversion() { //We start wtih a String with the CDL format @@ -368,7 +368,7 @@ private static void CDLFromExampleConversion() { String string = "0,1,2,3\n" + "value,5,-2.345E+68,true\n" + "value2,6,-8.345E+68,false"; - + //We obtain a JSONArray with toJSONOBject() JSONArray output = CDL.toJSONArray(string); @@ -377,8 +377,8 @@ private static void CDLFromExampleConversion() { ```

Properties Conversions

-``` - private static Properties PropertyToExampleConversion() { +```java +private static Properties PropertyToExampleConversion() { //We start with a JSONObject @@ -391,43 +391,43 @@ private static void CDLFromExampleConversion() { System.out.println("Final Properties: " + output); return output; - } +} ``` -``` - private static void PropertyFromExampleConversion() { +```java +private static void PropertyFromExampleConversion() { - //We start with a Properties object + //We start with a Properties object - Properties input = PropertyToExampleConversion(); + Properties input = PropertyToExampleConversion(); - //We obtain a JSONObject with toJSONOBject() + //We obtain a JSONObject with toJSONOBject() - JSONObject output = Property.toJSONObject(input); - System.out.println("Final JSONObject: " + output); - } + JSONObject output = Property.toJSONObject(input); + System.out.println("Final JSONObject: " + output); +} ```

List of all examples methods

-``` - public static void main(String[] args) { - //JSONObjectToArray(); - //JSONExampleArray1(); - //JSONExampleArray2(); - //JSONExampleStringer(); - //JSONExampleObject1(); - //JSONExampleObject2(); - //JSONExampleObject3(); - //JSONExamplWriter(); - //XMLToExampleConversion(); - //XMLFromExampleConversion(); - //CookieToExampleConversion(); - //CookieFromExampleConversion(); - //HTTPToExampleConversion(); - //HTTPFromExampleConversion(); - //CDLToExampleConversion(); - //CDLFromExampleConversion(); - //PropertyToExampleConversion(); - //PropertyFromExampleConversion(); - } +```java +public static void main(String[] args) { + //JSONObjectToArray(); + //JSONExampleArray1(); + //JSONExampleArray2(); + //JSONExampleStringer(); + //JSONExampleObject1(); + //JSONExampleObject2(); + //JSONExampleObject3(); + //JSONExamplWriter(); + //XMLToExampleConversion(); + //XMLFromExampleConversion(); + //CookieToExampleConversion(); + //CookieFromExampleConversion(); + //HTTPToExampleConversion(); + //HTTPFromExampleConversion(); + //CDLToExampleConversion(); + //CDLFromExampleConversion(); + //PropertyToExampleConversion(); + //PropertyFromExampleConversion(); +} ``` -- Gitee From 12411b7981e47a3541d1ec27694ca2bc0507a7ba Mon Sep 17 00:00:00 2001 From: TheCommandBlock <95651685+InACommandBlock@users.noreply.github.com> Date: Thu, 6 Oct 2022 03:18:03 +0200 Subject: [PATCH 11/48] Update Examples.md Co-authored-by: JAYSE <104235500+JayseMayne@users.noreply.github.com> --- Examples.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples.md b/Examples.md index 2671d1d..fb010d5 100644 --- a/Examples.md +++ b/Examples.md @@ -406,7 +406,7 @@ private static void PropertyFromExampleConversion() { System.out.println("Final JSONObject: " + output); } ``` -

List of all examples methods

+

List of all examples methods

```java public static void main(String[] args) { -- Gitee From b7f708b22299501305c2bd8577eb7b5bbdbbb8f4 Mon Sep 17 00:00:00 2001 From: Dean Date: Thu, 6 Oct 2022 12:01:13 +0100 Subject: [PATCH 12/48] Altered XML toString to allow indentation param --- src/main/java/org/json/XML.java | 95 +++++++++++++++++++++-- src/test/java/org/json/junit/XMLTest.java | 78 +++++++++++++++++++ 2 files changed, 166 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java index 69782cb..28a292f 100644 --- a/src/main/java/org/json/XML.java +++ b/src/main/java/org/json/XML.java @@ -752,6 +752,11 @@ public class XML { */ public static String toString(final Object object, final String tagName, final XMLParserConfiguration config) throws JSONException { + return toString(object, tagName, config, 0, 0); + } + + private static String toString(final Object object, final String tagName, final XMLParserConfiguration config, int indentFactor, int indent) + throws JSONException { StringBuilder sb = new StringBuilder(); JSONArray ja; JSONObject jo; @@ -761,9 +766,14 @@ public class XML { // Emit if (tagName != null) { + sb.append(indent(indent)); sb.append('<'); sb.append(tagName); sb.append('>'); + if(indentFactor > 0){ + sb.append("\n"); + indent += indentFactor; + } } // Loop thru the keys. @@ -806,31 +816,39 @@ public class XML { sb.append('<'); sb.append(key); sb.append('>'); - sb.append(toString(val, null, config)); + sb.append(toString(val, null, config, indentFactor, indent)); sb.append("'); } else { - sb.append(toString(val, key, config)); + sb.append(toString(val, key, config, indentFactor, indent)); } } } else if ("".equals(value)) { + sb.append(indent(indent)); sb.append('<'); sb.append(key); sb.append("/>"); + if(indentFactor > 0){ + sb.append("\n"); + } // Emit a new tag } else { - sb.append(toString(value, key, config)); + sb.append(toString(value, key, config, indentFactor, indent)); } } if (tagName != null) { // Emit the close tag + sb.append(indent(indent - indentFactor)); sb.append("'); + if(indentFactor > 0){ + sb.append("\n"); + } } return sb.toString(); @@ -849,15 +867,78 @@ public class XML { // XML does not have good support for arrays. If an array // appears in a place where XML is lacking, synthesize an // element. - sb.append(toString(val, tagName == null ? "array" : tagName, config)); + sb.append(toString(val, tagName == null ? "array" : tagName, config, indentFactor, indent)); } return sb.toString(); } + string = (object == null) ? "null" : escape(object.toString()); - return (tagName == null) ? "\"" + string + "\"" - : (string.length() == 0) ? "<" + tagName + "/>" : "<" + tagName - + ">" + string + ""; + if(tagName == null){ + return indent(indent) + "\"" + string + "\"" + ((indentFactor > 0) ? "\n" : ""); + } else if(string.length() == 0){ + return indent(indent) + "<" + tagName + "/>" + ((indentFactor > 0) ? "\n" : ""); + } else { + return indent(indent) + "<" + tagName + + ">" + string + "" + ((indentFactor > 0) ? "\n" : ""); + } + } + + /** + * Convert a JSONObject into a well-formed, pretty printed element-normal XML string. + * + * @param object + * A JSONObject. + * @param indentFactor + * The number of spaces to add to each level of indentation. + * @return A string. + * @throws JSONException Thrown if there is an error parsing the string + */ + public static String toString(Object object, int indentFactor){ + return toString(object, null, XMLParserConfiguration.ORIGINAL, indentFactor); + } + + /** + * Convert a JSONObject into a well-formed, pretty printed element-normal XML string. + * + * @param object + * A JSONObject. + * @param tagName + * The optional name of the enclosing tag. + * @param indentFactor + * The number of spaces to add to each level of indentation. + * @return A string. + * @throws JSONException Thrown if there is an error parsing the string + */ + public static String toString(final Object object, final String tagName, int indentFactor) { + return toString(object, tagName, XMLParserConfiguration.ORIGINAL, indentFactor); + } + + /** + * Convert a JSONObject into a well-formed, pretty printed element-normal XML string. + * + * @param object + * A JSONObject. + * @param tagName + * The optional name of the enclosing tag. + * @param config + * Configuration that can control output to XML. + * @param indentFactor + * The number of spaces to add to each level of indentation. + * @return A string. + * @throws JSONException Thrown if there is an error parsing the string + */ + public static String toString(final Object object, final String tagName, final XMLParserConfiguration config, int indentFactor) + throws JSONException { + return toString(object, tagName, config, indentFactor, 0); + } + + private static final String indent(int indent) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < indent; i++) { + sb.append(' '); + } + return sb.toString(); } } diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 906924d..9ba2279 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -1049,4 +1049,82 @@ public class XMLTest { fail("Expected to be unable to modify the config"); } catch (Exception ignored) { } } + + @Test + public void testXmlToStringWithIndent(){ + String str = "{\n" + + " \"success\": true,\n" + + " \"error\": null,\n" + + " \"response\": [\n" + + " {\n" + + " \"timestamp\": 1664917200,\n" + + " \"dateTimeISO\": \"2022-10-05T00:00:00+03:00\",\n" + + " \"loc\": {\n" + + " \"lat\": 39.91987,\n" + + " \"long\": 32.85427\n" + + " },\n" + + " \"place\": {\n" + + " \"name\": \"ankara\",\n" + + " \"state\": \"an\",\n" + + " \"country\": \"tr\"\n" + + " },\n" + + " \"profile\": {\n" + + " \"tz\": \"Europe/Istanbul\"\n" + + " },\n" + + " \"sun\": {\n" + + " \"rise\": 1664941721,\n" + + " \"riseISO\": \"2022-10-05T06:48:41+03:00\",\n" + + " \"set\": 1664983521,\n" + + " \"setISO\": \"2022-10-05T18:25:21+03:00\",\n" + + " \"transit\": 1664962621,\n" + + " \"transitISO\": \"2022-10-05T12:37:01+03:00\",\n" + + " \"midnightSun\": false,\n" + + " \"polarNight\": false,\n" + + " \"twilight\": {\n" + + " \"civilBegin\": 1664940106,\n" + + " \"civilBeginISO\": \"2022-10-05T06:21:46+03:00\",\n" + + " \"civilEnd\": 1664985136,\n" + + " \"civilEndISO\": \"2022-10-05T18:52:16+03:00\",\n" + + " \"nauticalBegin\": 1664938227,\n" + + " \"nauticalBeginISO\": \"2022-10-05T05:50:27+03:00\",\n" + + " \"nauticalEnd\": 1664987015,\n" + + " \"nauticalEndISO\": \"2022-10-05T19:23:35+03:00\",\n" + + " \"astronomicalBegin\": 1664936337,\n" + + " \"astronomicalBeginISO\": \"2022-10-05T05:18:57+03:00\",\n" + + " \"astronomicalEnd\": 1664988905,\n" + + " \"astronomicalEndISO\": \"2022-10-05T19:55:05+03:00\"\n" + + " }\n" + + " },\n" + + " \"moon\": {\n" + + " \"rise\": 1664976480,\n" + + " \"riseISO\": \"2022-10-05T16:28:00+03:00\",\n" + + " \"set\": 1664921520,\n" + + " \"setISO\": \"2022-10-05T01:12:00+03:00\",\n" + + " \"transit\": 1664994240,\n" + + " \"transitISO\": \"2022-10-05T21:24:00+03:00\",\n" + + " \"underfoot\": 1664949360,\n" + + " \"underfootISO\": \"2022-10-05T08:56:00+03:00\",\n" + + " \"phase\": {\n" + + " \"phase\": 0.3186,\n" + + " \"name\": \"waxing gibbous\",\n" + + " \"illum\": 71,\n" + + " \"age\": 9.41,\n" + + " \"angle\": 0.55\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + "}" ; + JSONObject jsonObject = new JSONObject(str); + String xmlString = XML.toString(jsonObject, "Outer", 1); + System.out.println(xmlString); + System.out.println(XML.toIndentedXmlString(xmlString, 2, true)); + + + } + + } + + + -- Gitee From fa457a4113d34fe768ebdc6ee39cdcd122ba1596 Mon Sep 17 00:00:00 2001 From: Dean Date: Thu, 6 Oct 2022 12:01:26 +0100 Subject: [PATCH 13/48] Test cases for XML toString indentation --- src/test/java/org/json/junit/XMLTest.java | 1505 ++++++++++++++++++++- 1 file changed, 1501 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 9ba2279..8d25b7e 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -1051,7 +1051,7 @@ public class XMLTest { } @Test - public void testXmlToStringWithIndent(){ + public void testIndentComplicatedJsonObject(){ String str = "{\n" + " \"success\": true,\n" + " \"error\": null,\n" + @@ -1116,14 +1116,1511 @@ public class XMLTest { " ]\n" + "}" ; JSONObject jsonObject = new JSONObject(str); - String xmlString = XML.toString(jsonObject, "Outer", 1); - System.out.println(xmlString); - System.out.println(XML.toIndentedXmlString(xmlString, 2, true)); + String actualIndentedXmlString = XML.toString(jsonObject, 1); + String expected = "true\n" + + "\n" + + " 2022-10-05T00:00:00+03:00\n" + + " \n" + + " 39.91987\n" + + " 32.85427\n" + + " \n" + + " \n" + + " \n" + + " 0.3186\n" + + " waxing gibbous\n" + + " 0.55\n" + + " 71\n" + + " 9.41\n" + + " \n" + + " 2022-10-05T01:12:00+03:00\n" + + " 1664949360\n" + + " 1664921520\n" + + " 1664994240\n" + + " 2022-10-05T21:24:00+03:00\n" + + " 2022-10-05T16:28:00+03:00\n" + + " 1664976480\n" + + " 2022-10-05T08:56:00+03:00\n" + + " \n" + + " \n" + + " Europe/Istanbul\n" + + " \n" + + " \n" + + " tr\n" + + " ankara\n" + + " an\n" + + " \n" + + " \n" + + " 2022-10-05T18:25:21+03:00\n" + + " false\n" + + " 1664983521\n" + + " 1664962621\n" + + " false\n" + + " 2022-10-05T12:37:01+03:00\n" + + " 2022-10-05T06:48:41+03:00\n" + + " 1664941721\n" + + " \n" + + " 1664985136\n" + + " 1664936337\n" + + " 1664988905\n" + + " 2022-10-05T05:18:57+03:00\n" + + " 1664940106\n" + + " 2022-10-05T19:23:35+03:00\n" + + " 2022-10-05T19:55:05+03:00\n" + + " 1664938227\n" + + " 1664987015\n" + + " 2022-10-05T05:50:27+03:00\n" + + " 2022-10-05T06:21:46+03:00\n" + + " 2022-10-05T18:52:16+03:00\n" + + " \n" + + " \n" + + " 1664917200\n" + + "\n" + + "null\n"; + assertEquals(actualIndentedXmlString, expected); } + @Test + public void testIndentSimpleJsonObject(){ + String str = "{ \"employee\": { \n" + + " \"name\": \"sonoo\", \n" + + " \"salary\": 56000, \n" + + " \"married\": true \n" + + " }}"; + JSONObject jsonObject = new JSONObject(str); + String actual = XML.toString(jsonObject, "Test", 2); + String expected = "\n" + + " \n" + + " sonoo\n" + + " 56000\n" + + " true\n" + + " \n" + + "\n"; + assertEquals(actual, expected); + } + @Test + public void testIndentSimpleJsonArray(){ + String str = "[ \n" + + " {\"name\":\"Ram\", \"email\":\"Ram@gmail.com\"}, \n" + + " {\"name\":\"Bob\", \"email\":\"bob32@gmail.com\"} \n" + + "] "; + JSONArray jsonObject = new JSONArray(str); + String actual = XML.toString(jsonObject, 2); + String expected = "\n" + + " Ram\n" + + " Ram@gmail.com\n" + + "\n" + + "\n" + + " Bob\n" + + " bob32@gmail.com\n" + + "\n"; + assertEquals(actual, expected); + + + } + @Test + public void testIndentComplicatedJsonObjectWithArrayAndWithConfig(){ + String str = "{\n" + + " \"success\": true,\n" + + " \"error\": null,\n" + + " \"response\": [\n" + + " {\n" + + " \"loc\": {\n" + + " \"long\": 31.25,\n" + + " \"lat\": 30.063\n" + + " },\n" + + " \"interval\": \"day\",\n" + + " \"place\": {\n" + + " \"name\": \"cairo\",\n" + + " \"state\": \"qh\",\n" + + " \"country\": \"eg\"\n" + + " },\n" + + " \"periods\": [\n" + + " {\n" + + " \"timestamp\": 1665032400,\n" + + " \"validTime\": \"2022-10-06T07:00:00+02:00\",\n" + + " \"dateTimeISO\": \"2022-10-06T07:00:00+02:00\",\n" + + " \"maxTempC\": 32,\n" + + " \"maxTempF\": 90,\n" + + " \"minTempC\": 19,\n" + + " \"minTempF\": 66,\n" + + " \"avgTempC\": 25,\n" + + " \"avgTempF\": 78,\n" + + " \"tempC\": null,\n" + + " \"tempF\": null,\n" + + " \"maxFeelslikeC\": 32,\n" + + " \"maxFeelslikeF\": 89,\n" + + " \"minFeelslikeC\": 21,\n" + + " \"minFeelslikeF\": 70,\n" + + " \"avgFeelslikeC\": 26,\n" + + " \"avgFeelslikeF\": 80,\n" + + " \"feelslikeC\": 21,\n" + + " \"feelslikeF\": 70,\n" + + " \"maxDewpointC\": 17,\n" + + " \"maxDewpointF\": 63,\n" + + " \"minDewpointC\": 11,\n" + + " \"minDewpointF\": 52,\n" + + " \"avgDewpointC\": 14,\n" + + " \"avgDewpointF\": 58,\n" + + " \"dewpointC\": 17,\n" + + " \"dewpointF\": 63,\n" + + " \"maxHumidity\": 77,\n" + + " \"minHumidity\": 29,\n" + + " \"humidity\": 77,\n" + + " \"pop\": 0,\n" + + " \"precipMM\": 0,\n" + + " \"precipIN\": 0,\n" + + " \"iceaccum\": null,\n" + + " \"iceaccumMM\": null,\n" + + " \"iceaccumIN\": null,\n" + + " \"snowCM\": 0,\n" + + " \"snowIN\": 0,\n" + + " \"pressureMB\": 1015,\n" + + " \"pressureIN\": 29.97,\n" + + " \"windDir\": \"N\",\n" + + " \"windDirDEG\": 353,\n" + + " \"windSpeedKTS\": 5,\n" + + " \"windSpeedKPH\": 9,\n" + + " \"windSpeedMPH\": 6,\n" + + " \"windGustKTS\": 21,\n" + + " \"windGustKPH\": 40,\n" + + " \"windGustMPH\": 25,\n" + + " \"windDirMax\": \"NNW\",\n" + + " \"windDirMaxDEG\": 342,\n" + + " \"windSpeedMaxKTS\": 9,\n" + + " \"windSpeedMaxKPH\": 16,\n" + + " \"windSpeedMaxMPH\": 10,\n" + + " \"windDirMin\": \"N\",\n" + + " \"windDirMinDEG\": 353,\n" + + " \"windSpeedMinKTS\": 1,\n" + + " \"windSpeedMinKPH\": 2,\n" + + " \"windSpeedMinMPH\": 1,\n" + + " \"windDir80m\": \"N\",\n" + + " \"windDir80mDEG\": 11,\n" + + " \"windSpeed80mKTS\": 12,\n" + + " \"windSpeed80mKPH\": 22,\n" + + " \"windSpeed80mMPH\": 13,\n" + + " \"windGust80mKTS\": 22,\n" + + " \"windGust80mKPH\": 41,\n" + + " \"windGust80mMPH\": 25,\n" + + " \"windDirMax80m\": \"NNW\",\n" + + " \"windDirMax80mDEG\": 343,\n" + + " \"windSpeedMax80mKTS\": 22,\n" + + " \"windSpeedMax80mKPH\": 41,\n" + + " \"windSpeedMax80mMPH\": 25,\n" + + " \"windDirMin80m\": \"E\",\n" + + " \"windDirMin80mDEG\": 95,\n" + + " \"windSpeedMin80mKTS\": 8,\n" + + " \"windSpeedMin80mKPH\": 15,\n" + + " \"windSpeedMin80mMPH\": 10,\n" + + " \"sky\": 22,\n" + + " \"cloudsCoded\": \"FW\",\n" + + " \"weather\": \"Mostly Sunny\",\n" + + " \"weatherCoded\": [],\n" + + " \"weatherPrimary\": \"Mostly Sunny\",\n" + + " \"weatherPrimaryCoded\": \"::FW\",\n" + + " \"icon\": \"fair.png\",\n" + + " \"visibilityKM\": 24.135,\n" + + " \"visibilityMI\": 15,\n" + + " \"uvi\": 6,\n" + + " \"solradWM2\": 5608,\n" + + " \"solradMinWM2\": 0,\n" + + " \"solradMaxWM2\": 778,\n" + + " \"isDay\": true,\n" + + " \"maxCoverage\": \"\",\n" + + " \"sunrise\": 1665028274,\n" + + " \"sunset\": 1665070502,\n" + + " \"sunriseISO\": \"2022-10-06T05:51:14+02:00\",\n" + + " \"sunsetISO\": \"2022-10-06T17:35:02+02:00\"\n" + + " },\n" + + " {\n" + + " \"timestamp\": 1665118800,\n" + + " \"validTime\": \"2022-10-07T07:00:00+02:00\",\n" + + " \"dateTimeISO\": \"2022-10-07T07:00:00+02:00\",\n" + + " \"maxTempC\": 30,\n" + + " \"maxTempF\": 86,\n" + + " \"minTempC\": 19,\n" + + " \"minTempF\": 66,\n" + + " \"avgTempC\": 24,\n" + + " \"avgTempF\": 76,\n" + + " \"tempC\": null,\n" + + " \"tempF\": null,\n" + + " \"maxFeelslikeC\": 29,\n" + + " \"maxFeelslikeF\": 85,\n" + + " \"minFeelslikeC\": 19,\n" + + " \"minFeelslikeF\": 67,\n" + + " \"avgFeelslikeC\": 24,\n" + + " \"avgFeelslikeF\": 76,\n" + + " \"feelslikeC\": 19,\n" + + " \"feelslikeF\": 67,\n" + + " \"maxDewpointC\": 15,\n" + + " \"maxDewpointF\": 60,\n" + + " \"minDewpointC\": 10,\n" + + " \"minDewpointF\": 50,\n" + + " \"avgDewpointC\": 12,\n" + + " \"avgDewpointF\": 54,\n" + + " \"dewpointC\": 15,\n" + + " \"dewpointF\": 60,\n" + + " \"maxHumidity\": 77,\n" + + " \"minHumidity\": 30,\n" + + " \"humidity\": 77,\n" + + " \"pop\": 0,\n" + + " \"precipMM\": 0,\n" + + " \"precipIN\": 0,\n" + + " \"iceaccum\": null,\n" + + " \"iceaccumMM\": null,\n" + + " \"iceaccumIN\": null,\n" + + " \"snowCM\": 0,\n" + + " \"snowIN\": 0,\n" + + " \"pressureMB\": 1014,\n" + + " \"pressureIN\": 29.95,\n" + + " \"windDir\": \"NW\",\n" + + " \"windDirDEG\": 325,\n" + + " \"windSpeedKTS\": 1,\n" + + " \"windSpeedKPH\": 2,\n" + + " \"windSpeedMPH\": 1,\n" + + " \"windGustKTS\": 16,\n" + + " \"windGustKPH\": 29,\n" + + " \"windGustMPH\": 18,\n" + + " \"windDirMax\": \"WNW\",\n" + + " \"windDirMaxDEG\": 298,\n" + + " \"windSpeedMaxKTS\": 7,\n" + + " \"windSpeedMaxKPH\": 13,\n" + + " \"windSpeedMaxMPH\": 8,\n" + + " \"windDirMin\": \"NW\",\n" + + " \"windDirMinDEG\": 325,\n" + + " \"windSpeedMinKTS\": 1,\n" + + " \"windSpeedMinKPH\": 2,\n" + + " \"windSpeedMinMPH\": 1,\n" + + " \"windDir80m\": \"NNW\",\n" + + " \"windDir80mDEG\": 347,\n" + + " \"windSpeed80mKTS\": 6,\n" + + " \"windSpeed80mKPH\": 10,\n" + + " \"windSpeed80mMPH\": 6,\n" + + " \"windGust80mKTS\": 20,\n" + + " \"windGust80mKPH\": 37,\n" + + " \"windGust80mMPH\": 23,\n" + + " \"windDirMax80m\": \"NW\",\n" + + " \"windDirMax80mDEG\": 316,\n" + + " \"windSpeedMax80mKTS\": 20,\n" + + " \"windSpeedMax80mKPH\": 37,\n" + + " \"windSpeedMax80mMPH\": 23,\n" + + " \"windDirMin80m\": \"NNW\",\n" + + " \"windDirMin80mDEG\": 347,\n" + + " \"windSpeedMin80mKTS\": 6,\n" + + " \"windSpeedMin80mKPH\": 10,\n" + + " \"windSpeedMin80mMPH\": 6,\n" + + " \"sky\": 30,\n" + + " \"cloudsCoded\": \"FW\",\n" + + " \"weather\": \"Mostly Sunny\",\n" + + " \"weatherCoded\": [],\n" + + " \"weatherPrimary\": \"Mostly Sunny\",\n" + + " \"weatherPrimaryCoded\": \"::FW\",\n" + + " \"icon\": \"fair.png\",\n" + + " \"visibilityKM\": 24.135,\n" + + " \"visibilityMI\": 15,\n" + + " \"uvi\": 6,\n" + + " \"solradWM2\": 5486,\n" + + " \"solradMinWM2\": 0,\n" + + " \"solradMaxWM2\": 742,\n" + + " \"isDay\": true,\n" + + " \"maxCoverage\": \"\",\n" + + " \"sunrise\": 1665114710,\n" + + " \"sunset\": 1665156831,\n" + + " \"sunriseISO\": \"2022-10-07T05:51:50+02:00\",\n" + + " \"sunsetISO\": \"2022-10-07T17:33:51+02:00\"\n" + + " },\n" + + " {\n" + + " \"timestamp\": 1665205200,\n" + + " \"validTime\": \"2022-10-08T07:00:00+02:00\",\n" + + " \"dateTimeISO\": \"2022-10-08T07:00:00+02:00\",\n" + + " \"maxTempC\": 30,\n" + + " \"maxTempF\": 87,\n" + + " \"minTempC\": 19,\n" + + " \"minTempF\": 66,\n" + + " \"avgTempC\": 25,\n" + + " \"avgTempF\": 76,\n" + + " \"tempC\": null,\n" + + " \"tempF\": null,\n" + + " \"maxFeelslikeC\": 30,\n" + + " \"maxFeelslikeF\": 86,\n" + + " \"minFeelslikeC\": 19,\n" + + " \"minFeelslikeF\": 67,\n" + + " \"avgFeelslikeC\": 25,\n" + + " \"avgFeelslikeF\": 76,\n" + + " \"feelslikeC\": 19,\n" + + " \"feelslikeF\": 67,\n" + + " \"maxDewpointC\": 15,\n" + + " \"maxDewpointF\": 59,\n" + + " \"minDewpointC\": 11,\n" + + " \"minDewpointF\": 52,\n" + + " \"avgDewpointC\": 13,\n" + + " \"avgDewpointF\": 56,\n" + + " \"dewpointC\": 15,\n" + + " \"dewpointF\": 59,\n" + + " \"maxHumidity\": 76,\n" + + " \"minHumidity\": 32,\n" + + " \"humidity\": 76,\n" + + " \"pop\": 0,\n" + + " \"precipMM\": 0,\n" + + " \"precipIN\": 0,\n" + + " \"iceaccum\": null,\n" + + " \"iceaccumMM\": null,\n" + + " \"iceaccumIN\": null,\n" + + " \"snowCM\": 0,\n" + + " \"snowIN\": 0,\n" + + " \"pressureMB\": 1014,\n" + + " \"pressureIN\": 29.94,\n" + + " \"windDir\": \"NNE\",\n" + + " \"windDirDEG\": 21,\n" + + " \"windSpeedKTS\": 1,\n" + + " \"windSpeedKPH\": 2,\n" + + " \"windSpeedMPH\": 1,\n" + + " \"windGustKTS\": 17,\n" + + " \"windGustKPH\": 32,\n" + + " \"windGustMPH\": 20,\n" + + " \"windDirMax\": \"WNW\",\n" + + " \"windDirMaxDEG\": 301,\n" + + " \"windSpeedMaxKTS\": 7,\n" + + " \"windSpeedMaxKPH\": 13,\n" + + " \"windSpeedMaxMPH\": 8,\n" + + " \"windDirMin\": \"NNE\",\n" + + " \"windDirMinDEG\": 21,\n" + + " \"windSpeedMinKTS\": 1,\n" + + " \"windSpeedMinKPH\": 2,\n" + + " \"windSpeedMinMPH\": 1,\n" + + " \"windDir80m\": \"NW\",\n" + + " \"windDir80mDEG\": 309,\n" + + " \"windSpeed80mKTS\": 5,\n" + + " \"windSpeed80mKPH\": 9,\n" + + " \"windSpeed80mMPH\": 5,\n" + + " \"windGust80mKTS\": 17,\n" + + " \"windGust80mKPH\": 31,\n" + + " \"windGust80mMPH\": 19,\n" + + " \"windDirMax80m\": \"NW\",\n" + + " \"windDirMax80mDEG\": 322,\n" + + " \"windSpeedMax80mKTS\": 17,\n" + + " \"windSpeedMax80mKPH\": 31,\n" + + " \"windSpeedMax80mMPH\": 19,\n" + + " \"windDirMin80m\": \"NW\",\n" + + " \"windDirMin80mDEG\": 309,\n" + + " \"windSpeedMin80mKTS\": 5,\n" + + " \"windSpeedMin80mKPH\": 9,\n" + + " \"windSpeedMin80mMPH\": 5,\n" + + " \"sky\": 47,\n" + + " \"cloudsCoded\": \"SC\",\n" + + " \"weather\": \"Partly Cloudy\",\n" + + " \"weatherCoded\": [],\n" + + " \"weatherPrimary\": \"Partly Cloudy\",\n" + + " \"weatherPrimaryCoded\": \"::SC\",\n" + + " \"icon\": \"pcloudy.png\",\n" + + " \"visibilityKM\": 24.135,\n" + + " \"visibilityMI\": 15,\n" + + " \"uvi\": 7,\n" + + " \"solradWM2\": 4785,\n" + + " \"solradMinWM2\": 0,\n" + + " \"solradMaxWM2\": 682,\n" + + " \"isDay\": true,\n" + + " \"maxCoverage\": \"\",\n" + + " \"sunrise\": 1665201146,\n" + + " \"sunset\": 1665243161,\n" + + " \"sunriseISO\": \"2022-10-08T05:52:26+02:00\",\n" + + " \"sunsetISO\": \"2022-10-08T17:32:41+02:00\"\n" + + " },\n" + + " {\n" + + " \"timestamp\": 1665291600,\n" + + " \"validTime\": \"2022-10-09T07:00:00+02:00\",\n" + + " \"dateTimeISO\": \"2022-10-09T07:00:00+02:00\",\n" + + " \"maxTempC\": 31,\n" + + " \"maxTempF\": 87,\n" + + " \"minTempC\": 19,\n" + + " \"minTempF\": 67,\n" + + " \"avgTempC\": 25,\n" + + " \"avgTempF\": 77,\n" + + " \"tempC\": null,\n" + + " \"tempF\": null,\n" + + " \"maxFeelslikeC\": 30,\n" + + " \"maxFeelslikeF\": 86,\n" + + " \"minFeelslikeC\": 20,\n" + + " \"minFeelslikeF\": 67,\n" + + " \"avgFeelslikeC\": 25,\n" + + " \"avgFeelslikeF\": 77,\n" + + " \"feelslikeC\": 20,\n" + + " \"feelslikeF\": 67,\n" + + " \"maxDewpointC\": 17,\n" + + " \"maxDewpointF\": 63,\n" + + " \"minDewpointC\": 11,\n" + + " \"minDewpointF\": 52,\n" + + " \"avgDewpointC\": 14,\n" + + " \"avgDewpointF\": 57,\n" + + " \"dewpointC\": 17,\n" + + " \"dewpointF\": 63,\n" + + " \"maxHumidity\": 86,\n" + + " \"minHumidity\": 31,\n" + + " \"humidity\": 86,\n" + + " \"pop\": 0,\n" + + " \"precipMM\": 0,\n" + + " \"precipIN\": 0,\n" + + " \"iceaccum\": null,\n" + + " \"iceaccumMM\": null,\n" + + " \"iceaccumIN\": null,\n" + + " \"snowCM\": 0,\n" + + " \"snowIN\": 0,\n" + + " \"pressureMB\": 1016,\n" + + " \"pressureIN\": 29.99,\n" + + " \"windDir\": \"N\",\n" + + " \"windDirDEG\": 356,\n" + + " \"windSpeedKTS\": 2,\n" + + " \"windSpeedKPH\": 4,\n" + + " \"windSpeedMPH\": 2,\n" + + " \"windGustKTS\": 19,\n" + + " \"windGustKPH\": 36,\n" + + " \"windGustMPH\": 22,\n" + + " \"windDirMax\": \"NNW\",\n" + + " \"windDirMaxDEG\": 343,\n" + + " \"windSpeedMaxKTS\": 8,\n" + + " \"windSpeedMaxKPH\": 14,\n" + + " \"windSpeedMaxMPH\": 9,\n" + + " \"windDirMin\": \"N\",\n" + + " \"windDirMinDEG\": 356,\n" + + " \"windSpeedMinKTS\": 2,\n" + + " \"windSpeedMinKPH\": 4,\n" + + " \"windSpeedMinMPH\": 2,\n" + + " \"windDir80m\": \"NW\",\n" + + " \"windDir80mDEG\": 316,\n" + + " \"windSpeed80mKTS\": 5,\n" + + " \"windSpeed80mKPH\": 9,\n" + + " \"windSpeed80mMPH\": 6,\n" + + " \"windGust80mKTS\": 20,\n" + + " \"windGust80mKPH\": 36,\n" + + " \"windGust80mMPH\": 23,\n" + + " \"windDirMax80m\": \"N\",\n" + + " \"windDirMax80mDEG\": 354,\n" + + " \"windSpeedMax80mKTS\": 20,\n" + + " \"windSpeedMax80mKPH\": 36,\n" + + " \"windSpeedMax80mMPH\": 23,\n" + + " \"windDirMin80m\": \"NW\",\n" + + " \"windDirMin80mDEG\": 316,\n" + + " \"windSpeedMin80mKTS\": 5,\n" + + " \"windSpeedMin80mKPH\": 9,\n" + + " \"windSpeedMin80mMPH\": 6,\n" + + " \"sky\": 47,\n" + + " \"cloudsCoded\": \"SC\",\n" + + " \"weather\": \"Partly Cloudy\",\n" + + " \"weatherCoded\": [],\n" + + " \"weatherPrimary\": \"Partly Cloudy\",\n" + + " \"weatherPrimaryCoded\": \"::SC\",\n" + + " \"icon\": \"pcloudy.png\",\n" + + " \"visibilityKM\": 24.135,\n" + + " \"visibilityMI\": 15,\n" + + " \"uvi\": 7,\n" + + " \"solradWM2\": 4768,\n" + + " \"solradMinWM2\": 0,\n" + + " \"solradMaxWM2\": 726,\n" + + " \"isDay\": true,\n" + + " \"maxCoverage\": \"\",\n" + + " \"sunrise\": 1665287583,\n" + + " \"sunset\": 1665329491,\n" + + " \"sunriseISO\": \"2022-10-09T05:53:03+02:00\",\n" + + " \"sunsetISO\": \"2022-10-09T17:31:31+02:00\"\n" + + " },\n" + + " {\n" + + " \"timestamp\": 1665378000,\n" + + " \"validTime\": \"2022-10-10T07:00:00+02:00\",\n" + + " \"dateTimeISO\": \"2022-10-10T07:00:00+02:00\",\n" + + " \"maxTempC\": 31,\n" + + " \"maxTempF\": 87,\n" + + " \"minTempC\": 21,\n" + + " \"minTempF\": 70,\n" + + " \"avgTempC\": 26,\n" + + " \"avgTempF\": 78,\n" + + " \"tempC\": null,\n" + + " \"tempF\": null,\n" + + " \"maxFeelslikeC\": 30,\n" + + " \"maxFeelslikeF\": 86,\n" + + " \"minFeelslikeC\": 21,\n" + + " \"minFeelslikeF\": 69,\n" + + " \"avgFeelslikeC\": 25,\n" + + " \"avgFeelslikeF\": 78,\n" + + " \"feelslikeC\": 21,\n" + + " \"feelslikeF\": 69,\n" + + " \"maxDewpointC\": 16,\n" + + " \"maxDewpointF\": 61,\n" + + " \"minDewpointC\": 13,\n" + + " \"minDewpointF\": 55,\n" + + " \"avgDewpointC\": 14,\n" + + " \"avgDewpointF\": 58,\n" + + " \"dewpointC\": 16,\n" + + " \"dewpointF\": 61,\n" + + " \"maxHumidity\": 75,\n" + + " \"minHumidity\": 35,\n" + + " \"humidity\": 75,\n" + + " \"pop\": 0,\n" + + " \"precipMM\": 0,\n" + + " \"precipIN\": 0,\n" + + " \"iceaccum\": null,\n" + + " \"iceaccumMM\": null,\n" + + " \"iceaccumIN\": null,\n" + + " \"snowCM\": 0,\n" + + " \"snowIN\": 0,\n" + + " \"pressureMB\": 1017,\n" + + " \"pressureIN\": 30.03,\n" + + " \"windDir\": \"N\",\n" + + " \"windDirDEG\": 358,\n" + + " \"windSpeedKTS\": 2,\n" + + " \"windSpeedKPH\": 4,\n" + + " \"windSpeedMPH\": 2,\n" + + " \"windGustKTS\": 16,\n" + + " \"windGustKPH\": 30,\n" + + " \"windGustMPH\": 19,\n" + + " \"windDirMax\": \"N\",\n" + + " \"windDirMaxDEG\": 10,\n" + + " \"windSpeedMaxKTS\": 8,\n" + + " \"windSpeedMaxKPH\": 15,\n" + + " \"windSpeedMaxMPH\": 9,\n" + + " \"windDirMin\": \"N\",\n" + + " \"windDirMinDEG\": 358,\n" + + " \"windSpeedMinKTS\": 2,\n" + + " \"windSpeedMinKPH\": 4,\n" + + " \"windSpeedMinMPH\": 2,\n" + + " \"windDir80m\": \"N\",\n" + + " \"windDir80mDEG\": 8,\n" + + " \"windSpeed80mKTS\": 7,\n" + + " \"windSpeed80mKPH\": 13,\n" + + " \"windSpeed80mMPH\": 8,\n" + + " \"windGust80mKTS\": 19,\n" + + " \"windGust80mKPH\": 36,\n" + + " \"windGust80mMPH\": 22,\n" + + " \"windDirMax80m\": \"N\",\n" + + " \"windDirMax80mDEG\": 10,\n" + + " \"windSpeedMax80mKTS\": 19,\n" + + " \"windSpeedMax80mKPH\": 36,\n" + + " \"windSpeedMax80mMPH\": 22,\n" + + " \"windDirMin80m\": \"E\",\n" + + " \"windDirMin80mDEG\": 91,\n" + + " \"windSpeedMin80mKTS\": 7,\n" + + " \"windSpeedMin80mKPH\": 13,\n" + + " \"windSpeedMin80mMPH\": 8,\n" + + " \"sky\": 64,\n" + + " \"cloudsCoded\": \"SC\",\n" + + " \"weather\": \"Partly Cloudy\",\n" + + " \"weatherCoded\": [],\n" + + " \"weatherPrimary\": \"Partly Cloudy\",\n" + + " \"weatherPrimaryCoded\": \"::SC\",\n" + + " \"icon\": \"pcloudy.png\",\n" + + " \"visibilityKM\": 24.135,\n" + + " \"visibilityMI\": 15,\n" + + " \"uvi\": 6,\n" + + " \"solradWM2\": 4494,\n" + + " \"solradMinWM2\": 0,\n" + + " \"solradMaxWM2\": 597,\n" + + " \"isDay\": true,\n" + + " \"maxCoverage\": \"\",\n" + + " \"sunrise\": 1665374020,\n" + + " \"sunset\": 1665415821,\n" + + " \"sunriseISO\": \"2022-10-10T05:53:40+02:00\",\n" + + " \"sunsetISO\": \"2022-10-10T17:30:21+02:00\"\n" + + " },\n" + + " {\n" + + " \"timestamp\": 1665464400,\n" + + " \"validTime\": \"2022-10-11T07:00:00+02:00\",\n" + + " \"dateTimeISO\": \"2022-10-11T07:00:00+02:00\",\n" + + " \"maxTempC\": 31,\n" + + " \"maxTempF\": 87,\n" + + " \"minTempC\": 21,\n" + + " \"minTempF\": 70,\n" + + " \"avgTempC\": 26,\n" + + " \"avgTempF\": 78,\n" + + " \"tempC\": null,\n" + + " \"tempF\": null,\n" + + " \"maxFeelslikeC\": 31,\n" + + " \"maxFeelslikeF\": 87,\n" + + " \"minFeelslikeC\": 22,\n" + + " \"minFeelslikeF\": 72,\n" + + " \"avgFeelslikeC\": 26,\n" + + " \"avgFeelslikeF\": 79,\n" + + " \"feelslikeC\": 22,\n" + + " \"feelslikeF\": 72,\n" + + " \"maxDewpointC\": 17,\n" + + " \"maxDewpointF\": 62,\n" + + " \"minDewpointC\": 11,\n" + + " \"minDewpointF\": 51,\n" + + " \"avgDewpointC\": 13,\n" + + " \"avgDewpointF\": 55,\n" + + " \"dewpointC\": 17,\n" + + " \"dewpointF\": 62,\n" + + " \"maxHumidity\": 71,\n" + + " \"minHumidity\": 30,\n" + + " \"humidity\": 71,\n" + + " \"pop\": 0,\n" + + " \"precipMM\": 0,\n" + + " \"precipIN\": 0,\n" + + " \"iceaccum\": null,\n" + + " \"iceaccumMM\": null,\n" + + " \"iceaccumIN\": null,\n" + + " \"snowCM\": 0,\n" + + " \"snowIN\": 0,\n" + + " \"pressureMB\": 1015,\n" + + " \"pressureIN\": 29.98,\n" + + " \"windDir\": \"NNE\",\n" + + " \"windDirDEG\": 13,\n" + + " \"windSpeedKTS\": 8,\n" + + " \"windSpeedKPH\": 15,\n" + + " \"windSpeedMPH\": 9,\n" + + " \"windGustKTS\": 15,\n" + + " \"windGustKPH\": 28,\n" + + " \"windGustMPH\": 17,\n" + + " \"windDirMax\": \"NNE\",\n" + + " \"windDirMaxDEG\": 28,\n" + + " \"windSpeedMaxKTS\": 15,\n" + + " \"windSpeedMaxKPH\": 28,\n" + + " \"windSpeedMaxMPH\": 18,\n" + + " \"windDirMin\": \"NNE\",\n" + + " \"windDirMinDEG\": 14,\n" + + " \"windSpeedMinKTS\": 7,\n" + + " \"windSpeedMinKPH\": 14,\n" + + " \"windSpeedMinMPH\": 8,\n" + + " \"windDir80m\": \"NNE\",\n" + + " \"windDir80mDEG\": 16,\n" + + " \"windSpeed80mKTS\": 10,\n" + + " \"windSpeed80mKPH\": 19,\n" + + " \"windSpeed80mMPH\": 12,\n" + + " \"windGust80mKTS\": 17,\n" + + " \"windGust80mKPH\": 31,\n" + + " \"windGust80mMPH\": 19,\n" + + " \"windDirMax80m\": \"NNE\",\n" + + " \"windDirMax80mDEG\": 28,\n" + + " \"windSpeedMax80mKTS\": 17,\n" + + " \"windSpeedMax80mKPH\": 31,\n" + + " \"windSpeedMax80mMPH\": 19,\n" + + " \"windDirMin80m\": \"NNE\",\n" + + " \"windDirMin80mDEG\": 13,\n" + + " \"windSpeedMin80mKTS\": 9,\n" + + " \"windSpeedMin80mKPH\": 18,\n" + + " \"windSpeedMin80mMPH\": 11,\n" + + " \"sky\": 0,\n" + + " \"cloudsCoded\": \"CL\",\n" + + " \"weather\": \"Sunny\",\n" + + " \"weatherCoded\": [],\n" + + " \"weatherPrimary\": \"Sunny\",\n" + + " \"weatherPrimaryCoded\": \"::CL\",\n" + + " \"icon\": \"sunny.png\",\n" + + " \"visibilityKM\": 24.135,\n" + + " \"visibilityMI\": 15,\n" + + " \"uvi\": null,\n" + + " \"solradWM2\": 5450,\n" + + " \"solradMinWM2\": 0,\n" + + " \"solradMaxWM2\": 758,\n" + + " \"isDay\": true,\n" + + " \"maxCoverage\": \"\",\n" + + " \"sunrise\": 1665460458,\n" + + " \"sunset\": 1665502153,\n" + + " \"sunriseISO\": \"2022-10-11T05:54:18+02:00\",\n" + + " \"sunsetISO\": \"2022-10-11T17:29:13+02:00\"\n" + + " },\n" + + " {\n" + + " \"timestamp\": 1665550800,\n" + + " \"validTime\": \"2022-10-12T07:00:00+02:00\",\n" + + " \"dateTimeISO\": \"2022-10-12T07:00:00+02:00\",\n" + + " \"maxTempC\": 31,\n" + + " \"maxTempF\": 88,\n" + + " \"minTempC\": 21,\n" + + " \"minTempF\": 69,\n" + + " \"avgTempC\": 26,\n" + + " \"avgTempF\": 79,\n" + + " \"tempC\": null,\n" + + " \"tempF\": null,\n" + + " \"maxFeelslikeC\": 31,\n" + + " \"maxFeelslikeF\": 88,\n" + + " \"minFeelslikeC\": 22,\n" + + " \"minFeelslikeF\": 72,\n" + + " \"avgFeelslikeC\": 26,\n" + + " \"avgFeelslikeF\": 80,\n" + + " \"feelslikeC\": 22,\n" + + " \"feelslikeF\": 72,\n" + + " \"maxDewpointC\": 16,\n" + + " \"maxDewpointF\": 60,\n" + + " \"minDewpointC\": 11,\n" + + " \"minDewpointF\": 51,\n" + + " \"avgDewpointC\": 13,\n" + + " \"avgDewpointF\": 55,\n" + + " \"dewpointC\": 16,\n" + + " \"dewpointF\": 60,\n" + + " \"maxHumidity\": 68,\n" + + " \"minHumidity\": 29,\n" + + " \"humidity\": 68,\n" + + " \"pop\": 0,\n" + + " \"precipMM\": 0,\n" + + " \"precipIN\": 0,\n" + + " \"iceaccum\": null,\n" + + " \"iceaccumMM\": null,\n" + + " \"iceaccumIN\": null,\n" + + " \"snowCM\": 0,\n" + + " \"snowIN\": 0,\n" + + " \"pressureMB\": 1014,\n" + + " \"pressureIN\": 29.95,\n" + + " \"windDir\": \"NNE\",\n" + + " \"windDirDEG\": 12,\n" + + " \"windSpeedKTS\": 8,\n" + + " \"windSpeedKPH\": 15,\n" + + " \"windSpeedMPH\": 9,\n" + + " \"windGustKTS\": 15,\n" + + " \"windGustKPH\": 28,\n" + + " \"windGustMPH\": 17,\n" + + " \"windDirMax\": \"E\",\n" + + " \"windDirMaxDEG\": 96,\n" + + " \"windSpeedMaxKTS\": 14,\n" + + " \"windSpeedMaxKPH\": 26,\n" + + " \"windSpeedMaxMPH\": 16,\n" + + " \"windDirMin\": \"NNE\",\n" + + " \"windDirMinDEG\": 12,\n" + + " \"windSpeedMinKTS\": 7,\n" + + " \"windSpeedMinKPH\": 13,\n" + + " \"windSpeedMinMPH\": 8,\n" + + " \"windDir80m\": \"NNE\",\n" + + " \"windDir80mDEG\": 15,\n" + + " \"windSpeed80mKTS\": 10,\n" + + " \"windSpeed80mKPH\": 19,\n" + + " \"windSpeed80mMPH\": 12,\n" + + " \"windGust80mKTS\": 18,\n" + + " \"windGust80mKPH\": 33,\n" + + " \"windGust80mMPH\": 21,\n" + + " \"windDirMax80m\": \"E\",\n" + + " \"windDirMax80mDEG\": 96,\n" + + " \"windSpeedMax80mKTS\": 18,\n" + + " \"windSpeedMax80mKPH\": 33,\n" + + " \"windSpeedMax80mMPH\": 21,\n" + + " \"windDirMin80m\": \"NNE\",\n" + + " \"windDirMin80mDEG\": 15,\n" + + " \"windSpeedMin80mKTS\": 10,\n" + + " \"windSpeedMin80mKPH\": 18,\n" + + " \"windSpeedMin80mMPH\": 11,\n" + + " \"sky\": 27,\n" + + " \"cloudsCoded\": \"FW\",\n" + + " \"weather\": \"Mostly Sunny\",\n" + + " \"weatherCoded\": [],\n" + + " \"weatherPrimary\": \"Mostly Sunny\",\n" + + " \"weatherPrimaryCoded\": \"::FW\",\n" + + " \"icon\": \"fair.png\",\n" + + " \"visibilityKM\": 24.135,\n" + + " \"visibilityMI\": 15,\n" + + " \"uvi\": null,\n" + + " \"solradWM2\": 4740,\n" + + " \"solradMinWM2\": 0,\n" + + " \"solradMaxWM2\": 743,\n" + + " \"isDay\": true,\n" + + " \"maxCoverage\": \"\",\n" + + " \"sunrise\": 1665546895,\n" + + " \"sunset\": 1665588484,\n" + + " \"sunriseISO\": \"2022-10-12T05:54:55+02:00\",\n" + + " \"sunsetISO\": \"2022-10-12T17:28:04+02:00\"\n" + + " }\n" + + " ],\n" + + " \"profile\": {\n" + + " \"tz\": \"Africa/Cairo\",\n" + + " \"elevM\": 23,\n" + + " \"elevFT\": 75\n" + + " }\n" + + " }\n" + + " ]\n" + + "}"; + JSONObject jsonObject = new JSONObject(str); + String actual = XML.toString(jsonObject, null, XMLParserConfiguration.KEEP_STRINGS,2); + String expected = "true\n" + + "\n" + + " \n" + + " 31.25\n" + + " 30.063\n" + + " \n" + + " \n" + + " 23\n" + + " Africa/Cairo\n" + + " 75\n" + + " \n" + + " \n" + + " 2022-10-06T07:00:00+02:00\n" + + " E\n" + + " 95\n" + + " 21\n" + + " 15\n" + + " 10\n" + + " 353\n" + + " N\n" + + " 2022-10-06T05:51:14+02:00\n" + + " null\n" + + " 9\n" + + " null\n" + + " 66\n" + + " 0\n" + + " Mostly Sunny\n" + + " 2022-10-06T17:35:02+02:00\n" + + " 32\n" + + " 77\n" + + " N\n" + + " 89\n" + + " 0\n" + + " 22\n" + + " 25\n" + + " 25\n" + + " Mostly Sunny\n" + + " 41\n" + + " 58\n" + + " 41\n" + + " 22\n" + + " 14\n" + + " 0\n" + + " 22\n" + + " 353\n" + + " 16\n" + + " 8\n" + + " 70\n" + + " 2022-10-06T07:00:00+02:00\n" + + " 10\n" + + " 778\n" + + " 25\n" + + " 15\n" + + " ::FW\n" + + " 1665028274\n" + + " 78\n" + + " N\n" + + " \n" + + " fair.png\n" + + " 21\n" + + " 17\n" + + " FW\n" + + " 70\n" + + " 29\n" + + " 63\n" + + " 12\n" + + " 0\n" + + " 0\n" + + " NNW\n" + + " 13\n" + + " 22\n" + + " 11\n" + + " 32\n" + + " 1015\n" + + " 24.135\n" + + " 1665032400\n" + + " 90\n" + + " null\n" + + " 11\n" + + " 0\n" + + " 1\n" + + " 343\n" + + " 21\n" + + " 2\n" + + " 63\n" + + " 1\n" + + " 26\n" + + " 6\n" + + " NNW\n" + + " 17\n" + + " 29.97\n" + + " 80\n" + + " null\n" + + " true\n" + + " 19\n" + + " 52\n" + + " 5\n" + + " 1665070502\n" + + " 5608\n" + + " 9\n" + + " 25\n" + + " 77\n" + + " 6\n" + + " 40\n" + + " 342\n" + + " null\n" + + " \n" + + " \n" + + " 2022-10-07T07:00:00+02:00\n" + + " NNW\n" + + " 347\n" + + " 19\n" + + " 15\n" + + " 8\n" + + " 325\n" + + " NW\n" + + " 2022-10-07T05:51:50+02:00\n" + + " null\n" + + " 7\n" + + " null\n" + + " 66\n" + + " 0\n" + + " Mostly Sunny\n" + + " 2022-10-07T17:33:51+02:00\n" + + " 29\n" + + " 77\n" + + " NNW\n" + + " 85\n" + + " 0\n" + + " 30\n" + + " 23\n" + + " 23\n" + + " Mostly Sunny\n" + + " 37\n" + + " 54\n" + + " 37\n" + + " 20\n" + + " 12\n" + + " 0\n" + + " 20\n" + + " 325\n" + + " 13\n" + + " 6\n" + + " 67\n" + + " 2022-10-07T07:00:00+02:00\n" + + " 6\n" + + " 742\n" + + " 24\n" + + " 10\n" + + " ::FW\n" + + " 1665114710\n" + + " 76\n" + + " NW\n" + + " \n" + + " fair.png\n" + + " 19\n" + + " 15\n" + + " FW\n" + + " 67\n" + + " 30\n" + + " 60\n" + + " 6\n" + + " 0\n" + + " 0\n" + + " WNW\n" + + " 6\n" + + " 10\n" + + " 347\n" + + " 30\n" + + " 1014\n" + + " 24.135\n" + + " 1665118800\n" + + " 86\n" + + " null\n" + + " 10\n" + + " 0\n" + + " 1\n" + + " 316\n" + + " 16\n" + + " 2\n" + + " 60\n" + + " 1\n" + + " 24\n" + + " 6\n" + + " NW\n" + + " 15\n" + + " 29.95\n" + + " 76\n" + + " null\n" + + " true\n" + + " 19\n" + + " 50\n" + + " 1\n" + + " 1665156831\n" + + " 5486\n" + + " 2\n" + + " 18\n" + + " 77\n" + + " 1\n" + + " 29\n" + + " 298\n" + + " null\n" + + " \n" + + " \n" + + " 2022-10-08T07:00:00+02:00\n" + + " NW\n" + + " 309\n" + + " 19\n" + + " 15\n" + + " 8\n" + + " 21\n" + + " NNE\n" + + " 2022-10-08T05:52:26+02:00\n" + + " null\n" + + " 7\n" + + " null\n" + + " 66\n" + + " 0\n" + + " Partly Cloudy\n" + + " 2022-10-08T17:32:41+02:00\n" + + " 30\n" + + " 76\n" + + " NW\n" + + " 86\n" + + " 0\n" + + " 47\n" + + " 19\n" + + " 19\n" + + " Partly Cloudy\n" + + " 31\n" + + " 56\n" + + " 31\n" + + " 17\n" + + " 13\n" + + " 0\n" + + " 17\n" + + " 21\n" + + " 13\n" + + " 5\n" + + " 67\n" + + " 2022-10-08T07:00:00+02:00\n" + + " 5\n" + + " 682\n" + + " 25\n" + + " 9\n" + + " ::SC\n" + + " 1665201146\n" + + " 76\n" + + " NNE\n" + + " \n" + + " pcloudy.png\n" + + " 19\n" + + " 15\n" + + " SC\n" + + " 67\n" + + " 32\n" + + " 59\n" + + " 5\n" + + " 0\n" + + " 0\n" + + " WNW\n" + + " 5\n" + + " 9\n" + + " 309\n" + + " 30\n" + + " 1014\n" + + " 24.135\n" + + " 1665205200\n" + + " 87\n" + + " null\n" + + " 11\n" + + " 0\n" + + " 1\n" + + " 322\n" + + " 17\n" + + " 2\n" + + " 59\n" + + " 1\n" + + " 25\n" + + " 7\n" + + " NW\n" + + " 15\n" + + " 29.94\n" + + " 76\n" + + " null\n" + + " true\n" + + " 19\n" + + " 52\n" + + " 1\n" + + " 1665243161\n" + + " 4785\n" + + " 2\n" + + " 20\n" + + " 76\n" + + " 1\n" + + " 32\n" + + " 301\n" + + " null\n" + + " \n" + + " \n" + + " 2022-10-09T07:00:00+02:00\n" + + " NW\n" + + " 316\n" + + " 20\n" + + " 15\n" + + " 9\n" + + " 356\n" + + " N\n" + + " 2022-10-09T05:53:03+02:00\n" + + " null\n" + + " 8\n" + + " null\n" + + " 67\n" + + " 0\n" + + " Partly Cloudy\n" + + " 2022-10-09T17:31:31+02:00\n" + + " 30\n" + + " 86\n" + + " NW\n" + + " 86\n" + + " 0\n" + + " 47\n" + + " 23\n" + + " 23\n" + + " Partly Cloudy\n" + + " 36\n" + + " 57\n" + + " 36\n" + + " 20\n" + + " 14\n" + + " 0\n" + + " 20\n" + + " 356\n" + + " 14\n" + + " 5\n" + + " 67\n" + + " 2022-10-09T07:00:00+02:00\n" + + " 6\n" + + " 726\n" + + " 25\n" + + " 9\n" + + " ::SC\n" + + " 1665287583\n" + + " 77\n" + + " N\n" + + " \n" + + " pcloudy.png\n" + + " 20\n" + + " 17\n" + + " SC\n" + + " 67\n" + + " 31\n" + + " 63\n" + + " 5\n" + + " 0\n" + + " 0\n" + + " NNW\n" + + " 6\n" + + " 9\n" + + " 316\n" + + " 31\n" + + " 1016\n" + + " 24.135\n" + + " 1665291600\n" + + " 87\n" + + " null\n" + + " 11\n" + + " 0\n" + + " 2\n" + + " 354\n" + + " 19\n" + + " 4\n" + + " 63\n" + + " 2\n" + + " 25\n" + + " 7\n" + + " N\n" + + " 17\n" + + " 29.99\n" + + " 77\n" + + " null\n" + + " true\n" + + " 19\n" + + " 52\n" + + " 2\n" + + " 1665329491\n" + + " 4768\n" + + " 4\n" + + " 22\n" + + " 86\n" + + " 2\n" + + " 36\n" + + " 343\n" + + " null\n" + + " \n" + + " \n" + + " 2022-10-10T07:00:00+02:00\n" + + " E\n" + + " 91\n" + + " 21\n" + + " 15\n" + + " 9\n" + + " 358\n" + + " N\n" + + " 2022-10-10T05:53:40+02:00\n" + + " null\n" + + " 8\n" + + " null\n" + + " 70\n" + + " 0\n" + + " Partly Cloudy\n" + + " 2022-10-10T17:30:21+02:00\n" + + " 30\n" + + " 75\n" + + " N\n" + + " 86\n" + + " 0\n" + + " 64\n" + + " 22\n" + + " 22\n" + + " Partly Cloudy\n" + + " 36\n" + + " 58\n" + + " 36\n" + + " 19\n" + + " 14\n" + + " 0\n" + + " 19\n" + + " 358\n" + + " 15\n" + + " 7\n" + + " 69\n" + + " 2022-10-10T07:00:00+02:00\n" + + " 8\n" + + " 597\n" + + " 26\n" + + " 13\n" + + " ::SC\n" + + " 1665374020\n" + + " 78\n" + + " N\n" + + " \n" + + " pcloudy.png\n" + + " 21\n" + + " 16\n" + + " SC\n" + + " 69\n" + + " 35\n" + + " 61\n" + + " 7\n" + + " 0\n" + + " 0\n" + + " N\n" + + " 8\n" + + " 13\n" + + " 8\n" + + " 31\n" + + " 1017\n" + + " 24.135\n" + + " 1665378000\n" + + " 87\n" + + " null\n" + + " 13\n" + + " 0\n" + + " 2\n" + + " 10\n" + + " 16\n" + + " 4\n" + + " 61\n" + + " 2\n" + + " 25\n" + + " 6\n" + + " N\n" + + " 16\n" + + " 30.03\n" + + " 78\n" + + " null\n" + + " true\n" + + " 21\n" + + " 55\n" + + " 2\n" + + " 1665415821\n" + + " 4494\n" + + " 4\n" + + " 19\n" + + " 75\n" + + " 2\n" + + " 30\n" + + " 10\n" + + " null\n" + + " \n" + + " \n" + + " 2022-10-11T07:00:00+02:00\n" + + " NNE\n" + + " 13\n" + + " 22\n" + + " 15\n" + + " 18\n" + + " 13\n" + + " NNE\n" + + " 2022-10-11T05:54:18+02:00\n" + + " null\n" + + " 15\n" + + " null\n" + + " 70\n" + + " 0\n" + + " Sunny\n" + + " 2022-10-11T17:29:13+02:00\n" + + " 31\n" + + " 71\n" + + " NNE\n" + + " 87\n" + + " 0\n" + + " 0\n" + + " 19\n" + + " 19\n" + + " Sunny\n" + + " 31\n" + + " 55\n" + + " 31\n" + + " 17\n" + + " 13\n" + + " 0\n" + + " 17\n" + + " 14\n" + + " 28\n" + + " 9\n" + + " 72\n" + + " 2022-10-11T07:00:00+02:00\n" + + " 11\n" + + " 758\n" + + " 26\n" + + " 18\n" + + " ::CL\n" + + " 1665460458\n" + + " 78\n" + + " NNE\n" + + " \n" + + " sunny.png\n" + + " 22\n" + + " 17\n" + + " CL\n" + + " 72\n" + + " 30\n" + + " 62\n" + + " 10\n" + + " 0\n" + + " 0\n" + + " NNE\n" + + " 12\n" + + " 19\n" + + " 16\n" + + " 31\n" + + " 1015\n" + + " 24.135\n" + + " 1665464400\n" + + " 87\n" + + " null\n" + + " 11\n" + + " 0\n" + + " 7\n" + + " 28\n" + + " 15\n" + + " 14\n" + + " 62\n" + + " 8\n" + + " 26\n" + + " null\n" + + " NNE\n" + + " 17\n" + + " 29.98\n" + + " 79\n" + + " null\n" + + " true\n" + + " 21\n" + + " 51\n" + + " 8\n" + + " 1665502153\n" + + " 5450\n" + + " 15\n" + + " 17\n" + + " 71\n" + + " 9\n" + + " 28\n" + + " 28\n" + + " null\n" + + " \n" + + " \n" + + " 2022-10-12T07:00:00+02:00\n" + + " NNE\n" + + " 15\n" + + " 22\n" + + " 15\n" + + " 16\n" + + " 12\n" + + " NNE\n" + + " 2022-10-12T05:54:55+02:00\n" + + " null\n" + + " 14\n" + + " null\n" + + " 69\n" + + " 0\n" + + " Mostly Sunny\n" + + " 2022-10-12T17:28:04+02:00\n" + + " 31\n" + + " 68\n" + + " NNE\n" + + " 88\n" + + " 0\n" + + " 27\n" + + " 21\n" + + " 21\n" + + " Mostly Sunny\n" + + " 33\n" + + " 55\n" + + " 33\n" + + " 18\n" + + " 13\n" + + " 0\n" + + " 18\n" + + " 12\n" + + " 26\n" + + " 10\n" + + " 72\n" + + " 2022-10-12T07:00:00+02:00\n" + + " 11\n" + + " 743\n" + + " 26\n" + + " 18\n" + + " ::FW\n" + + " 1665546895\n" + + " 79\n" + + " NNE\n" + + " \n" + + " fair.png\n" + + " 22\n" + + " 16\n" + + " FW\n" + + " 72\n" + + " 29\n" + + " 60\n" + + " 10\n" + + " 0\n" + + " 0\n" + + " E\n" + + " 12\n" + + " 19\n" + + " 15\n" + + " 31\n" + + " 1014\n" + + " 24.135\n" + + " 1665550800\n" + + " 88\n" + + " null\n" + + " 11\n" + + " 0\n" + + " 7\n" + + " 96\n" + + " 15\n" + + " 13\n" + + " 60\n" + + " 8\n" + + " 26\n" + + " null\n" + + " E\n" + + " 16\n" + + " 29.95\n" + + " 80\n" + + " null\n" + + " true\n" + + " 21\n" + + " 51\n" + + " 8\n" + + " 1665588484\n" + + " 4740\n" + + " 15\n" + + " 17\n" + + " 68\n" + + " 9\n" + + " 28\n" + + " 96\n" + + " null\n" + + " \n" + + " day\n" + + " \n" + + " eg\n" + + " cairo\n" + + " qh\n" + + " \n" + + "\n" + + "null\n"; + assertEquals(actual, expected); + } } -- Gitee From 4a8ff28fd8af4ad7f68c12b8ed6029cbdd14dfd3 Mon Sep 17 00:00:00 2001 From: Dean Date: Fri, 7 Oct 2022 10:35:06 +0100 Subject: [PATCH 14/48] Reduced Test code length by using resources --- src/test/java/org/json/junit/XMLTest.java | 1437 +-------------------- src/test/resources/Issue593.json | 189 +++ src/test/resources/Issue593.xml | 169 +++ 3 files changed, 390 insertions(+), 1405 deletions(-) create mode 100644 src/test/resources/Issue593.json create mode 100644 src/test/resources/Issue593.xml diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 8d25b7e..4c46cf1 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -18,16 +18,11 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; -import org.json.XML; -import org.json.XMLParserConfiguration; -import org.json.XMLXsiTypeConverter; +import org.json.*; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -1222,1404 +1217,36 @@ public class XMLTest { @Test public void testIndentComplicatedJsonObjectWithArrayAndWithConfig(){ - String str = "{\n" + - " \"success\": true,\n" + - " \"error\": null,\n" + - " \"response\": [\n" + - " {\n" + - " \"loc\": {\n" + - " \"long\": 31.25,\n" + - " \"lat\": 30.063\n" + - " },\n" + - " \"interval\": \"day\",\n" + - " \"place\": {\n" + - " \"name\": \"cairo\",\n" + - " \"state\": \"qh\",\n" + - " \"country\": \"eg\"\n" + - " },\n" + - " \"periods\": [\n" + - " {\n" + - " \"timestamp\": 1665032400,\n" + - " \"validTime\": \"2022-10-06T07:00:00+02:00\",\n" + - " \"dateTimeISO\": \"2022-10-06T07:00:00+02:00\",\n" + - " \"maxTempC\": 32,\n" + - " \"maxTempF\": 90,\n" + - " \"minTempC\": 19,\n" + - " \"minTempF\": 66,\n" + - " \"avgTempC\": 25,\n" + - " \"avgTempF\": 78,\n" + - " \"tempC\": null,\n" + - " \"tempF\": null,\n" + - " \"maxFeelslikeC\": 32,\n" + - " \"maxFeelslikeF\": 89,\n" + - " \"minFeelslikeC\": 21,\n" + - " \"minFeelslikeF\": 70,\n" + - " \"avgFeelslikeC\": 26,\n" + - " \"avgFeelslikeF\": 80,\n" + - " \"feelslikeC\": 21,\n" + - " \"feelslikeF\": 70,\n" + - " \"maxDewpointC\": 17,\n" + - " \"maxDewpointF\": 63,\n" + - " \"minDewpointC\": 11,\n" + - " \"minDewpointF\": 52,\n" + - " \"avgDewpointC\": 14,\n" + - " \"avgDewpointF\": 58,\n" + - " \"dewpointC\": 17,\n" + - " \"dewpointF\": 63,\n" + - " \"maxHumidity\": 77,\n" + - " \"minHumidity\": 29,\n" + - " \"humidity\": 77,\n" + - " \"pop\": 0,\n" + - " \"precipMM\": 0,\n" + - " \"precipIN\": 0,\n" + - " \"iceaccum\": null,\n" + - " \"iceaccumMM\": null,\n" + - " \"iceaccumIN\": null,\n" + - " \"snowCM\": 0,\n" + - " \"snowIN\": 0,\n" + - " \"pressureMB\": 1015,\n" + - " \"pressureIN\": 29.97,\n" + - " \"windDir\": \"N\",\n" + - " \"windDirDEG\": 353,\n" + - " \"windSpeedKTS\": 5,\n" + - " \"windSpeedKPH\": 9,\n" + - " \"windSpeedMPH\": 6,\n" + - " \"windGustKTS\": 21,\n" + - " \"windGustKPH\": 40,\n" + - " \"windGustMPH\": 25,\n" + - " \"windDirMax\": \"NNW\",\n" + - " \"windDirMaxDEG\": 342,\n" + - " \"windSpeedMaxKTS\": 9,\n" + - " \"windSpeedMaxKPH\": 16,\n" + - " \"windSpeedMaxMPH\": 10,\n" + - " \"windDirMin\": \"N\",\n" + - " \"windDirMinDEG\": 353,\n" + - " \"windSpeedMinKTS\": 1,\n" + - " \"windSpeedMinKPH\": 2,\n" + - " \"windSpeedMinMPH\": 1,\n" + - " \"windDir80m\": \"N\",\n" + - " \"windDir80mDEG\": 11,\n" + - " \"windSpeed80mKTS\": 12,\n" + - " \"windSpeed80mKPH\": 22,\n" + - " \"windSpeed80mMPH\": 13,\n" + - " \"windGust80mKTS\": 22,\n" + - " \"windGust80mKPH\": 41,\n" + - " \"windGust80mMPH\": 25,\n" + - " \"windDirMax80m\": \"NNW\",\n" + - " \"windDirMax80mDEG\": 343,\n" + - " \"windSpeedMax80mKTS\": 22,\n" + - " \"windSpeedMax80mKPH\": 41,\n" + - " \"windSpeedMax80mMPH\": 25,\n" + - " \"windDirMin80m\": \"E\",\n" + - " \"windDirMin80mDEG\": 95,\n" + - " \"windSpeedMin80mKTS\": 8,\n" + - " \"windSpeedMin80mKPH\": 15,\n" + - " \"windSpeedMin80mMPH\": 10,\n" + - " \"sky\": 22,\n" + - " \"cloudsCoded\": \"FW\",\n" + - " \"weather\": \"Mostly Sunny\",\n" + - " \"weatherCoded\": [],\n" + - " \"weatherPrimary\": \"Mostly Sunny\",\n" + - " \"weatherPrimaryCoded\": \"::FW\",\n" + - " \"icon\": \"fair.png\",\n" + - " \"visibilityKM\": 24.135,\n" + - " \"visibilityMI\": 15,\n" + - " \"uvi\": 6,\n" + - " \"solradWM2\": 5608,\n" + - " \"solradMinWM2\": 0,\n" + - " \"solradMaxWM2\": 778,\n" + - " \"isDay\": true,\n" + - " \"maxCoverage\": \"\",\n" + - " \"sunrise\": 1665028274,\n" + - " \"sunset\": 1665070502,\n" + - " \"sunriseISO\": \"2022-10-06T05:51:14+02:00\",\n" + - " \"sunsetISO\": \"2022-10-06T17:35:02+02:00\"\n" + - " },\n" + - " {\n" + - " \"timestamp\": 1665118800,\n" + - " \"validTime\": \"2022-10-07T07:00:00+02:00\",\n" + - " \"dateTimeISO\": \"2022-10-07T07:00:00+02:00\",\n" + - " \"maxTempC\": 30,\n" + - " \"maxTempF\": 86,\n" + - " \"minTempC\": 19,\n" + - " \"minTempF\": 66,\n" + - " \"avgTempC\": 24,\n" + - " \"avgTempF\": 76,\n" + - " \"tempC\": null,\n" + - " \"tempF\": null,\n" + - " \"maxFeelslikeC\": 29,\n" + - " \"maxFeelslikeF\": 85,\n" + - " \"minFeelslikeC\": 19,\n" + - " \"minFeelslikeF\": 67,\n" + - " \"avgFeelslikeC\": 24,\n" + - " \"avgFeelslikeF\": 76,\n" + - " \"feelslikeC\": 19,\n" + - " \"feelslikeF\": 67,\n" + - " \"maxDewpointC\": 15,\n" + - " \"maxDewpointF\": 60,\n" + - " \"minDewpointC\": 10,\n" + - " \"minDewpointF\": 50,\n" + - " \"avgDewpointC\": 12,\n" + - " \"avgDewpointF\": 54,\n" + - " \"dewpointC\": 15,\n" + - " \"dewpointF\": 60,\n" + - " \"maxHumidity\": 77,\n" + - " \"minHumidity\": 30,\n" + - " \"humidity\": 77,\n" + - " \"pop\": 0,\n" + - " \"precipMM\": 0,\n" + - " \"precipIN\": 0,\n" + - " \"iceaccum\": null,\n" + - " \"iceaccumMM\": null,\n" + - " \"iceaccumIN\": null,\n" + - " \"snowCM\": 0,\n" + - " \"snowIN\": 0,\n" + - " \"pressureMB\": 1014,\n" + - " \"pressureIN\": 29.95,\n" + - " \"windDir\": \"NW\",\n" + - " \"windDirDEG\": 325,\n" + - " \"windSpeedKTS\": 1,\n" + - " \"windSpeedKPH\": 2,\n" + - " \"windSpeedMPH\": 1,\n" + - " \"windGustKTS\": 16,\n" + - " \"windGustKPH\": 29,\n" + - " \"windGustMPH\": 18,\n" + - " \"windDirMax\": \"WNW\",\n" + - " \"windDirMaxDEG\": 298,\n" + - " \"windSpeedMaxKTS\": 7,\n" + - " \"windSpeedMaxKPH\": 13,\n" + - " \"windSpeedMaxMPH\": 8,\n" + - " \"windDirMin\": \"NW\",\n" + - " \"windDirMinDEG\": 325,\n" + - " \"windSpeedMinKTS\": 1,\n" + - " \"windSpeedMinKPH\": 2,\n" + - " \"windSpeedMinMPH\": 1,\n" + - " \"windDir80m\": \"NNW\",\n" + - " \"windDir80mDEG\": 347,\n" + - " \"windSpeed80mKTS\": 6,\n" + - " \"windSpeed80mKPH\": 10,\n" + - " \"windSpeed80mMPH\": 6,\n" + - " \"windGust80mKTS\": 20,\n" + - " \"windGust80mKPH\": 37,\n" + - " \"windGust80mMPH\": 23,\n" + - " \"windDirMax80m\": \"NW\",\n" + - " \"windDirMax80mDEG\": 316,\n" + - " \"windSpeedMax80mKTS\": 20,\n" + - " \"windSpeedMax80mKPH\": 37,\n" + - " \"windSpeedMax80mMPH\": 23,\n" + - " \"windDirMin80m\": \"NNW\",\n" + - " \"windDirMin80mDEG\": 347,\n" + - " \"windSpeedMin80mKTS\": 6,\n" + - " \"windSpeedMin80mKPH\": 10,\n" + - " \"windSpeedMin80mMPH\": 6,\n" + - " \"sky\": 30,\n" + - " \"cloudsCoded\": \"FW\",\n" + - " \"weather\": \"Mostly Sunny\",\n" + - " \"weatherCoded\": [],\n" + - " \"weatherPrimary\": \"Mostly Sunny\",\n" + - " \"weatherPrimaryCoded\": \"::FW\",\n" + - " \"icon\": \"fair.png\",\n" + - " \"visibilityKM\": 24.135,\n" + - " \"visibilityMI\": 15,\n" + - " \"uvi\": 6,\n" + - " \"solradWM2\": 5486,\n" + - " \"solradMinWM2\": 0,\n" + - " \"solradMaxWM2\": 742,\n" + - " \"isDay\": true,\n" + - " \"maxCoverage\": \"\",\n" + - " \"sunrise\": 1665114710,\n" + - " \"sunset\": 1665156831,\n" + - " \"sunriseISO\": \"2022-10-07T05:51:50+02:00\",\n" + - " \"sunsetISO\": \"2022-10-07T17:33:51+02:00\"\n" + - " },\n" + - " {\n" + - " \"timestamp\": 1665205200,\n" + - " \"validTime\": \"2022-10-08T07:00:00+02:00\",\n" + - " \"dateTimeISO\": \"2022-10-08T07:00:00+02:00\",\n" + - " \"maxTempC\": 30,\n" + - " \"maxTempF\": 87,\n" + - " \"minTempC\": 19,\n" + - " \"minTempF\": 66,\n" + - " \"avgTempC\": 25,\n" + - " \"avgTempF\": 76,\n" + - " \"tempC\": null,\n" + - " \"tempF\": null,\n" + - " \"maxFeelslikeC\": 30,\n" + - " \"maxFeelslikeF\": 86,\n" + - " \"minFeelslikeC\": 19,\n" + - " \"minFeelslikeF\": 67,\n" + - " \"avgFeelslikeC\": 25,\n" + - " \"avgFeelslikeF\": 76,\n" + - " \"feelslikeC\": 19,\n" + - " \"feelslikeF\": 67,\n" + - " \"maxDewpointC\": 15,\n" + - " \"maxDewpointF\": 59,\n" + - " \"minDewpointC\": 11,\n" + - " \"minDewpointF\": 52,\n" + - " \"avgDewpointC\": 13,\n" + - " \"avgDewpointF\": 56,\n" + - " \"dewpointC\": 15,\n" + - " \"dewpointF\": 59,\n" + - " \"maxHumidity\": 76,\n" + - " \"minHumidity\": 32,\n" + - " \"humidity\": 76,\n" + - " \"pop\": 0,\n" + - " \"precipMM\": 0,\n" + - " \"precipIN\": 0,\n" + - " \"iceaccum\": null,\n" + - " \"iceaccumMM\": null,\n" + - " \"iceaccumIN\": null,\n" + - " \"snowCM\": 0,\n" + - " \"snowIN\": 0,\n" + - " \"pressureMB\": 1014,\n" + - " \"pressureIN\": 29.94,\n" + - " \"windDir\": \"NNE\",\n" + - " \"windDirDEG\": 21,\n" + - " \"windSpeedKTS\": 1,\n" + - " \"windSpeedKPH\": 2,\n" + - " \"windSpeedMPH\": 1,\n" + - " \"windGustKTS\": 17,\n" + - " \"windGustKPH\": 32,\n" + - " \"windGustMPH\": 20,\n" + - " \"windDirMax\": \"WNW\",\n" + - " \"windDirMaxDEG\": 301,\n" + - " \"windSpeedMaxKTS\": 7,\n" + - " \"windSpeedMaxKPH\": 13,\n" + - " \"windSpeedMaxMPH\": 8,\n" + - " \"windDirMin\": \"NNE\",\n" + - " \"windDirMinDEG\": 21,\n" + - " \"windSpeedMinKTS\": 1,\n" + - " \"windSpeedMinKPH\": 2,\n" + - " \"windSpeedMinMPH\": 1,\n" + - " \"windDir80m\": \"NW\",\n" + - " \"windDir80mDEG\": 309,\n" + - " \"windSpeed80mKTS\": 5,\n" + - " \"windSpeed80mKPH\": 9,\n" + - " \"windSpeed80mMPH\": 5,\n" + - " \"windGust80mKTS\": 17,\n" + - " \"windGust80mKPH\": 31,\n" + - " \"windGust80mMPH\": 19,\n" + - " \"windDirMax80m\": \"NW\",\n" + - " \"windDirMax80mDEG\": 322,\n" + - " \"windSpeedMax80mKTS\": 17,\n" + - " \"windSpeedMax80mKPH\": 31,\n" + - " \"windSpeedMax80mMPH\": 19,\n" + - " \"windDirMin80m\": \"NW\",\n" + - " \"windDirMin80mDEG\": 309,\n" + - " \"windSpeedMin80mKTS\": 5,\n" + - " \"windSpeedMin80mKPH\": 9,\n" + - " \"windSpeedMin80mMPH\": 5,\n" + - " \"sky\": 47,\n" + - " \"cloudsCoded\": \"SC\",\n" + - " \"weather\": \"Partly Cloudy\",\n" + - " \"weatherCoded\": [],\n" + - " \"weatherPrimary\": \"Partly Cloudy\",\n" + - " \"weatherPrimaryCoded\": \"::SC\",\n" + - " \"icon\": \"pcloudy.png\",\n" + - " \"visibilityKM\": 24.135,\n" + - " \"visibilityMI\": 15,\n" + - " \"uvi\": 7,\n" + - " \"solradWM2\": 4785,\n" + - " \"solradMinWM2\": 0,\n" + - " \"solradMaxWM2\": 682,\n" + - " \"isDay\": true,\n" + - " \"maxCoverage\": \"\",\n" + - " \"sunrise\": 1665201146,\n" + - " \"sunset\": 1665243161,\n" + - " \"sunriseISO\": \"2022-10-08T05:52:26+02:00\",\n" + - " \"sunsetISO\": \"2022-10-08T17:32:41+02:00\"\n" + - " },\n" + - " {\n" + - " \"timestamp\": 1665291600,\n" + - " \"validTime\": \"2022-10-09T07:00:00+02:00\",\n" + - " \"dateTimeISO\": \"2022-10-09T07:00:00+02:00\",\n" + - " \"maxTempC\": 31,\n" + - " \"maxTempF\": 87,\n" + - " \"minTempC\": 19,\n" + - " \"minTempF\": 67,\n" + - " \"avgTempC\": 25,\n" + - " \"avgTempF\": 77,\n" + - " \"tempC\": null,\n" + - " \"tempF\": null,\n" + - " \"maxFeelslikeC\": 30,\n" + - " \"maxFeelslikeF\": 86,\n" + - " \"minFeelslikeC\": 20,\n" + - " \"minFeelslikeF\": 67,\n" + - " \"avgFeelslikeC\": 25,\n" + - " \"avgFeelslikeF\": 77,\n" + - " \"feelslikeC\": 20,\n" + - " \"feelslikeF\": 67,\n" + - " \"maxDewpointC\": 17,\n" + - " \"maxDewpointF\": 63,\n" + - " \"minDewpointC\": 11,\n" + - " \"minDewpointF\": 52,\n" + - " \"avgDewpointC\": 14,\n" + - " \"avgDewpointF\": 57,\n" + - " \"dewpointC\": 17,\n" + - " \"dewpointF\": 63,\n" + - " \"maxHumidity\": 86,\n" + - " \"minHumidity\": 31,\n" + - " \"humidity\": 86,\n" + - " \"pop\": 0,\n" + - " \"precipMM\": 0,\n" + - " \"precipIN\": 0,\n" + - " \"iceaccum\": null,\n" + - " \"iceaccumMM\": null,\n" + - " \"iceaccumIN\": null,\n" + - " \"snowCM\": 0,\n" + - " \"snowIN\": 0,\n" + - " \"pressureMB\": 1016,\n" + - " \"pressureIN\": 29.99,\n" + - " \"windDir\": \"N\",\n" + - " \"windDirDEG\": 356,\n" + - " \"windSpeedKTS\": 2,\n" + - " \"windSpeedKPH\": 4,\n" + - " \"windSpeedMPH\": 2,\n" + - " \"windGustKTS\": 19,\n" + - " \"windGustKPH\": 36,\n" + - " \"windGustMPH\": 22,\n" + - " \"windDirMax\": \"NNW\",\n" + - " \"windDirMaxDEG\": 343,\n" + - " \"windSpeedMaxKTS\": 8,\n" + - " \"windSpeedMaxKPH\": 14,\n" + - " \"windSpeedMaxMPH\": 9,\n" + - " \"windDirMin\": \"N\",\n" + - " \"windDirMinDEG\": 356,\n" + - " \"windSpeedMinKTS\": 2,\n" + - " \"windSpeedMinKPH\": 4,\n" + - " \"windSpeedMinMPH\": 2,\n" + - " \"windDir80m\": \"NW\",\n" + - " \"windDir80mDEG\": 316,\n" + - " \"windSpeed80mKTS\": 5,\n" + - " \"windSpeed80mKPH\": 9,\n" + - " \"windSpeed80mMPH\": 6,\n" + - " \"windGust80mKTS\": 20,\n" + - " \"windGust80mKPH\": 36,\n" + - " \"windGust80mMPH\": 23,\n" + - " \"windDirMax80m\": \"N\",\n" + - " \"windDirMax80mDEG\": 354,\n" + - " \"windSpeedMax80mKTS\": 20,\n" + - " \"windSpeedMax80mKPH\": 36,\n" + - " \"windSpeedMax80mMPH\": 23,\n" + - " \"windDirMin80m\": \"NW\",\n" + - " \"windDirMin80mDEG\": 316,\n" + - " \"windSpeedMin80mKTS\": 5,\n" + - " \"windSpeedMin80mKPH\": 9,\n" + - " \"windSpeedMin80mMPH\": 6,\n" + - " \"sky\": 47,\n" + - " \"cloudsCoded\": \"SC\",\n" + - " \"weather\": \"Partly Cloudy\",\n" + - " \"weatherCoded\": [],\n" + - " \"weatherPrimary\": \"Partly Cloudy\",\n" + - " \"weatherPrimaryCoded\": \"::SC\",\n" + - " \"icon\": \"pcloudy.png\",\n" + - " \"visibilityKM\": 24.135,\n" + - " \"visibilityMI\": 15,\n" + - " \"uvi\": 7,\n" + - " \"solradWM2\": 4768,\n" + - " \"solradMinWM2\": 0,\n" + - " \"solradMaxWM2\": 726,\n" + - " \"isDay\": true,\n" + - " \"maxCoverage\": \"\",\n" + - " \"sunrise\": 1665287583,\n" + - " \"sunset\": 1665329491,\n" + - " \"sunriseISO\": \"2022-10-09T05:53:03+02:00\",\n" + - " \"sunsetISO\": \"2022-10-09T17:31:31+02:00\"\n" + - " },\n" + - " {\n" + - " \"timestamp\": 1665378000,\n" + - " \"validTime\": \"2022-10-10T07:00:00+02:00\",\n" + - " \"dateTimeISO\": \"2022-10-10T07:00:00+02:00\",\n" + - " \"maxTempC\": 31,\n" + - " \"maxTempF\": 87,\n" + - " \"minTempC\": 21,\n" + - " \"minTempF\": 70,\n" + - " \"avgTempC\": 26,\n" + - " \"avgTempF\": 78,\n" + - " \"tempC\": null,\n" + - " \"tempF\": null,\n" + - " \"maxFeelslikeC\": 30,\n" + - " \"maxFeelslikeF\": 86,\n" + - " \"minFeelslikeC\": 21,\n" + - " \"minFeelslikeF\": 69,\n" + - " \"avgFeelslikeC\": 25,\n" + - " \"avgFeelslikeF\": 78,\n" + - " \"feelslikeC\": 21,\n" + - " \"feelslikeF\": 69,\n" + - " \"maxDewpointC\": 16,\n" + - " \"maxDewpointF\": 61,\n" + - " \"minDewpointC\": 13,\n" + - " \"minDewpointF\": 55,\n" + - " \"avgDewpointC\": 14,\n" + - " \"avgDewpointF\": 58,\n" + - " \"dewpointC\": 16,\n" + - " \"dewpointF\": 61,\n" + - " \"maxHumidity\": 75,\n" + - " \"minHumidity\": 35,\n" + - " \"humidity\": 75,\n" + - " \"pop\": 0,\n" + - " \"precipMM\": 0,\n" + - " \"precipIN\": 0,\n" + - " \"iceaccum\": null,\n" + - " \"iceaccumMM\": null,\n" + - " \"iceaccumIN\": null,\n" + - " \"snowCM\": 0,\n" + - " \"snowIN\": 0,\n" + - " \"pressureMB\": 1017,\n" + - " \"pressureIN\": 30.03,\n" + - " \"windDir\": \"N\",\n" + - " \"windDirDEG\": 358,\n" + - " \"windSpeedKTS\": 2,\n" + - " \"windSpeedKPH\": 4,\n" + - " \"windSpeedMPH\": 2,\n" + - " \"windGustKTS\": 16,\n" + - " \"windGustKPH\": 30,\n" + - " \"windGustMPH\": 19,\n" + - " \"windDirMax\": \"N\",\n" + - " \"windDirMaxDEG\": 10,\n" + - " \"windSpeedMaxKTS\": 8,\n" + - " \"windSpeedMaxKPH\": 15,\n" + - " \"windSpeedMaxMPH\": 9,\n" + - " \"windDirMin\": \"N\",\n" + - " \"windDirMinDEG\": 358,\n" + - " \"windSpeedMinKTS\": 2,\n" + - " \"windSpeedMinKPH\": 4,\n" + - " \"windSpeedMinMPH\": 2,\n" + - " \"windDir80m\": \"N\",\n" + - " \"windDir80mDEG\": 8,\n" + - " \"windSpeed80mKTS\": 7,\n" + - " \"windSpeed80mKPH\": 13,\n" + - " \"windSpeed80mMPH\": 8,\n" + - " \"windGust80mKTS\": 19,\n" + - " \"windGust80mKPH\": 36,\n" + - " \"windGust80mMPH\": 22,\n" + - " \"windDirMax80m\": \"N\",\n" + - " \"windDirMax80mDEG\": 10,\n" + - " \"windSpeedMax80mKTS\": 19,\n" + - " \"windSpeedMax80mKPH\": 36,\n" + - " \"windSpeedMax80mMPH\": 22,\n" + - " \"windDirMin80m\": \"E\",\n" + - " \"windDirMin80mDEG\": 91,\n" + - " \"windSpeedMin80mKTS\": 7,\n" + - " \"windSpeedMin80mKPH\": 13,\n" + - " \"windSpeedMin80mMPH\": 8,\n" + - " \"sky\": 64,\n" + - " \"cloudsCoded\": \"SC\",\n" + - " \"weather\": \"Partly Cloudy\",\n" + - " \"weatherCoded\": [],\n" + - " \"weatherPrimary\": \"Partly Cloudy\",\n" + - " \"weatherPrimaryCoded\": \"::SC\",\n" + - " \"icon\": \"pcloudy.png\",\n" + - " \"visibilityKM\": 24.135,\n" + - " \"visibilityMI\": 15,\n" + - " \"uvi\": 6,\n" + - " \"solradWM2\": 4494,\n" + - " \"solradMinWM2\": 0,\n" + - " \"solradMaxWM2\": 597,\n" + - " \"isDay\": true,\n" + - " \"maxCoverage\": \"\",\n" + - " \"sunrise\": 1665374020,\n" + - " \"sunset\": 1665415821,\n" + - " \"sunriseISO\": \"2022-10-10T05:53:40+02:00\",\n" + - " \"sunsetISO\": \"2022-10-10T17:30:21+02:00\"\n" + - " },\n" + - " {\n" + - " \"timestamp\": 1665464400,\n" + - " \"validTime\": \"2022-10-11T07:00:00+02:00\",\n" + - " \"dateTimeISO\": \"2022-10-11T07:00:00+02:00\",\n" + - " \"maxTempC\": 31,\n" + - " \"maxTempF\": 87,\n" + - " \"minTempC\": 21,\n" + - " \"minTempF\": 70,\n" + - " \"avgTempC\": 26,\n" + - " \"avgTempF\": 78,\n" + - " \"tempC\": null,\n" + - " \"tempF\": null,\n" + - " \"maxFeelslikeC\": 31,\n" + - " \"maxFeelslikeF\": 87,\n" + - " \"minFeelslikeC\": 22,\n" + - " \"minFeelslikeF\": 72,\n" + - " \"avgFeelslikeC\": 26,\n" + - " \"avgFeelslikeF\": 79,\n" + - " \"feelslikeC\": 22,\n" + - " \"feelslikeF\": 72,\n" + - " \"maxDewpointC\": 17,\n" + - " \"maxDewpointF\": 62,\n" + - " \"minDewpointC\": 11,\n" + - " \"minDewpointF\": 51,\n" + - " \"avgDewpointC\": 13,\n" + - " \"avgDewpointF\": 55,\n" + - " \"dewpointC\": 17,\n" + - " \"dewpointF\": 62,\n" + - " \"maxHumidity\": 71,\n" + - " \"minHumidity\": 30,\n" + - " \"humidity\": 71,\n" + - " \"pop\": 0,\n" + - " \"precipMM\": 0,\n" + - " \"precipIN\": 0,\n" + - " \"iceaccum\": null,\n" + - " \"iceaccumMM\": null,\n" + - " \"iceaccumIN\": null,\n" + - " \"snowCM\": 0,\n" + - " \"snowIN\": 0,\n" + - " \"pressureMB\": 1015,\n" + - " \"pressureIN\": 29.98,\n" + - " \"windDir\": \"NNE\",\n" + - " \"windDirDEG\": 13,\n" + - " \"windSpeedKTS\": 8,\n" + - " \"windSpeedKPH\": 15,\n" + - " \"windSpeedMPH\": 9,\n" + - " \"windGustKTS\": 15,\n" + - " \"windGustKPH\": 28,\n" + - " \"windGustMPH\": 17,\n" + - " \"windDirMax\": \"NNE\",\n" + - " \"windDirMaxDEG\": 28,\n" + - " \"windSpeedMaxKTS\": 15,\n" + - " \"windSpeedMaxKPH\": 28,\n" + - " \"windSpeedMaxMPH\": 18,\n" + - " \"windDirMin\": \"NNE\",\n" + - " \"windDirMinDEG\": 14,\n" + - " \"windSpeedMinKTS\": 7,\n" + - " \"windSpeedMinKPH\": 14,\n" + - " \"windSpeedMinMPH\": 8,\n" + - " \"windDir80m\": \"NNE\",\n" + - " \"windDir80mDEG\": 16,\n" + - " \"windSpeed80mKTS\": 10,\n" + - " \"windSpeed80mKPH\": 19,\n" + - " \"windSpeed80mMPH\": 12,\n" + - " \"windGust80mKTS\": 17,\n" + - " \"windGust80mKPH\": 31,\n" + - " \"windGust80mMPH\": 19,\n" + - " \"windDirMax80m\": \"NNE\",\n" + - " \"windDirMax80mDEG\": 28,\n" + - " \"windSpeedMax80mKTS\": 17,\n" + - " \"windSpeedMax80mKPH\": 31,\n" + - " \"windSpeedMax80mMPH\": 19,\n" + - " \"windDirMin80m\": \"NNE\",\n" + - " \"windDirMin80mDEG\": 13,\n" + - " \"windSpeedMin80mKTS\": 9,\n" + - " \"windSpeedMin80mKPH\": 18,\n" + - " \"windSpeedMin80mMPH\": 11,\n" + - " \"sky\": 0,\n" + - " \"cloudsCoded\": \"CL\",\n" + - " \"weather\": \"Sunny\",\n" + - " \"weatherCoded\": [],\n" + - " \"weatherPrimary\": \"Sunny\",\n" + - " \"weatherPrimaryCoded\": \"::CL\",\n" + - " \"icon\": \"sunny.png\",\n" + - " \"visibilityKM\": 24.135,\n" + - " \"visibilityMI\": 15,\n" + - " \"uvi\": null,\n" + - " \"solradWM2\": 5450,\n" + - " \"solradMinWM2\": 0,\n" + - " \"solradMaxWM2\": 758,\n" + - " \"isDay\": true,\n" + - " \"maxCoverage\": \"\",\n" + - " \"sunrise\": 1665460458,\n" + - " \"sunset\": 1665502153,\n" + - " \"sunriseISO\": \"2022-10-11T05:54:18+02:00\",\n" + - " \"sunsetISO\": \"2022-10-11T17:29:13+02:00\"\n" + - " },\n" + - " {\n" + - " \"timestamp\": 1665550800,\n" + - " \"validTime\": \"2022-10-12T07:00:00+02:00\",\n" + - " \"dateTimeISO\": \"2022-10-12T07:00:00+02:00\",\n" + - " \"maxTempC\": 31,\n" + - " \"maxTempF\": 88,\n" + - " \"minTempC\": 21,\n" + - " \"minTempF\": 69,\n" + - " \"avgTempC\": 26,\n" + - " \"avgTempF\": 79,\n" + - " \"tempC\": null,\n" + - " \"tempF\": null,\n" + - " \"maxFeelslikeC\": 31,\n" + - " \"maxFeelslikeF\": 88,\n" + - " \"minFeelslikeC\": 22,\n" + - " \"minFeelslikeF\": 72,\n" + - " \"avgFeelslikeC\": 26,\n" + - " \"avgFeelslikeF\": 80,\n" + - " \"feelslikeC\": 22,\n" + - " \"feelslikeF\": 72,\n" + - " \"maxDewpointC\": 16,\n" + - " \"maxDewpointF\": 60,\n" + - " \"minDewpointC\": 11,\n" + - " \"minDewpointF\": 51,\n" + - " \"avgDewpointC\": 13,\n" + - " \"avgDewpointF\": 55,\n" + - " \"dewpointC\": 16,\n" + - " \"dewpointF\": 60,\n" + - " \"maxHumidity\": 68,\n" + - " \"minHumidity\": 29,\n" + - " \"humidity\": 68,\n" + - " \"pop\": 0,\n" + - " \"precipMM\": 0,\n" + - " \"precipIN\": 0,\n" + - " \"iceaccum\": null,\n" + - " \"iceaccumMM\": null,\n" + - " \"iceaccumIN\": null,\n" + - " \"snowCM\": 0,\n" + - " \"snowIN\": 0,\n" + - " \"pressureMB\": 1014,\n" + - " \"pressureIN\": 29.95,\n" + - " \"windDir\": \"NNE\",\n" + - " \"windDirDEG\": 12,\n" + - " \"windSpeedKTS\": 8,\n" + - " \"windSpeedKPH\": 15,\n" + - " \"windSpeedMPH\": 9,\n" + - " \"windGustKTS\": 15,\n" + - " \"windGustKPH\": 28,\n" + - " \"windGustMPH\": 17,\n" + - " \"windDirMax\": \"E\",\n" + - " \"windDirMaxDEG\": 96,\n" + - " \"windSpeedMaxKTS\": 14,\n" + - " \"windSpeedMaxKPH\": 26,\n" + - " \"windSpeedMaxMPH\": 16,\n" + - " \"windDirMin\": \"NNE\",\n" + - " \"windDirMinDEG\": 12,\n" + - " \"windSpeedMinKTS\": 7,\n" + - " \"windSpeedMinKPH\": 13,\n" + - " \"windSpeedMinMPH\": 8,\n" + - " \"windDir80m\": \"NNE\",\n" + - " \"windDir80mDEG\": 15,\n" + - " \"windSpeed80mKTS\": 10,\n" + - " \"windSpeed80mKPH\": 19,\n" + - " \"windSpeed80mMPH\": 12,\n" + - " \"windGust80mKTS\": 18,\n" + - " \"windGust80mKPH\": 33,\n" + - " \"windGust80mMPH\": 21,\n" + - " \"windDirMax80m\": \"E\",\n" + - " \"windDirMax80mDEG\": 96,\n" + - " \"windSpeedMax80mKTS\": 18,\n" + - " \"windSpeedMax80mKPH\": 33,\n" + - " \"windSpeedMax80mMPH\": 21,\n" + - " \"windDirMin80m\": \"NNE\",\n" + - " \"windDirMin80mDEG\": 15,\n" + - " \"windSpeedMin80mKTS\": 10,\n" + - " \"windSpeedMin80mKPH\": 18,\n" + - " \"windSpeedMin80mMPH\": 11,\n" + - " \"sky\": 27,\n" + - " \"cloudsCoded\": \"FW\",\n" + - " \"weather\": \"Mostly Sunny\",\n" + - " \"weatherCoded\": [],\n" + - " \"weatherPrimary\": \"Mostly Sunny\",\n" + - " \"weatherPrimaryCoded\": \"::FW\",\n" + - " \"icon\": \"fair.png\",\n" + - " \"visibilityKM\": 24.135,\n" + - " \"visibilityMI\": 15,\n" + - " \"uvi\": null,\n" + - " \"solradWM2\": 4740,\n" + - " \"solradMinWM2\": 0,\n" + - " \"solradMaxWM2\": 743,\n" + - " \"isDay\": true,\n" + - " \"maxCoverage\": \"\",\n" + - " \"sunrise\": 1665546895,\n" + - " \"sunset\": 1665588484,\n" + - " \"sunriseISO\": \"2022-10-12T05:54:55+02:00\",\n" + - " \"sunsetISO\": \"2022-10-12T17:28:04+02:00\"\n" + - " }\n" + - " ],\n" + - " \"profile\": {\n" + - " \"tz\": \"Africa/Cairo\",\n" + - " \"elevM\": 23,\n" + - " \"elevFT\": 75\n" + - " }\n" + - " }\n" + - " ]\n" + - "}"; - JSONObject jsonObject = new JSONObject(str); - String actual = XML.toString(jsonObject, null, XMLParserConfiguration.KEEP_STRINGS,2); - String expected = "true\n" + - "\n" + - " \n" + - " 31.25\n" + - " 30.063\n" + - " \n" + - " \n" + - " 23\n" + - " Africa/Cairo\n" + - " 75\n" + - " \n" + - " \n" + - " 2022-10-06T07:00:00+02:00\n" + - " E\n" + - " 95\n" + - " 21\n" + - " 15\n" + - " 10\n" + - " 353\n" + - " N\n" + - " 2022-10-06T05:51:14+02:00\n" + - " null\n" + - " 9\n" + - " null\n" + - " 66\n" + - " 0\n" + - " Mostly Sunny\n" + - " 2022-10-06T17:35:02+02:00\n" + - " 32\n" + - " 77\n" + - " N\n" + - " 89\n" + - " 0\n" + - " 22\n" + - " 25\n" + - " 25\n" + - " Mostly Sunny\n" + - " 41\n" + - " 58\n" + - " 41\n" + - " 22\n" + - " 14\n" + - " 0\n" + - " 22\n" + - " 353\n" + - " 16\n" + - " 8\n" + - " 70\n" + - " 2022-10-06T07:00:00+02:00\n" + - " 10\n" + - " 778\n" + - " 25\n" + - " 15\n" + - " ::FW\n" + - " 1665028274\n" + - " 78\n" + - " N\n" + - " \n" + - " fair.png\n" + - " 21\n" + - " 17\n" + - " FW\n" + - " 70\n" + - " 29\n" + - " 63\n" + - " 12\n" + - " 0\n" + - " 0\n" + - " NNW\n" + - " 13\n" + - " 22\n" + - " 11\n" + - " 32\n" + - " 1015\n" + - " 24.135\n" + - " 1665032400\n" + - " 90\n" + - " null\n" + - " 11\n" + - " 0\n" + - " 1\n" + - " 343\n" + - " 21\n" + - " 2\n" + - " 63\n" + - " 1\n" + - " 26\n" + - " 6\n" + - " NNW\n" + - " 17\n" + - " 29.97\n" + - " 80\n" + - " null\n" + - " true\n" + - " 19\n" + - " 52\n" + - " 5\n" + - " 1665070502\n" + - " 5608\n" + - " 9\n" + - " 25\n" + - " 77\n" + - " 6\n" + - " 40\n" + - " 342\n" + - " null\n" + - " \n" + - " \n" + - " 2022-10-07T07:00:00+02:00\n" + - " NNW\n" + - " 347\n" + - " 19\n" + - " 15\n" + - " 8\n" + - " 325\n" + - " NW\n" + - " 2022-10-07T05:51:50+02:00\n" + - " null\n" + - " 7\n" + - " null\n" + - " 66\n" + - " 0\n" + - " Mostly Sunny\n" + - " 2022-10-07T17:33:51+02:00\n" + - " 29\n" + - " 77\n" + - " NNW\n" + - " 85\n" + - " 0\n" + - " 30\n" + - " 23\n" + - " 23\n" + - " Mostly Sunny\n" + - " 37\n" + - " 54\n" + - " 37\n" + - " 20\n" + - " 12\n" + - " 0\n" + - " 20\n" + - " 325\n" + - " 13\n" + - " 6\n" + - " 67\n" + - " 2022-10-07T07:00:00+02:00\n" + - " 6\n" + - " 742\n" + - " 24\n" + - " 10\n" + - " ::FW\n" + - " 1665114710\n" + - " 76\n" + - " NW\n" + - " \n" + - " fair.png\n" + - " 19\n" + - " 15\n" + - " FW\n" + - " 67\n" + - " 30\n" + - " 60\n" + - " 6\n" + - " 0\n" + - " 0\n" + - " WNW\n" + - " 6\n" + - " 10\n" + - " 347\n" + - " 30\n" + - " 1014\n" + - " 24.135\n" + - " 1665118800\n" + - " 86\n" + - " null\n" + - " 10\n" + - " 0\n" + - " 1\n" + - " 316\n" + - " 16\n" + - " 2\n" + - " 60\n" + - " 1\n" + - " 24\n" + - " 6\n" + - " NW\n" + - " 15\n" + - " 29.95\n" + - " 76\n" + - " null\n" + - " true\n" + - " 19\n" + - " 50\n" + - " 1\n" + - " 1665156831\n" + - " 5486\n" + - " 2\n" + - " 18\n" + - " 77\n" + - " 1\n" + - " 29\n" + - " 298\n" + - " null\n" + - " \n" + - " \n" + - " 2022-10-08T07:00:00+02:00\n" + - " NW\n" + - " 309\n" + - " 19\n" + - " 15\n" + - " 8\n" + - " 21\n" + - " NNE\n" + - " 2022-10-08T05:52:26+02:00\n" + - " null\n" + - " 7\n" + - " null\n" + - " 66\n" + - " 0\n" + - " Partly Cloudy\n" + - " 2022-10-08T17:32:41+02:00\n" + - " 30\n" + - " 76\n" + - " NW\n" + - " 86\n" + - " 0\n" + - " 47\n" + - " 19\n" + - " 19\n" + - " Partly Cloudy\n" + - " 31\n" + - " 56\n" + - " 31\n" + - " 17\n" + - " 13\n" + - " 0\n" + - " 17\n" + - " 21\n" + - " 13\n" + - " 5\n" + - " 67\n" + - " 2022-10-08T07:00:00+02:00\n" + - " 5\n" + - " 682\n" + - " 25\n" + - " 9\n" + - " ::SC\n" + - " 1665201146\n" + - " 76\n" + - " NNE\n" + - " \n" + - " pcloudy.png\n" + - " 19\n" + - " 15\n" + - " SC\n" + - " 67\n" + - " 32\n" + - " 59\n" + - " 5\n" + - " 0\n" + - " 0\n" + - " WNW\n" + - " 5\n" + - " 9\n" + - " 309\n" + - " 30\n" + - " 1014\n" + - " 24.135\n" + - " 1665205200\n" + - " 87\n" + - " null\n" + - " 11\n" + - " 0\n" + - " 1\n" + - " 322\n" + - " 17\n" + - " 2\n" + - " 59\n" + - " 1\n" + - " 25\n" + - " 7\n" + - " NW\n" + - " 15\n" + - " 29.94\n" + - " 76\n" + - " null\n" + - " true\n" + - " 19\n" + - " 52\n" + - " 1\n" + - " 1665243161\n" + - " 4785\n" + - " 2\n" + - " 20\n" + - " 76\n" + - " 1\n" + - " 32\n" + - " 301\n" + - " null\n" + - " \n" + - " \n" + - " 2022-10-09T07:00:00+02:00\n" + - " NW\n" + - " 316\n" + - " 20\n" + - " 15\n" + - " 9\n" + - " 356\n" + - " N\n" + - " 2022-10-09T05:53:03+02:00\n" + - " null\n" + - " 8\n" + - " null\n" + - " 67\n" + - " 0\n" + - " Partly Cloudy\n" + - " 2022-10-09T17:31:31+02:00\n" + - " 30\n" + - " 86\n" + - " NW\n" + - " 86\n" + - " 0\n" + - " 47\n" + - " 23\n" + - " 23\n" + - " Partly Cloudy\n" + - " 36\n" + - " 57\n" + - " 36\n" + - " 20\n" + - " 14\n" + - " 0\n" + - " 20\n" + - " 356\n" + - " 14\n" + - " 5\n" + - " 67\n" + - " 2022-10-09T07:00:00+02:00\n" + - " 6\n" + - " 726\n" + - " 25\n" + - " 9\n" + - " ::SC\n" + - " 1665287583\n" + - " 77\n" + - " N\n" + - " \n" + - " pcloudy.png\n" + - " 20\n" + - " 17\n" + - " SC\n" + - " 67\n" + - " 31\n" + - " 63\n" + - " 5\n" + - " 0\n" + - " 0\n" + - " NNW\n" + - " 6\n" + - " 9\n" + - " 316\n" + - " 31\n" + - " 1016\n" + - " 24.135\n" + - " 1665291600\n" + - " 87\n" + - " null\n" + - " 11\n" + - " 0\n" + - " 2\n" + - " 354\n" + - " 19\n" + - " 4\n" + - " 63\n" + - " 2\n" + - " 25\n" + - " 7\n" + - " N\n" + - " 17\n" + - " 29.99\n" + - " 77\n" + - " null\n" + - " true\n" + - " 19\n" + - " 52\n" + - " 2\n" + - " 1665329491\n" + - " 4768\n" + - " 4\n" + - " 22\n" + - " 86\n" + - " 2\n" + - " 36\n" + - " 343\n" + - " null\n" + - " \n" + - " \n" + - " 2022-10-10T07:00:00+02:00\n" + - " E\n" + - " 91\n" + - " 21\n" + - " 15\n" + - " 9\n" + - " 358\n" + - " N\n" + - " 2022-10-10T05:53:40+02:00\n" + - " null\n" + - " 8\n" + - " null\n" + - " 70\n" + - " 0\n" + - " Partly Cloudy\n" + - " 2022-10-10T17:30:21+02:00\n" + - " 30\n" + - " 75\n" + - " N\n" + - " 86\n" + - " 0\n" + - " 64\n" + - " 22\n" + - " 22\n" + - " Partly Cloudy\n" + - " 36\n" + - " 58\n" + - " 36\n" + - " 19\n" + - " 14\n" + - " 0\n" + - " 19\n" + - " 358\n" + - " 15\n" + - " 7\n" + - " 69\n" + - " 2022-10-10T07:00:00+02:00\n" + - " 8\n" + - " 597\n" + - " 26\n" + - " 13\n" + - " ::SC\n" + - " 1665374020\n" + - " 78\n" + - " N\n" + - " \n" + - " pcloudy.png\n" + - " 21\n" + - " 16\n" + - " SC\n" + - " 69\n" + - " 35\n" + - " 61\n" + - " 7\n" + - " 0\n" + - " 0\n" + - " N\n" + - " 8\n" + - " 13\n" + - " 8\n" + - " 31\n" + - " 1017\n" + - " 24.135\n" + - " 1665378000\n" + - " 87\n" + - " null\n" + - " 13\n" + - " 0\n" + - " 2\n" + - " 10\n" + - " 16\n" + - " 4\n" + - " 61\n" + - " 2\n" + - " 25\n" + - " 6\n" + - " N\n" + - " 16\n" + - " 30.03\n" + - " 78\n" + - " null\n" + - " true\n" + - " 21\n" + - " 55\n" + - " 2\n" + - " 1665415821\n" + - " 4494\n" + - " 4\n" + - " 19\n" + - " 75\n" + - " 2\n" + - " 30\n" + - " 10\n" + - " null\n" + - " \n" + - " \n" + - " 2022-10-11T07:00:00+02:00\n" + - " NNE\n" + - " 13\n" + - " 22\n" + - " 15\n" + - " 18\n" + - " 13\n" + - " NNE\n" + - " 2022-10-11T05:54:18+02:00\n" + - " null\n" + - " 15\n" + - " null\n" + - " 70\n" + - " 0\n" + - " Sunny\n" + - " 2022-10-11T17:29:13+02:00\n" + - " 31\n" + - " 71\n" + - " NNE\n" + - " 87\n" + - " 0\n" + - " 0\n" + - " 19\n" + - " 19\n" + - " Sunny\n" + - " 31\n" + - " 55\n" + - " 31\n" + - " 17\n" + - " 13\n" + - " 0\n" + - " 17\n" + - " 14\n" + - " 28\n" + - " 9\n" + - " 72\n" + - " 2022-10-11T07:00:00+02:00\n" + - " 11\n" + - " 758\n" + - " 26\n" + - " 18\n" + - " ::CL\n" + - " 1665460458\n" + - " 78\n" + - " NNE\n" + - " \n" + - " sunny.png\n" + - " 22\n" + - " 17\n" + - " CL\n" + - " 72\n" + - " 30\n" + - " 62\n" + - " 10\n" + - " 0\n" + - " 0\n" + - " NNE\n" + - " 12\n" + - " 19\n" + - " 16\n" + - " 31\n" + - " 1015\n" + - " 24.135\n" + - " 1665464400\n" + - " 87\n" + - " null\n" + - " 11\n" + - " 0\n" + - " 7\n" + - " 28\n" + - " 15\n" + - " 14\n" + - " 62\n" + - " 8\n" + - " 26\n" + - " null\n" + - " NNE\n" + - " 17\n" + - " 29.98\n" + - " 79\n" + - " null\n" + - " true\n" + - " 21\n" + - " 51\n" + - " 8\n" + - " 1665502153\n" + - " 5450\n" + - " 15\n" + - " 17\n" + - " 71\n" + - " 9\n" + - " 28\n" + - " 28\n" + - " null\n" + - " \n" + - " \n" + - " 2022-10-12T07:00:00+02:00\n" + - " NNE\n" + - " 15\n" + - " 22\n" + - " 15\n" + - " 16\n" + - " 12\n" + - " NNE\n" + - " 2022-10-12T05:54:55+02:00\n" + - " null\n" + - " 14\n" + - " null\n" + - " 69\n" + - " 0\n" + - " Mostly Sunny\n" + - " 2022-10-12T17:28:04+02:00\n" + - " 31\n" + - " 68\n" + - " NNE\n" + - " 88\n" + - " 0\n" + - " 27\n" + - " 21\n" + - " 21\n" + - " Mostly Sunny\n" + - " 33\n" + - " 55\n" + - " 33\n" + - " 18\n" + - " 13\n" + - " 0\n" + - " 18\n" + - " 12\n" + - " 26\n" + - " 10\n" + - " 72\n" + - " 2022-10-12T07:00:00+02:00\n" + - " 11\n" + - " 743\n" + - " 26\n" + - " 18\n" + - " ::FW\n" + - " 1665546895\n" + - " 79\n" + - " NNE\n" + - " \n" + - " fair.png\n" + - " 22\n" + - " 16\n" + - " FW\n" + - " 72\n" + - " 29\n" + - " 60\n" + - " 10\n" + - " 0\n" + - " 0\n" + - " E\n" + - " 12\n" + - " 19\n" + - " 15\n" + - " 31\n" + - " 1014\n" + - " 24.135\n" + - " 1665550800\n" + - " 88\n" + - " null\n" + - " 11\n" + - " 0\n" + - " 7\n" + - " 96\n" + - " 15\n" + - " 13\n" + - " 60\n" + - " 8\n" + - " 26\n" + - " null\n" + - " E\n" + - " 16\n" + - " 29.95\n" + - " 80\n" + - " null\n" + - " true\n" + - " 21\n" + - " 51\n" + - " 8\n" + - " 1665588484\n" + - " 4740\n" + - " 15\n" + - " 17\n" + - " 68\n" + - " 9\n" + - " 28\n" + - " 96\n" + - " null\n" + - " \n" + - " day\n" + - " \n" + - " eg\n" + - " cairo\n" + - " qh\n" + - " \n" + - "\n" + - "null\n"; - assertEquals(actual, expected); + try { + InputStream jsonStream = null; + try { + jsonStream = XMLTest.class.getClassLoader().getResourceAsStream("Issue593.json"); + final JSONObject object = new JSONObject(new JSONTokener(jsonStream)); + String actualString = XML.toString(object, null, XMLParserConfiguration.KEEP_STRINGS,2); + InputStream xmlStream = null; + try { + xmlStream = XMLTest.class.getClassLoader().getResourceAsStream("Issue593.xml"); + int bufferSize = 1024; + char[] buffer = new char[bufferSize]; + StringBuilder expected = new StringBuilder(); + Reader in = new InputStreamReader(xmlStream, "UTF-8"); + for (int numRead; (numRead = in.read(buffer, 0, buffer.length)) > 0; ) { + expected.append(buffer, 0, numRead); + } + assertEquals(expected.toString(), actualString); + } finally { + if (xmlStream != null) { + xmlStream.close(); + } + } + } finally { + if (jsonStream != null) { + jsonStream.close(); + } + } + } catch (IOException e) { + fail("file writer error: " +e.getMessage()); + } } } diff --git a/src/test/resources/Issue593.json b/src/test/resources/Issue593.json new file mode 100644 index 0000000..b3c82fe --- /dev/null +++ b/src/test/resources/Issue593.json @@ -0,0 +1,189 @@ +{ + "clinical_study": { + "brief_summary": { + "textblock": "CLEAR SYNERGY is an international multi center 2x2 randomized placebo controlled trial of" + }, + "brief_title": "CLEAR SYNERGY Neutrophil Substudy", + "overall_status": "Recruiting", + "eligibility": { + "study_pop": { + "textblock": "Patients who are randomized to the drug RCT portion of the CLEAR SYNERGY (OASIS 9) trial" + }, + "minimum_age": "19 Years", + "sampling_method": "Non-Probability Sample", + "gender": "All", + "criteria": { + "textblock": "Inclusion Criteria:" + }, + "healthy_volunteers": "No", + "maximum_age": "110 Years" + }, + "number_of_groups": "2", + "source": "NYU Langone Health", + "location_countries": { + "country": "United States" + }, + "study_design_info": { + "time_perspective": "Prospective", + "observational_model": "Other" + }, + "last_update_submitted_qc": "September 10, 2019", + "intervention_browse": { + "mesh_term": "Colchicine" + }, + "official_title": "Studies on the Effects of Colchicine on Neutrophil Biology in Acute Myocardial Infarction: A Substudy of the CLEAR SYNERGY (OASIS 9) Trial", + "primary_completion_date": { + "type": "Anticipated", + "content": "February 1, 2021" + }, + "sponsors": { + "lead_sponsor": { + "agency_class": "Other", + "agency": "NYU Langone Health" + }, + "collaborator": [ + { + "agency_class": "Other", + "agency": "Population Health Research Institute" + }, + { + "agency_class": "NIH", + "agency": "National Heart, Lung, and Blood Institute (NHLBI)" + } + ] + }, + "overall_official": { + "role": "Principal Investigator", + "affiliation": "NYU School of Medicine", + "last_name": "Binita Shah, MD" + }, + "overall_contact_backup": { + "last_name": "Binita Shah, MD" + }, + "condition_browse": { + "mesh_term": [ + "Myocardial Infarction", + "ST Elevation Myocardial Infarction", + "Infarction" + ] + }, + "overall_contact": { + "phone": "646-501-9648", + "last_name": "Fatmira Curovic", + "email": "fatmira.curovic@nyumc.org" + }, + "responsible_party": { + "responsible_party_type": "Principal Investigator", + "investigator_title": "Assistant Professor of Medicine", + "investigator_full_name": "Binita Shah", + "investigator_affiliation": "NYU Langone Health" + }, + "study_first_submitted_qc": "March 12, 2019", + "start_date": { + "type": "Actual", + "content": "March 4, 2019" + }, + "has_expanded_access": "No", + "study_first_posted": { + "type": "Actual", + "content": "March 14, 2019" + }, + "arm_group": [ + { + "arm_group_label": "Colchicine" + }, + { + "arm_group_label": "Placebo" + } + ], + "primary_outcome": { + "measure": "soluble L-selectin", + "time_frame": "between baseline and 3 months", + "description": "Change in soluble L-selectin between baseline and 3 mo after STEMI in the placebo vs. colchicine groups." + }, + "secondary_outcome": [ + { + "measure": "Other soluble markers of neutrophil activity", + "time_frame": "between baseline and 3 months", + "description": "Other markers of neutrophil activity will be evaluated at baseline and 3 months after STEMI (myeloperoxidase, matrix metalloproteinase-9, neutrophil gelatinase-associated lipocalin, neutrophil elastase, intercellular/vascular cellular adhesion molecules)" + }, + { + "measure": "Markers of systemic inflammation", + "time_frame": "between baseline and 3 months", + "description": "Markers of systemic inflammation will be evaluated at baseline and 3 months after STEMI (high sensitive CRP, IL-1β)" + }, + { + "measure": "Neutrophil-driven responses that may further propagate injury", + "time_frame": "between baseline and 3 months", + "description": "Neutrophil-driven responses that may further propagate injury will be evaluated at baseline and 3 months after STEMI (neutrophil extracellular traps, neutrophil-derived microparticles)" + } + ], + "oversight_info": { + "is_fda_regulated_drug": "No", + "is_fda_regulated_device": "No", + "has_dmc": "No" + }, + "last_update_posted": { + "type": "Actual", + "content": "September 12, 2019" + }, + "id_info": { + "nct_id": "NCT03874338", + "org_study_id": "18-01323", + "secondary_id": "1R01HL146206" + }, + "enrollment": { + "type": "Anticipated", + "content": "670" + }, + "study_first_submitted": "March 12, 2019", + "condition": [ + "Neutrophils.Hypersegmented | Bld-Ser-Plas", + "STEMI - ST Elevation Myocardial Infarction" + ], + "study_type": "Observational", + "required_header": { + "download_date": "ClinicalTrials.gov processed this data on July 19, 2020", + "link_text": "Link to the current ClinicalTrials.gov record.", + "url": "https://clinicaltrials.gov/show/NCT03874338" + }, + "last_update_submitted": "September 10, 2019", + "completion_date": { + "type": "Anticipated", + "content": "February 1, 2022" + }, + "location": { + "contact": { + "phone": "646-501-9648", + "last_name": "Fatmira Curovic", + "email": "fatmira.curovic@nyumc.org" + }, + "facility": { + "address": { + "zip": "10016", + "country": "United States", + "city": "New York", + "state": "New York" + }, + "name": "NYU School of Medicine" + }, + "status": "Recruiting", + "contact_backup": { + "last_name": "Binita Shah, MD" + } + }, + "intervention": { + "intervention_type": "Drug", + "arm_group_label": [ + "Colchicine", + "Placebo" + ], + "description": "Participants in the main CLEAR SYNERGY trial are randomized to colchicine/spironolactone versus placebo in a 2x2 factorial design. The substudy is interested in the evaluation of biospecimens obtained from patients in the colchicine vs placebo group.", + "intervention_name": "Colchicine Pill" + }, + "patient_data": { + "sharing_ipd": "No" + }, + "verification_date": "September 2019" + } +} \ No newline at end of file diff --git a/src/test/resources/Issue593.xml b/src/test/resources/Issue593.xml new file mode 100644 index 0000000..bf78f3b --- /dev/null +++ b/src/test/resources/Issue593.xml @@ -0,0 +1,169 @@ + + + + + ClinicalTrials.gov processed this data on July 19, 2020 + Link to the current ClinicalTrials.gov record. + https://clinicaltrials.gov/show/NCT03874338 + + + 18-01323 + 1R01HL146206 + NCT03874338 + + CLEAR SYNERGY Neutrophil Substudy + Studies on the Effects of Colchicine on Neutrophil Biology in Acute Myocardial Infarction: A Substudy of the CLEAR SYNERGY (OASIS 9) Trial + + + NYU Langone Health + Other + + + Population Health Research Institute + Other + + + National Heart, Lung, and Blood Institute (NHLBI) + NIH + + + NYU Langone Health + + No + No + No + + + + CLEAR SYNERGY is an international multi center 2x2 randomized placebo controlled trial of + + + Recruiting + March 4, 2019 + February 1, 2022 + February 1, 2021 + Observational + No + + Other + Prospective + + + soluble L-selectin + between baseline and 3 months + Change in soluble L-selectin between baseline and 3 mo after STEMI in the placebo vs. colchicine groups. + + + Other soluble markers of neutrophil activity + between baseline and 3 months + Other markers of neutrophil activity will be evaluated at baseline and 3 months after STEMI (myeloperoxidase, matrix metalloproteinase-9, neutrophil gelatinase-associated lipocalin, neutrophil elastase, intercellular/vascular cellular adhesion molecules) + + + Markers of systemic inflammation + between baseline and 3 months + Markers of systemic inflammation will be evaluated at baseline and 3 months after STEMI (high sensitive CRP, IL-1β) + + + Neutrophil-driven responses that may further propagate injury + between baseline and 3 months + Neutrophil-driven responses that may further propagate injury will be evaluated at baseline and 3 months after STEMI (neutrophil extracellular traps, neutrophil-derived microparticles) + + 2 + 670 + Neutrophils.Hypersegmented | Bld-Ser-Plas + STEMI - ST Elevation Myocardial Infarction + + Colchicine + + + Placebo + + + Drug + Colchicine Pill + Participants in the main CLEAR SYNERGY trial are randomized to colchicine/spironolactone versus placebo in a 2x2 factorial design. The substudy is interested in the evaluation of biospecimens obtained from patients in the colchicine vs placebo group. + Colchicine + Placebo + + + + + Patients who are randomized to the drug RCT portion of the CLEAR SYNERGY (OASIS 9) trial + + + Non-Probability Sample + + + Inclusion Criteria: + + + All + 19 Years + 110 Years + No + + + Binita Shah, MD + Principal Investigator + NYU School of Medicine + + + Fatmira Curovic + 646-501-9648 + fatmira.curovic@nyumc.org + + + Binita Shah, MD + + + + NYU School of Medicine +
+ New York + New York + 10016 + United States +
+
+ Recruiting + + Fatmira Curovic + 646-501-9648 + fatmira.curovic@nyumc.org + + + Binita Shah, MD + +
+ + United States + + September 2019 + March 12, 2019 + March 12, 2019 + March 14, 2019 + September 10, 2019 + September 10, 2019 + September 12, 2019 + + Principal Investigator + NYU Langone Health + Binita Shah + Assistant Professor of Medicine + + + + Myocardial Infarction + ST Elevation Myocardial Infarction + Infarction + + + + Colchicine + + + No + + +
-- Gitee From 153972afdf3150fa08e48b30da6b70bec63d4664 Mon Sep 17 00:00:00 2001 From: Dean Date: Fri, 7 Oct 2022 10:35:14 +0100 Subject: [PATCH 15/48] Adding resources --- src/test/resources/Issue593.json | 875 ++++++++++++++++++++++++------- src/test/resources/Issue593.xml | 860 ++++++++++++++++++++++++------ 2 files changed, 1386 insertions(+), 349 deletions(-) diff --git a/src/test/resources/Issue593.json b/src/test/resources/Issue593.json index b3c82fe..213625a 100644 --- a/src/test/resources/Issue593.json +++ b/src/test/resources/Issue593.json @@ -1,189 +1,704 @@ { - "clinical_study": { - "brief_summary": { - "textblock": "CLEAR SYNERGY is an international multi center 2x2 randomized placebo controlled trial of" - }, - "brief_title": "CLEAR SYNERGY Neutrophil Substudy", - "overall_status": "Recruiting", - "eligibility": { - "study_pop": { - "textblock": "Patients who are randomized to the drug RCT portion of the CLEAR SYNERGY (OASIS 9) trial" + "success": true, + "error": null, + "response": [ + { + "loc": { + "long": 31.25, + "lat": 30.063 }, - "minimum_age": "19 Years", - "sampling_method": "Non-Probability Sample", - "gender": "All", - "criteria": { - "textblock": "Inclusion Criteria:" + "interval": "day", + "place": { + "name": "cairo", + "state": "qh", + "country": "eg" }, - "healthy_volunteers": "No", - "maximum_age": "110 Years" - }, - "number_of_groups": "2", - "source": "NYU Langone Health", - "location_countries": { - "country": "United States" - }, - "study_design_info": { - "time_perspective": "Prospective", - "observational_model": "Other" - }, - "last_update_submitted_qc": "September 10, 2019", - "intervention_browse": { - "mesh_term": "Colchicine" - }, - "official_title": "Studies on the Effects of Colchicine on Neutrophil Biology in Acute Myocardial Infarction: A Substudy of the CLEAR SYNERGY (OASIS 9) Trial", - "primary_completion_date": { - "type": "Anticipated", - "content": "February 1, 2021" - }, - "sponsors": { - "lead_sponsor": { - "agency_class": "Other", - "agency": "NYU Langone Health" - }, - "collaborator": [ + "periods": [ { - "agency_class": "Other", - "agency": "Population Health Research Institute" + "timestamp": 1665032400, + "validTime": "2022-10-06T07:00:00+02:00", + "dateTimeISO": "2022-10-06T07:00:00+02:00", + "maxTempC": 32, + "maxTempF": 90, + "minTempC": 19, + "minTempF": 66, + "avgTempC": 25, + "avgTempF": 78, + "tempC": null, + "tempF": null, + "maxFeelslikeC": 32, + "maxFeelslikeF": 89, + "minFeelslikeC": 21, + "minFeelslikeF": 70, + "avgFeelslikeC": 26, + "avgFeelslikeF": 80, + "feelslikeC": 21, + "feelslikeF": 70, + "maxDewpointC": 17, + "maxDewpointF": 63, + "minDewpointC": 11, + "minDewpointF": 52, + "avgDewpointC": 14, + "avgDewpointF": 58, + "dewpointC": 17, + "dewpointF": 63, + "maxHumidity": 77, + "minHumidity": 29, + "humidity": 77, + "pop": 0, + "precipMM": 0, + "precipIN": 0, + "iceaccum": null, + "iceaccumMM": null, + "iceaccumIN": null, + "snowCM": 0, + "snowIN": 0, + "pressureMB": 1015, + "pressureIN": 29.97, + "windDir": "N", + "windDirDEG": 353, + "windSpeedKTS": 5, + "windSpeedKPH": 9, + "windSpeedMPH": 6, + "windGustKTS": 21, + "windGustKPH": 40, + "windGustMPH": 25, + "windDirMax": "NNW", + "windDirMaxDEG": 342, + "windSpeedMaxKTS": 9, + "windSpeedMaxKPH": 16, + "windSpeedMaxMPH": 10, + "windDirMin": "N", + "windDirMinDEG": 353, + "windSpeedMinKTS": 1, + "windSpeedMinKPH": 2, + "windSpeedMinMPH": 1, + "windDir80m": "N", + "windDir80mDEG": 11, + "windSpeed80mKTS": 12, + "windSpeed80mKPH": 22, + "windSpeed80mMPH": 13, + "windGust80mKTS": 22, + "windGust80mKPH": 41, + "windGust80mMPH": 25, + "windDirMax80m": "NNW", + "windDirMax80mDEG": 343, + "windSpeedMax80mKTS": 22, + "windSpeedMax80mKPH": 41, + "windSpeedMax80mMPH": 25, + "windDirMin80m": "E", + "windDirMin80mDEG": 95, + "windSpeedMin80mKTS": 8, + "windSpeedMin80mKPH": 15, + "windSpeedMin80mMPH": 10, + "sky": 22, + "cloudsCoded": "FW", + "weather": "Mostly Sunny", + "weatherCoded": [], + "weatherPrimary": "Mostly Sunny", + "weatherPrimaryCoded": "::FW", + "icon": "fair.png", + "visibilityKM": 24.135, + "visibilityMI": 15, + "uvi": 6, + "solradWM2": 5608, + "solradMinWM2": 0, + "solradMaxWM2": 778, + "isDay": true, + "maxCoverage": "", + "sunrise": 1665028274, + "sunset": 1665070502, + "sunriseISO": "2022-10-06T05:51:14+02:00", + "sunsetISO": "2022-10-06T17:35:02+02:00" }, { - "agency_class": "NIH", - "agency": "National Heart, Lung, and Blood Institute (NHLBI)" - } - ] - }, - "overall_official": { - "role": "Principal Investigator", - "affiliation": "NYU School of Medicine", - "last_name": "Binita Shah, MD" - }, - "overall_contact_backup": { - "last_name": "Binita Shah, MD" - }, - "condition_browse": { - "mesh_term": [ - "Myocardial Infarction", - "ST Elevation Myocardial Infarction", - "Infarction" - ] - }, - "overall_contact": { - "phone": "646-501-9648", - "last_name": "Fatmira Curovic", - "email": "fatmira.curovic@nyumc.org" - }, - "responsible_party": { - "responsible_party_type": "Principal Investigator", - "investigator_title": "Assistant Professor of Medicine", - "investigator_full_name": "Binita Shah", - "investigator_affiliation": "NYU Langone Health" - }, - "study_first_submitted_qc": "March 12, 2019", - "start_date": { - "type": "Actual", - "content": "March 4, 2019" - }, - "has_expanded_access": "No", - "study_first_posted": { - "type": "Actual", - "content": "March 14, 2019" - }, - "arm_group": [ - { - "arm_group_label": "Colchicine" - }, - { - "arm_group_label": "Placebo" - } - ], - "primary_outcome": { - "measure": "soluble L-selectin", - "time_frame": "between baseline and 3 months", - "description": "Change in soluble L-selectin between baseline and 3 mo after STEMI in the placebo vs. colchicine groups." - }, - "secondary_outcome": [ - { - "measure": "Other soluble markers of neutrophil activity", - "time_frame": "between baseline and 3 months", - "description": "Other markers of neutrophil activity will be evaluated at baseline and 3 months after STEMI (myeloperoxidase, matrix metalloproteinase-9, neutrophil gelatinase-associated lipocalin, neutrophil elastase, intercellular/vascular cellular adhesion molecules)" - }, - { - "measure": "Markers of systemic inflammation", - "time_frame": "between baseline and 3 months", - "description": "Markers of systemic inflammation will be evaluated at baseline and 3 months after STEMI (high sensitive CRP, IL-1β)" - }, - { - "measure": "Neutrophil-driven responses that may further propagate injury", - "time_frame": "between baseline and 3 months", - "description": "Neutrophil-driven responses that may further propagate injury will be evaluated at baseline and 3 months after STEMI (neutrophil extracellular traps, neutrophil-derived microparticles)" - } - ], - "oversight_info": { - "is_fda_regulated_drug": "No", - "is_fda_regulated_device": "No", - "has_dmc": "No" - }, - "last_update_posted": { - "type": "Actual", - "content": "September 12, 2019" - }, - "id_info": { - "nct_id": "NCT03874338", - "org_study_id": "18-01323", - "secondary_id": "1R01HL146206" - }, - "enrollment": { - "type": "Anticipated", - "content": "670" - }, - "study_first_submitted": "March 12, 2019", - "condition": [ - "Neutrophils.Hypersegmented | Bld-Ser-Plas", - "STEMI - ST Elevation Myocardial Infarction" - ], - "study_type": "Observational", - "required_header": { - "download_date": "ClinicalTrials.gov processed this data on July 19, 2020", - "link_text": "Link to the current ClinicalTrials.gov record.", - "url": "https://clinicaltrials.gov/show/NCT03874338" - }, - "last_update_submitted": "September 10, 2019", - "completion_date": { - "type": "Anticipated", - "content": "February 1, 2022" - }, - "location": { - "contact": { - "phone": "646-501-9648", - "last_name": "Fatmira Curovic", - "email": "fatmira.curovic@nyumc.org" - }, - "facility": { - "address": { - "zip": "10016", - "country": "United States", - "city": "New York", - "state": "New York" + "timestamp": 1665118800, + "validTime": "2022-10-07T07:00:00+02:00", + "dateTimeISO": "2022-10-07T07:00:00+02:00", + "maxTempC": 30, + "maxTempF": 86, + "minTempC": 19, + "minTempF": 66, + "avgTempC": 24, + "avgTempF": 76, + "tempC": null, + "tempF": null, + "maxFeelslikeC": 29, + "maxFeelslikeF": 85, + "minFeelslikeC": 19, + "minFeelslikeF": 67, + "avgFeelslikeC": 24, + "avgFeelslikeF": 76, + "feelslikeC": 19, + "feelslikeF": 67, + "maxDewpointC": 15, + "maxDewpointF": 60, + "minDewpointC": 10, + "minDewpointF": 50, + "avgDewpointC": 12, + "avgDewpointF": 54, + "dewpointC": 15, + "dewpointF": 60, + "maxHumidity": 77, + "minHumidity": 30, + "humidity": 77, + "pop": 0, + "precipMM": 0, + "precipIN": 0, + "iceaccum": null, + "iceaccumMM": null, + "iceaccumIN": null, + "snowCM": 0, + "snowIN": 0, + "pressureMB": 1014, + "pressureIN": 29.95, + "windDir": "NW", + "windDirDEG": 325, + "windSpeedKTS": 1, + "windSpeedKPH": 2, + "windSpeedMPH": 1, + "windGustKTS": 16, + "windGustKPH": 29, + "windGustMPH": 18, + "windDirMax": "WNW", + "windDirMaxDEG": 298, + "windSpeedMaxKTS": 7, + "windSpeedMaxKPH": 13, + "windSpeedMaxMPH": 8, + "windDirMin": "NW", + "windDirMinDEG": 325, + "windSpeedMinKTS": 1, + "windSpeedMinKPH": 2, + "windSpeedMinMPH": 1, + "windDir80m": "NNW", + "windDir80mDEG": 347, + "windSpeed80mKTS": 6, + "windSpeed80mKPH": 10, + "windSpeed80mMPH": 6, + "windGust80mKTS": 20, + "windGust80mKPH": 37, + "windGust80mMPH": 23, + "windDirMax80m": "NW", + "windDirMax80mDEG": 316, + "windSpeedMax80mKTS": 20, + "windSpeedMax80mKPH": 37, + "windSpeedMax80mMPH": 23, + "windDirMin80m": "NNW", + "windDirMin80mDEG": 347, + "windSpeedMin80mKTS": 6, + "windSpeedMin80mKPH": 10, + "windSpeedMin80mMPH": 6, + "sky": 30, + "cloudsCoded": "FW", + "weather": "Mostly Sunny", + "weatherCoded": [], + "weatherPrimary": "Mostly Sunny", + "weatherPrimaryCoded": "::FW", + "icon": "fair.png", + "visibilityKM": 24.135, + "visibilityMI": 15, + "uvi": 6, + "solradWM2": 5486, + "solradMinWM2": 0, + "solradMaxWM2": 742, + "isDay": true, + "maxCoverage": "", + "sunrise": 1665114710, + "sunset": 1665156831, + "sunriseISO": "2022-10-07T05:51:50+02:00", + "sunsetISO": "2022-10-07T17:33:51+02:00" }, - "name": "NYU School of Medicine" - }, - "status": "Recruiting", - "contact_backup": { - "last_name": "Binita Shah, MD" - } - }, - "intervention": { - "intervention_type": "Drug", - "arm_group_label": [ - "Colchicine", - "Placebo" + { + "timestamp": 1665205200, + "validTime": "2022-10-08T07:00:00+02:00", + "dateTimeISO": "2022-10-08T07:00:00+02:00", + "maxTempC": 30, + "maxTempF": 87, + "minTempC": 19, + "minTempF": 66, + "avgTempC": 25, + "avgTempF": 76, + "tempC": null, + "tempF": null, + "maxFeelslikeC": 30, + "maxFeelslikeF": 86, + "minFeelslikeC": 19, + "minFeelslikeF": 67, + "avgFeelslikeC": 25, + "avgFeelslikeF": 76, + "feelslikeC": 19, + "feelslikeF": 67, + "maxDewpointC": 15, + "maxDewpointF": 59, + "minDewpointC": 11, + "minDewpointF": 52, + "avgDewpointC": 13, + "avgDewpointF": 56, + "dewpointC": 15, + "dewpointF": 59, + "maxHumidity": 76, + "minHumidity": 32, + "humidity": 76, + "pop": 0, + "precipMM": 0, + "precipIN": 0, + "iceaccum": null, + "iceaccumMM": null, + "iceaccumIN": null, + "snowCM": 0, + "snowIN": 0, + "pressureMB": 1014, + "pressureIN": 29.94, + "windDir": "NNE", + "windDirDEG": 21, + "windSpeedKTS": 1, + "windSpeedKPH": 2, + "windSpeedMPH": 1, + "windGustKTS": 17, + "windGustKPH": 32, + "windGustMPH": 20, + "windDirMax": "WNW", + "windDirMaxDEG": 301, + "windSpeedMaxKTS": 7, + "windSpeedMaxKPH": 13, + "windSpeedMaxMPH": 8, + "windDirMin": "NNE", + "windDirMinDEG": 21, + "windSpeedMinKTS": 1, + "windSpeedMinKPH": 2, + "windSpeedMinMPH": 1, + "windDir80m": "NW", + "windDir80mDEG": 309, + "windSpeed80mKTS": 5, + "windSpeed80mKPH": 9, + "windSpeed80mMPH": 5, + "windGust80mKTS": 17, + "windGust80mKPH": 31, + "windGust80mMPH": 19, + "windDirMax80m": "NW", + "windDirMax80mDEG": 322, + "windSpeedMax80mKTS": 17, + "windSpeedMax80mKPH": 31, + "windSpeedMax80mMPH": 19, + "windDirMin80m": "NW", + "windDirMin80mDEG": 309, + "windSpeedMin80mKTS": 5, + "windSpeedMin80mKPH": 9, + "windSpeedMin80mMPH": 5, + "sky": 47, + "cloudsCoded": "SC", + "weather": "Partly Cloudy", + "weatherCoded": [], + "weatherPrimary": "Partly Cloudy", + "weatherPrimaryCoded": "::SC", + "icon": "pcloudy.png", + "visibilityKM": 24.135, + "visibilityMI": 15, + "uvi": 7, + "solradWM2": 4785, + "solradMinWM2": 0, + "solradMaxWM2": 682, + "isDay": true, + "maxCoverage": "", + "sunrise": 1665201146, + "sunset": 1665243161, + "sunriseISO": "2022-10-08T05:52:26+02:00", + "sunsetISO": "2022-10-08T17:32:41+02:00" + }, + { + "timestamp": 1665291600, + "validTime": "2022-10-09T07:00:00+02:00", + "dateTimeISO": "2022-10-09T07:00:00+02:00", + "maxTempC": 31, + "maxTempF": 87, + "minTempC": 19, + "minTempF": 67, + "avgTempC": 25, + "avgTempF": 77, + "tempC": null, + "tempF": null, + "maxFeelslikeC": 30, + "maxFeelslikeF": 86, + "minFeelslikeC": 20, + "minFeelslikeF": 67, + "avgFeelslikeC": 25, + "avgFeelslikeF": 77, + "feelslikeC": 20, + "feelslikeF": 67, + "maxDewpointC": 17, + "maxDewpointF": 63, + "minDewpointC": 11, + "minDewpointF": 52, + "avgDewpointC": 14, + "avgDewpointF": 57, + "dewpointC": 17, + "dewpointF": 63, + "maxHumidity": 86, + "minHumidity": 31, + "humidity": 86, + "pop": 0, + "precipMM": 0, + "precipIN": 0, + "iceaccum": null, + "iceaccumMM": null, + "iceaccumIN": null, + "snowCM": 0, + "snowIN": 0, + "pressureMB": 1016, + "pressureIN": 29.99, + "windDir": "N", + "windDirDEG": 356, + "windSpeedKTS": 2, + "windSpeedKPH": 4, + "windSpeedMPH": 2, + "windGustKTS": 19, + "windGustKPH": 36, + "windGustMPH": 22, + "windDirMax": "NNW", + "windDirMaxDEG": 343, + "windSpeedMaxKTS": 8, + "windSpeedMaxKPH": 14, + "windSpeedMaxMPH": 9, + "windDirMin": "N", + "windDirMinDEG": 356, + "windSpeedMinKTS": 2, + "windSpeedMinKPH": 4, + "windSpeedMinMPH": 2, + "windDir80m": "NW", + "windDir80mDEG": 316, + "windSpeed80mKTS": 5, + "windSpeed80mKPH": 9, + "windSpeed80mMPH": 6, + "windGust80mKTS": 20, + "windGust80mKPH": 36, + "windGust80mMPH": 23, + "windDirMax80m": "N", + "windDirMax80mDEG": 354, + "windSpeedMax80mKTS": 20, + "windSpeedMax80mKPH": 36, + "windSpeedMax80mMPH": 23, + "windDirMin80m": "NW", + "windDirMin80mDEG": 316, + "windSpeedMin80mKTS": 5, + "windSpeedMin80mKPH": 9, + "windSpeedMin80mMPH": 6, + "sky": 47, + "cloudsCoded": "SC", + "weather": "Partly Cloudy", + "weatherCoded": [], + "weatherPrimary": "Partly Cloudy", + "weatherPrimaryCoded": "::SC", + "icon": "pcloudy.png", + "visibilityKM": 24.135, + "visibilityMI": 15, + "uvi": 7, + "solradWM2": 4768, + "solradMinWM2": 0, + "solradMaxWM2": 726, + "isDay": true, + "maxCoverage": "", + "sunrise": 1665287583, + "sunset": 1665329491, + "sunriseISO": "2022-10-09T05:53:03+02:00", + "sunsetISO": "2022-10-09T17:31:31+02:00" + }, + { + "timestamp": 1665378000, + "validTime": "2022-10-10T07:00:00+02:00", + "dateTimeISO": "2022-10-10T07:00:00+02:00", + "maxTempC": 31, + "maxTempF": 87, + "minTempC": 21, + "minTempF": 70, + "avgTempC": 26, + "avgTempF": 78, + "tempC": null, + "tempF": null, + "maxFeelslikeC": 30, + "maxFeelslikeF": 86, + "minFeelslikeC": 21, + "minFeelslikeF": 69, + "avgFeelslikeC": 25, + "avgFeelslikeF": 78, + "feelslikeC": 21, + "feelslikeF": 69, + "maxDewpointC": 16, + "maxDewpointF": 61, + "minDewpointC": 13, + "minDewpointF": 55, + "avgDewpointC": 14, + "avgDewpointF": 58, + "dewpointC": 16, + "dewpointF": 61, + "maxHumidity": 75, + "minHumidity": 35, + "humidity": 75, + "pop": 0, + "precipMM": 0, + "precipIN": 0, + "iceaccum": null, + "iceaccumMM": null, + "iceaccumIN": null, + "snowCM": 0, + "snowIN": 0, + "pressureMB": 1017, + "pressureIN": 30.03, + "windDir": "N", + "windDirDEG": 358, + "windSpeedKTS": 2, + "windSpeedKPH": 4, + "windSpeedMPH": 2, + "windGustKTS": 16, + "windGustKPH": 30, + "windGustMPH": 19, + "windDirMax": "N", + "windDirMaxDEG": 10, + "windSpeedMaxKTS": 8, + "windSpeedMaxKPH": 15, + "windSpeedMaxMPH": 9, + "windDirMin": "N", + "windDirMinDEG": 358, + "windSpeedMinKTS": 2, + "windSpeedMinKPH": 4, + "windSpeedMinMPH": 2, + "windDir80m": "N", + "windDir80mDEG": 8, + "windSpeed80mKTS": 7, + "windSpeed80mKPH": 13, + "windSpeed80mMPH": 8, + "windGust80mKTS": 19, + "windGust80mKPH": 36, + "windGust80mMPH": 22, + "windDirMax80m": "N", + "windDirMax80mDEG": 10, + "windSpeedMax80mKTS": 19, + "windSpeedMax80mKPH": 36, + "windSpeedMax80mMPH": 22, + "windDirMin80m": "E", + "windDirMin80mDEG": 91, + "windSpeedMin80mKTS": 7, + "windSpeedMin80mKPH": 13, + "windSpeedMin80mMPH": 8, + "sky": 64, + "cloudsCoded": "SC", + "weather": "Partly Cloudy", + "weatherCoded": [], + "weatherPrimary": "Partly Cloudy", + "weatherPrimaryCoded": "::SC", + "icon": "pcloudy.png", + "visibilityKM": 24.135, + "visibilityMI": 15, + "uvi": 6, + "solradWM2": 4494, + "solradMinWM2": 0, + "solradMaxWM2": 597, + "isDay": true, + "maxCoverage": "", + "sunrise": 1665374020, + "sunset": 1665415821, + "sunriseISO": "2022-10-10T05:53:40+02:00", + "sunsetISO": "2022-10-10T17:30:21+02:00" + }, + { + "timestamp": 1665464400, + "validTime": "2022-10-11T07:00:00+02:00", + "dateTimeISO": "2022-10-11T07:00:00+02:00", + "maxTempC": 31, + "maxTempF": 87, + "minTempC": 21, + "minTempF": 70, + "avgTempC": 26, + "avgTempF": 78, + "tempC": null, + "tempF": null, + "maxFeelslikeC": 31, + "maxFeelslikeF": 87, + "minFeelslikeC": 22, + "minFeelslikeF": 72, + "avgFeelslikeC": 26, + "avgFeelslikeF": 79, + "feelslikeC": 22, + "feelslikeF": 72, + "maxDewpointC": 17, + "maxDewpointF": 62, + "minDewpointC": 11, + "minDewpointF": 51, + "avgDewpointC": 13, + "avgDewpointF": 55, + "dewpointC": 17, + "dewpointF": 62, + "maxHumidity": 71, + "minHumidity": 30, + "humidity": 71, + "pop": 0, + "precipMM": 0, + "precipIN": 0, + "iceaccum": null, + "iceaccumMM": null, + "iceaccumIN": null, + "snowCM": 0, + "snowIN": 0, + "pressureMB": 1015, + "pressureIN": 29.98, + "windDir": "NNE", + "windDirDEG": 13, + "windSpeedKTS": 8, + "windSpeedKPH": 15, + "windSpeedMPH": 9, + "windGustKTS": 15, + "windGustKPH": 28, + "windGustMPH": 17, + "windDirMax": "NNE", + "windDirMaxDEG": 28, + "windSpeedMaxKTS": 15, + "windSpeedMaxKPH": 28, + "windSpeedMaxMPH": 18, + "windDirMin": "NNE", + "windDirMinDEG": 14, + "windSpeedMinKTS": 7, + "windSpeedMinKPH": 14, + "windSpeedMinMPH": 8, + "windDir80m": "NNE", + "windDir80mDEG": 16, + "windSpeed80mKTS": 10, + "windSpeed80mKPH": 19, + "windSpeed80mMPH": 12, + "windGust80mKTS": 17, + "windGust80mKPH": 31, + "windGust80mMPH": 19, + "windDirMax80m": "NNE", + "windDirMax80mDEG": 28, + "windSpeedMax80mKTS": 17, + "windSpeedMax80mKPH": 31, + "windSpeedMax80mMPH": 19, + "windDirMin80m": "NNE", + "windDirMin80mDEG": 13, + "windSpeedMin80mKTS": 9, + "windSpeedMin80mKPH": 18, + "windSpeedMin80mMPH": 11, + "sky": 0, + "cloudsCoded": "CL", + "weather": "Sunny", + "weatherCoded": [], + "weatherPrimary": "Sunny", + "weatherPrimaryCoded": "::CL", + "icon": "sunny.png", + "visibilityKM": 24.135, + "visibilityMI": 15, + "uvi": null, + "solradWM2": 5450, + "solradMinWM2": 0, + "solradMaxWM2": 758, + "isDay": true, + "maxCoverage": "", + "sunrise": 1665460458, + "sunset": 1665502153, + "sunriseISO": "2022-10-11T05:54:18+02:00", + "sunsetISO": "2022-10-11T17:29:13+02:00" + }, + { + "timestamp": 1665550800, + "validTime": "2022-10-12T07:00:00+02:00", + "dateTimeISO": "2022-10-12T07:00:00+02:00", + "maxTempC": 31, + "maxTempF": 88, + "minTempC": 21, + "minTempF": 69, + "avgTempC": 26, + "avgTempF": 79, + "tempC": null, + "tempF": null, + "maxFeelslikeC": 31, + "maxFeelslikeF": 88, + "minFeelslikeC": 22, + "minFeelslikeF": 72, + "avgFeelslikeC": 26, + "avgFeelslikeF": 80, + "feelslikeC": 22, + "feelslikeF": 72, + "maxDewpointC": 16, + "maxDewpointF": 60, + "minDewpointC": 11, + "minDewpointF": 51, + "avgDewpointC": 13, + "avgDewpointF": 55, + "dewpointC": 16, + "dewpointF": 60, + "maxHumidity": 68, + "minHumidity": 29, + "humidity": 68, + "pop": 0, + "precipMM": 0, + "precipIN": 0, + "iceaccum": null, + "iceaccumMM": null, + "iceaccumIN": null, + "snowCM": 0, + "snowIN": 0, + "pressureMB": 1014, + "pressureIN": 29.95, + "windDir": "NNE", + "windDirDEG": 12, + "windSpeedKTS": 8, + "windSpeedKPH": 15, + "windSpeedMPH": 9, + "windGustKTS": 15, + "windGustKPH": 28, + "windGustMPH": 17, + "windDirMax": "E", + "windDirMaxDEG": 96, + "windSpeedMaxKTS": 14, + "windSpeedMaxKPH": 26, + "windSpeedMaxMPH": 16, + "windDirMin": "NNE", + "windDirMinDEG": 12, + "windSpeedMinKTS": 7, + "windSpeedMinKPH": 13, + "windSpeedMinMPH": 8, + "windDir80m": "NNE", + "windDir80mDEG": 15, + "windSpeed80mKTS": 10, + "windSpeed80mKPH": 19, + "windSpeed80mMPH": 12, + "windGust80mKTS": 18, + "windGust80mKPH": 33, + "windGust80mMPH": 21, + "windDirMax80m": "E", + "windDirMax80mDEG": 96, + "windSpeedMax80mKTS": 18, + "windSpeedMax80mKPH": 33, + "windSpeedMax80mMPH": 21, + "windDirMin80m": "NNE", + "windDirMin80mDEG": 15, + "windSpeedMin80mKTS": 10, + "windSpeedMin80mKPH": 18, + "windSpeedMin80mMPH": 11, + "sky": 27, + "cloudsCoded": "FW", + "weather": "Mostly Sunny", + "weatherCoded": [], + "weatherPrimary": "Mostly Sunny", + "weatherPrimaryCoded": "::FW", + "icon": "fair.png", + "visibilityKM": 24.135, + "visibilityMI": 15, + "uvi": null, + "solradWM2": 4740, + "solradMinWM2": 0, + "solradMaxWM2": 743, + "isDay": true, + "maxCoverage": "", + "sunrise": 1665546895, + "sunset": 1665588484, + "sunriseISO": "2022-10-12T05:54:55+02:00", + "sunsetISO": "2022-10-12T17:28:04+02:00" + } ], - "description": "Participants in the main CLEAR SYNERGY trial are randomized to colchicine/spironolactone versus placebo in a 2x2 factorial design. The substudy is interested in the evaluation of biospecimens obtained from patients in the colchicine vs placebo group.", - "intervention_name": "Colchicine Pill" - }, - "patient_data": { - "sharing_ipd": "No" - }, - "verification_date": "September 2019" - } + "profile": { + "tz": "Africa/Cairo", + "elevM": 23, + "elevFT": 75 + } + } + ] } \ No newline at end of file diff --git a/src/test/resources/Issue593.xml b/src/test/resources/Issue593.xml index bf78f3b..0c6c038 100644 --- a/src/test/resources/Issue593.xml +++ b/src/test/resources/Issue593.xml @@ -1,169 +1,691 @@ - - - - - ClinicalTrials.gov processed this data on July 19, 2020 - Link to the current ClinicalTrials.gov record. - https://clinicaltrials.gov/show/NCT03874338 - - - 18-01323 - 1R01HL146206 - NCT03874338 - - CLEAR SYNERGY Neutrophil Substudy - Studies on the Effects of Colchicine on Neutrophil Biology in Acute Myocardial Infarction: A Substudy of the CLEAR SYNERGY (OASIS 9) Trial - - - NYU Langone Health - Other - - - Population Health Research Institute - Other - - - National Heart, Lung, and Blood Institute (NHLBI) - NIH - - - NYU Langone Health - - No - No - No - - - - CLEAR SYNERGY is an international multi center 2x2 randomized placebo controlled trial of - - - Recruiting - March 4, 2019 - February 1, 2022 - February 1, 2021 - Observational - No - - Other - Prospective - - - soluble L-selectin - between baseline and 3 months - Change in soluble L-selectin between baseline and 3 mo after STEMI in the placebo vs. colchicine groups. - - - Other soluble markers of neutrophil activity - between baseline and 3 months - Other markers of neutrophil activity will be evaluated at baseline and 3 months after STEMI (myeloperoxidase, matrix metalloproteinase-9, neutrophil gelatinase-associated lipocalin, neutrophil elastase, intercellular/vascular cellular adhesion molecules) - - - Markers of systemic inflammation - between baseline and 3 months - Markers of systemic inflammation will be evaluated at baseline and 3 months after STEMI (high sensitive CRP, IL-1β) - - - Neutrophil-driven responses that may further propagate injury - between baseline and 3 months - Neutrophil-driven responses that may further propagate injury will be evaluated at baseline and 3 months after STEMI (neutrophil extracellular traps, neutrophil-derived microparticles) - - 2 - 670 - Neutrophils.Hypersegmented | Bld-Ser-Plas - STEMI - ST Elevation Myocardial Infarction - - Colchicine - - - Placebo - - - Drug - Colchicine Pill - Participants in the main CLEAR SYNERGY trial are randomized to colchicine/spironolactone versus placebo in a 2x2 factorial design. The substudy is interested in the evaluation of biospecimens obtained from patients in the colchicine vs placebo group. - Colchicine - Placebo - - - - - Patients who are randomized to the drug RCT portion of the CLEAR SYNERGY (OASIS 9) trial - - - Non-Probability Sample - - - Inclusion Criteria: - - - All - 19 Years - 110 Years - No - - - Binita Shah, MD - Principal Investigator - NYU School of Medicine - - - Fatmira Curovic - 646-501-9648 - fatmira.curovic@nyumc.org - - - Binita Shah, MD - - - - NYU School of Medicine -
- New York - New York - 10016 - United States -
-
- Recruiting - - Fatmira Curovic - 646-501-9648 - fatmira.curovic@nyumc.org - - - Binita Shah, MD - -
- - United States - - September 2019 - March 12, 2019 - March 12, 2019 - March 14, 2019 - September 10, 2019 - September 10, 2019 - September 12, 2019 - - Principal Investigator - NYU Langone Health - Binita Shah - Assistant Professor of Medicine - - - - Myocardial Infarction - ST Elevation Myocardial Infarction - Infarction - - - - Colchicine - - - No - - -
+true + + + 31.25 + 30.063 + + + 23 + Africa/Cairo + 75 + + + 2022-10-06T07:00:00+02:00 + E + 95 + 21 + 15 + 10 + 353 + N + 2022-10-06T05:51:14+02:00 + null + 9 + null + 66 + 0 + Mostly Sunny + 2022-10-06T17:35:02+02:00 + 32 + 77 + N + 89 + 0 + 22 + 25 + 25 + Mostly Sunny + 41 + 58 + 41 + 22 + 14 + 0 + 22 + 353 + 16 + 8 + 70 + 2022-10-06T07:00:00+02:00 + 10 + 778 + 25 + 15 + ::FW + 1665028274 + 78 + N + + fair.png + 21 + 17 + FW + 70 + 29 + 63 + 12 + 0 + 0 + NNW + 13 + 22 + 11 + 32 + 1015 + 24.135 + 1665032400 + 90 + null + 11 + 0 + 1 + 343 + 21 + 2 + 63 + 1 + 26 + 6 + NNW + 17 + 29.97 + 80 + null + true + 19 + 52 + 5 + 1665070502 + 5608 + 9 + 25 + 77 + 6 + 40 + 342 + null + + + 2022-10-07T07:00:00+02:00 + NNW + 347 + 19 + 15 + 8 + 325 + NW + 2022-10-07T05:51:50+02:00 + null + 7 + null + 66 + 0 + Mostly Sunny + 2022-10-07T17:33:51+02:00 + 29 + 77 + NNW + 85 + 0 + 30 + 23 + 23 + Mostly Sunny + 37 + 54 + 37 + 20 + 12 + 0 + 20 + 325 + 13 + 6 + 67 + 2022-10-07T07:00:00+02:00 + 6 + 742 + 24 + 10 + ::FW + 1665114710 + 76 + NW + + fair.png + 19 + 15 + FW + 67 + 30 + 60 + 6 + 0 + 0 + WNW + 6 + 10 + 347 + 30 + 1014 + 24.135 + 1665118800 + 86 + null + 10 + 0 + 1 + 316 + 16 + 2 + 60 + 1 + 24 + 6 + NW + 15 + 29.95 + 76 + null + true + 19 + 50 + 1 + 1665156831 + 5486 + 2 + 18 + 77 + 1 + 29 + 298 + null + + + 2022-10-08T07:00:00+02:00 + NW + 309 + 19 + 15 + 8 + 21 + NNE + 2022-10-08T05:52:26+02:00 + null + 7 + null + 66 + 0 + Partly Cloudy + 2022-10-08T17:32:41+02:00 + 30 + 76 + NW + 86 + 0 + 47 + 19 + 19 + Partly Cloudy + 31 + 56 + 31 + 17 + 13 + 0 + 17 + 21 + 13 + 5 + 67 + 2022-10-08T07:00:00+02:00 + 5 + 682 + 25 + 9 + ::SC + 1665201146 + 76 + NNE + + pcloudy.png + 19 + 15 + SC + 67 + 32 + 59 + 5 + 0 + 0 + WNW + 5 + 9 + 309 + 30 + 1014 + 24.135 + 1665205200 + 87 + null + 11 + 0 + 1 + 322 + 17 + 2 + 59 + 1 + 25 + 7 + NW + 15 + 29.94 + 76 + null + true + 19 + 52 + 1 + 1665243161 + 4785 + 2 + 20 + 76 + 1 + 32 + 301 + null + + + 2022-10-09T07:00:00+02:00 + NW + 316 + 20 + 15 + 9 + 356 + N + 2022-10-09T05:53:03+02:00 + null + 8 + null + 67 + 0 + Partly Cloudy + 2022-10-09T17:31:31+02:00 + 30 + 86 + NW + 86 + 0 + 47 + 23 + 23 + Partly Cloudy + 36 + 57 + 36 + 20 + 14 + 0 + 20 + 356 + 14 + 5 + 67 + 2022-10-09T07:00:00+02:00 + 6 + 726 + 25 + 9 + ::SC + 1665287583 + 77 + N + + pcloudy.png + 20 + 17 + SC + 67 + 31 + 63 + 5 + 0 + 0 + NNW + 6 + 9 + 316 + 31 + 1016 + 24.135 + 1665291600 + 87 + null + 11 + 0 + 2 + 354 + 19 + 4 + 63 + 2 + 25 + 7 + N + 17 + 29.99 + 77 + null + true + 19 + 52 + 2 + 1665329491 + 4768 + 4 + 22 + 86 + 2 + 36 + 343 + null + + + 2022-10-10T07:00:00+02:00 + E + 91 + 21 + 15 + 9 + 358 + N + 2022-10-10T05:53:40+02:00 + null + 8 + null + 70 + 0 + Partly Cloudy + 2022-10-10T17:30:21+02:00 + 30 + 75 + N + 86 + 0 + 64 + 22 + 22 + Partly Cloudy + 36 + 58 + 36 + 19 + 14 + 0 + 19 + 358 + 15 + 7 + 69 + 2022-10-10T07:00:00+02:00 + 8 + 597 + 26 + 13 + ::SC + 1665374020 + 78 + N + + pcloudy.png + 21 + 16 + SC + 69 + 35 + 61 + 7 + 0 + 0 + N + 8 + 13 + 8 + 31 + 1017 + 24.135 + 1665378000 + 87 + null + 13 + 0 + 2 + 10 + 16 + 4 + 61 + 2 + 25 + 6 + N + 16 + 30.03 + 78 + null + true + 21 + 55 + 2 + 1665415821 + 4494 + 4 + 19 + 75 + 2 + 30 + 10 + null + + + 2022-10-11T07:00:00+02:00 + NNE + 13 + 22 + 15 + 18 + 13 + NNE + 2022-10-11T05:54:18+02:00 + null + 15 + null + 70 + 0 + Sunny + 2022-10-11T17:29:13+02:00 + 31 + 71 + NNE + 87 + 0 + 0 + 19 + 19 + Sunny + 31 + 55 + 31 + 17 + 13 + 0 + 17 + 14 + 28 + 9 + 72 + 2022-10-11T07:00:00+02:00 + 11 + 758 + 26 + 18 + ::CL + 1665460458 + 78 + NNE + + sunny.png + 22 + 17 + CL + 72 + 30 + 62 + 10 + 0 + 0 + NNE + 12 + 19 + 16 + 31 + 1015 + 24.135 + 1665464400 + 87 + null + 11 + 0 + 7 + 28 + 15 + 14 + 62 + 8 + 26 + null + NNE + 17 + 29.98 + 79 + null + true + 21 + 51 + 8 + 1665502153 + 5450 + 15 + 17 + 71 + 9 + 28 + 28 + null + + + 2022-10-12T07:00:00+02:00 + NNE + 15 + 22 + 15 + 16 + 12 + NNE + 2022-10-12T05:54:55+02:00 + null + 14 + null + 69 + 0 + Mostly Sunny + 2022-10-12T17:28:04+02:00 + 31 + 68 + NNE + 88 + 0 + 27 + 21 + 21 + Mostly Sunny + 33 + 55 + 33 + 18 + 13 + 0 + 18 + 12 + 26 + 10 + 72 + 2022-10-12T07:00:00+02:00 + 11 + 743 + 26 + 18 + ::FW + 1665546895 + 79 + NNE + + fair.png + 22 + 16 + FW + 72 + 29 + 60 + 10 + 0 + 0 + E + 12 + 19 + 15 + 31 + 1014 + 24.135 + 1665550800 + 88 + null + 11 + 0 + 7 + 96 + 15 + 13 + 60 + 8 + 26 + null + E + 16 + 29.95 + 80 + null + true + 21 + 51 + 8 + 1665588484 + 4740 + 15 + 17 + 68 + 9 + 28 + 96 + null + + day + + eg + cairo + qh + + +null -- Gitee From a2c0562e04badc81259cf1d703a52aba7965b464 Mon Sep 17 00:00:00 2001 From: Dean Date: Fri, 7 Oct 2022 15:04:09 +0100 Subject: [PATCH 16/48] Removed unused import --- src/test/java/org/json/junit/XMLTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 4c46cf1..bfb916c 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -18,7 +18,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; -import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; -- Gitee From 9cb8e153bf38e12554455d13c5c8e7c348236a98 Mon Sep 17 00:00:00 2001 From: Dean Date: Fri, 7 Oct 2022 17:57:07 +0100 Subject: [PATCH 17/48] Added JavaDocs --- src/main/java/org/json/XML.java | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java index 28a292f..bb614d4 100644 --- a/src/main/java/org/json/XML.java +++ b/src/main/java/org/json/XML.java @@ -755,6 +755,23 @@ public class XML { return toString(object, tagName, config, 0, 0); } + /** + * Convert a JSONObject into a well-formed, element-normal XML string, + * either pretty print or single-lined depending on indent factor. + * + * @param object + * A JSONObject. + * @param tagName + * The optional name of the enclosing tag. + * @param config + * Configuration that can control output to XML. + * @param indentFactor + * The number of spaces to add to each level of indentation. + * @param indent + * The current ident level in spaces. + * @return + * @throws JSONException + */ private static String toString(final Object object, final String tagName, final XMLParserConfiguration config, int indentFactor, int indent) throws JSONException { StringBuilder sb = new StringBuilder(); @@ -934,6 +951,13 @@ public class XML { return toString(object, tagName, config, indentFactor, 0); } + /** + * Return a String consisting of a number of space characters specified by indent + * + * @param indent + * The number of spaces to be appended to the String. + * @return + */ private static final String indent(int indent) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < indent; i++) { -- Gitee From 7aba3ac941701aad36e70d3ae3c77780aeae73ec Mon Sep 17 00:00:00 2001 From: Dean Date: Mon, 10 Oct 2022 11:09:42 +0100 Subject: [PATCH 18/48] System line seperator now being used in JUnit test --- src/test/java/org/json/junit/XMLTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index bfb916c..88ea9ce 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -1232,7 +1232,7 @@ public class XMLTest { for (int numRead; (numRead = in.read(buffer, 0, buffer.length)) > 0; ) { expected.append(buffer, 0, numRead); } - assertEquals(expected.toString(), actualString); + assertEquals(expected.toString().replaceAll("\\n|\\r\\n", System.getProperty("line.separator")), actualString); } finally { if (xmlStream != null) { xmlStream.close(); -- Gitee From 85495facbd4a9e2e13f6ef50a35a4b35535c96b5 Mon Sep 17 00:00:00 2001 From: Dean Date: Mon, 10 Oct 2022 11:12:35 +0100 Subject: [PATCH 19/48] Corrected test --- src/test/java/org/json/junit/XMLTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 88ea9ce..937658e 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -1232,7 +1232,7 @@ public class XMLTest { for (int numRead; (numRead = in.read(buffer, 0, buffer.length)) > 0; ) { expected.append(buffer, 0, numRead); } - assertEquals(expected.toString().replaceAll("\\n|\\r\\n", System.getProperty("line.separator")), actualString); + assertEquals(expected.toString(), actualString.replaceAll("\\n|\\r\\n", System.getProperty("line.separator"))); } finally { if (xmlStream != null) { xmlStream.close(); -- Gitee From a2d3d3c9b5dca8359ca6aca2662f3b1b5f023982 Mon Sep 17 00:00:00 2001 From: Bharati Kulkarni Date: Tue, 11 Oct 2022 14:33:43 -0500 Subject: [PATCH 20/48] Fix Flaky Test --- src/test/java/org/json/junit/JSONPointerTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/json/junit/JSONPointerTest.java b/src/test/java/org/json/junit/JSONPointerTest.java index d88803e..45c7dbd 100644 --- a/src/test/java/org/json/junit/JSONPointerTest.java +++ b/src/test/java/org/json/junit/JSONPointerTest.java @@ -72,8 +72,10 @@ public class JSONPointerTest { @Test public void queryByEmptyKeySubObject() { - assertEquals( "{\"\":\"empty key of an object with an empty key\",\"subKey\":\"Some" + - " other value\"}", query("/obj/").toString()); + JSONObject json = new JSONObject("{\"\":\"empty key of an object with an empty key\",\"subKey\":\"Some" + + " other value\"}"); + JSONObject obj = (JSONObject) query("/obj/"); + assertTrue(json.similar(obj)); } @Test -- Gitee From 23d5e52a53b2b10825fbd42d2323285d6e84bb05 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 28 Oct 2022 08:45:54 +0300 Subject: [PATCH 21/48] feature/update-release-for-JSONMap-Change adding breaking change for JSONMap to corresponding release --- docs/RELEASES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/RELEASES.md b/docs/RELEASES.md index 0d49331..3fbab78 100644 --- a/docs/RELEASES.md +++ b/docs/RELEASES.md @@ -20,6 +20,7 @@ and artifactId "json". For example: 20190722 Recent commits 20180813 POM change to include Automatic-Module-Name (#431) + JSONObject(Map) now throws an exception if any of a map keys are null (#405) 20180130 Recent commits -- Gitee From c798c76ddd46d79140c27ecb15146c588ea34945 Mon Sep 17 00:00:00 2001 From: Niranjani Date: Sun, 30 Oct 2022 22:10:38 +0530 Subject: [PATCH 22/48] move javadoc comments above the interface definition to make it visible Fix #670 --- src/main/java/org/json/JSONPropertyIgnore.java | 6 +++--- src/main/java/org/json/JSONPropertyName.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/json/JSONPropertyIgnore.java b/src/main/java/org/json/JSONPropertyIgnore.java index 7c5fa53..d3a5bc5 100644 --- a/src/main/java/org/json/JSONPropertyIgnore.java +++ b/src/main/java/org/json/JSONPropertyIgnore.java @@ -11,13 +11,13 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; -@Documented -@Retention(RUNTIME) -@Target({METHOD}) /** * Use this annotation on a getter method to override the Bean name * parser for Bean -> JSONObject mapping. If this annotation is * present at any level in the class hierarchy, then the method will * not be serialized from the bean into the JSONObject. */ +@Documented +@Retention(RUNTIME) +@Target({METHOD}) public @interface JSONPropertyIgnore { } diff --git a/src/main/java/org/json/JSONPropertyName.java b/src/main/java/org/json/JSONPropertyName.java index a66f4ad..4391bb7 100644 --- a/src/main/java/org/json/JSONPropertyName.java +++ b/src/main/java/org/json/JSONPropertyName.java @@ -11,14 +11,14 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; -@Documented -@Retention(RUNTIME) -@Target({METHOD}) /** * Use this annotation on a getter method to override the Bean name * parser for Bean -> JSONObject mapping. A value set to empty string "" * will have the Bean parser fall back to the default field name processing. */ +@Documented +@Retention(RUNTIME) +@Target({METHOD}) public @interface JSONPropertyName { /** * @return The name of the property as to be used in the JSON Object. -- Gitee From 5369442671090b0e50b8ed95c6e628fefc2fc2aa Mon Sep 17 00:00:00 2001 From: ASAlisha <115576463+ASAlishaa@users.noreply.github.com> Date: Mon, 14 Nov 2022 03:26:18 +0530 Subject: [PATCH 23/48] Added new resource to the repos Added new useful JSON resource. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5181b8b..003c295 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ JSON in Java [package org.json] [JSON](http://www.JSON.org/) is a light-weight language-independent data interchange format. -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. +The JSON-Java package is a reference implementation that demonstrates how to parse [JSON documents](https://www.interviewbit.com/problems/pretty-json/) into Java objects and how to generate new JSON documents from the Java classes. Project goals include: * Reliable and consistent results -- Gitee From b732188e4e66824227cb299e76b6b6aa57cdbe53 Mon Sep 17 00:00:00 2001 From: ASAlisha <115576463+ASAlishaa@users.noreply.github.com> Date: Tue, 15 Nov 2022 16:31:05 +0530 Subject: [PATCH 24/48] Added new resource to this repos. Added resource in the correct format. --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 003c295..2fdda56 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ JSON in Java [package org.json] [JSON](http://www.JSON.org/) is a light-weight language-independent data interchange format. -The JSON-Java package is a reference implementation that demonstrates how to parse [JSON documents](https://www.interviewbit.com/problems/pretty-json/) into Java objects and how to generate new JSON documents from the Java classes. +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. Project goals include: * Reliable and consistent results @@ -102,6 +102,10 @@ For more information, please see [NOTES.md](https://github.com/stleary/JSON-java For more information on files, please see [FILES.md](https://github.com/stleary/JSON-java/blob/master/docs/FILES.md) +# Interview Practice Problems + +[Pretty Json](https://www.interviewbit.com/problems/pretty-json/) - Problem asked in Microsoft & Facebook + # Release history: For the release history, please see [RELEASES.md](https://github.com/stleary/JSON-java/blob/master/docs/RELEASES.md) -- Gitee From 3b097d051ac2182f6dcf38ed3bd8d6e63d4e5d50 Mon Sep 17 00:00:00 2001 From: 6d64 <61372877+6d64@users.noreply.github.com> Date: Thu, 1 Dec 2022 03:21:26 +1100 Subject: [PATCH 25/48] Revert pull 707 - interviewbit spam Reverted commit that was added by a bot adding interviewbit spam to repos on github --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 2fdda56..5181b8b 100644 --- a/README.md +++ b/README.md @@ -102,10 +102,6 @@ For more information, please see [NOTES.md](https://github.com/stleary/JSON-java For more information on files, please see [FILES.md](https://github.com/stleary/JSON-java/blob/master/docs/FILES.md) -# Interview Practice Problems - -[Pretty Json](https://www.interviewbit.com/problems/pretty-json/) - Problem asked in Microsoft & Facebook - # Release history: For the release history, please see [RELEASES.md](https://github.com/stleary/JSON-java/blob/master/docs/RELEASES.md) -- Gitee From f566a1d9ee1f8139357017dc6c7def1da19cd8d4 Mon Sep 17 00:00:00 2001 From: Cleydyr de Albuquerque Date: Tue, 31 Jan 2023 17:32:34 +0100 Subject: [PATCH 26/48] fix: limit the nesting depth --- src/main/java/org/json/XML.java | 14 +++++-- .../java/org/json/XMLParserConfiguration.java | 41 +++++++++++++++++++ .../org/json/junit/XMLConfigurationTest.java | 23 +++++++++++ src/test/java/org/json/junit/XMLTest.java | 35 ++++++++++++++++ 4 files changed, 110 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java index bb614d4..b8fdefc 100644 --- a/src/main/java/org/json/XML.java +++ b/src/main/java/org/json/XML.java @@ -232,7 +232,7 @@ public class XML { * @return true if the close tag is processed. * @throws JSONException */ - private static boolean parse(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config) + private static boolean parse(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config, int currentNestingDepth) throws JSONException { char c; int i; @@ -402,7 +402,11 @@ public class XML { } else if (token == LT) { // Nested element - if (parse(x, jsonObject, tagName, config)) { + if (currentNestingDepth == config.getMaxNestingDepth()) { + throw x.syntaxError("Maximum nesting depth of " + config.getMaxNestingDepth() + " reached"); + } + + if (parse(x, jsonObject, tagName, config, currentNestingDepth + 1)) { if (config.getForceList().contains(tagName)) { // Force the value to be an array if (jsonObject.length() == 0) { @@ -644,6 +648,10 @@ public class XML { * All values are converted as strings, for 1, 01, 29.0 will not be coerced to * numbers but will instead be the exact value as seen in the XML document. * + * This method can parse documents with a maximum nesting depth of 256. If you + * need to parse documents with a nesting depth greater than 256, you should use + * + * * @param reader The XML source reader. * @param config Configuration options for the parser * @return A JSONObject containing the structured data from the XML string. @@ -655,7 +663,7 @@ public class XML { while (x.more()) { x.skipPast("<"); if(x.more()) { - parse(x, jo, null, config); + parse(x, jo, null, config, 0); } } return jo; diff --git a/src/main/java/org/json/XMLParserConfiguration.java b/src/main/java/org/json/XMLParserConfiguration.java index 9f00710..e3311fc 100644 --- a/src/main/java/org/json/XMLParserConfiguration.java +++ b/src/main/java/org/json/XMLParserConfiguration.java @@ -16,6 +16,12 @@ import java.util.Set; */ @SuppressWarnings({""}) public class XMLParserConfiguration { + /** + * Used to indicate there's no defined limit to the maximum nesting depth when parsing a XML + * document to JSON. + */ + public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1; + /** Original Configuration of the XML Parser. */ public static final XMLParserConfiguration ORIGINAL = new XMLParserConfiguration(); @@ -54,6 +60,12 @@ public class XMLParserConfiguration { */ private Set forceList; + /** + * When parsing the XML into JSON, specifies the tags whose values should be converted + * to arrays + */ + private int maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH; + /** * Default parser configuration. Does not keep strings (tries to implicitly convert * values), and the CDATA Tag Name is "content". @@ -297,4 +309,33 @@ public class XMLParserConfiguration { newConfig.forceList = Collections.unmodifiableSet(cloneForceList); return newConfig; } + + /** + * The maximum nesting depth that the parser will descend before throwing an exception + * when parsing the XML into JSON. + * @return the maximum nesting depth set for this configuration + */ + public int getMaxNestingDepth() { + return maxNestingDepth; + } + + /** + * Defines the maximum nesting depth that the parser will descend before throwing an exception + * when parsing the XML into JSON. The default max nesting depth is undefined, which means the + * parser will go as deep as the maximum call stack size allows. Using any negative value as a + * parameter is equivalent to setting no limit to the nesting depth. + * @param maxNestingDepth the maximum nesting depth allowed to the XML parser + * @return The existing configuration will not be modified. A new configuration is returned. + */ + public XMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) { + XMLParserConfiguration newConfig = this.clone(); + + if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) { + newConfig.maxNestingDepth = maxNestingDepth; + } else { + newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH; + } + + return newConfig; + } } diff --git a/src/test/java/org/json/junit/XMLConfigurationTest.java b/src/test/java/org/json/junit/XMLConfigurationTest.java index f9d24a6..25b17e2 100755 --- a/src/test/java/org/json/junit/XMLConfigurationTest.java +++ b/src/test/java/org/json/junit/XMLConfigurationTest.java @@ -1051,6 +1051,29 @@ public class XMLConfigurationTest { Util.compareActualVsExpectedJsonObjects(jsonObject, expetedJsonObject); } + + @Test + public void testMaxNestingDepthIsSet() { + XMLParserConfiguration xmlParserConfiguration = XMLParserConfiguration.ORIGINAL; + + assertEquals(xmlParserConfiguration.getMaxNestingDepth(), XMLParserConfiguration.UNDEFINED_MAXIMUM_NESTING_DEPTH); + + xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(42); + + assertEquals(xmlParserConfiguration.getMaxNestingDepth(), 42); + + xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(0); + + assertEquals(xmlParserConfiguration.getMaxNestingDepth(), 0); + + xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(-31415926); + + assertEquals(xmlParserConfiguration.getMaxNestingDepth(), XMLParserConfiguration.UNDEFINED_MAXIMUM_NESTING_DEPTH); + + xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(Integer.MIN_VALUE); + + assertEquals(xmlParserConfiguration.getMaxNestingDepth(), XMLParserConfiguration.UNDEFINED_MAXIMUM_NESTING_DEPTH); + } /** * Convenience method, given an input string and expected result, diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 937658e..9c9ada4 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -7,6 +7,7 @@ Public Domain. import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -24,6 +25,7 @@ import java.util.Map; import org.json.*; import org.junit.Rule; import org.junit.Test; +import org.junit.function.ThrowingRunnable; import org.junit.rules.TemporaryFolder; @@ -1247,6 +1249,39 @@ public class XMLTest { fail("file writer error: " +e.getMessage()); } } + + @Test + public void testMaxNestingDepthIsRespected() { + final String wayTooLongMalformedXML = ""; + + Throwable throwable = assertThrows(JSONException.class, new ThrowingRunnable() { + + @Override + public void run() throws Throwable { + XML.toJSONObject(wayTooLongMalformedXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(42)); + } + }); + + assertTrue("Wrong throwable thrown: not expecting message <" + throwable.getMessage() + ">", throwable.getMessage().startsWith("Maximum nesting depth of")); + + final String perfectlyFineXML = "\n" + + " \n" + + " sonoo\n" + + " 56000\n" + + " true\n" + + " \n" + + "\n"; + + throwable = assertThrows(JSONException.class, new ThrowingRunnable() { + + @Override + public void run() throws Throwable { + XML.toJSONObject(perfectlyFineXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(1)); + } + }); + + assertTrue("Wrong throwable thrown: not expecting message <" + throwable.getMessage() + ">", throwable.getMessage().startsWith("Maximum nesting depth of")); + } } -- Gitee From a14cb12c85d50060b1f95840c01f0be5de24503d Mon Sep 17 00:00:00 2001 From: Cleydyr de Albuquerque Date: Wed, 1 Feb 2023 20:20:18 +0100 Subject: [PATCH 27/48] refactor: keep consistence with other tests and tidy up constant --- src/test/java/org/json/junit/XMLTest.java | 39 ++++++++++++----------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 9c9ada4..6c0de9f 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -7,7 +7,6 @@ Public Domain. import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -25,7 +24,6 @@ import java.util.Map; import org.json.*; import org.junit.Rule; import org.junit.Test; -import org.junit.function.ThrowingRunnable; import org.junit.rules.TemporaryFolder; @@ -1251,19 +1249,23 @@ public class XMLTest { } @Test - public void testMaxNestingDepthIsRespected() { - final String wayTooLongMalformedXML = ""; + public void testMaxNestingDepthOf42IsRespected() { + final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", ""); - Throwable throwable = assertThrows(JSONException.class, new ThrowingRunnable() { + final int maxNestingDepth = 42; - @Override - public void run() throws Throwable { - XML.toJSONObject(wayTooLongMalformedXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(42)); - } - }); + try { + XML.toJSONObject(wayTooLongMalformedXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); - assertTrue("Wrong throwable thrown: not expecting message <" + throwable.getMessage() + ">", throwable.getMessage().startsWith("Maximum nesting depth of")); + fail("Expecting a JSONException"); + } catch (JSONException e) { + assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">", + e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth)); + } + } + @Test + public void testMaxNestingDepthIsRespectedWithValidXML() { final String perfectlyFineXML = "\n" + " \n" + " sonoo\n" + @@ -1272,15 +1274,16 @@ public class XMLTest { " \n" + "\n"; - throwable = assertThrows(JSONException.class, new ThrowingRunnable() { + final int maxNestingDepth = 1; - @Override - public void run() throws Throwable { - XML.toJSONObject(perfectlyFineXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(1)); - } - }); + try { + XML.toJSONObject(perfectlyFineXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); - assertTrue("Wrong throwable thrown: not expecting message <" + throwable.getMessage() + ">", throwable.getMessage().startsWith("Maximum nesting depth of")); + fail("Expecting a JSONException"); + } catch (JSONException e) { + assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">", + e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth)); + } } } -- Gitee From 651511f50099a3b8d59617838c82e3d72dd39178 Mon Sep 17 00:00:00 2001 From: Cleydyr de Albuquerque Date: Wed, 1 Feb 2023 20:21:14 +0100 Subject: [PATCH 28/48] tests: add new test to verify that an XML having the permitted nesting depth can be converted --- src/test/java/org/json/junit/XMLTest.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 6c0de9f..7d22610 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -1285,6 +1285,27 @@ public class XMLTest { e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth)); } } + + @Test + public void testMaxNestingDepthWithValidFittingXML() { + final String perfectlyFineXML = "\n" + + " \n" + + " sonoo\n" + + " 56000\n" + + " true\n" + + " \n" + + "\n"; + + final int maxNestingDepth = 3; + + try { + XML.toJSONObject(perfectlyFineXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + } catch (JSONException e) { + e.printStackTrace(); + fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " + + "parameter of the XMLParserConfiguration used"); + } + } } -- Gitee From eb56704e68a186f975400e009d28d4e0b5d887ec Mon Sep 17 00:00:00 2001 From: Cleydyr de Albuquerque Date: Thu, 2 Feb 2023 18:15:03 +0100 Subject: [PATCH 29/48] fix: set default maximum nesting depth as 512 --- src/main/java/org/json/XMLParserConfiguration.java | 11 ++++++++--- src/test/java/org/json/junit/JSONArrayTest.java | 1 - .../java/org/json/junit/XMLConfigurationTest.java | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/json/XMLParserConfiguration.java b/src/main/java/org/json/XMLParserConfiguration.java index e3311fc..f118a81 100644 --- a/src/main/java/org/json/XMLParserConfiguration.java +++ b/src/main/java/org/json/XMLParserConfiguration.java @@ -22,6 +22,11 @@ public class XMLParserConfiguration { */ public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1; + /** + * The default maximum nesting depth when parsing a XML document to JSON. + */ + public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512; + /** Original Configuration of the XML Parser. */ public static final XMLParserConfiguration ORIGINAL = new XMLParserConfiguration(); @@ -64,7 +69,7 @@ public class XMLParserConfiguration { * When parsing the XML into JSON, specifies the tags whose values should be converted * to arrays */ - private int maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH; + private int maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH; /** * Default parser configuration. Does not keep strings (tries to implicitly convert @@ -321,8 +326,8 @@ public class XMLParserConfiguration { /** * Defines the maximum nesting depth that the parser will descend before throwing an exception - * when parsing the XML into JSON. The default max nesting depth is undefined, which means the - * parser will go as deep as the maximum call stack size allows. Using any negative value as a + * when parsing the XML into JSON. The default max nesting depth is 512, which means the parser + * will go as deep as the maximum call stack size allows. Using any negative value as a * parameter is equivalent to setting no limit to the nesting depth. * @param maxNestingDepth the maximum nesting depth allowed to the XML parser * @return The existing configuration will not be modified. A new configuration is returned. diff --git a/src/test/java/org/json/junit/JSONArrayTest.java b/src/test/java/org/json/junit/JSONArrayTest.java index 1a2df7f..aa8657f 100644 --- a/src/test/java/org/json/junit/JSONArrayTest.java +++ b/src/test/java/org/json/junit/JSONArrayTest.java @@ -6,7 +6,6 @@ Public Domain. import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/org/json/junit/XMLConfigurationTest.java b/src/test/java/org/json/junit/XMLConfigurationTest.java index 25b17e2..21a2b59 100755 --- a/src/test/java/org/json/junit/XMLConfigurationTest.java +++ b/src/test/java/org/json/junit/XMLConfigurationTest.java @@ -1056,7 +1056,7 @@ public class XMLConfigurationTest { public void testMaxNestingDepthIsSet() { XMLParserConfiguration xmlParserConfiguration = XMLParserConfiguration.ORIGINAL; - assertEquals(xmlParserConfiguration.getMaxNestingDepth(), XMLParserConfiguration.UNDEFINED_MAXIMUM_NESTING_DEPTH); + assertEquals(xmlParserConfiguration.getMaxNestingDepth(), XMLParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH); xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(42); -- Gitee From 448e204186784adc85c3498cf487eb7c8e83fa57 Mon Sep 17 00:00:00 2001 From: Cleydyr de Albuquerque Date: Thu, 2 Feb 2023 20:16:16 +0100 Subject: [PATCH 30/48] docs: remove wrong description of parse method --- src/main/java/org/json/XML.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java index b8fdefc..db3c79f 100644 --- a/src/main/java/org/json/XML.java +++ b/src/main/java/org/json/XML.java @@ -648,10 +648,6 @@ public class XML { * All values are converted as strings, for 1, 01, 29.0 will not be coerced to * numbers but will instead be the exact value as seen in the XML document. * - * This method can parse documents with a maximum nesting depth of 256. If you - * need to parse documents with a nesting depth greater than 256, you should use - * - * * @param reader The XML source reader. * @param config Configuration options for the parser * @return A JSONObject containing the structured data from the XML string. -- Gitee From 2391d248cc77202eb31d0e4df0edecfbde4ab2dc Mon Sep 17 00:00:00 2001 From: Tamas Perger Date: Fri, 10 Feb 2023 01:45:34 +0000 Subject: [PATCH 31/48] fix: amend XMLParserConfiguration.clone() to include the new maxNestingDepth param. Amend Javadoc for XML and XMLParserConfiguration classes. --- src/main/java/org/json/XML.java | 24 ++++++---- .../java/org/json/XMLParserConfiguration.java | 48 ++++++++++--------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java index db3c79f..925f056 100644 --- a/src/main/java/org/json/XML.java +++ b/src/main/java/org/json/XML.java @@ -98,7 +98,7 @@ public class XML { /** * Replace special characters with XML escapes: * - *
{@code 
+     * 
{@code
      * & (ampersand) is replaced by &amp;
      * < (less than) is replaced by &lt;
      * > (greater than) is replaced by &gt;
@@ -229,8 +229,12 @@ public class XML {
      *            The JSONObject that will include the new material.
      * @param name
      *            The tag name.
+     * @param config
+     *            The XML parser configuration.
+     * @param currentNestingDepth
+     *            The current nesting depth.
      * @return true if the close tag is processed.
-     * @throws JSONException
+     * @throws JSONException Thrown if any parsing error occurs.
      */
     private static boolean parse(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config, int currentNestingDepth)
             throws JSONException {
@@ -427,7 +431,7 @@ public class XML {
                                         context.accumulate(tagName, jsonObject);
                                     }
                                 }
-                                
+
                                 return false;
                             }
                         }
@@ -491,7 +495,7 @@ public class XML {
         }
         return string;
     }
-    
+
     /**
      * direct copy of {@link JSONObject#stringToNumber(String)} to maintain Android support.
      */
@@ -538,7 +542,7 @@ public class XML {
             // integer representation.
             // This will narrow any values to the smallest reasonable Object representation
             // (Integer, Long, or BigInteger)
-            
+
             // BigInteger down conversion: We use a similar bitLength compare as
             // BigInteger#intValueExact uses. Increases GC, but objects hold
             // only what they need. i.e. Less runtime overhead if the value is
@@ -554,7 +558,7 @@ public class XML {
         }
         throw new NumberFormatException("val ["+val+"] is not a valid number.");
     }
-    
+
     /**
      * direct copy of {@link JSONObject#isDecimalNotation(String)} to maintain Android support.
      */
@@ -572,7 +576,7 @@ public class XML {
      * name/value pairs and arrays of values. JSON does not does not like to
      * distinguish between elements and attributes. Sequences of similar
      * elements are represented as JSONArrays. Content text may be placed in a
-     * "content" member. Comments, prologs, DTDs, and 
{@code 
+     * "content" member. Comments, prologs, DTDs, and 
{@code
      * <[ [ ]]>}
* are ignored. * @@ -593,7 +597,7 @@ public class XML { * name/value pairs and arrays of values. JSON does not does not like to * distinguish between elements and attributes. Sequences of similar * elements are represented as JSONArrays. Content text may be placed in a - * "content" member. Comments, prologs, DTDs, and
{@code 
+     * "content" member. Comments, prologs, DTDs, and 
{@code
      * <[ [ ]]>}
* are ignored. * @@ -673,7 +677,7 @@ public class XML { * name/value pairs and arrays of values. JSON does not does not like to * distinguish between elements and attributes. Sequences of similar * elements are represented as JSONArrays. Content text may be placed in a - * "content" member. Comments, prologs, DTDs, and
{@code 
+     * "content" member. Comments, prologs, DTDs, and 
{@code
      * <[ [ ]]>}
* are ignored. * @@ -699,7 +703,7 @@ public class XML { * name/value pairs and arrays of values. JSON does not does not like to * distinguish between elements and attributes. Sequences of similar * elements are represented as JSONArrays. Content text may be placed in a - * "content" member. Comments, prologs, DTDs, and
{@code 
+     * "content" member. Comments, prologs, DTDs, and 
{@code
      * <[ [ ]]>}
* are ignored. * diff --git a/src/main/java/org/json/XMLParserConfiguration.java b/src/main/java/org/json/XMLParserConfiguration.java index f118a81..103023e 100644 --- a/src/main/java/org/json/XMLParserConfiguration.java +++ b/src/main/java/org/json/XMLParserConfiguration.java @@ -39,14 +39,14 @@ public class XMLParserConfiguration { * they should try to be guessed into JSON values (numeric, boolean, string) */ private boolean keepStrings; - + /** * The name of the key in a JSON Object that indicates a CDATA section. Historically this has * been the value "content" but can be changed. Use null to indicate no CDATA * processing. */ private String cDataTagName; - + /** * When parsing the XML into JSON, specifies if values with attribute xsi:nil="true" * should be kept as attribute(false), or they should be converted to @@ -66,8 +66,7 @@ public class XMLParserConfiguration { private Set forceList; /** - * When parsing the XML into JSON, specifies the tags whose values should be converted - * to arrays + * The maximum nesting depth when parsing a XML document to JSON. */ private int maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH; @@ -157,15 +156,18 @@ public class XMLParserConfiguration { * false to parse values with attribute xsi:nil="true" as {"xsi:nil":true}. * @param xsiTypeMap new HashMap>() to parse values with attribute * xsi:type="integer" as integer, xsi:type="string" as string - * @param forceList new HashSet() to parse the provided tags' values as arrays + * @param forceList new HashSet() to parse the provided tags' values as arrays + * @param maxNestingDepth int to limit the nesting depth */ private XMLParserConfiguration (final boolean keepStrings, final String cDataTagName, - final boolean convertNilAttributeToNull, final Map> xsiTypeMap, final Set forceList ) { + final boolean convertNilAttributeToNull, final Map> xsiTypeMap, final Set forceList, + final int maxNestingDepth) { this.keepStrings = keepStrings; this.cDataTagName = cDataTagName; this.convertNilAttributeToNull = convertNilAttributeToNull; this.xsiTypeMap = Collections.unmodifiableMap(xsiTypeMap); this.forceList = Collections.unmodifiableSet(forceList); + this.maxNestingDepth = maxNestingDepth; } /** @@ -183,14 +185,15 @@ public class XMLParserConfiguration { this.cDataTagName, this.convertNilAttributeToNull, this.xsiTypeMap, - this.forceList + this.forceList, + this.maxNestingDepth ); } - + /** * When parsing the XML into JSON, specifies if values should be kept as strings (true), or if * they should try to be guessed into JSON values (numeric, boolean, string) - * + * * @return The keepStrings configuration value. */ public boolean isKeepStrings() { @@ -200,10 +203,10 @@ public class XMLParserConfiguration { /** * When parsing the XML into JSON, specifies if values should be kept as strings (true), or if * they should try to be guessed into JSON values (numeric, boolean, string) - * + * * @param newVal * new value to use for the keepStrings configuration option. - * + * * @return The existing configuration will not be modified. A new configuration is returned. */ public XMLParserConfiguration withKeepStrings(final boolean newVal) { @@ -216,7 +219,7 @@ public class XMLParserConfiguration { * The name of the key in a JSON Object that indicates a CDATA section. Historically this has * been the value "content" but can be changed. Use null to indicate no CDATA * processing. - * + * * @return The cDataTagName configuration value. */ public String getcDataTagName() { @@ -227,10 +230,10 @@ public class XMLParserConfiguration { * The name of the key in a JSON Object that indicates a CDATA section. Historically this has * been the value "content" but can be changed. Use null to indicate no CDATA * processing. - * + * * @param newVal * new value to use for the cDataTagName configuration option. - * + * * @return The existing configuration will not be modified. A new configuration is returned. */ public XMLParserConfiguration withcDataTagName(final String newVal) { @@ -243,7 +246,7 @@ public class XMLParserConfiguration { * When parsing the XML into JSON, specifies if values with attribute xsi:nil="true" * should be kept as attribute(false), or they should be converted to * null(true) - * + * * @return The convertNilAttributeToNull configuration value. */ public boolean isConvertNilAttributeToNull() { @@ -254,10 +257,10 @@ public class XMLParserConfiguration { * When parsing the XML into JSON, specifies if values with attribute xsi:nil="true" * should be kept as attribute(false), or they should be converted to * null(true) - * + * * @param newVal * new value to use for the convertNilAttributeToNull configuration option. - * + * * @return The existing configuration will not be modified. A new configuration is returned. */ public XMLParserConfiguration withConvertNilAttributeToNull(final boolean newVal) { @@ -295,7 +298,7 @@ public class XMLParserConfiguration { /** * When parsing the XML into JSON, specifies that tags that will be converted to arrays - * in this configuration {@code Set} to parse the provided tags' values as arrays + * in this configuration {@code Set} to parse the provided tags' values as arrays * @return forceList unmodifiable configuration set. */ public Set getForceList() { @@ -304,8 +307,8 @@ public class XMLParserConfiguration { /** * When parsing the XML into JSON, specifies that tags that will be converted to arrays - * in this configuration {@code Set} to parse the provided tags' values as arrays - * @param forceList {@code new HashSet()} to parse the provided tags' values as arrays + * in this configuration {@code Set} to parse the provided tags' values as arrays + * @param forceList {@code new HashSet()} to parse the provided tags' values as arrays * @return The existing configuration will not be modified. A new configuration is returned. */ public XMLParserConfiguration withForceList(final Set forceList) { @@ -327,8 +330,9 @@ public class XMLParserConfiguration { /** * Defines the maximum nesting depth that the parser will descend before throwing an exception * when parsing the XML into JSON. The default max nesting depth is 512, which means the parser - * will go as deep as the maximum call stack size allows. Using any negative value as a - * parameter is equivalent to setting no limit to the nesting depth. + * will throw a JsonException if the maximum depth is reached. + * Using any negative value as a parameter is equivalent to setting no limit to the nesting depth, + * which means the parses will go as deep as the maximum call stack size allows. * @param maxNestingDepth the maximum nesting depth allowed to the XML parser * @return The existing configuration will not be modified. A new configuration is returned. */ -- Gitee From a6e412bded7a0ad605adfeca029318f184c32102 Mon Sep 17 00:00:00 2001 From: Tamas Perger Date: Fri, 10 Feb 2023 01:46:44 +0000 Subject: [PATCH 32/48] fix: limit the nesting depth in JSONML Limit the XML nesting depth for CVE-2022-45688 when using the JsonML transform. --- src/main/java/org/json/JSONML.java | 113 +++++++++++--- .../json/XMLtoJSONMLParserConfiguration.java | 128 ++++++++++++++++ src/test/java/org/json/junit/JSONMLTest.java | 140 +++++++++++++----- 3 files changed, 322 insertions(+), 59 deletions(-) create mode 100644 src/main/java/org/json/XMLtoJSONMLParserConfiguration.java diff --git a/src/main/java/org/json/JSONML.java b/src/main/java/org/json/JSONML.java index 2f9b840..c418ed7 100644 --- a/src/main/java/org/json/JSONML.java +++ b/src/main/java/org/json/JSONML.java @@ -27,7 +27,32 @@ public class JSONML { XMLTokener x, boolean arrayForm, JSONArray ja, - boolean keepStrings + boolean keepStrings, + int currentNestingDepth + ) throws JSONException { + return parse(x,arrayForm, ja, + keepStrings ? XMLtoJSONMLParserConfiguration.KEEP_STRINGS : XMLtoJSONMLParserConfiguration.ORIGINAL, + currentNestingDepth); + } + + /** + * Parse XML values and store them in a JSONArray. + * @param x The XMLTokener containing the source string. + * @param arrayForm true if array form, false if object form. + * @param ja The JSONArray that is containing the current tag or null + * if we are at the outermost level. + * @param config The XML parser configuration: + * XMLtoJSONMLParserConfiguration.ORIGINAL is the default behaviour; + * XMLtoJSONMLParserConfiguration.KEEP_STRINGS means Don't type-convert text nodes and attribute values. + * @return A JSONArray if the value is the outermost tag, otherwise null. + * @throws JSONException if a parsing error occurs + */ + private static Object parse( + XMLTokener x, + boolean arrayForm, + JSONArray ja, + XMLtoJSONMLParserConfiguration config, + int currentNestingDepth ) throws JSONException { String attribute; char c; @@ -152,7 +177,7 @@ public class JSONML { if (!(token instanceof String)) { throw x.syntaxError("Missing value"); } - newjo.accumulate(attribute, keepStrings ? ((String)token) :XML.stringToValue((String)token)); + newjo.accumulate(attribute, config.isKeepStrings() ? ((String)token) :XML.stringToValue((String)token)); token = null; } else { newjo.accumulate(attribute, ""); @@ -181,7 +206,12 @@ public class JSONML { if (token != XML.GT) { throw x.syntaxError("Misshaped tag"); } - closeTag = (String)parse(x, arrayForm, newja, keepStrings); + + if (currentNestingDepth == config.getMaxNestingDepth()) { + throw x.syntaxError("Maximum nesting depth of " + config.getMaxNestingDepth() + " reached"); + } + + closeTag = (String)parse(x, arrayForm, newja, config, currentNestingDepth + 1); if (closeTag != null) { if (!closeTag.equals(tagName)) { throw x.syntaxError("Mismatched '" + tagName + @@ -203,7 +233,7 @@ public class JSONML { } else { if (ja != null) { ja.put(token instanceof String - ? keepStrings ? XML.unescape((String)token) :XML.stringToValue((String)token) + ? (config.isKeepStrings() ? XML.unescape((String)token) : XML.stringToValue((String)token)) : token); } } @@ -224,7 +254,7 @@ public class JSONML { * @throws JSONException Thrown on error converting to a JSONArray */ public static JSONArray toJSONArray(String string) throws JSONException { - return (JSONArray)parse(new XMLTokener(string), true, null, false); + return (JSONArray)parse(new XMLTokener(string), true, null, XMLtoJSONMLParserConfiguration.ORIGINAL, 0); } @@ -235,8 +265,8 @@ public class JSONML { * attributes, then the second element will be JSONObject containing the * name/value pairs. If the tag contains children, then strings and * JSONArrays will represent the child tags. - * As opposed to toJSONArray this method does not attempt to convert - * any text node or attribute value to any type + * As opposed to toJSONArray this method does not attempt to convert + * any text node or attribute value to any type * but just leaves it as a string. * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. * @param string The source string. @@ -246,7 +276,7 @@ public class JSONML { * @throws JSONException Thrown on error converting to a JSONArray */ public static JSONArray toJSONArray(String string, boolean keepStrings) throws JSONException { - return (JSONArray)parse(new XMLTokener(string), true, null, keepStrings); + return (JSONArray)parse(new XMLTokener(string), true, null, keepStrings, 0); } @@ -257,8 +287,8 @@ public class JSONML { * attributes, then the second element will be JSONObject containing the * name/value pairs. If the tag contains children, then strings and * JSONArrays will represent the child content and tags. - * As opposed to toJSONArray this method does not attempt to convert - * any text node or attribute value to any type + * As opposed to toJSONArray this method does not attempt to convert + * any text node or attribute value to any type * but just leaves it as a string. * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. * @param x An XMLTokener. @@ -268,7 +298,7 @@ public class JSONML { * @throws JSONException Thrown on error converting to a JSONArray */ public static JSONArray toJSONArray(XMLTokener x, boolean keepStrings) throws JSONException { - return (JSONArray)parse(x, true, null, keepStrings); + return (JSONArray)parse(x, true, null, keepStrings, 0); } @@ -285,7 +315,7 @@ public class JSONML { * @throws JSONException Thrown on error converting to a JSONArray */ public static JSONArray toJSONArray(XMLTokener x) throws JSONException { - return (JSONArray)parse(x, true, null, false); + return (JSONArray)parse(x, true, null, false, 0); } @@ -303,10 +333,10 @@ public class JSONML { * @throws JSONException Thrown on error converting to a JSONObject */ public static JSONObject toJSONObject(String string) throws JSONException { - return (JSONObject)parse(new XMLTokener(string), false, null, false); + return (JSONObject)parse(new XMLTokener(string), false, null, false, 0); } - - + + /** * Convert a well-formed (but not necessarily valid) XML string into a * JSONObject using the JsonML transform. Each XML tag is represented as @@ -323,10 +353,32 @@ public class JSONML { * @throws JSONException Thrown on error converting to a JSONObject */ public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException { - return (JSONObject)parse(new XMLTokener(string), false, null, keepStrings); + return (JSONObject)parse(new XMLTokener(string), false, null, keepStrings, 0); } - + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject using the JsonML transform. Each XML tag is represented as + * a JSONObject with a "tagName" property. If the tag has attributes, then + * the attributes will be in the JSONObject as properties. If the tag + * contains children, the object will have a "childNodes" property which + * will be an array of strings and JsonML JSONObjects. + + * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. + * @param string The XML source text. + * @param config The XML parser configuration: + * XMLtoJSONMLParserConfiguration.ORIGINAL is the default behaviour; + * XMLtoJSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean + * or numeric values and will instead be left as strings + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown on error converting to a JSONObject + */ + public static JSONObject toJSONObject(String string, XMLtoJSONMLParserConfiguration config) throws JSONException { + return (JSONObject)parse(new XMLTokener(string), false, null, config, 0); + } + + /** * Convert a well-formed (but not necessarily valid) XML string into a * JSONObject using the JsonML transform. Each XML tag is represented as @@ -341,7 +393,7 @@ public class JSONML { * @throws JSONException Thrown on error converting to a JSONObject */ public static JSONObject toJSONObject(XMLTokener x) throws JSONException { - return (JSONObject)parse(x, false, null, false); + return (JSONObject)parse(x, false, null, false, 0); } @@ -361,7 +413,29 @@ public class JSONML { * @throws JSONException Thrown on error converting to a JSONObject */ public static JSONObject toJSONObject(XMLTokener x, boolean keepStrings) throws JSONException { - return (JSONObject)parse(x, false, null, keepStrings); + return (JSONObject)parse(x, false, null, keepStrings, 0); + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject using the JsonML transform. Each XML tag is represented as + * a JSONObject with a "tagName" property. If the tag has attributes, then + * the attributes will be in the JSONObject as properties. If the tag + * contains children, the object will have a "childNodes" property which + * will be an array of strings and JsonML JSONObjects. + + * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. + * @param x An XMLTokener of the XML source text. + * @param config The XML parser configuration: + * XMLtoJSONMLParserConfiguration.ORIGINAL is the default behaviour; + * XMLtoJSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean + * or numeric values and will instead be left as strings + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown on error converting to a JSONObject + */ + public static JSONObject toJSONObject(XMLTokener x, XMLtoJSONMLParserConfiguration config) throws JSONException { + return (JSONObject)parse(x, false, null, config, 0); } @@ -442,6 +516,7 @@ public class JSONML { return sb.toString(); } + /** * Reverse the JSONML transformation, making an XML text from a JSONObject. * The JSONObject must contain a "tagName" property. If it has children, diff --git a/src/main/java/org/json/XMLtoJSONMLParserConfiguration.java b/src/main/java/org/json/XMLtoJSONMLParserConfiguration.java new file mode 100644 index 0000000..452f992 --- /dev/null +++ b/src/main/java/org/json/XMLtoJSONMLParserConfiguration.java @@ -0,0 +1,128 @@ +package org.json; +/* +Public Domain. +*/ + +/** + * Configuration object for the XML to JSONML parser. The configuration is immutable. + */ +@SuppressWarnings({""}) +public class XMLtoJSONMLParserConfiguration { + /** + * Used to indicate there's no defined limit to the maximum nesting depth when parsing a XML + * document to JSONML. + */ + public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1; + + /** + * The default maximum nesting depth when parsing a XML document to JSONML. + */ + public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512; + + /** Original Configuration of the XML to JSONML Parser. */ + public static final XMLtoJSONMLParserConfiguration ORIGINAL + = new XMLtoJSONMLParserConfiguration(); + /** Original configuration of the XML to JSONML Parser except that values are kept as strings. */ + public static final XMLtoJSONMLParserConfiguration KEEP_STRINGS + = new XMLtoJSONMLParserConfiguration().withKeepStrings(true); + + /** + * When parsing the XML into JSONML, specifies if values should be kept as strings (true), or if + * they should try to be guessed into JSON values (numeric, boolean, string) + */ + private boolean keepStrings; + + /** + * The maximum nesting depth when parsing a XML document to JSONML. + */ + private int maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH; + + /** + * Default parser configuration. Does not keep strings (tries to implicitly convert values). + */ + public XMLtoJSONMLParserConfiguration() { + this.keepStrings = false; + } + + /** + * Configure the parser string processing and use the default CDATA Tag Name as "content". + * @param keepStrings true to parse all values as string. + * false to try and convert XML string values into a JSON value. + * @param maxNestingDepth int to limit the nesting depth + */ + public XMLtoJSONMLParserConfiguration(final boolean keepStrings, final int maxNestingDepth) { + this.keepStrings = keepStrings; + this.maxNestingDepth = maxNestingDepth; + } + + /** + * Provides a new instance of the same configuration. + */ + @Override + protected XMLtoJSONMLParserConfiguration clone() { + // future modifications to this method should always ensure a "deep" + // clone in the case of collections. i.e. if a Map is added as a configuration + // item, a new map instance should be created and if possible each value in the + // map should be cloned as well. If the values of the map are known to also + // be immutable, then a shallow clone of the map is acceptable. + return new XMLtoJSONMLParserConfiguration( + this.keepStrings, + this.maxNestingDepth + ); + } + + /** + * When parsing the XML into JSONML, specifies if values should be kept as strings (true), or if + * they should try to be guessed into JSON values (numeric, boolean, string) + * + * @return The keepStrings configuration value. + */ + public boolean isKeepStrings() { + return this.keepStrings; + } + + /** + * When parsing the XML into JSONML, specifies if values should be kept as strings (true), or if + * they should try to be guessed into JSON values (numeric, boolean, string) + * + * @param newVal + * new value to use for the keepStrings configuration option. + * + * @return The existing configuration will not be modified. A new configuration is returned. + */ + public XMLtoJSONMLParserConfiguration withKeepStrings(final boolean newVal) { + XMLtoJSONMLParserConfiguration newConfig = this.clone(); + newConfig.keepStrings = newVal; + return newConfig; + } + + /** + * The maximum nesting depth that the parser will descend before throwing an exception + * when parsing the XML into JSONML. + * @return the maximum nesting depth set for this configuration + */ + public int getMaxNestingDepth() { + return maxNestingDepth; + } + + /** + * Defines the maximum nesting depth that the parser will descend before throwing an exception + * when parsing the XML into JSONML. The default max nesting depth is 512, which means the parser + * will throw a JsonException if the maximum depth is reached. + * Using any negative value as a parameter is equivalent to setting no limit to the nesting depth, + * which means the parses will go as deep as the maximum call stack size allows. + * @param maxNestingDepth the maximum nesting depth allowed to the XML parser + * @return The existing configuration will not be modified. A new configuration is returned. + */ + public XMLtoJSONMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) { + XMLtoJSONMLParserConfiguration newConfig = this.clone(); + + if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) { + newConfig.maxNestingDepth = maxNestingDepth; + } else { + newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH; + } + + return newConfig; + } +} diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java index 34bc9f0..6a5062e 100644 --- a/src/test/java/org/json/junit/JSONMLTest.java +++ b/src/test/java/org/json/junit/JSONMLTest.java @@ -11,19 +11,19 @@ import org.junit.Test; /** * Tests for org.json.JSONML.java - * + * * Certain inputs are expected to result in exceptions. These tests are * executed first. JSONML provides an API to: - * Convert an XML string into a JSONArray or a JSONObject. + * Convert an XML string into a JSONArray or a JSONObject. * Convert a JSONArray or JSONObject into an XML string. * Both fromstring and tostring operations operations should be symmetrical - * within the limits of JSONML. + * within the limits of JSONML. * It should be possible to perform the following operations, which should * result in the original string being recovered, within the limits of the * underlying classes: * Convert a string -> JSONArray -> string -> JSONObject -> string * Convert a string -> JSONObject -> string -> JSONArray -> string - * + * */ public class JSONMLTest { @@ -56,7 +56,7 @@ public class JSONMLTest { /** * Attempts to call JSONML.toString() with a null JSONArray. - * Expects a NullPointerException. + * Expects a NullPointerException. */ @Test(expected=NullPointerException.class) public void nullJSONXMLException() { @@ -69,7 +69,7 @@ public class JSONMLTest { /** * Attempts to call JSONML.toString() with a null JSONArray. - * Expects a JSONException. + * Expects a JSONException. */ @Test public void emptyJSONXMLException() { @@ -125,7 +125,7 @@ public class JSONMLTest { "[\"addresses\","+ "{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+ "\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+ - // this array has no name + // this array has no name "["+ "[\"name\"],"+ "[\"nocontent\"],"+ @@ -180,7 +180,7 @@ public class JSONMLTest { } /** - * Attempts to transform a malformed XML document + * Attempts to transform a malformed XML document * (element tag has a frontslash) to a JSONArray.\ * Expects a JSONException */ @@ -191,7 +191,7 @@ public class JSONMLTest { * In this case, the XML is invalid because the 'name' element * contains an invalid frontslash. */ - String xmlStr = + String xmlStr = "\n"+ "\n"+ @@ -216,7 +216,7 @@ public class JSONMLTest { */ @Test public void invalidBangInTagException() { - String xmlStr = + String xmlStr = "\n"+ "\n"+ @@ -246,7 +246,7 @@ public class JSONMLTest { * In this case, the XML is invalid because an element * starts with '!' and has no closing tag */ - String xmlStr = + String xmlStr = "\n"+ "\n"+ @@ -276,7 +276,7 @@ public class JSONMLTest { * In this case, the XML is invalid because an element * has no closing '>'. */ - String xmlStr = + String xmlStr = "\n"+ "\n"+ @@ -306,7 +306,7 @@ public class JSONMLTest { * In this case, the XML is invalid because an element * has no name after the closing tag '\n"+ "\n"+ @@ -336,7 +336,7 @@ public class JSONMLTest { * In this case, the XML is invalid because an element * has '>' after the closing tag '\n"+ "\n"+ @@ -364,9 +364,9 @@ public class JSONMLTest { /** * xmlStr contains XML text which is transformed into a JSONArray. * In this case, the XML is invalid because an element - * does not have a complete CDATA string. + * does not have a complete CDATA string. */ - String xmlStr = + String xmlStr = "\n"+ "\n"+ @@ -388,7 +388,7 @@ public class JSONMLTest { /** * Convert an XML document into a JSONArray, then use JSONML.toString() * to convert it into a string. This string is then converted back into - * a JSONArray. Both JSONArrays are compared against a control to + * a JSONArray. Both JSONArrays are compared against a control to * confirm the contents. */ @Test @@ -405,7 +405,7 @@ public class JSONMLTest { * which is used to create a final JSONArray, which is also compared * against the expected JSONArray. */ - String xmlStr = + String xmlStr = "\n"+ "\n"+ @@ -414,7 +414,7 @@ public class JSONMLTest { ">\n"+ "\n"+ ""; - String expectedStr = + String expectedStr = "[\"addresses\","+ "{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+ "\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+ @@ -434,12 +434,12 @@ public class JSONMLTest { } /** - * Convert an XML document into a JSONObject. Use JSONML.toString() to + * Convert an XML document into a JSONObject. Use JSONML.toString() to * convert it back into a string, and then re-convert it into a JSONObject. * Both JSONObjects are compared against a control JSONObject to confirm * the contents. *

- * Next convert the XML document into a JSONArray. Use JSONML.toString() to + * Next convert the XML document into a JSONArray. Use JSONML.toString() to * convert it back into a string, and then re-convert it into a JSONArray. * Both JSONArrays are compared against a control JSONArray to confirm * the contents. @@ -452,23 +452,23 @@ public class JSONMLTest { /** * xmlStr contains XML text which is transformed into a JSONObject, * restored to XML, transformed into a JSONArray, and then restored - * to XML again. Both JSONObject and JSONArray should contain the same + * to XML again. Both JSONObject and JSONArray should contain the same * information and should produce the same XML, allowing for non-ordered * attributes. - * + * * Transformation to JSONObject: * The elementName is stored as a string where key="tagName" * Attributes are simply stored as key/value pairs * If the element has either content or child elements, they are stored * in a jsonArray with key="childNodes". - * + * * Transformation to JSONArray: * 1st entry = elementname * 2nd entry = attributes object (if present) * 3rd entry = content (if present) * 4th entry = child element JSONArrays (if present) */ - String xmlStr = + String xmlStr = "\n"+ "\n"+ @@ -585,7 +585,7 @@ public class JSONMLTest { "\"tagName\":\"addresses\""+ "}"; - String expectedJSONArrayStr = + String expectedJSONArrayStr = "["+ "\"addresses\","+ "{"+ @@ -645,12 +645,12 @@ public class JSONMLTest { JSONObject finalJsonObject = JSONML.toJSONObject(jsonObjectXmlToStr); Util.compareActualVsExpectedJsonObjects(finalJsonObject, expectedJsonObject); - // create a JSON array from the original string and make sure it + // create a JSON array from the original string and make sure it // looks as expected JSONArray jsonArray = JSONML.toJSONArray(xmlStr); JSONArray expectedJsonArray = new JSONArray(expectedJSONArrayStr); Util.compareActualVsExpectedJsonArrays(jsonArray,expectedJsonArray); - + // restore the XML, then make another JSONArray and make sure it // looks as expected String jsonArrayXmlToStr = JSONML.toString(jsonArray); @@ -668,14 +668,14 @@ public class JSONMLTest { * Convert an XML document which contains embedded comments into * a JSONArray. Use JSONML.toString() to turn it into a string, then * reconvert it into a JSONArray. Compare both JSONArrays to a control - * JSONArray to confirm the contents. + * JSONArray to confirm the contents. *

* This test shows how XML comments are handled. */ @Test public void commentsInXML() { - String xmlStr = + String xmlStr = "\n"+ "\n"+ "\n"+ @@ -734,7 +734,7 @@ public class JSONMLTest { final String expectedJsonString = "[\"root\",[\"id\",\"01\"],[\"id\",\"1\"],[\"id\",\"00\"],[\"id\",\"0\"],[\"item\",{\"id\":\"01\"}],[\"title\",\"True\"]]"; final JSONArray json = JSONML.toJSONArray(originalXml,true); assertEquals(expectedJsonString, json.toString()); - + final String reverseXml = JSONML.toString(json); assertEquals(originalXml, reverseXml); } @@ -749,7 +749,7 @@ public class JSONMLTest { final String revertedXml = JSONML.toString(jsonArray); assertEquals(revertedXml, originalXml); } - + /** * JSON string cannot be reverted to original xml. See test result in * comment below. @@ -770,7 +770,7 @@ public class JSONMLTest { // 1. Our XML parser does not handle generic HTML entities, only valid XML entities. Hence   // or other HTML specific entities would fail on reversability // 2. Our JSON implementation for storing the XML attributes uses the standard unordered map. -// This means that can not be reversed reliably. +// This means that can not be reversed reliably. // // /** // * Test texts taken from jsonml.org. Currently our implementation FAILS this conversion but shouldn't. @@ -783,13 +783,13 @@ public class JSONMLTest { // final String expectedJsonString = "[\"table\",{\"class\" : \"MyTable\",\"style\" : \"background-color:yellow\"},[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#550758\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:red\"},\"Example text here\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#993101\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:green\"},\"127624015\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#E33D87\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:blue\"},\"\u00A0\",[\"span\",{ \"style\" : \"background-color:maroon\" },\"\u00A9\"],\"\u00A0\"]]]"; // final JSONArray json = JSONML.toJSONArray(originalXml,true); // final String actualJsonString = json.toString(); -// +// // final String reverseXml = JSONML.toString(json); // assertNotEquals(originalXml, reverseXml); // // assertNotEquals(expectedJsonString, actualJsonString); // } -// +// // /** // * Test texts taken from jsonml.org but modified to have XML entities only. // */ @@ -799,15 +799,15 @@ public class JSONMLTest { // final String expectedJsonString = "[\"table\",{\"class\" : \"MyTable\",\"style\" : \"background-color:yellow\"},[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#550758\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:red\"},\"Example text here\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#993101\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:green\"},\"127624015\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#E33D87\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:blue\"},\"&\",[\"span\",{ \"style\" : \"background-color:maroon\" },\">\"],\"<\"]]]"; // final JSONArray jsonML = JSONML.toJSONArray(originalXml,true); // final String actualJsonString = jsonML.toString(); -// +// // final String reverseXml = JSONML.toString(jsonML); // // currently not equal because the hashing of the attribute objects makes the attribute -// // order not happen the same way twice +// // order not happen the same way twice // assertEquals(originalXml, reverseXml); // // assertEquals(expectedJsonString, actualJsonString); // } - + @Test (timeout = 6000) public void testIssue484InfinteLoop1() { try { @@ -819,11 +819,11 @@ public class JSONMLTest { ex.getMessage()); } } - + @Test (timeout = 6000) public void testIssue484InfinteLoop2() { try { - String input = "??*\n" + + String input = "??*\n" + "??|?CglR??`??>?w??PIlr??D?$?-?o??O?*??{OD?Y??`2a????NM?bq?:O?>S$ ?J?B.gUK?m\b??zE???!v]???????c??????h???s???g???`?qbi??:Zl?)?}1^??k?0??:$V?$?Ovs(}J??????2;gQ????Tg?K?`?h%c?hmGA?"); + + final int maxNestingDepth = 42; + + try { + JSONML.toJSONObject(wayTooLongMalformedXML, XMLtoJSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + + fail("Expecting a JSONException"); + } catch (JSONException e) { + assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">", + e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth)); + } + } + + @Test + public void testMaxNestingDepthIsRespectedWithValidXML() { + final String perfectlyFineXML = "\n" + + " \n" + + " sonoo\n" + + " 56000\n" + + " true\n" + + " \n" + + "\n"; + + final int maxNestingDepth = 1; + + try { + JSONML.toJSONObject(perfectlyFineXML, XMLtoJSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + + fail("Expecting a JSONException"); + } catch (JSONException e) { + assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">", + e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth)); + } + } + + @Test + public void testMaxNestingDepthWithValidFittingXML() { + final String perfectlyFineXML = "\n" + + " \n" + + " sonoo\n" + + " 56000\n" + + " true\n" + + " \n" + + "\n"; + + final int maxNestingDepth = 3; + + try { + JSONML.toJSONObject(perfectlyFineXML, XMLtoJSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + } catch (JSONException e) { + e.printStackTrace(); + fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " + + "parameter of the XMLtoJSONMLParserConfiguration used"); + } + } + } -- Gitee From df2d6f83630df4d302b0e20c1f32d5c4d47030db Mon Sep 17 00:00:00 2001 From: Tamas Perger Date: Sat, 11 Feb 2023 01:52:13 +0000 Subject: [PATCH 33/48] fix: introduce optional XMLtoJSONMLParserConfiguration parameter for JSONML.toJSONArray(...) functions, to facilitate max nesting depth override. --- src/main/java/org/json/JSONML.java | 49 ++++++++++++++ src/test/java/org/json/junit/JSONMLTest.java | 70 +++++++++++++++++++- 2 files changed, 116 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/json/JSONML.java b/src/main/java/org/json/JSONML.java index c418ed7..a58137e 100644 --- a/src/main/java/org/json/JSONML.java +++ b/src/main/java/org/json/JSONML.java @@ -280,6 +280,55 @@ public class JSONML { } + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONArray using the JsonML transform. Each XML tag is represented as + * a JSONArray in which the first element is the tag name. If the tag has + * attributes, then the second element will be JSONObject containing the + * name/value pairs. If the tag contains children, then strings and + * JSONArrays will represent the child tags. + * As opposed to toJSONArray this method does not attempt to convert + * any text node or attribute value to any type + * but just leaves it as a string. + * Comments, prologs, DTDs, and

{@code <[ [ ]]>}
are ignored. + * @param string The source string. + * @param config The XML parser configuration: + * XMLtoJSONMLParserConfiguration.ORIGINAL is the default behaviour; + * XMLtoJSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean + * or numeric values and will instead be left as strings + * @return A JSONArray containing the structured data from the XML string. + * @throws JSONException Thrown on error converting to a JSONArray + */ + public static JSONArray toJSONArray(String string, XMLtoJSONMLParserConfiguration config) throws JSONException { + return (JSONArray)parse(new XMLTokener(string), true, null, config, 0); + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONArray using the JsonML transform. Each XML tag is represented as + * a JSONArray in which the first element is the tag name. If the tag has + * attributes, then the second element will be JSONObject containing the + * name/value pairs. If the tag contains children, then strings and + * JSONArrays will represent the child content and tags. + * As opposed to toJSONArray this method does not attempt to convert + * any text node or attribute value to any type + * but just leaves it as a string. + * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. + * @param x An XMLTokener. + * @param config The XML parser configuration: + * XMLtoJSONMLParserConfiguration.ORIGINAL is the default behaviour; + * XMLtoJSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean + * or numeric values and will instead be left as strings + * @return A JSONArray containing the structured data from the XML string. + * @throws JSONException Thrown on error converting to a JSONArray + */ + public static JSONArray toJSONArray(XMLTokener x, XMLtoJSONMLParserConfiguration config) throws JSONException { + return (JSONArray)parse(x, true, null, config, 0); + } + + /** * Convert a well-formed (but not necessarily valid) XML string into a * JSONArray using the JsonML transform. Each XML tag is represented as diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java index 6a5062e..7d0a285 100644 --- a/src/test/java/org/json/junit/JSONMLTest.java +++ b/src/test/java/org/json/junit/JSONMLTest.java @@ -835,7 +835,71 @@ public class JSONMLTest { } @Test - public void testMaxNestingDepthOf42IsRespected() { + public void testToJSONArrayMaxNestingDepthOf42IsRespected() { + final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", "
"); + + final int maxNestingDepth = 42; + + try { + JSONML.toJSONArray(wayTooLongMalformedXML, XMLtoJSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + + fail("Expecting a JSONException"); + } catch (JSONException e) { + assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">", + e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth)); + } + } + + + @Test + public void testToJSONArrayMaxNestingDepthIsRespectedWithValidXML() { + final String perfectlyFineXML = "\n" + + " \n" + + " sonoo\n" + + " 56000\n" + + " true\n" + + " \n" + + "\n"; + + final int maxNestingDepth = 1; + + try { + JSONML.toJSONArray(perfectlyFineXML, XMLtoJSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + + fail("Expecting a JSONException"); + } catch (JSONException e) { + assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">", + e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth)); + } + } + + @Test + public void testToJSONArrayMaxNestingDepthWithValidFittingXML() { + final String perfectlyFineXML = "\n" + + " \n" + + " sonoo\n" + + " 56000\n" + + " true\n" + + " \n" + + "\n"; + + final int maxNestingDepth = 3; + + try { + JSONML.toJSONArray(perfectlyFineXML, XMLtoJSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + } catch (JSONException e) { + e.printStackTrace(); + fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " + + "parameter of the XMLtoJSONMLParserConfiguration used"); + } + } + + + + + + @Test + public void testToJSONObjectMaxNestingDepthOf42IsRespected() { final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", ""); final int maxNestingDepth = 42; @@ -851,7 +915,7 @@ public class JSONMLTest { } @Test - public void testMaxNestingDepthIsRespectedWithValidXML() { + public void testToJSONObjectMaxNestingDepthIsRespectedWithValidXML() { final String perfectlyFineXML = "\n" + " \n" + " sonoo\n" + @@ -873,7 +937,7 @@ public class JSONMLTest { } @Test - public void testMaxNestingDepthWithValidFittingXML() { + public void testToJSONObjectMaxNestingDepthWithValidFittingXML() { final String perfectlyFineXML = "\n" + " \n" + " sonoo\n" + -- Gitee From 72f4c3e6468c7391b34bc530c1905056fdd596e6 Mon Sep 17 00:00:00 2001 From: Tamas Perger Date: Sun, 12 Feb 2023 01:32:34 +0000 Subject: [PATCH 34/48] refactor: rename XMLtoJSONMLParserConfiguration to JSONMLParserConfiguration --- src/main/java/org/json/JSONML.java | 44 +++++++++---------- ...on.java => JSONMLParserConfiguration.java} | 26 +++++------ src/test/java/org/json/junit/JSONMLTest.java | 16 +++---- 3 files changed, 43 insertions(+), 43 deletions(-) rename src/main/java/org/json/{XMLtoJSONMLParserConfiguration.java => JSONMLParserConfiguration.java} (83%) diff --git a/src/main/java/org/json/JSONML.java b/src/main/java/org/json/JSONML.java index a58137e..4aea014 100644 --- a/src/main/java/org/json/JSONML.java +++ b/src/main/java/org/json/JSONML.java @@ -31,7 +31,7 @@ public class JSONML { int currentNestingDepth ) throws JSONException { return parse(x,arrayForm, ja, - keepStrings ? XMLtoJSONMLParserConfiguration.KEEP_STRINGS : XMLtoJSONMLParserConfiguration.ORIGINAL, + keepStrings ? JSONMLParserConfiguration.KEEP_STRINGS : JSONMLParserConfiguration.ORIGINAL, currentNestingDepth); } @@ -41,9 +41,9 @@ public class JSONML { * @param arrayForm true if array form, false if object form. * @param ja The JSONArray that is containing the current tag or null * if we are at the outermost level. - * @param config The XML parser configuration: - * XMLtoJSONMLParserConfiguration.ORIGINAL is the default behaviour; - * XMLtoJSONMLParserConfiguration.KEEP_STRINGS means Don't type-convert text nodes and attribute values. + * @param config The parser configuration: + * JSONMLParserConfiguration.ORIGINAL is the default behaviour; + * JSONMLParserConfiguration.KEEP_STRINGS means Don't type-convert text nodes and attribute values. * @return A JSONArray if the value is the outermost tag, otherwise null. * @throws JSONException if a parsing error occurs */ @@ -51,7 +51,7 @@ public class JSONML { XMLTokener x, boolean arrayForm, JSONArray ja, - XMLtoJSONMLParserConfiguration config, + JSONMLParserConfiguration config, int currentNestingDepth ) throws JSONException { String attribute; @@ -254,7 +254,7 @@ public class JSONML { * @throws JSONException Thrown on error converting to a JSONArray */ public static JSONArray toJSONArray(String string) throws JSONException { - return (JSONArray)parse(new XMLTokener(string), true, null, XMLtoJSONMLParserConfiguration.ORIGINAL, 0); + return (JSONArray)parse(new XMLTokener(string), true, null, JSONMLParserConfiguration.ORIGINAL, 0); } @@ -293,14 +293,14 @@ public class JSONML { * but just leaves it as a string. * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. * @param string The source string. - * @param config The XML parser configuration: - * XMLtoJSONMLParserConfiguration.ORIGINAL is the default behaviour; - * XMLtoJSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean + * @param config The parser configuration: + * JSONMLParserConfiguration.ORIGINAL is the default behaviour; + * JSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean * or numeric values and will instead be left as strings * @return A JSONArray containing the structured data from the XML string. * @throws JSONException Thrown on error converting to a JSONArray */ - public static JSONArray toJSONArray(String string, XMLtoJSONMLParserConfiguration config) throws JSONException { + public static JSONArray toJSONArray(String string, JSONMLParserConfiguration config) throws JSONException { return (JSONArray)parse(new XMLTokener(string), true, null, config, 0); } @@ -317,14 +317,14 @@ public class JSONML { * but just leaves it as a string. * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. * @param x An XMLTokener. - * @param config The XML parser configuration: - * XMLtoJSONMLParserConfiguration.ORIGINAL is the default behaviour; - * XMLtoJSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean + * @param config The parser configuration: + * JSONMLParserConfiguration.ORIGINAL is the default behaviour; + * JSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean * or numeric values and will instead be left as strings * @return A JSONArray containing the structured data from the XML string. * @throws JSONException Thrown on error converting to a JSONArray */ - public static JSONArray toJSONArray(XMLTokener x, XMLtoJSONMLParserConfiguration config) throws JSONException { + public static JSONArray toJSONArray(XMLTokener x, JSONMLParserConfiguration config) throws JSONException { return (JSONArray)parse(x, true, null, config, 0); } @@ -416,14 +416,14 @@ public class JSONML { * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. * @param string The XML source text. - * @param config The XML parser configuration: - * XMLtoJSONMLParserConfiguration.ORIGINAL is the default behaviour; - * XMLtoJSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean + * @param config The parser configuration: + * JSONMLParserConfiguration.ORIGINAL is the default behaviour; + * JSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean * or numeric values and will instead be left as strings * @return A JSONObject containing the structured data from the XML string. * @throws JSONException Thrown on error converting to a JSONObject */ - public static JSONObject toJSONObject(String string, XMLtoJSONMLParserConfiguration config) throws JSONException { + public static JSONObject toJSONObject(String string, JSONMLParserConfiguration config) throws JSONException { return (JSONObject)parse(new XMLTokener(string), false, null, config, 0); } @@ -476,14 +476,14 @@ public class JSONML { * Comments, prologs, DTDs, and
{@code <[ [ ]]>}
are ignored. * @param x An XMLTokener of the XML source text. - * @param config The XML parser configuration: - * XMLtoJSONMLParserConfiguration.ORIGINAL is the default behaviour; - * XMLtoJSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean + * @param config The parser configuration: + * JSONMLParserConfiguration.ORIGINAL is the default behaviour; + * JSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean * or numeric values and will instead be left as strings * @return A JSONObject containing the structured data from the XML string. * @throws JSONException Thrown on error converting to a JSONObject */ - public static JSONObject toJSONObject(XMLTokener x, XMLtoJSONMLParserConfiguration config) throws JSONException { + public static JSONObject toJSONObject(XMLTokener x, JSONMLParserConfiguration config) throws JSONException { return (JSONObject)parse(x, false, null, config, 0); } diff --git a/src/main/java/org/json/XMLtoJSONMLParserConfiguration.java b/src/main/java/org/json/JSONMLParserConfiguration.java similarity index 83% rename from src/main/java/org/json/XMLtoJSONMLParserConfiguration.java rename to src/main/java/org/json/JSONMLParserConfiguration.java index 452f992..26f7386 100644 --- a/src/main/java/org/json/XMLtoJSONMLParserConfiguration.java +++ b/src/main/java/org/json/JSONMLParserConfiguration.java @@ -7,7 +7,7 @@ Public Domain. * Configuration object for the XML to JSONML parser. The configuration is immutable. */ @SuppressWarnings({""}) -public class XMLtoJSONMLParserConfiguration { +public class JSONMLParserConfiguration { /** * Used to indicate there's no defined limit to the maximum nesting depth when parsing a XML * document to JSONML. @@ -20,11 +20,11 @@ public class XMLtoJSONMLParserConfiguration { public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512; /** Original Configuration of the XML to JSONML Parser. */ - public static final XMLtoJSONMLParserConfiguration ORIGINAL - = new XMLtoJSONMLParserConfiguration(); + public static final JSONMLParserConfiguration ORIGINAL + = new JSONMLParserConfiguration(); /** Original configuration of the XML to JSONML Parser except that values are kept as strings. */ - public static final XMLtoJSONMLParserConfiguration KEEP_STRINGS - = new XMLtoJSONMLParserConfiguration().withKeepStrings(true); + public static final JSONMLParserConfiguration KEEP_STRINGS + = new JSONMLParserConfiguration().withKeepStrings(true); /** * When parsing the XML into JSONML, specifies if values should be kept as strings (true), or if @@ -40,7 +40,7 @@ public class XMLtoJSONMLParserConfiguration { /** * Default parser configuration. Does not keep strings (tries to implicitly convert values). */ - public XMLtoJSONMLParserConfiguration() { + public JSONMLParserConfiguration() { this.keepStrings = false; } @@ -50,7 +50,7 @@ public class XMLtoJSONMLParserConfiguration { * false to try and convert XML string values into a JSON value. * @param maxNestingDepth int to limit the nesting depth */ - public XMLtoJSONMLParserConfiguration(final boolean keepStrings, final int maxNestingDepth) { + public JSONMLParserConfiguration(final boolean keepStrings, final int maxNestingDepth) { this.keepStrings = keepStrings; this.maxNestingDepth = maxNestingDepth; } @@ -59,13 +59,13 @@ public class XMLtoJSONMLParserConfiguration { * Provides a new instance of the same configuration. */ @Override - protected XMLtoJSONMLParserConfiguration clone() { + protected JSONMLParserConfiguration clone() { // future modifications to this method should always ensure a "deep" // clone in the case of collections. i.e. if a Map is added as a configuration // item, a new map instance should be created and if possible each value in the // map should be cloned as well. If the values of the map are known to also // be immutable, then a shallow clone of the map is acceptable. - return new XMLtoJSONMLParserConfiguration( + return new JSONMLParserConfiguration( this.keepStrings, this.maxNestingDepth ); @@ -90,8 +90,8 @@ public class XMLtoJSONMLParserConfiguration { * * @return The existing configuration will not be modified. A new configuration is returned. */ - public XMLtoJSONMLParserConfiguration withKeepStrings(final boolean newVal) { - XMLtoJSONMLParserConfiguration newConfig = this.clone(); + public JSONMLParserConfiguration withKeepStrings(final boolean newVal) { + JSONMLParserConfiguration newConfig = this.clone(); newConfig.keepStrings = newVal; return newConfig; } @@ -114,8 +114,8 @@ public class XMLtoJSONMLParserConfiguration { * @param maxNestingDepth the maximum nesting depth allowed to the XML parser * @return The existing configuration will not be modified. A new configuration is returned. */ - public XMLtoJSONMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) { - XMLtoJSONMLParserConfiguration newConfig = this.clone(); + public JSONMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) { + JSONMLParserConfiguration newConfig = this.clone(); if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) { newConfig.maxNestingDepth = maxNestingDepth; diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java index 7d0a285..1514ddd 100644 --- a/src/test/java/org/json/junit/JSONMLTest.java +++ b/src/test/java/org/json/junit/JSONMLTest.java @@ -841,7 +841,7 @@ public class JSONMLTest { final int maxNestingDepth = 42; try { - JSONML.toJSONArray(wayTooLongMalformedXML, XMLtoJSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + JSONML.toJSONArray(wayTooLongMalformedXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); fail("Expecting a JSONException"); } catch (JSONException e) { @@ -864,7 +864,7 @@ public class JSONMLTest { final int maxNestingDepth = 1; try { - JSONML.toJSONArray(perfectlyFineXML, XMLtoJSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + JSONML.toJSONArray(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); fail("Expecting a JSONException"); } catch (JSONException e) { @@ -886,11 +886,11 @@ public class JSONMLTest { final int maxNestingDepth = 3; try { - JSONML.toJSONArray(perfectlyFineXML, XMLtoJSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + JSONML.toJSONArray(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); } catch (JSONException e) { e.printStackTrace(); fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " + - "parameter of the XMLtoJSONMLParserConfiguration used"); + "parameter of the JSONMLParserConfiguration used"); } } @@ -905,7 +905,7 @@ public class JSONMLTest { final int maxNestingDepth = 42; try { - JSONML.toJSONObject(wayTooLongMalformedXML, XMLtoJSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + JSONML.toJSONObject(wayTooLongMalformedXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); fail("Expecting a JSONException"); } catch (JSONException e) { @@ -927,7 +927,7 @@ public class JSONMLTest { final int maxNestingDepth = 1; try { - JSONML.toJSONObject(perfectlyFineXML, XMLtoJSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + JSONML.toJSONObject(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); fail("Expecting a JSONException"); } catch (JSONException e) { @@ -949,11 +949,11 @@ public class JSONMLTest { final int maxNestingDepth = 3; try { - JSONML.toJSONObject(perfectlyFineXML, XMLtoJSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); + JSONML.toJSONObject(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth)); } catch (JSONException e) { e.printStackTrace(); fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " + - "parameter of the XMLtoJSONMLParserConfiguration used"); + "parameter of the JSONMLParserConfiguration used"); } } -- Gitee From 9234eab00a421850a20691b04bb18c7cffe4c58a Mon Sep 17 00:00:00 2001 From: Tamas Perger Date: Mon, 13 Feb 2023 01:09:29 +0000 Subject: [PATCH 35/48] refactor: make JSONMLParserConfiguration all-args constructor private, enforcing the builder pattern. --- src/main/java/org/json/JSONMLParserConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/json/JSONMLParserConfiguration.java b/src/main/java/org/json/JSONMLParserConfiguration.java index 26f7386..b7162bf 100644 --- a/src/main/java/org/json/JSONMLParserConfiguration.java +++ b/src/main/java/org/json/JSONMLParserConfiguration.java @@ -50,7 +50,7 @@ public class JSONMLParserConfiguration { * false to try and convert XML string values into a JSON value. * @param maxNestingDepth int to limit the nesting depth */ - public JSONMLParserConfiguration(final boolean keepStrings, final int maxNestingDepth) { + private JSONMLParserConfiguration(final boolean keepStrings, final int maxNestingDepth) { this.keepStrings = keepStrings; this.maxNestingDepth = maxNestingDepth; } -- Gitee From 24093491a8d9c1dfa8e062df9ae0c1dde56bba5a Mon Sep 17 00:00:00 2001 From: Tamas Perger Date: Tue, 21 Feb 2023 19:13:07 +0000 Subject: [PATCH 36/48] refactor: introduce ParserConfiguration class hierarchy --- .../org/json/JSONMLParserConfiguration.java | 83 ++----------- .../java/org/json/ParserConfiguration.java | 112 ++++++++++++++++++ .../java/org/json/XMLParserConfiguration.java | 64 ++-------- src/test/java/org/json/junit/JSONMLTest.java | 29 +++++ 4 files changed, 162 insertions(+), 126 deletions(-) create mode 100644 src/main/java/org/json/ParserConfiguration.java diff --git a/src/main/java/org/json/JSONMLParserConfiguration.java b/src/main/java/org/json/JSONMLParserConfiguration.java index b7162bf..b2514ab 100644 --- a/src/main/java/org/json/JSONMLParserConfiguration.java +++ b/src/main/java/org/json/JSONMLParserConfiguration.java @@ -7,17 +7,12 @@ Public Domain. * Configuration object for the XML to JSONML parser. The configuration is immutable. */ @SuppressWarnings({""}) -public class JSONMLParserConfiguration { - /** - * Used to indicate there's no defined limit to the maximum nesting depth when parsing a XML - * document to JSONML. - */ - public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1; +public class JSONMLParserConfiguration extends ParserConfiguration { /** - * The default maximum nesting depth when parsing a XML document to JSONML. + * We can override the default maximum nesting depth if needed. */ - public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512; + public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = ParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH; /** Original Configuration of the XML to JSONML Parser. */ public static final JSONMLParserConfiguration ORIGINAL @@ -26,22 +21,12 @@ public class JSONMLParserConfiguration { public static final JSONMLParserConfiguration KEEP_STRINGS = new JSONMLParserConfiguration().withKeepStrings(true); - /** - * When parsing the XML into JSONML, specifies if values should be kept as strings (true), or if - * they should try to be guessed into JSON values (numeric, boolean, string) - */ - private boolean keepStrings; - - /** - * The maximum nesting depth when parsing a XML document to JSONML. - */ - private int maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH; - /** * Default parser configuration. Does not keep strings (tries to implicitly convert values). */ public JSONMLParserConfiguration() { - this.keepStrings = false; + super(); + this.maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH; } /** @@ -50,9 +35,8 @@ public class JSONMLParserConfiguration { * false to try and convert XML string values into a JSON value. * @param maxNestingDepth int to limit the nesting depth */ - private JSONMLParserConfiguration(final boolean keepStrings, final int maxNestingDepth) { - this.keepStrings = keepStrings; - this.maxNestingDepth = maxNestingDepth; + protected JSONMLParserConfiguration(final boolean keepStrings, final int maxNestingDepth) { + super(keepStrings, maxNestingDepth); } /** @@ -71,58 +55,13 @@ public class JSONMLParserConfiguration { ); } - /** - * When parsing the XML into JSONML, specifies if values should be kept as strings (true), or if - * they should try to be guessed into JSON values (numeric, boolean, string) - * - * @return The keepStrings configuration value. - */ - public boolean isKeepStrings() { - return this.keepStrings; - } - - /** - * When parsing the XML into JSONML, specifies if values should be kept as strings (true), or if - * they should try to be guessed into JSON values (numeric, boolean, string) - * - * @param newVal - * new value to use for the keepStrings configuration option. - * - * @return The existing configuration will not be modified. A new configuration is returned. - */ + @Override public JSONMLParserConfiguration withKeepStrings(final boolean newVal) { - JSONMLParserConfiguration newConfig = this.clone(); - newConfig.keepStrings = newVal; - return newConfig; - } - - /** - * The maximum nesting depth that the parser will descend before throwing an exception - * when parsing the XML into JSONML. - * @return the maximum nesting depth set for this configuration - */ - public int getMaxNestingDepth() { - return maxNestingDepth; + return super.withKeepStrings(newVal); } - /** - * Defines the maximum nesting depth that the parser will descend before throwing an exception - * when parsing the XML into JSONML. The default max nesting depth is 512, which means the parser - * will throw a JsonException if the maximum depth is reached. - * Using any negative value as a parameter is equivalent to setting no limit to the nesting depth, - * which means the parses will go as deep as the maximum call stack size allows. - * @param maxNestingDepth the maximum nesting depth allowed to the XML parser - * @return The existing configuration will not be modified. A new configuration is returned. - */ + @Override public JSONMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) { - JSONMLParserConfiguration newConfig = this.clone(); - - if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) { - newConfig.maxNestingDepth = maxNestingDepth; - } else { - newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH; - } - - return newConfig; + return super.withMaxNestingDepth(maxNestingDepth); } } diff --git a/src/main/java/org/json/ParserConfiguration.java b/src/main/java/org/json/ParserConfiguration.java new file mode 100644 index 0000000..519e209 --- /dev/null +++ b/src/main/java/org/json/ParserConfiguration.java @@ -0,0 +1,112 @@ +package org.json; +/* +Public Domain. +*/ + +/** + * Configuration base object for parsers. The configuration is immutable. + */ +@SuppressWarnings({""}) +public class ParserConfiguration { + /** + * Used to indicate there's no defined limit to the maximum nesting depth when parsing a document. + */ + public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1; + + /** + * The default maximum nesting depth when parsing a document. + */ + public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512; + + /** + * Specifies if values should be kept as strings (true), or if + * they should try to be guessed into JSON values (numeric, boolean, string) + */ + protected boolean keepStrings; + + /** + * The maximum nesting depth when parsing a document. + */ + protected int maxNestingDepth; + + public ParserConfiguration() { + this.keepStrings = false; + this.maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH; + } + + protected ParserConfiguration(final boolean keepStrings, final int maxNestingDepth) { + this.keepStrings = keepStrings; + this.maxNestingDepth = maxNestingDepth; + } + + /** + * Provides a new instance of the same configuration. + */ + @Override + protected ParserConfiguration clone() { + // future modifications to this method should always ensure a "deep" + // clone in the case of collections. i.e. if a Map is added as a configuration + // item, a new map instance should be created and if possible each value in the + // map should be cloned as well. If the values of the map are known to also + // be immutable, then a shallow clone of the map is acceptable. + return new ParserConfiguration( + this.keepStrings, + this.maxNestingDepth + ); + } + + /** + * When parsing the XML into JSONML, specifies if values should be kept as strings (true), or if + * they should try to be guessed into JSON values (numeric, boolean, string) + * + * @return The keepStrings configuration value. + */ + public boolean isKeepStrings() { + return this.keepStrings; + } + + /** + * When parsing the XML into JSONML, specifies if values should be kept as strings (true), or if + * they should try to be guessed into JSON values (numeric, boolean, string) + * + * @param newVal + * new value to use for the keepStrings configuration option. + * + * @return The existing configuration will not be modified. A new configuration is returned. + */ + public T withKeepStrings(final boolean newVal) { + T newConfig = (T)this.clone(); + newConfig.keepStrings = newVal; + return newConfig; + } + + /** + * The maximum nesting depth that the parser will descend before throwing an exception + * when parsing the XML into JSONML. + * @return the maximum nesting depth set for this configuration + */ + public int getMaxNestingDepth() { + return maxNestingDepth; + } + + /** + * Defines the maximum nesting depth that the parser will descend before throwing an exception + * when parsing the XML into JSONML. The default max nesting depth is 512, which means the parser + * will throw a JsonException if the maximum depth is reached. + * Using any negative value as a parameter is equivalent to setting no limit to the nesting depth, + * which means the parses will go as deep as the maximum call stack size allows. + * @param maxNestingDepth the maximum nesting depth allowed to the XML parser + * @return The existing configuration will not be modified. A new configuration is returned. + */ + public T withMaxNestingDepth(int maxNestingDepth) { + T newConfig = (T)this.clone(); + + if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) { + newConfig.maxNestingDepth = maxNestingDepth; + } else { + newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH; + } + + return newConfig; + } +} diff --git a/src/main/java/org/json/XMLParserConfiguration.java b/src/main/java/org/json/XMLParserConfiguration.java index 103023e..566146d 100644 --- a/src/main/java/org/json/XMLParserConfiguration.java +++ b/src/main/java/org/json/XMLParserConfiguration.java @@ -15,17 +15,12 @@ import java.util.Set; * @author AylwardJ */ @SuppressWarnings({""}) -public class XMLParserConfiguration { - /** - * Used to indicate there's no defined limit to the maximum nesting depth when parsing a XML - * document to JSON. - */ - public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1; +public class XMLParserConfiguration extends ParserConfiguration { /** * The default maximum nesting depth when parsing a XML document to JSON. */ - public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512; +// public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512; // We could override /** Original Configuration of the XML Parser. */ public static final XMLParserConfiguration ORIGINAL @@ -34,12 +29,6 @@ public class XMLParserConfiguration { public static final XMLParserConfiguration KEEP_STRINGS = new XMLParserConfiguration().withKeepStrings(true); - /** - * When parsing the XML into JSON, specifies if values should be kept as strings (true), or if - * they should try to be guessed into JSON values (numeric, boolean, string) - */ - private boolean keepStrings; - /** * The name of the key in a JSON Object that indicates a CDATA section. Historically this has * been the value "content" but can be changed. Use null to indicate no CDATA @@ -65,17 +54,12 @@ public class XMLParserConfiguration { */ private Set forceList; - /** - * The maximum nesting depth when parsing a XML document to JSON. - */ - private int maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH; - /** * Default parser configuration. Does not keep strings (tries to implicitly convert * values), and the CDATA Tag Name is "content". */ public XMLParserConfiguration () { - this.keepStrings = false; + super(); this.cDataTagName = "content"; this.convertNilAttributeToNull = false; this.xsiTypeMap = Collections.emptyMap(); @@ -122,7 +106,7 @@ public class XMLParserConfiguration { */ @Deprecated public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName) { - this.keepStrings = keepStrings; + super(keepStrings, DEFAULT_MAXIMUM_NESTING_DEPTH); this.cDataTagName = cDataTagName; this.convertNilAttributeToNull = false; } @@ -141,7 +125,7 @@ public class XMLParserConfiguration { */ @Deprecated public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName, final boolean convertNilAttributeToNull) { - this.keepStrings = keepStrings; + super(keepStrings, DEFAULT_MAXIMUM_NESTING_DEPTH); this.cDataTagName = cDataTagName; this.convertNilAttributeToNull = convertNilAttributeToNull; } @@ -162,12 +146,11 @@ public class XMLParserConfiguration { private XMLParserConfiguration (final boolean keepStrings, final String cDataTagName, final boolean convertNilAttributeToNull, final Map> xsiTypeMap, final Set forceList, final int maxNestingDepth) { - this.keepStrings = keepStrings; + super(keepStrings, maxNestingDepth); this.cDataTagName = cDataTagName; this.convertNilAttributeToNull = convertNilAttributeToNull; this.xsiTypeMap = Collections.unmodifiableMap(xsiTypeMap); this.forceList = Collections.unmodifiableSet(forceList); - this.maxNestingDepth = maxNestingDepth; } /** @@ -190,16 +173,6 @@ public class XMLParserConfiguration { ); } - /** - * When parsing the XML into JSON, specifies if values should be kept as strings (true), or if - * they should try to be guessed into JSON values (numeric, boolean, string) - * - * @return The keepStrings configuration value. - */ - public boolean isKeepStrings() { - return this.keepStrings; - } - /** * When parsing the XML into JSON, specifies if values should be kept as strings (true), or if * they should try to be guessed into JSON values (numeric, boolean, string) @@ -209,10 +182,9 @@ public class XMLParserConfiguration { * * @return The existing configuration will not be modified. A new configuration is returned. */ + @Override public XMLParserConfiguration withKeepStrings(final boolean newVal) { - XMLParserConfiguration newConfig = this.clone(); - newConfig.keepStrings = newVal; - return newConfig; + return super.withKeepStrings(newVal); } /** @@ -318,15 +290,6 @@ public class XMLParserConfiguration { return newConfig; } - /** - * The maximum nesting depth that the parser will descend before throwing an exception - * when parsing the XML into JSON. - * @return the maximum nesting depth set for this configuration - */ - public int getMaxNestingDepth() { - return maxNestingDepth; - } - /** * Defines the maximum nesting depth that the parser will descend before throwing an exception * when parsing the XML into JSON. The default max nesting depth is 512, which means the parser @@ -336,15 +299,8 @@ public class XMLParserConfiguration { * @param maxNestingDepth the maximum nesting depth allowed to the XML parser * @return The existing configuration will not be modified. A new configuration is returned. */ + @Override public XMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) { - XMLParserConfiguration newConfig = this.clone(); - - if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) { - newConfig.maxNestingDepth = maxNestingDepth; - } else { - newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH; - } - - return newConfig; + return super.withMaxNestingDepth(maxNestingDepth); } } diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java index 1514ddd..35c0af2 100644 --- a/src/test/java/org/json/junit/JSONMLTest.java +++ b/src/test/java/org/json/junit/JSONMLTest.java @@ -895,7 +895,36 @@ public class JSONMLTest { } + @Test + public void testToJSONObjectMaxDefaultNestingDepthIsRespected() { + final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", "
"); + try { + JSONML.toJSONObject(wayTooLongMalformedXML, JSONMLParserConfiguration.ORIGINAL); + + fail("Expecting a JSONException"); + } catch (JSONException e) { + assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">", + e.getMessage().startsWith("Maximum nesting depth of " + JSONMLParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH)); + } + } + + @Test + public void testToJSONObjectUnlimitedNestingDepthIsPossible() { + int actualDepth = JSONMLParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH +10; + final String deeperThanDefaultMax = new String(new char[actualDepth]).replace("\0", "") + + "value" + + new String(new char[actualDepth]).replace("\0", ""); + + try { + JSONML.toJSONObject(deeperThanDefaultMax, JSONMLParserConfiguration.ORIGINAL + .withMaxNestingDepth(JSONMLParserConfiguration.UNDEFINED_MAXIMUM_NESTING_DEPTH)); + } catch (JSONException e) { + e.printStackTrace(); + fail("XML document should be parsed beyond the default maximum depth if maxNestingDepth " + + "parameter is set to -1 in JSONMLParserConfiguration"); + } + } @Test -- Gitee From f0a05e6911a6080749ad82df7c39acd5374af706 Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Mon, 27 Feb 2023 07:17:51 -0600 Subject: [PATCH 37/48] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5181b8b..0ecc12b 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ JSON in Java [package org.json] [![Maven Central](https://img.shields.io/maven-central/v/org.json/json.svg)](https://mvnrepository.com/artifact/org.json/json) -**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20220924/json-20220924.jar)** +**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20230227/json-20230227.jar)** # Overview -- Gitee From 0df034c9fd9189d0f9745c2e22803f6d339e534c Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Mon, 27 Feb 2023 07:20:10 -0600 Subject: [PATCH 38/48] Update for release 20230227 --- docs/RELEASES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/RELEASES.md b/docs/RELEASES.md index 3fbab78..166c43a 100644 --- a/docs/RELEASES.md +++ b/docs/RELEASES.md @@ -5,6 +5,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) ~~~ +20230227 Fix for CVE-2022-45688 and recent commits + 20220924 New License - public domain, and some minor updates 20220320 Wrap StackOverflow with JSONException -- Gitee From 47fb49b6a871cd1652870e33e89cbff082bb0ee1 Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Mon, 27 Feb 2023 07:21:11 -0600 Subject: [PATCH 39/48] Update for release 20230227 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4ef85a8..f17e0ab 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.json json - 20220924 + 20230227 bundle JSON in Java -- Gitee From 0d436d92e2d4625ae34572889ea97ca751d8e9c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Farias?= Date: Thu, 2 Mar 2023 16:39:11 +0100 Subject: [PATCH 40/48] Removing commented out code --- src/main/java/org/json/JSONObject.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java index 68d302d..97906b6 100644 --- a/src/main/java/org/json/JSONObject.java +++ b/src/main/java/org/json/JSONObject.java @@ -1290,11 +1290,7 @@ public class JSONObject { if (val == null) { return defaultValue; } - final double doubleValue = val.doubleValue(); - // if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue)) { - // return defaultValue; - // } - return doubleValue; + return val.doubleValue(); } /** -- Gitee From e1eabc9c27f954ce8fe8032f12f92f51c0e7c9eb Mon Sep 17 00:00:00 2001 From: HariBabu t Date: Sat, 4 Mar 2023 23:08:32 +0800 Subject: [PATCH 41/48] JSONTokener implemented java.io.Closeable --- src/main/java/org/json/JSONTokener.java | 16 +++++++++------- .../java/org/json/junit/JSONTokenerTest.java | 12 ++++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java index 8c98c77..4b7d833 100644 --- a/src/main/java/org/json/JSONTokener.java +++ b/src/main/java/org/json/JSONTokener.java @@ -1,11 +1,6 @@ package org.json; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; +import java.io.*; /* Public Domain. @@ -18,7 +13,7 @@ Public Domain. * @author JSON.org * @version 2014-05-03 */ -public class JSONTokener { +public class JSONTokener implements Closeable { /** current read character position on the current line. */ private long character; /** flag to indicate if the end of the input has been found. */ @@ -522,4 +517,11 @@ public class JSONTokener { return " at " + this.index + " [character " + this.character + " line " + this.line + "]"; } + + @Override + public void close() throws IOException { + if(reader!=null){ + reader.close(); + } + } } diff --git a/src/test/java/org/json/junit/JSONTokenerTest.java b/src/test/java/org/json/junit/JSONTokenerTest.java index da716b8..59ca6d8 100644 --- a/src/test/java/org/json/junit/JSONTokenerTest.java +++ b/src/test/java/org/json/junit/JSONTokenerTest.java @@ -313,4 +313,16 @@ public class JSONTokenerTest { assertEquals(0, t2.next()); assertFalse(t2.more()); } + + @Test + public void testAutoClose(){ + Reader reader = new StringReader("some test string"); + try { + JSONTokener tokener = new JSONTokener(reader); + tokener.close(); + tokener.next(); + } catch (Exception exception){ + assertEquals("Stream closed", exception.getMessage()); + } + } } -- Gitee From 7eca507d13c741dcf0fb468565439dcad937e794 Mon Sep 17 00:00:00 2001 From: HariBabu t Date: Tue, 7 Mar 2023 13:58:30 +0800 Subject: [PATCH 42/48] Removed overriding closable interface. --- src/main/java/org/json/JSONTokener.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java index 4b7d833..c180580 100644 --- a/src/main/java/org/json/JSONTokener.java +++ b/src/main/java/org/json/JSONTokener.java @@ -13,7 +13,7 @@ Public Domain. * @author JSON.org * @version 2014-05-03 */ -public class JSONTokener implements Closeable { +public class JSONTokener { /** current read character position on the current line. */ private long character; /** flag to indicate if the end of the input has been found. */ @@ -518,7 +518,6 @@ public class JSONTokener implements Closeable { this.line + "]"; } - @Override public void close() throws IOException { if(reader!=null){ reader.close(); -- Gitee From 48fb5261fec33a806deccf9107843fb90b5c3e2b Mon Sep 17 00:00:00 2001 From: superMaaax Date: Tue, 21 Mar 2023 20:58:32 -0500 Subject: [PATCH 43/48] Fixed Flaky Tests Caused by JSON permutations ###Description Flaky Tests found using NonDex by running the commands - mvn -pl . edu.illinois:nondex-maven-plugin:2.1.1:nondex -Dtest=org.json.junit.XMLTest#testIndentComplicatedJsonObject mvn -pl . edu.illinois:nondex-maven-plugin:2.1.1:nondex -Dtest=org.json.junit.XMLTest#testIndentSimpleJsonArray mvn -pl . edu.illinois:nondex-maven-plugin:2.1.1:nondex -Dtest=org.json.junit.XMLTest#testIndentSimpleJsonObject The logged failure was- [ERROR] Failures: [ERROR] XMLTest.testIndentSimpleJsonObject:1193 expected:<...> <[married>true sonoo 56000 but was:<...> <[name>sonoo 56000 true The issue is the same for all three tests, so here I only show the failure message for the third test (to reduce the length of the error message). ### Investigation The tests fail with a comparison error while comparing an expected JSON String and the result from the value returned from XML.toString(). The toString function of XML makes no guarantees as to the iteration order of the attributes in the object. This makes the test outcome non-deterministic, and the test fails whenever the function returns a mismatch in order of the elements in the JSON String. To fix this, the expected and actual keys should be checked in a more deterministic way so that the assertions do not fail. ### Fix Expected and Actual values can be converted into JSONObject and the similar function can be used to compare these objects. As this function compares the values inside the JSONObjects without needing order, the test becomes deterministic and ensures that the flakiness from the test is removed. The PR does not introduce a breaking change. --- src/test/java/org/json/junit/XMLTest.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 7d22610..aefaa49 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -1111,6 +1111,7 @@ public class XMLTest { "}" ; JSONObject jsonObject = new JSONObject(str); String actualIndentedXmlString = XML.toString(jsonObject, 1); + JSONObject actualJsonObject = XML.toJSONObject(actualIndentedXmlString); String expected = "true\n" + "\n" + " 2022-10-05T00:00:00+03:00\n" + @@ -1170,7 +1171,8 @@ public class XMLTest { " 1664917200\n" + "\n" + "null\n"; - assertEquals(actualIndentedXmlString, expected); + JSONObject expectedJsonObject = XML.toJSONObject(expected); + assertTrue(expectedJsonObject.similar(actualJsonObject)); } @@ -1183,6 +1185,7 @@ public class XMLTest { " }}"; JSONObject jsonObject = new JSONObject(str); String actual = XML.toString(jsonObject, "Test", 2); + JSONObject actualJsonObject = XML.toJSONObject(actual); String expected = "\n" + " \n" + " sonoo\n" + @@ -1190,7 +1193,8 @@ public class XMLTest { " true\n" + " \n" + "\n"; - assertEquals(actual, expected); + JSONObject expectedJsonObject = XML.toJSONObject(expected); + assertTrue(expectedJsonObject.similar(actualJsonObject)); } @Test @@ -1201,6 +1205,7 @@ public class XMLTest { "] "; JSONArray jsonObject = new JSONArray(str); String actual = XML.toString(jsonObject, 2); + JSONObject actualJsonObject = XML.toJSONObject(actual); String expected = "\n" + " Ram\n" + " Ram@gmail.com\n" + @@ -1209,7 +1214,8 @@ public class XMLTest { " Bob\n" + " bob32@gmail.com\n" + "\n"; - assertEquals(actual, expected); + JSONObject expectedJsonObject = XML.toJSONObject(expected); + assertTrue(expectedJsonObject.similar(actualJsonObject)); } -- Gitee From 133c0cc75fa55fae24c9b528f40a31179fe40a41 Mon Sep 17 00:00:00 2001 From: Michael Osipov Date: Wed, 24 May 2023 11:45:25 +0200 Subject: [PATCH 44/48] JSONTokener(InputStream) violates rfc8259#section-8.1 (#739) Always use UTF-8 when an InputStream is passed. This fixes #739. --- src/main/java/org/json/JSONTokener.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java index c180580..5dc8ae8 100644 --- a/src/main/java/org/json/JSONTokener.java +++ b/src/main/java/org/json/JSONTokener.java @@ -1,6 +1,7 @@ package org.json; import java.io.*; +import java.nio.charset.Charset; /* Public Domain. @@ -56,7 +57,7 @@ public class JSONTokener { * @param inputStream The source. */ public JSONTokener(InputStream inputStream) { - this(new InputStreamReader(inputStream)); + this(new InputStreamReader(inputStream, Charset.forName("UTF-8"))); } @@ -120,7 +121,7 @@ public class JSONTokener { /** * Checks if the end of the input has been reached. - * + * * @return true if at the end of the file and we didn't step back */ public boolean end() { @@ -184,7 +185,7 @@ public class JSONTokener { this.previous = (char) c; return this.previous; } - + /** * Get the last character read from the input or '\0' if nothing has been read yet. * @return the last character read from the input. -- Gitee From 084b24cbe7030cc5057effa9e6d269749ddf0beb Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Sun, 18 Jun 2023 12:16:14 -0500 Subject: [PATCH 45/48] Update README.md for 20230618 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ecc12b..e999230 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ JSON in Java [package org.json] [![Maven Central](https://img.shields.io/maven-central/v/org.json/json.svg)](https://mvnrepository.com/artifact/org.json/json) -**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20230227/json-20230227.jar)** +**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20230618/json-20230618.jar)** # Overview -- Gitee From f6e5bfa2db9c91f7a183c1e96d41e1328ee1b638 Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Sun, 18 Jun 2023 12:17:56 -0500 Subject: [PATCH 46/48] Update RELEASES.md for 20230618 --- docs/RELEASES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/RELEASES.md b/docs/RELEASES.md index 166c43a..ae43983 100644 --- a/docs/RELEASES.md +++ b/docs/RELEASES.md @@ -5,6 +5,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) ~~~ +20230618 Final release with Java 1.6 compatibility. Future releases will require Java 1.8 or greater. + 20230227 Fix for CVE-2022-45688 and recent commits 20220924 New License - public domain, and some minor updates -- Gitee From c048b36516a1e35a52498f3350c6d11c10fb6f20 Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Sun, 18 Jun 2023 12:18:36 -0500 Subject: [PATCH 47/48] Update pom.xml for 20230618 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f17e0ab..ba3edbd 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.json json - 20230227 + 20230618 bundle JSON in Java -- Gitee From a963115ac2527dee688f54f7c1150d6f25b887c1 Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Sun, 18 Jun 2023 12:58:32 -0500 Subject: [PATCH 48/48] Update pom.xml for maven deploy Deploy failed on the mac pro with: gpg: signing failed: Inappropriate ioctl for device Somehow I had a different gpg version installed. This change fixed it. --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index ba3edbd..b9e0e60 100644 --- a/pom.xml +++ b/pom.xml @@ -139,6 +139,12 @@ sign + + + --pinentry-mode + loopback + + -- Gitee