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();
