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 f084fa2ad1e81b98430d11c70ab8a064d3925e00
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Thu Sep 26 15:15:11 2024 +0200

    Add localized resources.
---
 .../main/org/apache/sis/util/resources/Errors.java |   5 +
 .../apache/sis/util/resources/Errors.properties    |   1 +
 .../apache/sis/util/resources/Errors_fr.properties |   1 +
 .../main/org/apache/sis/storage/gdal/Driver.java   |   3 +-
 .../main/org/apache/sis/storage/gdal/GDAL.java     |   8 +-
 .../org/apache/sis/storage/gdal/GDALStore.java     |  20 +--
 .../apache/sis/storage/gdal/GDALStoreProvider.java |   7 +-
 .../org/apache/sis/storage/gdal/SpatialRef.java    |   3 +-
 .../apache/sis/storage/panama/LibraryLoader.java   |   5 +-
 .../apache/sis/storage/panama/LibraryStatus.java   |  30 ++--
 .../org/apache/sis/storage/panama/Resources.java   | 175 +++++++++++++++++++++
 .../apache/sis/storage/panama/Resources.properties |  28 ++++
 .../apache/sis/storage/panama/Resources_en.java    |  30 ++++
 .../apache/sis/storage/panama/Resources_fr.java    |  30 ++++
 .../sis/storage/panama/Resources_fr.properties     |  33 ++++
 .../main/org/apache/sis/storage/gsf/GSF.java       |   4 +-
 .../apache/sis/storage/gsf/GSFStoreProvider.java   |   4 +-
 17 files changed, 343 insertions(+), 44 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java
index 3175d60500..e0353bcf29 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java
@@ -128,6 +128,11 @@ public class Errors extends IndexedResourceBundle {
          */
         public static final short CanNotOpen_1 = 14;
 
+        /**
+         * Cannot parse the Coordinate Reference System of “{0}”.
+         */
+        public static final short CanNotParseCRS_1 = 208;
+
         /**
          * Cannot parse “{0}”.
          */
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.properties
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.properties
index 616b01d17b..dcfe0a066c 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.properties
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.properties
@@ -40,6 +40,7 @@ CanNotCompute_1                   = Cannot compute 
\u201c{0}\u201d.
 CanNotCopy_1                      = Cannot copy \u201c{0}\u201d.
 CanNotOpen_1                      = Cannot open \u201c{0}\u201d.
 CanNotParse_1                     = Cannot parse \u201c{0}\u201d.
+CanNotParseCRS_1                  = Cannot parse the Coordinate Reference 
System of \u201c{0}\u201d.
 CanNotProcessProperty_2           = Cannot process property \u201c{0}\u201d. 
The reason is: {1}
 CanNotProcessPropertyAtPath_3     = Cannot process property \u201c{1}\u201d 
located at path \u201c{0}\u201d. The reason is: {2}
 CanNotRead_1                      = Cannot read \u201c{0}\u201d.
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors_fr.properties
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors_fr.properties
index ef89339a87..adf40d2ae8 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors_fr.properties
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors_fr.properties
@@ -37,6 +37,7 @@ CanNotCompute_1                   = Ne peut pas calculer 
\u00ab\u202f{0}\u202f\u
 CanNotCopy_1                      = Ne peut pas copier 
\u00ab\u202f{0}\u202f\u00bb.
 CanNotOpen_1                      = Ne peut pas ouvrir 
\u00ab\u202f{0}\u202f\u00bb.
 CanNotParse_1                     = Ne peut pas interpr\u00e9ter 
\u00ab\u202f{0}\u202f\u00bb.
+CanNotParseCRS_1                  = Ne peut pas interpr\u00e9ter le 
syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es de 
\u00ab\u202f{0}\u202f\u00bb.
 CanNotProcessProperty_2           = Ne peut pas traiter la propri\u00e9t\u00e9 
\u00ab\u202f{0}\u202f\u00bb pour la raison suivante\u00a0: {1}
 CanNotProcessPropertyAtPath_3     = Ne peut pas traiter la propri\u00e9t\u00e9 
\u00ab\u202f{1}\u202f\u00bb d\u00e9sign\u00e9e par le chemin 
\u00ab\u202f{0}\u202f\u00bb pour la raison suivante\u00a0: {2}
 CanNotRead_1                      = Ne peut pas lire 
\u00ab\u202f{0}\u202f\u00bb.
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/Driver.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/Driver.java
index ffa4d9c3d2..085323c917 100644
--- 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/Driver.java
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/Driver.java
@@ -38,6 +38,7 @@ import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.privy.Strings;
 import org.apache.sis.storage.Resource;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.panama.Resources;
 
 
 /**
@@ -295,7 +296,7 @@ public final class Driver {
         final var table = new DefaultTreeTable(shortNameColumn, 
longNameColumn);
         final TreeTable.Node root = table.getRoot();
         final String version = (gdal != null) ? 
gdal.version("--version").orElse(null) : null;
-        root.setValue(shortNameColumn, (gdal != null) ? gdal.libraryName : 
"GDAL library not found");
+        root.setValue(shortNameColumn, (gdal != null) ? gdal.libraryName : 
Resources.format(Resources.Keys.LibraryNotFound_1, GDALStoreProvider.NAME));
         root.setValue(longNameColumn, (version != null) ? version : 
Vocabulary.format(Vocabulary.Keys.NotKnown));
 
         DataStoreException error = null;
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDAL.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDAL.java
index 89ad84b4ba..acedf5c8cd 100644
--- 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDAL.java
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDAL.java
@@ -34,6 +34,7 @@ import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.panama.LibraryLoader;
 import org.apache.sis.storage.panama.LibraryStatus;
 import org.apache.sis.storage.panama.NativeFunctions;
+import org.apache.sis.storage.panama.Resources;
 
 
 /**
@@ -397,7 +398,8 @@ final class GDAL extends NativeFunctions {
 
         // Initialize GDAL after we found all functions.
         if (!invoke("GDALAllRegister")) {
-            log(GDAL.class, "<init>", new LogRecord(Level.WARNING, "Could not 
initialize GDAL."));
+            log(GDAL.class, "<init>", Resources.forLocale(null)
+                    .getLogRecord(Level.WARNING, 
Resources.Keys.CannotInitialize_1, GDALStoreProvider.NAME));
         }
     }
 
@@ -458,9 +460,9 @@ final class GDAL extends NativeFunctions {
      */
     static synchronized GDAL global() throws DataStoreException {
         if (globalStatus == null) {
-            load(true).validate();
+            load(true).validate(GDALStoreProvider.NAME);
         }
-        globalStatus.report(null);
+        globalStatus.report(GDALStoreProvider.NAME, null);
         return global;
     }
 
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStore.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStore.java
index 57d60b202c..324153cbbb 100644
--- 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStore.java
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStore.java
@@ -41,7 +41,6 @@ import org.apache.sis.storage.Aggregate;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreClosedException;
-import org.apache.sis.storage.InternalDataStoreException;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.base.MetadataBuilder;
 import org.apache.sis.storage.base.URIDataStore;
@@ -191,7 +190,7 @@ public class GDALStore extends DataStore implements 
Aggregate {
     final MemorySegment handle() throws DataStoreClosedException {
         assert Thread.holdsLock(this);
         if (handle != null) return handle;
-        throw new DataStoreClosedException("Data store is closed.");
+        throw new DataStoreClosedException(getLocale(), 
GDALStoreProvider.NAME);
     }
 
     /**
@@ -230,10 +229,9 @@ public class GDALStore extends DataStore implements 
Aggregate {
      * This name can be used as driver identifier for opening sub-components.
      *
      * @param  gdal  set of handles for invoking <abbr>GDAL</abbr> functions.
-     * @return name of the <abbr>GDAL</abbr> driver used for opening the file.
-     * @throws DataStoreException if the driver name cannot be fetched.
+     * @return name of the <abbr>GDAL</abbr> driver used for opening the file, 
or {@code null} if none.
      */
-    private String getDriverName(final GDAL gdal) throws DataStoreException {
+    private String getDriverName(final GDAL gdal) {
         try {
             var result = (MemorySegment) 
gdal.getDatasetDriver.invokeExact(handle());
             if (!GDAL.isNull(result)) {     // Paranoiac check.
@@ -243,7 +241,7 @@ public class GDALStore extends DataStore implements 
Aggregate {
         } catch (Throwable e) {
             throw GDAL.propagate(e);
         }
-        throw new InternalDataStoreException("Cannot get the driver name.");
+        return null;
     }
 
     /**
@@ -404,16 +402,6 @@ public class GDALStore extends DataStore implements 
Aggregate {
         return wktFormat;
     }
 
-    /**
-     * Returns the exception to throw for the given cause.
-     *
-     * @param  cause    the cause of the error. Cannot be null.
-     * @return the data store exception to throw.
-     */
-    private static DataStoreException cannotExecute(final Exception cause) {
-        return new DataStoreException(cause.getMessage(), cause);
-    }
-
     /**
      * Sends a warning to the listeners registered in the {@code GDALStore}.
      *
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStoreProvider.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStoreProvider.java
index ed6e781348..020e2f2dde 100644
--- 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStoreProvider.java
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStoreProvider.java
@@ -36,6 +36,7 @@ import org.apache.sis.storage.base.StoreMetadata;
 import org.apache.sis.storage.base.Capability;
 import org.apache.sis.storage.base.URIDataStoreProvider;
 import org.apache.sis.storage.panama.LibraryStatus;
+import org.apache.sis.storage.panama.Resources;
 import org.apache.sis.io.stream.InternalOptionKey;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.parameter.Parameters;
@@ -101,7 +102,9 @@ public class GDALStoreProvider extends DataStoreProvider {
     private static final ParameterDescriptorGroup OPEN_DESCRIPTOR;
     static {
         final var builder = new ParameterBuilder();
-        DRIVERS_PARAM = builder.addName("drivers").setDescription("GDAL 
drivers that may be used for opening the file.").create(String[].class, null);
+        DRIVERS_PARAM = builder.addName("drivers")
+                
.setDescription(Resources.formatInternational(Resources.Keys.AllowedDrivers_1, 
NAME))
+                .create(String[].class, null);
         OPEN_DESCRIPTOR = 
builder.addName(NAME).createGroup(URIDataStoreProvider.LOCATION_PARAM, 
DRIVERS_PARAM);
     }
 
@@ -146,7 +149,7 @@ public class GDALStoreProvider extends DataStoreProvider {
         if (status == null) {
             return GDAL.global();       // Fetch each time (no cache) because 
may have changed outside this class.
         }
-        status.report(null);            // Should never return if 
`nativeFunctions` is null.
+        status.report(NAME, null);      // Should never return if 
`nativeFunctions` is null.
         return nativeFunctions;
     }
 
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/SpatialRef.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/SpatialRef.java
index 33242b225d..912c6a1707 100644
--- 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/SpatialRef.java
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/SpatialRef.java
@@ -24,6 +24,7 @@ import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.util.resources.Errors;
 
 
 /**
@@ -127,7 +128,7 @@ final class SpatialRef {
             if (wkt != null && !wkt.isBlank()) try {
                 return (CoordinateReferenceSystem) 
owner.wktFormat().parseObject(wkt);
             } catch (ParseException | ClassCastException e) {
-                owner.warning(caller, "Cannot parse the CRS of " + 
owner.getDisplayName(), e);
+                owner.warning(caller, 
Errors.format(Errors.Keys.CanNotParseCRS_1, owner.getDisplayName()), e);
             }
         }
         return null;
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/LibraryLoader.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/LibraryLoader.java
index 863d7ba48d..f1b949b3a2 100644
--- 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/LibraryLoader.java
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/LibraryLoader.java
@@ -197,11 +197,12 @@ create: try {
     /**
      * Throws an exception if the loading of the native library failed.
      *
+     * @param  library  name of the library, used if an error message needs to 
be produced.
      * @throws DataStoreException if the native library has not been found
      *         or if SIS is not allowed to call native functions.
      */
-    public void validate() throws DataStoreException {
-        status.report(error);
+    public void validate(String library) throws DataStoreException {
+        status.report(library, error);
     }
 
     /**
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/LibraryStatus.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/LibraryStatus.java
index 8ac1c46fe6..775089e1cf 100644
--- 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/LibraryStatus.java
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/LibraryStatus.java
@@ -23,62 +23,62 @@ import org.apache.sis.storage.DataStoreClosedException;
  * Status of the native library.
  *
  * @author  Martin Desruisseaux (Geomatys)
- *
- * @todo If moved to a shared module, replace all "GDAL" strings.
  */
 public enum LibraryStatus {
     /**
      * The native library is ready for use.
      */
-    LOADED(null),
+    LOADED((short) 0),
 
     /**
      * The native library has been unloaded.
      */
-    UNLOADED("GDAL has been unloaded."),
+    UNLOADED(Resources.Keys.LibraryUnloaded_1),
 
     /**
      * The native library has not been found.
      */
-    LIBRARY_NOT_FOUND("The GDAL library has not been found."),
+    LIBRARY_NOT_FOUND(Resources.Keys.LibraryNotFound_1),
 
     /**
      * The native library was found, but not symbol that we searched.
      */
-    FUNCTION_NOT_FOUND("A GDAL function has not been found."),
+    FUNCTION_NOT_FOUND(Resources.Keys.FunctionNotFound_1),
 
     /**
      * <abbr>SIS</abbr> is not authorized to perform native function calls.
      */
-    UNAUTHORIZED("Apache SIS is not authorized to call native functions."),
+    UNAUTHORIZED(Resources.Keys.NativeAccessNotAllowed),
 
     /**
      * A fatal error occurred in the native library and that library should 
not be used anymore.
      */
-    FATAL_ERROR("A fatal error occurred and GDAL should not be used anymore in 
this JVM.");
+    FATAL_ERROR(Resources.Keys.FatalLibraryError_1);
 
     /**
-     * An explanatory message, or {@code null} if none.
+     * Resource key of an explanatory message, or 0 if none.
      */
-    private final String message;
+    private final short message;
 
     /**
      * Creates a new enumeration value.
      */
-    private LibraryStatus(final String message) {
+    private LibraryStatus(final short message) {
         this.message = message;
     }
 
     /**
      * Throws an exception if the native library is not available.
      *
-     * @param  cause the cause of the error, or {@code null} if none.
+     * @param  library  the library name, of formatting the error message.
+     * @param  cause    the cause of the error, or {@code null} if none.
      * @throws DataStoreClosedException if this enumeration value is not 
{@link #LOADED}
      *         or if the given cause is not null.
      */
-    public void report(Exception cause) throws DataStoreClosedException {
-        if (message != null || cause != null) {
-            throw new DataStoreClosedException(message, cause);
+    public void report(String library, Exception cause) throws 
DataStoreClosedException {
+        if (message != 0 || cause != null) {
+            // Note: `NativeAccessNotAllowed` will ignore the `library` 
argument.
+            throw new DataStoreClosedException(Resources.format(message, 
library), cause);
         }
     }
 }
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources.java
new file mode 100644
index 0000000000..1ba4bde055
--- /dev/null
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.storage.panama;
+
+import java.io.InputStream;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import org.opengis.util.InternationalString;
+import org.apache.sis.util.resources.KeyConstants;
+import org.apache.sis.util.resources.IndexedResourceBundle;
+import org.apache.sis.util.resources.ResourceInternationalString;
+
+
+/**
+ * Warning and error messages that are specific to the {@code 
org.apache.sis.storage.gdal} module.
+ * Resources in this file should not be used by any other module. For 
resources shared by
+ * all modules in the Apache SIS project, see {@code 
org.apache.sis.util.resources} package.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ */
+public class Resources extends IndexedResourceBundle {
+    /**
+     * Resource keys. This class is used when compiling sources, but no 
dependencies to
+     * {@code Keys} should appear in any resulting class files. Since the Java 
compiler
+     * inlines final integer values, using long identifiers will not bloat the 
constant
+     * pools of compiled classes.
+     *
+     * @author  Martin Desruisseaux (IRD, Geomatys)
+     */
+    public static final class Keys extends KeyConstants {
+        /**
+         * The unique instance of key constants handler.
+         */
+        static final Keys INSTANCE = new Keys();
+
+        /**
+         * For {@link #INSTANCE} creation only.
+         */
+        private Keys() {
+        }
+
+        /**
+         * Allowed {0} drivers for opening the file.
+         */
+        public static final short AllowedDrivers_1 = 1;
+
+        /**
+         * Cannot initialize {0}.
+         */
+        public static final short CannotInitialize_1 = 2;
+
+        /**
+         * A fatal error occurred and {0} should not be used anymore in this 
JVM.
+         */
+        public static final short FatalLibraryError_1 = 3;
+
+        /**
+         * A function of the {0} library has not been found.
+         */
+        public static final short FunctionNotFound_1 = 4;
+
+        /**
+         * The {0} library has not been found.
+         */
+        public static final short LibraryNotFound_1 = 5;
+
+        /**
+         * The {0} library has been unloaded.
+         */
+        public static final short LibraryUnloaded_1 = 6;
+
+        /**
+         * Apache SIS has not been authorized to call native functions.
+         */
+        public static final short NativeAccessNotAllowed = 7;
+    }
+
+    /**
+     * Constructs a new resource bundle loading data from
+     * the resource file of the same name as this class.
+     */
+    public Resources() {
+    }
+
+    /**
+     * Opens the binary file containing the localized resources to load.
+     * This method delegates to {@link Class#getResourceAsStream(String)},
+     * but this delegation must be done from the same module as the one
+     * that provides the binary file.
+     */
+    @Override
+    protected InputStream getResourceAsStream(final String name) {
+        return getClass().getResourceAsStream(name);
+    }
+
+    /**
+     * Returns the handle for the {@code Keys} constants.
+     *
+     * @return a handler for the constants declared in the inner {@code Keys} 
class.
+     */
+    @Override
+    protected KeyConstants getKeyConstants() {
+        return Keys.INSTANCE;
+    }
+
+    /**
+     * Returns resources in the given locale.
+     *
+     * @param  locale  the locale, or {@code null} for the default locale.
+     * @return resources in the given locale.
+     * @throws MissingResourceException if resources cannot be found.
+     */
+    public static Resources forLocale(final Locale locale) {
+        /*
+         * We cannot factorize this method into the parent class, because we 
need to call
+         * `ResourceBundle.getBundle(String)` from the module that provides 
the resources.
+         * We do not cache the result because `ResourceBundle` already 
provides a cache.
+         */
+        return (Resources) getBundle(Resources.class.getName(), 
nonNull(locale));
+    }
+
+    /**
+     * Gets a string for the given key and replaces all occurrence of "{0}"
+     * with value of {@code arg0}.
+     *
+     * @param  key   the key for the desired string.
+     * @param  arg0  value to substitute to "{0}".
+     * @return the formatted string for the given key.
+     * @throws MissingResourceException if no object for the given key can be 
found.
+     */
+    public static String format(final short  key,
+                                final Object arg0) throws 
MissingResourceException
+    {
+        return forLocale(null).getString(key, arg0);
+    }
+
+    /**
+     * The international string to be returned by {@code 
formatInternational(…)} methods.
+     */
+    private static class International extends ResourceInternationalString {
+        /** For cross-version compatibility. */
+        private static final long serialVersionUID = 7140976390544974247L;
+
+        International(final short key, final Object arguments)   {super(key, 
arguments);}
+        @Override protected final KeyConstants getKeyConstants() {return 
Resources.Keys.INSTANCE;}
+        @Override protected final IndexedResourceBundle getBundle(final Locale 
locale) {
+            return forLocale(locale);
+        }
+    }
+
+    /**
+     * Gets an international string for the given key.
+     *
+     * @param  key  the key for the desired string.
+     * @param  arguments  the argument(s) to give to {@code MessageFormat}.
+     * @return an international string for the given key.
+     */
+    public static InternationalString formatInternational(final short key, 
final Object arguments) {
+        return new International(key, arguments);
+    }
+}
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources.properties
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources.properties
new file mode 100644
index 0000000000..44d88c2730
--- /dev/null
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources.properties
@@ -0,0 +1,28 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Resources in this file are for `org.apache.sis.storage.gdal` usage only and 
should not be used by any other module.
+# For resources shared by all modules in the Apache SIS project, see 
"org.apache.sis.util.resources" package.
+#
+AllowedDrivers_1       = Allowed {0} drivers for opening the file.
+CannotInitialize_1     = Cannot initialize {0}.
+FatalLibraryError_1    = A fatal error occurred and {0} should not be used 
anymore in this JVM.
+FunctionNotFound_1     = A function of the {0} library has not been found.
+LibraryNotFound_1      = The {0} library has not been found.
+LibraryUnloaded_1      = The {0} library has been unloaded.
+NativeAccessNotAllowed = Apache SIS has not been authorized to call native 
functions.
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources_en.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources_en.java
new file mode 100644
index 0000000000..018ae8ed55
--- /dev/null
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources_en.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.storage.panama;
+
+
+/**
+ * Resource in English language.
+ */
+public class Resources_en extends Resources {
+    /**
+     * Constructs a new resource bundle loading data from
+     * the resource file of the same name as this class.
+     */
+    public Resources_en() {
+    }
+}
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources_fr.java
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources_fr.java
new file mode 100644
index 0000000000..f98ee4d8aa
--- /dev/null
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources_fr.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.storage.panama;
+
+
+/**
+ * Messages in French language.
+ */
+public class Resources_fr extends Resources {
+    /**
+     * Constructs a new resource bundle loading data from
+     * the resource file of the same name as this class.
+     */
+    public Resources_fr() {
+    }
+}
diff --git 
a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources_fr.properties
 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources_fr.properties
new file mode 100644
index 0000000000..dbaf05b743
--- /dev/null
+++ 
b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/panama/Resources_fr.properties
@@ -0,0 +1,33 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Resources in this file are for `org.apache.sis.storage.gdal` usage only and 
should not be used by any other module.
+# For resources shared by all modules in the Apache SIS project, see 
"org.apache.sis.util.resources" package.
+#
+# Punctuation rules in French (source: 
http://unicode.org/udhr/n/notes_fra.html)
+#
+#   U+202F NARROW NO-BREAK SPACE  before  ; ! and ?
+#   U+00A0 NO-BREAK SPACE         before  :
+#
+AllowedDrivers_1       = Pilotes {0} autoris\u00e9s pour ouvrir le fichier.
+CannotInitialize_1     = Ne peut pas initialiser {0}.
+FatalLibraryError_1    = Une erreur fatale s\u2019est produite et la 
biblioth\u00e8que {0} ne devrait plus \u00eatre utilis\u00e9e dans cette JVM.
+FunctionNotFound_1     = Une fonction de la biblioth\u00e8que {0} n\u2019a pas 
\u00e9t\u00e9 trouv\u00e9e.
+LibraryNotFound_1      = La biblioth\u00e8que {0} n\u2019a pas \u00e9t\u00e9 
trouv\u00e9e.
+LibraryUnloaded_1      = La biblioth\u00e8que {0} a \u00e9t\u00e9 
d\u00e9charg\u00e9e.
+NativeAccessNotAllowed = Apache SIS n\u2019a pas \u00e9t\u00e9 autoris\u00e9 
\u00e0 appeler des fonctions natives.
diff --git 
a/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSF.java
 
b/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSF.java
index fbaa11ff68..1a00375184 100644
--- 
a/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSF.java
+++ 
b/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSF.java
@@ -945,9 +945,9 @@ public class GSF extends NativeFunctions {
      */
     static synchronized GSF global() throws DataStoreException {
         if (globalStatus == null) {
-            load(true).validate();
+            load(true).validate(GSFStoreProvider.NAME);
         }
-        globalStatus.report(null);
+        globalStatus.report(GSFStoreProvider.NAME, null);
         return global;
     }
 
diff --git 
a/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSFStoreProvider.java
 
b/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSFStoreProvider.java
index dd02a3c1c3..4be4cdd695 100644
--- 
a/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSFStoreProvider.java
+++ 
b/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSFStoreProvider.java
@@ -112,9 +112,9 @@ public class GSFStoreProvider extends DataStoreProvider {
      */
     final synchronized GSF GSF() throws DataStoreException {
         if (status == null) {
-            return GSF.global();       // Fetch each time (no cache) because 
may have changed outside this class.
+            return GSF.global();        // Fetch each time (no cache) because 
may have changed outside this class.
         }
-        status.report(null);            // Should never return if 
`nativeFunctions` is null.
+        status.report(NAME, null);      // Should never return if 
`nativeFunctions` is null.
         return nativeFunctions;
     }
 

Reply via email to