From e0be53200fe0232f7cc05fbc4f1b80b58f634944 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 20 May 2025 10:21:39 +0300 Subject: [PATCH 1/6] Added method U.fileJsonToXml(jsonFileName, xmlFileName, identStep) --- src/main/java/com/github/underscore/U.java | 35 ++++++++++++ .../com/github/underscore/UnderscoreTest.java | 57 +++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/src/main/java/com/github/underscore/U.java b/src/main/java/com/github/underscore/U.java index a1873a4d..85b94eee 100644 --- a/src/main/java/com/github/underscore/U.java +++ b/src/main/java/com/github/underscore/U.java @@ -35,6 +35,7 @@ import java.nio.channels.ReadableByteChannel; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; @@ -2816,6 +2817,40 @@ public static void streamXmlToJson(InputStream xmlInputStream, OutputStream json streamXmlToJson(xmlInputStream, jsonOutputStream, Json.JsonStringBuilder.Step.TWO_SPACES); } + public static void fileJsonToXml( + String jsonFileName, String xmlFileName, Xml.XmlStringBuilder.Step identStep) + throws IOException { + final byte[] bytes = Files.readAllBytes(Paths.get(jsonFileName)); + String jsonText = new String(removeBom(bytes), detectEncoding(bytes)); + Object result = U.fromJson(jsonText); + 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")); + Files.write( + xmlFilePath, + formatString(Xml.toXml((Map) result, identStep), lineSeparator) + .getBytes(encoding)); + } else { + Files.write( + xmlFilePath, + formatString(Xml.toXml((Map) result, identStep), lineSeparator) + .getBytes(StandardCharsets.UTF_8)); + } + } else { + Files.write( + xmlFilePath, + formatString(Xml.toXml((List) result, identStep), lineSeparator) + .getBytes(StandardCharsets.UTF_8)); + } + } + + public static void fileJsonToXml( + String jsonFileName, String xmlFileName) throws IOException { + fileJsonToXml(jsonFileName, xmlFileName, 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 50aa9781..0c84138f 100644 --- a/src/test/java/com/github/underscore/UnderscoreTest.java +++ b/src/test/java/com/github/underscore/UnderscoreTest.java @@ -1153,4 +1153,61 @@ void testStreamXmlToJson_withIndentSteps_producesIndentedJson() throws IOExcepti String jsonOutput = jsonStream.toString("UTF-8"); assertTrue(jsonOutput.contains(" "), "JSON output should be indented with four spaces."); } + + @Test + void testMapWithEncodingKey(@TempDir Path tempDir) throws IOException { + // Arrange + Path jsonFile = tempDir.resolve("in.json"); + Path xmlFile = tempDir.resolve("out.xml"); + String encoding = "UTF-16"; + Map map = new LinkedHashMap<>(); + map.put("#encoding", encoding); + // Write json + String jsonText = "{\"#encoding\":\"" + encoding + "\"}"; + Files.write(jsonFile, jsonText.getBytes(StandardCharsets.UTF_8)); + // Act + U.fileJsonToXml(jsonFile.toString(), xmlFile.toString()); + // Assert + byte[] xmlBytes = Files.readAllBytes(xmlFile); + String xmlStr = new String(xmlBytes, encoding); + assertEquals("" + System.lineSeparator() + + "", xmlStr, "Should write XML with provided encoding when #encoding key present"); + } + + @Test + void testMapWithoutEncodingKey(@TempDir Path tempDir) throws IOException { + // Arrange + Path jsonFile = tempDir.resolve("in.json"); + Path xmlFile = tempDir.resolve("out.xml"); + Map map = new LinkedHashMap<>(); + String jsonText = "{}"; + Files.write(jsonFile, jsonText.getBytes(StandardCharsets.UTF_8)); + // Act + U.fileJsonToXml(jsonFile.toString(), xmlFile.toString(), Xml.XmlStringBuilder.Step.TWO_SPACES); + // Assert + byte[] xmlBytes = Files.readAllBytes(xmlFile); + String xmlStr = new String(xmlBytes, StandardCharsets.UTF_8); + assertEquals("" + System.lineSeparator() + + "", xmlStr, "Should write XML using UTF-8 when #encoding key not present"); + } + + @Test + void testListResult(@TempDir Path tempDir) throws IOException { + // Arrange + Path jsonFile = tempDir.resolve("in.json"); + Path xmlFile = tempDir.resolve("out.xml"); + Files.write(jsonFile, "[1,2,3]".getBytes(StandardCharsets.UTF_8)); + // Act + U.fileJsonToXml(jsonFile.toString(), xmlFile.toString(), Xml.XmlStringBuilder.Step.TWO_SPACES); + // Assert + byte[] xmlBytes = Files.readAllBytes(xmlFile); + String xmlStr = new String(xmlBytes, StandardCharsets.UTF_8); + assertEquals("" + System.lineSeparator() + + "" + System.lineSeparator() + + " 1" + System.lineSeparator() + + " 2" + System.lineSeparator() + + " 3" + System.lineSeparator() + + "", xmlStr, + "Should write XML using UTF-8 when result is a List"); + } } From eea49d8d836fdeebe04d241fa22345e0a0093c21 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 20 May 2025 10:25:36 +0300 Subject: [PATCH 2/6] Fixed sonar --- src/test/java/com/github/underscore/UnderscoreTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/github/underscore/UnderscoreTest.java b/src/test/java/com/github/underscore/UnderscoreTest.java index 0c84138f..f8f818a3 100644 --- a/src/test/java/com/github/underscore/UnderscoreTest.java +++ b/src/test/java/com/github/underscore/UnderscoreTest.java @@ -1179,7 +1179,6 @@ void testMapWithoutEncodingKey(@TempDir Path tempDir) throws IOException { // Arrange Path jsonFile = tempDir.resolve("in.json"); Path xmlFile = tempDir.resolve("out.xml"); - Map map = new LinkedHashMap<>(); String jsonText = "{}"; Files.write(jsonFile, jsonText.getBytes(StandardCharsets.UTF_8)); // Act From 8f0f20e4063210188561995292333e009c1f89d7 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 20 May 2025 11:55:18 +0300 Subject: [PATCH 3/6] Format sources --- src/main/java/com/github/underscore/U.java | 3 +- .../com/github/underscore/UnderscoreTest.java | 41 +++++++++++++------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/github/underscore/U.java b/src/main/java/com/github/underscore/U.java index 85b94eee..c19be850 100644 --- a/src/main/java/com/github/underscore/U.java +++ b/src/main/java/com/github/underscore/U.java @@ -2846,8 +2846,7 @@ public static void fileJsonToXml( } } - public static void fileJsonToXml( - String jsonFileName, String xmlFileName) throws IOException { + public static void fileJsonToXml(String jsonFileName, String xmlFileName) throws IOException { fileJsonToXml(jsonFileName, xmlFileName, Xml.XmlStringBuilder.Step.TWO_SPACES); } diff --git a/src/test/java/com/github/underscore/UnderscoreTest.java b/src/test/java/com/github/underscore/UnderscoreTest.java index f8f818a3..6046d868 100644 --- a/src/test/java/com/github/underscore/UnderscoreTest.java +++ b/src/test/java/com/github/underscore/UnderscoreTest.java @@ -1170,8 +1170,12 @@ void testMapWithEncodingKey(@TempDir Path tempDir) throws IOException { // Assert byte[] xmlBytes = Files.readAllBytes(xmlFile); String xmlStr = new String(xmlBytes, encoding); - assertEquals("" + System.lineSeparator() - + "", xmlStr, "Should write XML with provided encoding when #encoding key present"); + assertEquals( + "" + + System.lineSeparator() + + "", + xmlStr, + "Should write XML with provided encoding when #encoding key present"); } @Test @@ -1182,12 +1186,17 @@ void testMapWithoutEncodingKey(@TempDir Path tempDir) throws IOException { String jsonText = "{}"; Files.write(jsonFile, jsonText.getBytes(StandardCharsets.UTF_8)); // Act - U.fileJsonToXml(jsonFile.toString(), xmlFile.toString(), Xml.XmlStringBuilder.Step.TWO_SPACES); + U.fileJsonToXml( + jsonFile.toString(), xmlFile.toString(), Xml.XmlStringBuilder.Step.TWO_SPACES); // Assert byte[] xmlBytes = Files.readAllBytes(xmlFile); String xmlStr = new String(xmlBytes, StandardCharsets.UTF_8); - assertEquals("" + System.lineSeparator() - + "", xmlStr, "Should write XML using UTF-8 when #encoding key not present"); + assertEquals( + "" + + System.lineSeparator() + + "", + xmlStr, + "Should write XML using UTF-8 when #encoding key not present"); } @Test @@ -1197,16 +1206,24 @@ void testListResult(@TempDir Path tempDir) throws IOException { Path xmlFile = tempDir.resolve("out.xml"); Files.write(jsonFile, "[1,2,3]".getBytes(StandardCharsets.UTF_8)); // Act - U.fileJsonToXml(jsonFile.toString(), xmlFile.toString(), Xml.XmlStringBuilder.Step.TWO_SPACES); + U.fileJsonToXml( + jsonFile.toString(), xmlFile.toString(), Xml.XmlStringBuilder.Step.TWO_SPACES); // Assert byte[] xmlBytes = Files.readAllBytes(xmlFile); String xmlStr = new String(xmlBytes, StandardCharsets.UTF_8); - assertEquals("" + System.lineSeparator() - + "" + System.lineSeparator() - + " 1" + System.lineSeparator() - + " 2" + System.lineSeparator() - + " 3" + System.lineSeparator() - + "", xmlStr, + assertEquals( + "" + + System.lineSeparator() + + "" + + System.lineSeparator() + + " 1" + + System.lineSeparator() + + " 2" + + System.lineSeparator() + + " 3" + + System.lineSeparator() + + "", + xmlStr, "Should write XML using UTF-8 when result is a List"); } } From 06215da0bceec61415a16d0fd1068ac55215952b Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 20 May 2025 11:59:20 +0300 Subject: [PATCH 4/6] Improved tests --- .../com/github/underscore/UnderscoreTest.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/test/java/com/github/underscore/UnderscoreTest.java b/src/test/java/com/github/underscore/UnderscoreTest.java index 6046d868..21605d8b 100644 --- a/src/test/java/com/github/underscore/UnderscoreTest.java +++ b/src/test/java/com/github/underscore/UnderscoreTest.java @@ -1103,7 +1103,7 @@ void testStreamXmlToJson_validXml_writesJson() throws IOException { InputStream xmlStream = new ByteArrayInputStream(xml.getBytes()); ByteArrayOutputStream jsonStream = new ByteArrayOutputStream(); U.streamXmlToJson(xmlStream, jsonStream); - String jsonOutput = jsonStream.toString("UTF-8"); + String jsonOutput = jsonStream.toString(StandardCharsets.UTF_8); assertTrue(jsonOutput.contains("name"), "JSON output should contain 'name' field."); assertTrue(jsonOutput.contains("Test"), "JSON output should contain 'Test' value."); assertTrue(jsonOutput.startsWith("{"), "JSON output should start with '{'."); @@ -1117,10 +1117,11 @@ void testStreamXmlToJson_emptyInput_producesEmptyOrError() { Exception exception = assertThrows( Exception.class, - () -> { - U.streamXmlToJson( - xmlStream, jsonStream, Json.JsonStringBuilder.Step.TWO_SPACES); - }, + () -> + U.streamXmlToJson( + xmlStream, + jsonStream, + Json.JsonStringBuilder.Step.TWO_SPACES), "Should throw exception for empty input."); String msg = exception.getMessage(); assertNotNull(msg, "Exception message should not be null."); @@ -1135,10 +1136,11 @@ void testStreamXmlToJson_invalidXml_throwsException() { Exception exception = assertThrows( Exception.class, - () -> { - U.streamXmlToJson( - xmlStream, jsonStream, Json.JsonStringBuilder.Step.TWO_SPACES); - }, + () -> + U.streamXmlToJson( + xmlStream, + jsonStream, + Json.JsonStringBuilder.Step.TWO_SPACES), "Should throw exception for invalid XML."); String msg = exception.getMessage(); assertNotNull(msg, "Exception message for invalid XML should not be null."); @@ -1150,7 +1152,7 @@ void testStreamXmlToJson_withIndentSteps_producesIndentedJson() throws IOExcepti InputStream xmlStream = new ByteArrayInputStream(xml.getBytes()); ByteArrayOutputStream jsonStream = new ByteArrayOutputStream(); U.streamXmlToJson(xmlStream, jsonStream, Json.JsonStringBuilder.Step.FOUR_SPACES); - String jsonOutput = jsonStream.toString("UTF-8"); + String jsonOutput = jsonStream.toString(StandardCharsets.UTF_8); assertTrue(jsonOutput.contains(" "), "JSON output should be indented with four spaces."); } @@ -1160,8 +1162,6 @@ void testMapWithEncodingKey(@TempDir Path tempDir) throws IOException { Path jsonFile = tempDir.resolve("in.json"); Path xmlFile = tempDir.resolve("out.xml"); String encoding = "UTF-16"; - Map map = new LinkedHashMap<>(); - map.put("#encoding", encoding); // Write json String jsonText = "{\"#encoding\":\"" + encoding + "\"}"; Files.write(jsonFile, jsonText.getBytes(StandardCharsets.UTF_8)); From 5d6e5be0418346be70ed78f803bf3280ae7259bb Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Tue, 20 May 2025 12:13:22 +0300 Subject: [PATCH 5/6] Fixed idea warning --- src/main/java/com/github/underscore/U.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/github/underscore/U.java b/src/main/java/com/github/underscore/U.java index c19be850..3c6bc94b 100644 --- a/src/main/java/com/github/underscore/U.java +++ b/src/main/java/com/github/underscore/U.java @@ -2882,12 +2882,10 @@ public static String detectEncoding(byte[] buffer) { encoding = "UnicodeBigUnmarked"; break; case 0xFFFE0000: - encoding = "UTF_32LE"; - break; case 0x3C000000: encoding = "UTF_32LE"; break; - // Date: Tue, 20 May 2025 12:15:11 +0300 Subject: [PATCH 6/6] Fixed format --- src/main/java/com/github/underscore/U.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/underscore/U.java b/src/main/java/com/github/underscore/U.java index 3c6bc94b..1c0a5c63 100644 --- a/src/main/java/com/github/underscore/U.java +++ b/src/main/java/com/github/underscore/U.java @@ -2885,7 +2885,7 @@ public static String detectEncoding(byte[] buffer) { case 0x3C000000: encoding = "UTF_32LE"; break; - //