diff --git a/build.gradle b/build.gradle
index 1560d1d..61f9ec9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -31,6 +31,7 @@ repositories {
dependencies {
implementation 'tools.jackson.core:jackson-databind:3.0.2'
implementation 'tools.jackson.module:jackson-module-afterburner:3.0.2'
+ implementation 'tools.jackson.dataformat:jackson-dataformat-xml:3.0.2'
testImplementation platform('org.junit:junit-bom:6.0.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
@@ -38,4 +39,4 @@ dependencies {
test {
useJUnitPlatform()
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/felipestanzani/jtoon/JToon.java b/src/main/java/com/felipestanzani/jtoon/JToon.java
index a3eeb13..a9946a9 100644
--- a/src/main/java/com/felipestanzani/jtoon/JToon.java
+++ b/src/main/java/com/felipestanzani/jtoon/JToon.java
@@ -3,6 +3,7 @@
import com.felipestanzani.jtoon.decoder.ValueDecoder;
import com.felipestanzani.jtoon.encoder.ValueEncoder;
import com.felipestanzani.jtoon.normalizer.JsonNormalizer;
+import com.felipestanzani.jtoon.normalizer.XmlNormalizer;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
@@ -27,6 +28,9 @@
* // Encode a plain JSON string directly
* String toon = JToon.encodeJson("{\"id\":123,\"name\":\"Ada\"}");
*
+ * // Encode a plain XML string directly
+ * String toon = JToon.encodeXml("
+ * This is a convenience overload that parses the XML string and encodes it + * without requiring callers to create a {@code JsonNode} or intermediate + * objects. + *
+ * + * @param xml The XML string to encode (must be valid XML) + * @return The TOON-formatted string + * @throws IllegalArgumentException if the input is not valid XML + */ + public static String encodeXml(String xml) { + return encodeXml(xml, EncodeOptions.DEFAULT); + } + + /** + * Encodes a plain XML string to TOON format using custom options. + * + *+ * Parsing is delegated to + * {@link com.felipestanzani.jtoon.normalizer.XmlNormalizer#parse(String)} + * to maintain separation of concerns. + *
+ * + * @param xml The XML string to encode (must be valid XML) + * @param options Encoding options (indent, delimiter, length marker) + * @return The TOON-formatted string + * @throws IllegalArgumentException if the input is not valid XML + */ + public static String encodeXml(String xml, EncodeOptions options) { + JsonNode parsed = XmlNormalizer.parse(xml); + return ValueEncoder.encodeValue(parsed, options); + } + /** * Decodes a TOON-formatted string to Java objects using default options. * diff --git a/src/main/java/com/felipestanzani/jtoon/normalizer/XmlNormalizer.java b/src/main/java/com/felipestanzani/jtoon/normalizer/XmlNormalizer.java new file mode 100644 index 0000000..d0d3667 --- /dev/null +++ b/src/main/java/com/felipestanzani/jtoon/normalizer/XmlNormalizer.java @@ -0,0 +1,40 @@ +package com.felipestanzani.jtoon.normalizer; + +import tools.jackson.databind.JsonNode; +import tools.jackson.dataformat.xml.XmlMapper; + +/** + * Normalizes XML strings to Jackson JsonNode representation. + * Converts XML structure to JSON-compatible format for TOON encoding. + */ +public final class XmlNormalizer { + + private static final XmlMapper XML_MAPPER = XmlMapper.builder().build(); + + private XmlNormalizer() { + throw new UnsupportedOperationException("Utility class cannot be instantiated"); + } + + /** + * Parses an XML string into a JsonNode using the shared XmlMapper. + *+ * This centralizes XML parsing concerns to keep the public API thin and + * maintain separation of responsibilities between parsing, normalization, + * and encoding. + *
+ * + * @param xml The XML string to parse (must be valid XML) + * @return Parsed JsonNode + * @throws IllegalArgumentException if the input is blank or not valid XML + */ + public static JsonNode parse(String xml) { + if (xml == null || xml.trim().isEmpty()) { + throw new IllegalArgumentException("Invalid XML"); + } + try { + return XML_MAPPER.readTree(xml); + } catch (Exception e) { + throw new IllegalArgumentException("Invalid XML", e); + } + } +} diff --git a/src/test/java/com/felipestanzani/jtoon/JToonTest.java b/src/test/java/com/felipestanzani/jtoon/JToonTest.java index ab23250..29452f8 100644 --- a/src/test/java/com/felipestanzani/jtoon/JToonTest.java +++ b/src/test/java/com/felipestanzani/jtoon/JToonTest.java @@ -745,6 +745,94 @@ void noTrailingNewline() { } } + @Nested + @DisplayName("XML tests") + class XmlTests { + + @Test + @DisplayName("encodes XML with custom options") + void encodesXmlWithOptions() { + String xml = "