From fcdc96d75f57abbd399e2041f1722ad689af9c13 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Sat, 6 Jun 2020 14:58:48 -0700 Subject: [PATCH] Fixed #314 and #390 (same root cause) --- release-notes/CREDITS-2.x | 15 ++- release-notes/VERSION-2.x | 5 + .../dataformat/xml/deser/FromXmlParser.java | 3 +- .../dataformat/xml/deser/XmlTokenStream.java | 8 +- .../xml/failing/ListDeser314Test.java | 83 -------------- .../xml/failing/ListDeser390Test.java | 51 --------- ....java => ListWithAttributesDeserTest.java} | 103 +++++++++++++++++- 7 files changed, 127 insertions(+), 141 deletions(-) delete mode 100644 src/test/java/com/fasterxml/jackson/dataformat/xml/failing/ListDeser314Test.java delete mode 100644 src/test/java/com/fasterxml/jackson/dataformat/xml/failing/ListDeser390Test.java rename src/test/java/com/fasterxml/jackson/dataformat/xml/lists/{ListWithAttributes.java => ListWithAttributesDeserTest.java} (58%) diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index 05fc4abf2..0ea597e3f 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -92,12 +92,23 @@ Joseph Petersen (jetersen@github) * Reported #273: Input mismatch with case-insensitive properties (2.12.0) -Ghenadii Batalski (ghenadiibatalski@github) +Eduard Wirch (ewirch@github) -* Reported #377: `ToXmlGenerator` ignores `Base64Variant` while serializing `byte[]` +* Reported #314: Jackson gets confused by parent list element (2.12.0) Jochen Schalanda (joschi@github) * Reported #318: XMLMapper fails to deserialize null (POJO reference) from blank tag (2.12.0) + +Ghenadii Batalski (ghenadiibatalski@github) + +* Reported #377: `ToXmlGenerator` ignores `Base64Variant` while serializing `byte[]` + (2.12.0) + +David Schmidt (d-schmidt@github) + +* Reported #390: Unexpected attribute at string fields causes extra objects to be + created in parent list + (2.12.0) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 0bc1879b2..2bf13f525 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -17,12 +17,17 @@ Project: jackson-dataformat-xml (requested by Dave J) #273: Input mismatch with case-insensitive properties (reported by Joseph P) +#314: Jackson gets confused by parent list element + (reported by Eduard W) #318: XMLMapper fails to deserialize null (POJO reference) from blank tag (reported by Jochen S) #319: Empty root tag into `List` deserialization bug (reported by Seatec13@github) #377: `ToXmlGenerator` ignores `Base64Variant` while serializing `byte[]` (reported by Ghenadii B) +#390: Unexpected attribute at string fields causes extra objects to be + created in parent list + (reported by David S #397: `XmlReadContext` does not keep track of array index #403: Make `JsonNode` implicitly create `ArrayNode`s for repeated XML Elements #405: Mixed content not exposed through `FromXmlParser`, lost by `JsonNode` diff --git a/src/main/java/com/fasterxml/jackson/dataformat/xml/deser/FromXmlParser.java b/src/main/java/com/fasterxml/jackson/dataformat/xml/deser/FromXmlParser.java index 8918621dc..163f8a5ea 100644 --- a/src/main/java/com/fasterxml/jackson/dataformat/xml/deser/FromXmlParser.java +++ b/src/main/java/com/fasterxml/jackson/dataformat/xml/deser/FromXmlParser.java @@ -490,7 +490,7 @@ public boolean isExpectedStartArrayToken() _xmlTokens.skipAttributes(); return true; } -//System.out.println(" isExpectedArrayStart?: t="+t); +//System.out.println(" FromXmlParser.isExpectedArrayStart?: t="+t); return (t == JsonToken.START_ARRAY); } @@ -887,6 +887,7 @@ public String getValueAsString(String defValue) throws IOException _nextToken = null; // One more thing: must explicitly skip the END_OBJECT that would follow _skipEndElement(); +//System.out.println(" FromXmlParser.getValueAsString() on START_OBJECT, str == '"+str+"'"); return (_currText = str); } } catch (XMLStreamException e) { diff --git a/src/main/java/com/fasterxml/jackson/dataformat/xml/deser/XmlTokenStream.java b/src/main/java/com/fasterxml/jackson/dataformat/xml/deser/XmlTokenStream.java index 03857feb8..b5eafd779 100644 --- a/src/main/java/com/fasterxml/jackson/dataformat/xml/deser/XmlTokenStream.java +++ b/src/main/java/com/fasterxml/jackson/dataformat/xml/deser/XmlTokenStream.java @@ -358,9 +358,11 @@ protected String convertToString() throws XMLStreamException if (text == null) { text = ""; } - if (_currentWrapper != null) { - _currentWrapper = _currentWrapper.getParent(); - } + // 06-Jun-2020, tatu: As per [dataformat-xml#390], doing this is wrong, + // should not (at least always?) assume we need it +// if (_currentWrapper != null) { +// _currentWrapper = _currentWrapper.getParent(); +// } // just for diagnostics, reset to element name (from first attribute name) _localName = _xmlReader.getLocalName(); _namespaceURI = _xmlReader.getNamespaceURI(); diff --git a/src/test/java/com/fasterxml/jackson/dataformat/xml/failing/ListDeser314Test.java b/src/test/java/com/fasterxml/jackson/dataformat/xml/failing/ListDeser314Test.java deleted file mode 100644 index 799b4a2c7..000000000 --- a/src/test/java/com/fasterxml/jackson/dataformat/xml/failing/ListDeser314Test.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.fasterxml.jackson.dataformat.xml.failing; - -import java.util.*; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; - -import com.fasterxml.jackson.dataformat.xml.XmlTestBase; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText; - -// [dataformat-xml#314] -public class ListDeser314Test extends XmlTestBase -{ - static class Customer314 { - @JacksonXmlElementWrapper(localName = "Customer", useWrapping = false) - @JacksonXmlProperty(localName = "Address") - public List address; - } - - static class Address314 { - public String stateProv; - public CountryName314 countryName; - } - - static class CountryName314 { - public String code; - @JacksonXmlText - public String name; - } - - /* - /******************************************************** - /* Test methods - /******************************************************** - */ - - private final ObjectMapper MAPPER = mapperBuilder() - .propertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE) - .build(); - - // [dataformat-xml#314] - public void testDeser314Order1() throws Exception - { - String content = "" - + "\n" - + "
\n" - + " Niedersachsen\n" - + " Deutschland\n" - + "
\n" - + "
" - ; - Customer314 result = MAPPER.readValue(content, Customer314.class); - assertNotNull(result); - } -/* - public void testDeser314Order2() throws Exception - { - String content = "" - + "\n" - + "
\n" - + " Deutschland\n" - + " Niedersachsen\n" - + "
\n" - + "
" - ; - Customer314 result = MAPPER.readValue(content, Customer314.class); - assertNotNull(result); - } - - public void testDeser314Address() throws Exception - { - String content = "" - + "
\n" - + " Deutschland\n" - + " Niedersachsen\n" - + "
\n" - ; - Address314 result = MAPPER.readValue(content, Address314.class); - assertNotNull(result); - }*/ -} diff --git a/src/test/java/com/fasterxml/jackson/dataformat/xml/failing/ListDeser390Test.java b/src/test/java/com/fasterxml/jackson/dataformat/xml/failing/ListDeser390Test.java deleted file mode 100644 index 45693cce0..000000000 --- a/src/test/java/com/fasterxml/jackson/dataformat/xml/failing/ListDeser390Test.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.fasterxml.jackson.dataformat.xml.failing; - -import java.util.List; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.xml.XmlTestBase; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; - -public class ListDeser390Test extends XmlTestBase -{ - - @JacksonXmlRootElement(localName = "many") - static class Many390 { - @JacksonXmlProperty(localName = "one") - @JacksonXmlElementWrapper(useWrapping = false) - List ones; - } - - static class One390 { - @JacksonXmlProperty - String value; - @JacksonXmlProperty - String another; - } - - /* - /******************************************************** - /* Test methods - /******************************************************** - */ - - private final ObjectMapper MAPPER = newMapper(); - - // [dataformat-xml#390] - public void testDeser390() throws Exception - { - String XML = "\n" - + " \n" - + " foo\n" - + " \n" - + " \n" - + ""; - Many390 many = MAPPER.readValue(XML, Many390.class); - assertNotNull(many.ones); - -//System.err.println("XML:\n"+MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(many)); - assertEquals(1, many.ones.size()); - } -} diff --git a/src/test/java/com/fasterxml/jackson/dataformat/xml/lists/ListWithAttributes.java b/src/test/java/com/fasterxml/jackson/dataformat/xml/lists/ListWithAttributesDeserTest.java similarity index 58% rename from src/test/java/com/fasterxml/jackson/dataformat/xml/lists/ListWithAttributes.java rename to src/test/java/com/fasterxml/jackson/dataformat/xml/lists/ListWithAttributesDeserTest.java index 398821119..5b85ee463 100644 --- a/src/test/java/com/fasterxml/jackson/dataformat/xml/lists/ListWithAttributes.java +++ b/src/test/java/com/fasterxml/jackson/dataformat/xml/lists/ListWithAttributesDeserTest.java @@ -4,11 +4,13 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; + import com.fasterxml.jackson.databind.*; + import com.fasterxml.jackson.dataformat.xml.*; import com.fasterxml.jackson.dataformat.xml.annotation.*; -public class ListWithAttributes extends XmlTestBase +public class ListWithAttributesDeserTest extends XmlTestBase { // [dataformat-xml#43] static class Name { @@ -79,6 +81,43 @@ static class ChildB301 { public Double value; } + // [dataformat-xml#314] + static class Customer314 { + @JacksonXmlElementWrapper(localName = "Customer", useWrapping = false) + @JacksonXmlProperty(localName = "Address") + public List address; + } + + static class Address314 { + public String stateProv; + public CountryName314 countryName; + } + + static class CountryName314 { + public String code; + @JacksonXmlText + public String name; + } + + // [dataformat-xml#390] + @JacksonXmlRootElement(localName = "many") + static class Many390 { + @JacksonXmlProperty(localName = "one") + @JacksonXmlElementWrapper(useWrapping = false) + List ones; + } + + static class One390 { + @JacksonXmlProperty + String value; + @JacksonXmlProperty + String another; + + public void setAnother(String s) { + another = s; + } + } + /* /********************************************************** /* Test methods @@ -87,6 +126,10 @@ static class ChildB301 { private final ObjectMapper MAPPER = newMapper(); + private final ObjectMapper UPPER_CASE_MAPPER = mapperBuilder() + .propertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE) + .build(); + // [dataformat-xml#43] public void testIssue43() throws Exception { @@ -142,5 +185,63 @@ public void testIssue301WithAttr() throws Exception { assertEquals(1, result.childrenB.size()); assertEquals(Double.valueOf(12.25), result.childrenB.get(0).value); } + + // [dataformat-xml#314] + public void testDeser314Order1() throws Exception + { + String content = "" + + "\n" + + "
\n" + + " Niedersachsen\n" + + " Deutschland\n" + + "
\n" + + "
" + ; + Customer314 result = UPPER_CASE_MAPPER.readValue(content, Customer314.class); + assertNotNull(result); + } + + public void testDeser314Order2() throws Exception + { + String content = "" + + "\n" + + "
\n" + + " Deutschland\n" + + " Niedersachsen\n" + + "
\n" + + "
" + ; + Customer314 result = UPPER_CASE_MAPPER.readValue(content, Customer314.class); + assertNotNull(result); + } + + public void testDeser314Address() throws Exception + { + String content = "" + + "
\n" + + " Deutschland\n" + + " Niedersachsen\n" + + "
\n" + ; + Address314 result = UPPER_CASE_MAPPER.readValue(content, Address314.class); + assertNotNull(result); + } + + // [dataformat-xml#390] + public void testDeser390() throws Exception + { + String XML = "\n" + + " \n" + + " foo\n" + + " stuff\n" + + " \n" + + ""; + Many390 many = MAPPER.readValue(XML, Many390.class); + assertNotNull(many.ones); +//System.err.println("XML:\n"+MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(many)); + assertEquals(1, many.ones.size()); + assertEquals("foo", many.ones.get(0).value); + assertEquals("stuff", many.ones.get(0).another); + } }