From ab5a16720685b865aeef15889d0c706a10cd6eb8 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Thu, 6 Mar 2025 10:14:56 +0100 Subject: [PATCH 1/6] support configureForJackson2 --- .../jackson/dataformat/xml/XmlFactory.java | 12 ++++++ .../dataformat/xml/XmlFactoryBuilder.java | 18 +++++++++ .../jackson/dataformat/xml/XmlMapper.java | 30 ++++++++++++++ .../jackson/dataformat/xml/XmlMapperTest.java | 40 +++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 src/test/java/tools/jackson/dataformat/xml/XmlMapperTest.java diff --git a/src/main/java/tools/jackson/dataformat/xml/XmlFactory.java b/src/main/java/tools/jackson/dataformat/xml/XmlFactory.java index 7b5433f4..88718c82 100644 --- a/src/main/java/tools/jackson/dataformat/xml/XmlFactory.java +++ b/src/main/java/tools/jackson/dataformat/xml/XmlFactory.java @@ -167,6 +167,18 @@ public static XmlFactoryBuilder builder() { return new XmlFactoryBuilder(); } + /** + * The builder returned uses default settings more closely + * matching the default configs used in Jackson 2.x versions. + *

+ * This method is still a work in progress and may not yet fully replicate the + * default settings of Jackson 2.x. + *

+ */ + public static XmlFactoryBuilder builderWithJackson2Defaults() { + return builder().configureForJackson2(); + } + /** * Note: compared to base implementation by {@link TokenStreamFactory}, * here the copy will actually share underlying XML input and diff --git a/src/main/java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java b/src/main/java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java index 5f5c01cd..1af4f57e 100644 --- a/src/main/java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java +++ b/src/main/java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java @@ -6,6 +6,7 @@ import tools.jackson.core.ErrorReportConfiguration; import tools.jackson.core.StreamReadConstraints; +import tools.jackson.core.StreamReadFeature; import tools.jackson.core.StreamWriteConstraints; import tools.jackson.core.base.DecorableTSFactory.DecorableTSFBuilder; @@ -222,6 +223,23 @@ public XmlFactoryBuilder configure(XmlWriteFeature f, boolean state) { return state ? enable(f) : disable(f); } + /** + * The builder returned uses default settings more closely + * matching the default configs used in Jackson 2.x versions. + *

+ * This method is still a work in progress and may not yet fully replicate the + * default settings of Jackson 2.x. + *

+ */ + @Override + public XmlFactoryBuilder configureForJackson2() { + return super.configureForJackson2() + .disable(XmlWriteFeature.WRITE_NULLS_AS_XSI_NIL) + .disable(XmlWriteFeature.UNWRAP_ROOT_OBJECT_NODE) + .disable(XmlWriteFeature.AUTO_DETECT_XSI_TYPE) + .disable(XmlWriteFeature.WRITE_XML_SCHEMA_CONFORMING_FLOATS); + } + // // // Other config public XmlFactoryBuilder nameForTextElement(String name) { diff --git a/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java b/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java index 0b4a12d0..cff9fe06 100644 --- a/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java +++ b/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java @@ -235,6 +235,23 @@ public Builder configure(XmlWriteFeature feature, boolean state) return this; } + /** + * The builder returned uses default settings more closely + * matching the default configs used in Jackson 2.x versions. + *

+ * This method is still a work in progress and may not yet fully replicate the + * default settings of Jackson 2.x. + *

+ */ + //@Override + public Builder configureForJackson2() { + //TODO call super.configureForJackson2() when available - https://github.com/FasterXML/jackson-databind/pull/5004 + return disable(XmlWriteFeature.WRITE_NULLS_AS_XSI_NIL) + .disable(XmlWriteFeature.UNWRAP_ROOT_OBJECT_NODE) + .disable(XmlWriteFeature.AUTO_DETECT_XSI_TYPE) + .disable(XmlWriteFeature.WRITE_XML_SCHEMA_CONFORMING_FLOATS); + } + /* /****************************************************************** /* XML specific additional config @@ -340,6 +357,19 @@ public static XmlMapper.Builder builder(XmlFactory streamFactory) { return new XmlMapper.Builder(streamFactory); } + /** + * The builder returned uses default settings more closely + * matching the default configs used in Jackson 2.x versions. + *

+ * This method is still a work in progress and may not yet fully replicate the + * default settings of Jackson 2.x. + *

+ */ + public static XmlMapper.Builder builderWithJackson2Defaults() { + return builder(XmlFactory.builderWithJackson2Defaults().build()) + .configureForJackson2(); + } + @SuppressWarnings("unchecked") @Override public XmlMapper.Builder rebuild() { diff --git a/src/test/java/tools/jackson/dataformat/xml/XmlMapperTest.java b/src/test/java/tools/jackson/dataformat/xml/XmlMapperTest.java new file mode 100644 index 00000000..9f6f386f --- /dev/null +++ b/src/test/java/tools/jackson/dataformat/xml/XmlMapperTest.java @@ -0,0 +1,40 @@ +package tools.jackson.dataformat.xml; + +import org.junit.jupiter.api.Test; +import tools.jackson.core.StreamReadFeature; +import tools.jackson.dataformat.xml.ser.ToXmlGenerator; + +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamWriter; + +import java.io.ByteArrayOutputStream; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +public class XmlMapperTest extends XmlTestUtil +{ + + @Test + public void testBuilderWithJackson2Defaults() throws Exception + { + XmlMapper mapper = XmlMapper.builderWithJackson2Defaults().build(); + assertFalse(mapper.isEnabled(StreamReadFeature.USE_FAST_DOUBLE_PARSER)); + assertFalse(mapper.isEnabled(StreamReadFeature.USE_FAST_BIG_NUMBER_PARSER)); + + XMLOutputFactory outputFactory = mapper.tokenStreamFactory().getXMLOutputFactory(); + try ( + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ToXmlGenerator gen = + mapper.createGenerator( + outputFactory.createXMLStreamWriter(bos)) + ) { + assertFalse(gen.isEnabled(XmlWriteFeature.WRITE_NULLS_AS_XSI_NIL)); + assertFalse(gen.isEnabled(XmlWriteFeature.UNWRAP_ROOT_OBJECT_NODE)); + assertFalse(gen.isEnabled(XmlWriteFeature.AUTO_DETECT_XSI_TYPE)); + assertFalse(gen.isEnabled(XmlWriteFeature.WRITE_XML_SCHEMA_CONFORMING_FLOATS)); + // need to write something to the generator to avoid exception + final Point p = new Point(1, 2); + mapper.writeValue(gen, p); + } + } +} From 397fa5a070cb64d7835f37bce5b8e3ce76c97b58 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Fri, 7 Mar 2025 00:42:15 +0100 Subject: [PATCH 2/6] Update XmlMapper.java --- src/main/java/tools/jackson/dataformat/xml/XmlMapper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java b/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java index cff9fe06..213b8eb5 100644 --- a/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java +++ b/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java @@ -245,8 +245,8 @@ public Builder configure(XmlWriteFeature feature, boolean state) */ //@Override public Builder configureForJackson2() { - //TODO call super.configureForJackson2() when available - https://github.com/FasterXML/jackson-databind/pull/5004 - return disable(XmlWriteFeature.WRITE_NULLS_AS_XSI_NIL) + return super.configureForJackson2() + .disable(XmlWriteFeature.WRITE_NULLS_AS_XSI_NIL) .disable(XmlWriteFeature.UNWRAP_ROOT_OBJECT_NODE) .disable(XmlWriteFeature.AUTO_DETECT_XSI_TYPE) .disable(XmlWriteFeature.WRITE_XML_SCHEMA_CONFORMING_FLOATS); From 7bddcd4a0133ff4d06c0ffd53626f0f9358741b7 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Fri, 7 Mar 2025 00:46:27 +0100 Subject: [PATCH 3/6] Update XmlFactoryBuilder.java --- .../java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java b/src/main/java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java index 1af4f57e..14516d2d 100644 --- a/src/main/java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java +++ b/src/main/java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java @@ -6,7 +6,6 @@ import tools.jackson.core.ErrorReportConfiguration; import tools.jackson.core.StreamReadConstraints; -import tools.jackson.core.StreamReadFeature; import tools.jackson.core.StreamWriteConstraints; import tools.jackson.core.base.DecorableTSFactory.DecorableTSFBuilder; From 4021d5342041dbf8c2eccf37a0217b34f80df8c2 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Fri, 7 Mar 2025 00:47:51 +0100 Subject: [PATCH 4/6] Update XmlMapper.java --- src/main/java/tools/jackson/dataformat/xml/XmlMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java b/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java index 213b8eb5..2bdf7202 100644 --- a/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java +++ b/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java @@ -243,7 +243,7 @@ public Builder configure(XmlWriteFeature feature, boolean state) * default settings of Jackson 2.x. *

*/ - //@Override + @Override public Builder configureForJackson2() { return super.configureForJackson2() .disable(XmlWriteFeature.WRITE_NULLS_AS_XSI_NIL) From 54846c4e4d20e3a11b236588c8eb6bdbed2dce6b Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Fri, 7 Mar 2025 01:05:23 +0100 Subject: [PATCH 5/6] read feature --- .../tools/jackson/dataformat/xml/XmlMapper.java | 3 ++- .../dataformat/xml/deser/FromXmlParser.java | 5 +++++ .../jackson/dataformat/xml/XmlMapperTest.java | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java b/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java index 2bdf7202..01d0c052 100644 --- a/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java +++ b/src/main/java/tools/jackson/dataformat/xml/XmlMapper.java @@ -249,7 +249,8 @@ public Builder configureForJackson2() { .disable(XmlWriteFeature.WRITE_NULLS_AS_XSI_NIL) .disable(XmlWriteFeature.UNWRAP_ROOT_OBJECT_NODE) .disable(XmlWriteFeature.AUTO_DETECT_XSI_TYPE) - .disable(XmlWriteFeature.WRITE_XML_SCHEMA_CONFORMING_FLOATS); + .disable(XmlWriteFeature.WRITE_XML_SCHEMA_CONFORMING_FLOATS) + .disable(XmlReadFeature.AUTO_DETECT_XSI_TYPE); } /* diff --git a/src/main/java/tools/jackson/dataformat/xml/deser/FromXmlParser.java b/src/main/java/tools/jackson/dataformat/xml/deser/FromXmlParser.java index 44e7d490..73f6f0b5 100644 --- a/src/main/java/tools/jackson/dataformat/xml/deser/FromXmlParser.java +++ b/src/main/java/tools/jackson/dataformat/xml/deser/FromXmlParser.java @@ -19,6 +19,7 @@ import tools.jackson.core.io.NumberInput; import tools.jackson.core.util.ByteArrayBuilder; import tools.jackson.core.util.JacksonFeatureSet; +import tools.jackson.dataformat.xml.XmlWriteFeature; import tools.jackson.dataformat.xml.util.CaseInsensitiveNameSet; import tools.jackson.dataformat.xml.util.StaxUtil; @@ -283,6 +284,10 @@ public void addVirtualWrapping(Set namesToWrap0, boolean caseInsensitive _streamReadContext.setNamesToWrap(namesToWrap); } + public final boolean isEnabled(XmlReadFeature f) { + return (_formatFeatures & f.getMask()) != 0; + } + /* /********************************************************************** /* JsonParser impl, closing etc diff --git a/src/test/java/tools/jackson/dataformat/xml/XmlMapperTest.java b/src/test/java/tools/jackson/dataformat/xml/XmlMapperTest.java index 9f6f386f..1160a192 100644 --- a/src/test/java/tools/jackson/dataformat/xml/XmlMapperTest.java +++ b/src/test/java/tools/jackson/dataformat/xml/XmlMapperTest.java @@ -2,12 +2,15 @@ import org.junit.jupiter.api.Test; import tools.jackson.core.StreamReadFeature; +import tools.jackson.dataformat.xml.deser.FromXmlParser; import tools.jackson.dataformat.xml.ser.ToXmlGenerator; +import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; -import javax.xml.stream.XMLStreamWriter; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -36,5 +39,16 @@ public void testBuilderWithJackson2Defaults() throws Exception final Point p = new Point(1, 2); mapper.writeValue(gen, p); } + + final byte[] xml = "".getBytes(StandardCharsets.UTF_8); + XMLInputFactory inputFactory = mapper.tokenStreamFactory().getXMLInputFactory(); + try ( + ByteArrayInputStream bis = new ByteArrayInputStream(xml); + FromXmlParser parser = + mapper.createParser( + inputFactory.createXMLStreamReader(bis)) + ) { + assertFalse(parser.isEnabled(XmlReadFeature.AUTO_DETECT_XSI_TYPE)); + } } } From 2e57b03b2405616cebf6855d8f136b0682b86b5b Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Fri, 7 Mar 2025 01:07:48 +0100 Subject: [PATCH 6/6] Update XmlFactoryBuilder.java --- .../dataformat/xml/XmlFactoryBuilder.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/main/java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java b/src/main/java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java index 14516d2d..5f5c01cd 100644 --- a/src/main/java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java +++ b/src/main/java/tools/jackson/dataformat/xml/XmlFactoryBuilder.java @@ -222,23 +222,6 @@ public XmlFactoryBuilder configure(XmlWriteFeature f, boolean state) { return state ? enable(f) : disable(f); } - /** - * The builder returned uses default settings more closely - * matching the default configs used in Jackson 2.x versions. - *

- * This method is still a work in progress and may not yet fully replicate the - * default settings of Jackson 2.x. - *

- */ - @Override - public XmlFactoryBuilder configureForJackson2() { - return super.configureForJackson2() - .disable(XmlWriteFeature.WRITE_NULLS_AS_XSI_NIL) - .disable(XmlWriteFeature.UNWRAP_ROOT_OBJECT_NODE) - .disable(XmlWriteFeature.AUTO_DETECT_XSI_TYPE) - .disable(XmlWriteFeature.WRITE_XML_SCHEMA_CONFORMING_FLOATS); - } - // // // Other config public XmlFactoryBuilder nameForTextElement(String name) {