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 d94732535a5210151e4c32017a282ede8ffae08f
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Sun Dec 11 15:59:24 2022 +0100

    Resolve some more advanced cases that where identified by a "Pending JDK9" 
comment.
---
 .../java/org/apache/sis/io/wkt/WKTDictionary.java  |  8 +--
 .../sis/internal/system/DefaultFactories.java      | 76 ++++++++++++++------
 .../apache/sis/internal/system/package-info.java   |  2 +-
 .../java/org/apache/sis/util/logging/Logging.java  | 83 ++++++++--------------
 .../sis/internal/storage/xml/AbstractProvider.java | 43 ++++++-----
 .../sis/internal/storage/xml/StoreProvider.java    | 19 ++---
 .../sis/internal/storage/xml/package-info.java     |  2 +-
 .../apache/sis/storage/event/StoreListeners.java   | 26 ++++---
 .../sis/internal/storage/gpx/StoreProvider.java    | 11 +--
 .../sis/internal/storage/gpx/package-info.java     |  2 +-
 .../storage/xml/stream/StaxDataStoreProvider.java  | 12 ++--
 .../internal/storage/xml/stream/package-info.java  |  2 +-
 12 files changed, 144 insertions(+), 142 deletions(-)

diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTDictionary.java 
b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTDictionary.java
index 04268b3420..e7ac6de1f3 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTDictionary.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTDictionary.java
@@ -938,19 +938,13 @@ public class WKTDictionary extends 
GeodeticAuthorityFactory {
                      * Verify if an existing collection (assigned to another 
type) provides the same values.
                      * If we find one, share the same instance for reducing 
memory usage.
                      */
-                    boolean share = false;
                     for (final Set<String> other : codeCaches.values()) {
                         if (codes.equals(other)) {
                             codes = other;
-                            share = true;
                             break;
                         }
                     }
-                    if (!share) {
-                        // TODO: replace by Set.copyOf(Set) in JDK9 and remove 
the `share` flag
-                        // (not needed because Set.copyOf(Set) does the 
verification itself).
-                        codes = CollectionsExt.unmodifiableOrCopy(codes);
-                    }
+                    codes = Set.copyOf(codes);
                     codeCaches.put(type, codes);
                 }
             } finally {
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
 
b/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
index b2ac1610e0..6cf286badc 100644
--- 
a/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
+++ 
b/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
@@ -22,6 +22,7 @@ import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.ServiceLoader;
 import java.util.ServiceConfigurationError;
+import java.util.function.Consumer;
 import org.apache.sis.util.logging.Logging;
 
 import static java.util.logging.Logger.getLogger;
@@ -34,7 +35,7 @@ import static java.util.logging.Logger.getLogger;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Guilhem Legal (Geomatys)
- * @version 1.2
+ * @version 1.4
  *
  * @see <a href="https://jcp.org/en/jsr/detail?id=330";>JSR-330</a>
  *
@@ -207,33 +208,62 @@ public final class DefaultFactories extends 
SystemListener {
      * @since 0.8
      */
     public static ClassLoader getContextClassLoader() throws SecurityException 
{
-        final Thread thread = Thread.currentThread();
-        ClassLoader loader = thread.getContextClassLoader();
-        final Set<ClassLoader> parents = new HashSet<>();
-        for (ClassLoader c = loader; c != null; c = c.getParent()) {
-            parents.add(c);
+        final Walker walker = new Walker();
+        return 
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).walk((stream)
 -> {
+            stream.forEach(walker);
+            return walker.loader;
+        });
+    }
+
+    /**
+     * Action to be executed for each stack frame inspected by {@link 
#getContextClassLoader()}.
+     * The action is initialized to the context class loader of current thread.
+     * Then it checks if the class loader should be replaced by another one 
containing at least
+     * the Apache SIS class loader.
+     */
+    private static final class Walker implements 
Consumer<StackWalker.StackFrame> {
+        /**
+         * The context class loader to be returned by {@link 
#getContextClassLoader()}.
+         */
+        ClassLoader loader;
+
+        /**
+         * All parents of {@link #loader}.
+         */
+        private final Set<ClassLoader> parents;
+
+        /**
+         * Creates a new walker initialized to the context class loader of 
current thread.
+         */
+        Walker() {
+            parents = new HashSet<>();
+            setClassLoader(Thread.currentThread().getContextClassLoader());
         }
-        boolean warnings = false;
-        for (final StackTraceElement trace : thread.getStackTrace()) {      // 
TODO: replace by StackWalker in JDK9.
-            final String element = trace.getClassName();
-            if (element.startsWith(Modules.CLASSNAME_PREFIX)) try {
-                ClassLoader c = Class.forName(element).getClassLoader();
+
+        /**
+         * Set the class loader to the given value, which may be null.
+         */
+        private void setClassLoader(ClassLoader c) {
+            loader = c;
+            while (c != null) {
+                parents.add(c);
+                c = c.getParent();
+            }
+        }
+
+        /**
+         * If the given stack frame is an Apache SIS method, ensures that 
{@link #loader}
+         * is the SIS class loader or has the SIS class loader as a parent.
+         */
+        @Override
+        public void accept(final StackWalker.StackFrame frame) {
+            if (frame.getClassName().startsWith(Modules.CLASSNAME_PREFIX)) {
+                ClassLoader c = frame.getDeclaringClass().getClassLoader();
                 if (!parents.contains(c)) {
-                    loader = c;
                     parents.clear();
-                    while (c != null) {
-                        parents.add(c);
-                        c = c.getParent();
-                    }
-                }
-            } catch (SecurityException | ClassNotFoundException e) {
-                if (!warnings) {
-                    warnings = true;
-                    Logging.recoverableException(getLogger(Loggers.SYSTEM),
-                            DefaultFactories.class, "getContextClassLoader", 
e);
+                    setClassLoader(c);
                 }
             }
         }
-        return loader;
     }
 }
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/internal/system/package-info.java
 
b/core/sis-utility/src/main/java/org/apache/sis/internal/system/package-info.java
index 88db831943..f9f5e0586e 100644
--- 
a/core/sis-utility/src/main/java/org/apache/sis/internal/system/package-info.java
+++ 
b/core/sis-utility/src/main/java/org/apache/sis/internal/system/package-info.java
@@ -24,7 +24,7 @@
  * may change in incompatible ways in any future version without notice.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  * @module
  */
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java 
b/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
index 11d77db468..d7c3b8f361 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
@@ -16,9 +16,12 @@
  */
 package org.apache.sis.util.logging;
 
+import java.util.Arrays;
+import java.util.stream.Stream;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.logging.LogRecord;
+import java.lang.reflect.Modifier;
 
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Static;
@@ -40,7 +43,7 @@ import org.apache.sis.internal.system.Modules;
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  * @module
  */
@@ -102,7 +105,7 @@ public final class Logging extends Static {
      * @param  method  the method to report as the source of the logging 
message.
      * @param  record  the record to log.
      */
-    public static void log(final Class<?> classe, String method, final 
LogRecord record) {
+    public static void log(final Class<?> classe, final String method, final 
LogRecord record) {
         ArgumentChecks.ensureNonNull("record", record);
         final String loggerName = record.getLoggerName();
         Logger logger;
@@ -120,8 +123,11 @@ public final class Logging extends Static {
              * If the given class or method is null, infer them from stack 
trace. We do not document this feature
              * in public API because the rules applied here are heuristic and 
may change in any future SIS version.
              */
-            logger = inferCaller(logger, (classe != null) ? 
classe.getCanonicalName() : null,
-                            method, Thread.currentThread().getStackTrace(), 
record);
+            final Logger fl = logger;       // Because lambda functions 
require final values.
+            logger = 
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).walk((stream)
 ->
+                    inferCaller(fl, (classe != null) ? 
classe.getCanonicalName() : null, method,
+                            stream.filter((frame) -> 
Modifier.isPublic(frame.getDeclaringClass().getModifiers()))
+                                  
.map((StackWalker.StackFrame::toStackTraceElement)), record));
         }
         logger.log(record);
     }
@@ -131,6 +137,9 @@ public final class Logging extends Static {
      * This method inspects the given stack trace, skips what looks like 
internal API based on heuristic rules, then
      * if some arguments are non-null tries to match them.
      *
+     * <p>This method should be invoked only if at least one of {@code 
logger}, {@code classe} or {@code method}
+     * is null.</p>
+     *
      * @param  logger  where the log record will be sent after this method 
call, or {@code null} if unknown.
      * @param  classe  the name of the class to report in the log record, or 
{@code null} if unknown.
      * @param  method  the name of the method to report in the log record, or 
{@code null} if unknown.
@@ -138,61 +147,31 @@ public final class Logging extends Static {
      * @param  record  the record where to set the class and method names.
      * @return the record to use for logging the record.
      */
-    private static Logger inferCaller(Logger logger, String classe, String 
method,
-            final StackTraceElement[] trace, final LogRecord record)
+    private static Logger inferCaller(Logger logger, final String classe, 
final String method,
+            final Stream<StackTraceElement> trace, final LogRecord record)
     {
-        for (final StackTraceElement element : trace) {
+        final StackTraceElement first = trace.filter((element) -> {
             /*
-             * Search for the first stack trace element with a classname 
matching the expected one.
-             * We compare against the name of the class given in argument if 
it was non-null.
+             * Search for the first stack trace element with a class name and 
method name matching the expected ones.
+             * Null argument (class or method name) will not be compared (i.e. 
any name is accepted).
              *
              * Note: a previous version also compared logger name with package 
name.
              * This has been removed because those names are only loosely 
related.
              */
-            final String classname = element.getClassName();
-            if (classe != null) {
-                if (!classname.equals(classe)) {
-                    continue;
-                }
-            } else if (!isPublic(element)) {
-                continue;
-            }
-            /*
-             * Now that we have a stack trace element from the expected class 
(or any
-             * element if we don't know the class), make sure that we have the 
right method.
-             */
-            final String methodName = element.getMethodName();
-            if (method != null && !methodName.equals(method)) {
-                continue;
-            }
-            /*
-             * Now computes every values that are null, and stop the loop.
-             */
-            if (logger == null) {
+            return ((classe != null) ?  classe.equals(element.getClassName()) 
: isPublic(element)) &&
+                   ((method == null) || 
method.equals(element.getMethodName()));
+        }).findFirst().orElse(null);
+        if (logger == null) {
+            String name = Logger.GLOBAL_LOGGER_NAME;
+            if (first != null) {
+                final String classname = first.getClassName();
                 final int separator = classname.lastIndexOf('.');
-                logger = Logger.getLogger((separator >= 1) ? 
classname.substring(0, separator-1) : "");
-            }
-            if (classe == null) {
-                classe = classname;
-            }
-            if (method == null) {
-                method = methodName;
+                name = (separator >= 1) ? classname.substring(0, separator-1) 
: "";
             }
-            break;
-        }
-        /*
-         * The logger may stay null if we have been unable to find a suitable 
stack trace.
-         * Fallback on the global logger.
-         */
-        if (logger == null) {
-            logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
-        }
-        if (classe != null) {
-            record.setSourceClassName(classe);
-        }
-        if (method != null) {
-            record.setSourceMethodName(method);
+            logger = Logger.getLogger(name);
         }
+        if (classe != null || first != null) record.setSourceClassName (first 
== null ? classe : first.getClassName());
+        if (method != null || first != null) record.setSourceMethodName(first 
== null ? method : first.getMethodName());
         return logger;
     }
 
@@ -217,7 +196,7 @@ public final class Logging extends Static {
         if (classname.startsWith(Modules.CLASSNAME_PREFIX + "util.logging.")) {
             return classname.endsWith("Test");      // Consider JUnit tests as 
public.
         }
-        return true;    // TODO: with StackWalker on JDK9, check if the class 
is public.
+        return true;
     }
 
     /**
@@ -308,7 +287,7 @@ public final class Logging extends Static {
             record.setThrown(error);
         }
         if (logger == null || classe == null || method == null) {
-            logger = inferCaller(logger, classe, method, 
error.getStackTrace(), record);
+            logger = inferCaller(logger, classe, method, 
Arrays.stream(error.getStackTrace()), record);
         } else {
             record.setSourceClassName(classe);
             record.setSourceMethodName(method);
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java
index 0af607b10b..6588e2ea90 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/AbstractProvider.java
@@ -17,7 +17,6 @@
 package org.apache.sis.internal.storage.xml;
 
 import java.util.Map;
-import java.util.HashMap;
 import java.io.Reader;
 import java.io.IOException;
 import java.nio.ByteBuffer;
@@ -35,7 +34,7 @@ import 
org.apache.sis.internal.storage.DocumentedStoreProvider;
  * (JAXB, StAX, <i>etc</i>).
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.8
  * @module
  */
@@ -58,17 +57,15 @@ public abstract class AbstractProvider extends 
DocumentedStoreProvider {
     private static final byte[] HEADER = {'<','?','x','m','l',' '};
 
     /**
-     * The mapping from XML namespaces to MIME types. This map shall be 
populated by subclasses
-     * at construction time, then never modified anymore since we do not 
synchronize it.
+     * The mapping from XML namespaces to MIME types.
      *
-     * <div class="note"><b>Example</b>
-     * public MyDataStore() {
-     *     mimeForNameSpaces.put("http://www.opengis.net/gml/3.2";,        
"application/gml+xml");
-     *     mimeForNameSpaces.put("http://www.isotc211.org/2005/gmd";,      
"application/vnd.iso.19139+xml");
-     *     mimeForNameSpaces.put("http://www.opengis.net/cat/csw/2.0.2";,  
"application/vnd.ogc.csw_xml");
-     * }</div>
-     *
-     * @todo replace by {@code Map.of(…)} on JDK9 branch.
+     * <table class="sis">
+     *   <caption>Example</caption>
+     *   <tr><th>Key</th>                                  <th>Value</th></tr>
+     *   <tr><td>http://www.opengis.net/gml/3.2</td>       
<td>application/gml+xml</td></tr>
+     *   <tr><td>http://www.isotc211.org/2005/gmd</td>     
<td>application/vnd.iso.19139+xml</td></tr>
+     *   <tr><td>http://www.opengis.net/cat/csw/2.0.2</td> 
<td>application/vnd.ogc.csw_xml</td></tr>
+     * </table>
      */
     protected final Map<String,String> mimeForNameSpaces;
 
@@ -76,25 +73,25 @@ public abstract class AbstractProvider extends 
DocumentedStoreProvider {
      * The mapping from root elements to MIME types. Used only if the root 
element is in
      * the default namespace and contains no {@code xmlns} attributes for that 
namespace.
      *
-     * <div class="note"><b>Example</b>
-     * public MyDataStore() {
-     *     mimeForRootElements.put("MD_Metadata", 
"application/vnd.iso.19139+xml");
-     * }</div>
-     *
-     * @todo replace by {@code Map.of(…)} on JDK9 branch.
+     * <table class="sis">
+     *   <caption>Example</caption>
+     *   <tr><th>Key</th>         <th>Value</th></tr>
+     *   <tr><td>MD_Metadata</td> <td>application/vnd.iso.19139+xml</td></tr>
+     * </table>
      */
     protected final Map<String,String> mimeForRootElements;
 
     /**
-     * Creates a new provider. Subclasses shall populate the {@link 
#mimeForNameSpaces} map with a mapping
-     * from their namespace to the MIME type to declare.
+     * Creates a new provider.
      *
      * @param  name  the primary key to use for searching in the {@code 
MD_Format} table, or {@code null} if none.
+     * @param  mimeForNameSpaces    the mapping from XML namespaces to MIME 
type.
+     * @param  mimeForRootElements  the mapping from root elements to MIME 
types, used only as a fallback.
      */
-    protected AbstractProvider(final String name) {
+    protected AbstractProvider(final String name, final Map<String,String> 
mimeForNameSpaces, final Map<String,String> mimeForRootElements) {
         super(name);
-        mimeForNameSpaces   = new HashMap<>();
-        mimeForRootElements = new HashMap<>();
+        this.mimeForNameSpaces   = mimeForNameSpaces;
+        this.mimeForRootElements = mimeForRootElements;
     }
 
     /**
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
index 1f1c96d6d3..1ce9dafc70 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/StoreProvider.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.storage.xml;
 
+import java.util.Map;
 import org.apache.sis.xml.Namespaces;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
@@ -29,7 +30,7 @@ import org.apache.sis.internal.storage.Capability;
  * The provider of {@link Store} instances.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.4
  * @module
  */
@@ -46,14 +47,14 @@ public final class StoreProvider extends AbstractProvider {
      * Creates a new provider.
      */
     public StoreProvider() {
-        super(null);
-        mimeForNameSpaces.put(      Namespaces.GML,       
"application/gml+xml");
-        mimeForNameSpaces.put(      Namespaces.CSW,       
"application/vnd.ogc.csw_xml");
-        mimeForNameSpaces.put(LegacyNamespaces.CSW,       
"application/vnd.ogc.csw_xml");
-        mimeForNameSpaces.put(LegacyNamespaces.GMD,       
"application/vnd.iso.19139+xml");
-        mimeForNameSpaces.put(LegacyNamespaces.GMI,       
"application/vnd.iso.19139+xml");
-        mimeForNameSpaces.put(LegacyNamespaces.GMI_ALIAS, 
"application/vnd.iso.19139+xml");
-        mimeForRootElements.put("MD_Metadata",            
"application/vnd.iso.19139+xml");
+        super(null,
+              Map.of(      Namespaces.GML,       "application/gml+xml",
+                           Namespaces.CSW,       "application/vnd.ogc.csw_xml",
+                     LegacyNamespaces.CSW,       "application/vnd.ogc.csw_xml",
+                     LegacyNamespaces.GMD,       
"application/vnd.iso.19139+xml",
+                     LegacyNamespaces.GMI,       
"application/vnd.iso.19139+xml",
+                     LegacyNamespaces.GMI_ALIAS, 
"application/vnd.iso.19139+xml"),
+              Map.of("MD_Metadata",              
"application/vnd.iso.19139+xml"));
         // More types to be added in future versions.
     }
 
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/package-info.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/package-info.java
index c1890634b9..57e5e08529 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/package-info.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/package-info.java
@@ -26,7 +26,7 @@
  * the {@code sis-xmlstore} module extends this package with classes designed 
for use with StAX cursor API.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.4
  * @module
  */
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java
index 804badd303..b18e51ae6e 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/storage/event/StoreListeners.java
@@ -483,28 +483,26 @@ public class StoreListeners implements Localized {
      */
     public void warning(final Level level, String message, final Exception 
exception) {
         ArgumentChecks.ensureNonNull("level", level);
-        final LogRecord record;
-        final StackTraceElement[] trace;
-        if (exception != null) {
-            trace = exception.getStackTrace();
+        if (exception == null) {
+            ArgumentChecks.ensureNonEmpty("message", message);
+        } else {
             message = Exceptions.formatChainedMessages(getLocale(), message, 
exception);
             if (message == null) {
                 message = exception.toString();
             }
-            record = new LogRecord(level, message);
-            record.setThrown(exception);
-        } else {
-            ArgumentChecks.ensureNonEmpty("message", message);
-            trace = Thread.currentThread().getStackTrace();         // TODO: 
on JDK9, use StackWalker instead.
-            record = new LogRecord(level, message);
         }
-        try {
-            for (final StackTraceElement e : trace) {
+        final LogRecord record = new LogRecord(level, message);
+        if (exception == null) {
+           
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).walk((stream)
 -> stream.filter(
+                   (frame) -> setPublicSource(record, 
frame.getDeclaringClass(), frame.getMethodName())).findFirst());
+         } else try {
+            record.setThrown(exception);
+            for (final StackTraceElement e : exception.getStackTrace()) {
                 if (setPublicSource(record, Class.forName(e.getClassName()), 
e.getMethodName())) {
                     break;
                 }
             }
-        } catch (ClassNotFoundException | SecurityException e) {
+        } catch (ClassNotFoundException e) {
             Logging.ignorableException(StoreUtilities.LOGGER, 
StoreListeners.class, "warning", e);
         }
         warning(record, StoreUtilities.removeStackTraceInLogs());
@@ -512,7 +510,7 @@ public class StoreListeners implements Localized {
 
     /**
      * Eventually sets the class name and method name in the given record,
-     * and returns {@code true} if the method is public resource method.
+     * and returns {@code true} if the method is a public resource method.
      *
      * @param  record      the record where to set the source class/method 
name.
      * @param  type        the source class. This method does nothing if the 
class is not a {@link Resource}.
diff --git 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
index 6595a46bcb..eaf053596e 100644
--- 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
+++ 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/StoreProvider.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.storage.gpx;
 
+import java.util.Map;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import org.apache.sis.storage.DataStore;
@@ -35,7 +36,7 @@ import org.apache.sis.util.Version;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.8
  * @module
  */
@@ -68,10 +69,10 @@ public final class StoreProvider extends 
StaxDataStoreProvider {
      * Creates a new GPX store provider.
      */
     public StoreProvider() {
-        super("GPX");
-        mimeForNameSpaces.put(Tags.NAMESPACE_V10, "application/gpx+xml");
-        mimeForNameSpaces.put(Tags.NAMESPACE_V11, "application/gpx+xml");
-        mimeForRootElements.put("gpx", "application/gpx+xml");
+        super("GPX",
+              Map.of(Tags.NAMESPACE_V10, "application/gpx+xml",
+                     Tags.NAMESPACE_V11, "application/gpx+xml"),
+              Map.of("gpx",              "application/gpx+xml"));
     }
 
     /**
diff --git 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/package-info.java
 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/package-info.java
index 0ef4f26ff1..8fbb0f7ce1 100644
--- 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/package-info.java
+++ 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/package-info.java
@@ -56,7 +56,7 @@
  * </ul>
  *
  * @author  Johann Sorel (Geomatys)
- * @version 1.3
+ * @version 1.4
  *
  * @see <a href="https://en.wikipedia.org/wiki/GPS_Exchange_Format";>GPS 
Exchange Format on Wikipedia</a>
  * @see <a href="http://www.topografix.com/GPX/1/1/";>GPX 1.1 Schema 
Documentation</a>
diff --git 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/StaxDataStoreProvider.java
 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/StaxDataStoreProvider.java
index d83aa89851..7cc40d5490 100644
--- 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/StaxDataStoreProvider.java
+++ 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/StaxDataStoreProvider.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.storage.xml.stream;
 
+import java.util.Map;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import org.apache.sis.xml.MarshallerPool;
@@ -27,7 +28,7 @@ import org.apache.sis.internal.storage.xml.AbstractProvider;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.4
  * @since   0.8
  * @module
  */
@@ -40,13 +41,14 @@ public abstract class StaxDataStoreProvider extends 
AbstractProvider {
     private volatile MarshallerPool jaxb;
 
     /**
-     * Creates a new provider. Subclasses shall populate the {@link 
#mimeForNameSpaces}
-     * map with a mapping from their namespace to the MIME type to declare.
+     * Creates a new provider.
      *
      * @param  name  the primary key to use for searching in the {@code 
MD_Format} table, or {@code null} if none.
+     * @param  mimeForNameSpaces    the mapping from XML namespaces to MIME 
type.
+     * @param  mimeForRootElements  the mapping from root elements to MIME 
types, used only as a fallback.
      */
-    protected StaxDataStoreProvider(final String name) {
-        super(name);
+    protected StaxDataStoreProvider(final String name, final 
Map<String,String> mimeForNameSpaces, final Map<String,String> 
mimeForRootElements) {
+        super(name, mimeForNameSpaces, mimeForRootElements);
     }
 
     /**
diff --git 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/package-info.java
 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/package-info.java
index 20f295c0f6..7899d86ebb 100644
--- 
a/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/package-info.java
+++ 
b/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/package-info.java
@@ -24,7 +24,7 @@
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.8
  * @module
  */

Reply via email to