From fca6c6c9caaae29d2aa325b91de31e522b2b7ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CZiyunYang=E2=80=9D?= Date: Tue, 26 Jan 2021 14:53:42 -0800 Subject: [PATCH 1/4] add two toJSONObject functions in XML.java --- src/main/java/org/json/JSONTokener.java | 2 +- src/main/java/org/json/XML.java | 150 ++++++++++- src/test/java/org/json/junit/SWE262Test.java | 250 +++++++++++++++++++ 3 files changed, 393 insertions(+), 9 deletions(-) create mode 100644 src/test/java/org/json/junit/SWE262Test.java diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java index e6821de32..7f5509438 100644 --- a/src/main/java/org/json/JSONTokener.java +++ b/src/main/java/org/json/JSONTokener.java @@ -50,7 +50,7 @@ public class JSONTokener { /** previous character read from the input. */ private char previous; /** Reader for the input. */ - private final Reader reader; + public final Reader reader; /** flag to indicate that a previous character was requested. */ private boolean usePrevious; /** the number of characters read in the previous line. */ diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java index 805a5c376..99ef40440 100644 --- a/src/main/java/org/json/XML.java +++ b/src/main/java/org/json/XML.java @@ -24,12 +24,15 @@ of this software and associated documentation files (the "Software"), to deal SOFTWARE. */ +import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; +import java.util.Arrays; import java.util.Iterator; +import java.util.Stack; /** @@ -119,7 +122,7 @@ public void remove() { /** * Replace special characters with XML escapes: * - *
{@code 
+     * 
{@code
      * & (ampersand) is replaced by &
      * < (less than) is replaced by &lt;
      * > (greater than) is replaced by &gt;
@@ -484,7 +487,7 @@ public static Object stringToValue(String string) {
         }
         return string;
     }
-    
+
     /**
      * direct copy of {@link JSONObject#stringToNumber(String)} to maintain Android support.
      */
@@ -531,7 +534,7 @@ private static Number stringToNumber(final String val) throws NumberFormatExcept
             // integer representation.
             // This will narrow any values to the smallest reasonable Object representation
             // (Integer, Long, or BigInteger)
-            
+
             // BigInteger down conversion: We use a similar bitLenth compare as
             // BigInteger#intValueExact uses. Increases GC, but objects hold
             // only what they need. i.e. Less runtime overhead if the value is
@@ -547,7 +550,7 @@ private static Number stringToNumber(final String val) throws NumberFormatExcept
         }
         throw new NumberFormatException("val ["+val+"] is not a valid number.");
     }
-    
+
     /**
      * direct copy of {@link JSONObject#isDecimalNotation(String)} to maintain Android support.
      */
@@ -565,7 +568,7 @@ private static boolean isDecimalNotation(final String val) {
      * 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. * @@ -586,7 +589,7 @@ public static JSONObject toJSONObject(String string) throws JSONException { * 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. * @@ -666,7 +669,7 @@ public static JSONObject toJSONObject(Reader reader, XMLParserConfiguration conf * 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. * @@ -692,7 +695,7 @@ public static JSONObject toJSONObject(String string, boolean keepStrings) throws * 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. * @@ -709,6 +712,137 @@ public static JSONObject toJSONObject(String string, XMLParserConfiguration conf return toJSONObject(new StringReader(string), config); } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject. Some information may be lost in this transformation because + * JSON is a data format and XML is a document format. XML uses elements, + * attributes, and content text, while JSON uses unordered collections of + * 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
+     * <[ [ ]]>}
+ * are ignored. + * + * 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. + * + * @param reader The XML source reader + * @param jsonPointer The JSON pointer + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown if there is an errors while parsing the string + * @throws IOException Thrown if there is an errors while parsing the string + */ + public static JSONObject toJSONObject(Reader reader, JSONPointer jsonPointer) throws JSONException, IOException { + JSONObject jo = new JSONObject(); + XMLTokener x = new XMLTokener(reader); + String[] pathArr = jsonPointer.toURIFragment().substring(2).split("/"); + // the index of path array + int pos = 0; + while (x.more()) { + x.reader.mark(1); + x.skipPast("<"); + String key = x.nextToken().toString(); + if (key.equals(pathArr[pos])) { + + if(pos==pathArr.length-1){ + x.reader.reset(); + x.skipPast("<"); + parse(x, jo, null, XMLParserConfiguration.ORIGINAL); + return jo; + } + if(isNumeric(pathArr[pos+1])){ + x.reader.reset(); + int index = Integer.parseInt(pathArr[pos+1]); + for(int i=0; i stack = new Stack(); + x.skipPast("<"); + String newKey = x.nextToken().toString(); + stack.push(newKey); + while(!stack.isEmpty()){ + x.skipPast("<"); + newKey = x.nextToken().toString(); + if(newKey.equals("/")){ + stack.pop(); + }else{ + stack.push(newKey); + } + } + } + pos++; + if(pos==pathArr.length-1){ + x.skipPast("<"); + parse(x, jo, null, XMLParserConfiguration.ORIGINAL); + return jo; + }else{ + pos++; + } + }else{ + pos++; + } + } + } + return jo; + } + + private static boolean isNumeric(String str){ + for(char c : str.toCharArray()){ + if(!(c>='0'&&c<='9')){ + return false; + } + } + return true; + } + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject. Some information may be lost in this transformation because + * JSON is a data format and XML is a document format. XML uses elements, + * attributes, and content text, while JSON uses unordered collections of + * 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
+     * <[ [ ]]>}
+ * are ignored. + * + * 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. + * + * @param reader The XML source reader + * @param jsonPointer The JSON pointer + * @param replacement The new json object to replace the old one + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown if there is an errors while parsing the string + */ + public static JSONObject toJSONObject(Reader reader, JSONPointer jsonPointer, JSONObject replacement)throws JSONException{ + JSONObject jsonObj = toJSONObject(reader); + String[] arr = jsonPointer.toURIFragment().substring(2).split("/"); + if(arr==null||arr.length==0) return jsonObj; + Object cur = jsonObj; + for (int i=0; i\n" + + "\n" + + " \n" + + " Kress, Peter\n" + + " Paradox Lost\n" + + " Science Fiction\n" + + " 6.95\n" + + " 2000-11-02\n" + + " After an inadvertant trip through a Heisenberg\n" + + " Uncertainty Device, James Salway discovers the problems\n" + + " of being quantum.\n" + + " \n" + + " \n" + + " \n" + + " O'Brien, Tim\n" + + " Microsoft .NET: The Programming Bible\n" + + " Computer\n" + + " 36.95\n" + + " 2000-12-09\n" + + " Microsoft's .NET initiative is explored in\n" + + " detail in this deep programmer's reference.\n" + + " \n" + + " \n" + + " \n" + + " O'Brien, Tim\n" + + " MSXML3: A Comprehensive Guide\n" + + " Computer\n" + + " 36.95\n" + + " 2000-12-01\n" + + " The Microsoft MSXML3 parser is covered in\n" + + " detail, with attention to XML DOM interfaces, XSLT processing,\n" + + " SAX and more.\n" + + " \n" + + " \n" + + " \n" + + " Galos, Mike\n" + + " Visual Studio 7: A Comprehensive Guide\n" + + " Computer\n" + + " 49.95\n" + + " 2001-04-16\n" + + " Microsoft Visual Studio 7 is explored in depth,\n" + + " looking at how Visual Basic, Visual C++, C#, and ASP+ are\n" + + " integrated into a comprehensive development\n" + + " environment.\n" + + " \n" + + " \n" + + ""; + + try { + Reader reader = new StringReader(xmlStr); + JSONPointer pointer = new JSONPointer("/catalog/book/2/genre"); + + JSONObject jo = XML.toJSONObject(reader, pointer); + assertEquals("Correct result.","{\"genre\":\"Computer\"}",jo.toString()); + + reader.close(); + } catch (JSONException e) { + System.out.println("Caught a JSON Exception "); + e.printStackTrace(); + } catch (IOException e) { + System.out.println("Caught a IO Exception "); + e.printStackTrace(); + } + } + + + @Test + public void handleReadEmptySub() { + String xmlStr ="\n" + + "\n" + + " \n" + + " Kress, Peter\n" + + " Paradox Lost\n" + + " Science Fiction\n" + + " 6.95\n" + + " 2000-11-02\n" + + " After an inadvertant trip through a Heisenberg\n" + + " Uncertainty Device, James Salway discovers the problems\n" + + " of being quantum.\n" + + " \n" + + " \n" + + ""; + + try { + Reader reader = new StringReader(xmlStr); + JSONPointer pointer = new JSONPointer(""); + JSONObject jo = XML.toJSONObject(reader, pointer); + reader.close(); + } catch (JSONException e) { + System.out.println("Caught a JSON Exception "); + e.printStackTrace(); + } catch (IOException e){ + System.out.println("Caught a IO Exception "); + e.printStackTrace(); + }catch (StringIndexOutOfBoundsException e){ + assertEquals("Expecting an exception message", + "String index out of range: -1", + e.getMessage()); + } + } + + + @Test + public void handleReadWrongSub() { + String xmlStr ="\n" + + "\n" + + " \n" + + " Kress, Peter\n" + + " Paradox Lost\n" + + " Science Fiction\n" + + " 6.95\n" + + " 2000-11-02\n" + + " After an inadvertant trip through a Heisenberg\n" + + " Uncertainty Device, James Salway discovers the problems\n" + + " of being quantum.\n" + + " \n" + + " \n" + + ""; + + try { + Reader reader = new StringReader(xmlStr); + JSONPointer pointer = new JSONPointer("/catalog/book/0/name"); + JSONObject jo = XML.toJSONObject(reader, pointer); + reader.close(); + } catch (JSONException e) { + assertEquals("Expecting an exception message", + "Misshaped element at 465 [character 10 line 15]", + e.getMessage()); + } catch (IOException e){ + System.out.println("Caught a IO Exception "); + e.printStackTrace(); + } + } + + @Test + public void handleReplacement() { + String xmlStr ="\n" + + "\n" + + " \n" + + " Kress, Peter\n" + + " Paradox Lost\n" + + " Science Fiction\n" + + " 6.95\n" + + " 2000-11-02\n" + + " After an inadvertant trip through a Heisenberg\n" + + " Uncertainty Device, James Salway discovers the problems\n" + + " of being quantum.\n" + + " \n" + + " \n" + + " \n" + + " O'Brien, Tim\n" + + " Microsoft .NET: The Programming Bible\n" + + " Computer\n" + + " 36.95\n" + + " 2000-12-09\n" + + " Microsoft's .NET initiative is explored in\n" + + " detail in this deep programmer's reference.\n" + + " \n" + + " \n" + + ""; + + try { + Reader reader = new StringReader(xmlStr); + JSONPointer pointer = new JSONPointer("/catalog/book/1"); + JSONObject newObj = new JSONObject(); + newObj.put("author", "Bredan Gregg"); + newObj.put("price", "100"); + newObj.put("title", "Systems Performance"); + + JSONObject jo = XML.toJSONObject(reader, pointer,newObj); + String newValue = pointer.queryFrom(jo).toString(); + reader.close(); + assertEquals("Correct result","{\"author\":\"Bredan Gregg\",\"price\":\"100\",\"title\":\"Systems Performance\"}", newValue); + } catch (JSONException e) { + System.out.println("Caught a JSON Exception "); + e.printStackTrace(); + } catch (IOException e){ + System.out.println("Caught a IO Exception "); + e.printStackTrace(); + } + } + + @Test + public void handleWrongReplacement() { + String xmlStr ="\n" + + "\n" + + " \n" + + " Kress, Peter\n" + + " Paradox Lost\n" + + " Science Fiction\n" + + " 6.95\n" + + " 2000-11-02\n" + + " After an inadvertant trip through a Heisenberg\n" + + " Uncertainty Device, James Salway discovers the problems\n" + + " of being quantum.\n" + + " \n" + + " \n" + + " \n" + + " O'Brien, Tim\n" + + " Microsoft .NET: The Programming Bible\n" + + " Computer\n" + + " 36.95\n" + + " 2000-12-09\n" + + " Microsoft's .NET initiative is explored in\n" + + " detail in this deep programmer's reference.\n" + + " \n" + + " \n" + + ""; + + try { + Reader reader = new StringReader(xmlStr); + JSONPointer pointer = new JSONPointer("/catalog/name/1"); + JSONObject newObj = new JSONObject(); + newObj.put("author", "Bredan Gregg"); + newObj.put("price", "100"); + newObj.put("title", "Systems Performance"); + + JSONObject jo = XML.toJSONObject(reader, pointer,newObj); + String newValue = pointer.queryFrom(jo).toString(); + reader.close(); + } catch (JSONException e) { + assertEquals("Expecting an exception message", + "JSONObject[\"name\"] not found.", + e.getMessage()); + } catch (IOException e){ + System.out.println("Caught a IO Exception "); + e.printStackTrace(); + } + } +} From 3387653fb4d0de4ca18ea8e648011b84eb62fe0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CZiyunYang=E2=80=9D?= Date: Mon, 8 Feb 2021 15:28:34 -0800 Subject: [PATCH 2/4] add new parse() and toJsonObject() methods to transform token add Milestone_README.md --- Milestone_README.md | 8 + pom.xml | 4 +- src/main/java/org/json/XML.java | 228 +++++++++++++++++++ src/test/java/org/json/junit/SWE262Test.java | 44 ++++ 4 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 Milestone_README.md diff --git a/Milestone_README.md b/Milestone_README.md new file mode 100644 index 000000000..cd2e635c4 --- /dev/null +++ b/Milestone_README.md @@ -0,0 +1,8 @@ +# Notes +Milestone2 +Add two new toJsonObject() methods in src/main/java/org.json/XML.java file to enable users to extract smaller sub-objects and replace it. + +MileStone3 +Add new parse() and toJsonObject() methods in src/main/java/org.json/XML.java file to enable users to transform keys during translate xml file + +Operations to build or test are as same as mentioned in README.md \ No newline at end of file diff --git a/pom.xml b/pom.xml index e5449ba8c..e161b2d46 100644 --- a/pom.xml +++ b/pom.xml @@ -118,8 +118,8 @@ maven-compiler-plugin 2.3.2 - 1.6 - 1.6 + 8 + 8 diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java index 99ef40440..181868e6f 100644 --- a/src/main/java/org/json/XML.java +++ b/src/main/java/org/json/XML.java @@ -33,6 +33,7 @@ of this software and associated documentation files (the "Software"), to deal import java.util.Arrays; import java.util.Iterator; import java.util.Stack; +import java.util.function.Function; /** @@ -435,6 +436,199 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP } } + /** + * Scan the content following the named tag, attaching it to the context. + * + * @param x + * The XMLTokener containing the source string. + * @param context + * The JSONObject that will include the new material. + * @param name + * The tag name. + * @param func + * The Function to transform token. + * @return true if the close tag is processed. + * @throws JSONException + */ + private static boolean parse(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config, Function func) + throws JSONException { + char c; + int i; + JSONObject jsonObject = null; + String string; + String tagName; + Object token; + XMLXsiTypeConverter xmlXsiTypeConverter; + + // Test for and skip past these forms: + // + // + // + // + // Report errors for these forms: + // <> + // <= + // << + + token = x.nextToken(); + + // "); + return false; + } + x.back(); + } else if (c == '[') { + token = x.nextToken(); + if ("CDATA".equals(token)) { + if (x.next() == '[') { + string = x.nextCDATA(); + if (string.length() > 0) { + context.accumulate(config.getcDataTagName(), string); + } + return false; + } + } + throw x.syntaxError("Expected 'CDATA['"); + } + i = 1; + do { + token = x.nextMeta(); + if (token == null) { + throw x.syntaxError("Missing '>' after ' 0); + return false; + } else if (token == QUEST) { + + // "); + return false; + } else if (token == SLASH) { + + // Close tag + if (x.nextToken() != GT) { + throw x.syntaxError("Misshaped tag"); + } + if (nilAttributeFound) { + context.accumulate(tagName, JSONObject.NULL); + } else if (jsonObject.length() > 0) { + context.accumulate(tagName, jsonObject); + } else { + context.accumulate(tagName, ""); + } + return false; + + } else if (token == GT) { + // Content, between <...> and + for (;;) { + token = x.nextContent(); + if (token == null) { + if (tagName != null) { + throw x.syntaxError("Unclosed tag " + tagName); + } + return false; + } else if (token instanceof String) { + string = (String) token; + if (string.length() > 0) { + if(xmlXsiTypeConverter != null) { + jsonObject.accumulate(config.getcDataTagName(), + stringToValue(string, xmlXsiTypeConverter)); + } else { + jsonObject.accumulate(config.getcDataTagName(), + config.isKeepStrings() ? string : stringToValue(string)); + } + } + + } else if (token == LT) { + // Nested element + if (parse(x, jsonObject, tagName, config, func)) { + if (jsonObject.length() == 0) { + context.accumulate(tagName, ""); + } else if (jsonObject.length() == 1 + && jsonObject.opt(config.getcDataTagName()) != null) { + context.accumulate(tagName, jsonObject.opt(config.getcDataTagName())); + } else { + context.accumulate(tagName, jsonObject); + } + return false; + } + } + } + } else { + throw x.syntaxError("Misshaped tag"); + } + } + } + } + /** * This method tries to convert the given string value to the target object * @param string String to convert @@ -661,6 +855,40 @@ public static JSONObject toJSONObject(Reader reader, XMLParserConfiguration conf return jo; } + + /** + * Convert a well-formed (but not necessarily valid) XML into a + * JSONObject. Some information may be lost in this transformation because + * JSON is a data format and XML is a document format. XML uses elements, + * attributes, and content text, while JSON uses unordered collections of + * 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
+     * <[ [ ]]>}
+ * are ignored. + * + * 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. + * + * @param reader The XML source reader. + * @param func The Function to transform the token + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException Thrown if there is an errors while parsing the string + */ + public static JSONObject toJSONObjectTest(Reader reader, Function func) throws JSONException { + JSONObject jo = new JSONObject(); + XMLTokener x = new XMLTokener(reader); + while (x.more()) { + x.skipPast("<"); + if(x.more()) { + parse(x, jo, "", XMLParserConfiguration.ORIGINAL, func); + } + } + return jo; + } + + /** * Convert a well-formed (but not necessarily valid) XML string into a * JSONObject. Some information may be lost in this transformation because diff --git a/src/test/java/org/json/junit/SWE262Test.java b/src/test/java/org/json/junit/SWE262Test.java index 2a1599849..d92d1ffcb 100644 --- a/src/test/java/org/json/junit/SWE262Test.java +++ b/src/test/java/org/json/junit/SWE262Test.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.io.Reader; import java.io.StringReader; +import java.util.function.Function; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -247,4 +248,47 @@ public void handleWrongReplacement() { e.printStackTrace(); } } + + + @Test + public void handleReplaceTag() { + String xmlStr ="\n" + + "\n" + + " \n" + + " Kress, Peter\n" + + " Paradox Lost\n" + + " Science Fiction\n" + + " 6.95\n" + + " 2000-11-02\n" + + " After an inadvertant trip through a Heisenberg\n" + + " Uncertainty Device, James Salway discovers the problems\n" + + " of being quantum.\n" + + " \n" + + " \n" + + " \n" + + " O'Brien, Tim\n" + + " Microsoft .NET: The Programming Bible\n" + + " Computer\n" + + " 36.95\n" + + " 2000-12-09\n" + + " Microsoft's .NET initiative is explored in\n" + + " detail in this deep programmer's reference.\n" + + " \n" + + " \n" + + ""; + + try { + Reader reader = new StringReader(xmlStr); + JSONObject newObj = XML.toJSONObjectTest(reader, s -> "SWE262_" + s); + assertEquals("Correct result.","{\"SWE262_catalog\":{\"SWE262_book\":[{\"SWE262_author\":\"Kress, Peter\",\"SWE262_title\":\"Paradox Lost\",\"SWE262_publish_date\":\"2000-11-02\",\"SWE262_genre\":\"Science Fiction\",\"SWE262_description\":\"After an inadvertant trip through a Heisenberg\\n Uncertainty Device, James Salway discovers the problems\\n of being quantum.\",\"SWE262_id\":\"bk109\",\"SWE262_price\":6.95},{\"SWE262_author\":\"O'Brien, Tim\",\"SWE262_title\":\"Microsoft .NET: The Programming Bible\",\"SWE262_publish_date\":\"2000-12-09\",\"SWE262_genre\":\"Computer\",\"SWE262_description\":\"Microsoft's .NET initiative is explored in\\n detail in this deep programmer's reference.\",\"SWE262_id\":\"bk110\",\"SWE262_price\":36.95}]}}",newObj.toString()); +// System.out.println(newObj.toString()); + reader.close(); + } catch (JSONException e) { + System.out.println("Caught a JSON Exception "); + e.printStackTrace(); + } catch (IOException e){ + System.out.println("Caught a IO Exception "); + e.printStackTrace(); + } + } } From 79b587dcf12b6b6d18f6e778dae9a1b4c203b267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CZiyunYang=E2=80=9D?= Date: Tue, 23 Feb 2021 01:16:56 -0800 Subject: [PATCH 3/4] add the toStream method --- Milestone_README.md | 4 ++ src/main/java/org/json/JSONObject.java | 27 +++++++++++ src/test/java/org/json/junit/StreamTest.java | 51 ++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 src/test/java/org/json/junit/StreamTest.java diff --git a/Milestone_README.md b/Milestone_README.md index cd2e635c4..87c640665 100644 --- a/Milestone_README.md +++ b/Milestone_README.md @@ -5,4 +5,8 @@ Add two new toJsonObject() methods in src/main/java/org.json/XML.java file to en MileStone3 Add new parse() and toJsonObject() methods in src/main/java/org.json/XML.java file to enable users to transform keys during translate xml file +MileStone4 +Add a toStream() method in src/main/java/org.json/JSONObject.java file to transfer the leaf node of a JSONObject to stream + + Operations to build or test are as same as mentioned in README.md \ No newline at end of file diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java index b60344bad..41b3e9eef 100644 --- a/src/main/java/org/json/JSONObject.java +++ b/src/main/java/org/json/JSONObject.java @@ -46,6 +46,7 @@ of this software and associated documentation files (the "Software"), to deal import java.util.ResourceBundle; import java.util.Set; import java.util.regex.Pattern; +import java.util.stream.Stream; /** * A JSONObject is an unordered collection of name/value pairs. Its external @@ -2355,6 +2356,32 @@ public String toString(int indentFactor) throws JSONException { } } + public Stream toStream(){ + Stream.Builder builder = Stream.builder(); + Set> entrySet = this.entrySet(); + for(Entry e:entrySet){ + fillStream(e.getKey(),e.getValue(),builder); + } + Stream stream = builder.build(); + return stream; + } + + private void fillStream(String key, Object o,Stream.Builder builder){ + if(o instanceof JSONObject){ + for(Entry e:((JSONObject) o).map.entrySet()){ + fillStream(e.getKey(),e.getValue(),builder); + } + }else if (o instanceof JSONArray){ + for(int i=0; i<((JSONArray) o).length();i++){ + fillStream(key,((JSONArray) o).get(i),builder); + } + }else { + JSONObject newObj = new JSONObject(); + newObj.put(key,o); + builder.accept(newObj); + } + } + /** * Make a JSON text of an Object value. If the object has an * value.toJSONString() method, then that method will be used to produce the diff --git a/src/test/java/org/json/junit/StreamTest.java b/src/test/java/org/json/junit/StreamTest.java new file mode 100644 index 000000000..6ec70ff61 --- /dev/null +++ b/src/test/java/org/json/junit/StreamTest.java @@ -0,0 +1,51 @@ +package org.json.junit; + +import org.json.JSONObject; +import org.json.XML; +import org.json.XMLParserConfiguration; +import org.junit.Test; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class StreamTest { + @Test + public void streamTest(){ + String xml ="\n" + + "\n" + + " \n" + + " Kress Peter\n" + + " Paradox Lost\n" + + " Science Fiction\n" + + " 6.95\n" + + " 2000-11-02\n" + + " After an inadvertant trip through a Heisenberg\n" + + " Uncertainty Device, James Salway discovers the problems\n" + + " of being quantum.\n" + + " \n" + + " \n" + + " \n" + + " O'Brien, Tim\n" + + " Microsoft .NET: The Programming Bible\n" + + " Computer\n" + + " 36.95\n" + + " 2000-12-09\n" + + " Microsoft's .NET initiative is explored in\n" + + " detail in this deep programmer's reference.\n" + + " \n" + + " \n" + + ""; + JSONObject jsonObject = + XML.toJSONObject(xml); + Stream stream = jsonObject.toStream(); + int i=0; + List list = stream.collect(Collectors.toList()); + assertEquals("{\"author\":\"Kress Peter\"}",list.get(0).toString()); + } +} From b4df3308d41289781cba75463e6628ac66c6d4c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CZiyunYang=E2=80=9D?= Date: Tue, 9 Mar 2021 21:54:13 -0800 Subject: [PATCH 4/4] add a asynchronous toJSONObject method --- Milestone_README.md | 3 ++ src/main/java/org/json/XML.java | 21 ++++++++++ src/test/java/org/json/junit/SWE262Test.java | 2 + src/test/java/org/json/junit/XMLTest.java | 44 ++++++++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/Milestone_README.md b/Milestone_README.md index 87c640665..f7fd74f12 100644 --- a/Milestone_README.md +++ b/Milestone_README.md @@ -8,5 +8,8 @@ Add new parse() and toJsonObject() methods in src/main/java/org.json/XML.java fi MileStone4 Add a toStream() method in src/main/java/org.json/JSONObject.java file to transfer the leaf node of a JSONObject to stream +MileStone5 +Add new toJsonObject() method in src/main/java/org.json/XML.java file to asynchronously translate big xml file to JSON object. The parameter should be Reader, the method will return a Future. + Operations to build or test are as same as mentioned in README.md \ No newline at end of file diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java index 181868e6f..8038d6eee 100644 --- a/src/main/java/org/json/XML.java +++ b/src/main/java/org/json/XML.java @@ -33,6 +33,10 @@ of this software and associated documentation files (the "Software"), to deal import java.util.Arrays; import java.util.Iterator; import java.util.Stack; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.function.Function; @@ -941,6 +945,23 @@ public static JSONObject toJSONObject(String string, XMLParserConfiguration conf } + public static class Task implements Callable { + Reader reader; + public Task(Reader reader){ + this.reader = reader; + } + @Override + public JSONObject call() throws Exception { + return toJSONObject(reader); + } + } + public static Future toJSONObjectM5(Reader reader){ + ExecutorService es = Executors.newCachedThreadPool(); + Future future = es.submit(new Task(reader)); + es.shutdown(); + return future; + } + /** * Convert a well-formed (but not necessarily valid) XML string into a diff --git a/src/test/java/org/json/junit/SWE262Test.java b/src/test/java/org/json/junit/SWE262Test.java index d92d1ffcb..860bc4df5 100644 --- a/src/test/java/org/json/junit/SWE262Test.java +++ b/src/test/java/org/json/junit/SWE262Test.java @@ -291,4 +291,6 @@ public void handleReplaceTag() { e.printStackTrace(); } } + + } diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 62ee516b2..d837cbb70 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -40,6 +40,8 @@ of this software and associated documentation files (the "Software"), to deal import java.io.StringReader; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import org.json.JSONArray; import org.json.JSONException; @@ -1068,4 +1070,46 @@ public void testXSITypeMapNotModifiable() { fail("Expected to be unable to modify the config"); } catch (Exception ignored) { } } + + @Test + public void testAsyncToJson(){ + String xml ="\n" + + "\n" + + " \n" + + " Kress Peter\n" + + " Paradox Lost\n" + + " Science Fiction\n" + + " 6.95\n" + + " 2000-11-02\n" + + " After an inadvertant trip through a Heisenberg\n" + + " Uncertainty Device, James Salway discovers the problems\n" + + " of being quantum.\n" + + " \n" + + " \n" + + " \n" + + " O'Brien, Tim\n" + + " Microsoft .NET: The Programming Bible\n" + + " Computer\n" + + " 36.95\n" + + " 2000-12-09\n" + + " Microsoft's .NET initiative is explored in\n" + + " detail in this deep programmer's reference.\n" + + " \n" + + " \n" + + ""; + JSONObject expectedJsonObject = new JSONObject(); + Reader reader = new StringReader(xml); + Future future = XML.toJSONObjectM5(reader); + JSONObject obj = null; + try{ + obj = future.get(); + }catch (InterruptedException e) { + System.out.println("meet interrupted exception"); + e.printStackTrace(); + } catch (ExecutionException e) { + System.out.println("meet execution exception"); + e.printStackTrace(); + } + assertEquals(obj.toString(),"{\"catalog\":{\"book\":[{\"author\":\"Kress Peter\",\"price\":6.95,\"genre\":\"Science Fiction\",\"description\":\"After an inadvertant trip through a Heisenberg\\n Uncertainty Device, James Salway discovers the problems\\n of being quantum.\",\"id\":\"bk109\",\"title\":\"Paradox Lost\",\"publish_date\":\"2000-11-02\"},{\"author\":\"O'Brien, Tim\",\"price\":36.95,\"genre\":\"Computer\",\"description\":\"Microsoft's .NET initiative is explored in\\n detail in this deep programmer's reference.\",\"id\":\"bk110\",\"title\":\"Microsoft .NET: The Programming Bible\",\"publish_date\":\"2000-12-09\"}]}}"); + } }