You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2024/12/06 13:33:38 UTC

(sis) branch geoapi-4.0 updated (66809d27ae -> 6cdeffb8f5)

This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a change to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


    from 66809d27ae Handle empty files as non-existent files when opening a `DataStore` in write mode. This is needed because when requesting a temporary file, an empty file is created.
     new e93449f33c Document an extra step needed for a more complete shutdown of the system.
     new 6cdeffb8f5 Add a `DataStores.open(Object, String)` method which allows to specify the preferred data store implementation.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/sis/storage/DataStoreRegistry.java  |  2 +-
 .../main/org/apache/sis/storage/DataStores.java    | 63 +++++++++++++++++++++-
 .../apache/sis/storage/image/DataStoreFilter.java  | 21 ++++----
 .../main/org/apache/sis/setup/Configuration.java   | 31 ++++++++---
 settings.gradle.kts                                |  1 +
 5 files changed, 100 insertions(+), 18 deletions(-)


(sis) 02/02: Add a `DataStores.open(Object, String)` method which allows to specify the preferred data store implementation.

Posted by de...@apache.org.
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 6cdeffb8f511a66b66465b3eb6be9d4b176f834d
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Dec 6 14:32:59 2024 +0100

    Add a `DataStores.open(Object, String)` method which allows to specify the preferred data store implementation.
---
 .../org/apache/sis/storage/DataStoreRegistry.java  |  2 +-
 .../main/org/apache/sis/storage/DataStores.java    | 63 +++++++++++++++++++++-
 .../apache/sis/storage/image/DataStoreFilter.java  | 21 ++++----
 3 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStoreRegistry.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStoreRegistry.java
index 6d1ce5d717..cd117b737b 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStoreRegistry.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStoreRegistry.java
@@ -269,7 +269,7 @@ search:     for (final Category category : Category.values()) {
                     if (md == null) {
                         accept = isFirstIteration;      // If no metadata, test only during one iteration.
                     } else {
-                        accept = (md.yieldPriority() == category.yieldPriority) &&
+                        accept = (category.preferred || md.yieldPriority() == category.yieldPriority) &&
                                  ArraysExt.contains(md.capabilities(), capability);
                         if (accept & useSuffix) {
                             accept = ArraysExt.containsIgnoreCase(md.fileSuffixes(), extension) == category.useSuffix;
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStores.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStores.java
index c4ce0b2eb9..a5739a4d76 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStores.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStores.java
@@ -37,7 +37,10 @@ import org.apache.sis.coverage.grid.DisjointExtentException;
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
  * @version 1.5
- * @since   0.4
+ *
+ * <a href="https://sis.apache.org/formats.html">Data formats supported by Apache SIS</a>
+ *
+ * @since 0.4
  */
 public final class DataStores extends Static {
     /**
@@ -84,6 +87,9 @@ public final class DataStores extends Static {
      *   <li>An existing {@link StorageConnector} instance.</li>
      * </ul>
      *
+     * The file format is detected automatically by inspection of the file header.
+     * The file suffix may also be used in case of ambiguity.
+     *
      * @param  storage  the input object as a URL, file, image input stream, <i>etc.</i>.
      * @return the object to use for reading geospatial data from the given storage.
      * @throws UnsupportedStorageException if no {@link DataStoreProvider} is found for the given storage object.
@@ -93,6 +99,61 @@ public final class DataStores extends Static {
         return DataStoreRegistry.INSTANCE.open(storage, Capability.READ, null);
     }
 
+    /**
+     * Creates a {@link DataStore} capable to read the given storage, with a preference for the specified reader.
+     * The {@code storage} argument can be of the same types as documented in {@link #open(Object)}.
+     * The {@code preferredFormat} argument can be one of the following (non-exhaustive list).
+     * Note that which formats are available depend on which modules are on the module-path.
+     *
+     * <table class="sis">
+     *   <caption>Common formats</caption>
+     *   <tr><th>Format</th> <th>Description</th></tr>
+     *   <tr><td>{@code "ASCII Grid"}</td>  <td>ESRI ASCII Grid raster format</td></tr>
+     *   <tr><td>{@code "BIL/BIP/BSQ"}</td> <td>ESRI RAW binary encoding</td></tr>
+     *   <tr><td>{@code "CSV"}</td>         <td>Comma-Separated Values, optionally with Moving Features</td></tr>
+     *   <tr><td>{@code "folder"}</td>      <td>Directory of more files</td></tr>
+     *   <tr><td>{@code "GDAL"}</td>        <td>Binding to the <abbr>GDAL</abbr> C/C++ library</td></tr>
+     *   <tr><td>{@code "GeoTIFF"}</td>     <td>GeoTIFF, including big and <abbr>COG</abbr> variants</td></tr>
+     *   <tr><td>{@code "GPX"}</td>         <td><abbr>GPS</abbr> Exchange Format</td></tr>
+     *   <tr><td>{@code "Landsat"}</td>     <td>Landsat 8 level 1-2 data</td></tr>
+     *   <tr><td>{@code "NetCDF"}</td>      <td>NetCDF 3 (or 4 if UCAR dependency is included)</td></tr>
+     *   <tr><td>{@code "SQL"}</td>         <td>Connection to a <abbr>SQL</abbr> database</td></tr>
+     *   <tr><td>{@code "WKT"}</td>         <td>CRS definition in Well-Known Text format</td></tr>
+     *   <tr><td>{@code "World file"}</td>  <td>World File image read through Java Image I/O</td></tr>
+     *   <tr><td>{@code "XML"}</td>         <td>Metadata in <abbr>GML</abbr> format</td></tr>
+     * </table>
+     *
+     * The preferred format is only a hint. If the {@link DataStore} identified by {@code preferredFormat}
+     * cannot open the given storage, another data store will be searched as with {@link #open(Object)}.
+     * The actual format which has been selected is given by {@code DataStore.getProvider().getShortName()}.
+     *
+     * <h4>Example</h4>
+     * If both the {@code org.apache.sis.storage.geotiff} and {@code org.apache.sis.storage.gdal} modules
+     * are present on the module-path, then the Apache <abbr>SIS</abbr> implementation is used by default
+     * for opening GeoTIFF files. For using <abbr>GDAL</abbr> instead, use this method with {@code "GDAL"}
+     * argument value.
+     *
+     * @param  storage          the input object as a URL, file, image input stream, <i>etc.</i>.
+     * @param  preferredFormat  identification of the preferred {@code DataStore} implementation, or {@code null}.
+     * @return the object to use for reading geospatial data from the given storage.
+     * @throws UnsupportedStorageException if no {@link DataStoreProvider} is found for the given storage object.
+     * @throws DataStoreException if an error occurred while opening the storage in read mode.
+     *
+     * @see DataStore#getProvider()
+     * @see DataStoreProvider#getShortName()
+     *
+     * @since 1.5
+     */
+    public static DataStore open(final Object storage, final String preferredFormat)
+            throws UnsupportedStorageException, DataStoreException
+    {
+        Predicate<DataStoreProvider> preferred = null;
+        if (preferredFormat != null) {
+            preferred = new DataStoreFilter(preferredFormat, false);
+        }
+        return DataStoreRegistry.INSTANCE.open(storage, Capability.READ, preferred);
+    }
+
     /**
      * Creates a {@link DataStore} capable to write or update the given storage.
      * The {@code storage} argument can be any of the types documented in {@link #open(Object)}.
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/DataStoreFilter.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/DataStoreFilter.java
index a4639d0c6c..9b86a20d75 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/DataStoreFilter.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/DataStoreFilter.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.storage.image;
 
+import java.util.Objects;
 import java.util.function.Predicate;
 import javax.imageio.ImageIO;
 import org.apache.sis.util.ArraysExt;
@@ -57,7 +58,7 @@ public final class DataStoreFilter implements Predicate<DataStoreProvider> {
      * Creates a new filter for the given data store name.
      *
      * @param  preferred  name of the data store to search, or Image I/O format name.
-     * @param  writer     whether to search among writers intead of readers.
+     * @param  writer     whether to search among writers instead of readers.
      */
     public DataStoreFilter(final String preferred, final boolean writer) {
         this.preferred = preferred;
@@ -84,13 +85,15 @@ public final class DataStoreFilter implements Predicate<DataStoreProvider> {
      */
     @Override
     public boolean test(final DataStoreProvider candidate) {
-        final String formatName = StoreUtilities.getFormatName(candidate);
-        if (CharSequences.equalsFiltered(formatName, preferred, Characters.Filter.UNICODE_IDENTIFIER, true)) {
-            return true;
-        }
-        if (WorldFileStoreProvider.NAME.equals(formatName)) {
-            String[] formats = writer ? ImageIO.getWriterFormatNames() : ImageIO.getReaderFormatNames();
-            return ArraysExt.containsIgnoreCase(formats, preferred);
+        if (other == null || other.test(candidate)) {
+            final String formatName = StoreUtilities.getFormatName(candidate);
+            if (CharSequences.equalsFiltered(formatName, preferred, Characters.Filter.UNICODE_IDENTIFIER, true)) {
+                return true;
+            }
+            if (WorldFileStoreProvider.NAME.equals(formatName)) {
+                String[] formats = writer ? ImageIO.getWriterFormatNames() : ImageIO.getReaderFormatNames();
+                return ArraysExt.containsIgnoreCase(formats, preferred);
+            }
         }
         return false;
     }
@@ -102,6 +105,6 @@ public final class DataStoreFilter implements Predicate<DataStoreProvider> {
      */
     @Override
     public Predicate<DataStoreProvider> and(Predicate<? super DataStoreProvider> other) {
-        return new DataStoreFilter(this, other);
+        return new DataStoreFilter(this, Objects.requireNonNull(other));
     }
 }


(sis) 01/02: Document an extra step needed for a more complete shutdown of the system.

Posted by de...@apache.org.
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 e93449f33ca7568da11e401e51cd031b62eeff9a
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Dec 6 11:49:27 2024 +0100

    Document an extra step needed for a more complete shutdown of the system.
---
 .../main/org/apache/sis/setup/Configuration.java   | 31 +++++++++++++++++-----
 settings.gradle.kts                                |  1 +
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/Configuration.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/Configuration.java
index a0f0fa7618..a3e2e10a2c 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/Configuration.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/Configuration.java
@@ -151,18 +151,35 @@ public final class Configuration {
     }
 
     /**
-     * Shutdowns the Apache SIS library.
-     * This method close database connections and stops daemon threads.
-     * <strong>The Apache SIS library shall not be used anymore after this method call.</strong>
-     * Any use of Apache SIS after this method call may cause undermined behavior.
+     * Shutdowns the Apache <abbr>SIS</abbr> library.
+     * This method closes database connections and stops the daemon threads that were started by <abbr>SIS</abbr>.
+     * <strong>The Apache <abbr>SIS</abbr> library shall not be used anymore after this method call.</strong>
+     * Any use of Apache <abbr>SIS</abbr> after this method call may have unexpected effects.
      * In particular, it may cause memory leaks.
      *
      * <h4>When to use</h4>
-     * This method should generally <strong>not</strong> be invoked, because Apache SIS registers itself
-     * a {@linkplain Runtime#addShutdownHook(Thread) shutdown hook} to the Java Virtual Machine.
-     * This method may be useful in environments that do not allow the use of shutdown hooks,
+     * This method should generally <strong>not</strong> be invoked, because Apache <abbr>SIS</abbr> registers
+     * itself a {@linkplain Runtime#addShutdownHook(Thread) shutdown hook} to the Java Virtual Machine.
+     * This method may be useful in embedded environments that do not allow the use of shutdown hooks,
      * or when waiting for the <abbr>JVM</abbr> shutdown is overly conservative.
      *
+     * <h4>Complete shutdown</h4>
+     * This method shutdowns only the databases used by Apache <abbr>SIS</abbr>.
+     * If Apache Derby is used for the <abbr>EPSG</abbr> database, some Derby daemon threads may still be running.
+     * Those daemons can be ignored in standalone applications, but may need to be stopped in embedded environments.
+     * A complete Derby shutdown can be requested with the following code:
+     *
+     * {@snippet lang="java" :
+     *     Configuration.current().shutdown();
+     *     try {
+     *         DriverManager.getConnection("jdbc:derby:;shutdown=true");
+     *     } catch (SQLException e) {
+     *         // Expected exception as per Derby documentation.
+     *     }
+     *     }
+     *
+     * @see <a href="https://db.apache.org/derby/docs/10.15/devguide/tdevdvlp40464.html">Shutting down Derby</a>
+     *
      * @since 1.5
      */
     public void shutdown() {
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 794ea37440..2c4a36a3d2 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -84,6 +84,7 @@ dependencyResolutionManagement {
             version("derby") {
                 strictly("[10.0, 11.0[")
                 prefer("10.15.2.0")         // 10.15 is the last series compatible with JDK 11.
+                // If the derby version is updated, search for that version number in Javadoc.
             }
             // Derby vulnerabiliy: https://nvd.nist.gov/vuln/detail/CVE-2022-46337
             // Fix would require an upgrade to Java 21.