Skip to content

Commit 44f7a6e

Browse files
committed
[bugfix] When deserializing types in the eXist-db REST API if they do not declare a type, assume 'item()'.
Closes eXist-db/exist#5844
1 parent 0392935 commit 44f7a6e

File tree

4 files changed

+327
-49
lines changed

4 files changed

+327
-49
lines changed

exist-core/src/main/java/org/exist/xqj/Marshaller.java

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -195,17 +195,22 @@ public static Sequence demarshall(DBBroker broker,Node n) throws XMLStreamExcept
195195

196196
public static Sequence demarshall(DBBroker broker, XMLStreamReader parser) throws XMLStreamException, XPathException {
197197
int event = parser.next();
198-
while (event != XMLStreamConstants.START_ELEMENT)
198+
while (event != XMLStreamConstants.START_ELEMENT) {
199199
event = parser.next();
200-
if (!NAMESPACE.equals(parser.getNamespaceURI()))
201-
{throw new XMLStreamException("Root element is not in the correct namespace. Expected: " + NAMESPACE);}
202-
if (!SEQ_ELEMENT.equals(parser.getLocalName()))
203-
{throw new XMLStreamException("Root element should be a " + SEQ_ELEMENT_QNAME);}
200+
}
201+
if (!NAMESPACE.equals(parser.getNamespaceURI())) {
202+
throw new XMLStreamException("Root element is not in the correct namespace. Expected: " + NAMESPACE);
203+
}
204+
if (!SEQ_ELEMENT.equals(parser.getLocalName())) {
205+
throw new XMLStreamException("Root element should be a " + SEQ_ELEMENT_QNAME);
206+
}
204207
final ValueSequence result = new ValueSequence();
205208
while ((event = parser.next()) != XMLStreamConstants.END_DOCUMENT) {
206209
switch (event) {
207210
case XMLStreamConstants.START_ELEMENT :
208211
if (NAMESPACE.equals(parser.getNamespaceURI()) && VALUE_ELEMENT.equals(parser.getLocalName())) {
212+
int type = Type.ITEM;
213+
209214
String typeName = null;
210215
// scan through attributes instead of direct lookup to work around issue in xerces
211216
for (int i = 0; i < parser.getAttributeCount(); i++) {
@@ -214,15 +219,17 @@ public static Sequence demarshall(DBBroker broker, XMLStreamReader parser) throw
214219
break;
215220
}
216221
}
217-
if (typeName != null) {
218-
final int type = Type.getType(typeName);
219-
Item item;
220-
if (Type.subTypeOf(type, Type.NODE))
221-
{item = streamToDOM(type, parser, null);}
222-
else
223-
{item = new StringValue(null, parser.getElementText()).convertTo(type);}
224-
result.add(item);
222+
if (typeName != null && !typeName.isEmpty()) {
223+
type = Type.getType(typeName);
224+
}
225+
226+
final Item item;
227+
if (Type.subTypeOf(type, Type.NODE)) {
228+
item = streamToDOM(type, parser, null);
229+
} else {
230+
item = new StringValue(null, parser.getElementText()).convertTo(type);
225231
}
232+
result.add(item);
226233
}
227234
break;
228235
case XMLStreamConstants.END_ELEMENT :
@@ -239,45 +246,49 @@ public static Sequence demarshall(NodeImpl node) throws XMLStreamException, XPat
239246
if (ns == null || !NAMESPACE.equals(ns)) {
240247
throw new XMLStreamException("Root element is not in the correct namespace. Expected: " + NAMESPACE);
241248
}
242-
if (!SEQ_ELEMENT.equals(node.getLocalName()))
243-
{throw new XMLStreamException("Root element should be a " + SEQ_ELEMENT_QNAME);}
249+
if (!SEQ_ELEMENT.equals(node.getLocalName())) {
250+
throw new XMLStreamException("Root element should be a " + SEQ_ELEMENT_QNAME);
251+
}
244252
final ValueSequence result = new ValueSequence();
245253
final InMemoryNodeSet values = new InMemoryNodeSet();
246254
node.selectChildren(new NameTest(Type.ELEMENT, VALUE_QNAME), values);
247255
for (final SequenceIterator i = values.iterate(); i.hasNext();) {
248256
final ElementImpl child = (ElementImpl) i.nextItem();
257+
258+
int type = Type.ITEM;
249259
final String typeName = child.getAttribute(ATTR_TYPE);
250260
if (!typeName.isEmpty()) {
251-
final int type = Type.getType(typeName);
252-
Item item;
253-
if (Type.subTypeOf(type, Type.NODE)) {
254-
item = (Item) child.getFirstChild();
255-
if (type == Type.DOCUMENT) {
256-
final DocumentImpl n = (DocumentImpl) item;
257-
final DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(n.getExpression());
258-
try {
259-
receiver.startDocument();
260-
n.copyTo(n, receiver);
261-
receiver.endDocument();
262-
} catch (final SAXException e) {
263-
throw new XPathException(item != null ? item.getExpression() : null, "Error while demarshalling node: " + e.getMessage(), e);
264-
}
265-
item = (Item) receiver.getDocument();
261+
type = Type.getType(typeName);
262+
}
263+
264+
Item item;
265+
if (Type.subTypeOf(type, Type.NODE)) {
266+
item = (Item) child.getFirstChild();
267+
if (type == Type.DOCUMENT) {
268+
final DocumentImpl n = (DocumentImpl) item;
269+
final DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(n.getExpression());
270+
try {
271+
receiver.startDocument();
272+
n.copyTo(n, receiver);
273+
receiver.endDocument();
274+
} catch (final SAXException e) {
275+
throw new XPathException(item != null ? item.getExpression() : null, "Error while demarshalling node: " + e.getMessage(), e);
266276
}
267-
} else {
268-
final StringBuilder data = new StringBuilder();
269-
Node txt = child.getFirstChild();
270-
while (txt != null) {
271-
if (!(txt.getNodeType() == Node.TEXT_NODE || txt.getNodeType() == Node.CDATA_SECTION_NODE)) {
272-
throw new XMLStreamException("sx:value should only contain text if type is " + typeName);
273-
}
274-
data.append(txt.getNodeValue());
275-
txt = txt.getNextSibling();
277+
item = (Item) receiver.getDocument();
278+
}
279+
} else {
280+
final StringBuilder data = new StringBuilder();
281+
Node txt = child.getFirstChild();
282+
while (txt != null) {
283+
if (!(txt.getNodeType() == Node.TEXT_NODE || txt.getNodeType() == Node.CDATA_SECTION_NODE)) {
284+
throw new XMLStreamException("sx:value should only contain text if type is " + typeName);
276285
}
277-
item = new StringValue(data.toString()).convertTo(type);
286+
data.append(txt.getNodeValue());
287+
txt = txt.getNextSibling();
278288
}
279-
result.add(item);
289+
item = new StringValue(data.toString()).convertTo(type);
280290
}
291+
result.add(item);
281292
}
282293
return result;
283294
}

exist-core/src/main/xsd/rest-serialized-sequence.xsd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<xs:sequence>
3333
<xs:element name="value" minOccurs="0" maxOccurs="unbounded">
3434
<xs:complexType mixed="true">
35-
<xs:attribute name="type" type="xs:QName" use="required"/>
35+
<xs:attribute name="type" type="xs:string" default="item()"/>
3636
</xs:complexType>
3737
</xs:element>
3838
</xs:sequence>

0 commit comments

Comments
 (0)