Skip to content

Commit 4f1133a

Browse files
committed
[bugfix] Allow XDM Array and Map types to be serialized over the XML:DB API
Closes eXist-db/exist#4919
1 parent dcc8782 commit 4f1133a

File tree

5 files changed

+148
-5
lines changed

5 files changed

+148
-5
lines changed

exist-core/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,8 +917,11 @@
917917
<include>src/test/java/org/exist/w3c/tests/TestCase.java</include>
918918
<include>src/main/java/org/exist/webstart/JnlpJarFiles.java</include>
919919
<include>src/test/java/org/exist/xmldb/CreateCollectionsTest.java</include>
920+
<include>src/main/java/org/exist/xmldb/LocalXMLResource.java</include>
920921
<include>src/main/java/org/exist/xmldb/RemoteRestoreService.java</include>
922+
<include>src/test/java/org/exist/xmldb/SerializationTest.java</include>
921923
<include>src/main/java/org/exist/xmlrpc/ExistRpcTypeFactory.java</include>
924+
<include>src/main/java/org/exist/xmlrpc/RpcConnection.java</include>
922925
<include>src/main/java/org/exist/xqj/Marshaller.java</include>
923926
<include>src/main/java/org/exist/xquery/DynamicTypeCheck.java</include>
924927
<include>src/main/java/org/exist/xquery/ErrorCodes.java</include>
@@ -1214,10 +1217,13 @@
12141217
<exclude>src/test/java/org/exist/w3c/tests/TestCase.java</exclude>
12151218
<exclude>src/main/java/org/exist/webstart/JnlpJarFiles.java</exclude>
12161219
<exclude>src/test/java/org/exist/xmldb/CreateCollectionsTest.java</exclude>
1220+
<exclude>src/main/java/org/exist/xmldb/LocalXMLResource.java</exclude>
12171221
<exclude>src/main/java/org/exist/xmldb/RemoteRestoreService.java</exclude>
1222+
<exclude>src/test/java/org/exist/xmldb/SerializationTest.java</exclude>
12181223
<exclude>src/main/java/org/exist/xmlrpc/ACEAiderParser.java</exclude>
12191224
<exclude>src/main/java/org/exist/xmlrpc/ACEAiderSerializer.java</exclude>
12201225
<exclude>src/main/java/org/exist/xmlrpc/ExistRpcTypeFactory.java</exclude>
1226+
<exclude>src/main/java/org/exist/xmlrpc/RpcConnection.java</exclude>
12211227
<exclude>src/main/java/org/exist/xqj/Marshaller.java</exclude>
12221228
<exclude>src/main/java/org/exist/xquery/Cardinality.java</exclude>
12231229
<exclude>src/test/java/org/exist/xquery/CastExpressionTest.java</exclude>

exist-core/src/main/java/org/exist/xmldb/LocalXMLResource.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
/*
2+
* Elemental
3+
* Copyright (C) 2024, Evolved Binary Ltd
4+
*
5+
6+
* https://www.evolvedbinary.com | https://www.elemental.xyz
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; version 2.1.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*
21+
* NOTE: Parts of this file contain code from 'The eXist-db Authors'.
22+
* The original license header is included below.
23+
*
24+
* =====================================================================
25+
*
226
* eXist-db Open Source Native XML Database
327
* Copyright (C) 2001 The eXist-db Authors
428
*
@@ -137,7 +161,11 @@ else if (root != null && !(root instanceof NodeValue)) {
137161
} else if (value != null) {
138162
try {
139163
if (Type.subTypeOf(value.getType(),Type.STRING)) {
140-
return ((StringValue)value).getStringValue(true);
164+
return ((StringValue) value).getStringValue(true);
165+
166+
} else if (Type.subTypeOf(value.getType(), Type.MAP_ITEM) || Type.subTypeOf(value.getType(), Type.ARRAY_ITEM)) {
167+
return value.toString();
168+
141169
} else {
142170
return value.getStringValue();
143171
}

exist-core/src/main/java/org/exist/xmlrpc/RpcConnection.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
/*
2+
* Elemental
3+
* Copyright (C) 2024, Evolved Binary Ltd
4+
*
5+
6+
* https://www.evolvedbinary.com | https://www.elemental.xyz
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; version 2.1.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*
21+
* NOTE: Parts of this file contain code from 'The eXist-db Authors'.
22+
* The original license header is included below.
23+
*
24+
* =====================================================================
25+
*
226
* eXist-db Open Source Native XML Database
327
* Copyright (C) 2001 The eXist-db Authors
428
*
@@ -1818,6 +1842,10 @@ private Map<String, Object> queryResultToRpcResponse(final long startTime, final
18181842
entry.add(String.valueOf(((NodeImpl) next).getNodeNumber()));
18191843
}
18201844
result.add(entry);
1845+
1846+
} else if (Type.subTypeOf(next.getType(), Type.MAP_ITEM) || Type.subTypeOf(next.getType(), Type.ARRAY_ITEM)) {
1847+
result.add(next.toString());
1848+
18211849
} else {
18221850
result.add(next.getStringValue());
18231851
}
@@ -1982,7 +2010,14 @@ private Map<String, String> atomicMap(final Item item) throws XPathException {
19822010

19832011
final int type = item.getType();
19842012
result.put("type", Type.getTypeName(type));
1985-
result.put("value", item.getStringValue());
2013+
2014+
final String value;
2015+
if (Type.subTypeOf(item.getType(), Type.MAP_ITEM) || Type.subTypeOf(item.getType(), Type.ARRAY_ITEM)) {
2016+
value = item.toString();
2017+
} else {
2018+
value = item.getStringValue();
2019+
}
2020+
result.put("value", value);
19862021

19872022
return result;
19882023
}

exist-core/src/main/java/org/exist/xquery/functions/array/ArrayType.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,11 +489,37 @@ public String toString() {
489489
builder.append(' ');
490490
}
491491
for (int i = 0; i < vector.length(); i++) {
492-
final Sequence value = vector.nth(i);
493-
builder.append(value.toString());
494-
if (i < vector.length() - 1) {
492+
493+
if (i > 0) {
495494
builder.append(", ");
496495
}
496+
497+
final Sequence sequence = vector.nth(i);
498+
499+
if (!sequence.hasOne()) {
500+
builder.append('(');
501+
}
502+
503+
for (int j = 0; j < sequence.getItemCount(); j++) {
504+
if (j > 0) {
505+
builder.append(", ");
506+
}
507+
508+
final Item item = sequence.itemAt(j);
509+
if (Type.subTypeOf(item.getType(), Type.STRING)) {
510+
builder.append('"');
511+
}
512+
513+
builder.append(item.toString());
514+
515+
if (Type.subTypeOf(item.getType(), Type.STRING)) {
516+
builder.append('"');
517+
}
518+
}
519+
520+
if (!sequence.hasOne()) {
521+
builder.append(')');
522+
}
497523
}
498524
if (vector.length() > 0) {
499525
builder.append(' ');

exist-core/src/test/java/org/exist/xmldb/SerializationTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
/*
2+
* Elemental
3+
* Copyright (C) 2024, Evolved Binary Ltd
4+
*
5+
6+
* https://www.evolvedbinary.com | https://www.elemental.xyz
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; version 2.1.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*
21+
* NOTE: Parts of this file contain code from 'The eXist-db Authors'.
22+
* The original license header is included below.
23+
*
24+
* =====================================================================
25+
*
226
* eXist-db Open Source Native XML Database
327
* Copyright (C) 2001 The eXist-db Authors
428
*
@@ -242,6 +266,30 @@ public void getXmlDeclYes() throws XMLDBException {
242266
}
243267
}
244268

269+
@Test
270+
public void testArray() throws XMLDBException {
271+
final String query = "array { \"value 1\", \"value 2\" }";
272+
273+
final XQueryService service = testCollection.getService(XQueryService.class);
274+
final ResourceSet result = service.query(query);
275+
assertEquals(1, result.getSize());
276+
277+
final Resource resource = result.getResource(0);
278+
assertEquals("[ \"value 1\", \"value 2\" ]", resource.getContent());
279+
}
280+
281+
@Test
282+
public void testMap() throws XMLDBException {
283+
final String query = "map { \"prop1\" : \"value 1\", \"prop2\" : \"value 2\" }";
284+
285+
final XQueryService service = testCollection.getService(XQueryService.class);
286+
final ResourceSet result = service.query(query);
287+
assertEquals(1, result.getSize());
288+
289+
final Resource resource = result.getResource(0);
290+
assertEquals("map {\"prop2\": \"value 2\", \"prop1\": \"value 1\"}", resource.getContent());
291+
}
292+
245293
private static void assertXMLEquals(final String expected, final Resource actual) throws XMLDBException {
246294
final Source srcExpected = Input.fromString(expected).build();
247295
final Source srcActual = Input.fromString(actual.getContent().toString()).build();

0 commit comments

Comments
 (0)