diff --git a/elemental-parent/pom.xml b/elemental-parent/pom.xml index ccfd88047c..9b7686cb93 100644 --- a/elemental-parent/pom.xml +++ b/elemental-parent/pom.xml @@ -104,6 +104,7 @@ 3.0.1 3.0.2 2.0.17 + 9.9.1-8 1C @@ -129,6 +130,12 @@ 1.0.0 + + net.sf.saxon + Saxon-HE + ${saxon.version} + + com.evolvedbinary.j8fu j8fu @@ -216,6 +223,21 @@ jaxb-maven-plugin ${jaxb.impl.version} + + org.codehaus.mojo + xml-maven-plugin + 1.2.0 + + net.sf.saxon.TransformerFactoryImpl + + + + net.sf.saxon + Saxon-HE + ${saxon.version} + + + org.apache.maven.plugins maven-compiler-plugin diff --git a/exist-ant/pom.xml b/exist-ant/pom.xml index 565266484d..7bc52c1251 100644 --- a/exist-ant/pom.xml +++ b/exist-ant/pom.xml @@ -261,6 +261,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/exist-ant/src/test/resources-filtered/conf.xml b/exist-ant/src/test/resources-filtered/conf.xml index b2f5c0b5a5..a36447f3fb 100644 --- a/exist-ant/src/test/resources-filtered/conf.xml +++ b/exist-ant/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/exist-core/pom.xml b/exist-core/pom.xml index 21a336b657..b7b2df7587 100644 --- a/exist-core/pom.xml +++ b/exist-core/pom.xml @@ -733,6 +733,7 @@ src/main/java/org/exist/util/ByteOrderMark.java src/main/java/org/exist/util/JREUtil.java src/main/java/org/exist/util/OSUtil.java + src/main/java/org/exist/util/PropertiesUtil.java src/main/java/org/exist/util/StringUtil.java src/main/java/org/exist/util/io/AbstractContentFile.java src/test/java/org/exist/util/serializer/SAXSerializerTest.java @@ -757,6 +758,7 @@ 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/main/java/org/exist/xquery/functions/system/GetElementalHome.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 @@ -796,6 +798,7 @@ src/test/xquery/util/util.xml src/test/xquery/xquery3/parse-xml.xqm src/test/xquery/xquery3/serialize.xql + src/main/java/org/exist/BTreeTest.java src/main/java/org/exist/Indexer.java src/test/java/org/exist/Indexer2Test.java src/test/java/org/exist/Indexer3Test.java @@ -803,10 +806,13 @@ src/main/java/org/exist/Namespaces.java src/main/resources-filtered/org/exist/system.properties src/test/java/org/exist/TestDataGenerator.java + src/main/java/org/exist/TestUtils.java src/main/java/org/exist/backup/Backup.java + src/main/java/org/exist/backup/BackupDirectory.java src/main/java/org/exist/backup/CreateBackupDialog.java src/test/java/org/exist/backup/DeepEmbeddedBackupRestoreTest.java src/main/java/org/exist/backup/ExportGUI.java + src/main/java/org/exist/backup/FileSystemWriter.java src/main/java/org/exist/backup/Main.java src/main/java/org/exist/backup/Restore.java src/test/java/org/exist/backup/RestoreAppsTest.java @@ -1044,6 +1050,7 @@ src/test/java/org/exist/storage/CollectionTest.java src/test/java/org/exist/storage/ConcurrentBrokerPoolTest.java src/test/java/org/exist/storage/ConcurrentStoreTest.java + src/main/java/org/exist/storage/ConsistencyCheckTask.java src/test/java/org/exist/storage/CopyCollectionRecoveryTest.java src/test/java/org/exist/storage/CopyResourceRecoveryTest.java src/test/java/org/exist/storage/CopyResourceTest.java @@ -1121,6 +1128,7 @@ src/test/java/org/exist/util/CollationsTest.java src/main/java/org/exist/util/CollectionScanner.java src/main/java/org/exist/util/Configuration.java + src/main/java/org/exist/util/ConfigurationHelper.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 @@ -1128,6 +1136,7 @@ src/main/java/org/exist/util/MimeTable.java src/main/java/org/exist/util/MimeType.java src/main/java/org/exist/util/ParametersExtractor.java + src/main/java/org/exist/util/SingleInstanceConfiguration.java src/main/java/org/exist/util/XMLFilenameFilter.java src/test/java/org/exist/util/XMLReaderExpansionTest.java src/test/java/org/exist/util/XMLReaderSecurityTest.java @@ -1175,6 +1184,7 @@ src/main/java/org/exist/validation/resolver/SearchResourceResolver.java src/test/java/org/exist/w3c/tests/TestCase.java src/main/java/org/exist/webstart/JnlpJarFiles.java + src/main/java/org/exist/webstart/JnlpServlet.java src/main/java/org/exist/webstart/JnlpWriter.java src/main/java/org/exist/xmldb/AbstractEXistResource.java src/main/java/org/exist/xmldb/AbstractRemoteResource.java @@ -1603,6 +1613,7 @@ project-suppression.xml src/test/resources-filtered/conf.xml src/test/resources/log4j2.xml + src/test/resources-filtered/saxon-config.xml src/test/resources/standalone-webapp/WEB-INF/web.xml src/main/xjb/rest-api.xjb src/test/xquery/base-uri.xql @@ -1618,6 +1629,7 @@ src/test/xquery/xquery3/parse-xml.xqm src/test/xquery/xquery3/postfix-expr.xqm src/test/xquery/xquery3/serialize.xql + src/main/java/org/exist/BTreeTest.java src/main/java/org/exist/Indexer.java src/test/java/org/exist/Indexer2Test.java src/test/java/org/exist/Indexer3Test.java @@ -1625,10 +1637,13 @@ src/main/java/org/exist/Namespaces.java src/main/resources-filtered/org/exist/system.properties src/test/java/org/exist/TestDataGenerator.java + src/main/java/org/exist/TestUtils.java src/main/java/org/exist/backup/Backup.java + src/main/java/org/exist/backup/BackupDirectory.java src/main/java/org/exist/backup/CreateBackupDialog.java src/test/java/org/exist/backup/DeepEmbeddedBackupRestoreTest.java src/main/java/org/exist/backup/ExportGUI.java + src/main/java/org/exist/backup/FileSystemWriter.java src/main/java/org/exist/backup/Main.java src/main/java/org/exist/backup/Restore.java src/test/java/org/exist/backup/RestoreAppsTest.java @@ -1890,6 +1905,7 @@ src/test/java/org/exist/storage/CollectionTest.java src/test/java/org/exist/storage/ConcurrentBrokerPoolTest.java src/test/java/org/exist/storage/ConcurrentStoreTest.java + src/main/java/org/exist/storage/ConsistencyCheckTask.java src/test/java/org/exist/storage/CopyCollectionRecoveryTest.java src/test/java/org/exist/storage/CopyResourceRecoveryTest.java src/test/java/org/exist/storage/CopyResourceTest.java @@ -1949,6 +1965,7 @@ src/main/java/org/exist/storage/io/VariableByteOutputToOutputStream.java src/test/java/org/exist/storage/io/VariableByteStreamTest.java src/test/java/org/exist/storage/journal/AbstractJournalTest.java + src/test/java/org/exist/storage/journal/Journal.java src/test/java/org/exist/storage/journal/JournalBinaryTest.java src/main/java/org/exist/storage/journal/JournalManager.java src/main/java/org/exist/storage/journal/JournalReader.java @@ -2017,6 +2034,7 @@ src/test/java/org/exist/util/CollectionOfArrayIteratorTest.java src/main/java/org/exist/util/CollectionScanner.java src/main/java/org/exist/util/Configuration.java + src/main/java/org/exist/util/ConfigurationHelper.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 @@ -2028,6 +2046,8 @@ src/main/java/org/exist/util/MimeType.java src/main/java/org/exist/util/OSUtil.java src/main/java/org/exist/util/ParametersExtractor.java + src/main/java/org/exist/util/PropertiesUtil.java + src/main/java/org/exist/util/SingleInstanceConfiguration.java src/main/java/org/exist/util/StringUtil.java src/main/java/org/exist/util/UTF8.java src/main/java/org/exist/util/XMLFilenameFilter.java @@ -2079,6 +2099,7 @@ src/main/java/org/exist/validation/resolver/SearchResourceResolver.java src/test/java/org/exist/w3c/tests/TestCase.java src/main/java/org/exist/webstart/JnlpJarFiles.java + src/main/java/org/exist/webstart/JnlpServlet.java src/main/java/org/exist/webstart/JnlpWriter.java src/main/java/org/exist/xmldb/AbstractEXistResource.java src/main/java/org/exist/xmldb/AbstractRemoteResource.java @@ -2410,6 +2431,7 @@ 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/main/java/org/exist/xquery/functions/system/GetElementalHome.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 @@ -2635,6 +2657,7 @@ The original license statement is also included below.]]> src/main/java/org/exist/storage/blob/** src/test/java/org/exist/storage/blob/** src/test/java/org/exist/storage/journal/AbstractJournalTest.java + src/test/java/org/exist/storage/journal/Journal.java src/test/java/org/exist/storage/journal/JournalBinaryTest.java src/main/java/org/exist/storage/journal/JournalManager.java src/main/java/org/exist/storage/journal/JournalReader.java @@ -2858,6 +2881,35 @@ The BaseX Team. The original license statement is also included below.]]> + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + org/exist/storage/statistics/conf.xml + org/exist/xquery/import-from-pkg-test.conf.xml + org/exist/xquery/JavaBindingTest.conf.xml + org/exist/xquery/functions/transform/transform-from-pkg-test.conf.xml + + + + + + + + org.apache.maven.plugins maven-surefire-plugin @@ -2882,8 +2934,8 @@ The BaseX Team. The original license statement is also included below.]]>@{jacocoArgLine} -Dfile.encoding=${project.build.sourceEncoding} -Dexist.recovery.progressbar.hide=true ${project.basedir}/../exist-jetty-config/target/classes/org/exist/jetty - ${project.build.testOutputDirectory}/conf.xml - ${project.build.testOutputDirectory}/standalone-webapp + ${project.build.testOutputDirectory}/conf.xml + ${project.build.testOutputDirectory}/standalone-webapp ${project.build.testOutputDirectory}/log4j2.xml @@ -2990,8 +3042,8 @@ The BaseX Team. The original license statement is also included below.]]>-Dfile.encoding=${project.build.sourceEncoding} -Dexist.recovery.progressbar.hide=true ${project.basedir}/../exist-jetty-config/target/classes/org/exist/jetty - ${project.build.testOutputDirectory}/conf.xml - ${project.build.testOutputDirectory}/standalone-webapp + ${project.build.testOutputDirectory}/conf.xml + ${project.build.testOutputDirectory}/standalone-webapp ${project.build.testOutputDirectory}/log4j2.xml diff --git a/exist-core/src/main/java/org/exist/BTreeTest.java b/exist-core/src/main/java/org/exist/BTreeTest.java index b8ba058726..2f1daee24a 100644 --- a/exist-core/src/main/java/org/exist/BTreeTest.java +++ b/exist-core/src/main/java/org/exist/BTreeTest.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 * @@ -43,7 +67,7 @@ public class BTreeTest { private BrokerPool pool = null; public BTreeTest() { - file = Paths.get(System.getProperty("exist.home", ".")).resolve("test/test.dbx"); + file = Paths.get(System.getProperty("elemental.home", ".")).resolve("test/test.dbx"); try { Configuration config = new Configuration(); diff --git a/exist-core/src/main/java/org/exist/TestUtils.java b/exist-core/src/main/java/org/exist/TestUtils.java index 8c2cf884e7..7f951123c7 100644 --- a/exist-core/src/main/java/org/exist/TestUtils.java +++ b/exist-core/src/main/java/org/exist/TestUtils.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 * @@ -165,17 +189,17 @@ public static byte[] readFile(final Path file) throws IOException { } /** - * Get the EXIST_HOME directory + * Get the ELEMENTAL_HOME directory * - * @return The absolute path to the EXIST_HOME folder + * @return The absolute path to the ELEMENTAL_HOME folder * or {@link Optional#empty()} */ - public static Optional getEXistHome() { - return ConfigurationHelper.getExistHome().map(Path::toAbsolutePath); + public static Optional getElementalHome() { + return ConfigurationHelper.getElementalHome().map(Path::toAbsolutePath); } /** - * Get a file from within the EXIST_HOME directory. + * Get a file from within the ELEMENTAL_HOME directory. * * @param fileName Just the name of the file. * @@ -183,8 +207,8 @@ public static Optional getEXistHome() { * * @throws IOException if an IO error occurs. */ - public static Optional getExistHomeFile(final String fileName) throws IOException { - final Path path = getEXistHome().orElseGet(() -> Paths.get(".")).resolve(fileName); + public static Optional getElementalHomeFile(final String fileName) throws IOException { + final Path path = getElementalHome().orElseGet(() -> Paths.get(".")).resolve(fileName); if(Files.exists(path)) { return Optional.of(path); } else { diff --git a/exist-core/src/main/java/org/exist/backup/BackupDirectory.java b/exist-core/src/main/java/org/exist/backup/BackupDirectory.java index a3bb3bae2c..aee9d4f87b 100644 --- a/exist-core/src/main/java/org/exist/backup/BackupDirectory.java +++ b/exist-core/src/main/java/org/exist/backup/BackupDirectory.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 * @@ -21,10 +45,12 @@ */ package org.exist.backup; +import com.evolvedbinary.j8fu.tuple.Tuple2; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.exist.util.FileUtils; +import javax.annotation.Nullable; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -32,11 +58,17 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static com.evolvedbinary.j8fu.tuple.Tuple.Tuple; +import static org.exist.backup.BackupDescriptor.PREVIOUS_PROP_NAME; + public class BackupDirectory { public final static Logger LOG = LogManager.getLogger(BackupDirectory.class); @@ -45,25 +77,26 @@ public class BackupDirectory { public final static String PREFIX_FULL_BACKUP_FILE = "full"; public final static String PREFIX_INC_BACKUP_FILE = "inc"; - public final static String FILE_REGEX = "(" + PREFIX_FULL_BACKUP_FILE + "|" + PREFIX_INC_BACKUP_FILE + ")(\\d{8}-\\d{4}).*"; + public final static String FULL_FILE_REGEX = PREFIX_FULL_BACKUP_FILE + "(\\d{8}-\\d{6}).*"; + public final static String INC_FILE_REGEX = PREFIX_INC_BACKUP_FILE + "\\d{8}-\\d{6}.*"; + public final static String FILE_REGEX = "(?:" + PREFIX_FULL_BACKUP_FILE + "|" + PREFIX_INC_BACKUP_FILE + ")(\\d{8}-\\d{6}).*"; - public final static String DATE_FORMAT_PICTURE = "yyyyMMdd-HHmm"; - private final DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_PICTURE); + public final static String DATE_FORMAT_PICTURE = "yyyyMMdd-HHmmss"; + private final static DateFormat DATE_FORMAT = new SimpleDateFormat(DATE_FORMAT_PICTURE); private final Path dir; + private @Nullable Matcher fileMatcher; + private @Nullable Matcher fullFileMatcher; + private @Nullable Matcher incFileMatcher; - private final Matcher matcher; public BackupDirectory(final String dirPath) { this(Paths.get(dirPath)); } - public BackupDirectory(final Path directory) { this.dir = directory; - final Pattern pattern = Pattern.compile(FILE_REGEX); - matcher = pattern.matcher(""); } public Path createBackup(final boolean incremental, final boolean zip) { @@ -71,7 +104,7 @@ public Path createBackup(final boolean incremental, final boolean zip) { while (true) { final StringBuilder buf = new StringBuilder(); buf.append(incremental ? PREFIX_INC_BACKUP_FILE : PREFIX_FULL_BACKUP_FILE); - buf.append(dateFormat.format(new Date())); + buf.append(DATE_FORMAT.format(new Date())); if (counter++ > 0) { buf.append('_').append(counter); @@ -98,46 +131,201 @@ public Path createBackup(final boolean incremental, final boolean zip) { } } + /** + * Gets the details of the last backup (if any). + * + * @return the details of the last backup, or null if there was no previous backup. + */ + public @Nullable BackupDescriptor lastBackupFile() throws IOException { + final List files = FileUtils.list(dir); + + @Nullable Path newest = null; + @Nullable Date newestDate = null; - public BackupDescriptor lastBackupFile() throws IOException { + for (final Path file : files) { + @Nullable final Date date = isBackupFile(file); + if (date != null) { + if (newestDate == null || date.after(newestDate)) { + newestDate = date; + newest = file; + } + } + } + + if (newest != null) { + return getBackupDescriptor(newest); + } + + return null; + } + + /** + * If the provided file is a full or incremental backup + * then the Date of the backup is returned. + * + * @param file the file to test if it is a backup. + * + * @return the date of the backup, or null if the file is not a backup. + */ + private @Nullable Date isBackupFile(final Path file) { + final String fileName = FileUtils.fileName(file); + if (fileMatcher == null) { + final Pattern filePattern = Pattern.compile(FILE_REGEX); + this.fileMatcher = filePattern.matcher(fileName); + } else { + this.fileMatcher.reset(fileName); + } + + if (this.fileMatcher.matches()) { + final String dateTime = fileMatcher.group(1); + try { + return DATE_FORMAT.parse(dateTime); + } catch (final ParseException e) { + // no-op + } + } + + return null; + } + + /** + * Returns the number of full backups present in the directory. + * + * @return the number of full backups present in the directory. + */ + public int countFullBackups() throws IOException { final List files = FileUtils.list(dir); - Path newest = null; - Date newestDate = null; + int count = 0; for (final Path file : files) { - matcher.reset(FileUtils.fileName(file)); + @Nullable final Date date = isFullBackupFile(file); + if (date != null) { + count++; + } + } - if (matcher.matches()) { - final String dateTime = matcher.group(2); + return count; + } - try { - final Date date = dateFormat.parse(dateTime); + /** + * If the provided file is a full backup + * then the Date of the backup is returned. + * + * @param file the file to test if it is a full backup. + * + * @return the date of the full backup, or null if the file is not a full backup. + */ + private @Nullable Date isFullBackupFile(final Path file) { + final String fileName = FileUtils.fileName(file); + if (fullFileMatcher == null) { + final Pattern fullFilePattern = Pattern.compile(FULL_FILE_REGEX); + this.fullFileMatcher = fullFilePattern.matcher(fileName); + } else { + this.fullFileMatcher.reset(fileName); + } - if ((newestDate == null) || date.after(newestDate)) { - newestDate = date; - newest = file; + if (this.fullFileMatcher.matches()) { + final String dateTime = fullFileMatcher.group(1); + try { + return DATE_FORMAT.parse(dateTime); + } catch (final ParseException e) { + // no-op + } + } + + return null; + } + + /** + * Gets the oldest full-backup and any associated incremental backups (if any). + * + * @return the path of the oldest backup, and any associated incremental backups, or null if there was no previous full backup. + */ + public @Nullable List getOldestFullBackup() throws IOException { + final List files = FileUtils.list(dir); + + @Nullable Path oldestFullBackup = null; + @Nullable Date oldestFullBackupDate = null; + + // find the oldest full backup, and create a map of incremental backups + @Nullable Map> previousToIncremental = null; + for (final Path file : files) { + @Nullable final Date date = isFullBackupFile(file); + if (date != null) { + if (oldestFullBackupDate == null || date.before(oldestFullBackupDate)) { + oldestFullBackupDate = date; + oldestFullBackup = file; + } + } else { + @Nullable BackupDescriptor incBackupDescriptor = isIncBackupFile(file); + if (incBackupDescriptor != null) { + @Nullable String previousBackup = incBackupDescriptor.getProperties().getProperty(PREVIOUS_PROP_NAME); + if (previousBackup != null) { + if (previousToIncremental == null) { + previousToIncremental = new HashMap<>(); + } + previousToIncremental.put(previousBackup, Tuple(incBackupDescriptor.getName(), file)); } - } catch (final ParseException e) { } } } - BackupDescriptor descriptor = null; - if (newest != null) { + @Nullable List oldestBackups = null; + if (oldestFullBackup != null) { + oldestBackups = new ArrayList<>(); + oldestBackups.add(oldestFullBackup); - try { - - if (FileUtils.fileName(newest).toLowerCase().endsWith(".zip")) { - descriptor = new ZipArchiveBackupDescriptor(newest); - } else { - descriptor = new FileSystemBackupDescriptor(newest, newest.resolve("db").resolve(BackupDescriptor.COLLECTION_DESCRIPTOR)); + // Find any associated incremental backups + if (previousToIncremental != null) { + final BackupDescriptor oldestFullBackupDescriptor = getBackupDescriptor(oldestFullBackup); + @Nullable Tuple2 incrementalBackupInfo = previousToIncremental.get(oldestFullBackupDescriptor.getName()); + while (incrementalBackupInfo != null) { + oldestBackups.add(incrementalBackupInfo._2); + incrementalBackupInfo = previousToIncremental.get(incrementalBackupInfo._1); } - } catch (final IOException e) { - e.printStackTrace(); } } - return (descriptor); + + return oldestBackups; + } + + /** + * If the provided file is an incremental backup + * then the Date of the backup is returned. + * + * @param file the file to test if it is an incremental backup. + * + * @return the date of the incremental backup, or null if the file is not an incremental backup. + */ + private @Nullable BackupDescriptor isIncBackupFile(final Path file) { + final String fileName = FileUtils.fileName(file); + if (incFileMatcher == null) { + final Pattern incFilePattern = Pattern.compile(INC_FILE_REGEX); + this.incFileMatcher = incFilePattern.matcher(fileName); + } else { + this.incFileMatcher.reset(fileName); + } + + if (this.incFileMatcher.matches()) { + return getBackupDescriptor(file); + } + + return null; + } + + private @Nullable BackupDescriptor getBackupDescriptor(final Path path) { + try { + if (FileUtils.fileName(path).toLowerCase().endsWith(".zip")) { + return new ZipArchiveBackupDescriptor(path); + } else { + return new FileSystemBackupDescriptor(path, path.resolve("db").resolve(BackupDescriptor.COLLECTION_DESCRIPTOR)); + } + } catch (final IOException e) { + LOG.error(e.getMessage(), e); + } + + return null; } } diff --git a/exist-core/src/main/java/org/exist/backup/ExportGUI.java b/exist-core/src/main/java/org/exist/backup/ExportGUI.java index d1f0815ba0..532e2449d8 100644 --- a/exist-core/src/main/java/org/exist/backup/ExportGUI.java +++ b/exist-core/src/main/java/org/exist/backup/ExportGUI.java @@ -115,10 +115,10 @@ public class ExportGUI extends javax.swing.JFrame { public ExportGUI() { super("Consistency Check and Repair"); initComponents(); - final String existHome = System.getProperty("exist.home", "./"); + final String existHome = System.getProperty("elemental.home", System.getProperty("exist.home", "./")); final Path home = Paths.get(existHome).normalize(); dbConfig.setText( - Optional.ofNullable(System.getProperty("exist.configurationFile")).map(Paths::get) + Optional.ofNullable(System.getProperty("elemental.configurationFile", System.getProperty("exist.configurationFile"))).map(Paths::get) .orElse(home.resolve("etc").resolve("conf.xml")) .toAbsolutePath().toString()); outputDir.setText(home.resolve("export").toAbsolutePath().toString()); @@ -423,7 +423,7 @@ private void btnConfSelectActionPerformed(final java.awt.event.ActionEvent evt) final JFileChooser chooser = new JFileChooser(); chooser.setMultiSelectionEnabled(false); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); - chooser.setSelectedFile(Optional.ofNullable(System.getProperty("exist.configurationFile")) + chooser.setSelectedFile(Optional.ofNullable(System.getProperty("elemental.configurationFile", System.getProperty("exist.configurationFile"))) .map(Paths::get) .orElse(dir.resolve("etc").resolve("conf.xml")) .toFile()); diff --git a/exist-core/src/main/java/org/exist/backup/FileSystemWriter.java b/exist-core/src/main/java/org/exist/backup/FileSystemWriter.java index 04971405ed..1ef5184b3c 100644 --- a/exist-core/src/main/java/org/exist/backup/FileSystemWriter.java +++ b/exist-core/src/main/java/org/exist/backup/FileSystemWriter.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 * @@ -35,6 +59,8 @@ import java.nio.file.StandardCopyOption; import java.util.Properties; +import static org.exist.backup.BackupDescriptor.BACKUP_PROPERTIES; + /** * Implementation of BackupWriter that writes to the file system. @@ -129,7 +155,7 @@ public void setProperties(final Properties properties) throws IOException { if (dataWritten) { throw (new IOException("Backup properties need to be set before any backup data is written")); } - final Path propFile = rootDir.resolve("backup.properties"); + final Path propFile = rootDir.resolve(BACKUP_PROPERTIES); try (final OutputStream os = new BufferedOutputStream(Files.newOutputStream(propFile))) { properties.store(os, "Backup properties"); } diff --git a/exist-core/src/main/java/org/exist/backup/Main.java b/exist-core/src/main/java/org/exist/backup/Main.java index bb1dbe4665..7af936ec0f 100644 --- a/exist-core/src/main/java/org/exist/backup/Main.java +++ b/exist-core/src/main/java/org/exist/backup/Main.java @@ -73,6 +73,7 @@ import java.util.concurrent.*; import java.util.prefs.Preferences; +import static org.exist.backup.BackupDescriptor.BACKUP_PROPERTIES; import static org.exist.util.ArgumentUtil.getBool; import static org.exist.util.ArgumentUtil.getOpt; import static se.softhouse.jargo.Arguments.*; @@ -161,15 +162,15 @@ public class Main { private static Properties loadProperties() { try { - final Properties properties = ConfigurationHelper.loadProperties("backup.properties", Main.class); + final Properties properties = ConfigurationHelper.loadProperties(BACKUP_PROPERTIES, Main.class); if (properties != null) { return properties; } - System.err.println("WARN - Unable to find backup.properties"); + System.err.println("WARN - Unable to find " + BACKUP_PROPERTIES); } catch (final IOException e) { - System.err.println("WARN - Unable to load backup.properties: " + e.getMessage()); + System.err.println("WARN - Unable to load " + BACKUP_PROPERTIES + ": " + e.getMessage()); } // return new empty properties @@ -226,7 +227,7 @@ public static void process(final ParsedArguments arguments) { } // load MediaTypeResolver - final Optional existHome = ConfigurationHelper.getExistHome(); + final Optional existHome = ConfigurationHelper.getElementalHome(); @Nullable final Path applicationConfigDir = existHome.map(p -> p.resolve("etc")).filter(Files::exists).orElse(null); @Nullable final MediaTypeResolver mediaTypeResolver = MediaTypeUtil.newMediaTypeResolver(applicationConfigDir); diff --git a/exist-core/src/main/java/org/exist/backup/SystemExport.java b/exist-core/src/main/java/org/exist/backup/SystemExport.java index c7d6c84c4a..910454faa1 100644 --- a/exist-core/src/main/java/org/exist/backup/SystemExport.java +++ b/exist-core/src/main/java/org/exist/backup/SystemExport.java @@ -95,6 +95,7 @@ import org.xml.sax.helpers.NamespaceSupport; import xyz.elemental.mediatype.MediaType; +import javax.annotation.Nullable; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.transform.OutputKeys; @@ -106,6 +107,7 @@ import java.util.*; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.exist.util.PropertiesUtil.getIntegerProperty; /** @@ -181,31 +183,32 @@ public SystemExport(final DBBroker broker, final Txn transaction, final StatusCa } public Path export(final String targetDir, final boolean incremental, final boolean zip, final List errorList) { - return (export(targetDir, incremental, -1, zip, errorList)); + return (export(targetDir, incremental, -1, -1, zip, errorList)); } - /** - * Export the contents of the database, trying to preserve as much data as possible. To be effective, this method should be used in combination - * with class {@link ConsistencyCheck}. + * Export the contents of the database, trying to preserve as much data as possible. + * To be effective, this method should be used in combination with {@link ConsistencyCheck}. + * + * @param outputPath the output directory where the backup will be written. + * @param incremental true if an incremental backup should be attempted, otherwise a full backup is performed. + * @param incrementalMax the maximum number of incremental backups allowed between each full backup, ignored if a full backup is requested. + * @param fullMax The maximum number of full backups to keep on disk before creating a new backup erases the oldest backup. + * Set to -1 to create unlimited full backups. If a full backup is removed, any incremental backups for that full backup will also be removed. + * @param zip true to write the backup to a zip file, otherwise false to write the backup to a folder. + * @param errorList a list to capture {@link ErrorReport} objects as returned by methods in {@link ConsistencyCheck}. * - * @param targetDir the output directory or file to which data will be written. Output will be written to a zip file if target ends with - * .zip. - * @param incremental DOCUMENT ME! - * @param maxInc DOCUMENT ME! - * @param zip DOCUMENT ME! - * @param errorList a list of {@link ErrorReport} objects as returned by methods in {@link ConsistencyCheck}. - * @return DOCUMENT ME! + * @return the path to the new backup file or folder. */ - public Path export(final String targetDir, boolean incremental, final int maxInc, final boolean zip, final List errorList) { + public Path export(final String outputPath, boolean incremental, final int incrementalMax, final int fullMax, final boolean zip, final List errorList) { Path backupFile = null; try { - final BackupDirectory directory = new BackupDirectory(targetDir); + final BackupDirectory backupDirectory = new BackupDirectory(outputPath); BackupDescriptor prevBackup = null; if (incremental) { - prevBackup = directory.lastBackupFile(); + prevBackup = backupDirectory.lastBackupFile(); LOG.info("Creating incremental backup. Prev backup: {}", (prevBackup == null) ? "none" : prevBackup.getSymbolicPath()); } @@ -219,12 +222,10 @@ public Path export(final String targetDir, boolean incremental, final int maxInc final Properties prevProp = prevBackup.getProperties(); if (prevProp != null) { - final String seqNrStr = prevProp.getProperty(BackupDescriptor.NUMBER_IN_SEQUENCE_PROP_NAME, "1"); - try { - seqNr = Integer.parseInt(seqNrStr); + seqNr = getIntegerProperty(prevProp, BackupDescriptor.NUMBER_IN_SEQUENCE_PROP_NAME, 1); - if (seqNr == maxInc) { + if (seqNr > incrementalMax) { seqNr = 1; incremental = false; prevBackup = null; @@ -245,7 +246,7 @@ public Path export(final String targetDir, boolean incremental, final int maxInc } catch (final XPathException e) { } - backupFile = directory.createBackup(incremental && (prevBackup != null), zip); + backupFile = backupDirectory.createBackup(incremental && (prevBackup != null), zip); final FunctionE fWriter; if (zip) { @@ -268,6 +269,20 @@ public Path export(final String targetDir, boolean incremental, final int maxInc exportOrphans(output, cb.getDocs(), errorList); } + try { + if (fullMax != -1 && backupDirectory.countFullBackups() > fullMax) { + // There now more full backups than allowed, so delete the oldest full backup and any associated incremental backups + @Nullable final List oldestFullBackupFiles = backupDirectory.getOldestFullBackup(); + if (oldestFullBackupFiles != null) { + for (final Path oldestFullBackupFile : oldestFullBackupFiles) { + FileUtils.deleteQuietly(oldestFullBackupFile); + } + } + } + } catch (final IOException e) { + LOG.error("Unable to remove oldest backup: " + e.getMessage(), e); + } + return backupFile; } catch (final IOException e) { diff --git a/exist-core/src/main/java/org/exist/backup/ZipWriter.java b/exist-core/src/main/java/org/exist/backup/ZipWriter.java index dee39fa485..c27da508f5 100644 --- a/exist-core/src/main/java/org/exist/backup/ZipWriter.java +++ b/exist-core/src/main/java/org/exist/backup/ZipWriter.java @@ -56,6 +56,8 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import static org.exist.backup.BackupDescriptor.BACKUP_PROPERTIES; + /** * Implementation of BackupWriter that writes to a zip file. @@ -152,7 +154,7 @@ public void setProperties(final Properties properties ) throws IOException if( dataWritten ) { throw( new IOException( "Backup properties need to be set before any backup data is written" ) ); } - final ZipEntry entry = new ZipEntry( "backup.properties" ); + final ZipEntry entry = new ZipEntry(BACKUP_PROPERTIES); out.putNextEntry( entry ); try { properties.store(out, "Backup properties"); diff --git a/exist-core/src/main/java/org/exist/client/InteractiveClient.java b/exist-core/src/main/java/org/exist/client/InteractiveClient.java index 4fc917bfe7..149b033709 100644 --- a/exist-core/src/main/java/org/exist/client/InteractiveClient.java +++ b/exist-core/src/main/java/org/exist/client/InteractiveClient.java @@ -2244,7 +2244,7 @@ public boolean run() throws Exception { this.path = options.setCol.orElse(XmldbURI.ROOT_COLLECTION_URI); // get Elemental home - final Optional home = ConfigurationHelper.getExistHome(); + final Optional home = ConfigurationHelper.getElementalHome(); // get default configuration filename from the driver class and set it in properties Optional configFile = ConfigurationHelper.getFromSystemProperty(); diff --git a/exist-core/src/main/java/org/exist/config/Configuration.java b/exist-core/src/main/java/org/exist/config/Configuration.java index e49ec56b6b..0e134490db 100644 --- a/exist-core/src/main/java/org/exist/config/Configuration.java +++ b/exist-core/src/main/java/org/exist/config/Configuration.java @@ -54,6 +54,8 @@ import org.exist.storage.DBBroker; import org.w3c.dom.Element; +import javax.annotation.Nullable; + /** * Configuration interface provide methods to read settings. * @@ -101,7 +103,7 @@ public interface Configuration { * @param property to get the value for * @return String value of the requested property */ - String getProperty(String property); + @Nullable String getProperty(String property); /** * Return property map value. @@ -118,7 +120,7 @@ public interface Configuration { * @return property integer value * */ - Integer getPropertyInteger(String property); + @Nullable Integer getPropertyInteger(String property); /** * Return property long value. @@ -127,7 +129,7 @@ public interface Configuration { * @return property long value * */ - Long getPropertyLong(String property); + @Nullable Long getPropertyLong(String property); /** * Return property boolean value. @@ -136,7 +138,7 @@ public interface Configuration { * @return property boolean value * */ - Boolean getPropertyBoolean(String property); + @Nullable Boolean getPropertyBoolean(String property); /** * Keep at internal map object associated with key. diff --git a/exist-core/src/main/java/org/exist/config/ConfigurationImpl.java b/exist-core/src/main/java/org/exist/config/ConfigurationImpl.java index 6471b73118..9d73fdf711 100644 --- a/exist-core/src/main/java/org/exist/config/ConfigurationImpl.java +++ b/exist-core/src/main/java/org/exist/config/ConfigurationImpl.java @@ -56,8 +56,13 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import javax.annotation.Nullable; import javax.xml.XMLConstants; +import static org.exist.util.PropertiesUtil.getBooleanOrYesNoProperty; +import static org.exist.util.PropertiesUtil.getIntegerProperty; +import static org.exist.util.PropertiesUtil.getLongProperty; + /** * configuration -> element * property -> attribute @@ -185,7 +190,7 @@ public void clearCache() { } @Override - public String getProperty(String name) { + public @Nullable String getProperty(final String name) { cache(); @@ -200,10 +205,11 @@ public String getProperty(String name) { // return null; } - public String getProperty(String name, String default_property) { - final String property = getProperty(name); - - if (property == null) return default_property; + public String getProperty(final String name, final String defaultProperty) { + @Nullable final String property = getProperty(name); + if (property == null) { + return defaultProperty; + } return property; } @@ -280,7 +286,7 @@ public Map getPropertyMap(String name) { } @Override - public boolean hasProperty(String name) { + public boolean hasProperty(final String name) { cache(); return props.containsKey(name); @@ -290,85 +296,34 @@ public boolean hasProperty(String name) { // return (getElementsByTagName(name).getLength() == 1); } - public Object getRuntimeProperty(String name) { + public Object getRuntimeProperty(final String name) { return runtimeProperties.get(name); } - public boolean hasRuntimeProperty(String name) { + public boolean hasRuntimeProperty(final String name) { return runtimeProperties.containsKey(name); } - public void setRuntimeProperty(String name, Object obj) { + public void setRuntimeProperty(final String name, final Object obj) { runtimeProperties.put(name, obj); } @Override - public Boolean getPropertyBoolean(final String name) { - final String value = getProperty(name); - if(value == null) { - return null; - } - switch(value.toLowerCase()) { - case "yes": - case "true": - return true; - - case "no": - case "false": - return false; - - default: - return null; - } - } - - public Boolean getPropertyBoolean(String name, boolean defaultValue) { - Boolean value = getPropertyBoolean(name); - if(value == null) return defaultValue; - - return value; + public @Nullable Boolean getPropertyBoolean(final String name) { + cache(); + return getBooleanOrYesNoProperty(props, name); } @Override - public Integer getPropertyInteger(final String name) { - final String value = getProperty(name); - if (value == null) { - return null; - } - return Integer.valueOf(value); - } - - public Integer getPropertyInteger(final String name, final Integer defaultValue, final boolean positive) { - final String value = getProperty(name); - if (value == null) { - return defaultValue; - } - final int result = Integer.parseInt(value); - if ((positive) && (result < 0)) { - return defaultValue; - } - return result; + public @Nullable Integer getPropertyInteger(final String name) { + cache(); + return getIntegerProperty(props, name); } @Override - public Long getPropertyLong(final String name) { - final String value = getProperty(name); - if (value == null) { - return null; - } - return Long.valueOf(value); - } - - public Long getPropertyLong(final String name, final Long defaultValue, final boolean positive) { - final String value = getProperty(name); - if (value == null) { - return defaultValue; - } - final long result = Long.parseLong(value); - if ((positive) && (result < 0)) { - return defaultValue; - } - return result; + public @Nullable Long getPropertyLong(final String name) { + cache(); + return getLongProperty(props, name); } public Integer getPropertyMegabytes(String name, Integer defaultValue) { diff --git a/exist-core/src/main/java/org/exist/http/Descriptor.java b/exist-core/src/main/java/org/exist/http/Descriptor.java index 255e605de4..43674c52de 100644 --- a/exist-core/src/main/java/org/exist/http/Descriptor.java +++ b/exist-core/src/main/java/org/exist/http/Descriptor.java @@ -51,7 +51,6 @@ import org.exist.dom.memtree.SAXAdapter; import org.exist.util.ConfigurationHelper; import org.exist.util.ExistSAXParserFactory; -import org.exist.util.SingleInstanceConfiguration; import org.exist.xquery.Expression; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -104,6 +103,7 @@ public class Descriptor implements ErrorHandler { private boolean requestsFiltered; private String allowSourceList[] = null; //Array of xql files to allow source to be viewed private String mapList[][] = null; //Array of Mappings + private String webappDir; /** * Descriptor Constructor. @@ -141,6 +141,8 @@ private Descriptor() { } } + this.webappDir = ConfigurationHelper.getElementalHome().map(elementalHome -> elementalHome.resolve("etc")).map(etc -> etc.resolve("webapp")).orElseGet(() -> Paths.get(".")).normalize().toAbsolutePath().toString().replace('\\', '/'); + // initialize xml parser // we use eXist's in-memory DOM implementation to work // around a bug in Xerces @@ -234,8 +236,8 @@ private void configureAllowSourceXQuery(Element allowsourcexqueries) { LOG.warn("Error element 'xquery' requires an attribute 'path'"); return; } - path = path.replaceAll("\\$\\{WEBAPP_HOME\\}", - SingleInstanceConfiguration.getWebappHome().orElse(Paths.get(".")).toAbsolutePath().toString().replace('\\', '/')); + + path = path.replaceAll("\\$\\{WEBAPP_HOME\\}", webappDir); //store the path allowSourceList[i] = path; @@ -270,16 +272,14 @@ private void configureMaps(Element maps) { LOG.warn("Error element 'map' requires an attribute 'path' or an attribute 'pattern'"); return; } - path = path.replaceAll("\\$\\{WEBAPP_HOME\\}", - SingleInstanceConfiguration.getWebappHome().orElse(Paths.get(".")).toAbsolutePath().toString().replace('\\', '/')); + path = path.replaceAll("\\$\\{WEBAPP_HOME\\}", webappDir); //must be a view to map to if (view.isEmpty()) { LOG.warn("Error element 'map' requires an attribute 'view'"); return; } - view = view.replaceAll("\\$\\{WEBAPP_HOME\\}", - SingleInstanceConfiguration.getWebappHome().orElse(Paths.get(".")).toAbsolutePath().toString().replace('\\', '/')); + view = view.replaceAll("\\$\\{WEBAPP_HOME\\}", webappDir); //store what to map from /* if(path != null) diff --git a/exist-core/src/main/java/org/exist/http/servlets/AbstractExistHttpServlet.java b/exist-core/src/main/java/org/exist/http/servlets/AbstractExistHttpServlet.java index b692b60606..b0ecea08f8 100644 --- a/exist-core/src/main/java/org/exist/http/servlets/AbstractExistHttpServlet.java +++ b/exist-core/src/main/java/org/exist/http/servlets/AbstractExistHttpServlet.java @@ -141,7 +141,7 @@ private BrokerPool getOrCreateBrokerPool(final ServletConfig config) throws EXis ) .orElse(Optional.ofNullable(config.getServletContext().getRealPath("/")).map(Paths::get)); - getLog().info("EXistServlet: exist.home={}", dbHome.map(Path::toString).orElse("null")); + getLog().info("EXistServlet: elemental.home={}", dbHome.map(Path::toString).orElse("null")); final Path cf = dbHome.map(h -> h.resolve(confFile)).orElse(Paths.get(confFile)); getLog().info("Reading configuration from {}", cf.toAbsolutePath().toString()); diff --git a/exist-core/src/main/java/org/exist/jetty/JettyStart.java b/exist-core/src/main/java/org/exist/jetty/JettyStart.java index 0a2604499a..bc3086c7ee 100644 --- a/exist-core/src/main/java/org/exist/jetty/JettyStart.java +++ b/exist-core/src/main/java/org/exist/jetty/JettyStart.java @@ -69,7 +69,6 @@ import org.exist.util.ConfigurationHelper; import org.exist.util.FileUtils; import org.exist.util.OSUtil; -import org.exist.util.SingleInstanceConfiguration; import org.exist.util.SystemExitCodes; import org.exist.validation.XmlLibraryChecker; import org.exist.xmldb.DatabaseImpl; @@ -191,7 +190,7 @@ public synchronized void run() { public synchronized void run(final boolean standalone) { final String jettyHome = Optional.ofNullable(System.getProperty(JETTY_HOME_PROP)) .orElseGet(() -> { - final Optional home = ConfigurationHelper.getExistHome(); + final Optional home = ConfigurationHelper.getElementalHome(); final Path toolsJetty = FileUtils.resolve(home, "tools").resolve("jetty"); final String jettyPath = toolsJetty.toAbsolutePath().toString(); System.setProperty(JETTY_HOME_PROP, jettyPath); @@ -275,16 +274,17 @@ public synchronized void run(final String[] args, final Observer observer) { logger.info("[Elemental Build: {}]", SystemProperties.getInstance().getSystemProperty("product-build", "unknown")); logger.info("[Elemental Git commit: {}]", SystemProperties.getInstance().getSystemProperty("git-commit", "unknown")); logger.info("[Elemental Git commit timestamp: {}]", SystemProperties.getInstance().getSystemProperty("git-commit-timestamp", "unknown")); - logger.info("[Elemental Home: {}]", System.getProperty("exist.home", "unknown")); + logger.info("[Elemental Home: {}]", System.getProperty("elemental.home", System.getProperty("exist.home", "unknown"))); // configure the database instance - SingleInstanceConfiguration config; + final String configFilename; if (args.length == 2) { - config = new SingleInstanceConfiguration(args[1]); + configFilename = args[1]; } else { - config = new SingleInstanceConfiguration(); + configFilename = "conf.xml"; } - final String elementalConfigPath = config.getConfigFilePath() + final Configuration configuration = new Configuration(configFilename); + final String elementalConfigPath = configuration.getConfigFilePath() .map(Path::normalize).map(Path::toAbsolutePath).map(Path::toString) .orElse(""); logger.info("[Elemental Configuration: {}]", elementalConfigPath); @@ -301,7 +301,7 @@ public synchronized void run(final String[] args, final Observer observer) { final Object additionalElementalConfigPropertyValue = additionalElementalConfigProperty.getValue(); if (AUTODEPLOY_PROPERTY.equals(additionalElementalConfigPropertyKey) && "off".equals(additionalElementalConfigPropertyValue)) { // remove auto deploy from config if present - final List configuredStartupTriggers = (List) config.getProperty(BrokerPoolConstants.PROPERTY_STARTUP_TRIGGERS); + final List configuredStartupTriggers = (List) configuration.getProperty(BrokerPoolConstants.PROPERTY_STARTUP_TRIGGERS); for (final Configuration.StartupTriggerConfig configuredStartupTrigger : configuredStartupTriggers) { if (AutoDeploymentTrigger.class.getName().equals(configuredStartupTrigger.getClazz())) { configuredStartupTriggers.remove(configuredStartupTrigger); @@ -310,11 +310,11 @@ public synchronized void run(final String[] args, final Observer observer) { } } else { - config.setProperty(additionalElementalConfigPropertyKey.toString(), additionalElementalConfigPropertyValue); + configuration.setProperty(additionalElementalConfigPropertyKey.toString(), additionalElementalConfigPropertyValue); } } - BrokerPool.configure(1, 5, config, Optional.ofNullable(observer)); + BrokerPool.configure(1, 5, configuration, Optional.ofNullable(observer)); // register the XMLDB driver final Database xmldb = new DatabaseImpl(); diff --git a/exist-core/src/main/java/org/exist/launcher/ConfigurationDialog.java b/exist-core/src/main/java/org/exist/launcher/ConfigurationDialog.java index 07d7cf205b..324cbb741c 100644 --- a/exist-core/src/main/java/org/exist/launcher/ConfigurationDialog.java +++ b/exist-core/src/main/java/org/exist/launcher/ConfigurationDialog.java @@ -622,7 +622,7 @@ private void btnSelectDirActionPerformed(java.awt.event.ActionEvent evt) {//GEN- final Optional currentDir = Optional.ofNullable(dataDir.getText()) .map(d -> Optional.of(Paths.get(d))) .filter(md -> md.map(Files::exists).orElse(false)) - .orElse(ConfigurationHelper.getExistHome()); + .orElse(ConfigurationHelper.getElementalHome()); final JFileChooser chooser = new JFileChooser(); chooser.setMultiSelectionEnabled(false); diff --git a/exist-core/src/main/java/org/exist/launcher/ConfigurationUtility.java b/exist-core/src/main/java/org/exist/launcher/ConfigurationUtility.java index 45b6fc0175..5f22d9965a 100644 --- a/exist-core/src/main/java/org/exist/launcher/ConfigurationUtility.java +++ b/exist-core/src/main/java/org/exist/launcher/ConfigurationUtility.java @@ -78,8 +78,8 @@ public class ConfigurationUtility { /** * We try to resolve any config file relative to an Elemental - * config file indicated by the System Property {@link org.exist.util.ConfigurationHelper#PROP_EXIST_CONFIGURATION_FILE}, - * if such a file does not exist, then we try and resolve it from the user.home or EXIST_HOME. + * config file indicated by the System Property {@link org.exist.util.ConfigurationHelper#PROP_ELEMENTAL_CONFIGURATION_FILE}, + * if such a file does not exist, then we try and resolve it from the user.home or ELEMENTAL_HOME. * * @param configFileName the name/relative path of the config file to lookup * @param shouldExist if the file should already exist @@ -89,7 +89,7 @@ public class ConfigurationUtility { public static Path lookup(final String configFileName, final boolean shouldExist) { return org.exist.util.ConfigurationHelper.getFromSystemProperty() .filter(Files::exists) - .map(existConfigFile -> existConfigFile.resolveSibling(configFileName)) + .map(elementalConfigFile -> elementalConfigFile.resolveSibling(configFileName)) .filter(f -> !shouldExist || Files.exists(f)) .orElseGet(() -> org.exist.util.ConfigurationHelper.lookup(configFileName)); } diff --git a/exist-core/src/main/java/org/exist/launcher/Launcher.java b/exist-core/src/main/java/org/exist/launcher/Launcher.java index 6587c8d414..38323eda0e 100644 --- a/exist-core/src/main/java/org/exist/launcher/Launcher.java +++ b/exist-core/src/main/java/org/exist/launcher/Launcher.java @@ -45,6 +45,7 @@ */ package org.exist.launcher; +import com.evolvedbinary.j8fu.OptionalUtil; import org.exist.EXistException; import org.exist.jetty.JettyStart; import org.exist.repo.ExistRepository; @@ -160,10 +161,10 @@ public static void main(final String[] args) { captureConsole(); - // try and figure out exist home dir - final Optional existHomeDir = getFromSysPropOrEnv(Main.PROP_EXIST_HOME, Main.ENV_EXIST_HOME).map(Paths::get); + // try and figure out elemental home dir + final Optional elementalHomeDir = OptionalUtil.or(getFromSysPropOrEnv(Main.PROP_ELEMENTAL_HOME, Main.ENV_ELEMENTAL_HOME), () -> getFromSysPropOrEnv(Main.LEGACY_PROP_EXIST_HOME, Main.LEGACY_ENV_EXIST_HOME)).map(Paths::get); - this.jettyConfig = getJettyConfig(existHomeDir); + this.jettyConfig = getJettyConfig(elementalHomeDir); this.serviceManager = ServiceManagerFactory.getServiceManager(); @@ -757,9 +758,9 @@ public void update(final Observable observable, final Object o) { } } - private Path getJettyConfig(final Optional existHomeDir) { + private Path getJettyConfig(final Optional elementalHomeDir) { - Optional existJettyConfigFile = getFromSysPropOrEnv(Main.PROP_EXIST_JETTY_CONFIG, Main.ENV_EXIST_JETTY_CONFIG).map(Paths::get); + Optional existJettyConfigFile = OptionalUtil.or(getFromSysPropOrEnv(Main.PROP_ELEMENTAL_JETTY_CONFIG, Main.ENV_ELEMENTAL_JETTY_CONFIG), () -> getFromSysPropOrEnv(Main.LEGACY_PROP_EXIST_JETTY_CONFIG, Main.LEGACY_ENV_EXIST_JETTY_CONFIG)).map(Paths::get); if (!existJettyConfigFile.isPresent()) { final Optional jettyHomeDir = getFromSysPropOrEnv(Main.PROP_JETTY_HOME, Main.ENV_JETTY_HOME).map(Paths::get); @@ -767,12 +768,12 @@ private Path getJettyConfig(final Optional existHomeDir) { existJettyConfigFile = jettyHomeDir.map(f -> f.resolve(Main.CONFIG_DIR_NAME).resolve(Main.STANDARD_ENABLED_JETTY_CONFIGS)); } - if (existHomeDir.isPresent() && Files.exists(existHomeDir.get().resolve(Main.CONFIG_DIR_NAME))) { - existJettyConfigFile = existHomeDir.map(f -> f.resolve(Main.CONFIG_DIR_NAME).resolve(Main.STANDARD_ENABLED_JETTY_CONFIGS)); + if (elementalHomeDir.isPresent() && Files.exists(elementalHomeDir.get().resolve(Main.CONFIG_DIR_NAME))) { + existJettyConfigFile = elementalHomeDir.map(f -> f.resolve(Main.CONFIG_DIR_NAME).resolve(Main.STANDARD_ENABLED_JETTY_CONFIGS)); } if (!existJettyConfigFile.isPresent()) { - showMessageAndExit("Error Occurred", "ERROR: jetty config file could not be found! Make sure to set exist.jetty.config or EXIST_JETTY_CONFIG.", true); + showMessageAndExit("Error Occurred", "ERROR: jetty config file could not be found! Make sure to set elemental.jetty.config or ELEMENTAL_JETTY_CONFIG.", true); System.exit(SystemExitCodes.CATCH_ALL_GENERAL_ERROR_EXIT_CODE); } } @@ -888,7 +889,7 @@ public void actionPerformed(final ActionEvent actionEvent) { return; } final Desktop desktop = Desktop.getDesktop(); - final Optional home = ConfigurationHelper.getExistHome(); + final Optional home = ConfigurationHelper.getElementalHome(); final Path logFile = FileUtils.resolve(home, "logs/elemental.log"); diff --git a/exist-core/src/main/java/org/exist/launcher/LauncherWrapper.java b/exist-core/src/main/java/org/exist/launcher/LauncherWrapper.java index b1a4828f17..20982fa2e0 100644 --- a/exist-core/src/main/java/org/exist/launcher/LauncherWrapper.java +++ b/exist-core/src/main/java/org/exist/launcher/LauncherWrapper.java @@ -156,7 +156,7 @@ private void run(final List args) throws IOException { System.out.println(buf.toString()); final ProcessBuilder pb = new ProcessBuilder(args); - final Optional home = ConfigurationHelper.getExistHome(); + final Optional home = ConfigurationHelper.getElementalHome(); pb.directory(home.orElse(Paths.get(".")).toFile()); pb.redirectErrorStream(true); pb.inheritIO(); @@ -194,16 +194,16 @@ protected void getJavaOpts(final List args, final Properties launcherPro final Properties sysProps = System.getProperties(); for (final Map.Entry entry : sysProps.entrySet()) { final String key = entry.getKey().toString(); - if (key.startsWith("exist.") || key.startsWith("log4j.") || key.startsWith("jetty.") || key.startsWith("app.")) { + if (key.startsWith("elemental.") || key.startsWith("exist.") || key.startsWith("log4j.") || key.startsWith("jetty.") || key.startsWith("app.")) { args.add("-D" + key + "=" + entry.getValue().toString()); - if (key.equals("exist.home")) { + if (key.equals("elemental.home") || key.equals("exist.home")) { foundExistHomeSysProp = true; } } } if (!foundExistHomeSysProp) { - args.add("-Dexist.home=\".\""); + args.add("-Delemental.home=\".\""); } if (command.equals(LAUNCHER) && "mac os x".equals(OS)) { diff --git a/exist-core/src/main/java/org/exist/launcher/WindowsServiceManager.java b/exist-core/src/main/java/org/exist/launcher/WindowsServiceManager.java index 0fe426db88..b88c8fa908 100644 --- a/exist-core/src/main/java/org/exist/launcher/WindowsServiceManager.java +++ b/exist-core/src/main/java/org/exist/launcher/WindowsServiceManager.java @@ -102,13 +102,13 @@ private enum WindowsServiceState { WindowsServiceManager() { this.prunsrvExe = new LazyValE<>(() -> - OptionalUtil.toRight(() -> new ServiceManagerException("Could not detect EXIST_HOME when trying to find Procrun exe"), ConfigurationHelper.getExistHome()) + OptionalUtil.toRight(() -> new ServiceManagerException("Could not detect ELEMENTAL_HOME when trying to find Procrun exe"), ConfigurationHelper.getElementalHome()) .map(base -> base.resolve("bin").resolve(PROCRUN_SRV_EXE)) .flatMap(exe -> Files.exists(exe) ? Right(exe) : Left(new ServiceManagerException("Could not find Procrun at: " + exe))) .flatMap(exe -> Files.isExecutable(exe) ? Right(exe) : Left(new ServiceManagerException("Procrun is not executable at: " + exe))) ); - this.existHome = ConfigurationHelper.getExistHome().orElse(Paths.get(".")); + this.existHome = ConfigurationHelper.getElementalHome().orElse(Paths.get(".")); } @Override diff --git a/exist-core/src/main/java/org/exist/management/impl/Database.java b/exist-core/src/main/java/org/exist/management/impl/Database.java index 3a0cfcf9f0..3bb7837b5c 100644 --- a/exist-core/src/main/java/org/exist/management/impl/Database.java +++ b/exist-core/src/main/java/org/exist/management/impl/Database.java @@ -144,9 +144,14 @@ public long getUptime() { return System.currentTimeMillis() - pool.getStartupTime().getTimeInMillis(); } + @Override + public String getElementalHome() { + return pool.getConfiguration().getElementalHome().map(p -> p.toAbsolutePath().toString()).orElse(null); + } + @Override public String getExistHome() { - return pool.getConfiguration().getExistHome().map(p -> p.toAbsolutePath().toString()).orElse(null); + return getElementalHome(); } public String printStackTrace(final Thread thread) { diff --git a/exist-core/src/main/java/org/exist/management/impl/DatabaseMXBean.java b/exist-core/src/main/java/org/exist/management/impl/DatabaseMXBean.java index 2c1caa03e3..68914c1ee9 100644 --- a/exist-core/src/main/java/org/exist/management/impl/DatabaseMXBean.java +++ b/exist-core/src/main/java/org/exist/management/impl/DatabaseMXBean.java @@ -71,5 +71,8 @@ public interface DatabaseMXBean extends PerInstanceMBean { long getUptime(); + String getElementalHome(); + + @Deprecated String getExistHome(); } diff --git a/exist-core/src/main/java/org/exist/repo/AutoDeploymentTrigger.java b/exist-core/src/main/java/org/exist/repo/AutoDeploymentTrigger.java index 3d537d2e13..4201e334e7 100644 --- a/exist-core/src/main/java/org/exist/repo/AutoDeploymentTrigger.java +++ b/exist-core/src/main/java/org/exist/repo/AutoDeploymentTrigger.java @@ -100,7 +100,7 @@ public void execute(final DBBroker sysBroker, final Txn transaction, final Map homeDir = sysBroker.getConfiguration().getExistHome(); + final Optional homeDir = sysBroker.getConfiguration().getElementalHome(); autodeployDir = FileUtils.resolve(homeDir, AUTODEPLOY_DIRECTORY); } } diff --git a/exist-core/src/main/java/org/exist/repo/Deployment.java b/exist-core/src/main/java/org/exist/repo/Deployment.java index 9059d9c170..ecca4d2d17 100644 --- a/exist-core/src/main/java/org/exist/repo/Deployment.java +++ b/exist-core/src/main/java/org/exist/repo/Deployment.java @@ -751,7 +751,7 @@ public String getPurposeString() { final ConsumerE setupXqueryContextPreExecution = xqueryContext -> { xqueryContext.declareVariable("dir", true, tempDir.toAbsolutePath().toString()); - final Optional home = broker.getConfiguration().getExistHome(); + final Optional home = broker.getConfiguration().getElementalHome(); if (home.isPresent()) { xqueryContext.declareVariable("home", true, home.get().toAbsolutePath().toString()); } diff --git a/exist-core/src/main/java/org/exist/repo/ExistRepository.java b/exist-core/src/main/java/org/exist/repo/ExistRepository.java index e1bf8b6642..83f33de679 100644 --- a/exist-core/src/main/java/org/exist/repo/ExistRepository.java +++ b/exist-core/src/main/java/org/exist/repo/ExistRepository.java @@ -122,7 +122,7 @@ public void configure(final Configuration configuration) throws BrokerPoolServic @Override public void prepare(final BrokerPool brokerPool) throws BrokerPoolServiceException { if (!Files.exists(expathDir) && brokerPool != null) { - moveOldRepo(brokerPool.getConfiguration().getExistHome(), expathDir); + moveOldRepo(brokerPool.getConfiguration().getElementalHome(), expathDir); } try { Files.createDirectories(expathDir); @@ -377,7 +377,7 @@ public static Path getRepositoryDir(final Configuration config) throws IOExcepti final Path expathDir = dataDir.resolve(EXPATH_REPO_DIR_NAME); if(!Files.exists(expathDir)) { - moveOldRepo(config.getExistHome(), expathDir); + moveOldRepo(config.getElementalHome(), expathDir); } Files.createDirectories(expathDir); return expathDir; diff --git a/exist-core/src/main/java/org/exist/source/SourceFactory.java b/exist-core/src/main/java/org/exist/source/SourceFactory.java index a6cb344f65..9ca7a06f7a 100644 --- a/exist-core/src/main/java/org/exist/source/SourceFactory.java +++ b/exist-core/src/main/java/org/exist/source/SourceFactory.java @@ -340,11 +340,11 @@ private static Source getSource_fromClasspath(final String contextPath, final St if (source == null) { /* - * Lastly we try to load it using EXIST_HOME as the reference point + * Lastly we try to load it using ELEMENTAL_HOME as the reference point */ Path p8 = null; try { - p8 = FileUtils.resolve(BrokerPool.getInstance().getConfiguration().getExistHome(), locationPath); + p8 = FileUtils.resolve(BrokerPool.getInstance().getConfiguration().getElementalHome(), locationPath); if (Files.isReadable(p8)) { locationPath = p8.toUri().toASCIIString(); source = new FileSource(p8, checkXQEncoding); diff --git a/exist-core/src/main/java/org/exist/storage/ConsistencyCheckTask.java b/exist-core/src/main/java/org/exist/storage/ConsistencyCheckTask.java index 5e467ae994..7575e7d7ac 100644 --- a/exist-core/src/main/java/org/exist/storage/ConsistencyCheckTask.java +++ b/exist-core/src/main/java/org/exist/storage/ConsistencyCheckTask.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 * @@ -44,20 +68,26 @@ import org.exist.xquery.Expression; import org.exist.xquery.TerminatedException; +import javax.annotation.Nullable; + import static java.nio.charset.StandardCharsets.UTF_8; +import static org.exist.util.PropertiesUtil.getBooleanOrYesNoProperty; +import static org.exist.util.PropertiesUtil.getIntegerProperty; +import static org.exist.util.PropertiesUtil.getPositiveIntegerProperty; public class ConsistencyCheckTask implements SystemTask { private final static Logger LOG = LogManager.getLogger(ConsistencyCheckTask.class); - private String exportDir; + private String outputDir; private boolean createBackup = false; private boolean createZip = true; private boolean paused = false; private boolean incremental = false; private boolean incrementalCheck = false; - private boolean checkDocs = false; - private int maxInc = -1; + private int incrementalMax = -1; + private int fullMax = -1; + private boolean checkDocuments = false; private Path lastExportedBackup = null; @@ -68,7 +98,9 @@ public class ConsistencyCheckTask implements SystemTask { public final static String BACKUP_PROP_NAME = "backup"; public final static String INCREMENTAL_PROP_NAME = "incremental"; public final static String INCREMENTAL_CHECK_PROP_NAME = "incremental-check"; - public final static String MAX_PROP_NAME = "max"; + public final static String INCREMENTAL_MAX_PROP_NAME = "incremental-max"; + @Deprecated public final static String LEGACY_INCREMENTAL_MAX_PROP_NAME = "max"; + public final static String FULL_MAX_PROP_NAME = "full-max"; public final static String CHECK_DOCS_PROP_NAME = "check-documents"; private final static LoggingCallback logCallback = new LoggingCallback(); @@ -85,45 +117,47 @@ public String getName() { @Override public void configure(final Configuration config, final Properties properties) throws EXistException { - exportDir = properties.getProperty(OUTPUT_PROP_NAME, "export"); - Path dir = Paths.get(exportDir); + this.outputDir = properties.getProperty(OUTPUT_PROP_NAME, "export"); + Path dir = Paths.get(outputDir); if (!dir.isAbsolute()) { - dir = ((Path) config.getProperty(BrokerPool.PROPERTY_DATA_DIR)).resolve(exportDir); + dir = ((Path) config.getProperty(BrokerPool.PROPERTY_DATA_DIR)).resolve(outputDir); } try { Files.createDirectories(dir); } catch(final IOException ioe) { - throw new EXistException("Unable to create export directory: " + exportDir, ioe); + throw new EXistException("Unable to create export directory: " + outputDir, ioe); } - exportDir = dir.toAbsolutePath().toString(); + this.outputDir = dir.toAbsolutePath().toString(); if (LOG.isDebugEnabled()) { - LOG.debug("Using output directory {}", exportDir); + LOG.debug("Using output directory {}", outputDir); } - final String backup = properties.getProperty(BACKUP_PROP_NAME, "no"); - createBackup = backup.equalsIgnoreCase("YES"); + this.createBackup = getBooleanOrYesNoProperty(properties, BACKUP_PROP_NAME, false); + this.createZip = getBooleanOrYesNoProperty(properties, ZIP_PROP_NAME, true); + this.incremental = getBooleanOrYesNoProperty(properties, INCREMENTAL_PROP_NAME, false); + this.incrementalCheck = getBooleanOrYesNoProperty(properties, INCREMENTAL_CHECK_PROP_NAME, true); - final String zip = properties.getProperty(ZIP_PROP_NAME, "yes"); - createZip = zip.equalsIgnoreCase("YES"); - - final String inc = properties.getProperty(INCREMENTAL_PROP_NAME, "no"); - incremental = inc.equalsIgnoreCase("YES"); - - final String incCheck = properties.getProperty(INCREMENTAL_CHECK_PROP_NAME, "yes"); - incrementalCheck = incCheck.equalsIgnoreCase("YES"); + try { + @Nullable final Integer tmpMaxIncremental = getPositiveIntegerProperty(properties, INCREMENTAL_MAX_PROP_NAME); + if (tmpMaxIncremental != null) { + this.incrementalMax = tmpMaxIncremental; + } else { + this.incrementalMax = getPositiveIntegerProperty(properties, LEGACY_INCREMENTAL_MAX_PROP_NAME, 5); + } + } catch (final NumberFormatException e) { + throw new EXistException("Parameter 'incremental-max' has to be a positive integer: " + e.getMessage()); + } - final String max = properties.getProperty(MAX_PROP_NAME, "5"); try { - maxInc = Integer.parseInt(max); + this.fullMax = getIntegerProperty(properties, FULL_MAX_PROP_NAME, -1); } catch (final NumberFormatException e) { - throw new EXistException("Parameter 'max' has to be an integer"); + throw new EXistException("Parameter 'full-max' has to be an integer: " + e.getMessage()); } - final String check = properties.getProperty(CHECK_DOCS_PROP_NAME, "no"); - checkDocs = check.equalsIgnoreCase("YES"); + this.checkDocuments = getBooleanOrYesNoProperty(properties, CHECK_DOCS_PROP_NAME, false); } @Override @@ -154,7 +188,7 @@ public void execute(final DBBroker broker, final Txn transaction) throws EXistEx report = openLog(); final CheckCallback cb = new CheckCallback(report); - final ConsistencyCheck check = new ConsistencyCheck(broker, transaction, false, checkDocs); + final ConsistencyCheck check = new ConsistencyCheck(broker, transaction, false, checkDocuments); agentInstance.changeStatus(brokerPool, new TaskStatus(TaskStatus.Status.RUNNING_CHECK)); errors = check.checkAll(cb); @@ -179,7 +213,7 @@ public void execute(final DBBroker broker, final Txn transaction) throws EXistEx LOG.info("Starting backup..."); final SystemExport sysexport = new SystemExport(broker, transaction, logCallback, monitor, false); - lastExportedBackup = sysexport.export(exportDir, incremental, maxInc, createZip, errors); + lastExportedBackup = sysexport.export(outputDir, incremental, incrementalMax, fullMax, createZip, errors); agentInstance.changeStatus(brokerPool, new TaskStatus(TaskStatus.Status.RUNNING_BACKUP)); if (lastExportedBackup != null) { @@ -227,10 +261,10 @@ private boolean fatalErrorsFound(final List errors) { private PrintWriter openLog() throws EXistException { try { - final Path file = SystemExport.getUniqueFile("report", ".log", exportDir); + final Path file = SystemExport.getUniqueFile("report", ".log", outputDir); return new PrintWriter(Files.newBufferedWriter(file, UTF_8)); } catch (final IOException e) { - throw new EXistException("ERROR: failed to create report file in " + exportDir, e); + throw new EXistException("ERROR: failed to create report file in " + outputDir, e); } } diff --git a/exist-core/src/main/java/org/exist/storage/NativeBroker.java b/exist-core/src/main/java/org/exist/storage/NativeBroker.java index 4486d60322..c7dedfcaf7 100644 --- a/exist-core/src/main/java/org/exist/storage/NativeBroker.java +++ b/exist-core/src/main/java/org/exist/storage/NativeBroker.java @@ -615,7 +615,7 @@ public XmldbURI prepend(final XmldbURI uri) { try { // 1) try and load from etc/ dir - final Path fInitCollectionConfig = pool.getConfiguration().getExistHome() + final Path fInitCollectionConfig = pool.getConfiguration().getElementalHome() .map(h -> h.resolve("etc").resolve(INIT_COLLECTION_CONFIG)) .orElse(Paths.get("etc").resolve(INIT_COLLECTION_CONFIG)); if (Files.exists(fInitCollectionConfig)) { diff --git a/exist-core/src/main/java/org/exist/storage/journal/Journal.java b/exist-core/src/main/java/org/exist/storage/journal/Journal.java index f0fbd0e856..80e50cfc23 100644 --- a/exist-core/src/main/java/org/exist/storage/journal/Journal.java +++ b/exist-core/src/main/java/org/exist/storage/journal/Journal.java @@ -274,7 +274,7 @@ public Journal(final BrokerPool pool, final Path directory) throws EXistExceptio if (logDir.isPresent()) { Path f = logDir.get(); if (!f.isAbsolute()) { - f = configuration.getExistHome() + f = configuration.getElementalHome() .map(h -> Optional.of(h.resolve(logDir.get()))) .orElse(configuration.getConfigFilePath().map(p -> p.getParent().resolve(logDir.get()))) .orElse(f); diff --git a/exist-core/src/main/java/org/exist/storage/sync/SyncTask.java b/exist-core/src/main/java/org/exist/storage/sync/SyncTask.java index 127d56b5f6..38d378bdd4 100644 --- a/exist-core/src/main/java/org/exist/storage/sync/SyncTask.java +++ b/exist-core/src/main/java/org/exist/storage/sync/SyncTask.java @@ -94,11 +94,9 @@ public String getName() { @Override public void configure(final Configuration config, final Properties properties) throws EXistException { this.diskSpaceMin = 1024L * 1024L * config.getProperty(BrokerPool.DISK_SPACE_MIN_PROPERTY, BrokerPool.DEFAULT_DISK_SPACE_MIN); - - // fixme! - Shouldn't it be data dir AND journal dir we check - // rather than EXIST_HOME? /ljo - dataDir = (Path) config.getProperty(BrokerPool.PROPERTY_DATA_DIR); + this.dataDir = (Path) config.getProperty(BrokerPool.PROPERTY_DATA_DIR); LOG.info("Using DATA_DIR: {}. Minimal disk space required for database to continue operations: {}mb", dataDir.toAbsolutePath().toString(), diskSpaceMin / 1024 / 1024); + final long space = FileUtils.measureFileStore(dataDir, FileStore::getUsableSpace); LOG.info("Usable space on partition containing DATA_DIR: {}: {}mb", dataDir.toAbsolutePath().toString(), space / 1024 / 1024); } diff --git a/exist-core/src/main/java/org/exist/test/ExistEmbeddedServer.java b/exist-core/src/main/java/org/exist/test/ExistEmbeddedServer.java index 78c50e3fea..8db4919168 100644 --- a/exist-core/src/main/java/org/exist/test/ExistEmbeddedServer.java +++ b/exist-core/src/main/java/org/exist/test/ExistEmbeddedServer.java @@ -123,7 +123,7 @@ public ExistEmbeddedServer(final String instanceName, final Path configFile, fin public ExistEmbeddedServer(@Nullable final String instanceName, @Nullable final Path configFile, @Nullable final Properties configProperties, final boolean disableAutoDeploy, final boolean useTemporaryStorage) { this.instanceName = instanceName != null ? instanceName : BrokerPool.DEFAULT_INSTANCE_NAME; - this.home = Paths.get(System.getProperty("exist.home", System.getProperty("user.dir"))); + this.home = Paths.get(System.getProperty("elemental.home", System.getProperty("exist.home", System.getProperty("user.dir")))); this.configFile = configFile != null ? configFile : ConfigurationHelper.lookup("conf.xml", Optional.of(home)); this.configProperties = configProperties != null ? configProperties : new Properties(); this.disableAutoDeploy = disableAutoDeploy; diff --git a/exist-core/src/main/java/org/exist/test/runner/XMLTestRunner.java b/exist-core/src/main/java/org/exist/test/runner/XMLTestRunner.java index 38faabf47f..6064fb8b8e 100644 --- a/exist-core/src/main/java/org/exist/test/runner/XMLTestRunner.java +++ b/exist-core/src/main/java/org/exist/test/runner/XMLTestRunner.java @@ -86,8 +86,8 @@ import static org.exist.util.StringUtil.notNullOrEmptyOrWs; /** - * A JUnit test runner which can run the XML formatter XQuery tests - * using $EXIST_HOME/src/org/exist/xquery/lib/test.xq. + * A JUnit test runner which can run the XML formatted XQuery tests + * using exist-core/src/main/resources/org/exist/xquery/lib/test.xq. * * @author Adam Retter */ diff --git a/exist-core/src/main/java/org/exist/test/runner/XQueryTestRunner.java b/exist-core/src/main/java/org/exist/test/runner/XQueryTestRunner.java index 8b60b55025..d0e352d1d9 100644 --- a/exist-core/src/main/java/org/exist/test/runner/XQueryTestRunner.java +++ b/exist-core/src/main/java/org/exist/test/runner/XQueryTestRunner.java @@ -78,7 +78,7 @@ /** * A JUnit test runner which can run the XQuery tests (XQSuite) - * using $EXIST_HOME/src/org/exist/xquery/lib/xqsuite/xqsuite.xql. + * using exist-core/src/main/resources/org/exist/xquery/lib/xqsuite/xqsuite.xql. * * @author Adam Retter */ @@ -100,7 +100,7 @@ public XQueryTestRunner(final Path path, final boolean parallel) throws Initiali } private static Configuration getConfiguration() throws DatabaseConfigurationException { - final Optional home = Optional.ofNullable(System.getProperty("exist.home", System.getProperty("user.dir"))).map(Paths::get); + final Optional home = Optional.ofNullable(System.getProperty("elemental.home", System.getProperty("exist.home", System.getProperty("user.dir")))).map(Paths::get); final Path confFile = ConfigurationHelper.lookup("conf.xml", home); if (confFile.isAbsolute() && Files.exists(confFile)) { diff --git a/exist-core/src/main/java/org/exist/test/runner/XSuite.java b/exist-core/src/main/java/org/exist/test/runner/XSuite.java index 57623b912d..5db7627e91 100644 --- a/exist-core/src/main/java/org/exist/test/runner/XSuite.java +++ b/exist-core/src/main/java/org/exist/test/runner/XSuite.java @@ -80,8 +80,8 @@ * Using XSuite as a runner allows you to manually * build a suite containing tests from both: * - * 1. XQSuite - as defined in $EXIST_HOME/src/org/exist/xquery/lib/xqsuite/xqsuite.xql - * 2. XML Test - as defined in $EXIST_HOME/src/org/exist/xquery/lib/test.xq + * 1. XQSuite - as defined in exist-core/src/main/resources/org/exist/xquery/lib/xqsuite/xqsuite.xql + * 2. XML Test - as defined in exist-core/src/main/resources/org/exist/xquery/lib/test.xq * * To use it, annotate a class * with @RunWith(XSuite.class) and @XSuiteClasses({"extensions/my-extension/src/test/xquery", ...}). diff --git a/exist-core/src/main/java/org/exist/util/Configuration.java b/exist-core/src/main/java/org/exist/util/Configuration.java index 0b576890ef..b7b3935c47 100644 --- a/exist-core/src/main/java/org/exist/util/Configuration.java +++ b/exist-core/src/main/java/org/exist/util/Configuration.java @@ -111,7 +111,6 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; -import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; @@ -126,39 +125,32 @@ import static org.exist.util.io.VirtualTempPath.DEFAULT_IN_MEMORY_SIZE; -public class Configuration implements ErrorHandler -{ - private final static Logger LOG = LogManager.getLogger(Configuration.class); //Logger - protected Optional configFilePath = Optional.empty(); - protected Optional existHome = Optional.empty(); - - protected DocumentBuilder builder = null; - protected HashMap config = new HashMap<>(); //Configuration - +public class Configuration implements ErrorHandler { + public final static String BINARY_CACHE_CLASS_PROPERTY = "binary.cache.class"; private static final String PRP_DETAILS = "{}: {}"; + private static final Logger LOG = LogManager.getLogger(Configuration.class); //Logger private static final String XQUERY_CONFIGURATION_ELEMENT_NAME = "xquery"; private static final String XQUERY_BUILTIN_MODULES_CONFIGURATION_MODULES_ELEMENT_NAME = "builtin-modules"; private static final String XQUERY_BUILTIN_MODULES_CONFIGURATION_MODULE_ELEMENT_NAME = "module"; - - public final static String BINARY_CACHE_CLASS_PROPERTY = "binary.cache.class"; - + + private final Map config = new HashMap<>(); //Configuration + + protected Optional configFilePath = Optional.empty(); + protected Optional elementalHome = Optional.empty(); + public Configuration() throws DatabaseConfigurationException { this(DatabaseImpl.CONF_XML, Optional.empty()); } - - public Configuration(final String configFilename) throws DatabaseConfigurationException { + public Configuration(@Nullable final String configFilename) throws DatabaseConfigurationException { this(configFilename, Optional.empty()); } - - public Configuration(String configFilename, Optional existHomeDirname) throws DatabaseConfigurationException { + public Configuration(@Nullable String configFilename, Optional elementalHomeDirname) + throws DatabaseConfigurationException { InputStream is = null; try { - - existHomeDirname = existHomeDirname.map(Path::normalize); - - if(configFilename == null) { + if (configFilename == null) { // Default file name configFilename = DatabaseImpl.CONF_XML; } @@ -189,32 +181,35 @@ public Configuration(String configFilename, Optional existHomeDirname) thr LOG.debug(e); } + elementalHomeDirname = elementalHomeDirname.map(Path::normalize); + // otherwise, secondly try to read configuration from file. Guess the // location if necessary - if(is == null) { - existHome = existHomeDirname.map(Optional::of).orElse(ConfigurationHelper.getExistHome(configFilename)); + if (is == null) { + elementalHome = elementalHomeDirname.map(Optional::of) + .orElse(ConfigurationHelper.getElementalHome(configFilename)); - if(!existHome.isPresent()) { + if (!elementalHome.isPresent()) { - // EB: try to create existHome based on location of config file + // EB: try to create elementalHome based on location of config file // when config file points to absolute file location final Path absoluteConfigFile = Paths.get(configFilename); if(absoluteConfigFile.isAbsolute() && Files.exists(absoluteConfigFile) && Files.isReadable(absoluteConfigFile)) { - existHome = Optional.of(absoluteConfigFile.getParent()); + elementalHome = Optional.of(absoluteConfigFile.getParent()); configFilename = FileUtils.fileName(absoluteConfigFile); } } Path configFile = Paths.get(configFilename); - if(!configFile.isAbsolute() && existHome.isPresent()) { + if (!configFile.isAbsolute() && elementalHome.isPresent()) { - // try the passed or constructed existHome first - configFile = existHome.get().resolve(configFilename); + // try the passed or constructed elementalHome first + configFile = elementalHome.get().resolve(configFilename); if (!Files.exists(configFile)) { - configFile = existHome.get().resolve(Main.CONFIG_DIR_NAME).resolve(configFilename); + configFile = elementalHome.get().resolve(Main.CONFIG_DIR_NAME).resolve(configFilename); } } @@ -232,11 +227,10 @@ public Configuration(String configFilename, Optional existHomeDirname) thr LOG.info("Reading configuration from file {}", configFilePath.map(Path::toString).orElse("Unknown")); - // set dbHome to parent of the conf file found, to resolve relative - // path from conf file - existHomeDirname = configFilePath.map(Path::getParent); + // set dbHome to parent of the conf file found, to resolve relative path from conf file + final Optional elementalHomePath = configFilePath.map(Path::getParent); - loadConfigFile(is, existHomeDirname); + loadConfigFile(is, elementalHomePath); } catch (final SAXException | IOException | ParserConfigurationException e) { LOG.error("Error while reading config file: {}", configFilename, e); @@ -244,21 +238,19 @@ public Configuration(String configFilename, Optional existHomeDirname) thr } } - public Configuration(final InputStream config, final Optional existHomePath) throws DatabaseConfigurationException { + public Configuration(final InputStream config, final Optional elementalHome) throws DatabaseConfigurationException { try { - this.existHome = existHomePath; - loadConfigFile(config, existHome); + this.elementalHome = elementalHome; + loadConfigFile(config, elementalHome); } catch (final SAXException | IOException | ParserConfigurationException e) { LOG.error("Error while reading config file: {}", e.getMessage(), e); throw new DatabaseConfigurationException(e.getMessage(), e); } } - private void loadConfigFile(final InputStream is, final Optional existHomePath) throws ParserConfigurationException, IOException, SAXException, DatabaseConfigurationException { - + private void loadConfigFile(final InputStream is, final Optional elementalHomePath) throws ParserConfigurationException, IOException, SAXException, DatabaseConfigurationException { // initialize xml parser - // we use eXist's in-memory DOM implementation to work - // around a bug in Xerces + // we use eXist's in-memory DOM implementation to work around a bug in Xerces final SAXParserFactory factory = ExistSAXParserFactory.getSAXParserFactory(); factory.setNamespaceAware(true); @@ -280,7 +272,7 @@ private void loadConfigFile(final InputStream is, final Optional existHome //indexer settings final NodeList indexers = doc.getElementsByTagName(Indexer.CONFIGURATION_ELEMENT_NAME); if(indexers.getLength() > 0) { - configureIndexer(existHomePath, doc, (Element)indexers.item( 0 ) ); + configureIndexer(elementalHomePath, doc, (Element)indexers.item( 0 ) ); } //scheduler settings @@ -292,7 +284,7 @@ private void loadConfigFile(final InputStream is, final Optional existHome //db connection settings final NodeList dbcon = doc.getElementsByTagName(BrokerPool.CONFIGURATION_CONNECTION_ELEMENT_NAME); if(dbcon.getLength() > 0) { - configureBackend(existHomePath, (Element)dbcon.item(0)); + configureBackend(elementalHomePath, (Element)dbcon.item(0)); } // lock-table settings @@ -346,7 +338,7 @@ private void loadConfigFile(final InputStream is, final Optional existHome //Validation final NodeList validations = doc.getElementsByTagName(XMLReaderObjectFactory.CONFIGURATION_ELEMENT_NAME); if(validations.getLength() > 0) { - configureValidation(existHomePath, (Element)validations.item(0)); + configureValidation(elementalHomePath, (Element)validations.item(0)); } //RPC server @@ -1520,6 +1512,9 @@ private void configureValidation(final Optional dbHome, final Element vali if (uri.indexOf("${WEBAPP_HOME}") != -1) { uri = uri.replaceAll("\\$\\{WEBAPP_HOME\\}", webappHome.toUri().toString()); } + if (uri.indexOf("${ELEMENTAL_HOME}") != -1) { + uri = uri.replaceAll("\\$\\{ELEMENTAL_HOME\\}", dbHome.toString()); + } if (uri.indexOf("${EXIST_HOME}") != -1) { uri = uri.replaceAll("\\$\\{EXIST_HOME\\}", dbHome.toString()); } @@ -1632,9 +1627,25 @@ public Optional getConfigFilePath() { return configFilePath; } + /** + * Get the value of ELEMENTAL_HOME. + * + * @return the path to ELEMENTAL_HOME. + */ + public Optional getElementalHome() { + return elementalHome; + } + /** + * Get the value of ELEMENTAL_HOME. + * + * @return the path to ELEMENTAL_HOME. + * + * @deprecated use {@link #getElementalHome()} ()}. + */ + @Deprecated public Optional getExistHome() { - return existHome; + return getElementalHome(); } @@ -1650,7 +1661,6 @@ public boolean hasProperty(final String name) { return config.containsKey(name); } - public void setProperty(final String name, final Object obj) { config.put(name, obj); } diff --git a/exist-core/src/main/java/org/exist/util/ConfigurationHelper.java b/exist-core/src/main/java/org/exist/util/ConfigurationHelper.java index f296ab1f53..4d5ee38305 100644 --- a/exist-core/src/main/java/org/exist/util/ConfigurationHelper.java +++ b/exist-core/src/main/java/org/exist/util/ConfigurationHelper.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 * @@ -42,33 +66,45 @@ public class ConfigurationHelper { private final static Logger LOG = LogManager.getLogger(ConfigurationHelper.class); //Logger - public static final String PROP_EXIST_CONFIGURATION_FILE = "exist.configurationFile"; + public static final String PROP_ELEMENTAL_CONFIGURATION_FILE = "elemental.configurationFile"; + /** + * @deprecated use {@link #PROP_ELEMENTAL_CONFIGURATION_FILE}. + */ + public static final String LEGACY_PROP_EXIST_CONFIGURATION_FILE = "exist.configurationFile"; /** - * Returns a file handle for eXist's home directory. - * Order of tests is designed with the idea, the more precise it is, - * the more the developer know what he is doing + * Returns a file handle for Elemental's home directory. + * We search in the following order. *
    - *
  1. Brokerpool : if eXist was already configured. - *
  2. exist.home : if exists + *
  3. BrokerPool : if Elemental was already configured. + *
  4. elemental.home : if exists + *
  5. exist.home : (legacy) if exists *
  6. user.home : if exists, with a conf.xml file *
  7. user.dir : if exists, with a conf.xml file *
  8. classpath entry : if exists, with a conf.xml file *
* - * @return the path to exist home if known + * @return the path to Elemental's home if known + */ + public static Optional getElementalHome() { + return getElementalHome(DatabaseImpl.CONF_XML); + } + + /** + * @deprecated use {@link #getElementalHome()}. */ + @Deprecated public static Optional getExistHome() { - return getExistHome(DatabaseImpl.CONF_XML); + return getElementalHome(); } /** - * Returns a file handle for eXist's home directory. - * Order of tests is designed with the idea, the more precise it is, - * the more the developper know what he is doing + * Returns a file handle for Elemental's home directory. + * We search in the following order. *
    - *
  1. Brokerpool : if eXist was already configured. - *
  2. exist.home : if exists + *
  3. BrokerPool : if Elemental was already configured. + *
  4. elemental.home : if exists + *
  5. exist.home : (legacy) if exists *
  6. user.home : if exists, with a conf.xml file *
  7. user.dir : if exists, with a conf.xml file *
  8. classpath entry : if exists, with a conf.xml file @@ -76,30 +112,39 @@ public static Optional getExistHome() { * * @param config the path to the config file. * - * @return the path to exist home if known + * @return the path to Elemental's home if known */ - public static Optional getExistHome(final String config) { - // If eXist was already configured, then return - // the existHome of this instance. + public static Optional getElementalHome(final String config) { + // If Elemental was already configured, then return + // the E of this instance. try { final BrokerPool broker = BrokerPool.getInstance(); if(broker != null) { - final Optional existHome = broker.getConfiguration().getExistHome().map(Path::normalize); - if(existHome.isPresent()) { - LOG.debug("Got eXist home from broker: {}", existHome); - return existHome; + final Optional elementalHome = broker.getConfiguration().getElementalHome().map(Path::normalize); + if(elementalHome.isPresent()) { + LOG.debug("Got Elemental home from broker: {}", elementalHome); + return elementalHome; } } } catch(final Throwable e) { // Catch all potential problems LOG.debug("Could not retrieve instance of BrokerPool: {}", e.getMessage()); } + + // try elemental.home + if (System.getProperty("elemental.home") != null) { + final Path elementalHome = ConfigurationHelper.decodeUserHome(System.getProperty("elemental.home")).normalize(); + if (Files.isDirectory(elementalHome)) { + LOG.debug("Got Elemental home from system property 'elemental.home': {}", elementalHome.toAbsolutePath().toString()); + return Optional.of(elementalHome); + } + } // try exist.home if (System.getProperty("exist.home") != null) { final Path existHome = ConfigurationHelper.decodeUserHome(System.getProperty("exist.home")).normalize(); if (Files.isDirectory(existHome)) { - LOG.debug("Got eXist home from system property 'exist.home': {}", existHome.toAbsolutePath().toString()); + LOG.debug("Got Elemental home from system property 'exist.home': {}", existHome.toAbsolutePath().toString()); return Optional.of(existHome); } } @@ -108,9 +153,9 @@ public static Optional getExistHome(final String config) { final Path userHome = Paths.get(System.getProperty("user.home")); 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(), userHome.toAbsolutePath()); - return Optional.of(existHome); + final Path elementalHome = userHomeRelativeConfig.getParent().normalize(); + LOG.debug("Got Elemental home: {} from system property 'user.home': {}", elementalHome.toAbsolutePath(), userHome.toAbsolutePath()); + return Optional.of(elementalHome); } @@ -118,61 +163,70 @@ public static Optional getExistHome(final String config) { final Path userDir = Paths.get(System.getProperty("user.dir")); 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(), userDir.toAbsolutePath()); - return Optional.of(existHome); + final Path elementalHome = userDirRelativeConfig.getParent().normalize(); + LOG.debug("Got Elemental home: {} from system property 'user.dir': {}", elementalHome.toAbsolutePath(), userDir.toAbsolutePath()); + return Optional.of(elementalHome); } // try classpath final URL configUrl = ConfigurationHelper.class.getClassLoader().getResource(config); if (configUrl != null) { try { - Path existHome; + Path elementalHome; if ("jar".equals(configUrl.getProtocol())) { - 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); + elementalHome = Paths.get(new URI(configUrl.getPath())).getParent().getParent().normalize(); + LOG.warn("{} file was found on the classpath, but inside a Jar file! Derived Elemental home from Jar's parent folder: {}", config, elementalHome); } else { - existHome = Paths.get(configUrl.toURI()).getParent().normalize(); - if (FileUtils.fileName(existHome).equals("etc")) { - existHome = existHome.getParent().normalize(); + elementalHome = Paths.get(configUrl.toURI()).getParent().normalize(); + if (FileUtils.fileName(elementalHome).equals("etc")) { + elementalHome = elementalHome.getParent().normalize(); } - LOG.debug("Got EXIST_HOME from classpath: {}", existHome.toAbsolutePath().toString()); + LOG.debug("Got Elemental Home from classpath: {}", elementalHome.toAbsolutePath().toString()); } - return Optional.of(existHome); + return Optional.of(elementalHome); } catch (final URISyntaxException e) { // Catch all potential problems - LOG.error("Could not derive EXIST_HOME from classpath: {}", e.getMessage(), e); + LOG.error("Could not derive Elemental home from classpath: {}", e.getMessage(), e); } } return Optional.empty(); } + /** + * @deprecated use {@link #getElementalHome(String)} + */ + @Deprecated + public static Optional getExistHome(final String config) { + return getElementalHome(config); + } + public static Optional getFromSystemProperty() { - return Optional.ofNullable(System.getProperty(PROP_EXIST_CONFIGURATION_FILE)).map(Paths::get); + return Optional.ofNullable(System.getProperty(PROP_ELEMENTAL_CONFIGURATION_FILE)).map(Paths::get); } /** - * Returns a file handle for the given path, while path specifies - * the path to an eXist configuration file or directory. + * Returns a file handle for the given path, where path specifies + * the path to an Elemental configuration file or directory. *
    - * Note that relative paths are being interpreted relative to exist.home - * or the current working directory, in case exist.home was not set. + * Note that relative paths are being interpreted relative to elemental.home + * or the current working directory (in the case that elemental.home was not set). * - * @param path the file path - * @return the file handle + * @param path the file path. + * + * @return the file handle. */ public static Path lookup(final String path) { return lookup(path, Optional.empty()); } /** - * Returns a file handle for the given path, while path specifies - * the path to an eXist configuration file or directory. + * Returns a file handle for the given path, where path specifies + * the path to an Elemental configuration file or directory. *
    * If parent is null, then relative paths are being interpreted - * relative to exist.home or the current working directory, in - * case exist.home was not set. + * relative to elemental.home or the current working directory (in + * case elemental.home was not set). * * @param path path to the file or directory * @param parent parent directory used to lookup path @@ -183,7 +237,7 @@ public static Path lookup(final String path, final Optional parent) { Path p = decodeUserHome(path); if (!p.isAbsolute()) { p = parent - .orElse(getExistHome().orElse(Paths.get(System.getProperty("user.dir")))) + .orElse(getElementalHome().orElse(Paths.get(System.getProperty("user.dir")))) .resolve(path); } return p.normalize().toAbsolutePath(); diff --git a/exist-core/src/main/java/org/exist/util/PropertiesUtil.java b/exist-core/src/main/java/org/exist/util/PropertiesUtil.java new file mode 100644 index 0000000000..fa7b80d569 --- /dev/null +++ b/exist-core/src/main/java/org/exist/util/PropertiesUtil.java @@ -0,0 +1,576 @@ +/* + * 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.util; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.Map; +import java.util.Properties; + +/** + * Utilities for working with {@link java.util.Properties}. + * + * @author Adam Retter + */ +@NullMarked +public class PropertiesUtil { + + /** + * Parse a boolean property as a boolean value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + */ + public static boolean getBooleanProperty(final Properties properties, final String name, final boolean defaultValue) { + @Nullable final String str = properties.getProperty(name); + if (str == null) { + return defaultValue; + } + return "true".equalsIgnoreCase(str); + } + + /** + * Parse a boolean property as a boolean value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + */ + public static boolean getBooleanProperty(final Map properties, final String name, final boolean defaultValue) { + @Nullable final String str = properties.get(name); + if (str == null) { + return defaultValue; + } + return "true".equalsIgnoreCase(str); + } + + /** + * Parse a boolean property as a boolean value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + */ + public static @Nullable Boolean getBooleanProperty(final Properties properties, final String name) { + @Nullable final String str = properties.getProperty(name); + if (str == null) { + return null; + } + return "true".equalsIgnoreCase(str); + } + + /** + * Parse a boolean property as a boolean value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + */ + public static @Nullable Boolean getBooleanProperty(final Map properties, final String name) { + @Nullable final String str = properties.get(name); + if (str == null) { + return null; + } + return "true".equalsIgnoreCase(str); + } + + /** + * Parse a yes/no string property as a boolean value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + */ + public static boolean getYesNoProperty(final Properties properties, final String name, final boolean defaultValue) { + @Nullable final String str = properties.getProperty(name); + if (str == null) { + return defaultValue; + } + return "yes".equalsIgnoreCase(str); + } + + /** + * Parse a yes/no string property as a boolean value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + */ + public static boolean getYesNoProperty(final Map properties, final String name, final boolean defaultValue) { + @Nullable final String str = properties.get(name); + if (str == null) { + return defaultValue; + } + return "yes".equalsIgnoreCase(str); + } + + /** + * Parse a yes/no string property as a boolean value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + */ + public static @Nullable Boolean getYesNoProperty(final Properties properties, final String name) { + @Nullable final String str = properties.getProperty(name); + if (str == null) { + return null; + } + return "yes".equalsIgnoreCase(str); + } + + /** + * Parse a yes/no string property as a boolean value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + */ + public static @Nullable Boolean getYesNoProperty(final Map properties, final String name) { + @Nullable final String str = properties.get(name); + if (str == null) { + return null; + } + return "yes".equalsIgnoreCase(str); + } + + /** + * Parse a boolean or yes/no string property as a boolean value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + */ + public static boolean getBooleanOrYesNoProperty(final Properties properties, final String name, final boolean defaultValue) { + @Nullable String str = properties.getProperty(name); + if (str == null) { + return defaultValue; + } + + str = str.toLowerCase(); + return "true".equals(str) || "yes".equals(str); + } + + /** + * Parse a boolean or yes/no string property as a boolean value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + */ + public static boolean getBooleanOrYesNoProperty(final Map properties, final String name, final boolean defaultValue) { + @Nullable String str = properties.get(name); + if (str == null) { + return defaultValue; + } + + str = str.toLowerCase(); + return "true".equals(str) || "yes".equals(str); + } + + /** + * Parse a boolean or yes/no string property as a boolean value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + */ + public static @Nullable Boolean getBooleanOrYesNoProperty(final Properties properties, final String name) { + @Nullable String str = properties.getProperty(name); + if (str == null) { + return null; + } + str = str.toLowerCase(); + return "true".equals(str) || "yes".equals(str); + } + + /** + * Parse a boolean or yes/no string property as a boolean value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + */ + public static @Nullable Boolean getBooleanOrYesNoProperty(final Map properties, final String name) { + @Nullable String str = properties.get(name); + if (str == null) { + return null; + } + str = str.toLowerCase(); + return "true".equals(str) || "yes".equals(str); + } + + /** + * Parse an integer property as an integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + * + * @throws NumberFormatException if the property is not an integer. + */ + public static int getIntegerProperty(final Properties properties, final String name, final int defaultValue) throws NumberFormatException { + @Nullable final String str = properties.getProperty(name); + if (str == null) { + return defaultValue; + } + return Integer.parseInt(str); + } + + /** + * Parse an integer property as an integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + * + * @throws NumberFormatException if the property is not an integer. + */ + public static int getIntegerProperty(final Map properties, final String name, final int defaultValue) throws NumberFormatException { + @Nullable final String str = properties.get(name); + if (str == null) { + return defaultValue; + } + return Integer.parseInt(str); + } + + /** + * Parse an integer property as an integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + * + * @throws NumberFormatException if the property is not an integer. + */ + public static @Nullable Integer getIntegerProperty(final Properties properties, final String name) throws NumberFormatException { + @Nullable final String str = properties.getProperty(name); + if (str == null) { + return null; + } + return Integer.valueOf(str); + } + + /** + * Parse an integer property as an integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + * + * @throws NumberFormatException if the property is not an integer. + */ + public static @Nullable Integer getIntegerProperty(final Map properties, final String name) throws NumberFormatException { + @Nullable final String str = properties.get(name); + if (str == null) { + return null; + } + return Integer.valueOf(str); + } + + /** + * Parse a positive integer property as a positive integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + * + * @throws NumberFormatException if the property is not a positive integer. + */ + public static int getPositiveIntegerProperty(final Properties properties, final String name, final int defaultValue) throws NumberFormatException { + @Nullable final String str = properties.getProperty(name); + if (str == null) { + return defaultValue; + } + + final int result = Integer.parseInt(str); + if (result < 0) { + throw new NumberFormatException("Expected a positive integer, but found: " + str); + } + + return result; + } + + /** + * Parse a positive integer property as a positive integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + * + * @throws NumberFormatException if the property is not a positive integer. + */ + public static int getPositiveIntegerProperty(final Map properties, final String name, final int defaultValue) throws NumberFormatException { + @Nullable final String str = properties.get(name); + if (str == null) { + return defaultValue; + } + + final int result = Integer.parseInt(str); + if (result < 0) { + throw new NumberFormatException("Expected a positive integer, but found: " + str); + } + + return result; + } + + /** + * Parse a positive integer property as a positive integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + * + * @throws NumberFormatException if the property is not a positive integer. + */ + public static @Nullable Integer getPositiveIntegerProperty(final Properties properties, final String name) throws NumberFormatException { + @Nullable final String str = properties.getProperty(name); + if (str == null) { + return null; + } + + final int result = Integer.parseInt(str); + if (result < 0) { + throw new NumberFormatException("Expected a positive integer, but found: " + str); + } + + return result; + } + + /** + * Parse a positive integer property as a positive integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + * + * @throws NumberFormatException if the property is not a positive integer. + */ + public static @Nullable Integer getPositiveIntegerProperty(final Map properties, final String name) throws NumberFormatException { + @Nullable final String str = properties.get(name); + if (str == null) { + return null; + } + + final int result = Integer.parseInt(str); + if (result < 0) { + throw new NumberFormatException("Expected a positive integer, but found: " + str); + } + + return result; + } + + /** + * Parse a long integer property as a long integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + */ + public static long getLongProperty(final Properties properties, final String name, final long defaultValue) throws NumberFormatException { + @Nullable final String str = properties.getProperty(name); + if (str == null) { + return defaultValue; + } + return Long.parseLong(str); + } + + /** + * Parse a long integer property as a long integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + */ + public static long getLongProperty(final Map properties, final String name, final long defaultValue) throws NumberFormatException { + @Nullable final String str = properties.get(name); + if (str == null) { + return defaultValue; + } + return Long.parseLong(str); + } + + /** + * Parse a long integer property as a long integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + */ + public static @Nullable Long getLongProperty(final Properties properties, final String name) throws NumberFormatException { + @Nullable final String str = properties.getProperty(name); + if (str == null) { + return null; + } + return Long.valueOf(str); + } + + /** + * Parse a long integer property as a long integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + */ + public static @Nullable Long getLongProperty(final Map properties, final String name) throws NumberFormatException { + @Nullable final String str = properties.get(name); + if (str == null) { + return null; + } + return Long.valueOf(str); + } + + /** + * Parse a positive long integer property as a positive long integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + * + * @throws NumberFormatException if the property is not a positive long integer. + */ + public static long getPositiveLongProperty(final Properties properties, final String name, final long defaultValue) throws NumberFormatException { + @Nullable final String str = properties.getProperty(name); + if (str == null) { + return defaultValue; + } + + final long result = Long.parseLong(str); + if (result < 0) { + throw new NumberFormatException("Expected a positive long integer, but found: " + str); + } + + return result; + } + + /** + * Parse a positive long integer property as a positive long integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * @param defaultValue the default value to return if there is no such named property. + * + * @return the parsed value, or default value if there is no such named property. + * + * @throws NumberFormatException if the property is not a positive long integer. + */ + public static long getPositiveLongProperty(final Map properties, final String name, final long defaultValue) throws NumberFormatException { + @Nullable final String str = properties.get(name); + if (str == null) { + return defaultValue; + } + + final long result = Long.parseLong(str); + if (result < 0) { + throw new NumberFormatException("Expected a positive long integer, but found: " + str); + } + + return result; + } + + /** + * Parse a positive long integer property as a positive long integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + * + * @throws NumberFormatException if the property is not a positive long integer. + */ + public static @Nullable Long getPositiveLongProperty(final Properties properties, final String name) throws NumberFormatException { + @Nullable final String str = properties.getProperty(name); + if (str == null) { + return null; + } + + final long result = Long.parseLong(str); + if (result < 0) { + throw new NumberFormatException("Expected a positive long integer, but found: " + str); + } + + return result; + } + + /** + * Parse a positive long integer property as a positive long integer value. + * + * @param properties the properties collection. + * @param name the name of the property to retrieve. + * + * @return the parsed value, or null if there is no such named property. + * + * @throws NumberFormatException if the property is not a positive long integer. + */ + public static @Nullable Long getPositiveLongProperty(final Map properties, final String name) throws NumberFormatException { + @Nullable final String str = properties.get(name); + if (str == null) { + return null; + } + + final long result = Long.parseLong(str); + if (result < 0) { + throw new NumberFormatException("Expected a positive long integer, but found: " + str); + } + + return result; + } +} diff --git a/exist-core/src/main/java/org/exist/util/SingleInstanceConfiguration.java b/exist-core/src/main/java/org/exist/util/SingleInstanceConfiguration.java deleted file mode 100644 index 2b28aae891..0000000000 --- a/exist-core/src/main/java/org/exist/util/SingleInstanceConfiguration.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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.util; - -import java.nio.file.Path; -import java.util.Optional; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class SingleInstanceConfiguration extends Configuration { - - /* FIXME: It's not clear whether this class is meant to be a singleton (due to the static - * file and existHome fields and static methods), or if we should allow many instances to - * run around in the system. Right now, any attempts to create multiple instances will - * likely get the system confused. Let's decide which one it should be and fix it properly. - * - * This class cannot be a singleton as it is possible to run multiple instances of the database - * on the same system. - */ - - @SuppressWarnings("unused") - private final static Logger LOG = LogManager.getLogger(SingleInstanceConfiguration.class); //Logger - protected static Optional _configFile = Optional.empty(); //config file (conf.xml by default) - protected static Optional _existHome = Optional.empty(); - - - public SingleInstanceConfiguration() throws DatabaseConfigurationException { - this("conf.xml", Optional.empty()); - } - - public SingleInstanceConfiguration(final String configFilename) throws DatabaseConfigurationException { - this(configFilename, Optional.empty()); - } - - public SingleInstanceConfiguration(String configFilename, Optional existHomeDirname) throws DatabaseConfigurationException { - super(configFilename, existHomeDirname); - _configFile = configFilePath; - _existHome = existHome; - } - - /** - * Returns the absolute path to the configuration file. - * - * @return the path to the configuration file - */ - public static Optional getPath() { - if (!_configFile.isPresent()) { - final Path f = ConfigurationHelper.lookup("conf.xml"); - return Optional.of(f); - } - return _configFile; - } - - /** - * Get folder in which the exist webapplications are found. - * For default install ("jar install") and in webcontainer ("war install") - * the location is different. (EXIST_HOME/webapps vs. TOMCAT/webapps/exist) - * - * @return folder. - */ - public static Optional getWebappHome(){ - // if existHome is not set, try to do so. - if (!_existHome.isPresent()){ - _existHome = ConfigurationHelper.getExistHome(); - } - - return _existHome.map(h -> h.resolve("webapp")); - } -} diff --git a/exist-core/src/main/java/org/exist/webstart/JnlpServlet.java b/exist-core/src/main/java/org/exist/webstart/JnlpServlet.java index 8b96fb5c75..9f8c652620 100644 --- a/exist-core/src/main/java/org/exist/webstart/JnlpServlet.java +++ b/exist-core/src/main/java/org/exist/webstart/JnlpServlet.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 * @@ -19,7 +43,6 @@ * 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.webstart; import java.io.EOFException; @@ -63,7 +86,7 @@ public void init() throws ServletException { (Supplier>) () -> or ( // using explicit type declaration in order to circumvent AspectJ compiler bug, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=553623 Optional.ofNullable(System.getProperty("app.home")).map(Paths::get).map(p -> p.resolve("lib")).filter(Files::exists), (Supplier>) () -> or ( // using explicit type declaration in order to circumvent AspectJ compiler bug, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=553623 - Optional.ofNullable(System.getProperty("exist.home")).map(Paths::get).map(p -> p.resolve("lib")).filter(Files::exists), + Optional.ofNullable(System.getProperty("elemental.home", System.getProperty("exist.home"))).map(Paths::get).map(p -> p.resolve("lib")).filter(Files::exists), () -> Optional.ofNullable(getServletContext().getRealPath("/")).map(Paths::get).map(p -> p.resolve("lib")).filter(Files::exists) ) ) diff --git a/exist-core/src/main/java/org/exist/xquery/functions/system/GetElementalHome.java b/exist-core/src/main/java/org/exist/xquery/functions/system/GetElementalHome.java new file mode 100644 index 0000000000..c30b591844 --- /dev/null +++ b/exist-core/src/main/java/org/exist/xquery/functions/system/GetElementalHome.java @@ -0,0 +1,78 @@ +/* + * 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 org.exist.xquery.BasicFunction; +import org.exist.xquery.FunctionSignature; +import org.exist.xquery.XPathException; +import org.exist.xquery.XQueryContext; +import org.exist.xquery.value.Sequence; +import org.exist.xquery.value.StringValue; +import org.exist.xquery.value.Type; + +import java.nio.file.Path; +import java.util.Optional; + +import static org.exist.xquery.FunctionDSL.deprecated; +import static org.exist.xquery.FunctionDSL.returns; +import static org.exist.xquery.functions.system.SystemModule.functionSignature; + +/** + * Get the path to Elemental Home. + * + * @author Adam Retter + */ +public class GetElementalHome extends BasicFunction { + + private static final String FS_GET_ELEMENTAL_HOME_NAME = "get-elemental-home"; + static final FunctionSignature FS_GET_ELEMENTAL_HOME = functionSignature( + FS_GET_ELEMENTAL_HOME_NAME, + "Returns the path from ELEMENTAL_HOME; the path of where Elemental is installed and running from", + returns(Type.STRING, "The path from ELEMENTAL_HOME") + ); + + @Deprecated + private static final String FS_GET_EXIST_HOME_NAME = "get-exist-home"; + @Deprecated + static final FunctionSignature FS_GET_EXIST_HOME = deprecated( + "Use system:get-elemental-home() instead", + functionSignature( + FS_GET_EXIST_HOME_NAME, + "Returns the path from EXIST_HOME; the path of where Elemental is installed and running from", + returns(Type.STRING, "The path from EXIST_HOME") + ) + ); + + public GetElementalHome(final XQueryContext context, final FunctionSignature signature) { + super(context, signature); + } + + @Override + public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException { + final Optional maybeElementalHome = context.getBroker().getConfiguration().getElementalHome(); + if (!maybeElementalHome.isPresent()) { + throw new XPathException(this, "ELEMENTAL_HOME has not been set"); + } + + final Path elementalHome = maybeElementalHome.get(); + return new StringValue(this, elementalHome.normalize().toAbsolutePath().toString()); + } +} diff --git a/exist-core/src/main/java/org/exist/xquery/functions/system/GetExistHome.java b/exist-core/src/main/java/org/exist/xquery/functions/system/GetExistHome.java deleted file mode 100644 index 1e26110a87..0000000000 --- a/exist-core/src/main/java/org/exist/xquery/functions/system/GetExistHome.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.system; - -import java.nio.file.Path; -import java.util.Optional; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.exist.dom.QName; -import org.exist.xquery.*; -import org.exist.xquery.value.FunctionReturnSequenceType; -import org.exist.xquery.value.Sequence; -import org.exist.xquery.value.StringValue; -import org.exist.xquery.value.Type; - -/** - * Return the eXist home. - * - * @author Dannes Wessels - */ -public class GetExistHome extends BasicFunction { - - protected final static Logger logger = LogManager.getLogger(GetExistHome.class); - - public final static FunctionSignature signature = - new FunctionSignature( - new QName("get-exist-home", SystemModule.NAMESPACE_URI, SystemModule.PREFIX), - "Returns the eXist home location.", - FunctionSignature.NO_ARGS, - new FunctionReturnSequenceType(Type.STRING, Cardinality.EXACTLY_ONE, "the path to the eXist home")); - - public GetExistHome(XQueryContext context) { - super(context, signature); - } - - @Override - public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException { - final Optional existHome = context.getBroker().getConfiguration().getExistHome(); - final Expression expression = this; - return existHome.map(h -> new StringValue(expression, h.toAbsolutePath().toString())).orElse(Sequence.EMPTY_SEQUENCE); - } -} 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 a9682a0816..20d7e57ed1 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 @@ -85,7 +85,8 @@ public class SystemModule extends AbstractInternalModule { new FunctionDef(GetVersion.signature, GetVersion.class), new FunctionDef(GetBuild.signature, GetBuild.class), new FunctionDef(GetRevision.signature, GetRevision.class), - new FunctionDef(GetExistHome.signature, GetExistHome.class), + new FunctionDef(GetElementalHome.FS_GET_ELEMENTAL_HOME, GetElementalHome.class), + new FunctionDef(GetElementalHome.FS_GET_EXIST_HOME, GetElementalHome.class), new FunctionDef(Shutdown.signatures[0], Shutdown.class), new FunctionDef(Shutdown.signatures[1], Shutdown.class), new FunctionDef(GetModuleLoadPath.FS_GET_MODULE_LOAD_PATH, GetModuleLoadPath.class), diff --git a/exist-core/src/test/java/org/exist/backup/SystemExportImportTest.java b/exist-core/src/test/java/org/exist/backup/SystemExportImportTest.java index b887296a8f..9929e3c53f 100644 --- a/exist-core/src/test/java/org/exist/backup/SystemExportImportTest.java +++ b/exist-core/src/test/java/org/exist/backup/SystemExportImportTest.java @@ -51,8 +51,11 @@ import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; +import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Optional; import java.util.Properties; @@ -79,6 +82,7 @@ import static org.exist.test.TestConstants.TEST_COLLECTION_URI; import org.exist.test.ExistEmbeddedServer; +import org.exist.util.FileUtils; import org.exist.util.LockException; import org.exist.util.StringInputSource; import org.exist.util.io.InputStreamUtil; @@ -200,6 +204,70 @@ public void exportImport() throws EXistException, IOException, PermissionDeniedE } } + @Test + public void exportBackupFullMax() throws EXistException, IOException, PermissionDeniedException, SAXException, ParserConfigurationException, AuthenticationException, URISyntaxException, XMLDBException, InterruptedException { + final BrokerPool pool = existEmbeddedServer.getBrokerPool(); + try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject())); + final Txn transaction = pool.getTransactionManager().beginTransaction()) { + + final Collection test = broker.getCollection(TEST_COLLECTION_URI); + assertNotNull(test); + + final SystemExport sysexport = new SystemExport(broker, transaction, null, null, direct); + final String backupDir = temporaryFolder.newFolder().getAbsolutePath(); + + final int maxFullBackups = 3; + final int maxIncBackups = 2; + + // create maxFullBackups and maxIncBackups + final List fullBackups = new ArrayList<>(); + final List incBackups = new ArrayList<>(); + for (int i = 0 ; i < maxFullBackups; i++) { + final Path fullBackup = sysexport.export(backupDir, true, maxIncBackups, maxFullBackups, zip, null); + Files.exists(fullBackup); + assertTrue(FileUtils.fileName(fullBackup).startsWith("full")); + fullBackups.add(fullBackup); + + Thread.sleep(1000); // NOTE(AR) needed as filenames for backups only have a 1 second precision + + for (int j = 0 ; j < maxIncBackups; j++) { + final Path incBackup = sysexport.export(backupDir, true, maxIncBackups, maxFullBackups, zip, null); + Files.exists(incBackup); + assertTrue(FileUtils.fileName(incBackup).startsWith("inc")); + incBackups.add(incBackup); + + Thread.sleep(1000); // NOTE(AR) needed as filenames for backups only have a 1 second precision + } + } + + // now try to exceed maxFullBackups by creating another full backup + final Path fullBackup = sysexport.export(backupDir, true, maxIncBackups, maxFullBackups, zip, null); + Files.exists(fullBackup); + assertTrue(FileUtils.fileName(fullBackup).startsWith("full")); + fullBackups.add(fullBackup); + + // as we have exceeded the maxFullBackups, the first full backup and its subsequent incremental backups should have been deleted + for (int i = 0; i < fullBackups.size(); i++) { + final boolean fullBackupExists = Files.exists(fullBackups.get(i)); + if (i == 0) { + assertFalse(fullBackupExists); + } else { + assertTrue(fullBackupExists); + } + } + for (int j = 0; j < fullBackups.size(); j++) { + final boolean incBackupExists = Files.exists(incBackups.get(j)); + if (j < maxIncBackups) { + assertFalse(incBackupExists); + } else { + assertTrue(incBackupExists); + } + } + + transaction.commit(); + } + } + private DocumentImpl getDoc(final DBBroker broker, final Collection col, final XmldbURI uri) throws PermissionDeniedException { final DocumentImpl doc = col.getDocument(broker, uri); assertNotNull(doc); diff --git a/exist-core/src/test/java/org/exist/storage/AbstractRecoverTest.java b/exist-core/src/test/java/org/exist/storage/AbstractRecoverTest.java index 25afc7a73a..2eb9f8b5f4 100644 --- a/exist-core/src/test/java/org/exist/storage/AbstractRecoverTest.java +++ b/exist-core/src/test/java/org/exist/storage/AbstractRecoverTest.java @@ -789,7 +789,7 @@ protected void flushJournal() { } protected Path resolveTestFile(final String fileName) throws IOException { - final Path path = TestUtils.getEXistHome().orElseGet(() -> Paths.get(".")).resolve(fileName); + final Path path = TestUtils.getElementalHome().orElseGet(() -> Paths.get(".")).resolve(fileName); if(!Files.exists(path)) { throw new IOException("No such test file: " + path.toAbsolutePath().toString()); } diff --git a/exist-core/src/test/java/org/exist/xmldb/IndexingTest.java b/exist-core/src/test/java/org/exist/xmldb/IndexingTest.java index 3bb94498a9..65bf996f39 100644 --- a/exist-core/src/test/java/org/exist/xmldb/IndexingTest.java +++ b/exist-core/src/test/java/org/exist/xmldb/IndexingTest.java @@ -103,7 +103,6 @@ public class IndexingTest { private static String username = "admin"; private static String password = ""; // <<< private static String name = "test.xml"; - private String EXIST_HOME = ""; // <<< private int effectiveSiblingCount; @SuppressWarnings("unused") private int effectiveDepth; diff --git a/exist-core/src/test/java/org/exist/xquery/XPathQueryTest.java b/exist-core/src/test/java/org/exist/xquery/XPathQueryTest.java index 13593f3d32..87b61ca6cd 100644 --- a/exist-core/src/test/java/org/exist/xquery/XPathQueryTest.java +++ b/exist-core/src/test/java/org/exist/xquery/XPathQueryTest.java @@ -277,7 +277,7 @@ public void setUp() throws Exception { } @After - public void teadDown() throws XMLDBException { + public void tearDown() throws XMLDBException { testCollection.close(); } diff --git a/exist-core/src/test/java/org/exist/xquery/value/Base64BinaryValueTypeTest.java b/exist-core/src/test/java/org/exist/xquery/value/Base64BinaryValueTypeTest.java index de9ac2fd2d..2b9a51bfa5 100644 --- a/exist-core/src/test/java/org/exist/xquery/value/Base64BinaryValueTypeTest.java +++ b/exist-core/src/test/java/org/exist/xquery/value/Base64BinaryValueTypeTest.java @@ -99,7 +99,7 @@ public void verify_validBase64_passes_3() throws XPathException { @Test public void verify_validBase64_passes_large_string() throws XPathException, IOException, URISyntaxException { - Optional home = ConfigurationHelper.getExistHome(); + Optional home = ConfigurationHelper.getElementalHome(); Path binaryFile = Paths.get(getClass().getResource("logo.png").toURI()); final String base64data; diff --git a/exist-core/src/test/resources-filtered/conf.xml b/exist-core/src/test/resources-filtered/conf.xml index e66d78f1d9..52a4a35426 100644 --- a/exist-core/src/test/resources-filtered/conf.xml +++ b/exist-core/src/test/resources-filtered/conf.xml @@ -46,871 +46,78 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - - + @@ -935,47 +142,17 @@ + - - - - + + diff --git a/exist-core/src/test/resources-filtered/org/exist/storage/statistics/conf.xml b/exist-core/src/test/resources-filtered/org/exist/storage/statistics/conf.xml index 7e97a8a79b..272bf9e785 100644 --- a/exist-core/src/test/resources-filtered/org/exist/storage/statistics/conf.xml +++ b/exist-core/src/test/resources-filtered/org/exist/storage/statistics/conf.xml @@ -46,501 +46,47 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - + - - - - - - - - - - + @@ -548,365 +94,38 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + enable-xsl="no" indent="yes" match-tagging-attributes="no" + match-tagging-elements="no"/> + - - - - - - + + @@ -926,24 +145,17 @@ + - + + + + + + + + diff --git a/exist-core/src/test/resources-filtered/org/exist/xquery/JavaBindingTest.conf.xml b/exist-core/src/test/resources-filtered/org/exist/xquery/JavaBindingTest.conf.xml index a49080e6fb..80c43396a0 100644 --- a/exist-core/src/test/resources-filtered/org/exist/xquery/JavaBindingTest.conf.xml +++ b/exist-core/src/test/resources-filtered/org/exist/xquery/JavaBindingTest.conf.xml @@ -21,868 +21,75 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - + files="${basedir}/target/test-data" pageSize="4096" nodesBuffer="1000" cacheShrinkThreshold="10000" + minDiskSpace="1024M" posix-chown-restricted="true" preserve-on-copy="false"> - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + suppress-whitespace="none"/> - - - - - - - - - - - - - - - + + - - - - - - - - - - - @@ -909,47 +116,17 @@ - - - - - - + + diff --git a/exist-core/src/test/resources-filtered/org/exist/xquery/functions/transform/transform-from-pkg-test.conf.xml b/exist-core/src/test/resources-filtered/org/exist/xquery/functions/transform/transform-from-pkg-test.conf.xml index 35ad1a02b8..40cabec72e 100644 --- a/exist-core/src/test/resources-filtered/org/exist/xquery/functions/transform/transform-from-pkg-test.conf.xml +++ b/exist-core/src/test/resources-filtered/org/exist/xquery/functions/transform/transform-from-pkg-test.conf.xml @@ -46,878 +46,83 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + enable-xsl="no" indent="yes" match-tagging-attributes="no" + match-tagging-elements="no"/> + - - - - - - + + @@ -937,24 +142,17 @@ + - + + + + + + + + diff --git a/exist-core/src/test/resources-filtered/org/exist/xquery/import-from-pkg-test.conf.xml b/exist-core/src/test/resources-filtered/org/exist/xquery/import-from-pkg-test.conf.xml index 070ceda775..57bbaa9e16 100644 --- a/exist-core/src/test/resources-filtered/org/exist/xquery/import-from-pkg-test.conf.xml +++ b/exist-core/src/test/resources-filtered/org/exist/xquery/import-from-pkg-test.conf.xml @@ -21,878 +21,83 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - - + + @@ -912,24 +117,17 @@ + - + + + + + + + + diff --git a/exist-core/src/test/resources/org/exist/xmldb/allowAnyUri.xml b/exist-core/src/test/resources/org/exist/xmldb/allowAnyUri.xml index 9feb2f4edd..a70c3aa562 100644 --- a/exist-core/src/test/resources/org/exist/xmldb/allowAnyUri.xml +++ b/exist-core/src/test/resources/org/exist/xmldb/allowAnyUri.xml @@ -1,9 +1,8 @@ diff --git a/exist-distribution/pom.xml b/exist-distribution/pom.xml index 0a52dd5cb6..00d1c9fa6b 100644 --- a/exist-distribution/pom.xml +++ b/exist-distribution/pom.xml @@ -959,10 +959,10 @@ file.encoding=UTF-8 log4j.configurationFile=@BASEDIR@/etc/log4j2.xml - exist.home=@BASEDIR@ - exist.configurationFile=@BASEDIR@/etc/conf.xml + elemental.home=@BASEDIR@ + elemental.configurationFile=@BASEDIR@/etc/conf.xml jetty.home=@BASEDIR@ - exist.jetty.config=@BASEDIR@/etc/jetty/standard.enabled-jetty-configs + elemental.jetty.config=@BASEDIR@/etc/jetty/standard.enabled-jetty-configs elemental-LGPL-21-ONLY-license.txt @@ -1252,10 +1252,10 @@ - - + + - + diff --git a/exist-distribution/src/main/config/conf.xml b/exist-distribution/src/main/config/conf.xml index 11689be791..7e8e1a3ab9 100644 --- a/exist-distribution/src/main/config/conf.xml +++ b/exist-distribution/src/main/config/conf.xml @@ -1,9 +1,8 @@ @@ -712,7 +743,7 @@ and is capable of parsing HTML and emitting an XML Sax Stream. Whichever library you use for this, it must be present on the classpath - perhaps the best way to do this is to place it into $EXIST_HOME/lib/user + See $ELEMENTAL_HOME/lib Examples include: - org.cyberneko.html.parsers.SAXParser @@ -891,7 +922,7 @@ Specify the location of one or more catalog files. Catalogs are used to resolve external entities in XML documents. - "${WEBAPP_HOME}" and "${EXIST_HOME}" can be used as magic string. + "${WEBAPP_HOME}" and "${ELEMENTAL_HOME}" can be used as magic string. --> diff --git a/exist-distribution/src/main/config/descriptor.xml b/exist-distribution/src/main/config/descriptor.xml index 5486f8668b..93869d279a 100644 --- a/exist-distribution/src/main/config/descriptor.xml +++ b/exist-distribution/src/main/config/descriptor.xml @@ -3,7 +3,7 @@ This is the Web-application Descriptor file. If the database is running in a servlet-context, the descriptor file will be read from the WEB-INF directory of the web application. Otherwise, the descriptor - is read from the directory specified by the exist.home system property. + is read from the directory specified by the elemental.home system property. --> @@ -27,10 +27,9 @@ BEWARE the security consequences of enabling this for your queries! REST XQuery paths (EXistServlet/RESTServer) start from the db location e.g. /db/mycollection/myquery.xql - FileSystem XQuery paths (XQueryServlet) start from the root filesystem location e.g. $EXIST_HOME/webapp/myapp/myquery.xql - and end with a .xql suffix. However ${WEBAPP_HOME} may be used for convenience to represent eXist's webapp folder without + FileSystem XQuery paths (XQueryServlet) start from the root filesystem location e.g. ELEMENTAL_HOME/etc/webapp/myapp/myquery.xql + and end with a .xql suffix. However ${WEBAPP_HOME} may be used for convenience to represent the webapp folder without the need to know the specific path. - Cocoon XQuery Paths (XQueryGenerator) are not yet supported! --> diff --git a/exist-distribution/src/main/config/webdav.properties b/exist-distribution/src/main/config/webdav.properties index 2801781087..f68fa6fca8 100644 --- a/exist-distribution/src/main/config/webdav.properties +++ b/exist-distribution/src/main/config/webdav.properties @@ -21,7 +21,7 @@ # ## XML Serialization options for the WevDAV -## The file is read from EXIST_HOME/etc +## The file is read from ELEMENTAL_HOME/etc ## Be careful changing the default values ! #indent=yes #expand-xincludes=no diff --git a/exist-docker/src/main/resources-filtered/Dockerfile b/exist-docker/src/main/resources-filtered/Dockerfile index e6164d109e..9da68af6de 100644 --- a/exist-docker/src/main/resources-filtered/Dockerfile +++ b/exist-docker/src/main/resources-filtered/Dockerfile @@ -139,12 +139,11 @@ LABEL org.label-schema.build-date=${project.build.outputTimestamp} \ EXPOSE 8080 8443 ENV ELEMENTAL_HOME="/elemental" -ENV EXIST_HOME="/elemental" ENV CLASSPATH="/elemental/lib/${elemental.uber.jar.filename}" ENV JAVA_HOME="/usr/lib/jvm/java-1.8-openjdk" -ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF-8 -Djava.awt.headless=true -Dorg.exist.db-connection.cacheSize=${ELEMENTAL_SERVER_CACHE_MEM}M -Dorg.exist.db-connection.pool.max=${ELEMENTAL_SERVER_MAX_BROKER} -Dlog4j.configurationFile=/elemental/etc/log4j2.xml -Dexist.home=/elemental -Dexist.configurationFile=/elemental/etc/conf.xml -Djetty.home=/elemental -Dexist.jetty.config=/elemental/etc/jetty/standard.enabled-jetty-configs -XX:+Use${JVM_GC}GC -XX:+UseStringDeduplication -XX:+UseContainerSupport -XX:MaxRAMPercentage=${JVM_MAX_RAM_PERCENTAGE} -XX:+ExitOnOutOfMemoryError ${ADDITIONAL_JAVA_TOOL_OPTIONS}" +ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF-8 -Djava.awt.headless=true -Dorg.exist.db-connection.cacheSize=${ELEMENTAL_SERVER_CACHE_MEM}M -Dorg.exist.db-connection.pool.max=${ELEMENTAL_SERVER_MAX_BROKER} -Dlog4j.configurationFile=/elemental/etc/log4j2.xml -Delemental.home=/elemental -Delemental.configurationFile=/elemental/etc/conf.xml -Djetty.home=/elemental -Delemental.jetty.config=/elemental/etc/jetty/standard.enabled-jetty-configs -XX:+Use${JVM_GC}GC -XX:+UseStringDeduplication -XX:+UseContainerSupport -XX:MaxRAMPercentage=${JVM_MAX_RAM_PERCENTAGE} -XX:+ExitOnOutOfMemoryError ${ADDITIONAL_JAVA_TOOL_OPTIONS}" ENV PATH="/usr/lib/jvm/java-1.8-openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" diff --git a/exist-docker/src/main/resources-filtered/Dockerfile-DEBUG b/exist-docker/src/main/resources-filtered/Dockerfile-DEBUG index 5bf7b01b2a..f1edb4f0a6 100644 --- a/exist-docker/src/main/resources-filtered/Dockerfile-DEBUG +++ b/exist-docker/src/main/resources-filtered/Dockerfile-DEBUG @@ -116,12 +116,11 @@ LABEL org.label-schema.build-date=${project.build.outputTimestamp} \ EXPOSE 8080 8443 5005 ENV ELEMENTAL_HOME="/elemental" -ENV EXIST_HOME="/elemental" ENV CLASSPATH="/elemental/lib/${elemental.uber.jar.filename}" ENV JAVA_HOME="/usr/lib/jvm/java-1.8-openjdk" -ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF-8 -Djava.awt.headless=true -Dorg.exist.db-connection.cacheSize=${ELEMENTAL_SERVER_CACHE_MEM}M -Dorg.exist.db-connection.pool.max=${ELEMENTAL_SERVER_MAX_BROKER} -Dlog4j.configurationFile=/elemental/etc/log4j2.xml -Dexist.home=/elemental -Dexist.configurationFile=/elemental/etc/conf.xml -Djetty.home=/elemental -Dexist.jetty.config=/elemental/etc/jetty/standard.enabled-jetty-configs -XX:+Use${JVM_GC}GC -XX:+UseStringDeduplication -XX:+UseContainerSupport -XX:MaxRAMPercentage=${JVM_MAX_RAM_PERCENTAGE} -XX:+ExitOnOutOfMemoryError -agentlib:jdwp=transport=dt_socket,server=y,suspend=${JVM_JDWP_SUSPEND},address=${JVM_JDWP_ADDRESS} ${ADDITIONAL_JAVA_TOOL_OPTIONS}" +ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF-8 -Djava.awt.headless=true -Dorg.exist.db-connection.cacheSize=${ELEMENTAL_SERVER_CACHE_MEM}M -Dorg.exist.db-connection.pool.max=${ELEMENTAL_SERVER_MAX_BROKER} -Dlog4j.configurationFile=/elemental/etc/log4j2.xml -Delemental.home=/elemental -Delemental.configurationFile=/elemental/etc/conf.xml -Djetty.home=/elemental -Delemental.jetty.config=/elemental/etc/jetty/standard.enabled-jetty-configs -XX:+Use${JVM_GC}GC -XX:+UseStringDeduplication -XX:+UseContainerSupport -XX:MaxRAMPercentage=${JVM_MAX_RAM_PERCENTAGE} -XX:+ExitOnOutOfMemoryError -agentlib:jdwp=transport=dt_socket,server=y,suspend=${JVM_JDWP_SUSPEND},address=${JVM_JDWP_ADDRESS} ${ADDITIONAL_JAVA_TOOL_OPTIONS}" ENV PATH="/usr/lib/jvm/java-1.8-openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" diff --git a/exist-jetty-config/src/main/resources/org/exist/jetty/etc/standalone-webapps/elemental-webapp-context.xml b/exist-jetty-config/src/main/resources/org/exist/jetty/etc/standalone-webapps/elemental-webapp-context.xml index 7e01a99edd..e5eb79282f 100644 --- a/exist-jetty-config/src/main/resources/org/exist/jetty/etc/standalone-webapps/elemental-webapp-context.xml +++ b/exist-jetty-config/src/main/resources/org/exist/jetty/etc/standalone-webapps/elemental-webapp-context.xml @@ -4,7 +4,7 @@ / - /../../../standalone-webapp/ + /../../../standalone-webapp/ /etc/webdefault.xml diff --git a/exist-parent/pom.xml b/exist-parent/pom.xml index 90c931a55f..07d974809f 100644 --- a/exist-parent/pom.xml +++ b/exist-parent/pom.xml @@ -103,7 +103,6 @@ 2.26.1 4.10.4 1.8.1.3 - 9.9.1-8 2.12.2.2 6.0.19 2.11.0 @@ -143,12 +142,6 @@ 4.0.5 - - net.sf.saxon - Saxon-HE - ${saxon.version} - - com.evolvedbinary.multilock multilock @@ -469,21 +462,6 @@ antlr-maven-plugin 2.2 - - org.codehaus.mojo - xml-maven-plugin - 1.2.0 - - net.sf.saxon.TransformerFactoryImpl - - - - net.sf.saxon - Saxon-HE - ${saxon.version} - - - org.apache.maven.plugins maven-assembly-plugin @@ -675,4 +653,4 @@ - \ No newline at end of file + diff --git a/exist-start/pom.xml b/exist-start/pom.xml index 448a16e9d2..1c499d8cf2 100644 --- a/exist-start/pom.xml +++ b/exist-start/pom.xml @@ -113,6 +113,7 @@ pom.xml src/main/java/org/exist/start/CompatibleJavaVersionCheck.java src/test/java/org/exist/start/CompatibleJavaVersionCheckTest.java + src/main/java/org/exist/start/LatestFileResolver.java @@ -127,6 +128,7 @@ src/main/java/org/exist/start/Classpath.java src/main/java/org/exist/start/CompatibleJavaVersionCheck.java src/test/java/org/exist/start/CompatibleJavaVersionCheckTest.java + src/main/java/org/exist/start/LatestFileResolver.java src/main/java/org/exist/start/Main.java src/main/java/org/exist/start/Version.java diff --git a/exist-start/src/main/java/org/exist/start/LatestFileResolver.java b/exist-start/src/main/java/org/exist/start/LatestFileResolver.java index 5707c4c651..28e0381f5f 100644 --- a/exist-start/src/main/java/org/exist/start/LatestFileResolver.java +++ b/exist-start/src/main/java/org/exist/start/LatestFileResolver.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,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import static org.exist.start.Main.LEGACY_PROP_EXIST_START_DEBUG; +import static org.exist.start.Main.PROP_ELEMENTAL_START_DEBUG; + /** * This class uses regex pattern matching to find the latest version of a * particular jar file. @@ -51,7 +78,7 @@ public class LatestFileResolver { // Set debug mode for each file resolver instance based on whether or // not the system was started with debugging turned on. - private static boolean _debug = Boolean.getBoolean("exist.start.debug"); + private static boolean _DEBUG = Boolean.parseBoolean(System.getProperty(PROP_ELEMENTAL_START_DEBUG, System.getProperty(LEGACY_PROP_EXIST_START_DEBUG, "false"))); /** * If the passed file name contains a %latest% token, @@ -98,7 +125,7 @@ public String getResolvedFileName(final String filename) { if (!jars.isEmpty()) { final String actualFileName = jars.get(0).toAbsolutePath().toString(); - if (_debug) { + if (_DEBUG) { System.err.println( "Found match: " + actualFileName + " for jar file pattern: " + filename @@ -106,7 +133,7 @@ public String getResolvedFileName(final String filename) { } return actualFileName; } else { - if (_debug) { + if (_DEBUG) { System.err.println( "WARN: No latest version found for JAR file: '" + filename + "'" diff --git a/exist-start/src/main/java/org/exist/start/Main.java b/exist-start/src/main/java/org/exist/start/Main.java index e108a7b781..c4f214ba51 100644 --- a/exist-start/src/main/java/org/exist/start/Main.java +++ b/exist-start/src/main/java/org/exist/start/Main.java @@ -71,6 +71,7 @@ import java.nio.file.Paths; import java.util.*; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -96,23 +97,38 @@ public class Main { public static final String CONFIG_DIR_NAME = "etc"; - private static final String PROP_EXIST_START_DEBUG = "exist.start.debug"; - public static final String PROP_EXIST_JETTY_CONFIG = "exist.jetty.config"; - public static final String PROP_EXIST_HOME = "exist.home"; + static final String PROP_ELEMENTAL_START_DEBUG = "elemental.start.debug"; + @Deprecated + static final String LEGACY_PROP_EXIST_START_DEBUG = "exist.start.debug"; + + public static final String PROP_ELEMENTAL_JETTY_CONFIG = "elemental.jetty.config"; + @Deprecated + public static final String LEGACY_PROP_EXIST_JETTY_CONFIG = "exist.jetty.config"; + + public static final String PROP_ELEMENTAL_HOME = "elemental.home"; + @Deprecated + public static final String LEGACY_PROP_EXIST_HOME = "exist.home"; + public static final String PROP_JETTY_HOME = "jetty.home"; private static final String PROP_LOG4J_CONFIGURATION_FILE = "log4j.configurationFile"; private static final String PROP_JUL_MANAGER = "java.util.logging.manager"; private static final String PROP_JAVA_TEMP_DIR = "java.io.tmpdir"; - public static final String ENV_EXIST_JETTY_CONFIG = "EXIST_JETTY_CONFIG"; - public static final String ENV_EXIST_HOME = "EXIST_HOME"; + public static final String ENV_ELEMENTAL_JETTY_CONFIG = "ELEMENTAL_JETTY_CONFIG"; + @Deprecated + public static final String LEGACY_ENV_EXIST_JETTY_CONFIG = "EXIST_JETTY_CONFIG"; + + public static final String ENV_ELEMENTAL_HOME = "ELEMENTAL_HOME"; + @Deprecated + public static final String LEGACY_ENV_EXIST_HOME = "EXIST_HOME"; + public static final String ENV_JETTY_HOME = "JETTY_HOME"; private static Main exist; private String _mode = "jetty"; - private boolean _debug = Boolean.getBoolean(PROP_EXIST_START_DEBUG); + private final boolean _debug = Boolean.parseBoolean(System.getProperty(PROP_ELEMENTAL_START_DEBUG, System.getProperty(LEGACY_PROP_EXIST_START_DEBUG, "false"))); public static void main(final String[] args) { try { @@ -237,15 +253,15 @@ public void runEx(String[] args) throws StartException { System.err.println("mode=" + _mode); } - // try and figure out exist home dir - final Optional existHomeDir = getFromSysPropOrEnv(PROP_EXIST_HOME, ENV_EXIST_HOME).map(Paths::get); + // try and figure out Elemental home dir + final Optional elementalHomeDir = or(getFromSysPropOrEnv(PROP_ELEMENTAL_HOME, ENV_ELEMENTAL_HOME), () -> getFromSysPropOrEnv(LEGACY_PROP_EXIST_HOME, LEGACY_ENV_EXIST_HOME)).map(Paths::get); // try to find Jetty if ("jetty".equals(_mode) || "standalone".equals(_mode)) { final Optional jettyHomeDir = getFromSysPropOrEnv(PROP_JETTY_HOME, ENV_JETTY_HOME).map(Paths::get); - Optional existJettyConfigFile = getFromSysPropOrEnv(PROP_EXIST_JETTY_CONFIG, ENV_EXIST_JETTY_CONFIG).map(Paths::get); - if (!existJettyConfigFile.isPresent()) { + Optional elementalJettyConfigFile = or(getFromSysPropOrEnv(PROP_ELEMENTAL_JETTY_CONFIG, ENV_ELEMENTAL_JETTY_CONFIG), () -> getFromSysPropOrEnv(LEGACY_PROP_EXIST_JETTY_CONFIG, LEGACY_ENV_EXIST_JETTY_CONFIG)).map(Paths::get); + if (!elementalJettyConfigFile.isPresent()) { final String config; if ("jetty".equals(_mode)) { config = STANDARD_ENABLED_JETTY_CONFIGS; @@ -254,21 +270,21 @@ public void runEx(String[] args) throws StartException { } if (jettyHomeDir.isPresent() && Files.exists(jettyHomeDir.get().resolve(CONFIG_DIR_NAME))) { - existJettyConfigFile = jettyHomeDir.map(f -> f.resolve(CONFIG_DIR_NAME).resolve(config)); + elementalJettyConfigFile = jettyHomeDir.map(f -> f.resolve(CONFIG_DIR_NAME).resolve(config)); } - if (existHomeDir.isPresent() && Files.exists(existHomeDir.get().resolve(CONFIG_DIR_NAME))) { - existJettyConfigFile = existHomeDir.map(f -> f.resolve(CONFIG_DIR_NAME).resolve(config)); + if (elementalHomeDir.isPresent() && Files.exists(elementalHomeDir.get().resolve(CONFIG_DIR_NAME))) { + elementalJettyConfigFile = elementalHomeDir.map(f -> f.resolve(CONFIG_DIR_NAME).resolve(config)); } - if (!existJettyConfigFile.isPresent()) { - System.err.println("ERROR: jetty config file could not be found! Make sure to set exist.jetty.config or EXIST_JETTY_CONFIG."); + if (!elementalJettyConfigFile.isPresent()) { + System.err.println("ERROR: jetty config file could not be found! Make sure to set elemental.jetty.config or ELEMENTAL_JETTY_CONFIG."); System.err.flush(); throw new StartException(ERROR_CODE_NO_JETTY_CONFIG); } } final String[] jettyStartArgs = new String[1 + args.length]; - jettyStartArgs[0] = existJettyConfigFile.get().toAbsolutePath().toString(); + jettyStartArgs[0] = elementalJettyConfigFile.get().toAbsolutePath().toString(); System.arraycopy(args, 0, jettyStartArgs, 1, args.length); args = jettyStartArgs; } @@ -276,8 +292,8 @@ public void runEx(String[] args) throws StartException { // find log4j2.xml Optional log4jConfigurationFile = Optional.ofNullable(System.getProperty(PROP_LOG4J_CONFIGURATION_FILE)).map(Paths::get); if (!log4jConfigurationFile.isPresent()) { - if (existHomeDir.isPresent() && Files.exists(existHomeDir.get().resolve(CONFIG_DIR_NAME))) { - log4jConfigurationFile = existHomeDir.map(f -> f.resolve(CONFIG_DIR_NAME).resolve("log4j2.xml")); + if (elementalHomeDir.isPresent() && Files.exists(elementalHomeDir.get().resolve(CONFIG_DIR_NAME))) { + log4jConfigurationFile = elementalHomeDir.map(f -> f.resolve(CONFIG_DIR_NAME).resolve("log4j2.xml")); } } @@ -388,7 +404,7 @@ public void shutdownEx() throws StopException { /** * Copied from {@link org.exist.util.FileUtils#list(Path, Predicate)} * as org.exist.start is compiled into a separate Jar and doesn't have - * the rest of eXist available on the classpath + * the rest of Elemental available on the classpath */ static List list(final Path directory, final Predicate filter) throws IOException { try(final Stream entries = Files.list(directory).filter(filter)) { @@ -399,9 +415,22 @@ static List list(final Path directory, final Predicate filter) throw /** * Copied from {@link org.exist.util.FileUtils#fileName(Path)} * as org.exist.start is compiled into a separate Jar and doesn't have - * the rest of eXist available on the classpath + * the rest of Elemental available on the classpath */ static String fileName(final Path path) { return path.getFileName().toString(); } + + /** + * Copied from {@link com.evolvedbinary.j8fu.OptionalUtil#or(Optional, Supplier)} + * as org.exist.start is compiled into a separate Jar and doesn't have + * j8fu available on the classpath + */ + static Optional or(final Optional left, final Supplier> right) { + if(left.isPresent()) { + return left; + } else { + return right.get(); + } + } } diff --git a/extensions/contentextraction/pom.xml b/extensions/contentextraction/pom.xml index fb728d667f..1e70fe3a70 100644 --- a/extensions/contentextraction/pom.xml +++ b/extensions/contentextraction/pom.xml @@ -212,6 +212,7 @@ true + org.apache.maven.plugins maven-dependency-plugin @@ -231,6 +232,31 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + diff --git a/extensions/contentextraction/src/test/resources-filtered/conf.xml b/extensions/contentextraction/src/test/resources-filtered/conf.xml index 6d13e0b374..bc0f72d185 100644 --- a/extensions/contentextraction/src/test/resources-filtered/conf.xml +++ b/extensions/contentextraction/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/debuggee/pom.xml b/extensions/debuggee/pom.xml index 4c3484d092..3a4bb5580a 100644 --- a/extensions/debuggee/pom.xml +++ b/extensions/debuggee/pom.xml @@ -179,6 +179,31 @@ + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + org.apache.maven.plugins maven-surefire-plugin @@ -187,7 +212,8 @@ CLDR,SPI ${project.build.testOutputDirectory}/log4j2.xml - ${project.build.testOutputDirectory}/standalone-webapp + ${project.build.testOutputDirectory}/conf.xml + ${project.build.testOutputDirectory}/standalone-webapp diff --git a/extensions/debuggee/src/test/resources-filtered/conf.xml b/extensions/debuggee/src/test/resources-filtered/conf.xml index e9949d1b9b..5edf18da5a 100644 --- a/extensions/debuggee/src/test/resources-filtered/conf.xml +++ b/extensions/debuggee/src/test/resources-filtered/conf.xml @@ -46,746 +46,86 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - - - - - - - - + raise-error-on-failed-retrieval="no"/> + + + + + + + + + diff --git a/extensions/expath/pom.xml b/extensions/expath/pom.xml index 59468b348a..28ece40034 100644 --- a/extensions/expath/pom.xml +++ b/extensions/expath/pom.xml @@ -197,6 +197,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/extensions/expath/src/test/resources-filtered/conf.xml b/extensions/expath/src/test/resources-filtered/conf.xml index a8ad4c4504..0717d7d9e6 100644 --- a/extensions/expath/src/test/resources-filtered/conf.xml +++ b/extensions/expath/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/exquery/restxq/pom.xml b/extensions/exquery/restxq/pom.xml index 544c84aa29..6f9d53521f 100644 --- a/extensions/exquery/restxq/pom.xml +++ b/extensions/exquery/restxq/pom.xml @@ -289,6 +289,7 @@ + org.apache.maven.plugins maven-dependency-plugin @@ -308,7 +309,33 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + - \ No newline at end of file + diff --git a/extensions/exquery/restxq/src/test/resources-filtered/conf.xml b/extensions/exquery/restxq/src/test/resources-filtered/conf.xml index aa098d21d7..f01de43e99 100644 --- a/extensions/exquery/restxq/src/test/resources-filtered/conf.xml +++ b/extensions/exquery/restxq/src/test/resources-filtered/conf.xml @@ -27,720 +27,73 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - - + @@ -767,24 +120,17 @@ + - + + + + + + + + diff --git a/extensions/images/README.md b/extensions/images/README.md index a788ffaea2..3baa9db582 100644 --- a/extensions/images/README.md +++ b/extensions/images/README.md @@ -11,20 +11,7 @@ Rendered images can be cached on a file system path. Installation ------------ -Get the Java Advanced Imaging jars for your platform from - -https://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-client-419417.html - -Please choose the CLASSPATH installation bundle. Open the downloaded archive and -copy the contents of the lib/ folder to $EXIST_HOME/lib/user. - -- If you are on MacOSX, you can just extract the jai_codec.jar and jai_core.jar files from the Linux CLASSPATH installation bundle and place these in $EXIST_HOME/lib/user - -You should now be able to compile the servlet from EXIST_HOME with - -./build.sh -f extensions/images/build.xml - -Next, you need to register the servlet in EXIST_HOME/webapp/WEB-INF/web.xml as follows: +Next, you need to register the servlet in ELEMENTAL_HOME/etc/webapp/WEB-INF/web.xml as follows: ScaleImageJAI @@ -43,7 +30,7 @@ Next, you need to register the servlet in EXIST_HOME/webapp/WEB-INF/web.xml as f where "output-dir" should point to an existing directory on your server. To use the servlet from Elemental, make sure your -EXIST_HOME/webapp/WEB-INF/controller-config.xml has a mapping: +ELEMENTAL_HOME/etc/webapp/WEB-INF/controller-config.xml has a mapping: diff --git a/extensions/indexes/lucene/pom.xml b/extensions/indexes/lucene/pom.xml index e0fce17537..3bcb369afc 100644 --- a/extensions/indexes/lucene/pom.xml +++ b/extensions/indexes/lucene/pom.xml @@ -349,6 +349,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/extensions/indexes/lucene/src/test/resources-filtered/conf.xml b/extensions/indexes/lucene/src/test/resources-filtered/conf.xml index 3424baa6e1..08a146f9c0 100644 --- a/extensions/indexes/lucene/src/test/resources-filtered/conf.xml +++ b/extensions/indexes/lucene/src/test/resources-filtered/conf.xml @@ -46,501 +46,47 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - + doc-ids="default" minDiskSpace="1024M"> - - - - - - + - - - - - - - - + - - - - - - - - - - + @@ -551,359 +97,31 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/indexes/ngram/pom.xml b/extensions/indexes/ngram/pom.xml index dcb4de706c..0172df4b8c 100644 --- a/extensions/indexes/ngram/pom.xml +++ b/extensions/indexes/ngram/pom.xml @@ -207,6 +207,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/extensions/indexes/ngram/src/test/resources-filtered/conf.xml b/extensions/indexes/ngram/src/test/resources-filtered/conf.xml index 398f7280d1..cba7b31180 100644 --- a/extensions/indexes/ngram/src/test/resources-filtered/conf.xml +++ b/extensions/indexes/ngram/src/test/resources-filtered/conf.xml @@ -46,501 +46,47 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - + doc-ids="default" minDiskSpace="1024M"> - - - - - - + - - - - - - - - + - - - - - - - - - - + @@ -551,364 +97,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + match-tagging-elements="no"/> + - - - - - + @@ -928,24 +146,17 @@ + - + + + + + + + + diff --git a/extensions/indexes/range/pom.xml b/extensions/indexes/range/pom.xml index cbd04c9d88..9865029f1e 100644 --- a/extensions/indexes/range/pom.xml +++ b/extensions/indexes/range/pom.xml @@ -226,6 +226,7 @@ + org.apache.maven.plugins maven-dependency-plugin @@ -244,8 +245,34 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + - \ No newline at end of file + diff --git a/extensions/indexes/range/src/test/resources-filtered/conf.xml b/extensions/indexes/range/src/test/resources-filtered/conf.xml index 5fa6c6d215..15ffc3fcc4 100644 --- a/extensions/indexes/range/src/test/resources-filtered/conf.xml +++ b/extensions/indexes/range/src/test/resources-filtered/conf.xml @@ -46,501 +46,47 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - + doc-ids="default" minDiskSpace="1024M"> - - - - - - + - - - - - - - - + - - - - - - - - - - + @@ -554,364 +100,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + match-tagging-elements="no"/> + - - - - - + @@ -932,24 +150,17 @@ + - + + + + + + + + diff --git a/extensions/indexes/sort/pom.xml b/extensions/indexes/sort/pom.xml index f8065e98ee..1ef95447b0 100644 --- a/extensions/indexes/sort/pom.xml +++ b/extensions/indexes/sort/pom.xml @@ -165,6 +165,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/extensions/indexes/sort/src/test/resources-filtered/conf.xml b/extensions/indexes/sort/src/test/resources-filtered/conf.xml index 6da857c67b..875b865eb2 100644 --- a/extensions/indexes/sort/src/test/resources-filtered/conf.xml +++ b/extensions/indexes/sort/src/test/resources-filtered/conf.xml @@ -46,501 +46,47 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - + doc-ids="default" minDiskSpace="1024M"> - - - - - - + - - - - - - - - + - - - - - - - - - - + @@ -551,364 +97,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + match-tagging-elements="no"/> + - - - - - + @@ -928,24 +146,17 @@ + - + + + + + + + + diff --git a/extensions/indexes/spatial/hsql.bat b/extensions/indexes/spatial/hsql.bat deleted file mode 100644 index e04ab25082..0000000000 --- a/extensions/indexes/spatial/hsql.bat +++ /dev/null @@ -1,24 +0,0 @@ -@REM -@REM eXist-db Open Source Native XML Database -@REM Copyright (C) 2001 The eXist-db Authors -@REM -@REM info@exist-db.org -@REM http://www.exist-db.org -@REM -@REM This library is free software; you can redistribute it and/or -@REM modify it under the terms of the GNU Lesser General Public -@REM License as published by the Free Software Foundation; either -@REM version 2.1 of the License, or (at your option) any later version. -@REM -@REM This library is distributed in the hope that it will be useful, -@REM but WITHOUT ANY WARRANTY; without even the implied warranty of -@REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -@REM Lesser General Public License for more details. -@REM -@REM You should have received a copy of the GNU Lesser General Public -@REM License along with this library; if not, write to the Free Software -@REM Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -@REM - -set EXIST_HOME=..\..\.. -java -Xmx200m -cp .\lib\hsqldb.jar org.hsqldb.util.DatabaseManagerSwing --url jdbc:hsqldb:%EXIST_HOME%\webapp\WEB-INF\data\spatial_index diff --git a/extensions/indexes/spatial/hsql.sh b/extensions/indexes/spatial/hsql.sh deleted file mode 100755 index d3cb53d700..0000000000 --- a/extensions/indexes/spatial/hsql.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash -# -# 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 -# - - -# Run the HSQL Database Manager - -if [ -z "${EXIST_HOME}" ]; then - EXIST_HOME="../../.."; -fi -# set java options -if [ -z "${CLIENT_JAVA_OPTIONS}" ]; then - CLIENT_JAVA_OPTIONS="-Xms64m -Xmx256m -Dfile.encoding=UTF-8"; -fi - -HSQL_LIB="${EXIST_HOME}/extensions/indexes/spatial/lib" - -if [ "x$1" = "x" ]; then - HSQL_DATA="${EXIST_HOME}/webapp/WEB-INF/data/spatial_index" -else - HSQL_DATA="${EXIST_HOME}/$1" -fi - -JAVA_OPTIONS="${CLIENT_JAVA_OPTIONS} -cp ${HSQL_LIB}/hsqldb.jar" - - -${JAVA_HOME}/bin/java ${JAVA_OPTIONS} org.hsqldb.util.DatabaseManagerSwing --url jdbc:hsqldb:${HSQL_DATA} diff --git a/extensions/indexes/spatial/ivysettings.xml b/extensions/indexes/spatial/ivysettings.xml deleted file mode 100644 index 3f7d31bcd9..0000000000 --- a/extensions/indexes/spatial/ivysettings.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/extensions/indexes/spatial/pom.xml b/extensions/indexes/spatial/pom.xml index 4f54f69f7a..c1cd084b4d 100644 --- a/extensions/indexes/spatial/pom.xml +++ b/extensions/indexes/spatial/pom.xml @@ -304,8 +304,33 @@ - org.apache.maven.plugins - maven-surefire-plugin + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin - - - - + doc-ids="default" minDiskSpace="1024M"> - - - - - - + - - - - - - - - - - + - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + match-tagging-elements="no"/> + - - - - - + + + + + + + - + + + + + + + + diff --git a/extensions/modules/cache/pom.xml b/extensions/modules/cache/pom.xml index c4f2545081..57cd3cfe5b 100644 --- a/extensions/modules/cache/pom.xml +++ b/extensions/modules/cache/pom.xml @@ -192,6 +192,33 @@ + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + lazy-cache-conf.xml + non-lazy-cache-conf.xml + + + + + + + + diff --git a/extensions/modules/cache/src/test/resources-filtered/conf.xml b/extensions/modules/cache/src/test/resources-filtered/conf.xml index 5fa9b470a3..5499a3fb21 100644 --- a/extensions/modules/cache/src/test/resources-filtered/conf.xml +++ b/extensions/modules/cache/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/modules/cache/src/test/resources-filtered/lazy-cache-conf.xml b/extensions/modules/cache/src/test/resources-filtered/lazy-cache-conf.xml index 5fa9b470a3..5499a3fb21 100644 --- a/extensions/modules/cache/src/test/resources-filtered/lazy-cache-conf.xml +++ b/extensions/modules/cache/src/test/resources-filtered/lazy-cache-conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/modules/cache/src/test/resources-filtered/non-lazy-cache-conf.xml b/extensions/modules/cache/src/test/resources-filtered/non-lazy-cache-conf.xml index 5f35cba3c4..dfe8071538 100644 --- a/extensions/modules/cache/src/test/resources-filtered/non-lazy-cache-conf.xml +++ b/extensions/modules/cache/src/test/resources-filtered/non-lazy-cache-conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/modules/compression/pom.xml b/extensions/modules/compression/pom.xml index 99b4f688cc..573236ec8d 100644 --- a/extensions/modules/compression/pom.xml +++ b/extensions/modules/compression/pom.xml @@ -208,6 +208,31 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + diff --git a/extensions/modules/compression/src/test/resources-filtered/conf.xml b/extensions/modules/compression/src/test/resources-filtered/conf.xml index d03a3413b9..f6c2fe20bb 100644 --- a/extensions/modules/compression/src/test/resources-filtered/conf.xml +++ b/extensions/modules/compression/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/modules/counter/pom.xml b/extensions/modules/counter/pom.xml index 38a5a50ce7..d4b1b871bf 100644 --- a/extensions/modules/counter/pom.xml +++ b/extensions/modules/counter/pom.xml @@ -186,6 +186,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/extensions/modules/counter/src/test/resources-filtered/conf.xml b/extensions/modules/counter/src/test/resources-filtered/conf.xml index 6d5c877b4e..aa5f7184af 100644 --- a/extensions/modules/counter/src/test/resources-filtered/conf.xml +++ b/extensions/modules/counter/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - - + + + + + + + + diff --git a/extensions/modules/expathrepo/expathrepo-trigger-test/pom.xml b/extensions/modules/expathrepo/expathrepo-trigger-test/pom.xml index 64713909ec..66d618e336 100644 --- a/extensions/modules/expathrepo/expathrepo-trigger-test/pom.xml +++ b/extensions/modules/expathrepo/expathrepo-trigger-test/pom.xml @@ -156,6 +156,17 @@ + + + src/test/resources + false + + + src/test/resources-filtered + true + + + com.mycila @@ -190,7 +201,7 @@ pom.xml xar-assembly.xml - src/test/resources/conf.xml + src/test/resources-filtered/conf.xml src/main/xar-resources/controller.xq src/main/java/org/exist/repo/ExampleModule.java src/test/java/org/exist/repo/ExampleModuleTest.java @@ -206,7 +217,7 @@ pom.xml xar-assembly.xml - src/test/resources/conf.xml + src/test/resources-filtered/conf.xml src/main/xar-resources/controller.xq src/main/java/org/exist/repo/ExampleModule.java src/test/java/org/exist/repo/ExampleModuleTest.java @@ -223,6 +234,31 @@ + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + ro.kuberam.maven.plugins kuberam-expath-plugin diff --git a/extensions/modules/expathrepo/expathrepo-trigger-test/src/test/resources-filtered/conf.xml b/extensions/modules/expathrepo/expathrepo-trigger-test/src/test/resources-filtered/conf.xml new file mode 100644 index 0000000000..256a0e7585 --- /dev/null +++ b/extensions/modules/expathrepo/expathrepo-trigger-test/src/test/resources-filtered/conf.xml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extensions/modules/expathrepo/expathrepo-trigger-test/src/test/resources/conf.xml b/extensions/modules/expathrepo/expathrepo-trigger-test/src/test/resources/conf.xml deleted file mode 100644 index 7dff31c75f..0000000000 --- a/extensions/modules/expathrepo/expathrepo-trigger-test/src/test/resources/conf.xml +++ /dev/null @@ -1,798 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/extensions/modules/expathrepo/pom.xml b/extensions/modules/expathrepo/pom.xml index 317a7cac71..d6eb4763f0 100644 --- a/extensions/modules/expathrepo/pom.xml +++ b/extensions/modules/expathrepo/pom.xml @@ -232,6 +232,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/extensions/modules/expathrepo/src/test/resources-filtered/conf.xml b/extensions/modules/expathrepo/src/test/resources-filtered/conf.xml index f445acf25b..2d756b7be5 100644 --- a/extensions/modules/expathrepo/src/test/resources-filtered/conf.xml +++ b/extensions/modules/expathrepo/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/modules/file/pom.xml b/extensions/modules/file/pom.xml index 9cb70c6401..eb6a1728cc 100644 --- a/extensions/modules/file/pom.xml +++ b/extensions/modules/file/pom.xml @@ -295,6 +295,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + org.apache.maven.plugins maven-surefire-plugin @@ -302,8 +328,8 @@ @{jacocoArgLine} ${project.basedir}/../../../exist-jetty-config/target/classes/org/exist/jetty - ${project.build.testOutputDirectory}/conf.xml - ${project.build.testOutputDirectory}/standalone-webapp + ${project.build.testOutputDirectory}/conf.xml + ${project.build.testOutputDirectory}/standalone-webapp ${project.build.testOutputDirectory}/log4j2.xml diff --git a/extensions/modules/file/src/main/java/org/exist/xquery/modules/file/Sync.java b/extensions/modules/file/src/main/java/org/exist/xquery/modules/file/Sync.java index 599fd05234..3844cf06c9 100644 --- a/extensions/modules/file/src/main/java/org/exist/xquery/modules/file/Sync.java +++ b/extensions/modules/file/src/main/java/org/exist/xquery/modules/file/Sync.java @@ -129,7 +129,7 @@ public class Sync extends BasicFunction { new FunctionParameterSequenceType("collection", Type.STRING, Cardinality.EXACTLY_ONE, "Absolute path to the collection to synchronize to disk."), new FunctionParameterSequenceType("targetPath", Type.ITEM, Cardinality.EXACTLY_ONE, - "The path or URI to the target directory. Relative paths resolve against EXIST_HOME."), + "The path or URI to the target directory. Relative paths resolve against ELEMENTAL_HOME."), new FunctionParameterSequenceType("dateTimeOrOptionsMap", Type.ITEM, Cardinality.ZERO_OR_ONE, "Options as map(*). The available settings are:" + "\"" + PRUNE_OPT + "\": delete any file/dir that does not correspond to a doc/collection in the DB. " + @@ -257,7 +257,7 @@ private Sequence startSync( if (p.isAbsolute()) { targetDir = p; } else { - final Optional home = context.getBroker().getConfiguration().getExistHome(); + final Optional home = context.getBroker().getConfiguration().getElementalHome(); targetDir = FileUtils.resolve(home, target); } diff --git a/extensions/modules/file/src/test/resources-filtered/conf.xml b/extensions/modules/file/src/test/resources-filtered/conf.xml index b462856f0f..274ee6a1c1 100644 --- a/extensions/modules/file/src/test/resources-filtered/conf.xml +++ b/extensions/modules/file/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/modules/image/pom.xml b/extensions/modules/image/pom.xml index 7623d98499..9a2661b9bf 100644 --- a/extensions/modules/image/pom.xml +++ b/extensions/modules/image/pom.xml @@ -159,7 +159,8 @@ + - \ No newline at end of file + diff --git a/extensions/modules/mail/pom.xml b/extensions/modules/mail/pom.xml index c4eae1e198..edf8733974 100644 --- a/extensions/modules/mail/pom.xml +++ b/extensions/modules/mail/pom.xml @@ -269,6 +269,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/extensions/modules/mail/src/test/resources-filtered/conf.xml b/extensions/modules/mail/src/test/resources-filtered/conf.xml index 98d325c9e8..7d06db2f83 100644 --- a/extensions/modules/mail/src/test/resources-filtered/conf.xml +++ b/extensions/modules/mail/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/modules/persistentlogin/pom.xml b/extensions/modules/persistentlogin/pom.xml index f50f11f121..e9cdf7554d 100644 --- a/extensions/modules/persistentlogin/pom.xml +++ b/extensions/modules/persistentlogin/pom.xml @@ -168,15 +168,41 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + org.apache.maven.plugins maven-surefire-plugin @{jacocoArgLine} -Dfile.encoding=${project.build.sourceEncoding} - ${project.build.testOutputDirectory}/conf.xml + ${project.build.testOutputDirectory}/conf.xml ${project.basedir}/../../../exist-jetty-config/target/classes/org/exist/jetty - ${project.build.testOutputDirectory}/standalone-webapp + ${project.build.testOutputDirectory}/standalone-webapp ${project.build.testOutputDirectory}/log4j2.xml diff --git a/extensions/modules/persistentlogin/src/test/resources-filtered/conf.xml b/extensions/modules/persistentlogin/src/test/resources-filtered/conf.xml index 0126a7ccd6..43fbdc461d 100644 --- a/extensions/modules/persistentlogin/src/test/resources-filtered/conf.xml +++ b/extensions/modules/persistentlogin/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/modules/process/pom.xml b/extensions/modules/process/pom.xml index a1c2c0aba9..578b540852 100644 --- a/extensions/modules/process/pom.xml +++ b/extensions/modules/process/pom.xml @@ -102,6 +102,7 @@ pom.xml + src/main/java/org/exist/xquery/modules/process/Execute.java @@ -112,6 +113,7 @@
    ${project.parent.relativePath}/../../exist-parent/existdb-LGPL-21-license.template.txt
    pom.xml + src/main/java/org/exist/xquery/modules/process/Execute.java diff --git a/extensions/modules/process/src/main/java/org/exist/xquery/modules/process/Execute.java b/extensions/modules/process/src/main/java/org/exist/xquery/modules/process/Execute.java index 3fbef44dd5..5b0e8a392e 100644 --- a/extensions/modules/process/src/main/java/org/exist/xquery/modules/process/Execute.java +++ b/extensions/modules/process/src/main/java/org/exist/xquery/modules/process/Execute.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 * @@ -152,7 +176,7 @@ private Path getWorkingDir(String arg) { if (file.isAbsolute()) { return file; } - final Optional home = context.getBroker().getConfiguration().getExistHome(); + final Optional home = context.getBroker().getConfiguration().getElementalHome(); return FileUtils.resolve(home, arg); } diff --git a/extensions/modules/sql/pom.xml b/extensions/modules/sql/pom.xml index a492f66035..fd9b853d45 100644 --- a/extensions/modules/sql/pom.xml +++ b/extensions/modules/sql/pom.xml @@ -245,6 +245,32 @@
    + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/extensions/modules/sql/src/test/resources-filtered/conf.xml b/extensions/modules/sql/src/test/resources-filtered/conf.xml index ec48a5b6af..b8fa9fac78 100644 --- a/extensions/modules/sql/src/test/resources-filtered/conf.xml +++ b/extensions/modules/sql/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/modules/xmldiff/pom.xml b/extensions/modules/xmldiff/pom.xml index f2ebad9d7d..fed0b2221f 100644 --- a/extensions/modules/xmldiff/pom.xml +++ b/extensions/modules/xmldiff/pom.xml @@ -214,6 +214,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/extensions/modules/xmldiff/src/test/resources-filtered/conf.xml b/extensions/modules/xmldiff/src/test/resources-filtered/conf.xml index 3c77d2f52e..60921a715c 100644 --- a/extensions/modules/xmldiff/src/test/resources-filtered/conf.xml +++ b/extensions/modules/xmldiff/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/modules/xslfo/pom.xml b/extensions/modules/xslfo/pom.xml index 44c6e00090..3abcd239ea 100644 --- a/extensions/modules/xslfo/pom.xml +++ b/extensions/modules/xslfo/pom.xml @@ -256,6 +256,32 @@ true + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/extensions/modules/xslfo/src/test/resources-filtered/conf.xml b/extensions/modules/xslfo/src/test/resources-filtered/conf.xml index 2eac07bfa1..8d5496ddff 100644 --- a/extensions/modules/xslfo/src/test/resources-filtered/conf.xml +++ b/extensions/modules/xslfo/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/extensions/security/ldap/pom.xml b/extensions/security/ldap/pom.xml index 98d2557347..87917e4620 100644 --- a/extensions/security/ldap/pom.xml +++ b/extensions/security/ldap/pom.xml @@ -166,6 +166,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/extensions/security/ldap/src/test/resources-filtered/conf.xml b/extensions/security/ldap/src/test/resources-filtered/conf.xml index e9949d1b9b..74c5e2412e 100644 --- a/extensions/security/ldap/src/test/resources-filtered/conf.xml +++ b/extensions/security/ldap/src/test/resources-filtered/conf.xml @@ -46,746 +46,86 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - - - - - - - - - + enforce-index-use="strict" + raise-error-on-failed-retrieval="no"/> + + + + + + + + + diff --git a/extensions/webdav/pom.xml b/extensions/webdav/pom.xml index 331c7d6c13..55a84178d1 100644 --- a/extensions/webdav/pom.xml +++ b/extensions/webdav/pom.xml @@ -311,6 +311,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + org.apache.maven.plugins maven-surefire-plugin @@ -318,8 +344,8 @@ @{jacocoArgLine} ${project.basedir}/../../exist-jetty-config/target/classes/org/exist/jetty - ${project.build.testOutputDirectory}/conf.xml - ${project.build.testOutputDirectory}/standalone-webapp + ${project.build.testOutputDirectory}/conf.xml + ${project.build.testOutputDirectory}/standalone-webapp ${project.build.testOutputDirectory}/log4j2.xml diff --git a/extensions/webdav/src/main/java/org/exist/webdav/ExistResourceFactory.java b/extensions/webdav/src/main/java/org/exist/webdav/ExistResourceFactory.java index 7503145acb..5bf7bdce7e 100644 --- a/extensions/webdav/src/main/java/org/exist/webdav/ExistResourceFactory.java +++ b/extensions/webdav/src/main/java/org/exist/webdav/ExistResourceFactory.java @@ -109,9 +109,9 @@ public ExistResourceFactory() { } try { - // 2) try and find overridden config relative to EXIST_HOME/etc - final Optional eXistHome = brokerPool.getConfiguration().getExistHome(); - final Path config = FileUtils.resolve(eXistHome, "etc").resolve("webdav.properties"); + // 2) try and find overridden config relative to ELEMENTAL_HOME/etc + final Optional elementalHome = brokerPool.getConfiguration().getElementalHome(); + final Path config = FileUtils.resolve(elementalHome, "etc").resolve("webdav.properties"); // Read from file if existent if (Files.isReadable(config)) { diff --git a/extensions/webdav/src/test/resources-filtered/conf.xml b/extensions/webdav/src/test/resources-filtered/conf.xml index e9949d1b9b..5edf18da5a 100644 --- a/extensions/webdav/src/test/resources-filtered/conf.xml +++ b/extensions/webdav/src/test/resources-filtered/conf.xml @@ -46,746 +46,86 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - - - - - - - - + raise-error-on-failed-retrieval="no"/> + + + + + + + + + diff --git a/extensions/xqdoc/pom.xml b/extensions/xqdoc/pom.xml index 120c86af7d..246b0119bb 100644 --- a/extensions/xqdoc/pom.xml +++ b/extensions/xqdoc/pom.xml @@ -197,6 +197,32 @@ + + + org.codehaus.mojo + xml-maven-plugin + + + validate-test-conf + process-test-resources + + validate + + + + + true + ${project.build.testOutputDirectory} + + conf.xml + + + + + + + + diff --git a/extensions/xqdoc/src/test/resources-filtered/conf.xml b/extensions/xqdoc/src/test/resources-filtered/conf.xml index 395e3f2e52..0979f5e0bb 100644 --- a/extensions/xqdoc/src/test/resources-filtered/conf.xml +++ b/extensions/xqdoc/src/test/resources-filtered/conf.xml @@ -46,720 +46,73 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - + match-tagging-elements="no"/> + - - - - + - + + + + + + + + diff --git a/schema/conf.xsd b/schema/conf.xsd index dee0be751b..671fbfb261 100644 --- a/schema/conf.xsd +++ b/schema/conf.xsd @@ -190,7 +190,7 @@ - + @@ -213,7 +213,7 @@ - + - + @@ -326,7 +326,24 @@ - + + + + The Java classname of a parser which implements org.xml.sax.XMLReader + and is capable of parsing HTML and emitting an XML Sax Stream. +

    + Whichever library you use for this, it must be present on the classpath. + See $ELEMENTAL_HOME/lib +

    + Examples include: + - org.codelibs.nekohtml.parsers.SAXParser + The Cyber NekoHTML parser from https://sourceforge.net/projects/nekohtml/ +

    + - org.ccil.cowan.tagsoup.Parser + The TagSoup parser from http://home.ccil.org/~cowan/XML/tagsoup/ + + + @@ -406,7 +423,7 @@ - + @@ -441,9 +458,32 @@ - - - + + + + Defines the maximum number of page splits allowed within a document + before a defragmentation run will be triggered. + + + + + + + For debugging only. If the parameter is set to "yes", a consistency + check will be run on every modified document after every XUpdate + request. It checks if the persistent DOM is complete and all + pointers in the structural index point to valid storage addresses + containing valid nodes. + + + + + + + TODO + + +