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 9703e401f8aeff168bcc0e04eca1757bb0886153
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Wed Aug 20 16:27:09 2025 +0200

    Fix the generation of embedded Derby database containing EPSG data.
    If the instruction documented in `.../epsg/README.md` are followed,
    then a build with tests enabled will automatically create the full
    spatial metadata database ready to deploy.
---
 optional/build.gradle.kts                          |  18 ++--
 .../sis/resources/embedded/EmbeddedResources.java  |  14 +--
 .../sis/resources/embedded/package-info.java       |  12 +--
 .../resources/embedded/EmbeddedResourcesTest.java  |  40 ++++---
 .../apache/sis/resources/embedded/Generator.java   | 117 +++++++++++----------
 .../sis/referencing/factory/sql/epsg/README.md     |  13 +--
 .../factory/sql/epsg/ScriptProviderTest.java       |   4 +-
 7 files changed, 112 insertions(+), 106 deletions(-)

diff --git a/optional/build.gradle.kts b/optional/build.gradle.kts
index 51e4111a76..cdc3818db3 100644
--- a/optional/build.gradle.kts
+++ b/optional/build.gradle.kts
@@ -175,13 +175,17 @@ fun downloadFontGIS() {
  * Adds symbolic links to EPSG license if those optional data are present.
  */
 fun addLicenseEPSG() {
-    var targetFile = File(file("build"), 
"classes/java/main/org.apache.sis.referencing.epsg/META-INF/LICENSE")
-    if (!targetFile.exists()) {
-        val sourceFile = File(file("src"), 
"org.apache.sis.referencing.epsg/main/org/apache/sis/referencing/factory/sql/epsg/LICENSE.txt")
-        if (sourceFile.exists()) {
-            Files.createLink(targetFile.toPath(), sourceFile.toPath())
-            targetFile = File(file("build"), 
"classes/java/main/org.apache.sis.referencing.database/META-INF/LICENSE")
-            Files.createLink(targetFile.toPath(), sourceFile.toPath())
+    var buildDir = file("build")
+    if (buildDir.exists()) {
+        var targetFile = File(buildDir, 
"classes/java/main/org.apache.sis.referencing.epsg/META-INF/LICENSE")
+        if (!targetFile.exists()) {
+            val sourceFile = File(file("src"), 
"org.apache.sis.referencing.epsg/main/org/apache/sis/referencing/factory/sql/epsg/LICENSE.txt")
+            if (sourceFile.exists()) {
+                var realPath = sourceFile.toPath().toRealPath()
+                Files.createLink(targetFile.toPath(), realPath)
+                targetFile = File(file("build"), 
"classes/java/main/org.apache.sis.referencing.database/META-INF/LICENSE")
+                Files.createLink(targetFile.toPath(), realPath)
+            }
         }
     }
 }
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 c53faee85b..a97598cfac 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
@@ -18,6 +18,7 @@ package org.apache.sis.resources.embedded;
 
 import java.util.Set;
 import java.util.Locale;
+import java.util.StringJoiner;
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.io.IOException;
@@ -30,7 +31,7 @@ import org.apache.sis.util.resources.Errors;
 
 
 /**
- * Provides an embedded database for the EPSG geodetic dataset and other 
resources.
+ * Provides an embedded database for the <abbr>EPSG</abbr> geodetic dataset 
and other resources.
  * Provides also a copy of the <a 
href="https://epsg.org/terms-of-use.html";>EPSG terms of use</a>,
  * which should be accepted by users before the EPSG dataset can be installed.
  *
@@ -45,7 +46,7 @@ public class EmbeddedResources extends InstallationResources {
      * The name of the database embedded in the JAR file.
      * It must be an invalid package name, because otherwise the Java Platform 
Module System (JPMS) enforces
      * encapsulation in the same way as non-exported packages, which makes the 
database inaccessible to Derby.
-     * This naming trick is part of JPMS specification, so it should be 
reliable.
+     * This naming trick is part of <abbr>JPMS</abbr> specification, so it 
should be reliable.
      */
     static final String EMBEDDED_DATABASE = "spatial-metadata";
 
@@ -95,14 +96,13 @@ public class EmbeddedResources extends 
InstallationResources {
         } else {
             return null;
         }
-        final StringBuilder buffer = new StringBuilder();
-        final String lineSeparator = System.lineSeparator();
+        final var buffer = new StringJoiner(System.lineSeparator(), "", 
System.lineSeparator());
         try (BufferedReader in = new BufferedReader(new InputStreamReader(
                 EmbeddedResources.class.getResourceAsStream(filename), 
"UTF-8")))
         {
             String line;
             while ((line = in.readLine()) != null) {
-                buffer.append(line).append(lineSeparator);
+                buffer.add(line);
             }
         }
         return buffer.toString();
@@ -130,14 +130,14 @@ public class EmbeddedResources extends 
InstallationResources {
     @Override
     public DataSource getResource(String authority, int index) {
         verifyAuthority(authority);
-        final EmbeddedDataSource ds = new EmbeddedDataSource();
+        final var ds = new EmbeddedDataSource();
         ds.setDataSourceName(Initializer.DATABASE);
         ds.setDatabaseName("classpath:SIS_DATA/Databases/" + 
EMBEDDED_DATABASE);
         return ds;
     }
 
     /**
-     * Unconditionally throws an exception since the embedded database is not 
provided as SQL scripts.
+     * Unconditionally throws an exception since the embedded database is not 
provided as <abbr>SQL</abbr> scripts.
      *
      * @param  authority  shall be {@code "Embedded"}.
      * @param  resource   shall be 0.
diff --git 
a/optional/src/org.apache.sis.referencing.database/main/org/apache/sis/resources/embedded/package-info.java
 
b/optional/src/org.apache.sis.referencing.database/main/org/apache/sis/resources/embedded/package-info.java
index 2ccb718065..893d4b032d 100644
--- 
a/optional/src/org.apache.sis.referencing.database/main/org/apache/sis/resources/embedded/package-info.java
+++ 
b/optional/src/org.apache.sis.referencing.database/main/org/apache/sis/resources/embedded/package-info.java
@@ -16,15 +16,15 @@
  */
 
 /**
- * Provides non-free data, including the EPSG geodetic dataset, in a single 
read-only JAR file.
- * This module contains a copy of EPSG geodetic dataset in an embedded Apache 
Derby database.
+ * Provides data, including the non-free <abbr>EPSG</abbr> geodetic dataset, 
in a single read-only <abbr>JAR</abbr> file.
+ * This module contains a copy of the <abbr>EPSG</abbr> geodetic dataset in an 
embedded Apache Derby database.
  * Having this module on the module-path avoid the need to set the {@code 
SIS_DATA} environment variable
- * for using the Coordinate Reference Systems (<abbr>CRS</abbr>) and 
Coordinate Operations defined by EPSG.
+ * for using the Coordinate Reference Systems (<abbr>CRS</abbr>) and 
Coordinate Operations defined by <abbr>EPSG</abbr>.
  *
  * <h2>Licensing</h2>
- * EPSG is maintained by the <a href="https://www.iogp.org/";>International 
Association of Oil and Gas Producers</a>
- * (IOGP) Surveying &amp; Positioning Committee and is subject to <a 
href="https://epsg.org/terms-of-use.html";>EPSG
- * terms of use</a>. This module is not included in the Apache 
<abbr>SIS</abbr> distribution of convenience binaries,
+ * <abbr>EPSG</abbr> is maintained by the <a 
href="https://www.iogp.org/";>International Association of Oil and Gas 
Producers</a> (<abbr>IOGP</abbr>)
+ * Surveying &amp; Positioning Committee and is subject to <a 
href="https://epsg.org/terms-of-use.html";><abbr>EPSG</abbr> terms of use</a>.
+ * This module is not included in the Apache <abbr>SIS</abbr> distribution of 
convenience binaries,
  * and the source code contains only the Java classes without the 
<abbr>EPSG</abbr> data. For use in an application,
  * see <a href="https://sis.apache.org/epsg.html";>How to use EPSG geodetic 
dataset</a> on the <abbr>SIS</abbr> web site.
  *
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 6dee0b4fbb..4c8393cdcc 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
@@ -27,10 +27,10 @@ import org.apache.sis.setup.InstallationResources;
 import org.apache.sis.metadata.sql.privy.Initializer;
 import org.apache.sis.system.DataDirectory;
 import org.apache.sis.referencing.CRS;
-import org.apache.sis.referencing.factory.sql.epsg.ScriptProvider;
 
 // Test dependencies
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.junit.jupiter.api.Assumptions.assumeTrue;
 import org.apache.sis.test.TestUtilities;
@@ -41,27 +41,29 @@ import 
org.opengis.referencing.crs.CoordinateReferenceSystem;
 
 /**
  * Tests {@link EmbeddedResources}.
+ * This test has the side-effect of creating the database if it does not 
already exists.
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
 public final strictfp class EmbeddedResourcesTest {
-    /**
-     * Whether the database has been created.
-     */
-    private static boolean databaseCreated;
-
     /**
      * Creates a new test case.
+     *
+     * @throws Exception if an error occurred while creating the database.
      */
-    public EmbeddedResourcesTest() {
+    public EmbeddedResourcesTest() throws Exception {
+        new Generator().createIfAbsent();
     }
 
     /**
-     * Skips the test if the EPSG scripts are not present.
+     * Skips the test if the <abbr>EPSG</abbr> scripts are not present.
      * This method uses {@code LICENSE.txt} as a sentinel file.
+     * Note that even if the <abbr>EPSG</abbr> data are not available,
+     * the database may still contain other metadata.
      */
-    private static void assumeDataPresent() {
-        assumeTrue(ScriptProvider.class.getResource("LICENSE.txt") != null,
+    private static void assumeContainsEPSG() {
+        assumeTrue(EmbeddedResources.class.getResource("LICENSE.txt") != null,
                 "EPSG resources not found. See `README.md` for manual 
installation.");
     }
 
@@ -69,13 +71,7 @@ public final strictfp class EmbeddedResourcesTest {
      * Returns the {@link EmbeddedResources} instance declared in the {@code 
META-INF/services/} directory.
      * The provider may coexist with providers defined in other modules, so we 
need to filter them.
      */
-    private static synchronized InstallationResources getInstance() {
-        if (!databaseCreated) try {
-            new Generator().run();
-            databaseCreated = true;
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
+    private static InstallationResources getInstance() {
         InstallationResources provider = null;
         for (InstallationResources candidate : 
ServiceLoader.load(InstallationResources.class)) {
             if (candidate instanceof EmbeddedResources) {
@@ -94,7 +90,7 @@ public final strictfp class EmbeddedResourcesTest {
      */
     @Test
     public void testLicences() throws IOException {
-        assumeDataPresent();
+        assumeContainsEPSG();
         final InstallationResources provider = getInstance();
         assertTrue(provider.getLicense("Embedded", null, 
"text/plain").contains("IOGP"));
         assertTrue(provider.getLicense("Embedded", null, "text/html" 
).contains("IOGP"));
@@ -107,13 +103,13 @@ public final strictfp class EmbeddedResourcesTest {
      */
     @Test
     public void testConnection() throws Exception {
-        assumeDataPresent();
+        assumeContainsEPSG();
         final String dir = DataDirectory.getenv();
-        assertTrue((dir == null) || dir.isEmpty(), "The SIS_DATA environment 
variable must be unset for enabling this test.");
+        assumeTrue((dir == null) || dir.isEmpty(), "The SIS_DATA environment 
variable must be unset for enabling this test.");
         final DataSource ds = Initializer.getDataSource();
         assertNotNull(ds, "Cannot find the data source.");
         try (Connection c = ds.getConnection()) {
-            
assertEquals("jdbc:derby:classpath:SIS_DATA/Databases/spatial-metadata", 
c.getMetaData().getURL(), "URL");
+            assertEquals("jdbc:derby:classpath:SIS_DATA/Databases/" + 
EmbeddedResources.EMBEDDED_DATABASE, c.getMetaData().getURL(), "URL");
             try (Statement s = c.createStatement()) {
                 try (ResultSet r = s.executeQuery("SELECT COORD_REF_SYS_NAME 
FROM EPSG.\"Coordinate Reference System\" WHERE COORD_REF_SYS_CODE = 4326")) {
                     assertTrue(r.next(), "ResultSet.next()");
@@ -133,7 +129,7 @@ public final strictfp class EmbeddedResourcesTest {
      */
     @Test
     public void testCrsforCode() throws FactoryException {
-        assumeDataPresent();
+        assumeContainsEPSG();
         CoordinateReferenceSystem crs = CRS.forCode("EPSG:6676");
         String area = 
TestUtilities.getSingleton(crs.getDomains()).getDomainOfValidity().getDescription().toString();
         assertTrue(area.contains("Japan"), area);
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 fcc3b69f99..95b646aaa1 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
@@ -16,16 +16,11 @@
  */
 package org.apache.sis.resources.embedded;
 
-import java.util.List;
 import java.util.ArrayList;
-import java.util.Map;
 import java.util.HashMap;
-import java.io.InputStream;
 import java.io.IOException;
-import java.io.FileNotFoundException;
 import java.lang.reflect.Method;
 import java.net.URISyntaxException;
-import java.nio.file.FileAlreadyExistsException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.sql.CallableStatement;
@@ -41,15 +36,14 @@ import org.apache.sis.metadata.sql.MetadataStoreException;
 import org.apache.sis.metadata.sql.privy.Initializer;
 import org.apache.sis.metadata.sql.privy.LocalDataSource;
 import org.apache.sis.system.DataDirectory;
-import org.apache.sis.system.Shutdown;
 import org.apache.sis.referencing.factory.sql.EPSGFactory;
 import org.apache.sis.referencing.factory.sql.epsg.ScriptProvider;
 
 
 /**
- * Generates {@code SpatialMetadata} database with EPSG geodetic dataset.
- * This class is invoked only at build time and should be excluded from the 
final JAR file.
- * The {@link #main(String[])} method generates resources directly in the 
{@code target/classes} directory.
+ * Generates {@code SpatialMetadata} database with <abbr>EPSG</abbr> geodetic 
dataset.
+ * This class is invoked only at build time and should be excluded from the 
final <abbr>JAR</abbr> file.
+ * The {@link #createIfAbsent()} method generates resources directly in the 
{@code target/classes} directory.
  *
  * <p><b>Note:</b>
  * Maven usage is to generate resources in the {@code 
target/generated-resources} directory.
@@ -58,39 +52,22 @@ import 
org.apache.sis.referencing.factory.sql.epsg.ScriptProvider;
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
-public final class Generator extends ScriptProvider {
+final class Generator extends ScriptProvider {
     /**
-     * Generates the embedded resources in the {@code target/classes} 
directory.
-     * See class Javadoc for more information.
-     *
-     * @param  args  ignored. Can be null.
-     * @throws Exception if a failure occurred while searching directories,
-     *         executing SQL scripts, copying data or any other operation.
+     * Directory where the {@link EmbeddedResources} class file is located.
+     * This is the directory where to copy the license files.
      */
-    public static void main(String[] args) throws Exception {
-        new Generator().run();
-        Shutdown.stop(Generator.class);
-    }
+    private final Path classesDirectory;
 
     /**
-     * Generates the embedded resources in the {@code target/classes} 
directory.
-     *
-     * @throws Exception if a failure occurred while searching directories,
-     *         executing SQL scripts, copying data or any other operation.
+     * Directory where to search for <abbr>EPSG</abbr> data.
      */
-    final void run() throws Exception {
-        if (dataSource != null) {
-            createMetadata();
-            createEPSG();
-            compress();
-            shutdown();
-        }
-    }
+    private final Path sourceEPSG;
 
     /**
      * Provides a connection to the "SpatialMetadata" database, or {@code 
null} if the database already exists.
-     * The connection URL will reference the {@code 
SIS_DATA/Databases/spatial-metadata} directory in the Maven
-     * {@code target/classes} directory.
+     * The connection <abbr>URL</abbr> references the 
<code>SIS_DATA/Databases/{@value EmbeddedResources#EMBEDDED_DATABASE}</code>
+     * directory in the Maven {@code target/classes} directory.
      */
     private final EmbeddedDataSource dataSource;
 
@@ -98,12 +75,14 @@ public final class Generator extends ScriptProvider {
      * Creates a new database generator.
      */
     Generator() throws URISyntaxException, IOException {
-        Path target = copyLicenseFiles();
+        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);
         if (Files.isDirectory(target)) {
             dataSource = null;
+            sourceEPSG = null;
             return;
         }
         /*
@@ -116,28 +95,51 @@ public final class Generator extends ScriptProvider {
         dataSource.setDataSourceName(Initializer.DATABASE);
         
dataSource.setDatabaseName(target.resolve(EmbeddedResources.EMBEDDED_DATABASE).toString());
         dataSource.setCreateDatabase("create");
+        sourceEPSG = directoryOf(ScriptProvider.class);
+    }
+
+    /**
+     * Returns the directory which contains the given class.
+     */
+    private static Path directoryOf(final Class<?> member) throws 
URISyntaxException {
+        return Path.of(member.getResource(member.getSimpleName() + 
".class").toURI()).getParent();
+    }
+
+    /**
+     * Generates the embedded resources in the {@code target/classes} 
directory if it does not already exists.
+     * See class Javadoc for more information.
+     *
+     * @throws Exception if a failure occurred while searching directories,
+     *         executing <abbr>SQL</abbr> scripts, copying data or any other 
operation.
+     */
+    final void createIfAbsent() throws Exception {
+        if (dataSource != null) {
+            copyLicenseFiles();
+            createMetadata();
+            createEPSG();
+            compress();
+            shutdown();
+        }
     }
 
     /**
-     * Copies the EPSG terms of use from the {@code sis-epsg} module to this 
{@code sis-embedded-data} module.
-     * We copy those files ourselves instead than relying on {@code 
maven-resources-plugin} because a future
-     * version may combine more licenses in a single file.
+     * Copies the <abbr>EPSG</abbr> terms of use from the {@code sis-epsg} 
module to this {@code sis-embedded-data} module.
+     * If the <abbr>EPSG</abbr> data are not found, then this method does 
nothing.
      *
-     * @return the directory where the licenses have been copied.
+     * <p>We copy those files ourselves instead than relying on {@code 
maven-resources-plugin}
+     * because a future version may combine more licenses in a single file.</p>
      */
-    private Path copyLicenseFiles() throws URISyntaxException, IOException {
-        final Class<?> consumer = EmbeddedResources.class;
-        final Path target = 
Path.of(consumer.getResource(consumer.getSimpleName() + 
".class").toURI()).getParent();
+    private void copyLicenseFiles() throws URISyntaxException, IOException {
         final String[] files = {"LICENSE.txt", "LICENSE.html"};
         for (String file : files) {
-            try (InputStream in = openStream(file)) {
-                if (in == null) throw new FileNotFoundException(file);
-                Files.copy(in, target.resolve(file));
-            } catch (FileAlreadyExistsException e) {
-                break;
+            final Path source = sourceEPSG.resolve(file);
+            if (Files.exists(source)) {
+                final Path target = classesDirectory.resolve(file);
+                if (Files.notExists(target)) {
+                    Files.createLink(target, source);
+                }
             }
         }
-        return target;
     }
 
     /**
@@ -146,7 +148,7 @@ public final class Generator extends ScriptProvider {
      * @throws FactoryException  if an error occurred while creating or 
querying the database.
      */
     private void createMetadata() throws MetadataStoreException, 
ReflectiveOperationException {
-        try (MetadataSource md = new 
MetadataSource(MetadataStandard.ISO_19115, dataSource, "metadata", null)) {
+        try (var md = new MetadataSource(MetadataStandard.ISO_19115, 
dataSource, "metadata", null)) {
             Method install = md.getClass().getDeclaredMethod("install");
             install.setAccessible(true);
             install.invoke(md);
@@ -154,12 +156,18 @@ public final class Generator extends ScriptProvider {
     }
 
     /**
-     * Creates the EPSG database schema.
+     * Creates the <abbr>EPSG</abbr> database schema.
+     * This method does nothing if the <abbr>EPSG</abbr> are not available.
+     * In the latter case, only the database will contain only free metadata.
      *
      * @throws FactoryException  if an error occurred while creating or 
querying the database.
+     * @return whether the <abbr>EPSG</abbr> data were found.
      */
-    private void createEPSG() throws FactoryException {
-        final Map<String,Object> properties = new HashMap<>();
+    private boolean createEPSG() throws FactoryException {
+        if (Files.notExists(sourceEPSG.resolve("Data.sql"))) {
+            return false;
+        }
+        final var properties = new HashMap<String,Object>();
         properties.put("dataSource", dataSource);
         properties.put("scriptProvider", this);
         /*
@@ -173,16 +181,17 @@ public final class Generator extends ScriptProvider {
         if (!crs.getName().getCode().equals("WGS 84")) {
             throw new FactoryException("Unexpected CRS: " + crs.getName());
         }
+        return true;
     }
 
     /**
-     * Compresses all tables in the EPSG schema. Compression can save space if 
there was many update
+     * Compresses all tables in all schema. Compression can save space if 
there was many update
      * or delete operations in the database. In the case of the database 
generated by this class,
      * the benefit is very small because the database is fresh. But it is 
still non-zero.
      */
     private void compress() throws SQLException {
         try (Connection c = dataSource.getConnection()) {
-            List<String> tables = new ArrayList<>(80);  // As (schema,table) 
pairs.
+            final var tables = new ArrayList<String>(80);  // As 
(schema,table) pairs.
             try (ResultSet r = c.getMetaData().getTables(null, null, null, 
null)) {
                 while (r.next()) {
                     final String schema = r.getString("TABLE_SCHEM");
diff --git 
a/optional/src/org.apache.sis.referencing.epsg/main/org/apache/sis/referencing/factory/sql/epsg/README.md
 
b/optional/src/org.apache.sis.referencing.epsg/main/org/apache/sis/referencing/factory/sql/epsg/README.md
index bfd7a72114..115306fa6b 100644
--- 
a/optional/src/org.apache.sis.referencing.epsg/main/org/apache/sis/referencing/factory/sql/epsg/README.md
+++ 
b/optional/src/org.apache.sis.referencing.epsg/main/org/apache/sis/referencing/factory/sql/epsg/README.md
@@ -9,16 +9,13 @@ the following commands must be executed manually in a 
separated directory:
 ```shell
 svn checkout https://svn.apache.org/repos/asf/sis/data/non-free/
 cd non-free/EPSG
-export NON_FREE_DIR=$PWD
+export EPSG_DIR=$PWD
 ```
 
-Then, the following commands must be executed with this directory as the 
current directory:
+Then, the following commands (or something equivalent) should be executed
+with the directory of this `README.md` file as the current directory:
 
 ```shell
-ln --symbolic $NON_FREE_DIR/LICENSE.txt
-ln --symbolic $NON_FREE_DIR/LICENSE.html
-ln --symbolic $NON_FREE_DIR/Tables.sql
-ln --symbolic $NON_FREE_DIR/Data.sql
-ln --symbolic $NON_FREE_DIR/FKeys.sql
-cd -
+ln --symbolic $EPSG_DIR/LICENSE.* .
+ln --symbolic $EPSG_DIR/*.sql .
 ```
diff --git 
a/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/ScriptProviderTest.java
 
b/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/ScriptProviderTest.java
index f18c0c8b77..71792815a2 100644
--- 
a/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/ScriptProviderTest.java
+++ 
b/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/ScriptProviderTest.java
@@ -80,11 +80,11 @@ public final strictfp class ScriptProviderTest {
     public void testResources() throws IOException {
         final InstallationResources provider = getInstance();
         final String[] names = provider.getResourceNames("EPSG");
-        assertArrayEquals(new String[] {"Prepare", "Tables.sql", "Data.sql", 
"FKeys.sql", "Finish"}, names);
+        assertArrayEquals(new String[] {"Prepare.sql", "Tables.sql", 
"Data.sql", "FKeys.sql", "Finish.sql"}, names);
         for (int i=0; i<names.length; i++) {
             try (BufferedReader in = provider.openScript("EPSG", i)) {
                 // Just verify that we can read.
-                assertFalse(in.readLine().isEmpty());
+                assertFalse(in.readLine().isBlank());
             }
         }
     }

Reply via email to