# Class InstallationResources

Object
InstallationResources

Direct Known Subclasses:
  `EmbeddedResources, InstallationScriptProvider, OptionalInstallations`

public abstract class InstallationResources extends Object
Resources needed for installation of third-party or optional components. `InstallationResources` can be used for downloading large files that may not be of interest to every users, or data that are subject to more restricting terms of use than the Apache license.

## Examples

- The NADCON grid files provide datum shifts data for North America. Since those files are in the public domain, they could be bundled in Apache SIS. But the weight of those files (about 2.4 Mb) is unnecessary for users who do not live in North America.
- On the other hand, the EPSG geodetic dataset is important for most users. Codes like `"EPSG:4326"` became a de-facto standard in various places like Web Map Services, images encoded in GeoTIFF format, etc. But the EPSG terms of use are more restrictive than the Apache license and require that we inform the users about those conditions.

## Recognized authorities

Some authorities implemented in Apache SIS modules are listed below. In this list, `"Embedded"` is a pseudo-authority for an embedded database containing EPSG and other data. The embedded database is provided as a convenience for avoiding the need to define a `SIS_DATA` directory on the local machine.

Authorities supported by Apache SIS
Authority | Provided by Maven artifact | Used by class
--- | --- | ---
`"EPSG"` | `org.apache.sis.non-free:sis-epsg` | `EPSGFactory`
`"Embedded"` | `org.apache.sis.non-free:sis-embedded-data` | All the above

In order to allow those classes to discover which resources are available, `InstallationResources` implementations shall be declared in the `module-info​.java` file as providers of the `org​.apache​.sis​.setup​.InstallationResources` service.

Above registration is usually done automatically when extension modules are added on the module path. For example, adding the `org​.apache​.sis​.non-free:sis-epsg` Maven dependency as documented on the Apache SIS web site is the only step needed for allowing Apache SIS to read the EPSG scripts (however SIS still needs an installation directory for writing the database; see above-cited web page for more information).

## Asking user's permission before installation

By default, data provided by `InstallationResources` subclasses must be bundled with the application and are silently installed when first needed. If instead, it is desired to ask user's permission before to download and install the data, see the `OptionalInstallations` subclass.

Since:
  0.7

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  `protected`
  `InstallationResources()`
  For subclass constructors.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `abstract Set<String>`
  `getAuthorities()`
  Returns identifiers of the resources provided by this instance.
  `String`
  `getInstructionURL()`
  Returns a URL where users can get more information about the installation process.
  `abstract String`
  `getLicense(String authority, Locale locale, String mimeType)`
  Returns the terms of use of the resources distributed by the specified authority, or `null` if none.
  `Object`
  `getResource(String authority, int index)`
  Returns an installation resource for the given authority, or `null` if not available.
  `abstract String[]`
  `getResourceNames(String authority)`
  Returns the names of all resources of the specified authority that are distributed by this instance.
  `static ServiceLoader<InstallationResources>`
  `load()`
  Returns all installation resources found on the module path, regardless if supported or not.
  `abstract BufferedReader`
  `openScript(String authority, int resource)`
  Returns a reader for the resources at the given index.

  ### Methods inherited from class Object

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

- ## Constructor Details

  - ### InstallationResources

    protected InstallationResources()
    For subclass constructors.

- ## Method Details

  - ### load

    public static ServiceLoader<InstallationResources> load()
    Returns all installation resources found on the module path, regardless if supported or not. Callers should filter the services for executing only those where `getAuthorities()` returns a non-empty set.
    Returns:
      installation resources found on the module path.
    Since:
      1.4

  - ### getAuthorities

    public abstract Set<String> getAuthorities()
    Returns identifiers of the resources provided by this instance. The values recognized by SIS are listed below (note that this list may be expanded in any future SIS versions):

    Authorities supported by Apache SIS
    Authority | Resources
    --- | ---
    `"EPSG"` | SQL installation scripts for EPSG geodetic dataset.
    `"Embedded"` | Data source of embedded database containing EPSG and other resources.

    Note: `"Embedded"` is a pseudo-authority for an embedded database containing EPSG and other data. This embedded database is provided by the `org​.apache​.sis​.referencing​.database` module as a convenience for avoiding the need to define a `SIS_DATA` directory on the local machine. In this particular case, the resource is more for execution than for installation.

    #### Availability check

    This method may return an empty set if this `InstallationResources` instance did not find the resources (for example because of files not found) or does not have the permission to distribute them. For example, this method should return an empty set in the following circumstances:
    - The installation requires user's agreement, but this agreement cannot be asked because:
      - this class is a graphical installer but `GraphicsEnvironment​.isHeadless()` returns `true`, or
      - this class is a command-line installer but `Console​.isTerminal()` returns `false`.
    Returns:
      identifiers of resources that this instance can distribute, or an empty set if this `InstallationResources` cannot be used.

  - ### getInstructionURL

    public String getInstructionURL()
    Returns a URL where users can get more information about the installation process.
    Returns:
      URL to installation instruction, or `null` if none.
    Since:
      1.2

  - ### getLicense

    public abstract String getLicense(String authority, Locale locale, String mimeType) throws IOException
    Returns the terms of use of the resources distributed by the specified authority, or `null` if none. The terms of use can be returned in either plain text or HTML.

    Licenses for some supported authorities
    Authority | License
    --- | ---
    `"EPSG"` | A copy of the https://epsg.org/terms-of-use.html page.
    `"Embedded"` | Above EPSG license.

    Parameters:
      `authority` - one of the values returned by `getAuthorities()`.
      `locale` - the preferred locale for the terms of use.
      `mimeType` - either `"text/plain"` or `"text/html"`.
    Returns:
      the terms of use in plain text or HTML, or `null` if none.
    Throws:
      `IllegalArgumentException` - if the given `authority` argument is not one of the expected values.
      `IOException` - if an error occurred while reading the license file.

  - ### getResourceNames

    public abstract String[] getResourceNames(String authority) throws IOException
    Returns the names of all resources of the specified authority that are distributed by this instance. The resources will be used in the order they appear in the array. Examples:
    - `"EPSG"` authority: the resource names are the filenames of all SQL scripts to execute. One of the first script creates tables, followed by a script that populates tables with data, followed by a script that creates foreigner keys.
    - `"Embedded"` pseudo-authority: the database name, which is `"SpatialMetadata"`. When embedded, this database is read-only.
    Parameters:
      `authority` - one of the values returned by `getAuthorities()`.
    Returns:
      the names of all resources of the given authority that are distributed by this instance.
    Throws:
      `IllegalArgumentException` - if the given `authority` argument is not one of the expected values.
      `IOException` - if fetching the resource names required an I/O operation and that operation failed.

  - ### getResource

    public Object getResource(String authority, int index) throws IOException
    Returns an installation resource for the given authority, or `null` if not available. The return value may be an instance of any type, at implementation choice. This may be for example a `URL` referencing the actual resource, or a `DataSource` for an embedded database.

    The default implementation returns `null`. A null value means that the resource is fetched by `openScript(String, int)` instead of this method. We do not return `URL` to text files in order to ensure that the file is opened with proper character encoding.

    Parameters:
      `authority` - one of the values returned by `getAuthorities()`.
      `index` - index of the resource to get, from 0 inclusive to `getResourceNames(authority)​.length` exclusive.
    Returns:
      the resource as an URL or any other type (at implementation choice), or `null` if not available.
    Throws:
      `IllegalArgumentException` - if the given `authority` argument is not one of the expected values.
      `IndexOutOfBoundsException` - if the given `resource` argument is out of bounds.
      `IOException` - if an error occurred while fetching the resource.
    Since:
      0.8
    See Also:
      - `ClassLoader​.getResource(String)`

  - ### openScript

    public abstract BufferedReader openScript(String authority, int resource) throws IOException
    Returns a reader for the resources at the given index. The resource may be a SQL script or any other resources readable as a text. The returned `BufferedReader` instance shall be closed by the caller.
    Parameters:
      `authority` - one of the values returned by `getAuthorities()`.
      `resource` - index of the script to open, from 0 inclusive to `getResourceNames(authority)​.length` exclusive.
    Returns:
      a reader for the installation script content.
    Throws:
      `IllegalArgumentException` - if the given `authority` argument is not one of the expected values.
      `IndexOutOfBoundsException` - if the given `resource` argument is out of bounds.
      `IOException` - if an error occurred while creating the reader.