Package org.apache.sis.referencing.factory.sql

# Class InstallationScriptProvider

Object
InstallationResources
InstallationScriptProvider

public abstract class InstallationScriptProvider extends InstallationResources
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 can be declared in the following file for automatic discovery by `EPSGFactory`:

>     META-INF/services/org.apache.sis.setup.InstallationResources

## How this class is used

The first time that an `EPSGDataAccess` needs to be instantiated, `EPSGFactory` verifies if the EPSG database exists. If it does not, then:

1. `EPSGFactory​.install(Connection)` searches for the first instance of `InstallationResources` (the parent of this class) for which the set of authorities contains `"EPSG"`.
2. The license may be shown to the user if the application allows that (for example when running as a console application).
3. If the installation process is allowed to continue, it will iterate over all readers provided by `openScript(String, int)` and execute the SQL statements (not necessarily verbatim; the installation process may adapt to the target database).

Since:
  0.7

Defined in the `sis-referencing` module

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected static final String`
  `FINISH`
  A sentinel value for the content of the script to execute after the SQL scripts provided by the authority.
  `protected static final String`
  `PREPARE`
  A sentinel value for the content of the script to execute before the SQL scripts provided by the authority.

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  `protected`
  `InstallationScriptProvider(String authority, String... resources)`
  Creates a new provider which will read script files of the given names in that order.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `Set<String>`
  `getAuthorities()`
  Returns the identifiers of the dataset installed by the SQL scripts.
  `String[]`
  `getResourceNames(String authority)`
  Returns the names of all SQL scripts to execute.
  `BufferedReader`
  `openScript(String authority, int resource)`
  Returns a reader for the SQL script at the given index.
  `protected abstract InputStream`
  `openStream(String name)`
  Opens the input stream for the SQL script of the given name.

  ### Methods inherited from class InstallationResources

  `getLicense, getResource`

  ### Methods inherited from class Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Field Details

  - ### PREPARE

    protected static final String PREPARE
    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 `VARCHAR` columns to enumerations of values recognized by `EPSGDataAccess`. Those enumerations are not required for proper working of `EPSGFactory`, but can improve data integrity.
    See Also:
      - Constant Field Values

  - ### FINISH

    protected static final String FINISH
    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 `EPSGFactory`, but can significantly improve performances.
    See Also:
      - Constant Field Values

- ## Constructor Details

  - ### InstallationScriptProvider

    protected InstallationScriptProvider(String authority, String... resources)
    Creates a new provider which will read script files of the given names in that order. The given names are often filenames, but not necessarily (it is okay to use those names only as labels).

    Typical argument values
    Authority | Argument values
    --- | ---
    `EPSG` | `{PREPARE, "EPSG_Tables.sql", "EPSG_Data.sql", "EPSG_FKeys.sql", FINISH}`

    Parameters:
      `authority` - the authority (typically `"EPSG"`), or `null` if not available.
      `resources` - names of the SQL scripts to read.
    See Also:
      - `getResourceNames(String)`
      - `openStream(String)`

- ## Method Details

  - ### getAuthorities

    public Set<String> getAuthorities()
    Returns the identifiers of the dataset installed by the SQL scripts. The values currently recognized by SIS are:
    - `"EPSG"` for the EPSG geodetic dataset.
    The default implementation returns the authority given at construction time, or an empty set if that authority was `null`. An empty set means that the provider does not have all needed resources or does not have permission to distribute the installation scripts.
    Specified by:
      `getAuthorities` in class `InstallationResources`
    Returns:
      identifiers of SQL scripts that this instance can distribute.

  - ### getResourceNames

    public String[] getResourceNames(String authority) throws IOException
    Returns the names of all SQL 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).
    Specified by:
      `getResourceNames` in class `InstallationResources`
    Parameters:
      `authority` - the value given at construction time (e.g. `"EPSG"`).
    Returns:
      the names of all SQL scripts to execute.
    Throws:
      `IllegalArgumentException` - if the given `authority` argument is not the expected value.
      `IOException` - if fetching the script names required an I/O operation and that operation failed.

  - ### openScript

    public BufferedReader openScript(String authority, int resource) throws IOException
    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 `BufferedReader` instances shall be closed by the caller.

    #### EPSG case

    In the EPSG dataset case, the iterator should return `BufferedReader` instances for the following files (replace `<version>` by the EPSG version number and `<product>` by the target database) in same order. The first and last files are provided by Apache SIS. All other files can be downloaded from https://epsg.org/.
    1. Content of `PREPARE`, an optional data definition script that define the enumerations expected by `EPSGDataAccess`.
    2. Content of `"EPSG_<version>.mdb_Tables_<product>.sql"`, a data definition script that create empty tables.
    3. Content of `"EPSG_<version>.mdb_Data_<product>.sql"`, a data manipulation script that populate the tables.
    4. Content of `"EPSG_<version>.mdb_FKeys_<product>.sql"`, a data definition script that create foreigner key constraints.
    5. Content of `FINISH`, an optional data definition and data control script that create indexes and set permissions.
    Implementers are free to return a different set of scripts with equivalent content.

    #### Default implementation

    The default implementation invokes `openStream(String)` – except for `PREPARE` and `FINISH` in which case an Apache SIS build-in script is used – and wrap the result in a `LineNumberReader`. The file encoding is UTF-8 (the encoding used in the scripts distributed by EPSG since version 9.4).
    Specified by:
      `openScript` in class `InstallationResources`
    Parameters:
      `authority` - the value given at construction time (e.g. `"EPSG"`).
      `resource` - index of the SQL script to read, from 0 inclusive to `getResourceNames(authority)​.length` exclusive.
    Returns:
      a reader for the content of SQL script to execute.
    Throws:
      `IllegalArgumentException` - if the given `authority` argument is not the expected value.
      `IndexOutOfBoundsException` - if the given `resource` argument is out of bounds.
      `FileNotFoundException` - if the SQL script of the given name has not been found.
      `IOException` - if an error occurred while creating the reader.

  - ### openStream

    protected abstract InputStream openStream(String name) throws IOException
    Opens the input stream for the SQL script of the given name. This method is invoked by the default implementation of `openScript(String, int)` for all scripts except `PREPARE` and `FINISH`.
    Example 1: if this `InstallationScriptProvider` instance gets the SQL scripts from files in a well-known directory and if the names given at construction time are the filenames in that directory, then this method can be implemented as below:

    >     protected InputStream openStream(String name) throws IOException {
    >         return Files.newInputStream(directory.resolve(name));
    >     }

    Example 2: if this `InstallationScriptProvider` instance rather gets the SQL scripts from resources bundled in the same JAR files than and in the same package, then this method can be implemented as below:

    >     protected InputStream openStream(String name) {
    >         return MyClass.getResourceAsStream(name);
    >     }

    Parameters:
      `name` - name of the script file to open. Can be `null` if the resource is not found.
    Returns:
      an input stream opened of the given script file.
    Throws:
      `IOException` - if an error occurred while opening the file.