diff --git a/MILESTONE3-README.md b/MILESTONE3-README.md
new file mode 100644
index 000000000..2f3c499b5
--- /dev/null
+++ b/MILESTONE3-README.md
@@ -0,0 +1,12 @@
+**Performance Implications of doing this inside the
+library vs. doing it in client code:**
+
+Performing a transformation on all the keys of the resulting JSON object is
+much more efficient when done inside the library for two reasons:
+1. You can modify the key as you're reading the XML file and generating the
+JSON object versus generating the entire JSON Object first and then going back
+to parse the entire structure again and updating the keys.
+
+2. You can provide your own custom transformations which can be
+handled dynamically thanks to the functional interface built into
+Java 8.
\ 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 805a5c376..cc52dd50e 100644
--- a/src/main/java/org/json/XML.java
+++ b/src/main/java/org/json/XML.java
@@ -29,7 +29,10 @@ of this software and associated documentation files (the "Software"), to deal
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.util.Iterator;
+import java.util.*;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Stream;
/**
@@ -40,7 +43,7 @@ of this software and associated documentation files (the "Software"), to deal
* @version 2016-08-10
*/
@SuppressWarnings("boxing")
-public class XML {
+public class XML{
/** The Character '&'. */
public static final Character AMP = '&';
@@ -709,6 +712,396 @@ public static JSONObject toJSONObject(String string, XMLParserConfiguration conf
return toJSONObject(new StringReader(string), config);
}
+ //[RJ ADDED] Overloaded static method
+ public static JSONObject toJSONObject(Reader reader, JSONPointer path)
+ {
+ //Need substring to take out first / so can use split successfully.
+ String[] pathArray = path.toString().substring(1).split("[\\\\/]", -1);
+ int pathSize = pathArray.length;
+
+
+ JSONObject jo = new JSONObject();
+ XMLParserConfiguration config = new XMLParserConfiguration();
+ XMLTokener x = new XMLTokener(reader);
+
+ //Find the last non-numerical tag in pathArray
+ int containsNumber = 0; //index of array where number is
+ for(int i = 0; i < pathSize; i ++)
+ {
+ if(pathArray[i].matches("-?\\d+(\\.\\d+)?"))
+ {
+ containsNumber = i;
+ }
+ }
+
+ System.out.println("Contains number: " + containsNumber);
+
+ String parseTag;// = (containsNumber == 0) ? pathArray[pathSize - 1] : pathArray[containsNumber - 1];
+ if(containsNumber == 0)
+ {
+ parseTag = pathArray[pathSize -1];
+ }
+ else
+ {
+ if(pathSize < 2)
+ {
+ parseTag = pathArray[0];
+ }
+ else
+ {
+ parseTag = pathArray[containsNumber - 1];
+ }
+ }
+ String remArr = "";
+
+ //Need to get the new string array that can use JSONPointer to solve
+ if(containsNumber != 0)
+ {
+ for(int z = containsNumber-1; z < pathSize; z ++)
+ remArr += "/" + pathArray[z];
+ }
+
+ System.out.println("remArr: " + remArr);
+ System.out.println("Parse Tag: " + parseTag);
+
+ //rebuild the sub xml
+ String rebuildXML = "";
+ boolean cycle = false;
+
+ boolean exitLoop = false;
+
+ String currTag ="";
+
+ String startString = "<" + parseTag;
+ String exitString = "" + parseTag;
+
+ while (x.more()) {
+ x.skipPast("<");
+ currTag = "<" + x.nextContent();
+ //System.out.println(currTag);
+
+ //Start recording after start string reached.
+ if(currTag.contains(startString)) {
+ cycle = true;
+ //Needed in case XML has array structure
+ //e.g. ......
+ exitLoop = false; //Needed incase JSON has array structure.
+ }
+
+ if(cycle)
+ {
+ if(exitLoop)
+ break;
+
+ rebuildXML += currTag;
+ //System.out.println("Pre If: " + currTag);
+ }
+
+ //Start recording after start string reached.
+ if(currTag.contains(exitString))
+ {
+ exitLoop = true;
+ if(containsNumber != 0)
+ cycle = false;
+ else
+ cycle = true;
+ }
+ }
+
+ //System.out.println(rebuildXML);
+ JSONObject query = XML.toJSONObject(rebuildXML);
+ //System.out.println(query.toString());
+
+ if(containsNumber != 0)
+ {
+ Object jsquery = query.query(remArr);
+ //System.out.println(jsquery);
+ if(jsquery instanceof String)
+ query = new JSONObject().put(pathArray[pathSize - 1], jsquery);
+ else if(jsquery instanceof BigDecimal)
+ query = new JSONObject().put(pathArray[pathSize - 1], jsquery.toString());
+ else
+ query = (JSONObject) jsquery;
+ }
+
+ //System.out.println("PrintingJSON");
+
+ return query;
+
+ }
+
+ public static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
+ {
+ //Logic
+ //Get the JSONObject (or XML) up to a certain nonnumerical path - done
+ //Concert the replacement to a JSONObject
+ //Merge the tw
+
+ if(path.toString().equals("/"))
+ {
+ return XML.toJSONObject(XML.toString(replacement));
+ }
+
+ //Need substring to take out first / so can use split successfully.
+ String[] pathArray = path.toString().substring(1).split("[\\\\/]", -1);
+ int pathSize = pathArray.length;
+
+ String replacementXML = toString(replacement);
+
+ JSONObject jo = new JSONObject();
+ XMLParserConfiguration config = new XMLParserConfiguration();
+ XMLTokener x = new XMLTokener(reader);
+
+ //Find the last non-numerical tag in pathArray
+ int containsNumber = 0; //index of array where number is
+ for(int i = 0; i < pathSize; i ++)
+ {
+ if(pathArray[i].matches("-?\\d+(\\.\\d+)?"))
+ {
+ containsNumber = i;
+ }
+ }
+
+ System.out.println("Contains number: " + containsNumber);
+
+ String parseTag;// = (containsNumber == 0) ? pathArray[pathSize - 1] : pathArray[containsNumber - 1];
+ if(containsNumber == 0)
+ {
+ parseTag = pathArray[pathSize -1];
+ }
+ else
+ {
+ if(pathSize < 2)
+ {
+ parseTag = pathArray[0];
+ }
+ else
+ {
+ parseTag = pathArray[containsNumber - 1];
+ }
+ }
+ String remArr = "";
+
+ //Need to get the new string array that can use JSONPointer to solve
+ if(containsNumber != 0)
+ {
+ for(int z = containsNumber-1; z < pathSize; z ++)
+ remArr += "/" + pathArray[z];
+ }
+
+ System.out.println("remArr: " + remArr);
+ System.out.println("Parse Tag: " + parseTag);
+
+ //rebuild the sub xml
+ String rebuildXML = "";
+ boolean cycle = true;
+
+ //boolean replacementPast = false;
+ boolean firstPass = false;
+ boolean replaceEverything = false;
+ String currTag ="";
+
+ String startString = "<" + parseTag;
+ String exitString = "" + parseTag;
+
+
+ //If something like / or /catalog, then return everything.
+ if(pathSize < 2)
+ replaceEverything = true;
+
+ //This is where we rebuild the XML
+ while (x.more()) {
+ x.skipPast("<");
+ currTag = "<" + x.nextContent();
+ //System.out.println(currTag);
+
+
+ if (replaceEverything){
+ rebuildXML = startString + ">" + replacementXML + exitString + ">";
+ break;
+ }
+ //Stop recording after start string reached.
+ if(currTag.contains(startString))
+ cycle = false;
+
+
+ if(cycle)
+ {
+ if(firstPass)
+ {
+ // add the replacement string
+ rebuildXML += replacementXML;
+
+ //turn it off
+ firstPass = false;
+ }
+
+ rebuildXML += currTag;
+ //System.out.println("Pre If: " + currTag);
+ }
+
+ //Start recording after the LAST non-numerical path string is reached.
+ if(currTag.contains(exitString))
+ {
+ // if(containsNumber != 0)
+ cycle = true;
+
+ //Mark that we have been through one iteration of the parse tag
+ //Marking in case we need more in a JSON Array situation.
+ firstPass = true;
+ //else
+ // break;
+ }
+ }
+
+ System.out.println(rebuildXML);
+ JSONObject query = XML.toJSONObject(rebuildXML);
+ System.out.println(query.toString());
+
+ if(containsNumber != 0)
+ {
+ Object jsquery = query.query(remArr);
+ //System.out.println(jsquery);
+ query = (JSONObject) jsquery;
+ }
+
+ //System.out.println("PrintingJSON");
+
+ return query;
+ }
+
+ //[RJ_ADDED] This overloaded static method replces all keys with output
+ //of keyTransformer output.
+ public static JSONObject toJSONObject(Reader reader, Function keyTransformer)
+ {
+ XMLTokener x = new XMLTokener(reader);
+
+ //rebuild the sub xml
+ String rebuildXML = "";
+
+ String currTag ="";
+
+ while (x.more()) {
+ x.skipPast("<");
+ currTag = "<" + x.nextContent();
+
+ //Current tag holds the tag <> with possible info afterwards.
+ //1. Extract the first word after opening tag openTag = ",0);
+ //Get the first word after < in the tag
+ tag = tag[0].split(" ",0);
+
+ //Handle close toStream(JSONObject obj)
+ {
+ /***Takes an already established JSON Object and converts it into
+ an XML object: **/
+ String jsonXML = XML.toString(obj);
+
+ //Now we can play with our XML
+ // a type of collections so that the Streams can act upon it.
+ /*************************************************************/
+ XMLTokener x = new XMLTokener(jsonXML);
+
+ //rebuild the sub xml
+ String rebuildXML = "";
+
+ String currTag ="";
+
+ ArrayList listOfTags = new ArrayList<>();
+
+ while (x.more()) {
+ x.skipPast("<");
+ currTag = "<" + x.nextContent();
+ //System.out.println(currTag);
+ //Current tag holds the tag <> with possible info afterwards.
+ //1. Extract the first word after opening tag openTag = command, Consumer errorHandler)
+ {
+
+ //"Thread run method" - Apply the User-Given function.
+ Runnable runnable = () -> {
+ try{
+ JSONObject myJSON = toJSONObject(r);
+ command.apply(myJSON);
+ }
+ catch(Exception e)
+ {
+ errorHandler.accept(e);
+ }
+
+ };
+
+ //"Creating Thread"
+ Thread thread = new Thread(runnable);
+
+ //"Starting Thread"
+ thread.start();
+ }
+
/**
* Convert a JSONObject into a well-formed, element-normal XML string.
*
diff --git a/src/test/java/org/json/junit/XMLTest_SWE262.java b/src/test/java/org/json/junit/XMLTest_SWE262.java
new file mode 100644
index 000000000..3c1c34d83
--- /dev/null
+++ b/src/test/java/org/json/junit/XMLTest_SWE262.java
@@ -0,0 +1,472 @@
+package org.json.junit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import org.json.*;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class XMLTest_SWE262 {
+ /**
+ * JUnit supports temporary files and folders that are cleaned up after the test.
+ * https://garygregory.wordpress.com/2010/01/20/junit-tip-use-rules-to-manage-temporary-files-and-folders/
+ */
+ @Rule
+ public TemporaryFolder testFolder = new TemporaryFolder();
+
+
+ /**
+ * Empty JSONObject from a non-XML string.
+ */
+ @Test
+ public void testMethodOne_singleValue() {
+
+ System.out.println("Rahul Hello World");
+
+ String expectedStr =
+ "{\"author\":\"Gambardella, Matthew\"}";
+ String actualStr = "";
+
+ try {
+ FileReader filereader = new FileReader("src/test/resources/Catalog.xml");
+ JSONObject jo = XML.toJSONObject(filereader, new JSONPointer("/catalog/book/0/author"));
+
+ actualStr = jo.toString();
+
+ System.out.println("Actual: " + actualStr);
+ System.out.println("Expected: " + expectedStr);
+ assertEquals(expectedStr, actualStr);
+
+ } catch (FileNotFoundException e) {
+ System.out.println("File not found");
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Empty JSONObject from a non-XML string.
+ */
+ @Test
+ public void testMethodOne_outerTag() {
+
+ System.out.println("Rahul Hello World");
+
+ String expectedStr =
+ " Ralls, Kim\n"+
+ " Midnight Rain\n"+
+ " Fantasy\n"+
+ " 5.95\n"+
+ " 2000-12-16\n"+
+ " A former architect battles corporate zombies, " +
+ "an evil sorceress, and her own childhood to become queen " +
+ "of the world.\n" +
+ " bk102\n";
+
+ expectedStr = XML.toJSONObject(expectedStr).toString();
+ //expectedStr = expectedStr.replaceAll("\\n", "");
+ String actualStr = "";
+
+ try {
+ //FileReader filereader = new FileReader("src/test/resources/file.xml");
+ //JSONObject jo = XML.toJSONObject(filereader, new JSONPointer("/clinical_study/sponsors/lead_sponsor/agency_class"));
+ FileReader filereader = new FileReader("src/test/resources/Catalog.xml");
+ JSONObject jo = XML.toJSONObject(filereader, new JSONPointer("/catalog/book/1"));
+
+ actualStr = jo.toString();
+ //actualStr = actualStr.replaceAll((\\r\\n|\\n|\\r), "");
+
+ System.out.println("Actual: " + actualStr);
+ System.out.println("Expected: " + expectedStr);
+ assertEquals(expectedStr, actualStr);
+
+ } catch (FileNotFoundException e) {
+ System.out.println("File not found");
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testMethodTwo_replaceTag()
+ {
+ System.out.println("\nIn Test Method 2");
+ String expectedStr = "{\"catalog\":{\"tname\":\"rahul jain\"}}";
+
+ try {
+ FileReader filereader = new FileReader("src/test/resources/Catalog.xml");
+ JSONObject jo = XML.toJSONObject(filereader, new JSONPointer("/catalog/book"), XML.toJSONObject("rahul jain"));
+
+ String actualStr = jo.toString();
+ assertEquals(expectedStr, actualStr);
+
+ } catch (FileNotFoundException e) {
+ System.out.println("File not found");
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testMethodTwo_replaceAll()
+ {
+ System.out.println("\nIn Test Method 2");
+ String expectedStr = "{\"tname\":\"rahul jain\"}";
+
+ try {
+ FileReader filereader = new FileReader("src/test/resources/Catalog.xml");
+ JSONObject jo = XML.toJSONObject(filereader, new JSONPointer("/"), XML.toJSONObject("rahul jain"));
+
+ String actualStr = jo.toString();
+ assertEquals(expectedStr, actualStr);
+
+ } catch (FileNotFoundException e) {
+ System.out.println("File not found");
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testMethodThree_replaceKey()
+ {
+ System.out.println("\nIn Test Method three");
+ String expectedStr = "\n" +
+ "\n" +
+ " \n" +
+ " Gambardella, Matthew\n" +
+ " XML Developer's Guide\n" +
+ " Computer\n" +
+ " 44.95\n" +
+ " 2000-10-01\n" +
+ " An in-depth look at creating applications\n" +
+ " with XML.\n" +
+ " \n" +
+ " \n" +
+ " Ralls, Kim\n" +
+ " Midnight Rain\n" +
+ " Fantasy\n" +
+ " 5.95\n" +
+ " 2000-12-16\n" +
+ " A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.\n" +
+ " \n" +
+ " \n" +
+ " Corets, Eva\n" +
+ " Maeve Ascendant\n" +
+ " Fantasy\n" +
+ " 5.95\n" +
+ " 2000-11-17\n" +
+ " After the collapse of a nanotechnology\n" +
+ " society in England, the young survivors lay the\n" +
+ " foundation for a new society.\n" +
+ " \n" +
+ " \n" +
+ " Corets, Eva\n" +
+ " Oberon's Legacy\n" +
+ " Fantasy\n" +
+ " 5.95\n" +
+ " 2001-03-10\n" +
+ " In post-apocalypse England, the mysterious\n" +
+ " agent known only as Oberon helps to create a new life\n" +
+ " for the inhabitants of London. Sequel to Maeve\n" +
+ " Ascendant.\n" +
+ " \n" +
+ " \n" +
+ " Corets, Eva\n" +
+ " The Sundered Grail\n" +
+ " Fantasy\n" +
+ " 5.95\n" +
+ " 2001-09-10\n" +
+ " The two daughters of Maeve, half-sisters,\n" +
+ " battle one another for control of England. Sequel to\n" +
+ " Oberon's Legacy.\n" +
+ " \n" +
+ " \n" +
+ " Randall, Cynthia\n" +
+ " Lover Birds\n" +
+ " Romance\n" +
+ " 4.95\n" +
+ " 2000-09-02\n" +
+ " When Carla meets Paul at an ornithology\n" +
+ " conference, tempers fly as feathers get ruffled.\n" +
+ " \n" +
+ " \n" +
+ " Thurman, Paula\n" +
+ " Splish Splash\n" +
+ " Romance\n" +
+ " 4.95\n" +
+ " 2000-11-02\n" +
+ " A deep sea diver finds true love twenty\n" +
+ " thousand leagues beneath the sea.\n" +
+ " \n" +
+ " \n" +
+ " Knorr, Stefan\n" +
+ " Creepy Crawlies\n" +
+ " Horror\n" +
+ " 4.95\n" +
+ " 2000-12-06\n" +
+ " An anthology of horror stories about roaches,\n" +
+ " centipedes, scorpions and other insects.\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" +
+ " 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" +
+ " 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" +
+ " 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" +
+ "";
+
+ expectedStr = XML.toJSONObject(expectedStr).toString();
+ try {
+ //Define the function
+ Function keyTransformer= (x) -> ("RJ_"+x);
+ FileReader filereader = new FileReader("src/test/resources/Catalog.xml");
+ JSONObject jo = XML.toJSONObject(filereader, keyTransformer);
+
+ System.out.println(XML.toString(jo));
+ XML.toStream(jo);
+
+ String actualStr = jo.toString();
+ //System.out.println(actualStr);
+ assertEquals(expectedStr, actualStr);
+
+ } catch (FileNotFoundException e) {
+ System.out.println("File not found");
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testReplaceKey2()
+ {
+ String expectedStr = "\n" +
+ "\n" +
+ " rajihul@gmail.com\n" +
+ "";
+ expectedStr = XML.toJSONObject(expectedStr).toString();
+
+ try {
+ //Define the function
+ Function keyTransformer= (x) -> ("SWE262_"+x);
+ FileReader filereader = new FileReader("src/test/resources/TransformerTest.xml");
+ JSONObject jo = XML.toJSONObject(filereader, keyTransformer);
+
+ String actualStr = jo.toString();
+ //System.out.println(actualStr);
+ assertEquals(expectedStr, actualStr);
+
+ } catch (FileNotFoundException e) {
+ System.out.println("File not found");
+ e.printStackTrace();
+ }
+
+ }
+
+ @Test
+ public void testStream()
+ {
+ String expectedStr = "rajihul@gmail.com";
+
+ String Str = "\n" +
+ "\n" +
+ " rajihul@gmail.com\n" +
+ "";
+
+ //expectedStr = XML.toJSONObject(expectedStr).toString();
+ String actualStr = "";
+
+ try {
+ //Define the function
+ //Function keyTransformer= (x) -> ("SWE262_"+x);
+ FileReader filereader = new FileReader("src/test/resources/TransformerTest.xml");
+ JSONObject jo = XML.toJSONObject(Str);
+
+ List trstr = XML.toStream(jo)
+ // .forEach(x -> x.replace("SWE262","RJ"))
+ .filter(x->x.contains("SWE262_email"))
+ .collect(Collectors.toList());
+
+ for(String i:trstr)
+ actualStr += i;
+
+ //System.out.println(actualStr);
+ //System.out.println(actualStr);
+ assertEquals(expectedStr, actualStr);
+
+ } catch (FileNotFoundException e) {
+ System.out.println("File not found");
+ e.printStackTrace();
+ }
+ }
+ @Test
+ public void testStream2()
+ {
+ String expectedStr = "";
+
+ String Str = "\n" +
+ "\n" +
+ " rajihul@gmail.com\n" +
+ "";
+
+ //expectedStr = XML.toJSONObject(expectedStr).toString();
+ String actualStr = "";
+
+ try {
+ //Define the function
+ //Function keyTransformer= (x) -> ("SWE262_"+x);
+ FileReader filereader = new FileReader("src/test/resources/TransformerTest.xml");
+ JSONObject jo = XML.toJSONObject(Str);
+
+ List trstr = XML.toStream(jo)
+ // .forEach(x -> x.replace("SWE262","RJ"))
+ .filter(x->!x.contains("SWE262_email"))
+ .collect(Collectors.toList());
+
+ for(String i:trstr)
+ actualStr += i;
+
+ System.out.println(actualStr);
+ //System.out.println(actualStr);
+ assertEquals(expectedStr, actualStr);
+
+ } catch (FileNotFoundException e) {
+ System.out.println("File not found");
+ e.printStackTrace();
+ }
+ }
+
+ /** For Milestone 5 **/
+ @Test
+ public void async()
+ {
+ String expectedStr = "";
+ //Generate output.txt
+ try
+ {
+ FileReader filereader = new FileReader("src/test/resources/Catalog.xml");
+ FileWriter filewriter = new FileWriter("output.json");
+ XML.toJSONObject(filereader, (JSONObject joo) -> joo.write(filewriter), (Exception e)-> e.printStackTrace());
+ //XML.toJSONObject();
+ expectedStr = XML.toJSONObject(filereader).toString();
+
+
+ //Give thread adequate time to finish
+ try{
+ Thread.sleep(1000);
+
+ }catch(InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+
+ //filewriter.flush();
+ filewriter.close();
+ }catch(IOException e)
+ {
+ e.printStackTrace();
+ }
+
+ //Compare the output.txt to the Catalog.xml JSON
+ try
+ {
+ FileReader filereader = new FileReader("output.json");
+ JSONObject actualJSON = XML.toJSONObject(filereader);
+ assertEquals(expectedStr, actualJSON.toString());
+
+ }catch(IOException e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+
+ /** For Milestone 5 **/
+ @Test
+ public void async_exception()
+ {
+ String expectedStr = "";
+ //Generate output.txt
+ try
+ {
+ //The baddata file doens't have closing tag so should throw exception
+ FileReader filereader = new FileReader("src/test/resources/baddata.xml");
+ FileWriter filewriter = new FileWriter("output.json");
+ XML.toJSONObject(filereader, (JSONObject joo) -> joo.write(filewriter), (Exception e)-> System.out.println("Something went wrong!"));
+ //XML.toJSONObject();
+ expectedStr = XML.toJSONObject(filereader).toString();
+
+
+ //Give thread adequate time to finish
+ try{
+ Thread.sleep(1000);
+
+ }catch(InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+
+ //filewriter.flush();
+ filewriter.close();
+ }catch(IOException e)
+ {
+ e.printStackTrace();
+ }
+
+ //Compare the output.txt to the Catalog.xml JSON
+ try
+ {
+ FileReader filereader = new FileReader("output.json");
+ JSONObject actualJSON = XML.toJSONObject(filereader);
+ assertEquals(expectedStr, actualJSON.toString());
+
+ }catch(IOException e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+
+}
diff --git a/src/test/resources/Catalog.xml b/src/test/resources/Catalog.xml
new file mode 100644
index 000000000..96fb8546f
--- /dev/null
+++ b/src/test/resources/Catalog.xml
@@ -0,0 +1,118 @@
+
+
+
+ Gambardella, Matthew
+ XML Developer's Guide
+ Computer
+ 44.95
+ 2000-10-01
+ An in-depth look at creating applications
+ with XML.
+
+
+ Ralls, Kim
+ Midnight Rain
+ Fantasy
+ 5.95
+ 2000-12-16
+ A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.
+
+
+ Corets, Eva
+ Maeve Ascendant
+ Fantasy
+ 5.95
+ 2000-11-17
+ After the collapse of a nanotechnology
+ society in England, the young survivors lay the
+ foundation for a new society.
+
+
+ Corets, Eva
+ Oberon's Legacy
+ Fantasy
+ 5.95
+ 2001-03-10
+ In post-apocalypse England, the mysterious
+ agent known only as Oberon helps to create a new life
+ for the inhabitants of London. Sequel to Maeve
+ Ascendant.
+
+
+ Corets, Eva
+ The Sundered Grail
+ Fantasy
+ 5.95
+ 2001-09-10
+ The two daughters of Maeve, half-sisters,
+ battle one another for control of England. Sequel to
+ Oberon's Legacy.
+
+
+ Randall, Cynthia
+ Lover Birds
+ Romance
+ 4.95
+ 2000-09-02
+ When Carla meets Paul at an ornithology
+ conference, tempers fly as feathers get ruffled.
+
+
+ Thurman, Paula
+ Splish Splash
+ Romance
+ 4.95
+ 2000-11-02
+ A deep sea diver finds true love twenty
+ thousand leagues beneath the sea.
+
+
+ Knorr, Stefan
+ Creepy Crawlies
+ Horror
+ 4.95
+ 2000-12-06
+ An anthology of horror stories about roaches,
+ centipedes, scorpions and other insects.
+
+
+ Kress, Peter
+ Paradox Lost
+ Science Fiction
+ 6.95
+ 2000-11-02
+ After an inadvertant trip through a Heisenberg
+ Uncertainty Device, James Salway discovers the problems
+ of being quantum.
+
+
+ O'Brien, Tim
+ Microsoft .NET: The Programming Bible
+ Computer
+ 36.95
+ 2000-12-09
+ Microsoft's .NET initiative is explored in
+ detail in this deep programmer's reference.
+
+
+ O'Brien, Tim
+ MSXML3: A Comprehensive Guide
+ Computer
+ 36.95
+ 2000-12-01
+ The Microsoft MSXML3 parser is covered in
+ detail, with attention to XML DOM interfaces, XSLT processing,
+ SAX and more.
+
+
+ Galos, Mike
+ Visual Studio 7: A Comprehensive Guide
+ Computer
+ 49.95
+ 2001-04-16
+ Microsoft Visual Studio 7 is explored in depth,
+ looking at how Visual Basic, Visual C++, C#, and ASP+ are
+ integrated into a comprehensive development
+ environment.
+
+
\ No newline at end of file
diff --git a/src/test/resources/TransformerTest.xml b/src/test/resources/TransformerTest.xml
new file mode 100644
index 000000000..cef50a89c
--- /dev/null
+++ b/src/test/resources/TransformerTest.xml
@@ -0,0 +1,4 @@
+
+
+ rajihul@gmail.com
+
\ No newline at end of file
diff --git a/src/test/resources/baddata.xml b/src/test/resources/baddata.xml
new file mode 100644
index 000000000..4c684918e
--- /dev/null
+++ b/src/test/resources/baddata.xml
@@ -0,0 +1,11 @@
+
+
+
+ Gambardella, Matthew
+ XML Developer's Guide
+ Computer
+ 44.95
+ 2000-10-01
+ An in-depth look at creating applications
+ with XML.
+
\ No newline at end of file
diff --git a/src/test/resources/file.xml b/src/test/resources/file.xml
new file mode 100644
index 000000000..b38836331
--- /dev/null
+++ b/src/test/resources/file.xml
@@ -0,0 +1,36 @@
+
+
+
+ 11ClinicalTrials.gov processed this data on July 19, 2020
+ Link to the current ClinicalTrials.gov record.
+ https://clinicaltrials.gov/show/NCT03874338
+
+
+ 22ClinicalTrials.gov processed this data on July 19, 2020
+ Link to the current ClinicalTrials.gov record.
+ https://clinicaltrials.gov/show/NCT03874338
+
+
+ ClinicalTrials.gov processed this data on July 19, 2020
+ Link to the current ClinicalTrials.gov record.
+ https://clinicaltrials.gov/show/NCT03874338
+
+ raji date caji
+ Link to the current ClinicalTrials.gov record.
+ https://clinicaltrials.gov/show/NCT03874338
+
+
+
+ NYU Langone Health
+ Other
+
+
+ Population Health Research Institute
+ Other
+
+
+ National Heart, Lung, and Blood Institute (NHLBI)
+ NIH
+
+
+