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 6d1043d6839d9c534fa565a47e97955dbaaf4abe
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Mon Nov 27 11:59:04 2023 +0100

    When opening files in a folder, inherit the options specified in the parent 
`StorageConnector`.
---
 .../org/apache/sis/storage/StorageConnector.java   | 35 ++++++++++++----
 .../main/org/apache/sis/storage/folder/Store.java  | 46 ++++++++++------------
 .../apache/sis/storage/folder/WritableStore.java   |  5 +--
 3 files changed, 48 insertions(+), 38 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/StorageConnector.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/StorageConnector.java
index 7d48090aee..708d431156 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/StorageConnector.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/StorageConnector.java
@@ -17,6 +17,7 @@
 package org.apache.sis.storage;
 
 import java.util.Map;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.IdentityHashMap;
 import java.util.function.UnaryOperator;
@@ -55,9 +56,11 @@ import org.apache.sis.util.ObjectConverters;
 import org.apache.sis.util.UnconvertibleObjectException;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.internal.Strings;
 import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.collection.TableColumn;
 import org.apache.sis.util.collection.DefaultTreeTable;
+import org.apache.sis.util.collection.Containers;
 import org.apache.sis.storage.internal.Resources;
 import org.apache.sis.storage.base.StoreUtilities;
 import org.apache.sis.io.InvalidSeekException;
@@ -72,7 +75,6 @@ import org.apache.sis.io.stream.InputStreamAdapter;
 import org.apache.sis.io.stream.RewindableLineReader;
 import org.apache.sis.io.stream.InternalOptionKey;
 import org.apache.sis.system.Configuration;
-import org.apache.sis.util.internal.Strings;
 import org.apache.sis.setup.OptionKey;
 
 
@@ -623,15 +625,19 @@ public class StorageConnector implements Serializable {
     }
 
     /**
-     * Returns the option value for the given key, or {@code null} if none.
+     * Creates a new data store connection which has a sub-component of a 
larger data store.
+     * The new storage connector inherits all options that were specified in 
the parent connector.
      *
-     * @param  <T>  the type of option value.
-     * @param  key  the option for which to get the value.
-     * @return the current value for the given option, or {@code null} if none.
+     * @param  parent  the storage connector from which to inherit options.
+     * @param storage  the input/output object as a URL, file, image input 
stream, <i>etc.</i>.
+     *
+     * @since 1.5
      */
-    public <T> T getOption(final OptionKey<T> key) {
-        ArgumentChecks.ensureNonNull("key", key);
-        return key.getValueFrom(options);
+    public StorageConnector(final StorageConnector parent, final Object 
storage) {
+        this(storage);
+        if (!Containers.isNullOrEmpty(parent.options)) {
+            options = new HashMap<>(parent.options);
+        }
     }
 
     /**
@@ -653,6 +659,19 @@ public class StorageConnector implements Serializable {
         options = key.setValueInto(options, value);
     }
 
+    /**
+     * Returns the option value for the given key, or {@code null} if none.
+     * This is the value specified by the last call to a {@code setOption(…)} 
with the given key.
+     *
+     * @param  <T>  the type of option value.
+     * @param  key  the option for which to get the value.
+     * @return the current value for the given option, or {@code null} if none.
+     */
+    public <T> T getOption(final OptionKey<T> key) {
+        ArgumentChecks.ensureNonNull("key", key);
+        return key.getValueFrom(options);
+    }
+
     /**
      * Returns the input/output object given at construction time.
      * The object can be of any type, but the class javadoc lists the most 
typical ones.
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/folder/Store.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/folder/Store.java
index af69ac87f5..f6821a7fd4 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/folder/Store.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/folder/Store.java
@@ -32,6 +32,7 @@ import java.nio.file.Path;
 import java.nio.file.Files;
 import java.nio.file.DirectoryStream;
 import java.nio.file.DirectoryIteratorException;
+import java.nio.file.StandardOpenOption;
 import org.opengis.util.GenericName;
 import org.opengis.util.NameFactory;
 import org.opengis.util.NameSpace;
@@ -99,19 +100,10 @@ class Store extends DataStore implements StoreResource, 
UnstructuredAggregate, D
     private GenericName identifier;
 
     /**
-     * Formatting conventions of dates and numbers, or {@code null} if 
unspecified.
+     * The user-specified connector of the root directory.
+     * Used for inheriting options when creating connector for components.
      */
-    protected final Locale locale;
-
-    /**
-     * Timezone of dates in the data store, or {@code null} if unspecified.
-     */
-    protected final TimeZone timezone;
-
-    /**
-     * Character encoding used by the data store, or {@code null} if 
unspecified.
-     */
-    protected final Charset encoding;
+    protected final StorageConnector configuration;
 
     /**
      * All data stores (including sub-folders) found in the directory 
structure, including the root directory.
@@ -173,12 +165,10 @@ class Store extends DataStore implements StoreResource, 
UnstructuredAggregate, D
             throws DataStoreException, IOException
     {
         super(provider, connector);
-        originator = this;
-        location   = path;
-        locale     = connector.getOption(OptionKey.LOCALE);
-        timezone   = connector.getOption(OptionKey.TIMEZONE);
-        encoding   = connector.getOption(OptionKey.ENCODING);
-        children   = new ConcurrentHashMap<>();
+        configuration = connector;
+        originator    = this;
+        location      = path;
+        children      = new ConcurrentHashMap<>();
         children.put(path.toRealPath(), this);
         componentProvider = format;
     }
@@ -192,10 +182,8 @@ class Store extends DataStore implements StoreResource, 
UnstructuredAggregate, D
      */
     private Store(final Store parent, final StorageConnector connector, final 
NameFactory nameFactory) throws DataStoreException {
         super(parent, parent.getProvider(), connector, false);
+        configuration     = parent.configuration;
         originator        = parent;
-        locale            = connector.getOption(OptionKey.LOCALE);
-        timezone          = connector.getOption(OptionKey.TIMEZONE);
-        encoding          = connector.getOption(OptionKey.ENCODING);
         location          = connector.commit(Path.class, StoreProvider.NAME);
         children          = parent.children;
         componentProvider = parent.componentProvider;
@@ -218,6 +206,9 @@ class Store extends DataStore implements StoreResource, 
UnstructuredAggregate, D
         final String format = StoreUtilities.getFormatName(componentProvider);
         final ParameterValueGroup pg = (provider != null ? 
provider.getOpenParameters() : StoreProvider.PARAMETERS).createValue();
         pg.parameter(DataStoreProvider.LOCATION).setValue(location);
+        Locale   locale   = configuration.getOption(OptionKey.LOCALE);
+        TimeZone timezone = configuration.getOption(OptionKey.TIMEZONE);
+        Charset  encoding = configuration.getOption(OptionKey.ENCODING);
         if (locale   != null) pg.parameter("locale"  ).setValue(locale  );
         if (timezone != null) pg.parameter("timezone").setValue(timezone);
         if (encoding != null) pg.parameter("encoding").setValue(encoding);
@@ -270,7 +261,10 @@ class Store extends DataStore implements StoreResource, 
UnstructuredAggregate, D
         if (metadata == null) {
             final MetadataBuilder mb = new MetadataBuilder();
             mb.addResourceScope(ScopeCode.COLLECTION, 
Resources.formatInternational(Resources.Keys.DirectoryContent_1, 
getDisplayName()));
-            mb.addLanguage(locale, encoding, MetadataBuilder.Scope.RESOURCE);
+            mb.addLanguage(configuration.getOption(OptionKey.LOCALE),
+                           configuration.getOption(OptionKey.ENCODING),
+                           MetadataBuilder.Scope.RESOURCE);
+
             final GenericName identifier = identifier(null);
             String name = null;
             if (identifier != null) {
@@ -320,11 +314,11 @@ class Store extends DataStore implements StoreResource, 
UnstructuredAggregate, D
                          * If the file format is unknown 
(UnsupportedStorageException), we will
                          * check if we can open it as a child folder store 
before to skip it.
                          */
-                        final StorageConnector connector = new 
StorageConnector(candidate);
-                        connector.setOption(OptionKey.LOCALE,   locale);
-                        connector.setOption(OptionKey.TIMEZONE, timezone);
-                        connector.setOption(OptionKey.ENCODING, encoding);
+                        final StorageConnector connector = new 
StorageConnector(configuration, candidate);
                         connector.setOption(DataOptionKey.PARENT_LISTENERS, 
listeners);
+                        connector.setOption(OptionKey.OPEN_OPTIONS, new 
StandardOpenOption[] {
+                            StandardOpenOption.READ         // Restrict to 
read-only mode.
+                        });
                         try {
                             if (componentProvider == null) {
                                 next = DataStores.open(connector);          // 
May throw UnsupportedStorageException.
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/folder/WritableStore.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/folder/WritableStore.java
index 4f4f94a91c..1f9f65e780 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/folder/WritableStore.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/folder/WritableStore.java
@@ -107,10 +107,7 @@ final class WritableStore extends Store implements 
WritableAggregate {
          */
         final Path path = location.resolve(filename);
         if (!children.containsKey(path)) {
-            final StorageConnector connector = new StorageConnector(path);
-            connector.setOption(OptionKey.LOCALE,   locale);
-            connector.setOption(OptionKey.TIMEZONE, timezone);
-            connector.setOption(OptionKey.ENCODING, encoding);
+            final StorageConnector connector = new 
StorageConnector(configuration, path);
             connector.setOption(OptionKey.OPEN_OPTIONS, new 
StandardOpenOption[] {
                 StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE
             });

Reply via email to