diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 2fe976729..b96b934d1 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -9,6 +9,8 @@ Project: jackson-dataformat-xml #618: `ArrayIndexOutOfBoundsException` thrown for invalid ending XML string when using JDK default Stax XML parser (reported by Arthur C) +#631: Add `XmlMapper.createGenerator(XMLStreamWriter)` and + `XmlMapper.createParser(XMLStreamReader)` overloads * Upgrade Woodstox to 6.6.0 (latest at the time) 2.16.1 (24-Dec-2023) diff --git a/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java b/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java index a83327261..fe2c8cd44 100644 --- a/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java +++ b/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java @@ -427,6 +427,24 @@ public XmlFactory tokenStreamFactory() { /********************************************************************** */ + /** + * Overloaded variant that allows constructing {@link FromXmlParser} + * for given Stax {@link XMLStreamReader}. + */ + public FromXmlParser createParser(XMLStreamReader r) throws IOException { + DeserializationContext ctxt = _deserializationContext(); + return tokenStreamFactory().createParser(ctxt, r); + } + + /** + * Overloaded variant that allows constructing {@link ToXmlGenerator} + * for given Stax {@link XMLStreamWriter}. + */ + public ToXmlGenerator createGenerator(XMLStreamWriter w) throws IOException { + SerializationContextExt prov = _serializerProvider(serializationConfig()); + return tokenStreamFactory().createGenerator(prov, w); + } + /** * Method for reading a single XML value from given XML-specific input * source; useful for incremental data-binding, combining traversal using @@ -453,9 +471,7 @@ public T readValue(XMLStreamReader r, TypeReference valueTypeRef) throws @SuppressWarnings("resource") public T readValue(XMLStreamReader r, JavaType valueType) throws IOException { - DeserializationContext ctxt = _deserializationContext(); - FromXmlParser p = tokenStreamFactory().createParser(ctxt, r); - return super.readValue(p, valueType); + return super.readValue(createParser(r), valueType); } /** @@ -464,14 +480,13 @@ public T readValue(XMLStreamReader r, JavaType valueType) throws IOException * a time. */ @SuppressWarnings("resource") - public void writeValue(XMLStreamWriter w0, Object value) throws IOException + public void writeValue(XMLStreamWriter w, Object value) throws IOException { // 04-Oct-2017, tatu: Unfortunately can not simply delegate to super-class implementation // because we need the context first... - - SerializationConfig config = serializationConfig(); - SerializationContextExt prov = _serializerProvider(config); - ToXmlGenerator g = tokenStreamFactory().createGenerator(prov, w0); + + ToXmlGenerator g = createGenerator(w); + final SerializationConfig config = serializationConfig(); if (config.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) { _writeCloseableValue(g, value, config); diff --git a/src/test/java/tools/jackson/dataformat/xml/incr/IncrementalWritingTest.java b/src/test/java/tools/jackson/dataformat/xml/incr/IncrementalWritingTest.java index ad5514ba8..b15b993ae 100644 --- a/src/test/java/tools/jackson/dataformat/xml/incr/IncrementalWritingTest.java +++ b/src/test/java/tools/jackson/dataformat/xml/incr/IncrementalWritingTest.java @@ -2,10 +2,12 @@ import java.io.*; +import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamWriter; import tools.jackson.dataformat.xml.XmlMapper; import tools.jackson.dataformat.xml.XmlTestBase; +import tools.jackson.dataformat.xml.ser.ToXmlGenerator; public class IncrementalWritingTest extends XmlTestBase { @@ -31,4 +33,29 @@ public void testSimple() throws Exception +"GrowlTiger", xml); } + + // @since 2.17 + public void testWriteUsingXMLStreamWriter() throws Exception + { + XMLOutputFactory staxF = MAPPER.tokenStreamFactory().getXMLOutputFactory(); + final Point p = new Point(1, 2); + + // Serialize first using convenience method + try (StringWriter w = new StringWriter()) { + XMLStreamWriter sw = staxF.createXMLStreamWriter(w); + MAPPER.writeValue(sw, p); + assertEquals("12", w.toString()); + } + + // and then by explicit XMLStreamWriter + try (StringWriter w = new StringWriter()) { + XMLStreamWriter sw = staxF.createXMLStreamWriter(w); + sw.writeStartDocument("US-ASCII", "1.1"); + try (ToXmlGenerator g = MAPPER.createGenerator(sw)) { + MAPPER.writeValue(g, p); + assertEquals("" + +"12", w.toString()); + } + } + } } diff --git a/src/test/java/tools/jackson/dataformat/xml/incr/PartialReadTest.java b/src/test/java/tools/jackson/dataformat/xml/incr/PartialReadTest.java index 031a2309a..2cfdba002 100644 --- a/src/test/java/tools/jackson/dataformat/xml/incr/PartialReadTest.java +++ b/src/test/java/tools/jackson/dataformat/xml/incr/PartialReadTest.java @@ -3,6 +3,8 @@ import java.io.*; import javax.xml.stream.*; +import tools.jackson.core.JsonParser; + import tools.jackson.dataformat.xml.XmlMapper; import tools.jackson.dataformat.xml.XmlTestBase; @@ -43,4 +45,27 @@ public void testSimpleRead() throws Exception sr.close(); } + + // @since 2.17 + public void testReadUsingXMLStreamReader() throws Exception + { + final String DOC = "12"; + + XMLInputFactory staxF = MAPPER.tokenStreamFactory().getXMLInputFactory(); + + // First read using XmlMapper convenience method + XMLStreamReader sr = staxF.createXMLStreamReader(new StringReader(DOC)); + Point p = MAPPER.readValue(sr, Point.class); + assertEquals(1, p.x); + assertEquals(2, p.y); + sr.close(); + + // Then read using XmlFactory parser factory method + sr = staxF.createXMLStreamReader(new StringReader(DOC)); + try (JsonParser jp = MAPPER.createParser(sr)) { + p = MAPPER.readValue(jp, Point.class); + assertEquals(1, p.x); + assertEquals(2, p.y); + } + } }