Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions src/main/java/com/github/underscore/U.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public class U<T> extends Underscore<T> {
java.util.regex.Pattern.compile(
UPPER + "+(?=" + UPPER + LOWER + ")|" + UPPER + "?" + LOWER + "|" + UPPER
+ "+|\\d+");
private static final String ENCODING = "#encoding";

static {
String[] deburredLetters =
Expand Down Expand Up @@ -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)
Expand All @@ -2850,6 +2851,35 @@ 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 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);
Expand Down
82 changes: 82 additions & 0 deletions src/test/java/com/github/underscore/UnderscoreTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
String expectedXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ System.lineSeparator()
+ "<root>value</root>";
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 =
"<?xml version=\"1.0\" encoding=\"UTF-16\"?>"
+ System.lineSeparator()
+ "<root>value</root>";
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 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ System.lineSeparator()
+ "<root>"
+ System.lineSeparator()
+ " <element array=\"true\">"
+ System.lineSeparator()
+ " <item number=\"true\">42</item>"
+ System.lineSeparator()
+ " </element>"
+ System.lineSeparator()
+ "</root>";
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");
}
}
Loading