Skip to content

Commit

Permalink
Merge pull request #5012 from evolvedbinary/6.x.x/hotfix/expath-impor…
Browse files Browse the repository at this point in the history
…t-xquery-transient

[6.x.x] Fix an issue with XQuery transient imports within EXPath Package
  • Loading branch information
dizzzz authored Aug 30, 2023
2 parents 7430778 + a79be27 commit 8bd8732
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2190,7 +2190,7 @@ public boolean run(final String args[]) throws Exception {
configFile = Optional.ofNullable(ConfigurationHelper.lookup((String) CONF_XML.get("")));
}
}
configFile.ifPresent(value -> properties.setProperty(CONFIGURATION, value.toAbsolutePath().toString()));
configFile.ifPresent(value -> properties.setProperty(CONFIGURATION, value.toString()));

properties.putAll(loadClientProperties());

Expand Down
39 changes: 39 additions & 0 deletions exist-core/src/main/java/org/exist/repo/ExistRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,17 @@

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.exist.dom.persistent.BinaryDocument;
import org.exist.security.PermissionDeniedException;
import org.exist.source.DBSource;
import org.exist.storage.BrokerPool;
import org.exist.storage.BrokerPoolService;
import org.exist.storage.BrokerPoolServiceException;
import org.exist.storage.DBBroker;
import org.exist.storage.NativeBroker;
import org.exist.util.Configuration;
import org.exist.util.FileUtils;
import org.exist.xmldb.XmldbURI;
import org.exist.xquery.ErrorCodes;
import org.exist.xquery.Expression;
import org.exist.xquery.Module;
Expand All @@ -41,7 +46,9 @@
import org.expath.pkg.repo.PackageException;
import org.expath.pkg.repo.Repository;
import org.expath.pkg.repo.URISpace;
import org.w3c.dom.Document;

import javax.annotation.Nullable;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import java.io.IOException;
Expand Down Expand Up @@ -273,6 +280,38 @@ public Path resolveXQueryModule(final String namespace) throws XPathException {
return null;
}

/**
* Attempt to lookup an XQuery from the filesystem in the database.
*
* @param broker the database broker
* @param xqueryPath the path to the xquery within the EXPath filesystem repo.
*
* @return the database source for the xquery, or null.
*/
public @Nullable org.exist.source.Source resolveStoredXQueryModuleFromDb(final DBBroker broker, final Path xqueryPath) throws PermissionDeniedException {
if (!xqueryPath.startsWith(expathDir)) {
return null;
}

final String relXQueryPath = expathDir.relativize(xqueryPath).toString();

// 1. attempt to locate it within a library
XmldbURI xqueryDbPath = XmldbURI.create("xmldb:exist:///db/system/repo/" + relXQueryPath);
@Nullable Document doc = broker.getXMLResource(xqueryDbPath);
if (doc != null && doc instanceof BinaryDocument) {
return new DBSource(broker, (BinaryDocument) doc, false);
}

// 2. attempt to locate it within an app
xqueryDbPath = XmldbURI.create("xmldb:exist:///db/apps/" + relXQueryPath);
doc = broker.getXMLResource(xqueryDbPath);
if (doc != null && doc instanceof BinaryDocument) {
return new DBSource(broker, (BinaryDocument) doc, false);
}

return null;
}

public Source resolveXSLTModule(final String namespace) throws PackageException {
for (final Packages pp : myParent.listPackages()) {
final Package pkg = pp.latest();
Expand Down
13 changes: 7 additions & 6 deletions exist-core/src/main/java/org/exist/util/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ public Configuration(String configFilename, Optional<Path> existHomeDirname) thr
InputStream is = null;
try {

existHomeDirname = existHomeDirname.map(Path::normalize);

if(configFilename == null) {
// Default file name
configFilename = DatabaseImpl.CONF_XML;
Expand Down Expand Up @@ -164,7 +166,6 @@ public Configuration(String configFilename, Optional<Path> existHomeDirname) thr
}
}


Path configFile = Paths.get(configFilename);

if(!configFile.isAbsolute() && existHome.isPresent()) {
Expand Down Expand Up @@ -863,15 +864,15 @@ private void configureBackend( final Optional<Path> dbHome, Element con ) throws
final String dataFiles = getConfigAttributeValue( con, BrokerPool.DATA_DIR_ATTRIBUTE );

if (dataFiles != null) {
final Path df = ConfigurationHelper.lookup( dataFiles, dbHome );
final Path df = ConfigurationHelper.lookup(dataFiles, dbHome);
if (!Files.isReadable(df)) {
try {
Files.createDirectories(df);
} catch (final IOException ioe) {
throw new DatabaseConfigurationException("cannot read data directory: " + df.toAbsolutePath().toString(), ioe);
throw new DatabaseConfigurationException("cannot read data directory: " + df, ioe);
}
}
config.put(BrokerPool.PROPERTY_DATA_DIR, df.toAbsolutePath());
config.put(BrokerPool.PROPERTY_DATA_DIR, df);
LOG.debug(BrokerPool.PROPERTY_DATA_DIR + ": {}", config.get(BrokerPool.PROPERTY_DATA_DIR));
}

Expand Down Expand Up @@ -1090,9 +1091,9 @@ private void configureRecovery( final Optional<Path> dbHome, Element recovery )
final Path rf = ConfigurationHelper.lookup( option, dbHome );

if(!Files.isReadable(rf)) {
throw new DatabaseConfigurationException( "cannot read data directory: " + rf.toAbsolutePath());
throw new DatabaseConfigurationException( "cannot read data directory: " + rf);
}
setProperty(Journal.PROPERTY_RECOVERY_JOURNAL_DIR, rf.toAbsolutePath());
setProperty(Journal.PROPERTY_RECOVERY_JOURNAL_DIR, rf);
LOG.debug(Journal.PROPERTY_RECOVERY_JOURNAL_DIR + ": {}", config.get(Journal.PROPERTY_RECOVERY_JOURNAL_DIR));
}

Expand Down
21 changes: 10 additions & 11 deletions exist-core/src/main/java/org/exist/util/ConfigurationHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public static Optional<Path> getExistHome(final String config) {
final Path userHomeRelativeConfig = userHome.resolve(config);
if (Files.isDirectory(userHome) && Files.isRegularFile(userHomeRelativeConfig)) {
final Path existHome = userHomeRelativeConfig.getParent().normalize();
LOG.debug("Got eXist home: {} from system property 'user.home': {}", existHome.toAbsolutePath().toString(), userHome.toAbsolutePath().toString());
LOG.debug("Got eXist home: {} from system property 'user.home': {}", existHome.toAbsolutePath(), userHome.toAbsolutePath());
return Optional.of(existHome);
}

Expand All @@ -119,7 +119,7 @@ public static Optional<Path> getExistHome(final String config) {
final Path userDirRelativeConfig = userDir.resolve(config);
if (Files.isDirectory(userDir) && Files.isRegularFile(userDirRelativeConfig)) {
final Path existHome = userDirRelativeConfig.getParent().normalize();
LOG.debug("Got eXist home: {} from system property 'user.dir': {}", existHome.toAbsolutePath().toString(), userDir.toAbsolutePath().toString());
LOG.debug("Got eXist home: {} from system property 'user.dir': {}", existHome.toAbsolutePath(), userDir.toAbsolutePath());
return Optional.of(existHome);
}

Expand All @@ -132,7 +132,7 @@ public static Optional<Path> getExistHome(final String config) {
existHome = Paths.get(new URI(configUrl.getPath())).getParent().getParent().normalize();
LOG.warn("{} file was found on the classpath, but inside a Jar file! Derived EXIST_HOME from Jar's parent folder: {}", config, existHome);
} else {
existHome = Paths.get(configUrl.toURI()).getParent();
existHome = Paths.get(configUrl.toURI()).getParent().normalize();
if (FileUtils.fileName(existHome).equals("etc")) {
existHome = existHome.getParent().normalize();
}
Expand Down Expand Up @@ -179,15 +179,14 @@ public static Path lookup(final String path) {
* @return the file handle
*/
public static Path lookup(final String path, final Optional<Path> parent) {
// resolvePath is used for things like ~user/folder
final Path p = decodeUserHome(path);
if (p.isAbsolute()) {
return p;
// attempt to first resolve the path that is used for things like ~user/folder
Path p = decodeUserHome(path);
if (!p.isAbsolute()) {
p = parent
.orElse(getExistHome().orElse(Paths.get(System.getProperty("user.dir"))))
.resolve(path);
}

return parent
.orElse(getExistHome().orElse(Paths.get(System.getProperty("user.dir"))))
.resolve(path);
return p.normalize().toAbsolutePath();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public SingleInstanceConfiguration(String configFilename, Optional<Path> existHo
public static Optional<Path> getPath() {
if (!_configFile.isPresent()) {
final Path f = ConfigurationHelper.lookup("conf.xml");
return Optional.of(f.toAbsolutePath());
return Optional.of(f);
}
return _configFile;
}
Expand Down
26 changes: 23 additions & 3 deletions exist-core/src/main/java/org/exist/xquery/XQueryContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;
Expand Down Expand Up @@ -588,9 +589,28 @@ public Optional<ExistRepository> getRepository() {

// use the resolved file or return null
if (resolved != null) {
// build a module object from the file
final Source src = new FileSource(resolved, false);
return compileOrBorrowModule(prefix, namespace, "", src);

String location = "";

try {

// see if the src exists in the database and if so, use that instead
Source src = repo.get().resolveStoredXQueryModuleFromDb(getBroker(), resolved);
if (src != null) {
// NOTE(AR) set the location of the module to import relative to this module's load path - so that transient imports of the imported module will resolve correctly!
location = Paths.get(XmldbURI.create(moduleLoadPath).getCollectionPath()).relativize(Paths.get(((DBSource)src).getDocumentPath().getCollectionPath())).toString();
} else {
// else, fallback to the one from the filesystem
src = new FileSource(resolved, false);
}

// build a module object from the source
final ExternalModule module = compileOrBorrowModule(prefix, namespace, location, src);
return module;

} catch (final PermissionDeniedException e) {
throw new XPathException(e.getMessage(), e);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion exist-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@
<dependency>
<groupId>org.expath.packaging</groupId>
<artifactId>pkg-java</artifactId>
<version>2.0.0</version>
<version>2.0.1</version>
</dependency>

<dependency>
Expand Down

0 comments on commit 8bd8732

Please sign in to comment.