This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit d04033fd12f8e7eaf27c3406b57c2c825a13481f
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Wed Oct 1 16:00:32 2025 +0200

    Fix again the path to the embedded EPSG database.
---
 .../metadata/sql/internal/shared/Initializer.java  |  4 +++
 .../apache/sis/setup/InstallationResources.java    |  6 ++--
 .../sis/resources/embedded/EmbeddedResources.java  | 19 +++++++---
 .../resources/embedded/EmbeddedResourcesTest.java  | 42 ++++++++++------------
 .../apache/sis/resources/embedded/Generator.java   | 41 ++++++++++++---------
 5 files changed, 65 insertions(+), 47 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/internal/shared/Initializer.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/internal/shared/Initializer.java
index ad733af259..ad80ddb0d0 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/internal/shared/Initializer.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/internal/shared/Initializer.java
@@ -62,6 +62,10 @@ import static 
org.apache.sis.util.internal.shared.MetadataServices.EMBEDDED;
  *
  * All other methods are related to getting the {@code DataSource} instance, 
through JNDI or otherwise.
  *
+ * <h2>Note for maintainers about synchronization</h2>
+ * Some operations are synchronized on {@code Initializer} not only in this 
class, but also in other modules.
+ * If the synchronization lock is changed, search {@code synchronized 
(Initializer.class)} in the whole project.
+ *
  * @author  Martin Desruisseaux (Geomatys)
  */
 public abstract class Initializer {
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/InstallationResources.java
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/InstallationResources.java
index 1b9858c72d..55be5828be 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/InstallationResources.java
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/InstallationResources.java
@@ -34,10 +34,10 @@ import org.apache.sis.system.Reflect;
  *
  * <h2>Examples</h2>
  * <ul>
- * <li>The NADCON grid files provide <i>datum shifts</i> data for North 
America.
- *     Since those files are in the public domain, they could be bundled in 
Apache SIS.
+ * <li>The <abbr>NADCON</abbr> grid files provide <i>datum shifts</i> data for 
North America.
+ *     Since those files are in the public domain, they could be bundled in 
Apache <abbr>SIS</abbr>.
  *     But the weight of those files (about 2.4 Mb) is unnecessary for users 
who do not live in North America.</li>
- * <li>On the other hand, the <a href="https://epsg.org/";>EPSG geodetic 
dataset</a> is important for most users.
+ * <li>On the other hand, the <a href="https://epsg.org/";><abbr>EPSG</abbr> 
geodetic dataset</a> is important for most users.
  *     Codes like {@code "EPSG:4326"} became a <i>de-facto</i> standard in 
various places like <cite>Web Map Services</cite>,
  *     images encoded in GeoTIFF format, <i>etc</i>. But the <a 
href="https://epsg.org/terms-of-use.html";>EPSG terms of use</a>
  *     are more restrictive than the Apache license and require that we inform 
the users about those conditions.</li>
diff --git 
a/optional/src/org.apache.sis.referencing.database/main/org/apache/sis/resources/embedded/EmbeddedResources.java
 
b/optional/src/org.apache.sis.referencing.database/main/org/apache/sis/resources/embedded/EmbeddedResources.java
index ba8b15e26b..8dabce60c1 100644
--- 
a/optional/src/org.apache.sis.referencing.database/main/org/apache/sis/resources/embedded/EmbeddedResources.java
+++ 
b/optional/src/org.apache.sis.referencing.database/main/org/apache/sis/resources/embedded/EmbeddedResources.java
@@ -50,6 +50,12 @@ public class EmbeddedResources extends InstallationResources 
{
      */
     static final String DIRECTORY = "SIS-DATA";
 
+    /**
+     * The data source, created when first needed.
+     * Also set to a different value during tests.
+     */
+    static DataSource dataSource;
+
     /**
      * Creates a new provider for connections to the embedded database.
      */
@@ -130,10 +136,15 @@ public class EmbeddedResources extends 
InstallationResources {
     @Override
     public DataSource getResource(String authority, int index) {
         verifyAuthority(authority);
-        final var ds = new EmbeddedDataSource();
-        ds.setDataSourceName(Initializer.DATABASE);
-        ds.setDatabaseName("classpath:" + DIRECTORY + "/Databases/" + 
Initializer.DATABASE);
-        return ds;
+        synchronized (Initializer.class) {
+            if (dataSource == null) {
+                final var ds = new EmbeddedDataSource();
+                ds.setDataSourceName(Initializer.DATABASE);
+                ds.setDatabaseName("classpath:" + DIRECTORY + "/Databases/" + 
Initializer.DATABASE);
+                dataSource = ds;
+            }
+            return dataSource;
+        }
     }
 
     /**
diff --git 
a/optional/src/org.apache.sis.referencing.database/test/org/apache/sis/resources/embedded/EmbeddedResourcesTest.java
 
b/optional/src/org.apache.sis.referencing.database/test/org/apache/sis/resources/embedded/EmbeddedResourcesTest.java
index 4106cbfaad..cab83b2b7a 100644
--- 
a/optional/src/org.apache.sis.referencing.database/test/org/apache/sis/resources/embedded/EmbeddedResourcesTest.java
+++ 
b/optional/src/org.apache.sis.referencing.database/test/org/apache/sis/resources/embedded/EmbeddedResourcesTest.java
@@ -23,12 +23,10 @@ import java.sql.Statement;
 import javax.sql.DataSource;
 import java.util.Map;
 import java.util.ServiceLoader;
-import org.opengis.util.FactoryException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.apache.sis.setup.InstallationResources;
 import org.apache.sis.metadata.sql.internal.shared.Initializer;
 import org.apache.sis.system.DataDirectory;
-import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.factory.sql.EPSGFactory;
 
 // Test dependencies
@@ -55,7 +53,21 @@ public final strictfp class EmbeddedResourcesTest {
      * @throws Exception if an error occurred while creating the database.
      */
     public EmbeddedResourcesTest() throws Exception {
-        new Generator().createIfAbsent();
+        // TODO: use @BeforeAll annotation instead. It doesn't seem to work 
with current Gradle build.
+        createDatabaseIfAbsent();
+    }
+
+    /**
+     * Creates the database if not already done.
+     *
+     * @throws Exception if an error occurred while creating the database.
+     */
+    private static void createDatabaseIfAbsent() throws Exception {
+        final var generator = new Generator();
+        synchronized (Initializer.class) {
+            generator.registerAsDefaultDataSource();  // Done first because 
`….metadata.sql` will want its data source.
+            generator.createIfAbsent();
+        }
     }
 
     /**
@@ -123,31 +135,15 @@ public final strictfp class EmbeddedResourcesTest {
                 }
             }
         }
-        try (EPSGFactory factory = new EPSGFactory(Map.of("dataSource", 
Initializer.getDataSource()))) {
+        try (EPSGFactory factory = new EPSGFactory(Map.of("dataSource", ds))) {
             
verifyEPSG_6676(factory.createCoordinateReferenceSystem("EPSG:6676"));
         }
     }
 
     /**
-     * Tests the use of the embedded database. This test asks for a CRS for 
which no hard-coded fallback exists
-     * in {@link org.apache.sis.referencing.CommonCRS}. Consequently, this 
test should fail if we do not have a
-     * connection to a complete <abbr>EPSG</abbr> database.
-     *
-     * @throws FactoryException if an error occurred while creating the 
<abbr>CRS</abbr>.
-     *
-     * @todo The test is currently not executed because {@code SIS_DATA} is 
set by the build script.
-     *       We need a way to ignore it.
-     */
-    @Test
-    public void testCrsforCode() throws FactoryException {
-        assumeContainsEPSG();
-        final String dir = DataDirectory.getenv();
-        assumeTrue((dir == null) || dir.isEmpty(), "The SIS_DATA environment 
variable must be unset for enabling this test.");
-        verifyEPSG_6676(CRS.forCode("EPSG:6676"));
-    }
-
-    /**
-     * Verifies the <abbr>CRS</abbr> created from code EPSG:6676
+     * Verifies the <abbr>CRS</abbr> created from code EPSG:6676. This is a 
<abbr>CRS</abbr>
+     * for which no hard-coded fallback exists in {@link 
org.apache.sis.referencing.CommonCRS}.
+     * Consequently, this verification fails if we do not have a connection to 
a complete <abbr>EPSG</abbr> database.
      */
     private static void verifyEPSG_6676(final CoordinateReferenceSystem crs) {
         String area = 
TestUtilities.getSingleton(crs.getDomains()).getDomainOfValidity().getDescription().toString();
diff --git 
a/optional/src/org.apache.sis.referencing.database/test/org/apache/sis/resources/embedded/Generator.java
 
b/optional/src/org.apache.sis.referencing.database/test/org/apache/sis/resources/embedded/Generator.java
index 68bfc2e0b6..046c390466 100644
--- 
a/optional/src/org.apache.sis.referencing.database/test/org/apache/sis/resources/embedded/Generator.java
+++ 
b/optional/src/org.apache.sis.referencing.database/test/org/apache/sis/resources/embedded/Generator.java
@@ -35,7 +35,6 @@ import org.apache.sis.metadata.sql.MetadataSource;
 import org.apache.sis.metadata.sql.MetadataStoreException;
 import org.apache.sis.metadata.sql.internal.shared.Initializer;
 import org.apache.sis.metadata.sql.internal.shared.LocalDataSource;
-import org.apache.sis.system.DataDirectory;
 import org.apache.sis.referencing.factory.sql.EPSGFactory;
 import org.apache.sis.referencing.factory.sql.epsg.ScriptProvider;
 
@@ -60,12 +59,13 @@ final class Generator extends ScriptProvider {
     private final Path classesDirectory;
 
     /**
-     * Directory where to search for <abbr>EPSG</abbr> data.
+     * Directory where to search for <abbr>EPSG</abbr> installation script,
+     * or {@code null} if the database already exists.
      */
     private final Path sourceEPSG;
 
     /**
-     * Provides a connection to the "SpatialMetadata" database, or {@code 
null} if the database already exists.
+     * Provides a connection to the "SpatialMetadata" database.
      * The connection <abbr>URL</abbr> references the following directory in 
the compilation output directory:
      * <code>{@value EmbeddedResources#DIRECTORY}/Databases/{@value 
Initializer#DATABASE}</code>
      */
@@ -75,27 +75,24 @@ final class Generator extends ScriptProvider {
      * Creates a new database generator.
      */
     Generator() throws URISyntaxException, IOException {
+        dataSource = new EmbeddedDataSource();
+        dataSource.setDataSourceName(Initializer.DATABASE);
         classesDirectory = directoryOf(EmbeddedResources.class);
         Path target = classesDirectory;
         do target = target.getParent();     // Move to the root directory of 
classes.
         while (!target.getFileName().toString().startsWith("org.apache.sis."));
-        target = target.resolve("META-INF").resolve(DataDirectory.ENV);
+        target = target.resolve(EmbeddedResources.DIRECTORY);
         if (Files.isDirectory(target)) {
-            dataSource = null;
+            target = target.resolve("Databases");
             sourceEPSG = null;
-            return;
+        } else {
+            // We don't use `Files.createDirectories(…)` for safety against 
creation of undesirable directories.
+            target = Files.createDirectory(target);
+            target = Files.createDirectory(target.resolve("Databases"));
+            sourceEPSG = directoryOf(ScriptProvider.class);
+            dataSource.setCreateDatabase("create");
         }
-        /*
-         * Creates sub-directory step by step instead of invoking 
Files.createDirectories(…)
-         * for making sure that we do not create undesirable directories.
-         */
-        target = Files.createDirectory(target);
-        target = Files.createDirectory(target.resolve(Path.of("Databases")));
-        dataSource = new EmbeddedDataSource();
-        dataSource.setDataSourceName(Initializer.DATABASE);
         
dataSource.setDatabaseName(target.resolve(Initializer.DATABASE).toString());
-        dataSource.setCreateDatabase("create");
-        sourceEPSG = directoryOf(ScriptProvider.class);
     }
 
     /**
@@ -105,6 +102,16 @@ final class Generator extends ScriptProvider {
         return Path.of(member.getResource(member.getSimpleName() + 
".class").toURI()).getParent();
     }
 
+    /**
+     * Registers the data source created by this generator as the source of 
embedded data.
+     * This is needed because the database is available on the module path 
rather than inside a <abbr>JAR</abbr>
+     * file during test executions, so the {@code 
classpath:SIS-DATA/Databases/SpatialMetadata} <abbr>URL</abbr>
+     * will not work.
+     */
+    final void registerAsDefaultDataSource() {
+        EmbeddedResources.dataSource = dataSource;
+    }
+
     /**
      * Generates the embedded resources in the {@code target/classes} 
directory if it does not already exists.
      * See class Javadoc for more information.
@@ -113,7 +120,7 @@ final class Generator extends ScriptProvider {
      *         executing <abbr>SQL</abbr> scripts, copying data or any other 
operation.
      */
     final void createIfAbsent() throws Exception {
-        if (dataSource != null) {
+        if (sourceEPSG != null) {
             copyLicenseFiles();
             createMetadata();
             createEPSG();

Reply via email to