diff --git a/src/main/java/tools/jackson/dataformat/xml/deser/XmlTextDeserializer.java b/src/main/java/tools/jackson/dataformat/xml/deser/XmlTextDeserializer.java index ed0cbced0..3e056c697 100644 --- a/src/main/java/tools/jackson/dataformat/xml/deser/XmlTextDeserializer.java +++ b/src/main/java/tools/jackson/dataformat/xml/deser/XmlTextDeserializer.java @@ -4,6 +4,7 @@ import tools.jackson.databind.*; import tools.jackson.databind.deser.*; import tools.jackson.databind.deser.bean.BeanDeserializerBase; +import tools.jackson.databind.deser.bean.BuilderBasedDeserializer; import tools.jackson.databind.deser.std.DelegatingDeserializer; import tools.jackson.databind.jsontype.TypeDeserializer; import tools.jackson.databind.util.TokenBuffer; @@ -33,6 +34,12 @@ public class XmlTextDeserializer protected final ValueInstantiator _valueInstantiator; + /** + * A flag indicating the ValueInstantiator.createUsingDefault() + * will return an instance (and specifically not a builder) + */ + protected final boolean _canCreateUsingDefault; + /* /********************************************************************** /* Construction @@ -51,6 +58,8 @@ public XmlTextDeserializer(BeanDeserializerBase delegate, SettableBeanProperty p _xmlTextProperty = prop; _xmlTextPropertyIndex = prop.getPropertyIndex(); _valueInstantiator = delegate.getValueInstantiator(); + _canCreateUsingDefault = _valueInstantiator.canCreateUsingDefault() && + !(delegate instanceof BuilderBasedDeserializer); } /** @@ -65,6 +74,8 @@ public XmlTextDeserializer(BeanDeserializerBase delegate, int textPropIndex) _xmlTextPropertyIndex = textPropIndex; _valueInstantiator = delegate.getValueInstantiator(); _xmlTextProperty = delegate.findProperty(textPropIndex); + _canCreateUsingDefault = _valueInstantiator.canCreateUsingDefault() && + !(delegate instanceof BuilderBasedDeserializer); } /** @@ -82,6 +93,8 @@ public XmlTextDeserializer(ValueDeserializer delegate, _xmlTextPropertyIndex = textPropIndex; _valueInstantiator = inner.getValueInstantiator(); _xmlTextProperty = inner.findProperty(textPropIndex); + _canCreateUsingDefault = _valueInstantiator.canCreateUsingDefault() && + !(inner instanceof BuilderBasedDeserializer); } /* @@ -122,7 +135,7 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt) throws JacksonException { if (p.currentToken() == JsonToken.VALUE_STRING) { - if (_valueInstantiator.canCreateUsingDefault()) { + if (_canCreateUsingDefault) { Object bean = _valueInstantiator.createUsingDefault(ctxt); _xmlTextProperty.deserializeAndSet(p, ctxt, bean); return bean; diff --git a/src/test/java/tools/jackson/dataformat/xml/deser/builder/BuilderWithTextValueTest.java b/src/test/java/tools/jackson/dataformat/xml/deser/builder/BuilderWithTextValueTest.java new file mode 100644 index 000000000..cffeb3158 --- /dev/null +++ b/src/test/java/tools/jackson/dataformat/xml/deser/builder/BuilderWithTextValueTest.java @@ -0,0 +1,104 @@ +package tools.jackson.dataformat.xml.deser.builder; + + +import org.junit.jupiter.api.Test; + + +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonPOJOBuilder; + +import tools.jackson.dataformat.xml.XmlMapper; +import tools.jackson.dataformat.xml.XmlTestUtil; +import tools.jackson.dataformat.xml.annotation.*; + +import static org.junit.jupiter.api.Assertions.*; + +public class BuilderWithTextValueTest extends XmlTestUtil +{ + @JsonDeserialize(builder = Outer.OuterBuilder.class) + public static class Outer { + + final Inner inner; + + final String title; + + private Outer(Inner inner, String title) { + this.inner = inner; + this.title = title; + } + + public static OuterBuilder builder() { + return new OuterBuilder(); + } + + @JsonPOJOBuilder(withPrefix = "") + public static class OuterBuilder { + private Inner inner; + private String title; + + @JacksonXmlProperty(localName = "Inner") + public OuterBuilder inner(Inner inner) { + this.inner = inner; + return this; + } + + @JacksonXmlProperty(localName = "Title") + public OuterBuilder title(String title) { + this.title = title; + return this; + } + + public Outer build() { + return new Outer(inner, title); + } + } + } + + @JsonDeserialize(builder = Inner.InnerBuilder.class) + public static class Inner { + + final String value; + + final String title; + + private Inner(String value, String title) { + this.value = value; + this.title = title; + } + + public static InnerBuilder builder() { + return new InnerBuilder(); + } + + @JsonPOJOBuilder(withPrefix = "") + public static class InnerBuilder { + private String value; + private String title; + + @JacksonXmlText + public InnerBuilder value(String value) { + this.value = value; + return this; + } + + @JacksonXmlProperty(isAttribute = true) + public InnerBuilder title(String title) { + this.title = title; + return this; + } + + public Inner build() { + return new Inner(value, title); + } + } + } + + @Test + public void testNestedBuilderWithTextValue() throws Exception + { + XmlMapper mapper = XmlMapper.builder().build(); + final String XML = "Value"; + Outer outer = mapper.readValue(XML, Outer.class); + assertEquals("Value", outer.inner.value); + } +}