diff --git a/exist-core/pom.xml b/exist-core/pom.xml index de72cfe9b4..330179a94d 100644 --- a/exist-core/pom.xml +++ b/exist-core/pom.xml @@ -803,6 +803,7 @@ src/test/resources/log4j2.xml src/test/resources/standalone-webapp/WEB-INF/web.xml src/main/xjb/rest-api.xjb + src/test/xquery/base-uri.xql src/test/xquery/parenthesizedLocationStep.xml src/test/xquery/tail-recursion.xml src/test/xquery/maps/maps.xqm @@ -893,6 +894,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/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 @@ -923,6 +925,7 @@ src/main/java/org/exist/dom/persistent/EmptyNodeSet.java src/main/java/org/exist/dom/persistent/LockToken.java src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java + src/main/java/org/exist/dom/persistent/NodeImpl.java src/main/java/org/exist/dom/persistent/NodeProxy.java src/main/java/org/exist/dom/persistent/NodeSet.java src/test/java/org/exist/dom/persistent/NodeTest.java @@ -1510,6 +1513,7 @@ src/test/resources/log4j2.xml src/test/resources/standalone-webapp/WEB-INF/web.xml src/main/xjb/rest-api.xjb + src/test/xquery/base-uri.xql src/test/xquery/binary-value.xqm src/test/xquery/instance-of.xqm src/test/xquery/operator-mapping.xqm @@ -1612,6 +1616,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/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 @@ -1650,6 +1655,7 @@ src/main/java/org/exist/dom/persistent/EmptyNodeSet.java src/main/java/org/exist/dom/persistent/LockToken.java src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java + src/main/java/org/exist/dom/persistent/NodeImpl.java src/main/java/org/exist/dom/persistent/NodeProxy.java src/main/java/org/exist/dom/persistent/NodeSet.java src/test/java/org/exist/dom/persistent/NodeTest.java diff --git a/exist-core/src/main/java/org/exist/dom/memtree/AttrImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/AttrImpl.java index ba9dcf0479..b3341a7f13 100644 --- a/exist-core/src/main/java/org/exist/dom/memtree/AttrImpl.java +++ b/exist-core/src/main/java/org/exist/dom/memtree/AttrImpl.java @@ -53,6 +53,8 @@ import org.exist.xquery.value.Type; import org.w3c.dom.*; +import javax.annotation.Nullable; + public class AttrImpl extends NodeImpl implements Attr { @@ -90,9 +92,9 @@ public int getType() { } @Override - public String getBaseURI() { - final Node parent = document.getNode(document.attrParent[nodeNumber]); - if(parent == null) { + public @Nullable String getBaseURI() { + @Nullable final Node parent = document.getNode(document.attrParent[nodeNumber]); + if (parent == null) { return null; } return parent.getBaseURI(); diff --git a/exist-core/src/main/java/org/exist/dom/memtree/CommentImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/CommentImpl.java index 9438d5f760..b75eda3e7b 100644 --- a/exist-core/src/main/java/org/exist/dom/memtree/CommentImpl.java +++ b/exist-core/src/main/java/org/exist/dom/memtree/CommentImpl.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 * @@ -29,6 +53,8 @@ import org.w3c.dom.Comment; import org.w3c.dom.Node; +import javax.annotation.Nullable; + public class CommentImpl extends AbstractCharacterData implements Comment { public CommentImpl(final DocumentImpl doc, final int nodeNumber) { @@ -53,9 +79,9 @@ public AtomicValue atomize() throws XPathException { } @Override - public String getBaseURI() { - final Node parent = getParentNode(); - if(parent == null) { + public @Nullable String getBaseURI() { + @Nullable final Node parent = getParentNode(); + if (parent == null) { return null; } return parent.getBaseURI(); diff --git a/exist-core/src/main/java/org/exist/dom/memtree/DocumentImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/DocumentImpl.java index 9270b1652f..93b41a3f22 100644 --- a/exist-core/src/main/java/org/exist/dom/memtree/DocumentImpl.java +++ b/exist-core/src/main/java/org/exist/dom/memtree/DocumentImpl.java @@ -1657,26 +1657,28 @@ public XQueryContext getContext() { } @Override - public String getBaseURI() { - final Element el = getDocumentElement(); - if(el != null) { + public @Nullable String getBaseURI() { + @Nullable final Element el = getDocumentElement(); + if (el != null) { final String baseURI = getDocumentElement().getAttributeNS(Namespaces.XML_NS, "base"); - if(baseURI != null) { + if (!baseURI.isEmpty()) { return baseURI; } } - final String docURI = getDocumentURI(); - if(docURI != null) { + + @Nullable final String docURI = getDocumentURI(); + if (docURI != null) { return docURI; } else { - if(context!=null && context.isBaseURIDeclared()) { + if (context != null && context.isBaseURIDeclared()) { try { return context.getBaseURI().getStringValue(); - } catch(final XPathException e) { - //TODO : make something ! + } catch (final XPathException e) { + // no-op } } - return XmldbURI.EMPTY_URI.toString(); + + return null; } } diff --git a/exist-core/src/main/java/org/exist/dom/memtree/ElementImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/ElementImpl.java index ab1b674080..260f69196b 100644 --- a/exist-core/src/main/java/org/exist/dom/memtree/ElementImpl.java +++ b/exist-core/src/main/java/org/exist/dom/memtree/ElementImpl.java @@ -61,6 +61,7 @@ import org.exist.xquery.value.ValueSequence; import org.w3c.dom.*; +import javax.annotation.Nullable; import javax.xml.XMLConstants; import java.util.HashMap; import java.util.HashSet; @@ -619,18 +620,18 @@ public int getItemType() { } @Override - public String getBaseURI() { - final XmldbURI baseURI = calculateBaseURI(); - if(baseURI != null) { + public @Nullable String getBaseURI() { + @Nullable final XmldbURI baseURI = calculateBaseURI(); + if (baseURI != null) { return baseURI.toString(); } - return "";//UNDERSTAND: is it ok? + return null; } // NOTE(AR) please keep in sync with org.exist.dom.persistent.ElementImpl - private XmldbURI calculateBaseURI() { - XmldbURI baseURI = null; + private @Nullable XmldbURI calculateBaseURI() { + @Nullable XmldbURI baseURI = null; final String nodeBaseURI = getAttributeNS(Namespaces.XML_NS, "base"); if (!nodeBaseURI.isEmpty()) { @@ -648,27 +649,32 @@ private XmldbURI calculateBaseURI() { if (parent != -1) { if (nodeBaseURI.isEmpty()) { - baseURI = ((ElementImpl) document.getNode(parent)) - .calculateBaseURI(); + baseURI = ((ElementImpl) document.getNode(parent)).calculateBaseURI(); } else { - final XmldbURI parentsBaseURI = ((ElementImpl) document.getNode(parent)).calculateBaseURI(); - if (parentsBaseURI.toString().endsWith("/") || !parentsBaseURI.toString().contains("/")) { - baseURI = parentsBaseURI.append(baseURI); + @Nullable final XmldbURI parentsBaseURI = ((ElementImpl) document.getNode(parent)).calculateBaseURI(); + if (parentsBaseURI == null) { + baseURI = null; } else { - // there is a filename, remove it - baseURI = parentsBaseURI.removeLastSegment().append(baseURI); + if (parentsBaseURI.toString().endsWith("/") || !parentsBaseURI.toString().contains("/")) { + baseURI = parentsBaseURI.append(baseURI); + } else { + // there is a filename, remove it + baseURI = parentsBaseURI.removeLastSegment().append(baseURI); + } } } } else { - if (nodeBaseURI.isEmpty()) { - return XmldbURI.create(getOwnerDocument().getBaseURI(), false); + @Nullable final String docBaseURI = getOwnerDocument().getBaseURI(); + if (docBaseURI == null) { + baseURI = null; + } else if (nodeBaseURI.isEmpty()) { + baseURI = XmldbURI.create(docBaseURI, false); } else if (nodeNumber != 1) { - final String docBaseURI = getOwnerDocument().getBaseURI(); if (docBaseURI.endsWith("/")) { - baseURI = XmldbURI.create(getOwnerDocument().getBaseURI(), false); + baseURI = XmldbURI.create(docBaseURI, false); baseURI.append(baseURI); } else { - baseURI = XmldbURI.create(getOwnerDocument().getBaseURI(), false); + baseURI = XmldbURI.create(docBaseURI, false); baseURI = baseURI.removeLastSegment(); baseURI.append(baseURI); } diff --git a/exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java index 0f5cbfa870..82cd0ddd60 100644 --- a/exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java +++ b/exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java @@ -770,7 +770,7 @@ public void removeDuplicates() { } @Override - public String getBaseURI() { + public @Nullable String getBaseURI() { return null; } diff --git a/exist-core/src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java index 913682b992..4f8a97cc6f 100644 --- a/exist-core/src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java +++ b/exist-core/src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java @@ -57,6 +57,8 @@ import org.w3c.dom.Node; import org.w3c.dom.ProcessingInstruction; +import javax.annotation.Nullable; + public class ProcessingInstructionImpl extends NodeImpl implements ProcessingInstruction { @@ -102,37 +104,12 @@ public void setData(final String data) throws DOMException { } @Override - public String getBaseURI() { - String baseURI = ""; - int parent = -1; - int test = document.getParentNodeFor(nodeNumber); - - if(document.nodeKind[test] != Node.DOCUMENT_NODE) { - parent = test; - } - - // fixme! Testa med 0/ljo - while((parent != -1) && (document.getNode(parent).getBaseURI() != null)) { - - if(baseURI.isEmpty()) { - baseURI = document.getNode(parent).getBaseURI(); - } else { - baseURI = document.getNode(parent).getBaseURI() + "/" + baseURI; - } - - test = document.getParentNodeFor(parent); - - if(document.nodeKind[test] == Node.DOCUMENT_NODE) { - return (baseURI); - } else { - parent = test; - } - } - - if(baseURI.isEmpty()) { - baseURI = getOwnerDocument().getBaseURI(); + public @Nullable String getBaseURI() { + @Nullable final Node parent = getParentNode(); + if (parent == null) { + return null; } - return (baseURI); + return parent.getBaseURI(); } @Override diff --git a/exist-core/src/main/java/org/exist/dom/memtree/TextImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/TextImpl.java index 55aa7ad886..11efd59387 100644 --- a/exist-core/src/main/java/org/exist/dom/memtree/TextImpl.java +++ b/exist-core/src/main/java/org/exist/dom/memtree/TextImpl.java @@ -24,8 +24,11 @@ import org.exist.xquery.Expression; import org.exist.xquery.value.Type; import org.w3c.dom.DOMException; +import org.w3c.dom.Node; import org.w3c.dom.Text; +import javax.annotation.Nullable; + public class TextImpl extends AbstractCharacterData implements Text { @@ -42,6 +45,15 @@ public int getItemType() { return Type.TEXT; } + @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 a829fb5639..6f2dff640c 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 @@ -60,6 +60,7 @@ import org.exist.xquery.Expression; import org.w3c.dom.*; +import javax.annotation.Nullable; import javax.xml.XMLConstants; import static java.nio.charset.StandardCharsets.UTF_8; @@ -421,9 +422,9 @@ public boolean isId() { } @Override - public String getBaseURI() { - final Element e = getOwnerElement(); - if(e != null) { + public @Nullable String getBaseURI() { + @Nullable final Element e = getOwnerElement(); + if (e != null) { return e.getBaseURI(); } return null; 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 99d7ec3c7a..9ad5f108cb 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 @@ -53,6 +53,8 @@ import org.w3c.dom.Comment; import org.w3c.dom.Node; +import javax.annotation.Nullable; + import static java.nio.charset.StandardCharsets.UTF_8; public class CommentImpl extends AbstractCharacterData implements Comment { @@ -86,6 +88,16 @@ public String toString() { return ""; } + @Override + public @Nullable String getBaseURI() { + @Nullable final Node parent = getParentNode(); + if (parent != null) { + return parent.getBaseURI(); + } else { + return null; + } + } + /** * Serializes a (persistent DOM) Comment to a byte array * 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 c58e77d777..24e3f489d4 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 @@ -2000,18 +2000,18 @@ public void setIdAttributeNode(final Attr idAttr, final boolean isId) throws DOM } @Override - public String getBaseURI() { - final XmldbURI baseURI = calculateBaseURI(); - if(baseURI != null) { + public @Nullable String getBaseURI() { + @Nullable final XmldbURI baseURI = calculateBaseURI(); + if (baseURI != null) { return baseURI.toString(); } - return ""; //UNDERSTAND: is it ok? + return null; } // NOTE(AR) please keep in sync with org.exist.dom.memtree.ElementImpl private XmldbURI calculateBaseURI() { - XmldbURI baseURI = null; + @Nullable XmldbURI baseURI = null; final String nodeBaseURI = getAttributeNS(Namespaces.XML_NS, "base"); if (!nodeBaseURI.isEmpty()) { @@ -2022,28 +2022,35 @@ private XmldbURI calculateBaseURI() { } final IStoredNode parent = getParentStoredNode(); + if (parent != null) { if (nodeBaseURI.isEmpty()) { baseURI = ((ElementImpl) parent).calculateBaseURI(); } else { - final XmldbURI parentsBaseURI = ((ElementImpl) parent).calculateBaseURI(); - if (parentsBaseURI.toString().endsWith("/") || !parentsBaseURI.toString().contains("/")) { - baseURI = parentsBaseURI.append(baseURI); + @Nullable final XmldbURI parentsBaseURI = ((ElementImpl) parent).calculateBaseURI(); + if (parentsBaseURI == null) { + baseURI = null; } else { - // there is a filename, remove it - baseURI = parentsBaseURI.removeLastSegment().append(baseURI); + if (parentsBaseURI.toString().endsWith("/") || !parentsBaseURI.toString().contains("/")) { + baseURI = parentsBaseURI.append(baseURI); + } else { + // there is a filename, remove it + baseURI = parentsBaseURI.removeLastSegment().append(baseURI); + } } } } else { - if (nodeBaseURI.isEmpty()) { - return XmldbURI.create(getOwnerDocument().getBaseURI(), false); + @Nullable final String docBaseURI = getOwnerDocument().getBaseURI(); + if (docBaseURI == null) { + baseURI = null; + } else if (nodeBaseURI.isEmpty()) { + baseURI = XmldbURI.create(docBaseURI, false); } else { - final String docBaseURI = getOwnerDocument().getBaseURI(); if (docBaseURI.endsWith("/")) { - baseURI = XmldbURI.create(getOwnerDocument().getBaseURI(), false); + baseURI = XmldbURI.create(docBaseURI, false); baseURI.append(baseURI); } else { - baseURI = XmldbURI.create(getOwnerDocument().getBaseURI(), false); + baseURI = XmldbURI.create(docBaseURI, false); baseURI = baseURI.removeLastSegment(); baseURI.append(baseURI); } diff --git a/exist-core/src/main/java/org/exist/dom/persistent/NodeImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/NodeImpl.java index 893f88b534..354dc98a63 100644 --- a/exist-core/src/main/java/org/exist/dom/persistent/NodeImpl.java +++ b/exist-core/src/main/java/org/exist/dom/persistent/NodeImpl.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 * @@ -30,6 +54,7 @@ import org.exist.xquery.Expression; import org.w3c.dom.*; +import javax.annotation.Nullable; import javax.xml.XMLConstants; public abstract class NodeImpl implements INode { @@ -187,8 +212,8 @@ public void normalize() { } @Override - public String getBaseURI() { - throw unsupported(); + public @Nullable String getBaseURI() { + return null; } @Override 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 1f16448e98..6a42f27b0e 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 @@ -55,6 +55,8 @@ import org.w3c.dom.Node; import org.w3c.dom.ProcessingInstruction; +import javax.annotation.Nullable; + import static java.nio.charset.StandardCharsets.UTF_8; /** @@ -148,13 +150,10 @@ public void setData(final String data) { this.data = data; } - /** - * ? @see org.w3c.dom.Node#getBaseURI() - */ @Override - public String getBaseURI() { - final StoredNode parent = getParentStoredNode(); - if(parent != null) { + public @Nullable String getBaseURI() { + @Nullable final StoredNode parent = getParentStoredNode(); + if (parent != null) { return parent.getBaseURI(); } 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 7887e0b0ce..6c9d9c8971 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 @@ -58,6 +58,8 @@ import org.w3c.dom.Text; import org.w3c.dom.UserDataHandler; +import javax.annotation.Nullable; + /** * TextImpl.java * @@ -175,9 +177,9 @@ public Text splitText(final int offset) throws DOMException { } @Override - public String getBaseURI() { - final Node parent = getParentNode(); - if(parent != null) { + public @Nullable String getBaseURI() { + @Nullable final Node parent = getParentNode(); + if (parent != null) { return parent.getBaseURI(); } else { return null; diff --git a/exist-core/src/main/java/org/exist/xquery/functions/fn/FunBaseURI.java b/exist-core/src/main/java/org/exist/xquery/functions/fn/FunBaseURI.java index b23870a6e6..c2b7291850 100644 --- a/exist-core/src/main/java/org/exist/xquery/functions/fn/FunBaseURI.java +++ b/exist-core/src/main/java/org/exist/xquery/functions/fn/FunBaseURI.java @@ -50,6 +50,7 @@ import org.exist.xquery.value.*; import org.w3c.dom.Node; +import javax.annotation.Nullable; import java.net.URI; import java.net.URISyntaxException; @@ -172,7 +173,7 @@ public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathExce final boolean hasContextBaseURI = context.isBaseURIDeclared(); // "" when not set, can be null - final String nodeBaseURI = node.getBaseURI(); + @Nullable final String nodeBaseURI = node.getBaseURI(); final boolean hasNodeBaseURI = notNullOrEmptyOrWs(nodeBaseURI); try { diff --git a/exist-core/src/test/java/org/exist/dom/memtree/DocumentImplTest.java b/exist-core/src/test/java/org/exist/dom/memtree/DocumentImplTest.java index 7fdb1113b9..0dcc7b2055 100644 --- a/exist-core/src/test/java/org/exist/dom/memtree/DocumentImplTest.java +++ b/exist-core/src/test/java/org/exist/dom/memtree/DocumentImplTest.java @@ -206,6 +206,36 @@ public void testGetInScopePrefix() throws IOException, ParserConfigurationExcept assertEquals(Namespaces.XHTML_NS, namespaceUri); } + @Test + public void getBaseURI_withDocumentURI() throws IOException, SAXException, ParserConfigurationException { + final DocumentImpl doc; + try(final InputStream is = new UnsynchronizedByteArrayInputStream("".getBytes(UTF_8))) { + doc = parseExist(is); + } + doc.setDocumentURI("file:///intranet/xsl/template.xsl"); + assertEquals("file:///intranet/xsl/template.xsl", doc.getBaseURI()); + } + + @Test + public void getBaseURI_prefersXmlBaseOnRoot() throws IOException, SAXException, ParserConfigurationException { + final DocumentImpl doc; + try(final InputStream is = new UnsynchronizedByteArrayInputStream( + "".getBytes(UTF_8))) { + doc = parseExist(is); + } + doc.setDocumentURI("file:///intranet/xsl/template.xsl"); + assertEquals("http://example.org/", doc.getBaseURI()); + } + + @Test + public void getBaseURI_noDocumentURI() throws IOException, SAXException, ParserConfigurationException { + final DocumentImpl doc; + try(final InputStream is = new UnsynchronizedByteArrayInputStream("".getBytes(UTF_8))) { + doc = parseExist(is); + } + assertNull("", doc.getBaseURI()); + } + private Document parseXerces(final InputStream is) throws ParserConfigurationException, SAXException, IOException { final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); diff --git a/exist-core/src/test/xquery/base-uri.xql b/exist-core/src/test/xquery/base-uri.xql index 51b46bb64f..3aff020995 100644 --- a/exist-core/src/test/xquery/base-uri.xql +++ b/exist-core/src/test/xquery/base-uri.xql @@ -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 : @@ -100,7 +124,7 @@ function baseuri:root() { }; declare - %test:assertEquals("http://example.org/a/","http://example.org/b/","http://example.org/c/","/yy","zz") + %test:assertEquals("http://example.org/a/","http://example.org/b/","http://example.org/c/","/yy") function baseuri:sub1() { for $sub in $baseuri:DOCUMENT//sub return base-uri($sub)