diff --git a/exist-core/pom.xml b/exist-core/pom.xml
index d1c1e77a6e..9a6956048f 100644
--- a/exist-core/pom.xml
+++ b/exist-core/pom.xml
@@ -780,6 +780,7 @@
src/test/xquery/base-uri.xql
src/test/xquery/parenthesizedLocationStep.xml
src/test/xquery/tail-recursion.xml
+ src/test/xquery/indexing/indexes-base-uri.xq
src/test/xquery/maps/maps.xqm
src/test/xquery/numbers/format-numbers.xql
src/test/xquery/util/util.xml
@@ -865,6 +866,7 @@
src/main/java/org/exist/dom/QName.java
src/main/java/org/exist/dom/memtree/AbstractCharacterData.java
src/main/java/org/exist/dom/memtree/AttrImpl.java
+ src/main/java/org/exist/dom/memtree/CDATASectionImpl.java
src/main/java/org/exist/dom/memtree/CommentImpl.java
src/main/java/org/exist/dom/memtree/DocumentBuilderReceiver.java
src/main/java/org/exist/dom/memtree/DocumentImpl.java
@@ -884,6 +886,7 @@
src/test/java/org/exist/dom/persistent/BasicNodeSetTest.java
src/main/java/org/exist/dom/persistent/BinaryDocument.java
src/test/java/org/exist/dom/persistent/CDataIntergationTest.java
+ src/main/java/org/exist/dom/persistent/CDATASectionImpl.java
src/main/java/org/exist/dom/persistent/CommentImpl.java
src/test/java/org/exist/dom/persistent/CommentTest.java
src/test/java/org/exist/dom/persistent/DefaultDocumentSetTest.java
@@ -1086,6 +1089,7 @@
src/test/java/org/exist/util/CollationsTest.java
src/main/java/org/exist/util/Configuration.java
src/test/java/org/exist/util/DOMSerializerTest.java
+ src/main/java/org/exist/util/EXistURISchemeURIResolver.java
src/test/java/org/exist/util/LeasableTest.java
src/test/java/org/exist/util/MediaTypeResolverTest.java
src/main/java/org/exist/util/MimeTable.java
@@ -1347,6 +1351,7 @@
src/main/java/org/exist/xquery/functions/fn/transform/Options.java
src/main/java/org/exist/xquery/functions/fn/transform/Transform.java
src/main/java/org/exist/xquery/functions/fn/transform/TreeUtils.java
+ src/main/java/org/exist/xquery/functions/fn/transform/URIResolution.java
src/test/java/org/exist/xquery/functions/inspect/InspectModuleTest.java
src/main/java/org/exist/xquery/functions/integer/WordPicture.java
src/main/java/org/exist/xquery/functions/map/MapExpr.java
@@ -1390,6 +1395,7 @@
src/test/java/org/exist/xquery/functions/validate/JingSchematronTest.java
src/test/java/org/exist/xquery/functions/validate/JingXsdTest.java
src/main/java/org/exist/xquery/functions/validation/Jaxp.java
+ src/main/java/org/exist/xquery/functions/validation/Shared.java
src/test/java/org/exist/xquery/functions/xmldb/DbStore2Test.java
src/main/java/org/exist/xquery/functions/xmldb/XMLDBGetMimeType.java
src/main/java/org/exist/xquery/functions/xmldb/XMLDBLoadFromPattern.java
@@ -1491,6 +1497,7 @@
src/test/xquery/parenthesizedLocationStep.xml
src/test/xquery/pi.xqm
src/test/xquery/tail-recursion.xml
+ src/test/xquery/indexing/indexes-base-uri.xq
src/test/xquery/maps/maps.xqm
src/test/xquery/numbers/format-numbers.xql
src/test/xquery/securitymanager/acl.xqm
@@ -1578,7 +1585,8 @@
src/main/java/org/exist/dom/QName.java
src/main/java/org/exist/dom/memtree/AbstractCharacterData.java
src/main/java/org/exist/dom/memtree/AttrImpl.java
- src/main/java/org/exist/dom/memtree/CommentImpl.java
+ src/main/java/org/exist/dom/memtree/CDATASectionImpl.java
+ src/main/java/org/exist/dom/memtree/CommentImpl.java
src/main/java/org/exist/dom/memtree/DocumentBuilderReceiver.java
src/main/java/org/exist/dom/memtree/DocumentImpl.java
src/test/java/org/exist/dom/memtree/DocumentImplTest.java
@@ -1605,6 +1613,7 @@
src/test/java/org/exist/dom/persistent/BasicNodeSetTest.java
src/main/java/org/exist/dom/persistent/BinaryDocument.java
src/test/java/org/exist/dom/persistent/CDataIntergationTest.java
+ src/main/java/org/exist/dom/persistent/CDATASectionImpl.java
src/main/java/org/exist/dom/persistent/CommentImpl.java
src/test/java/org/exist/dom/persistent/CommentTest.java
src/test/java/org/exist/dom/persistent/DefaultDocumentSetTest.java
@@ -1870,6 +1879,7 @@
src/test/java/org/exist/util/CollectionOfArrayIteratorTest.java
src/main/java/org/exist/util/Configuration.java
src/test/java/org/exist/util/DOMSerializerTest.java
+ src/main/java/org/exist/util/EXistURISchemeURIResolver.java
src/main/java/org/exist/util/IPUtil.java
src/main/java/org/exist/util/JREUtil.java
src/test/java/org/exist/util/LeasableTest.java
@@ -2163,6 +2173,7 @@
src/main/java/org/exist/xquery/functions/fn/transform/Options.java
src/main/java/org/exist/xquery/functions/fn/transform/Transform.java
src/main/java/org/exist/xquery/functions/fn/transform/TreeUtils.java
+ src/main/java/org/exist/xquery/functions/fn/transform/URIResolution.java
src/test/java/org/exist/xquery/functions/inspect/InspectModuleTest.java
src/main/java/org/exist/xquery/functions/integer/WordPicture.java
src/main/java/org/exist/xquery/functions/map/MapExpr.java
@@ -2213,6 +2224,7 @@
src/test/java/org/exist/xquery/functions/validate/JingSchematronTest.java
src/test/java/org/exist/xquery/functions/validate/JingXsdTest.java
src/main/java/org/exist/xquery/functions/validation/Jaxp.java
+ src/main/java/org/exist/xquery/functions/validation/Shared.java
src/test/java/org/exist/xquery/functions/xmldb/AbstractXMLDBTest.java
src/test/java/org/exist/xquery/functions/xmldb/DbStore2Test.java
src/test/java/org/exist/xquery/functions/xmldb/XMLDBAuthenticateTest.java
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/CDATASectionImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/CDATASectionImpl.java
index 1a2ac78056..84c204af13 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/CDATASectionImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/CDATASectionImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -25,8 +49,11 @@
import org.exist.xquery.value.Type;
import org.w3c.dom.CDATASection;
import org.w3c.dom.DOMException;
+import org.w3c.dom.Node;
import org.w3c.dom.Text;
+import javax.annotation.Nullable;
+
/**
* Represents a CDATA section.
@@ -48,6 +75,15 @@ public int getItemType() {
return Type.CDATA_SECTION;
}
+ @Override
+ public @Nullable String getBaseURI() {
+ @Nullable final Node parent = getParentNode();
+ if (parent == null) {
+ return null;
+ }
+ return parent.getBaseURI();
+ }
+
@Override
public Text splitText(final int offset) throws DOMException {
return null;
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/AttrImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/AttrImpl.java
index 923164c52b..f32aba3022 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/AttrImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/AttrImpl.java
@@ -57,6 +57,7 @@
import org.exist.util.XMLString;
import org.exist.util.pool.NodePool;
import org.exist.util.serializer.AttrList;
+import org.exist.xmldb.XmldbURI;
import org.exist.xquery.Expression;
import org.w3c.dom.*;
@@ -434,7 +435,12 @@ public boolean isId() {
public @Nullable String getBaseURI() {
@Nullable final Element e = getOwnerElement();
if (e != null) {
- return e.getBaseURI();
+ @Nullable String strBaseUri = e.getBaseURI();
+ if (strBaseUri != null && strBaseUri.startsWith("/db/")) {
+ // Must be a URI!
+ strBaseUri = XmldbURI.EMBEDDED_SERVER_URI_PREFIX + strBaseUri;
+ }
+ return strBaseUri;
}
return null;
}
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/CDATASectionImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/CDATASectionImpl.java
index e89bbbba47..6ddede486c 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/CDATASectionImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/CDATASectionImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -27,12 +51,15 @@
import org.exist.util.ByteConversion;
import org.exist.util.UTF8;
import org.exist.util.XMLString;
+import org.exist.xmldb.XmldbURI;
import org.exist.xquery.Expression;
import org.w3c.dom.CDATASection;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
+import javax.annotation.Nullable;
+
public class CDATASectionImpl extends AbstractCharacterData implements CDATASection {
public CDATASectionImpl() {
@@ -77,6 +104,20 @@ public CDATASectionImpl(final Expression expression, final String data) {
}
@Override
+ public @Nullable String getBaseURI() {
+ @Nullable final Node parent = getParentNode();
+ if (parent != null) {
+ @Nullable String strBaseUri = parent.getBaseURI();
+ if (strBaseUri != null && strBaseUri.startsWith("/db/")) {
+ // Must be a URI!
+ strBaseUri = XmldbURI.EMBEDDED_SERVER_URI_PREFIX + strBaseUri;
+ }
+ return strBaseUri;
+ } else {
+ return null;
+ }
+ }
+
/**
* Serializes a (persistent DOM) CDATA Section to a byte array
*
@@ -94,6 +135,7 @@ public CDATASectionImpl(final Expression expression, final String data) {
* @return the returned byte array after use must be returned to the ByteArrayPool
* by calling {@link ByteArrayPool#releaseByteArray(byte[])}
*/
+ @Override
public byte[] serialize() {
final int nodeIdLen = nodeId.size();
final byte[] data = ByteArrayPool.getByteArray(LENGTH_SIGNATURE_LENGTH + NodeId.LENGTH_NODE_ID_UNITS +
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/CommentImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/CommentImpl.java
index 9ad5f108cb..2fb227708c 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/CommentImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/CommentImpl.java
@@ -49,6 +49,7 @@
import org.exist.storage.Signatures;
import org.exist.util.ByteConversion;
import org.exist.util.pool.NodePool;
+import org.exist.xmldb.XmldbURI;
import org.exist.xquery.Expression;
import org.w3c.dom.Comment;
import org.w3c.dom.Node;
@@ -92,7 +93,12 @@ public String toString() {
public @Nullable String getBaseURI() {
@Nullable final Node parent = getParentNode();
if (parent != null) {
- return parent.getBaseURI();
+ @Nullable String strBaseUri = parent.getBaseURI();
+ if (strBaseUri != null && strBaseUri.startsWith("/db/")) {
+ // Must be a URI!
+ strBaseUri = XmldbURI.EMBEDDED_SERVER_URI_PREFIX + strBaseUri;
+ }
+ return strBaseUri;
} else {
return null;
}
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/DocumentImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/DocumentImpl.java
index 21903f63f3..de13604b03 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/DocumentImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/DocumentImpl.java
@@ -1592,7 +1592,7 @@ public Node renameNode(final Node n, final String namespaceURI, final String qua
@Override
public String getBaseURI() {
- return getURI().toString();
+ return XmldbURI.EMBEDDED_SERVER_URI_PREFIX + getURI().getCollectionPath();
}
@Override
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/ElementImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/ElementImpl.java
index 0f4403f7bf..3c2fe2feec 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/ElementImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/ElementImpl.java
@@ -2021,7 +2021,12 @@ public void setIdAttributeNode(final Attr idAttr, final boolean isId) throws DOM
public @Nullable String getBaseURI() {
@Nullable final XmldbURI baseURI = calculateBaseURI();
if (baseURI != null) {
- return baseURI.toString();
+ String strBaseUri = baseURI.toString();
+ if (strBaseUri.startsWith("/db/")) {
+ // Must be a URI!
+ strBaseUri = XmldbURI.EMBEDDED_SERVER_URI_PREFIX + baseURI;
+ }
+ return strBaseUri;
}
return null;
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/ProcessingInstructionImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/ProcessingInstructionImpl.java
index 6a42f27b0e..5c2d8124bb 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/ProcessingInstructionImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/ProcessingInstructionImpl.java
@@ -50,6 +50,7 @@
import org.exist.storage.Signatures;
import org.exist.util.ByteConversion;
import org.exist.util.pool.NodePool;
+import org.exist.xmldb.XmldbURI;
import org.exist.xquery.Expression;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
@@ -154,7 +155,12 @@ public void setData(final String data) {
public @Nullable String getBaseURI() {
@Nullable final StoredNode parent = getParentStoredNode();
if (parent != null) {
- return parent.getBaseURI();
+ @Nullable String strBaseUri = parent.getBaseURI();
+ if (strBaseUri != null && strBaseUri.startsWith("/db/")) {
+ // Must be a URI!
+ strBaseUri = XmldbURI.EMBEDDED_SERVER_URI_PREFIX + strBaseUri;
+ }
+ return strBaseUri;
} else {
return getOwnerDocument().getBaseURI();
}
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/TextImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/TextImpl.java
index 6c9d9c8971..a0ba26b9ce 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/TextImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/TextImpl.java
@@ -52,6 +52,7 @@
import org.exist.util.ByteConversion;
import org.exist.util.UTF8;
import org.exist.util.pool.NodePool;
+import org.exist.xmldb.XmldbURI;
import org.exist.xquery.Expression;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
@@ -180,7 +181,12 @@ public Text splitText(final int offset) throws DOMException {
public @Nullable String getBaseURI() {
@Nullable final Node parent = getParentNode();
if (parent != null) {
- return parent.getBaseURI();
+ @Nullable String strBaseUri = parent.getBaseURI();
+ if (strBaseUri != null && strBaseUri.startsWith("/db/")) {
+ // Must be a URI!
+ strBaseUri = XmldbURI.EMBEDDED_SERVER_URI_PREFIX + strBaseUri;
+ }
+ return strBaseUri;
} else {
return null;
}
diff --git a/exist-core/src/main/java/org/exist/util/EXistURISchemeURIResolver.java b/exist-core/src/main/java/org/exist/util/EXistURISchemeURIResolver.java
index f378dee2ef..41628cc190 100644
--- a/exist-core/src/main/java/org/exist/util/EXistURISchemeURIResolver.java
+++ b/exist-core/src/main/java/org/exist/util/EXistURISchemeURIResolver.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -56,6 +80,8 @@ private String rewriteScheme(String uri) {
uri = uri.replace("exist://localhost/db", "/db");
} else if (uri.startsWith("exist://")) {
uri = uri.replace("exist://", "xmldb:exist://");
+ } else if (uri.startsWith("exist:/")) {
+ uri = uri.replace("exist:/", "xmldb:exist:///");
}
}
diff --git a/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Options.java b/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Options.java
index 788ade00e6..98ee6dd178 100644
--- a/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Options.java
+++ b/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Options.java
@@ -56,6 +56,7 @@
import org.exist.dom.memtree.NamespaceNode;
import org.exist.dom.persistent.NodeProxy;
import org.exist.security.PermissionDeniedException;
+import org.exist.xmldb.XmldbURI;
import org.exist.xquery.ErrorCodes;
import org.exist.xquery.XPathException;
import org.exist.xquery.XQueryContext;
@@ -490,7 +491,13 @@ private Tuple2 getStylesheet(final MapType options) throws XPath
final List> results = new ArrayList<>(1);
final Optional stylesheetLocation = Options.STYLESHEET_LOCATION.get(options).map(StringValue::getStringValue);
if (stylesheetLocation.isPresent()) {
- results.add(Tuple(stylesheetLocation.get(), resolveStylesheetLocation(stylesheetLocation.get())));
+ final String strStylesheetLocationUri;
+ if (stylesheetLocation.get().startsWith("/db/")) {
+ strStylesheetLocationUri = XmldbURI.EMBEDDED_SERVER_URI_PREFIX + stylesheetLocation.get();
+ } else {
+ strStylesheetLocationUri = stylesheetLocation.get();
+ }
+ results.add(Tuple(strStylesheetLocationUri, resolveStylesheetLocation(stylesheetLocation.get())));
}
final Optional stylesheetNode = Options.STYLESHEET_NODE.get(options).map(NodeValue::getNode);
diff --git a/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Transform.java b/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Transform.java
index 8cfadd1ccc..215ceea43e 100644
--- a/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Transform.java
+++ b/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/Transform.java
@@ -251,22 +251,24 @@ private XsltExecutable compileExecutable(final Options options) throws XPathExce
xsltCompiler.setParameter(new net.sf.saxon.s9api.QName(qKey.getPrefix(), qKey.getLocalPart()), value);
}
- // Take URI resolution into our own hands when there is no base
- xsltCompiler.setURIResolver((href, base) -> {
- try {
- final URI hrefURI = URI.create(href);
- if ((!options.resolvedStylesheetBaseURI.isPresent()) && !hrefURI.isAbsolute() && isNullOrEmpty(base)) {
- final XPathException resolutionException = new XPathException(fnTransform,
- ErrorCodes.XTSE0165,
- "transform using a relative href, \n" +
- "using option stylesheet-text, but without stylesheet-base-uri");
- throw new TransformerException(resolutionException);
+ xsltCompiler.setURIResolver(new URIResolution.CompileTimeURIResolver(context, fnTransform) {
+ @Override public Source resolve(final String href, final String base) throws TransformerException {
+ // Correct error from URI resolution when there is no base
+ try {
+ final URI hrefURI = URI.create(href);
+ if ((!options.resolvedStylesheetBaseURI.isPresent()) && !hrefURI.isAbsolute() && isNullOrEmpty(base)) {
+ final XPathException resolutionException = new XPathException(fnTransform,
+ ErrorCodes.XTSE0165,
+ "transform using a relative href, \n" +
+ "using option stylesheet-text, but without stylesheet-base-uri");
+ throw new TransformerException(resolutionException);
+ }
+ } catch (final IllegalArgumentException e) {
+ throw new TransformerException(e);
}
- } catch (final IllegalArgumentException e) {
- throw new TransformerException(e);
- }
- // Pass it back
- return null;
+ // Checked the special error case, defer to eXist resolution
+ return super.resolve(href, base);
+ };
});
try {
diff --git a/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/URIResolution.java b/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/URIResolution.java
new file mode 100644
index 0000000000..c61da90924
--- /dev/null
+++ b/exist-core/src/main/java/org/exist/xquery/functions/fn/transform/URIResolution.java
@@ -0,0 +1,160 @@
+/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
+ * eXist-db Open Source Native XML Database
+ * Copyright (C) 2001 The eXist-db Authors
+ *
+ * info@exist-db.org
+ * http://www.exist-db.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.exist.xquery.functions.fn.transform;
+
+import org.exist.dom.persistent.NodeProxy;
+import org.exist.security.PermissionDeniedException;
+import org.exist.xmldb.XmldbURI;
+import org.exist.xquery.ErrorCodes;
+import org.exist.xquery.Expression;
+import org.exist.xquery.XPathException;
+import org.exist.xquery.XQueryContext;
+import org.exist.xquery.util.DocUtils;
+import org.exist.xquery.value.AnyURIValue;
+import org.exist.xquery.value.Sequence;
+import org.exist.xquery.value.Type;
+import org.w3c.dom.Node;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.dom.DOMSource;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+public class URIResolution {
+
+ /**
+ * URI resolution, the core should be the same as for fn:resolve-uri
+ * @param relative URI to resolve
+ * @param base to resolve against
+ * @return resolved URI
+ * @throws URISyntaxException if resolution is not possible
+ */
+ static AnyURIValue resolveURI(final AnyURIValue relative, final AnyURIValue base) throws URISyntaxException, XPathException {
+ final URI relativeURI = new URI(relative.getStringValue());
+ if (relativeURI.isAbsolute()) {
+ return relative;
+ }
+ final URI baseURI = new URI(base.getStringValue() );
+ if (!baseURI.isAbsolute()) {
+ return relative;
+ }
+ try {
+ final XmldbURI xBase = XmldbURI.xmldbUriFor(baseURI);
+ final URI resolved = xBase.getURI().resolve(relativeURI);
+ return new AnyURIValue(XmldbURI.XMLDB_URI_PREFIX + resolved);
+ } catch (URISyntaxException e) {
+ return new AnyURIValue(baseURI.resolve(relativeURI));
+ }
+ }
+
+ public static class CompileTimeURIResolver implements URIResolver {
+
+ private final XQueryContext xQueryContext;
+ private final Expression containingExpression;
+
+ public CompileTimeURIResolver(XQueryContext xQueryContext, Expression containingExpression) {
+ this.xQueryContext = xQueryContext;
+ this.containingExpression = containingExpression;
+ }
+
+ @Override
+ public Source resolve(final String href, final String base) throws TransformerException {
+
+ try {
+ final AnyURIValue baseURI = new AnyURIValue(base);
+ final AnyURIValue hrefURI = new AnyURIValue(href);
+ final AnyURIValue resolved = resolveURI(hrefURI, baseURI);
+ return resolveDocument(resolved.getStringValue());
+ } catch (URISyntaxException e) {
+ throw new TransformerException(
+ "Failed to resolve " + href + " against " + base, e);
+ } catch (XPathException e) {
+ throw new TransformerException(
+ "Failed to find document as result of resolving " + href + " against " + base, e);
+ }
+ }
+
+ protected Source resolveDocument(final String location) throws XPathException {
+ return URIResolution.resolveDocument(location, xQueryContext, containingExpression);
+ }
+ }
+
+ /**
+ * Resolve an absolute document location, stylesheet or included source
+ *
+ * @param location of the stylesheet
+ * @return the resolved stylesheet as a source
+ * @throws XPathException if the item does not exist, or is not a document
+ */
+ static Source resolveDocument(final String location, final XQueryContext xQueryContext, Expression containingExpression) throws XPathException {
+
+ final Sequence document;
+ try {
+ document = DocUtils.getDocument(xQueryContext, location);
+ } catch (final PermissionDeniedException e) {
+ throw new XPathException(containingExpression, ErrorCodes.FODC0002,
+ "Can not access '" + location + "'" + e.getMessage());
+ }
+ if (document == null || document.isEmpty()) {
+ throw new XPathException(containingExpression, ErrorCodes.FODC0002,
+ "No document found at location '"+ location);
+ }
+ if (document.hasOne() && Type.subTypeOf(document.getItemType(), Type.NODE)) {
+ if (document instanceof NodeProxy) {
+ final NodeProxy proxy = (NodeProxy) document;
+ return new DOMSource(proxy.getNode());
+ }
+ else if (document.itemAt(0) instanceof Node) {
+ final Node node = (Node) document.itemAt(0);
+ return new DOMSource(node);
+ }
+ }
+ throw new XPathException(containingExpression, ErrorCodes.FODC0002,
+ "Location '"+ location + "' returns an item which is not a document node");
+ }
+}
\ No newline at end of file
diff --git a/exist-core/src/main/java/org/exist/xquery/functions/transform/Transform.java b/exist-core/src/main/java/org/exist/xquery/functions/transform/Transform.java
index ccdf90a8cb..178ce328d3 100644
--- a/exist-core/src/main/java/org/exist/xquery/functions/transform/Transform.java
+++ b/exist-core/src/main/java/org/exist/xquery/functions/transform/Transform.java
@@ -181,7 +181,14 @@ public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathExce
// Parameter 1 & 2
final Sequence inputNode = args[0];
- final Item stylesheetItem = args[1].itemAt(0);
+ Item stylesheetItem = args[1].itemAt(0);
+ if (stylesheetItem instanceof StringValue) {
+ final StringValue sv = (StringValue) stylesheetItem;
+ if (sv.toString().startsWith("/db/")) {
+ // adjust /db like URI to xmldb:exist:///db/ like URI
+ stylesheetItem = new StringValue(XmldbURI.EMBEDDED_SERVER_URI_PREFIX + sv.toString().substring(3));
+ }
+ }
// Parse 3rd parameter
final Node options = args[2].isEmpty() ? null : ((NodeValue) args[2].itemAt(0)).getNode();
diff --git a/exist-core/src/main/java/org/exist/xquery/functions/validation/Shared.java b/exist-core/src/main/java/org/exist/xquery/functions/validation/Shared.java
index 454f9c9833..812f881555 100644
--- a/exist-core/src/main/java/org/exist/xquery/functions/validation/Shared.java
+++ b/exist-core/src/main/java/org/exist/xquery/functions/validation/Shared.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -147,7 +171,7 @@ public static StreamSource getStreamSource(Item item, XQueryContext context) thr
if (item instanceof NodeProxy) {
final NodeProxy np = (NodeProxy) item;
- final String url = "xmldb:exist://" + np.getOwnerDocument().getBaseURI();
+ final String url = np.getOwnerDocument().getBaseURI();
LOG.debug("Document detected, adding URL {}", url);
streamSource.setSystemId(url);
}
diff --git a/exist-core/src/test/java/org/exist/xquery/TransformTest.java b/exist-core/src/test/java/org/exist/xquery/TransformTest.java
index ce5c3995d9..8cbd50f8a5 100644
--- a/exist-core/src/test/java/org/exist/xquery/TransformTest.java
+++ b/exist-core/src/test/java/org/exist/xquery/TransformTest.java
@@ -95,6 +95,50 @@ public void transform() throws XMLDBException {
"End Template 1
" +
"");
}
+
+ @Test
+ public void transformWithSameDirectoryImportViaDbLocation() throws XMLDBException {
+ final String query =
+ "import module namespace transform='http://exist-db.org/xquery/transform';\n" +
+ "let $xml := \n" +
+ "let $xsl := '/db/" + TEST_COLLECTION_NAME + "/same-dir/a.xsl'\n" +
+ "return transform:transform($xml, $xsl, ())";
+ final String result = execQuery(query);
+ assertEquals("From A
From B
", result);
+ }
+
+ @Test
+ public void transformWithSameDirectoryImportViaXmldbLocation() throws XMLDBException {
+ final String query =
+ "import module namespace transform='http://exist-db.org/xquery/transform';\n" +
+ "let $xml := \n" +
+ "let $xsl := 'xmldb:exist:///db/" + TEST_COLLECTION_NAME + "/same-dir/a.xsl'\n" +
+ "return transform:transform($xml, $xsl, ())";
+ final String result = execQuery(query);
+ assertEquals("From A
From B
", result);
+ }
+
+ @Test
+ public void transformWithSameDirectoryImportViaDbNode() throws XMLDBException {
+ final String query =
+ "import module namespace transform='http://exist-db.org/xquery/transform';\n" +
+ "let $xml := \n" +
+ "let $xsl := doc('/db/" + TEST_COLLECTION_NAME + "/same-dir/a.xsl')\n" +
+ "return transform:transform($xml, $xsl, ())";
+ final String result = execQuery(query);
+ assertEquals("From A
From B
", result);
+ }
+
+ @Test
+ public void transformWithSameDirectoryImportViaXmldbNode() throws XMLDBException {
+ final String query =
+ "import module namespace transform='http://exist-db.org/xquery/transform';\n" +
+ "let $xml := \n" +
+ "let $xsl := doc('xmldb:exist:///db/" + TEST_COLLECTION_NAME + "/same-dir/a.xsl')\n" +
+ "return transform:transform($xml, $xsl, ())";
+ final String result = execQuery(query);
+ assertEquals("From A
From B
", result);
+ }
private String execQuery(String query) throws XMLDBException {
@@ -174,6 +218,29 @@ public void setUp() throws ClassNotFoundException, IllegalAccessException, Insta
addXMLDocument(xsl1, doc1, "1.xsl");
addXMLDocument(xsl2, doc2, "2.xsl");
addXMLDocument(xsl3, doc3, "3.xsl");
+
+ service = (CollectionManagementService) testCollection.getService("CollectionManagementService", "1.0");
+
+ Collection sameDir = service.createCollection("same-dir");
+ assertNotNull(sameDir);
+
+ String docA = "\n" +
+ "\n"+
+ "\n" +
+ "" +
+ "From A
" +
+ "" +
+ "";
+
+ String docB = "\n" +
+ "\n"+
+ "" +
+ "From B
" +
+ "" +
+ "";
+
+ addXMLDocument(sameDir, docA, "a.xsl");
+ addXMLDocument(sameDir, docB, "b.xsl");
}
@After
diff --git a/exist-core/src/test/java/org/exist/xquery/XQueryTest.java b/exist-core/src/test/java/org/exist/xquery/XQueryTest.java
index a33248f1d8..6a4a905335 100644
--- a/exist-core/src/test/java/org/exist/xquery/XQueryTest.java
+++ b/exist-core/src/test/java/org/exist/xquery/XQueryTest.java
@@ -2592,14 +2592,14 @@ public void resolveBaseURI_1841635() throws XMLDBException {
ResourceSet result = service.query(query);
assertEquals(1, result.getSize());
- assertEquals("/db/test/baseuri.xml", result.getResource(0).getContent().toString());
+ assertEquals("xmldb:exist:///db/test/baseuri.xml", result.getResource(0).getContent().toString());
query = "doc('/db/test/baseuri.xml')/Root/Node1/base-uri()";
result = service.query(query);
assertEquals(1, result.getSize());
- assertEquals("/db/test/baseuri.xml", result.getResource(0).getContent().toString());
+ assertEquals("xmldb:exist:///db/test/baseuri.xml", result.getResource(0).getContent().toString());
query = "doc('/db/test/baseuri.xml')/Root/Node1/Node2/base-uri()";
@@ -2607,14 +2607,14 @@ public void resolveBaseURI_1841635() throws XMLDBException {
result = service.query(query);
assertEquals(1, result.getSize());
- assertEquals("/db/test/baseuri.xml", result.getResource(0).getContent().toString());
+ assertEquals("xmldb:exist:///db/test/baseuri.xml", result.getResource(0).getContent().toString());
query = "doc('/db/test/baseuri.xml')/Root/Node1/Node2/Node3/base-uri()";
result = service.query(query);
assertEquals(1, result.getSize());
- assertEquals("/db/test/baseuri.xml", result.getResource(0).getContent().toString());
+ assertEquals("xmldb:exist:///db/test/baseuri.xml", result.getResource(0).getContent().toString());
}
/**
diff --git a/exist-core/src/test/java/org/exist/xquery/functions/fn/transform/FunTransformITTest.java b/exist-core/src/test/java/org/exist/xquery/functions/fn/transform/FunTransformITTest.java
index 1ca74a5b9e..aa1a152413 100644
--- a/exist-core/src/test/java/org/exist/xquery/functions/fn/transform/FunTransformITTest.java
+++ b/exist-core/src/test/java/org/exist/xquery/functions/fn/transform/FunTransformITTest.java
@@ -58,6 +58,47 @@
*/
public class FunTransformITTest {
+ private static final XmldbURI TEST_IMPORT_XSLT_COLLECTION = XmldbURI.create("/db/fn-transform-import-test");
+ private static final XmldbURI IMPORT_A_XSLT_NAME = XmldbURI.create("a.xsl");
+ private static final XmldbURI IMPORT_B_XSLT_NAME = XmldbURI.create("b.xsl");
+
+ private static final String IMPORT_A_XSLT =
+ "\n" +
+ " \n" +
+ " \n" +
+ " From A
\n" +
+ " \n" +
+ "";
+
+ private static final String IMPORT_B_XSLT =
+ "\n" +
+ " From B
\n" +
+ "";
+
+ private static final String SAME_DIR_IMPORT_VIA_DB_LOCATION_QUERY =
+ "fn:transform(map {\n" +
+ " \"stylesheet-location\": \"/db/fn-transform-import-test/a.xsl\",\n" +
+ " \"source-node\": document { }\n" +
+ "})?output";
+
+ private static final String SAME_DIR_IMPORT_VIA_XMLDB_LOCATION_QUERY =
+ "fn:transform(map {\n" +
+ " \"stylesheet-location\": \"xmldb:exist:///db/fn-transform-import-test/a.xsl\",\n" +
+ " \"source-node\": document { }\n" +
+ "})?output";
+
+ private static final String SAME_DIR_IMPORT_VIA_DB_NODE_QUERY =
+ "fn:transform(map {\n" +
+ " \"stylesheet-node\": doc(\"/db/fn-transform-import-test/a.xsl\"),\n" +
+ " \"source-node\": document { }\n" +
+ "})?output";
+
+ private static final String SAME_DIR_IMPORT_VIA_XMLDB_NODE_QUERY =
+ "fn:transform(map {\n" +
+ " \"stylesheet-node\": doc(\"xmldb:exist:///db/fn-transform-import-test/a.xsl\"),\n" +
+ " \"source-node\": document { }\n" +
+ "})?output";
+
private static final XmldbURI TEST_IDENTITY_XSLT_COLLECTION = XmldbURI.create("/db/transform-identity-test");
private static final XmldbURI IDENTITY_XSLT_NAME = XmldbURI.create("xsl-identity.xslt");
@@ -143,6 +184,30 @@ public class FunTransformITTest {
@ClassRule
public static ExistEmbeddedServer existEmbeddedServer = new ExistEmbeddedServer(true, true);
+ @Test
+ public void sameDirectoryImportViaDbLocation() throws XPathException, PermissionDeniedException, EXistException {
+ final Source expected = Input.fromString("From A
From B
").build();
+ expectQuery(SAME_DIR_IMPORT_VIA_DB_LOCATION_QUERY, expected);
+ }
+
+ @Test
+ public void sameDirectoryImportViaXmldbLocation() throws XPathException, PermissionDeniedException, EXistException {
+ final Source expected = Input.fromString("From A
From B
").build();
+ expectQuery(SAME_DIR_IMPORT_VIA_XMLDB_LOCATION_QUERY, expected);
+ }
+
+ @Test
+ public void sameDirectoryImportViaDbNode() throws XPathException, PermissionDeniedException, EXistException {
+ final Source expected = Input.fromString("From A
From B
").build();
+ expectQuery(SAME_DIR_IMPORT_VIA_DB_NODE_QUERY, expected);
+ }
+
+ @Test
+ public void sameDirectoryImportViaXmldbNode() throws XPathException, PermissionDeniedException, EXistException {
+ final Source expected = Input.fromString("From A
From B
").build();
+ expectQuery(SAME_DIR_IMPORT_VIA_XMLDB_NODE_QUERY, expected);
+ }
+
@Test
public void identityPersistentDom() throws XPathException, PermissionDeniedException, EXistException {
final Source expected = Input.fromString(IDENTITY_XML).build();
@@ -212,6 +277,11 @@ public static void storeResources() throws EXistException, PermissionDeniedExcep
Tuple(IDENTITY_XML_NAME, IDENTITY_XML)
);
+ createCollection(broker, transaction, TEST_IMPORT_XSLT_COLLECTION,
+ Tuple(IMPORT_A_XSLT_NAME, IMPORT_A_XSLT),
+ Tuple(IMPORT_B_XSLT_NAME, IMPORT_B_XSLT)
+ );
+
transaction.commit();
}
}
diff --git a/exist-core/src/test/xquery/base-uri.xql b/exist-core/src/test/xquery/base-uri.xql
index 3aff020995..6c36ce40b7 100644
--- a/exist-core/src/test/xquery/base-uri.xql
+++ b/exist-core/src/test/xquery/base-uri.xql
@@ -118,7 +118,7 @@ function baseuri:cleanup() {
declare
- %test:assertEquals("-/db/base-uri/test.xml")
+ %test:assertEquals("-xmldb:exist:///db/base-uri/test.xml")
function baseuri:root() {
$baseuri:DOCUMENT/base-uri() || "-" || base-uri(doc($baseuri:full_path_document))
};
@@ -131,7 +131,7 @@ function baseuri:sub1() {
};
declare
- %test:assertEquals("http://example.org/a/","http://example.org/b/","http://example.org/c/","/yy","/db/base-uri/zz")
+ %test:assertEquals("http://example.org/a/","http://example.org/b/","http://example.org/c/","/yy","xmldb:exist:///db/base-uri/zz")
function baseuri:sub2() {
for $sub in doc($baseuri:full_path_document)//sub
return base-uri($sub)
diff --git a/exist-core/src/test/xquery/indexing/indexes-base-uri.xq b/exist-core/src/test/xquery/indexing/indexes-base-uri.xq
index 52acaea094..3921c7b2df 100644
--- a/exist-core/src/test/xquery/indexing/indexes-base-uri.xq
+++ b/exist-core/src/test/xquery/indexing/indexes-base-uri.xq
@@ -1,4 +1,28 @@
(:
+ : Elemental
+ : Copyright (C) 2024, Evolved Binary Ltd
+ :
+ : admin@evolvedbinary.com
+ : https://www.evolvedbinary.com | https://www.elemental.xyz
+ :
+ : This library is free software; you can redistribute it and/or
+ : modify it under the terms of the GNU Lesser General Public
+ : License as published by the Free Software Foundation; version 2.1.
+ :
+ : This library is distributed in the hope that it will be useful,
+ : but WITHOUT ANY WARRANTY; without even the implied warranty of
+ : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ : Lesser General Public License for more details.
+ :
+ : You should have received a copy of the GNU Lesser General Public
+ : License along with this library; if not, write to the Free Software
+ : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ :
+ : NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ : The original license header is included below.
+ :
+ : =====================================================================
+ :
: eXist-db Open Source Native XML Database
: Copyright (C) 2001 The eXist-db Authors
:
@@ -50,7 +74,7 @@ function but:tearDown() {
declare
%test:pending("Each test interferes with each other test, we need to figure out how to have but:tearDown called after every test")
- %test:assertEquals("/db/but/a/data/test.xml", "/db/but/a/data/test.xml", "/db/but/b/data/test.xml")
+ %test:assertEquals("xmldb:exist:///db/but/a/data/test.xml", "xmldb:exist:///db/but/a/data/test.xml", "xmldb:exist:///db/but/b/data/test.xml")
function but:base-uri-after-collection-copy() {
let $test-col-a-data-uri := xmldb:create-collection($but:test-col-a-uri, "data")
let $doc-path := xmldb:store($test-col-a-data-uri, "test.xml", $but:XML)
@@ -66,7 +90,7 @@ function but:base-uri-after-collection-copy() {
};
declare
- %test:assertEquals("/db/but/a/data/test.xml", "/db/but/b/data/test.xml")
+ %test:assertEquals("xmldb:exist:///db/but/a/data/test.xml", "xmldb:exist:///db/but/b/data/test.xml")
function but:base-uri-after-collection-move() {
let $test-col-a-data-uri := xmldb:create-collection($but:test-col-a-uri, "data")
let $doc-path := xmldb:store($test-col-a-data-uri, "test.xml", $but:XML)
@@ -83,7 +107,7 @@ function but:base-uri-after-collection-move() {
declare
%test:pending("Each test interferes with each other test, we need to figure out how to have but:tearDown called after every test")
- %test:assertEquals("/db/but/a/data/test.xml", "/db/but/a/data/test.xml", "/db/but/b/test.xml")
+ %test:assertEquals("xmldb:exist:///db/but/a/data/test.xml", "xmldb:exist:///db/but/a/data/test.xml", "xmldb:exist:///db/but/b/test.xml")
function but:base-uri-after-resource-copy() {
let $test-col-a-data-uri := xmldb:create-collection($but:test-col-a-uri, "data")
let $doc-path := xmldb:store($test-col-a-data-uri, "test.xml", $but:XML)
@@ -100,7 +124,7 @@ function but:base-uri-after-resource-copy() {
declare
%test:pending("Each test interferes with each other test, we need to figure out how to have but:tearDown called after every test")
- %test:assertEquals("/db/but/a/data/test.xml", "/db/but/b/test.xml")
+ %test:assertEquals("xmldb:exist:///db/but/a/data/test.xml", "xmldb:exist:///db/but/b/test.xml")
function but:base-uri-after-resource-move() {
let $test-col-a-data-uri := xmldb:create-collection($but:test-col-a-uri, "data")
let $doc-path := xmldb:store($test-col-a-data-uri, "test.xml", $but:XML)
diff --git a/extensions/indexes/lucene/src/main/java/org/exist/indexing/lucene/AbstractFieldConfig.java b/extensions/indexes/lucene/src/main/java/org/exist/indexing/lucene/AbstractFieldConfig.java
index 42c264fdce..76003da71f 100644
--- a/extensions/indexes/lucene/src/main/java/org/exist/indexing/lucene/AbstractFieldConfig.java
+++ b/extensions/indexes/lucene/src/main/java/org/exist/indexing/lucene/AbstractFieldConfig.java
@@ -172,20 +172,30 @@ protected CompiledXQuery compile(DBBroker broker, String code) {
}
}
- private String resolveURI(String baseURI, String location) {
+ private String resolveURI(@Nullable final String strBaseUri, final String strLocation) {
try {
- final URI uri = new URI(location);
- if (!uri.isAbsolute() && baseURI != null && baseURI.startsWith(CollectionConfigurationManager.CONFIG_COLLECTION)) {
- String base = baseURI.substring(CollectionConfigurationManager.CONFIG_COLLECTION.length());
- final int lastSlash = base.lastIndexOf('/');
- if (lastSlash > -1) {
- base = base.substring(0, lastSlash);
+ final URI uriLocation = new URI(strLocation);
+ if (!uriLocation.isAbsolute() && strBaseUri != null) {
+ if (strBaseUri.startsWith(CollectionConfigurationManager.CONFIG_COLLECTION)) {
+ String base = strBaseUri.substring(CollectionConfigurationManager.CONFIG_COLLECTION.length());
+ final int lastSlash = base.lastIndexOf('/');
+ if (lastSlash > -1) {
+ base = base.substring(0, lastSlash);
+ }
+ final String resolved = XmldbURI.EMBEDDED_SERVER_URI_PREFIX + base + '/' + strLocation;
+ return resolved;
+ }
+
+ if (strBaseUri.startsWith(XmldbURI.EMBEDDED_SERVER_URI_PREFIX + CollectionConfigurationManager.CONFIG_COLLECTION)) {
+ final String basePath = strBaseUri.substring((XmldbURI.EMBEDDED_SERVER_URI_PREFIX + CollectionConfigurationManager.CONFIG_COLLECTION).length());
+ final String locationPath = new URI(basePath).resolve(uriLocation).toString();
+ final String resolved = XmldbURI.EMBEDDED_SERVER_URI_PREFIX + locationPath;
+ return resolved;
}
- return XmldbURI.EMBEDDED_SERVER_URI_PREFIX + base + '/' + location;
}
- } catch (URISyntaxException e) {
+ } catch (final URISyntaxException e) {
// ignore and return location
}
- return location;
+ return strLocation;
}
}
diff --git a/extensions/indexes/lucene/src/main/java/org/exist/xquery/modules/lucene/Query.java b/extensions/indexes/lucene/src/main/java/org/exist/xquery/modules/lucene/Query.java
index d9780e91ec..e2e658f249 100644
--- a/extensions/indexes/lucene/src/main/java/org/exist/xquery/modules/lucene/Query.java
+++ b/extensions/indexes/lucene/src/main/java/org/exist/xquery/modules/lucene/Query.java
@@ -258,7 +258,7 @@ public NodeSet preSelect(final Sequence contextSequence, final boolean useContex
final LuceneIndexWorker index = (LuceneIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(LuceneIndex.ID);
final DocumentSet docs = contextSequence.getDocumentSet();
- final Item key = getKey(contextSequence, null);
+ @Nullable final Item key = getKey(contextSequence, null);
@Nullable final List qnames = contextQNames != null ? Arrays.asList(contextQNames) : null;
final QueryOptions options = parseOptions(this, contextSequence, null, 3);
try {