mapper) throws ParseException {
return super.parse(mapper);
}
- //
- //
- //
- //
- //
- //
- //
-
protected void read() throws IOException {
int i = in.read();
c = (i == -1) ? (char) EOI : (char) i;
pos++;
- //
}
protected void readS() throws IOException {
@@ -84,6 +80,5 @@ protected void readNoEnd() throws ParseException, IOException {
int i = in.read();
if (i == -1) throw new ParseException(pos - 1, ERROR_UNEXPECTED_EOF, "EOF");
c = (char) i;
- //
}
}
diff --git a/json-smart/src/main/java/net/minidev/json/parser/JSONParserStream.java b/json-smart/src/main/java/net/minidev/json/parser/JSONParserStream.java
index dbcc938..1ec1236 100644
--- a/json-smart/src/main/java/net/minidev/json/parser/JSONParserStream.java
+++ b/json-smart/src/main/java/net/minidev/json/parser/JSONParserStream.java
@@ -28,8 +28,6 @@
* @see JSONParserReader
*/
abstract class JSONParserStream extends JSONParserBase {
- // len
- //
public JSONParserStream(int permissiveMode) {
super(permissiveMode);
}
@@ -112,26 +110,8 @@ protected void readString() throws ParseException, IOException {
throw new ParseException(pos, ERROR_UNEXPECTED_CHAR, c);
}
sb.clear();
- //
- //
- //
- //
- //
- //
- //
- //
- //
- //
+
/* assert (c == '\"' || c == '\'') */
readString2();
}
-
- //
- //
- //
- //
- //
- //
- //
- //
}
diff --git a/json-smart/src/main/java/net/minidev/json/parser/JSONParserString.java b/json-smart/src/main/java/net/minidev/json/parser/JSONParserString.java
index 4d505e2..04d4ba3 100644
--- a/json-smart/src/main/java/net/minidev/json/parser/JSONParserString.java
+++ b/json-smart/src/main/java/net/minidev/json/parser/JSONParserString.java
@@ -32,6 +32,12 @@ public JSONParserString(int permissiveMode) {
super(permissiveMode);
}
+ public JSONParserString(String in, int permissiveMode) {
+ super(permissiveMode);
+ this.in = in;
+ this.len = in.length();
+ }
+
/**
* use to return Primitive Type, or String, Or JsonObject or JsonArray generated by a
* ContainerFactory
diff --git a/json-smart/src/main/java/net/minidev/json/parser/MultipleJsonParser.java b/json-smart/src/main/java/net/minidev/json/parser/MultipleJsonParser.java
new file mode 100644
index 0000000..76a1c68
--- /dev/null
+++ b/json-smart/src/main/java/net/minidev/json/parser/MultipleJsonParser.java
@@ -0,0 +1,67 @@
+package net.minidev.json.parser;
+
+import java.io.InputStream;
+import java.io.Reader;
+import net.minidev.json.JSONValue;
+import net.minidev.json.writer.JsonReaderI;
+
+/**
+ * json-smart will parse multiple json separated by blank or line break character.
+ *
+ * multiple json example:
+ * {"json1": "value1"} {"json2": "value2"}
+ * or
+ * [{"json1-key1": "value1"}] [{"json2": "value2"}]
+ */
+public class MultipleJsonParser {
+
+ private final JSONParserBase jsonParser;
+
+ public MultipleJsonParser(byte[] in, int permissiveMode) {
+ this.jsonParser = new JSONParserByteArray(in, permissiveMode);
+ }
+
+ public MultipleJsonParser(InputStream in, int permissiveMode) {
+ this.jsonParser = new JSONParserInputStream(in, permissiveMode);
+ }
+
+ public MultipleJsonParser(Reader in, int permissiveMode) {
+ this.jsonParser = new JSONParserReader(in, permissiveMode);
+ }
+
+ public MultipleJsonParser(String in, int permissiveMode) {
+ this.jsonParser = new JSONParserString(in, permissiveMode);
+ }
+
+ /**
+ * Parse next json with defaultReader
+ * use to return Primitive Type, or String, Or JsonObject or JsonArray generated by a
+ * ContainerFactory
+ */
+ public Object parseNext() throws ParseException {
+ return jsonParser.parseNext(JSONValue.defaultReader.DEFAULT);
+ }
+
+ /**
+ * Parse next json with target JsonReaderI
+ * use to return Primitive Type, or String, Or JsonObject or JsonArray generated by a
+ * ContainerFactory
+ */
+ public T parseNext(JsonReaderI mapper) throws ParseException {
+ return this.jsonParser.parseNext(mapper);
+ }
+
+ /** Parse next json with target Class */
+ public T parseNext(Class mapTo) throws ParseException {
+ return this.jsonParser.parseNext(JSONValue.defaultReader.getMapper(mapTo));
+ }
+
+ /**
+ * Checks if there is another JSON value available in the input.
+ *
+ * @return true if another JSON value exists, false otherwise
+ */
+ public boolean hasNext() {
+ return this.jsonParser.hasNext();
+ }
+}
diff --git a/json-smart/src/test/java/net/minidev/json/test/parser/MultipleJsonParserTest.java b/json-smart/src/test/java/net/minidev/json/test/parser/MultipleJsonParserTest.java
new file mode 100644
index 0000000..7cecb8a
--- /dev/null
+++ b/json-smart/src/test/java/net/minidev/json/test/parser/MultipleJsonParserTest.java
@@ -0,0 +1,206 @@
+package net.minidev.json.test.parser;
+
+import static net.minidev.json.parser.JSONParser.DEFAULT_PERMISSIVE_MODE;
+
+import java.io.ByteArrayInputStream;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.nio.charset.StandardCharsets;
+import net.minidev.json.JSONArray;
+import net.minidev.json.JSONObject;
+import net.minidev.json.JSONValue;
+import net.minidev.json.parser.JSONParser;
+import net.minidev.json.parser.MultipleJsonParser;
+import net.minidev.json.parser.ParseException;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class MultipleJsonParserTest {
+
+ @Test
+ public void testMultipleJsonsFromSingleJsonArraySuccess()
+ throws ParseException, UnsupportedEncodingException {
+ String json =
+ "[{\"friends\":[{\"id\":0,\"name\":\"test1\"},{\"id\":1,\"name\":\"test2\"}]}] other data";
+ MultipleJsonParser parser = new MultipleJsonParser(json, DEFAULT_PERMISSIVE_MODE);
+ JSONArray root = (JSONArray) parser.parseNext();
+ JSONObject rootObj = (JSONObject) root.get(0);
+ JSONArray array = (JSONArray) rootObj.get("friends");
+ for (int idx = 0; idx < array.size(); idx++) {
+ JSONObject cap = (JSONObject) array.get(idx);
+ String first = (String) cap.get("name");
+ Assertions.assertEquals("test" + (idx + 1), first);
+ }
+ }
+
+ @Test
+ public void testMultipleJsonsFromMultipleJsonArraySuccess()
+ throws ParseException, UnsupportedEncodingException {
+ String json =
+ "[{\"friends\":[{\"id\":0,\"name\":\"test1\"},{\"id\":1,\"name\":\"test2\"}]}] "
+ + "[{\"friends\":[{\"id\":2,\"name\":\"test3\"},{\"id\":3,\"name\":\"test4\"}]}]";
+ MultipleJsonParser parser = new MultipleJsonParser(json, DEFAULT_PERMISSIVE_MODE);
+
+ // first
+ JSONArray root = (JSONArray) parser.parseNext();
+ JSONObject rootObj = (JSONObject) root.get(0);
+ JSONArray array = (JSONArray) rootObj.get("friends");
+ for (int idx = 0; idx < array.size(); idx++) {
+ JSONObject cap = (JSONObject) array.get(idx);
+ String first = (String) cap.get("name");
+ Assertions.assertEquals("test" + (idx + 1), first);
+ }
+
+ // second
+ JSONArray root2 = (JSONArray) parser.parseNext();
+ JSONObject rootObj2 = (JSONObject) root2.get(0);
+ JSONArray array2 = (JSONArray) rootObj2.get("friends");
+ for (int idx = 0; idx < array2.size(); idx++) {
+ JSONObject cap = (JSONObject) array2.get(idx);
+ String first = (String) cap.get("name");
+ Assertions.assertEquals("test" + (idx + 3), first);
+ }
+ }
+
+ @Test
+ public void testMultipleJsonsFromByteSuccess() throws Exception {
+ String json =
+ "{tranid:\"1212\", \"user\":{\"name\":\"123\",\"addr\":\"786 rt\"}}"
+ + "\n{tranid:\"1213\", \"user\":{\"name\":\"345\",\"addr\":\"4234 iu\"}}";
+ MultipleJsonParser parser =
+ new MultipleJsonParser(json.getBytes(StandardCharsets.UTF_8), DEFAULT_PERMISSIVE_MODE);
+
+ JSONObject root1 = (JSONObject) parser.parseNext();
+ Assertions.assertEquals("1212", root1.get("tranid"));
+
+ Assertions.assertTrue(parser.hasNext());
+ JSONObject root2 = (JSONObject) parser.parseNext();
+ Assertions.assertEquals("1213", root2.get("tranid"));
+
+ Assertions.assertFalse(parser.hasNext());
+ }
+
+ @Test
+ public void testMultipleJsonsFromInputStreamSuccess() throws Exception {
+ String json =
+ "{tranid:\"1212\", \"user\":{\"name\":\"123\",\"addr\":\"786 rt\"}}"
+ + "\n{tranid:\"1213\", \"user\":{\"name\":\"345\",\"addr\":\"4234 iu\"}}";
+ ByteArrayInputStream stream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
+ MultipleJsonParser parser = new MultipleJsonParser(stream, DEFAULT_PERMISSIVE_MODE);
+
+ JSONObject root1 = (JSONObject) parser.parseNext();
+ Assertions.assertEquals("1212", root1.get("tranid"));
+
+ Assertions.assertTrue(parser.hasNext());
+ JSONObject root2 = (JSONObject) parser.parseNext();
+ Assertions.assertEquals("1213", root2.get("tranid"));
+
+ Assertions.assertFalse(parser.hasNext());
+ }
+
+ @Test
+ public void testMultipleJsonsFromInputStreamReaderSuccess() throws Exception {
+ String json =
+ "{tranid:\"1212\", \"user\":{\"name\":\"123\",\"addr\":\"786 rt\"}}"
+ + "\n{tranid:\"1213\", \"user\":{\"name\":\"345\",\"addr\":\"4234 iu\"}}";
+ StringReader reader = new StringReader(json);
+ MultipleJsonParser parser = new MultipleJsonParser(reader, DEFAULT_PERMISSIVE_MODE);
+
+ JSONObject root1 = (JSONObject) parser.parseNext();
+ Assertions.assertEquals("1212", root1.get("tranid"));
+
+ Assertions.assertTrue(parser.hasNext());
+ JSONObject root2 = (JSONObject) parser.parseNext();
+ Assertions.assertEquals("1213", root2.get("tranid"));
+
+ Assertions.assertFalse(parser.hasNext());
+ }
+
+ @Test
+ public void testMultipleJsonsFromStringSuccess() throws Exception {
+ String json =
+ "{tranid:\"1212\", \"user\":{\"name\":\"123\",\"addr\":\"786 rt\"}}"
+ + " {tranid:\"1213\", \"user\":{\"name\":\"343\",\"addr\":\"4233 iu\"}}"
+ + "\r{tranid:\"1214\", \"user\":{\"name\":\"344\",\"addr\":\"4234 iu\"}}"
+ + "\t{tranid:\"1215\", \"user\":{\"name\":\"345\",\"addr\":\"4235 iu\"}}"
+ + "\n{tranid:\"1216\", \"user\":{\"name\":\"346\",\"addr\":\"4236 iu\"}}";
+ MultipleJsonParser parser = new MultipleJsonParser(json, DEFAULT_PERMISSIVE_MODE);
+ JSONObject root1 = (JSONObject) parser.parseNext(JSONValue.defaultReader.DEFAULT);
+ Assertions.assertEquals("1212", root1.get("tranid"));
+
+ int count = 3;
+ while (parser.hasNext()) {
+ JSONObject root2 = (JSONObject) parser.parseNext(JSONValue.defaultReader.DEFAULT);
+ Assertions.assertEquals("121" + count, root2.get("tranid"));
+ count++;
+ }
+ Assertions.assertEquals(7, count);
+ }
+
+ @Test
+ public void testMultipleJsonsParseClassFromStringSuccess() throws Exception {
+ String json =
+ "{tranid:\"1212\", \"user\":{\"name\":\"123\",\"addr\":\"786 rt\"}}"
+ + " {tranid:\"1213\", \"user\":{\"name\":\"343\",\"addr\":\"4233 iu\"}}"
+ + "\r{tranid:\"1214\", \"user\":{\"name\":\"344\",\"addr\":\"4234 iu\"}}"
+ + "\t{tranid:\"1215\", \"user\":{\"name\":\"345\",\"addr\":\"4235 iu\"}}"
+ + "\n{tranid:\"1216\", \"user\":{\"name\":\"346\",\"addr\":\"4236 iu\"}}";
+ MultipleJsonParser parser = new MultipleJsonParser(json, DEFAULT_PERMISSIVE_MODE);
+ JSONObject root1 = (JSONObject) parser.parseNext(JSONValue.defaultReader.DEFAULT);
+ Assertions.assertEquals("1212", root1.get("tranid"));
+
+ int count = 3;
+ while (parser.hasNext()) {
+ Transaction root2 = parser.parseNext(Transaction.class);
+ Assertions.assertEquals("121" + count, root2.getTranid());
+ Assertions.assertEquals("34" + count, root2.getUser().getName());
+ count++;
+ }
+ Assertions.assertEquals(7, count);
+ }
+
+ @Test
+ public void testMultipleJsonsFromInvalidStringFailed() throws Exception {
+ String json =
+ "{tranid:\"1212\", \"user\":{\"name\":\"123\",\"addr\":\"786 rt\"}} bbb "
+ + "\n{tranid:\"1213\", \"user\":{\"name\":\"343\",\"addr\":\"4233 iu\"}} ";
+ MultipleJsonParser parser = new MultipleJsonParser(json, DEFAULT_PERMISSIVE_MODE);
+ JSONObject root1 = (JSONObject) parser.parseNext(JSONValue.defaultReader.DEFAULT);
+ Assertions.assertEquals("1212", root1.get("tranid"));
+
+ int count = 3;
+ while (parser.hasNext()) {
+ // return invalid input when parse failed
+ Object root2 = parser.parseNext(JSONValue.defaultReader.DEFAULT);
+ Assertions.assertEquals(
+ "bbb \n" + "{tranid:\"1213\", \"user\":{\"name\":\"343\",\"addr\":\"4233 iu\"}}", root2);
+ count++;
+ }
+ Assertions.assertEquals(4, count);
+ }
+
+ @Test
+ public void testMultipleJsonsWithJsonParserBySubStringSuccess() throws Exception {
+ String json =
+ "{tranid:\"1212\", \"user\":{\"name\":\"123\",\"addr\":\"786 rt\"}}"
+ + "\n{tranid:\"1213\", \"user\":{\"name\":\"345\",\"addr\":\"4234 iu\"}}";
+ JSONParser parser = new JSONParser(DEFAULT_PERMISSIVE_MODE);
+ JSONObject root1 = (JSONObject) parser.parse(json, JSONValue.defaultReader.DEFAULT);
+ Assertions.assertEquals("1212", root1.get("tranid"));
+
+ Field field = Class.forName("net.minidev.json.parser.JSONParserBase").getDeclaredField("pos");
+ field.setAccessible(true);
+ Field pStringField = JSONParser.class.getDeclaredField("pString");
+ pStringField.setAccessible(true);
+ Object parser2 = pStringField.get(parser);
+ Integer ipos = (Integer) field.get(parser2);
+ Assertions.assertEquals(54, ipos);
+
+ JSONObject root2 =
+ (JSONObject) parser.parse(json.substring(ipos), JSONValue.defaultReader.DEFAULT);
+ Assertions.assertEquals("1213", root2.get("tranid"));
+ ipos = (Integer) field.get(parser2);
+ Assertions.assertEquals(56, ipos);
+ }
+}
diff --git a/json-smart/src/test/java/net/minidev/json/test/parser/Transaction.java b/json-smart/src/test/java/net/minidev/json/test/parser/Transaction.java
new file mode 100644
index 0000000..e8c9db1
--- /dev/null
+++ b/json-smart/src/test/java/net/minidev/json/test/parser/Transaction.java
@@ -0,0 +1,77 @@
+package net.minidev.json.test.parser;
+
+import java.util.List;
+import java.util.Map;
+
+/** Represents a transaction data structure parsed from JSON. */
+public class Transaction {
+ private String tranid;
+ private User user;
+ private List