Skip to content

Commit 3830bbf

Browse files
committed
[bugfix] Fix an issue with relative module paths
Closes eXist-db/exist#5525
1 parent 1405e01 commit 3830bbf

File tree

5 files changed

+1075
-2
lines changed

5 files changed

+1075
-2
lines changed

exist-core/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,8 @@
677677
<header>${project.parent.relativePath}/../elemental-parent/elemental-LGPL-21-ONLY-license.template.txt</header>
678678
<includes>
679679
<include>project-suppression.xml</include>
680+
<include>src/test/java/org/exist/xquery/ImportFromPkgTest.java</include>
681+
<include>src/test/resources-filtered/org/exist/xquery/import-from-pkg-test.conf.xml</include>
680682
</includes>
681683
</licenseSet>
682684

@@ -818,6 +820,7 @@
818820
<exclude>src/test/resources/log4j2.xml</exclude>
819821
<exclude>src/test/resources-filtered/conf.xml</exclude>
820822
<exclude>src/test/resources-filtered/org/exist/storage/statistics/conf.xml</exclude>
823+
<exclude>src/test/resources-filtered/org/exist/xquery/import-from-pkg-test.conf.xml</exclude>
821824
<exclude>src/test/resources-filtered/org/exist/xquery/functions/transform/transform-from-pkg-test.conf.xml</exclude>
822825
<exclude>src/main/antlr/org/exist/xquery/parser/XQueryTree.g</exclude>
823826
<exclude>src/main/java/org/exist/client/ClientFrame.java</exclude>
@@ -882,6 +885,7 @@
882885
<exclude>src/main/java/org/exist/webstart/JnlpJarFiles.java</exclude>
883886
<exclude>src/main/java/org/exist/xmldb/RemoteRestoreService.java</exclude>
884887
<exclude>src/main/java/org/exist/xmlrpc/ExistRpcTypeFactory.java</exclude>
888+
<exclude>src/test/java/org/exist/xquery/ImportFromPkgTest.java</exclude>
885889
<exclude>src/main/java/org/exist/xquery/functions/fn/FunUriCollection.java</exclude>
886890
<exclude>src/main/java/org/exist/xquery/functions/system/GetUptime.java</exclude>
887891
<exclude>src/main/java/org/exist/xquery/functions/system/Shutdown.java</exclude>

exist-core/src/main/java/org/exist/source/SourceFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public class SourceFactory {
135135
&& ((location.startsWith("/db") && !Files.exists(Paths.get(firstPathSegment(location))))
136136
|| (contextPath != null && contextPath.startsWith("/db") && !Files.exists(Paths.get(firstPathSegment(contextPath)))))) {
137137
final XmldbURI pathUri;
138-
if (contextPath == null) {
138+
if (contextPath == null || (".".equals(contextPath) && location.startsWith("/"))) {
139139
pathUri = XmldbURI.create(location);
140140
} else {
141141
pathUri = XmldbURI.create(contextPath).append(location);

exist-core/src/main/java/org/exist/xquery/XQueryContext.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,13 @@ public Optional<ExistRepository> getRepository() {
597597
Source src = repo.get().resolveStoredXQueryModuleFromDb(getBroker(), resolved);
598598
if (src != null) {
599599
// NOTE(AR) set the location of the module to import relative to this module's load path - so that transient imports of the imported module will resolve correctly!
600-
location = Paths.get(XmldbURI.create(moduleLoadPath).getCollectionPath()).relativize(Paths.get(((DBSource)src).getDocumentPath().getCollectionPath())).toString();
600+
final Path srcCollectionPath = Paths.get(((DBSource)src).getDocumentPath().getCollectionPath());
601+
if (srcCollectionPath.isAbsolute()) {
602+
location = srcCollectionPath.toString();
603+
} else {
604+
final Path moduleLoadPathCollectionPath = Paths.get(XmldbURI.create(moduleLoadPath).getCollectionPath());
605+
location = moduleLoadPathCollectionPath.relativize(srcCollectionPath).toString();
606+
}
601607
} else {
602608
// else, fallback to the one from the filesystem
603609
src = new FileSource(resolved, false);
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
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+
package org.exist.xquery;
22+
23+
import org.exist.test.ExistXmldbEmbeddedServer;
24+
import org.junit.ClassRule;
25+
import org.junit.Test;
26+
import org.xmldb.api.base.Resource;
27+
import org.xmldb.api.base.ResourceSet;
28+
import org.xmldb.api.base.XMLDBException;
29+
30+
import java.net.URISyntaxException;
31+
import java.nio.file.Path;
32+
import java.nio.file.Paths;
33+
34+
import static org.junit.Assert.*;
35+
36+
/**
37+
* @author <a href="mailto:[email protected]">Adam Retter</a>
38+
*/
39+
public class ImportFromPkgTest {
40+
41+
private static Path getConfigFile() {
42+
final ClassLoader loader = ImportFromPkgTest.class.getClassLoader();
43+
final char separator = System.getProperty("file.separator").charAt(0);
44+
final String packagePath = ImportFromPkgTest.class.getPackage().getName().replace('.', separator);
45+
46+
try {
47+
return Paths.get(loader.getResource(packagePath + separator + "import-from-pkg-test.conf.xml").toURI());
48+
} catch (final URISyntaxException e) {
49+
fail(e.getMessage());
50+
return null;
51+
}
52+
}
53+
54+
@ClassRule
55+
public static ExistXmldbEmbeddedServer existXmldbEmbeddedServer = new ExistXmldbEmbeddedServer(true, false, true, getConfigFile());
56+
57+
@Test
58+
public void printPackages() throws XMLDBException {
59+
//final String query = "import module namespace packages=\"http://exist-db.org/apps/existdb-packages\" at \"/db/apps/packageservice/modules/packages.xqm\";\n" +
60+
//"packages:get-local-packages()";
61+
62+
final String query = "xmldb:get-child-resources('/db/system/repo/functx-1.0.1/functx/')";
63+
64+
final ResourceSet resultSet = existXmldbEmbeddedServer.executeQuery(query);
65+
66+
for (int i = 0; i < resultSet.getSize(); i++) {
67+
System.out.println(resultSet.getResource(i).getContent().toString());
68+
}
69+
}
70+
71+
@Test
72+
public void importFunctxNs() throws XMLDBException {
73+
final String query =
74+
"import module namespace functx = \"http://www.functx.com\";\n" +
75+
"\n" +
76+
"<test>{functx:index-of-string('hello', 'll')}</test>";
77+
final ResourceSet resultSet = existXmldbEmbeddedServer.executeQuery(query);
78+
assertNotNull(resultSet);
79+
assertEquals(1, resultSet.getSize());
80+
final Resource result = resultSet.getResource(0);
81+
assertNotNull(result);
82+
assertEquals("<test>3</test>", result.getContent().toString());
83+
}
84+
85+
@Test
86+
public void importFunctxLocationHintDb() throws XMLDBException {
87+
final String query =
88+
"import module namespace functx = \"http://www.functx.com\" at \"/db/system/repo/functx-1.0.1/functx/functx.xq\";\n" +
89+
"\n" +
90+
"<test>{functx:index-of-string('hello', 'll')}</test>";
91+
final ResourceSet resultSet = existXmldbEmbeddedServer.executeQuery(query);
92+
assertNotNull(resultSet);
93+
assertEquals(1, resultSet.getSize());
94+
final Resource result = resultSet.getResource(0);
95+
assertNotNull(result);
96+
assertEquals("<test>3</test>", result.getContent().toString());
97+
}
98+
99+
@Test
100+
public void importFunctxLocationHintXmldb() throws XMLDBException {
101+
final String query =
102+
"import module namespace functx = \"http://www.functx.com\" at \"xmldb:exist:///db/system/repo/functx-1.0.1/functx/functx.xq\";\n" +
103+
"\n" +
104+
"<test>{functx:index-of-string('hello', 'll')}</test>";
105+
final ResourceSet resultSet = existXmldbEmbeddedServer.executeQuery(query);
106+
assertNotNull(resultSet);
107+
assertEquals(1, resultSet.getSize());
108+
final Resource result = resultSet.getResource(0);
109+
assertNotNull(result);
110+
assertEquals("<test>3</test>", result.getContent().toString());
111+
}
112+
113+
@Test
114+
public void declareFunctx() {
115+
try {
116+
final String query =
117+
"declare namespace functx = \"http://www.functx.com\";\n" +
118+
"\n" +
119+
"<test>{functx:index-of-string('hello', 'll')}</test>";
120+
existXmldbEmbeddedServer.executeQuery(query);
121+
} catch (final XMLDBException e) {
122+
assertTrue(e.getMessage().startsWith("err:XPST0017 Call to undeclared function: functx:index-of-string"));
123+
return;
124+
}
125+
126+
fail("Expected XPathException: err:XPST0017 Call to undeclared function: functx:index-of-string");
127+
}
128+
}

0 commit comments

Comments
 (0)