From 141c6b99bea1d877b2c5ccc5a02852cf6bed17e3 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 23 May 2025 10:08:25 +0300 Subject: [PATCH 1/4] Added method U.streamJsonToXml(jsonInputStream, xmlOutputStream, identStep) --- src/main/java/com/github/underscore/U.java | 24 ++++++ .../com/github/underscore/UnderscoreTest.java | 82 +++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/src/main/java/com/github/underscore/U.java b/src/main/java/com/github/underscore/U.java index 1c0a5c63..248e4ca3 100644 --- a/src/main/java/com/github/underscore/U.java +++ b/src/main/java/com/github/underscore/U.java @@ -2850,6 +2850,30 @@ public static void fileJsonToXml(String jsonFileName, String xmlFileName) throws fileJsonToXml(jsonFileName, xmlFileName, Xml.XmlStringBuilder.Step.TWO_SPACES); } + public static void streamJsonToXml( + InputStream jsonInputStream, + OutputStream xmlOutputStream, + Xml.XmlStringBuilder.Step identStep) + throws IOException { + byte[] bytes = jsonInputStream.readAllBytes(); + String jsonText = new String(removeBom(bytes), detectEncoding(bytes)); + Object jsonObject = U.fromJson(jsonText); + String lineSeparator = System.lineSeparator(); + String xml; + if (jsonObject instanceof Map) { + xml = formatString(Xml.toXml((Map) jsonObject, identStep), lineSeparator); + if (((Map) jsonObject).containsKey("#encoding")) { + String encoding = String.valueOf(((Map) jsonObject).get("#encoding")); + xmlOutputStream.write(xml.getBytes(encoding)); + } else { + xmlOutputStream.write(xml.getBytes(StandardCharsets.UTF_8)); + } + } else { + xml = formatString(Xml.toXml((List) jsonObject, identStep), lineSeparator); + xmlOutputStream.write(xml.getBytes(StandardCharsets.UTF_8)); + } + } + public static byte[] removeBom(byte[] bytes) { if ((bytes.length >= 3) && (bytes[0] == -17) && (bytes[1] == -69) && (bytes[2] == -65)) { return Arrays.copyOfRange(bytes, 3, bytes.length); diff --git a/src/test/java/com/github/underscore/UnderscoreTest.java b/src/test/java/com/github/underscore/UnderscoreTest.java index 21605d8b..d92efae9 100644 --- a/src/test/java/com/github/underscore/UnderscoreTest.java +++ b/src/test/java/com/github/underscore/UnderscoreTest.java @@ -1226,4 +1226,86 @@ void testListResult(@TempDir Path tempDir) throws IOException { xmlStr, "Should write XML using UTF-8 when result is a List"); } + + @Test + void testStreamJsonToXml_ObjectMap_DefaultEncoding() throws Exception { + String inputJson = "{\"root\":\"value\"}"; + ByteArrayInputStream inputStream = + new ByteArrayInputStream(inputJson.getBytes(StandardCharsets.UTF_8)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + U.streamJsonToXml(inputStream, outputStream, Xml.XmlStringBuilder.Step.TWO_SPACES); + String expectedXml = + "" + + System.lineSeparator() + + "value"; + String actualXml = outputStream.toString(StandardCharsets.UTF_8); + assertEquals( + expectedXml, + actualXml, + "XML output should match expected XML for simple JSON object with default encoding"); + } + + @Test + void testStreamJsonToXml_ObjectMap_CustomEncoding() throws Exception { + String inputJson = "{\"root\":\"value\",\"#encoding\":\"UTF-16\"}"; + ByteArrayInputStream inputStream = + new ByteArrayInputStream(inputJson.getBytes(StandardCharsets.UTF_8)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + U.streamJsonToXml(inputStream, outputStream, Xml.XmlStringBuilder.Step.TWO_SPACES); + String expectedXml = + "" + + System.lineSeparator() + + "value"; + String actualXml = outputStream.toString(StandardCharsets.UTF_16); + assertEquals( + expectedXml, + actualXml, + "XML output should match expected XML for simple JSON object with default encoding"); + } + + @Test + void testStreamJsonToXml_List() throws Exception { + String inputJson = "[{\"item\":42}]"; + ByteArrayInputStream inputStream = + new ByteArrayInputStream(inputJson.getBytes(StandardCharsets.UTF_8)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + U.streamJsonToXml(inputStream, outputStream, Xml.XmlStringBuilder.Step.TWO_SPACES); + String expectedXml = + "" + + System.lineSeparator() + + "" + + System.lineSeparator() + + " " + + System.lineSeparator() + + " 42" + + System.lineSeparator() + + " " + + System.lineSeparator() + + ""; + String actualXml = outputStream.toString(StandardCharsets.UTF_8); + assertEquals( + expectedXml, + actualXml, + "XML output should match expected XML for JSON array root with default encoding"); + } + + @Test + void testStreamJsonToXml_InvalidJson_ThrowsException() { + String inputJson = "invalid"; + ByteArrayInputStream inputStream = + new ByteArrayInputStream(inputJson.getBytes(StandardCharsets.UTF_8)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + Exception exception = + assertThrows( + Json.ParseException.class, + () -> + U.streamJsonToXml( + inputStream, + outputStream, + Xml.XmlStringBuilder.Step.TWO_SPACES)); + String actualMessage = exception.getMessage(); + assertTrue( + actualMessage.contains("Expected value"), + "Should throw exception if JSON is invalid"); + } } From fb06cdcaa19df4a4972b63465a7f37ffe129398b Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 23 May 2025 10:11:42 +0300 Subject: [PATCH 2/4] Added method without identStep --- src/main/java/com/github/underscore/U.java | 4 ++++ src/test/java/com/github/underscore/UnderscoreTest.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/underscore/U.java b/src/main/java/com/github/underscore/U.java index 248e4ca3..b2ee2c79 100644 --- a/src/main/java/com/github/underscore/U.java +++ b/src/main/java/com/github/underscore/U.java @@ -2874,6 +2874,10 @@ public static void streamJsonToXml( } } + public static void streamJsonToXml(InputStream jsonInputStream, OutputStream xmlOutputStream) throws IOException { + streamJsonToXml(jsonInputStream, xmlOutputStream, Xml.XmlStringBuilder.Step.TWO_SPACES); + } + public static byte[] removeBom(byte[] bytes) { if ((bytes.length >= 3) && (bytes[0] == -17) && (bytes[1] == -69) && (bytes[2] == -65)) { return Arrays.copyOfRange(bytes, 3, bytes.length); diff --git a/src/test/java/com/github/underscore/UnderscoreTest.java b/src/test/java/com/github/underscore/UnderscoreTest.java index d92efae9..f018e03c 100644 --- a/src/test/java/com/github/underscore/UnderscoreTest.java +++ b/src/test/java/com/github/underscore/UnderscoreTest.java @@ -1233,7 +1233,7 @@ void testStreamJsonToXml_ObjectMap_DefaultEncoding() throws Exception { ByteArrayInputStream inputStream = new ByteArrayInputStream(inputJson.getBytes(StandardCharsets.UTF_8)); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - U.streamJsonToXml(inputStream, outputStream, Xml.XmlStringBuilder.Step.TWO_SPACES); + U.streamJsonToXml(inputStream, outputStream); String expectedXml = "" + System.lineSeparator() From dc1570b7566a30129950a7caa419f5ca359ae2e8 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 23 May 2025 10:12:03 +0300 Subject: [PATCH 3/4] Format sources --- src/main/java/com/github/underscore/U.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/underscore/U.java b/src/main/java/com/github/underscore/U.java index b2ee2c79..c110f229 100644 --- a/src/main/java/com/github/underscore/U.java +++ b/src/main/java/com/github/underscore/U.java @@ -2874,7 +2874,8 @@ public static void streamJsonToXml( } } - public static void streamJsonToXml(InputStream jsonInputStream, OutputStream xmlOutputStream) throws IOException { + public static void streamJsonToXml(InputStream jsonInputStream, OutputStream xmlOutputStream) + throws IOException { streamJsonToXml(jsonInputStream, xmlOutputStream, Xml.XmlStringBuilder.Step.TWO_SPACES); } From f9ab4d9125e3c97cb37f0534869c2d7876e0f36a Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Fri, 23 May 2025 10:15:26 +0300 Subject: [PATCH 4/4] Fixed sonar warning --- src/main/java/com/github/underscore/U.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/github/underscore/U.java b/src/main/java/com/github/underscore/U.java index c110f229..7f545360 100644 --- a/src/main/java/com/github/underscore/U.java +++ b/src/main/java/com/github/underscore/U.java @@ -103,6 +103,7 @@ public class U extends Underscore { java.util.regex.Pattern.compile( UPPER + "+(?=" + UPPER + LOWER + ")|" + UPPER + "?" + LOWER + "|" + UPPER + "+|\\d+"); + private static final String ENCODING = "#encoding"; static { String[] deburredLetters = @@ -2826,8 +2827,8 @@ public static void fileJsonToXml( Path xmlFilePath = Paths.get(xmlFileName); String lineSeparator = System.lineSeparator(); if (result instanceof Map) { - if (((Map) result).containsKey("#encoding")) { - String encoding = String.valueOf(((Map) result).get("#encoding")); + if (((Map) result).containsKey(ENCODING)) { + String encoding = String.valueOf(((Map) result).get(ENCODING)); Files.write( xmlFilePath, formatString(Xml.toXml((Map) result, identStep), lineSeparator) @@ -2862,8 +2863,8 @@ public static void streamJsonToXml( String xml; if (jsonObject instanceof Map) { xml = formatString(Xml.toXml((Map) jsonObject, identStep), lineSeparator); - if (((Map) jsonObject).containsKey("#encoding")) { - String encoding = String.valueOf(((Map) jsonObject).get("#encoding")); + if (((Map) jsonObject).containsKey(ENCODING)) { + String encoding = String.valueOf(((Map) jsonObject).get(ENCODING)); xmlOutputStream.write(xml.getBytes(encoding)); } else { xmlOutputStream.write(xml.getBytes(StandardCharsets.UTF_8));