diff --git a/README.md b/README.md index 40bcbfdfd..09bc000e6 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,35 @@ -![Json-Java logo](https://github.com/stleary/JSON-java/blob/master/images/JsonJava.png?raw=true) +JSONC in Java [package org.json] +=============================== -image credit: Ismael Pérez Ortiz +# Fork +This fork allows for using comments inside JSON as well as tries to preserve the order of the keys. + +# Usage -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) +Add a repository to pom.xml: -**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20210307/json-20210307.jar)** +```xml + + + stirante-nexus-snapshots + https://nexus.stirante.com/repository/maven-snapshots/ + + +``` + +Add dependency to pom.xml: +```xml + + + org.json + jsonc + v20200429-SNAPSHOT + + +``` # Overview diff --git a/pom.xml b/pom.xml index 643bea532..8334a5270 100644 --- a/pom.xml +++ b/pom.xml @@ -2,11 +2,11 @@ 4.0.0 org.json - json - 20210307 + jsonc + v20210307-SNAPSHOT bundle - JSON in Java + JSONC in Java JSON is a light-weight, language independent, data interchange format. See http://www.JSON.org/ @@ -19,6 +19,8 @@ in Java. Perhaps someday the Java community will standardize on one. Until then, choose carefully. + This version is modified to allow comments. + 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. @@ -31,10 +33,22 @@ 9 + + + + stirante-nexus-releases + https://nexus.stirante.com/repository/maven-releases/ + + + stirante-nexus-snapshots + https://nexus.stirante.com/repository/maven-snapshots/ + + + - https://github.com/douglascrockford/JSON-java.git - scm:git:git://github.com/douglascrockford/JSON-java.git - scm:git:git@github.com:douglascrockford/JSON-java.git + scm:git:git@github.com:stirante/JSONC-java.git + scm:git:git@github.com:stirante/JSONC-java.git + scm:git:git@github.com:stirante/JSONC-java.git @@ -69,6 +83,10 @@ Douglas Crockford douglas@crockford.com + + Piotr Brzozowski + brzozowski.s.piotr@gmail.com + @@ -151,20 +169,6 @@ - - org.apache.maven.plugins - maven-gpg-plugin - 1.5 - - - sign-artifacts - verify - - sign - - - - org.sonatype.plugins nexus-staging-maven-plugin diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java index 97a6df8d2..5fc83f66e 100644 --- a/src/main/java/org/json/JSONObject.java +++ b/src/main/java/org/json/JSONObject.java @@ -36,15 +36,8 @@ of this software and associated documentation files (the "Software"), to deal import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.ResourceBundle; -import java.util.Set; import java.util.regex.Pattern; /** @@ -161,7 +154,7 @@ public String toString() { /** * The map where the JSONObject's properties are kept. */ - private final Map map; + private final LinkedHashMap map; /** * It is sometimes more convenient and less ambiguous to have a @@ -175,13 +168,9 @@ public String toString() { * Construct an empty JSONObject. */ public JSONObject() { - // HashMap is used on purpose to ensure that elements are unordered by - // the specification. - // JSON tends to be a portable transfer format to allows the container - // implementations to rearrange their items for a faster element - // retrieval based on associative access. - // Therefore, an implementation mustn't rely on the order of the item. - this.map = new HashMap(); + // LinkedHashMap is used on purpose to ensure that elements are ordered the same way as they were inserted. + // It's not RFC compliant + this.map = new LinkedHashMap(); } /** @@ -286,9 +275,9 @@ public JSONObject(JSONTokener x) throws JSONException { */ public JSONObject(Map m) { if (m == null) { - this.map = new HashMap(); + this.map = new LinkedHashMap(); } else { - this.map = new HashMap(m.size()); + this.map = new LinkedHashMap(m.size()); for (final Entry e : m.entrySet()) { if(e.getKey() == null) { throw new NullPointerException("Null key."); @@ -457,7 +446,7 @@ public JSONObject(String baseName, Locale locale) throws JSONException { * @param initialCapacity initial capacity of the internal map. */ protected JSONObject(int initialCapacity){ - this.map = new HashMap(initialCapacity); + this.map = new LinkedHashMap(initialCapacity); } /** @@ -539,19 +528,7 @@ public static String doubleToString(double d) { return "null"; } -// Shave off trailing zeros and decimal point, if possible. - - String string = Double.toString(d); - if (string.indexOf('.') > 0 && string.indexOf('e') < 0 - && string.indexOf('E') < 0) { - while (string.endsWith("0")) { - string = string.substring(0, string.length() - 1); - } - if (string.endsWith(".")) { - string = string.substring(0, string.length() - 1); - } - } - return string; + return Double.toString(d); } /** @@ -1019,19 +996,7 @@ public static String numberToString(Number number) throws JSONException { } testValidity(number); - // Shave off trailing zeros and decimal point, if possible. - - String string = number.toString(); - if (string.indexOf('.') > 0 && string.indexOf('e') < 0 - && string.indexOf('E') < 0) { - while (string.endsWith("0")) { - string = string.substring(0, string.length() - 1); - } - if (string.endsWith(".")) { - string = string.substring(0, string.length() - 1); - } - } - return string; + return number.toString(); } /** diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java index e6821de32..e00371f0d 100644 --- a/src/main/java/org/json/JSONTokener.java +++ b/src/main/java/org/json/JSONTokener.java @@ -290,6 +290,19 @@ public String next(int n) throws JSONException { public char nextClean() throws JSONException { for (;;) { char c = this.next(); + if (c == '/') { + c = next(); + if (c == '/') { + nextToEndOfLine(); + back(); + continue; + } + if (c == '*') { + nextToEndOfCommentBlock(); + back(); + continue; + } + } if (c == 0 || c > ' ') { return c; } @@ -297,6 +310,45 @@ public char nextClean() throws JSONException { } + /** + * Scan to the next end of line char. + * @throws JSONException Thrown if there is an error reading the source string. + */ + public void nextToEndOfLine() throws JSONException { + for (;;) { + char c = next(); + + if (c == 0 || c == '\r' || c == '\n') { + next(); + return; + } + } + } + + + /** + * Get the next char in the string, skipping comments. + * @throws JSONException Thrown if there is an error reading the source string. + */ + public void nextToEndOfCommentBlock() throws JSONException { + for (;;) { + char c = next(); + + if (c == 0) { + return; + } + + if (c == '*') { + c = next(); + if (c == '/') { + next(); + return; + } + } + } + } + + /** * Return the characters up to the next close quote character. * Backslash processing is done. The formal JSON format does not diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index 0d5acdd2e..56dae6e75 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -803,7 +803,7 @@ public void jsonObjectAppend() { @SuppressWarnings("boxing") @Test public void jsonObjectDoubleToString() { - String [] expectedStrs = {"1", "1", "-23.4", "-2.345E68", "null", "null" }; + String [] expectedStrs = {"1.0", "1.0", "-23.4", "-2.345E68", "null", "null" }; Double [] doubles = { 1.0, 00001.00000, -23.4, -23.45e67, Double.NaN, Double.NEGATIVE_INFINITY }; for (int i = 0; i < expectedStrs.length; ++i) { @@ -1210,13 +1210,10 @@ public void unexpectedDoubleToIntConversion() { jsonObject.getDouble(key30) == 3); assertTrue("3.1 should remain a double", jsonObject.getDouble(key31) == 3.1); - - // turns 3.0 into 3. + String serializedString = jsonObject.toString(); JSONObject deserialized = new JSONObject(serializedString); - assertTrue("3.0 is now an int", deserialized.get(key30) instanceof Integer); - assertTrue("3.0 can still be interpreted as a double", - deserialized.getDouble(key30) == 3.0); + assertTrue("3.0 remains a double", deserialized.get(key30) instanceof BigDecimal); assertTrue("3.1 remains a double", deserialized.getDouble(key31) == 3.1); } @@ -1691,7 +1688,7 @@ public void jsonObjectNumberToString() { // trailing .0 is truncated, so it doesn't quite match toString() dVal = 5000000.0000000; str = JSONObject.numberToString(dVal); - assertTrue("expected 5000000 actual "+str, str.equals("5000000")); + assertTrue("expected 5000000.0 actual "+str, str.equals("5000000.0")); } /** diff --git a/src/test/java/org/json/junit/JSONTokenerTest.java b/src/test/java/org/json/junit/JSONTokenerTest.java index e8e0f98a9..bce4f0f98 100644 --- a/src/test/java/org/json/junit/JSONTokenerTest.java +++ b/src/test/java/org/json/junit/JSONTokenerTest.java @@ -119,6 +119,8 @@ public void testValid() { checkValid("[1,2]",JSONArray.class); checkValid("\n\n[1,2]\n\n",JSONArray.class); checkValid("1 2", String.class); + checkValid(" {\"a\":1/*test comment*/}",JSONObject.class); + checkValid(" {\"a\":1//test comment\n}",JSONObject.class); } @Test