diff --git a/exist-core/pom.xml b/exist-core/pom.xml index 8f0b69ed8b..5d709d5a5a 100644 --- a/exist-core/pom.xml +++ b/exist-core/pom.xml @@ -778,6 +778,9 @@ src/test/java/org/exist/xquery/functions/fn/transform/FunTransformITTest.java src/test/java/org/exist/xquery/functions/securitymanager/AccountMetadataFunctionsTest.java src/test/java/org/exist/xquery/functions/securitymanager/SecurityManagerTestUtil.java + src/test/java/org/exist/xquery/functions/system/GetMainModuleLoadPathTest.java + src/main/java/org/exist/xquery/functions/system/GetModuleLoadPath.java + src/test/java/org/exist/xquery/functions/system/GetModuleLoadPathTest.java src/main/java/org/exist/xquery/functions/system/FunctionAvailable.java src/test/java/org/exist/xquery/functions/xmldb/XMLDBStoreTest.java src/test/java/org/exist/xquery/functions/xquery3/SerializeTest.java @@ -2445,6 +2448,9 @@ src/test/java/org/exist/xquery/functions/session/AbstractSessionTest.java src/test/java/org/exist/xquery/functions/session/AttributeTest.java src/main/java/org/exist/xquery/functions/system/FunctionAvailable.java + src/test/java/org/exist/xquery/functions/system/GetMainModuleLoadPathTest.java + src/main/java/org/exist/xquery/functions/system/GetModuleLoadPath.java + src/test/java/org/exist/xquery/functions/system/GetModuleLoadPathTest.java src/test/java/org/exist/xquery/functions/system/GetRunningXQueriesTest.java src/main/java/org/exist/xquery/functions/system/GetUptime.java src/main/java/org/exist/xquery/functions/system/Restore.java diff --git a/exist-core/src/main/java/org/exist/xquery/functions/system/GetModuleLoadPath.java b/exist-core/src/main/java/org/exist/xquery/functions/system/GetModuleLoadPath.java index b30b8b6080..7910e34556 100644 --- a/exist-core/src/main/java/org/exist/xquery/functions/system/GetModuleLoadPath.java +++ b/exist-core/src/main/java/org/exist/xquery/functions/system/GetModuleLoadPath.java @@ -1,14 +1,13 @@ /* - * eXist-db Open Source Native XML Database - * Copyright (C) 2001 The eXist-db Authors + * Elemental + * Copyright (C) 2024, Evolved Binary Ltd * - * info@exist-db.org - * http://www.exist-db.org + * 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; either - * version 2.1 of the License, or (at your option) any later version. + * 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 @@ -21,41 +20,52 @@ */ package org.exist.xquery.functions.system; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.exist.dom.QName; import org.exist.xquery.BasicFunction; -import org.exist.xquery.Cardinality; import org.exist.xquery.FunctionSignature; import org.exist.xquery.XPathException; import org.exist.xquery.XQueryContext; -import org.exist.xquery.value.FunctionReturnSequenceType; import org.exist.xquery.value.Sequence; import org.exist.xquery.value.StringValue; import org.exist.xquery.value.Type; -public class GetModuleLoadPath extends BasicFunction { +import javax.annotation.Nullable; + +import static org.exist.xquery.FunctionDSL.returns; +import static org.exist.xquery.functions.system.SystemModule.functionSignature; - protected final static Logger logger = LogManager.getLogger(GetModuleLoadPath.class); +public class GetModuleLoadPath extends BasicFunction { - public final static FunctionSignature signature = - new FunctionSignature( - new QName("get-module-load-path", SystemModule.NAMESPACE_URI, SystemModule.PREFIX), - "Returns the module load path from the current query context. The module load path " + - "corresponds to the location on the file system from where modules are loaded " + - "into an XQuery. This is usually the directory from which the main XQuery was " + - "compiled, or - when executing a stored XQuery - the collection in which the main " + - "query resides. The module load path " + - "is also used to resolve relative XInclude paths.", - FunctionSignature.NO_ARGS, - new FunctionReturnSequenceType(Type.STRING, Cardinality.EXACTLY_ONE, "the load path")); + private static final String FS_GET_MODULE_LOAD_PATH_NAME = "get-module-load-path"; + public static final FunctionSignature FS_GET_MODULE_LOAD_PATH = functionSignature( + FS_GET_MODULE_LOAD_PATH_NAME, + "Returns the path from which the module was loaded. Either a filesystem directory, or database collection. If the path cannot be determined, for example because the query module is in-memory then '.' is returned.", + returns(Type.STRING, "The path from which the module was loaded") + ); + private static final String FS_GET_MAIN_MODULE_LOAD_PATH_NAME = "get-main-module-load-path"; + public static final FunctionSignature FS_GET_MAIN_MODULE_LOAD_PATH = functionSignature( + FS_GET_MAIN_MODULE_LOAD_PATH_NAME, + "Returns the path from which the main module was loaded. If called from a library module, it finds the path of the ancestor main module. Either a filesystem directory, or database collection. If the path cannot be determined, for example because the query module is in-memory then '.' is returned.", + returns(Type.STRING, "The path from which the main module was loaded") + ); - public GetModuleLoadPath(XQueryContext context) { + public GetModuleLoadPath(final XQueryContext context, final FunctionSignature signature) { super(context, signature); } - public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException { - return new StringValue(this, context.getModuleLoadPath()); + @Override + public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException { + final String moduleLoadPath; + if (isCalledAs(FS_GET_MODULE_LOAD_PATH_NAME)) { + moduleLoadPath = context.getModuleLoadPath(); + } else { + @Nullable final XQueryContext rootContext = context.getRootContext(); + if (rootContext == null) { + // there may not be a main module, e.g. RESTXQ resource functions + throw new XPathException(this, "There is no root context as the library module was executed via a named function"); + } + moduleLoadPath = rootContext.getModuleLoadPath(); + } + return new StringValue(this, moduleLoadPath); } } diff --git a/exist-core/src/main/java/org/exist/xquery/functions/system/SystemModule.java b/exist-core/src/main/java/org/exist/xquery/functions/system/SystemModule.java index a6cc18833d..a9682a0816 100644 --- a/exist-core/src/main/java/org/exist/xquery/functions/system/SystemModule.java +++ b/exist-core/src/main/java/org/exist/xquery/functions/system/SystemModule.java @@ -88,7 +88,8 @@ public class SystemModule extends AbstractInternalModule { new FunctionDef(GetExistHome.signature, GetExistHome.class), new FunctionDef(Shutdown.signatures[0], Shutdown.class), new FunctionDef(Shutdown.signatures[1], Shutdown.class), - new FunctionDef(GetModuleLoadPath.signature, GetModuleLoadPath.class), + new FunctionDef(GetModuleLoadPath.FS_GET_MODULE_LOAD_PATH, GetModuleLoadPath.class), + new FunctionDef(GetModuleLoadPath.FS_GET_MAIN_MODULE_LOAD_PATH, GetModuleLoadPath.class), new FunctionDef(TriggerSystemTask.signature, TriggerSystemTask.class), new FunctionDef(AsUser.FS_AS_USER, AsUser.class), new FunctionDef(AsUser.FS_FUNCTION_AS_USER, AsUser.class), diff --git a/exist-core/src/test/java/org/exist/xquery/functions/system/GetMainModuleLoadPathTest.java b/exist-core/src/test/java/org/exist/xquery/functions/system/GetMainModuleLoadPathTest.java new file mode 100644 index 0000000000..ac6bb9bb26 --- /dev/null +++ b/exist-core/src/test/java/org/exist/xquery/functions/system/GetMainModuleLoadPathTest.java @@ -0,0 +1,244 @@ +/* + * 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 + */ +package org.exist.xquery.functions.system; + +import com.evolvedbinary.j8fu.function.ConsumerE; +import org.exist.EXistException; +import org.exist.collections.Collection; +import org.exist.security.PermissionDeniedException; +import org.exist.source.DbUriSource; +import org.exist.source.StringSource; +import org.exist.storage.BrokerPool; +import org.exist.storage.DBBroker; +import org.exist.storage.txn.Txn; +import org.exist.test.ExistEmbeddedServer; +import org.exist.util.LockException; +import org.exist.util.StringInputSource; +import org.exist.xmldb.XmldbURI; +import org.exist.xquery.XPathException; +import org.exist.xquery.XQueryContext; +import org.exist.xquery.XQueryUtil; +import org.exist.xquery.value.Item; +import org.exist.xquery.value.Type; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; +import org.xmlunit.builder.DiffBuilder; +import org.xmlunit.builder.Input; +import org.xmlunit.diff.Diff; + +import javax.xml.transform.Source; +import java.io.IOException; +import java.util.Optional; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.exist.test.Util.storeQuery; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +public class GetMainModuleLoadPathTest { + + private static XmldbURI TEST_COLLECTION_URI = XmldbURI.create("/db/get-main-module-load-path-test"); + private static XmldbURI TEST_SUB_COLLECTION_URI = TEST_COLLECTION_URI.append("sub1"); + + private static XmldbURI STANDALONE_MAIN_MODULE_URI = TEST_COLLECTION_URI.append("standalone-main.xq"); + private static String STANDALONE_MAIN_MODULE_XQ = + "import module namespace system = \"http://exist-db.org/xquery/system\";\n" + + "document {\n" + + " {system:get-main-module-load-path()}\n" + + "}"; + + private static XmldbURI IMPORTED_LIBRARY_MODULE_URI = TEST_SUB_COLLECTION_URI.append("imported-library.xqm"); + private static String IMPORTED_LIBRARY_MODULE_XQ = + "module namespace ilm = \"http://ilm\";\n" + + "import module namespace system = \"http://exist-db.org/xquery/system\";\n" + + "declare function ilm:main-module-load-path() {\n" + + " system:get-main-module-load-path()\n" + + "};"; + + private static XmldbURI IMPORTING_MAIN_MODULE_URI = TEST_COLLECTION_URI.append("importing-main.xq"); + private static String IMPORTING_MAIN_MODULE_XQ = + "import module namespace system = \"http://exist-db.org/xquery/system\";\n" + + "import module namespace ilm = \"http://ilm\" at \"xmldb:exist://" + IMPORTED_LIBRARY_MODULE_URI.getXmldbURI().toString() + "\";\n" + + "document {\n" + + " \n" + + " {system:get-main-module-load-path()}\n" + + " {ilm:main-module-load-path()}\n" + + " \n" + + "}"; + + @ClassRule + public static ExistEmbeddedServer EXIST_EMBEDDED_SERVER = new ExistEmbeddedServer(true, true); + + @BeforeClass + public static void setup() throws EXistException, PermissionDeniedException, IOException, SAXException, LockException { + final BrokerPool brokerPool = EXIST_EMBEDDED_SERVER.getBrokerPool(); + try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject())); + final Txn transaction = brokerPool.getTransactionManager().beginTransaction()) { + + // store xquery documents + try (final Collection testCollection = broker.getOrCreateCollection(transaction, TEST_COLLECTION_URI)) { + storeQuery(broker, transaction, new StringInputSource(STANDALONE_MAIN_MODULE_XQ.getBytes(UTF_8)), testCollection, STANDALONE_MAIN_MODULE_URI); + + try (final Collection testSubCollection = broker.getOrCreateCollection(transaction, TEST_SUB_COLLECTION_URI)) { + storeQuery(broker, transaction, new StringInputSource(IMPORTED_LIBRARY_MODULE_XQ.getBytes(UTF_8)), testSubCollection, IMPORTED_LIBRARY_MODULE_URI); + } + + storeQuery(broker, transaction, new StringInputSource(IMPORTING_MAIN_MODULE_XQ.getBytes(UTF_8)), testCollection, IMPORTING_MAIN_MODULE_URI); + } + + transaction.commit(); + } + } + + @Test + public void standaloneMainModule() throws EXistException, PermissionDeniedException, XPathException, IOException { + final String expected = "."; + + final BrokerPool brokerPool = EXIST_EMBEDDED_SERVER.getBrokerPool(); + try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject())); + final Txn transaction = brokerPool.getTransactionManager().beginTransaction()) { + + try (final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, new StringSource(STANDALONE_MAIN_MODULE_XQ), false, null, null, null, null, null)) { + assertNotNull(queryResult.result); + assertEquals(1, queryResult.result.getItemCount()); + final Item item = queryResult.result.itemAt(0); + assertEquals(Type.DOCUMENT, item.getType()); + + final Source expectedSrc = Input.fromString(expected).build(); + final Source actualSrc = Input.fromNode((Document) item).build(); + + final Diff diff = DiffBuilder.compare(expectedSrc) + .withTest(actualSrc) + .checkForSimilar() + .build(); + + assertFalse(diff.toString(), diff.hasDifferences()); + } + + transaction.commit(); + } + } + + @Test + public void importingMainModule() throws EXistException, PermissionDeniedException, XPathException, IOException { + final String expected = + "" + + "." + + "." + + ""; + + final BrokerPool brokerPool = EXIST_EMBEDDED_SERVER.getBrokerPool(); + try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject())); + final Txn transaction = brokerPool.getTransactionManager().beginTransaction()) { + + try (final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, new StringSource(IMPORTING_MAIN_MODULE_XQ), false, null, null, null, null, null)) { + assertNotNull(queryResult.result); + assertEquals(1, queryResult.result.getItemCount()); + final Item item = queryResult.result.itemAt(0); + assertEquals(Type.DOCUMENT, item.getType()); + + final Source expectedSrc = Input.fromString(expected).build(); + final Source actualSrc = Input.fromNode((Document) item).build(); + + final Diff diff = DiffBuilder.compare(expectedSrc) + .withTest(actualSrc) + .checkForSimilar() + .build(); + + assertFalse(diff.toString(), diff.hasDifferences()); + } + + transaction.commit(); + } + } + + + @Test + public void storedStandaloneMainModule() throws EXistException, PermissionDeniedException, XPathException, IOException { + final String expected = "" + TEST_COLLECTION_URI.getCollectionPath() + ""; + + final BrokerPool brokerPool = EXIST_EMBEDDED_SERVER.getBrokerPool(); + try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject())); + final Txn transaction = brokerPool.getTransactionManager().beginTransaction()) { + + final ConsumerE preCompilationContextSetup = xqueryContext -> xqueryContext.setModuleLoadPath(STANDALONE_MAIN_MODULE_URI.removeLastSegment().getCollectionPath()); + + try (final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, DbUriSource.from(brokerPool, STANDALONE_MAIN_MODULE_URI, false, false), false, null, null, preCompilationContextSetup, null, null)) { + assertNotNull(queryResult.result); + assertEquals(1, queryResult.result.getItemCount()); + final Item item = queryResult.result.itemAt(0); + assertEquals(Type.DOCUMENT, item.getType()); + + final Source expectedSrc = Input.fromString(expected).build(); + final Source actualSrc = Input.fromNode((Document) item).build(); + + final Diff diff = DiffBuilder.compare(expectedSrc) + .withTest(actualSrc) + .checkForSimilar() + .build(); + + assertFalse(diff.toString(), diff.hasDifferences()); + } + + transaction.commit(); + } + } + + @Test + public void storedImportingMainModule() throws EXistException, PermissionDeniedException, XPathException, IOException { + final String expected = + "" + + "" + TEST_COLLECTION_URI.getCollectionPath() + "" + + "" + TEST_COLLECTION_URI.getCollectionPath() + "" + + ""; + + final BrokerPool brokerPool = EXIST_EMBEDDED_SERVER.getBrokerPool(); + try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject())); + final Txn transaction = brokerPool.getTransactionManager().beginTransaction()) { + + final ConsumerE preCompilationContextSetup = xqueryContext -> xqueryContext.setModuleLoadPath(IMPORTING_MAIN_MODULE_URI.removeLastSegment().getCollectionPath()); + + + try (final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, DbUriSource.from(brokerPool, IMPORTING_MAIN_MODULE_URI, false, false), false, null, null, preCompilationContextSetup, null, null)) { + assertNotNull(queryResult.result); + assertEquals(1, queryResult.result.getItemCount()); + final Item item = queryResult.result.itemAt(0); + assertEquals(Type.DOCUMENT, item.getType()); + + final Source expectedSrc = Input.fromString(expected).build(); + final Source actualSrc = Input.fromNode((Document) item).build(); + + final Diff diff = DiffBuilder.compare(expectedSrc) + .withTest(actualSrc) + .checkForSimilar() + .build(); + + assertFalse(diff.toString(), diff.hasDifferences()); + } + + transaction.commit(); + } + } +} diff --git a/exist-core/src/test/java/org/exist/xquery/functions/system/GetModuleLoadPathTest.java b/exist-core/src/test/java/org/exist/xquery/functions/system/GetModuleLoadPathTest.java new file mode 100644 index 0000000000..4ad2770153 --- /dev/null +++ b/exist-core/src/test/java/org/exist/xquery/functions/system/GetModuleLoadPathTest.java @@ -0,0 +1,244 @@ +/* + * 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 + */ +package org.exist.xquery.functions.system; + +import com.evolvedbinary.j8fu.function.ConsumerE; +import org.exist.EXistException; +import org.exist.collections.Collection; +import org.exist.security.PermissionDeniedException; +import org.exist.source.DbUriSource; +import org.exist.source.StringSource; +import org.exist.storage.BrokerPool; +import org.exist.storage.DBBroker; +import org.exist.storage.txn.Txn; +import org.exist.test.ExistEmbeddedServer; +import org.exist.util.LockException; +import org.exist.util.StringInputSource; +import org.exist.xmldb.XmldbURI; +import org.exist.xquery.XPathException; +import org.exist.xquery.XQueryContext; +import org.exist.xquery.XQueryUtil; +import org.exist.xquery.value.Item; +import org.exist.xquery.value.Type; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; +import org.xmlunit.builder.DiffBuilder; +import org.xmlunit.builder.Input; +import org.xmlunit.diff.Diff; + +import javax.xml.transform.Source; +import java.io.IOException; +import java.util.Optional; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.exist.test.Util.storeQuery; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +public class GetModuleLoadPathTest { + + private static XmldbURI TEST_COLLECTION_URI = XmldbURI.create("/db/get-module-load-path-test"); + private static XmldbURI TEST_SUB_COLLECTION_URI = TEST_COLLECTION_URI.append("sub1"); + + private static XmldbURI STANDALONE_MAIN_MODULE_URI = TEST_COLLECTION_URI.append("standalone-main.xq"); + private static String STANDALONE_MAIN_MODULE_XQ = + "import module namespace system = \"http://exist-db.org/xquery/system\";\n" + + "document {\n" + + " {system:get-module-load-path()}\n" + + "}"; + + private static XmldbURI IMPORTED_LIBRARY_MODULE_URI = TEST_SUB_COLLECTION_URI.append("imported-library.xqm"); + private static String IMPORTED_LIBRARY_MODULE_XQ = + "module namespace ilm = \"http://ilm\";\n" + + "import module namespace system = \"http://exist-db.org/xquery/system\";\n" + + "declare function ilm:module-load-path() {\n" + + " system:get-module-load-path()\n" + + "};"; + + private static XmldbURI IMPORTING_MAIN_MODULE_URI = TEST_COLLECTION_URI.append("importing-main.xq"); + private static String IMPORTING_MAIN_MODULE_XQ = + "import module namespace system = \"http://exist-db.org/xquery/system\";\n" + + "import module namespace ilm = \"http://ilm\" at \"xmldb:exist://" + IMPORTED_LIBRARY_MODULE_URI.getXmldbURI().toString() + "\";\n" + + "document {\n" + + " \n" + + " {system:get-module-load-path()}\n" + + " {ilm:module-load-path()}\n" + + " \n" + + "}"; + + @ClassRule + public static ExistEmbeddedServer EXIST_EMBEDDED_SERVER = new ExistEmbeddedServer(true, true); + + @BeforeClass + public static void setup() throws EXistException, PermissionDeniedException, IOException, SAXException, LockException { + final BrokerPool brokerPool = EXIST_EMBEDDED_SERVER.getBrokerPool(); + try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject())); + final Txn transaction = brokerPool.getTransactionManager().beginTransaction()) { + + // store xquery documents + try (final Collection testCollection = broker.getOrCreateCollection(transaction, TEST_COLLECTION_URI)) { + storeQuery(broker, transaction, new StringInputSource(STANDALONE_MAIN_MODULE_XQ.getBytes(UTF_8)), testCollection, STANDALONE_MAIN_MODULE_URI); + + try (final Collection testSubCollection = broker.getOrCreateCollection(transaction, TEST_SUB_COLLECTION_URI)) { + storeQuery(broker, transaction, new StringInputSource(IMPORTED_LIBRARY_MODULE_XQ.getBytes(UTF_8)), testSubCollection, IMPORTED_LIBRARY_MODULE_URI); + } + + storeQuery(broker, transaction, new StringInputSource(IMPORTING_MAIN_MODULE_XQ.getBytes(UTF_8)), testCollection, IMPORTING_MAIN_MODULE_URI); + } + + transaction.commit(); + } + } + + @Test + public void standaloneMainModule() throws EXistException, PermissionDeniedException, XPathException, IOException { + final String expected = "."; + + final BrokerPool brokerPool = EXIST_EMBEDDED_SERVER.getBrokerPool(); + try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject())); + final Txn transaction = brokerPool.getTransactionManager().beginTransaction()) { + + try (final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, new StringSource(STANDALONE_MAIN_MODULE_XQ), false, null, null, null, null, null)) { + assertNotNull(queryResult.result); + assertEquals(1, queryResult.result.getItemCount()); + final Item item = queryResult.result.itemAt(0); + assertEquals(Type.DOCUMENT, item.getType()); + + final Source expectedSrc = Input.fromString(expected).build(); + final Source actualSrc = Input.fromNode((Document) item).build(); + + final Diff diff = DiffBuilder.compare(expectedSrc) + .withTest(actualSrc) + .checkForSimilar() + .build(); + + assertFalse(diff.toString(), diff.hasDifferences()); + } + + transaction.commit(); + } + } + + @Test + public void importingMainModule() throws EXistException, PermissionDeniedException, XPathException, IOException { + final String expected = + "" + + "." + + "xmldb:exist://" + IMPORTED_LIBRARY_MODULE_URI.removeLastSegment().getCollectionPath() + "" + + ""; + + final BrokerPool brokerPool = EXIST_EMBEDDED_SERVER.getBrokerPool(); + try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject())); + final Txn transaction = brokerPool.getTransactionManager().beginTransaction()) { + + try (final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, new StringSource(IMPORTING_MAIN_MODULE_XQ), false, null, null, null, null, null)) { + assertNotNull(queryResult.result); + assertEquals(1, queryResult.result.getItemCount()); + final Item item = queryResult.result.itemAt(0); + assertEquals(Type.DOCUMENT, item.getType()); + + final Source expectedSrc = Input.fromString(expected).build(); + final Source actualSrc = Input.fromNode((Document) item).build(); + + final Diff diff = DiffBuilder.compare(expectedSrc) + .withTest(actualSrc) + .checkForSimilar() + .build(); + + assertFalse(diff.toString(), diff.hasDifferences()); + } + + transaction.commit(); + } + } + + + @Test + public void storedStandaloneMainModule() throws EXistException, PermissionDeniedException, XPathException, IOException { + final String expected = "" + TEST_COLLECTION_URI.getCollectionPath() + ""; + + final BrokerPool brokerPool = EXIST_EMBEDDED_SERVER.getBrokerPool(); + try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject())); + final Txn transaction = brokerPool.getTransactionManager().beginTransaction()) { + + final ConsumerE preCompilationContextSetup = xqueryContext -> xqueryContext.setModuleLoadPath(STANDALONE_MAIN_MODULE_URI.removeLastSegment().getCollectionPath()); + + try (final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, DbUriSource.from(brokerPool, STANDALONE_MAIN_MODULE_URI, false, false), false, null, null, preCompilationContextSetup, null, null)) { + assertNotNull(queryResult.result); + assertEquals(1, queryResult.result.getItemCount()); + final Item item = queryResult.result.itemAt(0); + assertEquals(Type.DOCUMENT, item.getType()); + + final Source expectedSrc = Input.fromString(expected).build(); + final Source actualSrc = Input.fromNode((Document) item).build(); + + final Diff diff = DiffBuilder.compare(expectedSrc) + .withTest(actualSrc) + .checkForSimilar() + .build(); + + assertFalse(diff.toString(), diff.hasDifferences()); + } + + transaction.commit(); + } + } + + @Test + public void storedImportingMainModule() throws EXistException, PermissionDeniedException, XPathException, IOException { + final String expected = + "" + + "" + TEST_COLLECTION_URI.getCollectionPath() + "" + + "" + IMPORTED_LIBRARY_MODULE_URI.removeLastSegment().getCollectionPath() + "" + + ""; + + final BrokerPool brokerPool = EXIST_EMBEDDED_SERVER.getBrokerPool(); + try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject())); + final Txn transaction = brokerPool.getTransactionManager().beginTransaction()) { + + final ConsumerE preCompilationContextSetup = xqueryContext -> xqueryContext.setModuleLoadPath(IMPORTING_MAIN_MODULE_URI.removeLastSegment().getCollectionPath()); + + + try (final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, DbUriSource.from(brokerPool, IMPORTING_MAIN_MODULE_URI, false, false), false, null, null, preCompilationContextSetup, null, null)) { + assertNotNull(queryResult.result); + assertEquals(1, queryResult.result.getItemCount()); + final Item item = queryResult.result.itemAt(0); + assertEquals(Type.DOCUMENT, item.getType()); + + final Source expectedSrc = Input.fromString(expected).build(); + final Source actualSrc = Input.fromNode((Document) item).build(); + + final Diff diff = DiffBuilder.compare(expectedSrc) + .withTest(actualSrc) + .checkForSimilar() + .build(); + + assertFalse(diff.toString(), diff.hasDifferences()); + } + + transaction.commit(); + } + } +}