From ce2840f7b38ed4e255008624cd95e145198c12d1 Mon Sep 17 00:00:00 2001 From: Sylvain Wallez Date: Thu, 15 Jun 2023 10:13:50 +0200 Subject: [PATCH] Fix spurious JSON event emitted by JsonpUtils.copy() --- .../co/elastic/clients/json/JsonpUtils.java | 1 - .../elastic/clients/json/JsonpUtilsTest.java | 109 +++++++++++++++++- 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/java-client/src/main/java/co/elastic/clients/json/JsonpUtils.java b/java-client/src/main/java/co/elastic/clients/json/JsonpUtils.java index 7975c0c6b..fff4b148d 100644 --- a/java-client/src/main/java/co/elastic/clients/json/JsonpUtils.java +++ b/java-client/src/main/java/co/elastic/clients/json/JsonpUtils.java @@ -175,7 +175,6 @@ public static void copy(JsonParser parser, JsonGenerator generator, JsonParser.E case START_ARRAY: generator.writeStartArray(); - generator.writeStartObject(); while ((event = parser.next()) != Event.END_ARRAY) { copy(parser, generator, event); } diff --git a/java-client/src/test/java/co/elastic/clients/json/JsonpUtilsTest.java b/java-client/src/test/java/co/elastic/clients/json/JsonpUtilsTest.java index c7db13643..a57a5f959 100644 --- a/java-client/src/test/java/co/elastic/clients/json/JsonpUtilsTest.java +++ b/java-client/src/test/java/co/elastic/clients/json/JsonpUtilsTest.java @@ -25,13 +25,14 @@ import co.elastic.clients.elasticsearch.security.IndicesPrivileges; import co.elastic.clients.elasticsearch.security.RoleTemplateScript; import co.elastic.clients.elasticsearch.security.UserIndicesPrivileges; -import co.elastic.clients.json.JsonpUtils; import co.elastic.clients.util.AllowForbiddenApis; import jakarta.json.JsonException; import jakarta.json.spi.JsonProvider; import jakarta.json.stream.JsonGenerator; +import jakarta.json.stream.JsonParser; import org.junit.jupiter.api.Test; +import java.io.StringReader; import java.io.StringWriter; import java.net.URL; import java.util.Collections; @@ -209,6 +210,47 @@ public void testJsonString() { } } + @Test + public void testCopy() { + // Tests round-tripping a json document that contains all event types and various kinds of nesting + + String json = "{\n" + + " \"p1\": \"str1\",\n" + + " \"p2\": 42,\n" + + " \"p3\": [\"str31\", \"str32\"],\n" + + " \"p4\": {\n" + + " \"p41\": \"str41\",\n" + + " \"p42\": [\"str421\", \"str422\"],\n" + + " \"p43\": {\n" + + " \"p431\": \"str431\"\n" + + " },\n" + + " \"p44\": true,\n" + + " \"p45\": false,\n" + + " \"p46\": 3.14\n" + + " },\n" + + " \"p5\": [{\n" + + " \"p51\": {\n" + + " \"p511\": \"str511\"\n" + + " }\n" + + " }],\n" + + " \"p6\": null\n" + + "}\n"; + + json = normalizeIndent(json); + + JsonProvider provider = JsonpUtils.provider(); + + JsonParser parser = provider.createParser(new StringReader(json)); + StringWriter sw = new StringWriter(); + JsonGenerator generator = provider.createGenerator(sw); + + JsonpUtils.copy(parser, generator); + parser.close(); + generator.close(); + + assertEquals(json, sw.toString()); + } + private static String orNullHelper(Consumer c) { StringWriter sw = new StringWriter(); JsonGenerator generator = JsonpUtils.provider().createGenerator(sw); @@ -221,4 +263,69 @@ private static String orNullHelper(Consumer c) { return sw.toString(); } + + /** + * Normalizes the whitespace and indentation of a JSON string by parsing it and copying it to a string generator. + */ + private static String normalizeIndent(String json) { + JsonParser parser = JsonpUtils.provider().createParser(new StringReader(json)); + StringWriter sw = new StringWriter(); + JsonGenerator generator = JsonpUtils.provider().createGenerator(sw); + + copyAll(parser, generator); + + parser.close(); + generator.close(); + return sw.toString(); + } + + private static void copyAll(JsonParser parser, JsonGenerator generator) { + while(parser.hasNext()) { + switch (parser.next()) { + case START_OBJECT: + generator.writeStartObject(); + break; + + case END_OBJECT: + generator.writeEnd(); + break; + + case START_ARRAY: + generator.writeStartArray(); + break; + + case END_ARRAY: + generator.writeEnd(); + break; + + case KEY_NAME: + generator.writeKey(parser.getString()); + break; + + case VALUE_STRING: + generator.write(parser.getString()); + break; + + case VALUE_NULL: + generator.writeNull(); + break; + + case VALUE_TRUE: + generator.write(true); + break; + + case VALUE_FALSE: + generator.write(false); + break; + + case VALUE_NUMBER: + if (parser.isIntegralNumber()) { + generator.write(parser.getLong()); + } else { + generator.write(parser.getBigDecimal()); + } + break; + } + } + } }