Skip to content

Commit 3997aec

Browse files
committed
Fix #451
1 parent f199076 commit 3997aec

File tree

3 files changed

+52
-24
lines changed

3 files changed

+52
-24
lines changed

release-notes/VERSION-2.x

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

99
#445: `XmlMapper`/`UntypedObjectDeserializer` mixes multiple unwrapped collections
1010
(fix contributed by Migwel@github)
11+
#451: Xml type resolver fails with NPE when property name is not specified in
12+
polymorphic (de)serialization
13+
(reported by MichalStehlikCz@github)
1114

1215
2.12.1 (08-Jan-2021)
1316

src/main/java/com/fasterxml/jackson/dataformat/xml/util/StaxUtil.java

+6
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ private static String _message(Throwable t1, Throwable t2) {
7575
*/
7676
public static String sanitizeXmlTypeName(String name)
7777
{
78+
// [dataformat-xml#451]: with DEDUCTION, at least, won't have property name
79+
// (but probably sensible to check for it anyway)
80+
if (name == null) {
81+
return null;
82+
}
83+
7884
StringBuilder sb;
7985
int changes = 0;
8086
// First things first: remove array types' trailing[]...

src/test/java/com/fasterxml/jackson/dataformat/xml/misc/PolymorphicTypesTest.java

+43-24
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33
import java.util.ArrayList;
44
import java.util.List;
55

6+
import com.fasterxml.jackson.annotation.JsonCreator;
67
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
8+
import com.fasterxml.jackson.annotation.JsonProperty;
9+
import com.fasterxml.jackson.annotation.JsonSubTypes;
710
import com.fasterxml.jackson.annotation.JsonTypeInfo;
811
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
12+
913
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
1014
import com.fasterxml.jackson.dataformat.xml.XmlTestBase;
1115

@@ -47,30 +51,35 @@ public Wrapper(){}
4751
public Wrapper(List<TypeWithClassPropertyAndObjectId> data) { this.data = data; }
4852
}
4953

50-
/*
51-
/**********************************************************
52-
/* Set up
53-
/**********************************************************
54-
*/
54+
// [dataformat-xml#451]
55+
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
56+
@JsonSubTypes(@JsonSubTypes.Type(Child451.class))
57+
public interface Value451 {}
5558

56-
protected XmlMapper _xmlMapper;
59+
public static class Child451 implements Value451 {
60+
private final String property1;
5761

58-
// let's actually reuse XmlMapper to make things bit faster
59-
@Override
60-
public void setUp() throws Exception {
61-
super.setUp();
62-
_xmlMapper = new XmlMapper();
63-
}
62+
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
63+
public Child451(@JsonProperty("property1") String property1) {
64+
this.property1 = property1;
65+
}
66+
67+
public String getProperty1() {
68+
return property1;
69+
}
70+
}
6471

6572
/*
66-
/**********************************************************
67-
/* Unit tests
68-
/**********************************************************
73+
/**********************************************************************
74+
/* Test methods
75+
/**********************************************************************
6976
*/
7077

78+
private final XmlMapper MAPPER = newMapper();
79+
7180
public void testAsClassProperty() throws Exception
7281
{
73-
String xml = _xmlMapper.writeValueAsString(new SubTypeWithClassProperty("Foobar"));
82+
String xml = MAPPER.writeValueAsString(new SubTypeWithClassProperty("Foobar"));
7483

7584
// Type info should be written as an attribute, so:
7685
final String exp =
@@ -80,36 +89,46 @@ public void testAsClassProperty() throws Exception
8089
;
8190
assertEquals(exp, xml);
8291

83-
Object result = _xmlMapper.readValue(xml, BaseTypeWithClassProperty.class);
92+
Object result = MAPPER.readValue(xml, BaseTypeWithClassProperty.class);
8493
assertNotNull(result);
8594
assertEquals(SubTypeWithClassProperty.class, result.getClass());
8695
assertEquals("Foobar", ((SubTypeWithClassProperty) result).name);
8796
}
8897

8998
public void testAsClassObject() throws Exception
9099
{
91-
String xml = _xmlMapper.writeValueAsString(new SubTypeWithClassObject("Foobar"));
92-
Object result = _xmlMapper.readValue(xml, BaseTypeWithClassObject.class);
100+
String xml = MAPPER.writeValueAsString(new SubTypeWithClassObject("Foobar"));
101+
Object result = MAPPER.readValue(xml, BaseTypeWithClassObject.class);
93102
assertNotNull(result);
94103
assertEquals(SubTypeWithClassObject.class, result.getClass());
95104
assertEquals("Foobar", ((SubTypeWithClassObject) result).name);
96105
}
97106

98-
/**
99-
* Test for [dataformat-xml#81]
100-
*/
107+
// Test for [dataformat-xml#81]
101108
public void testAsPropertyWithObjectId() throws Exception
102109
{
103110
List<TypeWithClassPropertyAndObjectId> data = new ArrayList<PolymorphicTypesTest.TypeWithClassPropertyAndObjectId>();
104111
TypeWithClassPropertyAndObjectId object = new TypeWithClassPropertyAndObjectId("Foobar");
105112
data.add(object);
106113
// This will be written as an id reference instead of object; as such, no type info will be written.
107114
data.add(object);
108-
String xml = _xmlMapper.writeValueAsString(new Wrapper(data));
109-
Wrapper result = _xmlMapper.readValue(xml, Wrapper.class);
115+
String xml = MAPPER.writeValueAsString(new Wrapper(data));
116+
Wrapper result = MAPPER.readValue(xml, Wrapper.class);
110117
assertNotNull(result);
111118
assertSame(result.data.get(0), result.data.get(1));
112119
assertEquals("Foobar", result.data.get(0).id);
113120
}
121+
122+
// Test for [dataformat-xml#451]
123+
public void testDeduction() throws Exception
124+
{
125+
String xml = MAPPER.writeValueAsString(new Child451("value1"));
126+
assertTrue(xml.contains("<property1>value1</property1>"));
127+
128+
// and try reading back for funsies
129+
Value451 result = MAPPER.readValue(xml, Value451.class);
130+
assertNotNull(result);
131+
assertEquals(Child451.class, result.getClass());
132+
}
114133
}
115134

0 commit comments

Comments
 (0)