Skip to content

Commit 7749b6f

Browse files
committed
Fixed #191
1 parent 24a10ce commit 7749b6f

File tree

5 files changed

+85
-74
lines changed

5 files changed

+85
-74
lines changed

release-notes/VERSION

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@ Project: jackson-dataformat-xml
66

77
2.7.4 (not yet released)
88

9+
#178: Problem with polymorphic serialization, inclusion type of
10+
`As.WRAPPER_OBJECT`, extra tag
911
#190: Ensure that defaults for `XMLInputFactory` have expansion of external
10-
parsed general entities disabled
12+
parsed general entities disabled
13+
#191: Strange behaviour of an empty item (but with whitespace between
14+
start/end tags) in List
15+
(reported by Hronom@github)
1116

1217
2.7.3 (16-Mar-2016)
1318

src/main/java/com/fasterxml/jackson/dataformat/xml/deser/FromXmlParser.java

Lines changed: 68 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ public boolean isExpectedStartArrayToken()
425425
}
426426

427427
// DEBUGGING
428-
/*
428+
/*
429429
@Override
430430
public JsonToken nextToken() throws IOException
431431
{
@@ -444,8 +444,11 @@ public JsonToken nextToken() throws IOException
444444
}
445445
return t;
446446
}
447-
*/
448447
448+
// public JsonToken nextToken0() throws IOException
449+
*/
450+
451+
449452
@Override
450453
public JsonToken nextToken() throws IOException
451454
{
@@ -509,81 +512,79 @@ public JsonToken nextToken() throws IOException
509512
}
510513

511514
// Ok; beyond start element, what do we get?
512-
switch (token) {
513-
case XmlTokenStream.XML_END_ELEMENT:
514-
// Simple, except that if this is a leaf, need to suppress end:
515-
if (_mayBeLeaf) {
516-
_mayBeLeaf = false;
517-
if (_parsingContext.inArray()) {
518-
// 06-Jan-2015, tatu: as per [dataformat-xml#180], need to
519-
// expose as empty Object, not null
520-
_nextToken = JsonToken.END_OBJECT;
521-
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
522-
return (_currToken = JsonToken.START_OBJECT);
523-
}
524-
return (_currToken = JsonToken.VALUE_NULL);
525-
}
526-
_currToken = _parsingContext.inArray() ? JsonToken.END_ARRAY : JsonToken.END_OBJECT;
527-
_parsingContext = _parsingContext.getParent();
528-
_namesToWrap = _parsingContext.getNamesToWrap();
529-
return _currToken;
530-
531-
case XmlTokenStream.XML_ATTRIBUTE_NAME:
532-
// If there was a chance of leaf node, no more...
533-
if (_mayBeLeaf) {
534-
_mayBeLeaf = false;
535-
_nextToken = JsonToken.FIELD_NAME;
536-
_currText = _xmlTokens.getText();
537-
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
538-
return (_currToken = JsonToken.START_OBJECT);
539-
}
540-
_parsingContext.setCurrentName(_xmlTokens.getLocalName());
541-
return (_currToken = JsonToken.FIELD_NAME);
542-
case XmlTokenStream.XML_ATTRIBUTE_VALUE:
543-
_currText = _xmlTokens.getText();
544-
return (_currToken = JsonToken.VALUE_STRING);
545-
case XmlTokenStream.XML_TEXT:
546-
_currText = _xmlTokens.getText();
547-
if (_mayBeLeaf) {
548-
_mayBeLeaf = false;
549-
/* One more refinement (pronunced like "hack") is that if
550-
* we had an empty String (or all white space), and we are
551-
* deserializing an array, we better hide the empty text.
552-
*/
553-
// Also: must skip following END_ELEMENT
554-
_xmlTokens.skipEndElement();
555-
if (_parsingContext.inArray()) {
556-
if (_isEmpty(_currText)) {
515+
while (true) {
516+
switch (token) {
517+
case XmlTokenStream.XML_END_ELEMENT:
518+
// Simple, except that if this is a leaf, need to suppress end:
519+
if (_mayBeLeaf) {
520+
_mayBeLeaf = false;
521+
if (_parsingContext.inArray()) {
557522
// 06-Jan-2015, tatu: as per [dataformat-xml#180], need to
558-
// expose as empty Object, not null (or, worse, as used to
559-
// be done, by swallowing the token)
523+
// expose as empty Object, not null
560524
_nextToken = JsonToken.END_OBJECT;
561525
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
562526
return (_currToken = JsonToken.START_OBJECT);
563527
}
528+
return (_currToken = JsonToken.VALUE_NULL);
529+
}
530+
_currToken = _parsingContext.inArray() ? JsonToken.END_ARRAY : JsonToken.END_OBJECT;
531+
_parsingContext = _parsingContext.getParent();
532+
_namesToWrap = _parsingContext.getNamesToWrap();
533+
return _currToken;
534+
535+
case XmlTokenStream.XML_ATTRIBUTE_NAME:
536+
// If there was a chance of leaf node, no more...
537+
if (_mayBeLeaf) {
538+
_mayBeLeaf = false;
539+
_nextToken = JsonToken.FIELD_NAME;
540+
_currText = _xmlTokens.getText();
541+
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
542+
return (_currToken = JsonToken.START_OBJECT);
564543
}
544+
_parsingContext.setCurrentName(_xmlTokens.getLocalName());
545+
return (_currToken = JsonToken.FIELD_NAME);
546+
case XmlTokenStream.XML_ATTRIBUTE_VALUE:
547+
_currText = _xmlTokens.getText();
565548
return (_currToken = JsonToken.VALUE_STRING);
566-
} else {
567-
// [dataformat-xml#177]: empty text may also need to be skipped
568-
if (_parsingContext.inObject()
569-
&& (_currToken != JsonToken.FIELD_NAME) && _isEmpty(_currText)) {
570-
_currToken = JsonToken.END_OBJECT;
571-
_parsingContext = _parsingContext.getParent();
572-
_namesToWrap = _parsingContext.getNamesToWrap();
573-
return _currToken;
549+
case XmlTokenStream.XML_TEXT:
550+
_currText = _xmlTokens.getText();
551+
if (_mayBeLeaf) {
552+
_mayBeLeaf = false;
553+
// One more refinement (pronunced like "hack") is that if
554+
// we had an empty String (or all white space), and we are
555+
// deserializing an array, we better hide the empty text.
556+
// Also: must skip following END_ELEMENT
557+
_xmlTokens.skipEndElement();
558+
if (_parsingContext.inArray()) {
559+
if (_isEmpty(_currText)) {
560+
// 06-Jan-2015, tatu: as per [dataformat-xml#180], need to
561+
// expose as empty Object, not null (or, worse, as used to
562+
// be done, by swallowing the token)
563+
_nextToken = JsonToken.END_OBJECT;
564+
_parsingContext = _parsingContext.createChildObjectContext(-1, -1);
565+
return (_currToken = JsonToken.START_OBJECT);
566+
}
567+
}
568+
return (_currToken = JsonToken.VALUE_STRING);
569+
} else {
570+
// [dataformat-xml#177]: empty text may also need to be skipped
571+
// but... [dataformat-xml#191]: looks like we can't short-cut, must
572+
// loop over again
573+
if (_parsingContext.inObject()) {
574+
if ((_currToken != JsonToken.FIELD_NAME) && _isEmpty(_currText)) {
575+
token = _xmlTokens.next();
576+
continue;
577+
}
578+
}
574579
}
580+
// If not a leaf (or otherwise ignorable), need to transform into property...
581+
_parsingContext.setCurrentName(_cfgNameForTextElement);
582+
_nextToken = JsonToken.VALUE_STRING;
583+
return (_currToken = JsonToken.FIELD_NAME);
584+
case XmlTokenStream.XML_END:
585+
return (_currToken = null);
575586
}
576-
// If not a leaf (or otherwise ignorable), need to transform into property...
577-
_parsingContext.setCurrentName(_cfgNameForTextElement);
578-
_nextToken = JsonToken.VALUE_STRING;
579-
return (_currToken = JsonToken.FIELD_NAME);
580-
case XmlTokenStream.XML_END:
581-
return (_currToken = null);
582587
}
583-
584-
// should never get here
585-
_throwInternal();
586-
return null;
587588
}
588589

589590
/*

src/main/java/com/fasterxml/jackson/dataformat/xml/deser/XmlTokenStream.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ public int next() throws IOException
152152
return n;
153153
}
154154
*/
155-
155+
156156
public int next() throws IOException
157157
{
158158
if (_repeatElement != 0) {

src/test/java/com/fasterxml/jackson/dataformat/xml/failing/DeserializePolyList178Test.java renamed to src/test/java/com/fasterxml/jackson/dataformat/xml/lists/DeserializePolyList178Test.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.fasterxml.jackson.dataformat.xml.failing;
1+
package com.fasterxml.jackson.dataformat.xml.lists;
22

33
import java.util.ArrayList;
44
import java.util.List;
@@ -68,13 +68,19 @@ public void testPolyIdList178() throws Exception
6868
{
6969
Company input = new Company();
7070
input.add(new DesktopComputer().with("1", "http://foo.com"));
71-
input.add(new DesktopComputer().with("2", "http://bar.com"));
71+
final String LOC2 = "http://bar.com";
72+
input.add(new DesktopComputer().with("2", LOC2));
7273
String xml = MAPPER.writerWithDefaultPrettyPrinter()
7374
.writeValueAsString(input);
7475
//System.out.println("XML:\n"+xml);
7576

7677
Company result = MAPPER.readValue(xml, Company.class);
7778
assertNotNull(result.computers);
7879
assertEquals(2, result.computers.size());
80+
Computer comp = result.computers.get(1);
81+
assertNotNull(comp);
82+
assertEquals(DesktopComputer.class, comp.getClass());
83+
DesktopComputer dt = (DesktopComputer) comp;
84+
assertEquals(LOC2, dt.location);
7985
}
8086
}

src/test/java/com/fasterxml/jackson/dataformat/xml/failing/ListDeser191Test.java renamed to src/test/java/com/fasterxml/jackson/dataformat/xml/lists/ListDeser191Test.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.fasterxml.jackson.dataformat.xml.failing;
1+
package com.fasterxml.jackson.dataformat.xml.lists;
22

33
import java.util.ArrayList;
44

@@ -27,8 +27,7 @@ public void testListDeser() throws Exception
2727
"<TestList>\n"+
2828
" <items>\n"+
2929
" <item name='Item1'/>\n"+
30-
" <item name='Item2'>\n"+
31-
" </item>\n"+
30+
" <item name='Item2'> </item>\n"+ // important: at least one ws char between start/end
3231
" <item name='Item3'/>\n"+
3332
" </items>\n"+
3433
"</TestList>"

0 commit comments

Comments
 (0)