Skip to content

Commit 8e722bb

Browse files
committed
Merge branch '2.12' into 2.13
2 parents d9e559a + b8b81d7 commit 8e722bb

File tree

4 files changed

+173
-3
lines changed

4 files changed

+173
-3
lines changed

release-notes/VERSION-2.x

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Project: jackson-dataformat-xml
2020

2121
#469: Empty tags cause incorrect deserialization of unwrapped lists
2222
(reported by jackson-code1@github)
23+
#473: Parsing of `null` Integer fields changed behavior between versions
24+
2.11.4 and 2.12.X
25+
(reported by Steviep@github)
2326

2427
2.12.3 (12-Apr-2021)
2528

src/main/java/com/fasterxml/jackson/dataformat/xml/XmlMapper.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.fasterxml.jackson.databind.deser.BeanDeserializerFactory;
1717
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
1818
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
19+
import com.fasterxml.jackson.databind.type.LogicalType;
1920
import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser;
2021
import com.fasterxml.jackson.dataformat.xml.deser.XmlDeserializationContext;
2122
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
@@ -177,7 +178,15 @@ public XmlMapper(XmlFactory xmlFactory, JacksonXmlModule module)
177178
.setAcceptBlankAsEmpty(Boolean.TRUE)
178179
// and then coercion from empty String to empty value, in general
179180
.setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty)
180-
;
181+
;
182+
// 03-May-2021, tatu: ... except make sure to keep "empty to Null" for
183+
// scalar types...
184+
coercionConfigFor(LogicalType.Integer)
185+
.setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsNull);
186+
coercionConfigFor(LogicalType.Float)
187+
.setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsNull);
188+
coercionConfigFor(LogicalType.Boolean)
189+
.setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsNull);
181190
}
182191

183192
/**

src/test/java/com/fasterxml/jackson/dataformat/xml/deser/EmptyStringValueTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ static class Product427 {
4949
}
5050

5151
/*
52-
/**********************************************************
52+
/**********************************************************************
5353
/* Test methods
54-
/**********************************************************
54+
/**********************************************************************
5555
*/
5656

5757
private final XmlMapper MAPPER = newMapper();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package com.fasterxml.jackson.dataformat.xml.deser;
2+
3+
import java.math.BigDecimal;
4+
import java.math.BigInteger;
5+
6+
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
7+
import com.fasterxml.jackson.dataformat.xml.XmlTestBase;
8+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
9+
10+
// [dataformat-xml#473]: 2.11 -> 2.12 coercion of empty to "default"
11+
// [dataformat-xml#474]: no failure for primitives, no null
12+
public class EmptyWithScalarsTest extends XmlTestBase
13+
{
14+
@JacksonXmlRootElement(localName = "w")
15+
static class NumbersPrimitive {
16+
public int i = 1;
17+
public long l = 2L;
18+
19+
public double d = 0.5;
20+
public float f = 0.25f;
21+
}
22+
23+
@JacksonXmlRootElement(localName = "w")
24+
static class NumbersWrapper {
25+
public Integer I = Integer.valueOf(1);
26+
public Long L = Long.valueOf(1L);
27+
28+
public Double D = Double.valueOf(0.5);
29+
public Float F = Float.valueOf(0.5f);
30+
}
31+
32+
@JacksonXmlRootElement(localName = "w")
33+
static class NumbersOther {
34+
public BigInteger bi = BigInteger.ONE;
35+
public BigDecimal bd = BigDecimal.ONE;
36+
}
37+
38+
@JacksonXmlRootElement(localName = "w")
39+
static class MiscOther {
40+
public Boolean B = Boolean.TRUE;
41+
}
42+
43+
private final XmlMapper MAPPER = newMapper();
44+
45+
/*
46+
/**********************************************************************
47+
/* Test methods, Numbers / primitive
48+
/**********************************************************************
49+
*/
50+
51+
public void testPrimitiveIntsWithEmpty() throws Exception
52+
{
53+
NumbersPrimitive p = MAPPER.readValue(_emptyWrapped("i"),
54+
NumbersPrimitive.class);
55+
assertEquals(0, p.i);
56+
p = MAPPER.readValue(_emptyWrapped("l"),
57+
NumbersPrimitive.class);
58+
assertEquals(0L, p.l);
59+
}
60+
61+
public void testPrimitiveFPsWithEmpty() throws Exception
62+
{
63+
NumbersPrimitive p = MAPPER.readValue(_emptyWrapped("d"),
64+
NumbersPrimitive.class);
65+
assertEquals(0d, p.d);
66+
p = MAPPER.readValue(_emptyWrapped("f"),
67+
NumbersPrimitive.class);
68+
assertEquals(0f, p.f);
69+
}
70+
71+
// [dataformat-xml#474]: no failure for primitives, no null
72+
// (will try to fix in 2.13, but not 2.12)
73+
public void testPrimitivesNoNulls() throws Exception
74+
{
75+
/*
76+
ObjectReader r = MAPPER
77+
.readerFor(NumbersPrimitive.class)
78+
.with(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
79+
_testPrimitivesNoNulls(r, _emptyWrapped("i"));
80+
_testPrimitivesNoNulls(r, _emptyWrapped("l"));
81+
_testPrimitivesNoNulls(r, _emptyWrapped("d"));
82+
_testPrimitivesNoNulls(r, _emptyWrapped("f"));
83+
}
84+
85+
private void _testPrimitivesNoNulls(ObjectReader r, String doc) throws Exception
86+
{
87+
try {
88+
r.readValue(_emptyWrapped("i"));
89+
fail("Should not pass");
90+
} catch (MismatchedInputException e) {
91+
verifyException(e, "Cannot coerce empty String");
92+
}
93+
*/
94+
}
95+
96+
/*
97+
/**********************************************************************
98+
/* Test methods, Numbers / wrapper (or Object)
99+
/**********************************************************************
100+
*/
101+
102+
public void testIntegralsWithEmpty() throws Exception
103+
{
104+
NumbersWrapper w = MAPPER.readValue(_emptyWrapped("I"),
105+
NumbersWrapper.class);
106+
assertNull(w.I);
107+
w = MAPPER.readValue(_emptyWrapped("L"),
108+
NumbersWrapper.class);
109+
assertNull(w.L);
110+
111+
NumbersOther o = MAPPER.readValue(_emptyWrapped("bi"),
112+
NumbersOther.class);
113+
assertNull(o.bi);
114+
}
115+
116+
public void testFPWithEmpty() throws Exception
117+
{
118+
NumbersWrapper w = MAPPER.readValue(_emptyWrapped("D"),
119+
NumbersWrapper.class);
120+
assertNull(w.D);
121+
w = MAPPER.readValue(_emptyWrapped("F"),
122+
NumbersWrapper.class);
123+
assertNull(w.F);
124+
125+
NumbersOther o = MAPPER.readValue(_emptyWrapped("bd"),
126+
NumbersOther.class);
127+
assertNull(o.bd);
128+
}
129+
130+
/*
131+
/**********************************************************************
132+
/* Test methods, otber Scalars
133+
/**********************************************************************
134+
*/
135+
136+
public void testOtherScalarWithEmpty() throws Exception
137+
{
138+
MiscOther o = MAPPER.readValue(_emptyWrapped("B"),
139+
MiscOther.class);
140+
assertNull(o.B);
141+
}
142+
143+
/*
144+
/**********************************************************************
145+
/* Internal methods
146+
/**********************************************************************
147+
*/
148+
149+
private String _emptyWrapped(String name) {
150+
return _simpleWrapped(name, "");
151+
}
152+
153+
private String _simpleWrapped(String name, String value) {
154+
return "<w>\n"
155+
+"<"+name+">"+value+"</"+name+">\n"
156+
+"</w>\n";
157+
}
158+
}

0 commit comments

Comments
 (0)