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 f373d1fcd85bf45db8e8bb8af4099f66701b002d Author: Martin Desruisseaux <[email protected]> AuthorDate: Thu Jun 26 16:05:25 2025 +0200 Fix documentation relative to EPSG in the `README` files and in Javadoc of installation script providers. Some sentences where from the days when the EPSG optional modules were on the SVN source code repository. --- .../sis/metadata/sql/privy/SQLUtilities.java | 6 +- .../sis/metadata/sql/privy/ScriptRunner.java | 3 +- .../sis/referencing/factory/sql/EPSGFactory.java | 10 +- .../sis/referencing/factory/sql/EPSGInstaller.java | 4 +- .../sis/referencing/factory/sql/EPSG_README.md | 15 +-- .../factory/sql/InstallationScriptProvider.java | 102 ++++++++++----------- .../sis/io/wkt/GeodeticObjectParserTest.java | 2 +- .../referencing/factory/sql/EPSGInstallerTest.java | 7 +- .../main/org/apache/sis/system/DataDirectory.java | 2 +- .../sis/referencing/factory/sql/epsg/README.md | 25 ++--- .../factory/sql/epsg/DataScriptFormatter.java | 30 +++--- .../sis/referencing/factory/sql/epsg/README.md | 85 ++++++++--------- .../factory/sql/epsg/ScriptProviderTest.java | 2 +- 13 files changed, 150 insertions(+), 143 deletions(-) diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/SQLUtilities.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/SQLUtilities.java index 814630e5e1..a547856773 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/SQLUtilities.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/SQLUtilities.java @@ -136,8 +136,8 @@ public final class SQLUtilities extends Static { } /** - * Returns a string like the given string but with accented letters replaced by ASCII letters - * and all characters that are not letter or digit replaced by the wildcard % character. + * Returns a string like the given string but with accented letters replaced by <abbr>ASCII</abbr> + * letters and all characters that are not letter or digit replaced by the wildcard % character. * * @param text the text to get as a SQL LIKE pattern. * @param toLower whether to convert characters to lower case. @@ -150,7 +150,7 @@ public final class SQLUtilities extends Static { } /** - * Returns a SQL LIKE pattern for the given text. The text is optionally returned in all lower cases + * Returns a <abbr>SQL</abbr> LIKE pattern for the given text. The text is optionally returned in all lower cases * for allowing case-insensitive searches. Punctuations are replaced by any sequence of characters ({@code '%'}) * and non-ASCII letters or digits are replaced by any single character ({@code '_'}). This method avoid to put * a {@code '%'} symbol as the first character since it prevents some databases to use their index. diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/ScriptRunner.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/ScriptRunner.java index 8697ccaf2d..4ca39c62ff 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/ScriptRunner.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/privy/ScriptRunner.java @@ -389,7 +389,8 @@ public class ScriptRunner implements AutoCloseable { * SQL keywords understood by the database. For example if a database does not support the {@code "TEXT"} * data type, it may be replaced by {@code "LONG VARCHAR"}. * - * <b>Limitation:</b> the {@code inScript} word to replace must be a single word with no space. + * <h4>Limitation</h3> + * The {@code inScript} word to replace must be a single word with no space. * If the text to replace contains two words (for example {@code "CREATE TABLE"}), then revert * commit {@code bceb569558bfb7e3cf1a14aaf9261e786db06856} for bringing back this functionality. * diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGFactory.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGFactory.java index 6a33c156f5..9fdc0cf6d4 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGFactory.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGFactory.java @@ -75,7 +75,7 @@ import org.apache.sis.util.resources.Messages; * subclass. * * @author Martin Desruisseaux (Geomatys) - * @version 1.4 + * @version 1.5 * * @see EPSGDataAccess * @see SQLTranslator @@ -520,9 +520,8 @@ public class EPSGFactory extends ConcurrentAuthorityFactory<EPSGDataAccess> impl /** * Returns {@code true} if the given Data Access Object (DAO) can be closed. This method is invoked automatically - * after the {@linkplain #getTimeout timeout} if the given DAO has been idle during all that time. The default - * implementation always returns {@code false} if a set returned by {@link EPSGDataAccess#getAuthorityCodes(Class)} - * is still in use. + * after the {@linkplain #getTimeout timeout} if the given <abbr>DAO</abbr> has been idle during all that time. + * Returns {@code false} if a set returned by {@link EPSGDataAccess#getAuthorityCodes(Class)} is still in use. * * @param factory the Data Access Object which is about to be closed. * @return {@code true} if the given Data Access Object can be closed. @@ -536,8 +535,7 @@ public class EPSGFactory extends ConcurrentAuthorityFactory<EPSGDataAccess> impl * Returns whether the given object can be cached. * This method is invoked after {@link EPSGDataAccess} created a new object not previously in the cache. * - * @return whether the given object should be cached. - * + * @hidden * @since 0.8 */ @Override diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java index 4a1d5f3fab..b577ab1676 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGInstaller.java @@ -38,7 +38,7 @@ import org.apache.sis.setup.InstallationResources; /** - * Runs the SQL scripts for creating an EPSG database. + * Runs the <abbr>SQL</abbr> scripts for creating an <abbr>EPSG</abbr> database. * * See {@code org.apache.sis.referencing.factory.sql.epsg.DataScriptFormatter} * in the test directory for more information about how the scripts are formatted. @@ -55,7 +55,7 @@ final class EPSGInstaller extends ScriptRunner { * SET datum_name = replace(datum_name, CHAR(182), CHAR(10)); * } * - * Note: this regular expression use a capturing group. + * Note: this regular expression uses a capturing group. */ static final String REPLACE_STATEMENT = "UPDATE\\s+[\\w\\.\" ]+\\s+SET\\s+(\\w+)\\s*=\\s*replace\\s*\\(\\s*\\1\\W+.*"; diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSG_README.md b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSG_README.md index 9e36a858ca..c98287e285 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSG_README.md +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSG_README.md @@ -1,7 +1,10 @@ -Do not create an `epsg` sub-package (except for tests or maintenance tasks only) -because the `org.apache.sis.referencing.factory.sql.epsg` package name is owned -by the `org.apache.sis.referencing.epsg` module and we should not put anything -in a package owned by another module. +# Location of EPSG resources -We make this separation for licensing reason because the EPSG geodetic dataset -is subject to different terms of use than Apache 2 license. +There is no `epsg` sub-package in this module because such package is defined +in the `optional/src/org.apache.sis.referencing.factory.sql.epsg` module. +The current directory nevertheless contains EPSG-related classes and resources, +which are prefixed by "EPSG" instead of being placed in the `epsg` sub-package. +This mix of two conventions is for licensing reasons: use of `epsg` sub-package +requires acceptance of EPSG terms of use, while the EPSG-related resources in +this directory are under Apache 2 license and can be used without the `epsg` +sub-package if the user got EPSG scripts in another way. diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java index 993922d5d6..9e78b8cd3d 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java @@ -44,22 +44,23 @@ import org.apache.sis.util.privy.Constants; /** - * Provides SQL scripts needed for creating a local copy of a dataset. This class allows Apache SIS users - * to bundle the EPSG or other datasets in their own product for automatic installation when first needed. - * Implementations of this class are discovered automatically by {@link EPSGFactory} if they are declared - * in {@code module-info.java} as providers of the {@code org.apache.sis.setup.InstallationResources} service. + * Provides SQL scripts needed for creating a local copy of a dataset. This class allows Apache <abbr>SIS</abbr> users + * to bundle the <abbr>EPSG</abbr> geodetic datasets in their own product for automatic installation when first needed. + * Implementations of this class are discovered automatically by {@link EPSGFactory} if they are declared in the + * {@code module-info.class} file as providers of the {@code org.apache.sis.setup.InstallationResources} service. * * <h2>How this class is used</h2> * The first time that an {@link EPSGDataAccess} needs to be instantiated, - * {@link EPSGFactory} verifies if the EPSG database exists. If it does not, then: + * {@link EPSGFactory} verifies if the <abbr>EPSG</abbr> database exists. + * If it does not, then: * <ol> * <li>{@link EPSGFactory#install(Connection)} searches for the first instance of {@link InstallationResources} - * (the parent of this class) for which the {@linkplain #getAuthorities() set of authorities} contains {@code "EPSG"}.</li> - * <li>The {@linkplain #getLicense license} may be shown to the user if the application allows that - * (for example when running as a {@linkplain org.apache.sis.console console application}).</li> - * <li>If the installation process is allowed to continue, it will iterate over all readers provided by - * {@link #openScript(String, int)} and execute the SQL statements (not necessarily verbatim; - * the installation process may adapt to the target database).</li> + * for which the {@linkplain #getAuthorities() set of authorities} contains {@code "EPSG"}.</li> + * <li>The {@linkplain #getLicense license} will be shown to the user if the application allows that + * (for example, when running as a {@linkplain org.apache.sis.console console application}).</li> + * <li>If the user accepts the <abbr>EPSG</abbr> terms of use, then this class iterates over all readers provided + * by {@link #openScript(String, int)} and executes the <abbr>SQL</abbr> statements (not necessarily verbatim, + * as the installation process may adapt some <abbr>SQL</abbr> statements to the target database).</li> * </ol> * * @author Martin Desruisseaux (Geomatys) @@ -69,17 +70,17 @@ import org.apache.sis.util.privy.Constants; public abstract class InstallationScriptProvider extends InstallationResources { /** * A sentinel value for the content of the script to execute before the SQL scripts provided by the authority. - * This is an Apache SIS build-in script for constraining the values of some {@code VARCHAR} columns - * to enumerations of values recognized by {@link EPSGDataAccess}. Those enumerations are not required - * for proper working of {@link EPSGFactory}, but can improve data integrity. + * This is an Apache <abbr>SIS</abbr> build-in script for replacing the {@code VARCHAR} type of some columns + * by enumeration types, in order to constraint the values to the codes recognized by {@link EPSGDataAccess}. + * Those enumerations are not mandatory for allowing {@link EPSGFactory} to work, but improve data integrity. */ protected static final String PREPARE = "Prepare"; /** * A sentinel value for the content of the script to execute after the SQL scripts provided by the authority. - * This is an Apache SIS build-in script for creating indexes or performing any other manipulation that help - * SIS to use the dataset. Those indexes are not required for proper working of {@link EPSGFactory}, - * but can significantly improve performances. + * This is an Apache <abbr>SIS</abbr> build-in script for creating indexes or performing other manipulations + * that help <abbr>SIS</abbr> to use the dataset. Those indexes are not mandatory for allowing + * {@link EPSGFactory} to work, but improve performances. */ protected static final String FINISH = "Finish"; @@ -127,14 +128,14 @@ public abstract class InstallationScriptProvider extends InstallationResources { * The values currently recognized by SIS are: * * <ul> - * <li>{@code "EPSG"} for the EPSG geodetic dataset.</li> + * <li>{@code "EPSG"} for the <abbr>EPSG</abbr> geodetic dataset.</li> * </ul> * * The default implementation returns the authority given at construction time, or an empty set * if that authority was {@code null}. An empty set means that the provider does not have all * needed resources or does not have permission to distribute the installation scripts. * - * @return identifiers of SQL scripts that this instance can distribute. + * @return identifiers of <abbr>SQL</abbr> scripts that this instance can distribute. */ @Override @SuppressWarnings("ReturnOfCollectionOrArrayField") @@ -152,12 +153,12 @@ public abstract class InstallationScriptProvider extends InstallationResources { } /** - * Returns the names of all SQL scripts to execute. + * Returns the names of all <abbr>SQL</abbr> scripts to execute. * This is a copy of the array of names given to the constructor. * Those names are often filenames, but not necessarily (they may be just labels). * * @param authority the value given at construction time (e.g. {@code "EPSG"}). - * @return the names of all SQL scripts to execute. + * @return the names of all <abbr>SQL</abbr> scripts to execute. * @throws IllegalArgumentException if the given {@code authority} argument is not the expected value. * @throws IOException if fetching the script names required an I/O operation and that operation failed. */ @@ -168,35 +169,34 @@ public abstract class InstallationScriptProvider extends InstallationResources { } /** - * Returns a reader for the SQL script at the given index. Contents may be read from files in a local directory, - * or from resources in a JAR file, or from entries in a ZIP file, or any other means at implementer choice. - * The {@link BufferedReader} instances shall be closed by the caller. + * Returns a reader for the <abbr>SQL</abbr> script at the given index. + * The script may be read, for example, from a local file or from a resource in a <abbr>JAR</abbr> file. + * The returned {@link BufferedReader} instance shall be closed by the caller. * - * <h4>EPSG case</h4> - * In the EPSG dataset case, the iterator should return {@code BufferedReader} instances for the following files - * (replace {@code <version>} by the EPSG version number and {@code <product>} by the target database) in same order. - * The first and last files are provided by Apache SIS. + * <h4><abbr>EPSG</abbr> case</h4> + * In the case of the <abbr>EPSG</abbr> geodetic dataset, this method should return the following scripts + * (replace {@code <product>} by the target database such as {@code PostgreSQL}), in the same order. + * The first and last files are provided by Apache <abbr>SIS</abbr>. * All other files can be downloaded from <a href="https://epsg.org/">https://epsg.org/</a>. * - * <ol> + * <ol start="0"> * <li>Content of {@link #PREPARE}, an optional data definition script that define the enumerations expected by {@link EPSGDataAccess}.</li> - * <li>Content of {@code "EPSG_<version>.mdb_Tables_<product>.sql"}, a data definition script that create empty tables.</li> - * <li>Content of {@code "EPSG_<version>.mdb_Data_<product>.sql"}, a data manipulation script that populate the tables.</li> - * <li>Content of {@code "EPSG_<version>.mdb_FKeys_<product>.sql"}, a data definition script that create foreigner key constraints.</li> + * <li>Content of {@code "<product>_Tables_Script.sql"}, a data definition script that create empty tables.</li> + * <li>Content of {@code "<product>_Data_Script.sql"}, a data manipulation script that populate the tables.</li> + * <li>Content of {@code "<product>_FKeys_Script.sql"}, a data definition script that create foreigner key constraints.</li> * <li>Content of {@link #FINISH}, an optional data definition and data control script that create indexes and set permissions.</li> * </ol> * - * Implementers are free to return a different set of scripts with equivalent content. - * * <h4>Default implementation</h4> - * The default implementation invokes {@link #openStream(String)} – except for {@link #PREPARE} and {@link #FINISH} - * in which case an Apache SIS build-in script is used – and wrap the result in a {@link LineNumberReader}. - * The file encoding is UTF-8 (the encoding used in the scripts distributed by EPSG since version 9.4). + * The default implementation delegates to {@link #openStream(String)}, + * except for {@link #PREPARE} and {@link #FINISH} which are Apache <abbr>SIS</abbr> build-in scripts. + * The input stream returned by {@code openStream(…)} is assumed encoded in <abbr>UTF</abbr>-8 and is + * wrapped in a {@link LineNumberReader}. * * @param authority the value given at construction time (e.g. {@code "EPSG"}). - * @param resource index of the SQL script to read, from 0 inclusive to + * @param resource index of the <abbr>SQL</abbr> script to read, from 0 inclusive to * <code>{@linkplain #getResourceNames getResourceNames}(authority).length</code> exclusive. - * @return a reader for the content of SQL script to execute. + * @return a reader for the content of <abbr>SQL</abbr> script to execute. * @throws IllegalArgumentException if the given {@code authority} argument is not the expected value. * @throws IndexOutOfBoundsException if the given {@code resource} argument is out of bounds. * @throws FileNotFoundException if the SQL script of the given name has not been found. @@ -235,7 +235,7 @@ public abstract class InstallationScriptProvider extends InstallationResources { * The returned input stream does not need to be buffered. * * <h4>Example 1</h4> - * if this {@code InstallationScriptProvider} instance gets the SQL scripts from files in a well-known directory + * If this {@code InstallationScriptProvider} instance gets the SQL scripts from files in a well-known directory * and if the names given at {@linkplain #InstallationScriptProvider(String, String...) construction time} are the * filenames in that directory, then this method can be implemented as below: * @@ -246,8 +246,8 @@ public abstract class InstallationScriptProvider extends InstallationResources { * } * * <h4>Example 2</h4> - * if this {@code InstallationScriptProvider} instance rather gets the SQL scripts from resources bundled - * in the same JAR files as and in the same package, then this method can be implemented as below: + * If this {@code InstallationScriptProvider} instance gets the <abbr>SQL</abbr> scripts from resources bundled in + * the same <abbr>JAR</abbr> file and in the same package as the subclass, this method can be implemented as below: * * {@snippet lang="java" : * protected InputStream openStream(String name) { @@ -304,20 +304,14 @@ public abstract class InstallationScriptProvider extends InstallationResources { * @param locale the locale for warning messages, if any. */ Default(final Locale locale) throws IOException { - super(Constants.EPSG, - PREPARE, - "Tables", - "Data", - "FKeys", - FINISH); - + super(Constants.EPSG, PREPARE, "Tables", "Data", "FKeys", FINISH); final String[] resources = super.resources; - final String[] found = new String[resources.length - (FIRST_FILE + 1)]; + final String[] found = new String[resources.length - (FIRST_FILE + 1)]; // +1 is for omitting `FINISH`. @SuppressWarnings("LocalVariableHidesMemberVariable") Path directory = DataDirectory.DATABASES.getDirectory(); - if (directory == null || Files.isDirectory(directory = directory.resolve("ExternalSources"))) { - try (DirectoryStream<Path> stream = Files.newDirectoryStream(directory, "EPSG_*.sql")) { - for (final Path path : stream) { + if (directory != null && Files.isDirectory(directory = directory.resolve("ExternalSources"))) { + try (DirectoryStream<Path> content = Files.newDirectoryStream(directory, "EPSG_*.sql")) { + for (final Path path : content) { final String name = path.getFileName().toString(); for (int i=0; i<found.length; i++) { final String part = resources[FIRST_FILE + i]; @@ -337,7 +331,7 @@ public abstract class InstallationScriptProvider extends InstallationResources { } this.directory = directory; /* - * Store the actual file names including the target database and EPSG dataset version. Example: + * Store the actual file names including the target database. Example: * * - PostgreSQL_Table_Script.sql * - PostgreSQL_Data_Script.sql diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/GeodeticObjectParserTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/GeodeticObjectParserTest.java index 73faa32290..d07e3cbe01 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/GeodeticObjectParserTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/GeodeticObjectParserTest.java @@ -699,7 +699,7 @@ public final class GeodeticObjectParserTest extends EPSGDependentTestCase { /** * Tests the same CRS as {@link #testProjectedWithGradUnits()}, but from a WKT 2 definition - * (except for inclusion of accented characters). + * (except for inclusion of accented letters). * * @throws ParseException if the parsing failed. * diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java index ba0168b6bc..9579346e50 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java @@ -60,7 +60,7 @@ import org.apache.sis.metadata.sql.TestDatabase; * <a href="https://sis.apache.org/source.html#non-free">SIS non-free directory</a>.</p> * * <p>Every databases created by this test suite exist only in memory. - * This class does not write anything to disk (except maybe some temporary files).</p> + * This class does not write to disk, except temporary files for some databases.</p> * * @author Martin Desruisseaux (Geomatys) */ @@ -103,11 +103,14 @@ public final class EPSGInstallerTest extends TestCaseWithLogs { /** * Returns the SQL scripts needed for testing the database creation, * or skip the JUnit test if those scripts are not found. + * + * @return provider of SQL scripts to execute for building the EPSG geodetic dataset. + * @throws IOException if an I/O operation was required and failed. */ private static InstallationScriptProvider getScripts() throws IOException { final var scripts = new InstallationScriptProvider.Default(null); assumeTrue(scripts.getAuthorities().contains(Constants.EPSG), - "EPSG scripts not found in Databases/ExternalSources directory."); + "EPSG scripts not found in the \"Databases/ExternalSources\" directory."); return scripts; } diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/DataDirectory.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/DataDirectory.java index dfe7357d47..e7cd25a004 100644 --- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/DataDirectory.java +++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/DataDirectory.java @@ -203,7 +203,7 @@ public enum DataDirectory { if (directory == null) { final Path root = getRootDirectory(); if (root != null) { - final StringBuilder buffer = new StringBuilder(name()); + final var buffer = new StringBuilder(name()); for (int i=1; i<buffer.length(); i++) { final char c = buffer.charAt(i); if (c == '_') buffer.deleteCharAt(i); 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 fcd650b55e..bfd7a72114 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 @@ -3,21 +3,22 @@ This is the directory where EPSG data can be placed. Those data are not commited in the Apache SIS source code repository because they are licensed under [EPSG terms of use](https://epsg.org/terms-of-use.html). -For including the EPSG data in the `org.apache.sis.referencing.epsg` artifact, -the following commands must be executed manually with this directory as the -current directory: +For including the EPSG data in the `org.apache.sis.referencing.epsg` module, +the following commands must be executed manually in a separated directory: ```shell -# Execute the following in a separated directory. svn checkout https://svn.apache.org/repos/asf/sis/data/non-free/ -cd non-free -export NON_FREE_DIR=`pwd` +cd non-free/EPSG +export NON_FREE_DIR=$PWD +``` + +Then, the following commands must be executed with this directory as the current directory: -# Execute the following in the directory of this `README.md` file. -ln --symbolic $NON_FREE_DIR/EPSG/LICENSE.txt -ln --symbolic $NON_FREE_DIR/EPSG/LICENSE.html -ln --symbolic $NON_FREE_DIR/EPSG/Tables.sql -ln --symbolic $NON_FREE_DIR/EPSG/Data.sql -ln --symbolic $NON_FREE_DIR/EPSG/FKeys.sql +```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 - ``` diff --git a/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/DataScriptFormatter.java b/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/DataScriptFormatter.java index d09221a312..cd8dd320f4 100644 --- a/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/DataScriptFormatter.java +++ b/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/DataScriptFormatter.java @@ -43,22 +43,26 @@ import org.apache.sis.metadata.sql.TestDatabase; /** * Rewrites the {@code INSERT TO ...} statements in a SQL script in a more compact form. - * This class is used only for updating the SQL scripts used by Apache SIS for the EPSG - * dataset when a newer release of the EPSG dataset is available. - * The steps to follow are documented in the {@code package.html} file. + * This class is used only for updating the <abbr>SQL</abbr> scripts used by Apache SIS + * for the <abbr>EPSG</abbr> dataset when a newer release of that dataset is available. + * The steps to follow are documented in the {@code README.md} file. * * @author Martin Desruisseaux (IRD, Geomatys) */ public final class DataScriptFormatter extends ScriptRunner { /** - * Compacts the {@code Data.sql} file provided by EPSG. This method expects two arguments. - * The first argument is the file of the SQL script to read, which must exist. - * The second argument is the file where to write the compacted SQL script, - * which will be overwritten without warning if it exists. + * Compacts the {@code *Data_Script.sql} file provided by <abbr>EPSG</abbr>. + * This method expects two arguments: + * + * <ol> + * <li>The file of the <abbr>SQL</abbr> script to convert, which must exist.</li> + * <li>The file where to write the compacted script, which will be overwritten without warning if it exists.</li> + * </ol> + * * The values of those arguments are typically: * * <ol> - * <li>{@code $EPSG_SCRIPTS/PostgreSQL_Table_Script.sql}</li> + * <li>{@code $EPSG_SCRIPTS/PostgreSQL_Data_Script.sql}</li> * <li>{@code sis-epsg/src/main/resources/org/apache/sis/referencing/factory/sql/epsg/Data.sql}</li> * </ol> * @@ -74,8 +78,8 @@ public final class DataScriptFormatter extends ScriptRunner { try (TestDatabase db = TestDatabase.create("dummy"); Connection c = db.source.getConnection()) { - final DataScriptFormatter f = new DataScriptFormatter(c); - f.run(Path.of(arguments[0]), Path.of(arguments[1])); + final var formatter = new DataScriptFormatter(c); + formatter.run(Path.of(arguments[0]), Path.of(arguments[1])); } } @@ -103,7 +107,7 @@ public final class DataScriptFormatter extends ScriptRunner { /** * Indices (in reversal order) of columns to change from type SMALLINT to type BOOLEAN. * Index 0 is the last column, index 1 is the column before the last, <i>etc</i>. - * We use the reverse order because most boolean columns in the EPSG dataset are last. + * We use the reverse order because most Boolean columns in the EPSG dataset are last. */ private int[] booleanColumnIndices; @@ -140,7 +144,7 @@ public final class DataScriptFormatter extends ScriptRunner { super(c, Integer.MAX_VALUE); final int[] lastColumn = new int[] {0 }; final int[] twoLastColumns = new int[] {0,1}; - final Map<String,int[]> m = new HashMap<>(); + final var m = new HashMap<String,int[]>(); m.put("epsg_area", lastColumn ); m.put("epsg_coordinateaxisname", lastColumn ); m.put("epsg_coordinatereferencesystem", twoLastColumns); @@ -373,7 +377,7 @@ public final class DataScriptFormatter extends ScriptRunner { private static String editColumns(final int[] indices, final String line, final UnaryOperator<String> converter) throws SQLException { - final StringBuilder buffer = new StringBuilder(line); + final var buffer = new StringBuilder(line); int end = CharSequences.skipTrailingWhitespaces(buffer, 0, buffer.length()); if (buffer.codePointBefore(end) == ')') end--; for (int n=0, columnIndex=0; n < indices.length; columnIndex++) { diff --git a/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/README.md b/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/README.md index 017ec271ba..0bb40aca0b 100644 --- a/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/README.md +++ b/optional/src/org.apache.sis.referencing.epsg/test/org/apache/sis/referencing/factory/sql/epsg/README.md @@ -2,44 +2,38 @@ The `org.apache.sis.referencing.factory.sql.epsg` package in the `non-free:sis-epsg` Maven artifact provides SQL scripts for installing a local copy of the [EPSG geodetic dataset](https://epsg.org/). -This dataset provides definitions for thousands of Coordinate Reference Systems (CRS), +That dataset provides definitions for thousands of Coordinate Reference Systems (CRS), together with parameter values for thousands of Coordinate Operations between various pairs of CRS. EPSG is maintained by the [International Association of Oil and Gas Producers](https://www.iogp.org/) (IOGP) Surveying & Positioning Committee and is subject to [EPSG terms of use](https://epsg.org/terms-of-use.html). -Because of incompatibilities between EPSG terms of use and Apache 2 license, the EPSG geodetic dataset is not distributed -by default with Apache SIS. A copy of the dataset is provided in a separated module in a separated source code repository. -The Maven identifier of that module is `org.apache.sis.non-free:sis-epsg` and the source repository is located at -http://svn.apache.org/repos/asf/sis/data/non-free/sis-epsg. -The EPSG scripts are copied in that module with identical content, but in a more compact format. - -This `org.apache.sis.referencing.factory.sql.epsg` package in `endorsed/org.opengis.sis.referencing` module -contains only tools for maintaining the `non-free/org.apache.sis.referencing.epsg` module. -This package is provided only in the **test** directory, not in the main directory, because the -`org.apache.sis.referencing.factory.sql.epsg` package name is reserved by the `non-free/org.apache.sis.referencing.epsg` module. -The `endorsed/org.apache.sis.referencing` module should not distribute anything in packages owned by other modules. -However, it is okay to use those package names in directories that are not part of the distribution, like tests. -We put those tools here for easier maintainance when the core of Apache SIS is modified. +Because of incompatibilities between EPSG terms of use and Apache 2 license, +the EPSG geodetic dataset is not distributed with Apache SIS source code or other bundles released on Apache web sites. +A modified copy of the dataset is provided in a [separated source code repository](https://svn.apache.org/repos/asf/sis/data/non-free/EPSG/) +for inclusion in the `org.apache.sis.non-free:sis-epsg` artifact only if links are provided as +[described in the main module](../../../../../../../../main/org/apache/sis/referencing/factory/sql/epsg/README.md). +The copy has the same content as the original EPSG scripts, but more compact and sometime with accent characters added. +Column order may also differ for more consistency (e.g., keeping `deprecated` as the last column in all tables). ## How to apply EPSG geodetic dataset updates This page explains how to convert the SQL scripts published by EPSG into the more compact form used by Apache SIS. The compact form is about half the size of the original files. Compaction is achieved by avoiding redundant statements. -This conversion applies only to the data types, the integrity constraints and the way the SQL scripts are written. -No data value should be altered. Steps to follow: +This conversion applies only to the data types, the integrity constraints and the way that the SQL scripts are written. +No data value should be altered, accept for accented letters in some names. Steps to follow: Download the latest SQL scripts for PostgreSQL from https://epsg.org/ (require registration). Unzip in the directory of your choice and remember the path to that directory: -``` -unzip EPSG-PSQL-export-_<version>_.zip +```bash +unzip EPSG-<version>-PostgreSQL.zip export EPSG_SCRIPTS=$PWD ``` If a copy of the original SQL scripts (as downloaded from EPSG) for the previous version is still available, and if the following commands report no difference, then jump to "execute main" step. -``` +```bash cd _<directory containing EPSG scripts of previous version>_ diff PostgreSQL_Table_Script.sql $EPSG_SCRIPTS/PostgreSQL_Table_Script.sql diff PostgreSQL_FKey_Script.sql $EPSG_SCRIPTS/PostgreSQL_FKey_Script.sql @@ -47,14 +41,15 @@ diff PostgreSQL_FKey_Script.sql $EPSG_SCRIPTS/PostgreSQL_FKey_Script.sql Otherwise, move to the directory which contains the Apache SIS scripts: -``` -cd <SIS_HOME>/non-free/sis-epsg/src/main/resources/org/apache/sis/referencing/factory/sql/epsg/ +```bash +cd <path to a local copy of http://svn.apache.org/repos/asf/sis/data/non-free/EPSG/> +export NON_FREE_DIR=$PWD ``` Overwrite `Tables.sql` and `FKeys.sql` with the new SQL scripts. -Do not overwrite `Data.sql` and `Indexes.sql`: +Do not overwrite `Data.sql` yet: -``` +```bash cp $EPSG_SCRIPTS/PostgreSQL_Table_Script.sql Tables.sql cp $EPSG_SCRIPTS/PostgreSQL_FKey_Script.sql FKeys.sql ``` @@ -62,6 +57,8 @@ cp $EPSG_SCRIPTS/PostgreSQL_FKey_Script.sql FKeys.sql Open the `Tables.sql` file for edition: * Keep the header comments that existed in the overwritten file. +* Keep the same column order than in the previous `Tables.sql`. +* Suppress trailing `NULL` (not to be confused with `NOT NULL`) as they are implicit. * In the statement creating the `coordinateaxis` table, add the `NOT NULL` constraint to the `coord_axis_code` column. * In the statement creating the `change` table, @@ -72,38 +69,44 @@ Open the `Tables.sql` file for edition: * Change the type of `ellipsoid_shape`, `reverse_op`, `param_sign_reversal` `show_crs`, `show_operation` and all `deprecated` fields from `SMALLINT` (or sometimes `VARCHAR(3)`) to `BOOLEAN`. +* Change all `FLOAT` types to `DOUBLE PRECISION` because Apache SIS reads all numbers as `double` type. + This change avoids spurious digits in the conversions from `float` to `double`. +* Change the type of `epsg_usage` column from `SERIAL` to `INTEGER NOT NULL`. * Change the type of every `table_name` columns from `VARCHAR(80)` to `epsg_table_name`. * Change the type of `coord_ref_sys_kind` column from `VARCHAR(24)` to `epsg_crs_kind`. * Change the type of `coord_sys_type` column from `VARCHAR(24)` to `epsg_cs_kind`. * Change the type of `datum_type` column from `VARCHAR(24)` to `epsg_datum_kind`. * Suppress trailing spaces and save. -Usually this results in no change at all compared to the previous script (ignoring white spaces), -in which case the maintainer can just revert the changes in order to preserve the formatting. Then open the `FKeys.sql` file for edition: * At the end of all `ALTER TABLE` statement, append `ON UPDATE RESTRICT ON DELETE RESTRICT`. * Suppress trailing spaces and save. -In most cases this results in unmodified `FKeys.sql` file compared to the previous version. - +Usually, the above editions result in no change compared to the previous scripts (ignoring white spaces), +in which case the maintainer can just revert the changes in order to preserve the formatting. +However, if some changes are found in the schema, then hard-coded values in the `DataScriptFormatter` class may need +to be modified, in particular the `booleanColumnIndicesForTables` and `doubleColumnIndicesForTables` collections. -### Main Execute the `main` method of the `org.apache.sis.referencing.factory.sql.epsg.DataScriptFormatter` class -located in the test directory of `sis-referencing` module -(adjust version numbers as needed; we may provide an easier way after migration to Jigsaw modules): +located in the test directory of the `org.apache.sis.non-free:sis-epsg` Maven sub-project. +Adjust version numbers as needed in the following commands: -``` +```bash cd _<path to SIS project directory>_ -mvn clean install +gradle clean test jar export CLASSPATH=~/.m2/repository/org/apache/derby/derby/10.14.2.0/derby-10.14.2.0.jar -export CLASSPATH=$PWD/core/sis-metadata/target/test-classes:$CLASSPATH -export CLASSPATH=$PWD/target/binaries/sis-referencing-2.0-SNAPSHOT.jar:$CLASSPATH -export CLASSPATH=$PWD/core/sis-metadata/target/test-classes:$CLASSPATH -export CLASSPATH=$PWD/core/sis-referencing/target/test-classes:$CLASSPATH -cd <path to local copy of http://svn.apache.org/repos/asf/sis/data/non-free/> -java org.apache.sis.referencing.factory.sql.epsg.DataScriptFormatter $EPSG_SCRIPTS/PostgreSQL_Data_Script.sql \ - sis-epsg/src/main/resources/org/apache/sis/referencing/factory/sql/epsg/Data.sql +export CLASSPATH=~/.m2/repository/javax/measure/unit-api/2.1.3/unit-api-2.1.3.jar:$CLASSPATH +export CLASSPATH=$PWD/geoapi/snapshot/geoapi/target/geoapi-4.0-SNAPSHOT.jar:$CLASSPATH +export CLASSPATH=$PWD/endorsed/build/libs/org.apache.sis.referencing.jar:$CLASSPATH +export CLASSPATH=$PWD/endorsed/build/libs/org.apache.sis.metadata.jar:$CLASSPATH +export CLASSPATH=$PWD/endorsed/build/libs/org.apache.sis.util.jar:$CLASSPATH +export CLASSPATH=$PWD/endorsed/build/classes/java/test/org.apache.sis.referencing:$CLASSPATH +export CLASSPATH=$PWD/endorsed/build/classes/java/test/org.apache.sis.metadata:$CLASSPATH +export CLASSPATH=$PWD/optional/build/classes/java/test/org.apache.sis.referencing.epsg:$CLASSPATH + +# From any directory +java org.apache.sis.referencing.factory.sql.epsg.DataScriptFormatter $EPSG_SCRIPTS/PostgreSQL_Data_Script.sql $NON_FREE_DIR/Data.sql ``` Run the tests. It it convenient to run `org.apache.sis.referencing.factory.sql.EPSGInstallerTest` @@ -111,14 +114,14 @@ in an IDE first, for easier debugging if some changes in database structure or c Then the whole Apache SIS project should be [tested extensively](https://sis.apache.org/source.html#tests), preferably with a PostgreSQL server ready to accept local connections to `SpatialMetadataTest` database: -``` +```bash EXPORT SIS_TEST_OPTIONS=extensive,postgresql gradle test ``` Regenerate the HTML pages listing available CRS and coordinate operation methods. Those pages will be copied into the -[site/content/tables/](http://svn.apache.org/repos/asf/sis/site/trunk/content/tables/) +[site/content/tables/](https://github.com/apache/sis-site/tree/main/static/tables) directory during the [release process](https://sis.apache.org/release-management.html#update-crs-list), but for now the purpose is only to check if there is errors: 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 0758110649..f18c0c8b77 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 @@ -40,7 +40,7 @@ public final strictfp class ScriptProviderTest { } /** - * Returns the {@link ScriptProvider} instance declared in the {@code META-INF/services/} directory. + * Returns the {@link ScriptProvider} instance declared in the {@code module-info.class} file. * The provider may coexist with providers defined in other modules, so we need to filter them. */ private static InstallationResources getInstance() {
