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 2026/05/26 13:22:22 UTC
(sis) branch geoapi-4.0 updated (b5bad671d8 -> 1f95591ce4)
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a change to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
from b5bad671d8 Remove the `SecondaryTrait` internal annotation and use the information provided by the `getStandardType()` method instead.
new 6d513dd481 Remove `DataStoreProvider.TIMEZONE` because that parameter is optional while `DataStoreProvider` should declare only essential parameters.
new 1f95591ce4 Remove unused `StoreUtilities` method and move URI-related method to `URIDataStoreProvider`.
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/console/OperationParser.java | 2 +-
.../apache/sis/storage/landsat/LandsatStore.java | 4 +-
.../sis/storage/landsat/LandsatStoreProvider.java | 4 +-
.../apache/sis/storage/geotiff/GeoTiffStore.java | 6 +-
.../sis/storage/geotiff/GeoTiffStoreProvider.java | 13 +-
.../org/apache/sis/storage/netcdf/NetcdfStore.java | 4 +-
.../sis/storage/netcdf/NetcdfStoreProvider.java | 10 +-
.../sis/storage/netcdf/classic/VariableInfo.java | 4 +-
.../org/apache/sis/storage/gpx/StoreProvider.java | 16 +-
.../storage/xml/stream/StaxDataStoreProvider.java | 8 +-
.../main/org/apache/sis/storage/DataStore.java | 27 +-
.../org/apache/sis/storage/DataStoreProvider.java | 32 +-
.../org/apache/sis/storage/StorageConnector.java | 1 +
.../org/apache/sis/storage/base/PRJDataStore.java | 100 ++----
.../apache/sis/storage/base/StoreUtilities.java | 155 ++-------
.../org/apache/sis/storage/base/URIDataStore.java | 96 ++++--
.../sis/storage/base/URIDataStoreOption.java | 367 +++++++++++++++++++++
.../sis/storage/base/URIDataStoreProvider.java | 178 ++++------
.../main/org/apache/sis/storage/csv/Store.java | 27 +-
.../org/apache/sis/storage/csv/StoreProvider.java | 69 ++--
.../apache/sis/storage/esri/AsciiGridStore.java | 7 +-
.../sis/storage/esri/AsciiGridStoreProvider.java | 7 +-
.../org/apache/sis/storage/esri/RasterStore.java | 6 +-
.../apache/sis/storage/esri/RawRasterStore.java | 2 +-
.../sis/storage/esri/RawRasterStoreProvider.java | 7 +-
.../main/org/apache/sis/storage/folder/Store.java | 42 +--
.../apache/sis/storage/folder/StoreProvider.java | 90 ++---
.../apache/sis/storage/folder/WritableStore.java | 10 +-
.../sis/storage/image/WorldFileStoreProvider.java | 9 +-
.../org/apache/sis/storage/internal/Resources.java | 7 +-
.../sis/storage/internal/Resources.properties | 3 +-
.../sis/storage/internal/Resources_fr.properties | 3 +-
.../main/org/apache/sis/storage/wkt/Store.java | 10 +-
.../org/apache/sis/storage/wkt/StoreFormat.java | 2 +-
.../org/apache/sis/storage/wkt/StoreProvider.java | 63 ++--
.../apache/sis/storage/xml/AbstractProvider.java | 13 +-
.../org/apache/sis/storage/xml/StoreProvider.java | 2 +-
.../sis/storage/base/StoreUtilitiesTest.java | 15 +-
...tiesTest.java => URIDataStoreProviderTest.java} | 20 +-
.../test/org/apache/sis/storage/csv/StoreTest.java | 3 +-
.../org/apache/sis/storage/folder/StoreTest.java | 2 +-
.../apache/sis/storage/wkt/StoreProviderTest.java | 6 +-
.../storage/coveragejson/CoverageJsonStore.java | 4 +-
.../coveragejson/CoverageJsonStoreProvider.java | 5 +-
.../apache/sis/storage/geoheif/GeoHeifStore.java | 4 +-
.../sis/storage/geoheif/GeoHeifStoreProvider.java | 9 +-
.../sis/storage/geopackage/GpkgStoreProvider.java | 7 +-
.../main/org/apache/sis/storage/gsf/GSFStore.java | 6 +-
.../apache/sis/storage/gsf/GSFStoreProvider.java | 25 +-
.../sis/storage/shapefile/ShapefileProvider.java | 45 +--
.../sis/storage/shapefile/ShapefileStore.java | 70 ++--
.../sis/storage/shapefile/ShapefileStoreTest.java | 27 +-
.../org/apache/sis/storage/shapefile/Snippets.java | 7 +-
.../org/apache/sis/gui/dataset/PathAction.java | 43 ++-
.../org/apache/sis/gui/dataset/ResourceCell.java | 3 +-
.../org/apache/sis/storage/gdal/GDALStore.java | 4 +-
.../apache/sis/storage/gdal/GDALStoreProvider.java | 7 +-
57 files changed, 928 insertions(+), 790 deletions(-)
create mode 100644 endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreOption.java
copy endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/base/{StoreUtilitiesTest.java => URIDataStoreProviderTest.java} (63%)
(sis) 02/02: Remove unused `StoreUtilities` method and move URI-related method to `URIDataStoreProvider`.
Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
commit 1f95591ce47849b74149c9453afb789eb2e35e55
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue May 26 15:12:09 2026 +0200
Remove unused `StoreUtilities` method and move URI-related method to `URIDataStoreProvider`.
---
.../sis/storage/netcdf/classic/VariableInfo.java | 4 +-
.../apache/sis/storage/base/StoreUtilities.java | 155 ++++-----------------
.../sis/storage/base/URIDataStoreProvider.java | 20 +++
.../sis/storage/base/StoreUtilitiesTest.java | 15 +-
...tiesTest.java => URIDataStoreProviderTest.java} | 20 +--
5 files changed, 67 insertions(+), 147 deletions(-)
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/classic/VariableInfo.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/classic/VariableInfo.java
index 4e12b8380e..249d4ea4ca 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/classic/VariableInfo.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/classic/VariableInfo.java
@@ -43,7 +43,7 @@ import org.apache.sis.storage.netcdf.base.Grid;
import org.apache.sis.storage.netcdf.base.Variable;
import org.apache.sis.storage.netcdf.base.GridAdjustment;
import org.apache.sis.storage.netcdf.internal.Resources;
-import org.apache.sis.storage.base.StoreUtilities;
+import org.apache.sis.storage.base.URIDataStoreProvider;
import org.apache.sis.io.stream.ChannelDataInput;
import org.apache.sis.io.stream.HyperRectangleReader;
import org.apache.sis.io.stream.Region;
@@ -786,7 +786,7 @@ final class VariableInfo extends Variable implements Comparable<VariableInfo> {
final String[] strings = new String[count];
int lower = 0;
String previous = ""; // For sharing same `String` instances when same value is repeated.
- if (StoreUtilities.basedOnASCII(encoding)) {
+ if (URIDataStoreProvider.basedOnASCII(encoding)) {
int plo = 0, phi = 0; // Index range of bytes used for building the previous string.
for (int i=0; i<count; i++) {
String element = "";
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/StoreUtilities.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/StoreUtilities.java
index ae1e8f1dc9..f4975053e4 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/StoreUtilities.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/StoreUtilities.java
@@ -16,21 +16,14 @@
*/
package org.apache.sis.storage.base;
-import java.util.Set;
-import java.util.EnumSet;
import java.util.Optional;
import java.util.stream.Stream;
import java.util.logging.Filter;
import java.util.logging.Logger;
import java.util.logging.LogRecord;
-import java.nio.file.OpenOption;
-import java.nio.file.StandardOpenOption;
-import java.nio.charset.Charset;
import org.opengis.util.GenericName;
import org.opengis.geometry.Envelope;
import org.opengis.metadata.Metadata;
-import org.opengis.metadata.extent.Extent;
-import org.opengis.metadata.extent.GeographicExtent;
import org.opengis.metadata.extent.GeographicBoundingBox;
import org.opengis.metadata.identification.Identification;
import org.opengis.metadata.identification.DataIdentification;
@@ -49,6 +42,7 @@ import org.apache.sis.storage.event.StoreListeners;
import org.apache.sis.storage.internal.Resources;
import org.apache.sis.geometry.GeneralEnvelope;
import org.apache.sis.metadata.internal.shared.Identifiers;
+import org.apache.sis.metadata.iso.extent.Extents;
import org.apache.sis.system.Configuration;
import org.apache.sis.system.Modules;
import org.apache.sis.util.resources.Errors;
@@ -59,8 +53,11 @@ import org.opengis.feature.Feature;
/**
* Utility methods related to {@link DataStore}s, {@link DataStoreProvider}s and {@link Resource}s.
- * This is not a committed API; any method in this class may change in any future Apache SIS version.
- * Some methods may also move in public API if we feel confident enough.
+ * This is not a committed <abbr>API</abbr>: any method in this class may change in any future version.
+ * Some methods may also move in public <abbr>API</abbr> if we feel confident enough.
+ *
+ * <p>This class contains methods applicable to any data stores, including <abbr>SQL</abbr>-based data stores.
+ * For utility methods more specifically for data stores that open a file, see {@link URIDataStoreProvider}.</p>
*
* @author Martin Desruisseaux (Geomatys)
*/
@@ -90,16 +87,27 @@ public final class StoreUtilities {
public static final Logger LOGGER = Logger.getLogger(Modules.STORAGE);
/**
- * Names of encoding where bytes less than 128 can be interpreted as ASCII.
- *
- * @see #basedOnASCII(Charset)
+ * Do not allow instantiation of this class.
*/
- private static final Set<String> basedOnASCII = Set.of("US-ASCII", "ISO-8859-1", "UTF-8");
+ private StoreUtilities() {
+ }
/**
- * Do not allow instantiation of this class.
+ * Returns a provider for the given format name.
+ *
+ * @param format name of the format for which to get a provider.
+ * @return first provider found for the given format name.
+ * @throws UnsupportedStorageException if no provider is found for the specified format.
+ *
+ * @see StoreMetadata#formatName()
*/
- private StoreUtilities() {
+ public static DataStoreProvider providerByFormatName(final String format) throws UnsupportedStorageException {
+ for (DataStoreProvider provider : DataStores.providers()) {
+ if (format.equalsIgnoreCase(getFormatName(provider))) {
+ return provider;
+ }
+ }
+ throw new UnsupportedStorageException(Errors.format(Errors.Keys.UnsupportedFormat_1, format));
}
/**
@@ -185,7 +193,8 @@ public final class StoreUtilities {
/**
* Returns the spatiotemporal envelope of the given metadata.
- * This method computes the union of all {@link GeographicBoundingBox} in the metadata, assuming the
+ * This method computes the union of all {@link GeographicBoundingBox} instances
+ * in the given metadata and returns the result as an envelope in the
* {@linkplain org.apache.sis.referencing.CommonCRS#defaultGeographic() default geographic CRS}
* (usually WGS 84).
*
@@ -193,24 +202,8 @@ public final class StoreUtilities {
* @return the spatiotemporal extent, or {@code null} if none.
*/
public static Envelope getEnvelope(final Metadata metadata) {
- GeneralEnvelope bounds = null;
- if (metadata != null) {
- for (final Identification identification : metadata.getIdentificationInfo()) {
- for (final Extent extent : identification.getExtents()) {
- for (final GeographicExtent ge : extent.getGeographicElements()) {
- if (ge instanceof GeographicBoundingBox) {
- final GeneralEnvelope env = new GeneralEnvelope((GeographicBoundingBox) ge);
- if (bounds == null) {
- bounds = env;
- } else {
- bounds.add(env);
- }
- }
- }
- }
- }
- }
- return bounds;
+ final GeographicBoundingBox bbox = Extents.getGeographicBoundingBox(metadata);
+ return (bbox != null) ? new GeneralEnvelope(bbox) : null;
}
/**
@@ -223,7 +216,7 @@ public final class StoreUtilities {
public static Class<? extends Resource> getInterface(final Class<? extends Resource> implementation) {
final Class<? extends Resource>[] types = Classes.getLeafInterfaces(implementation, Resource.class);
Class<? extends Resource> type = null;
- for (int i=types.length; --i >= 0;) {
+ for (int i = types.length; --i >= 0;) {
type = types[i];
if (FeatureSet.class.isAssignableFrom(type)) break; // Arbitrary precedence rule.
}
@@ -255,6 +248,7 @@ public final class StoreUtilities {
* @return whether the data store has write capability, or {@code null} if it cannot be determined.
*
* @see StoreMetadata#capabilities()
+ * @see URIDataStoreProvider#isWritable(StorageConnector, boolean)
*/
public static Boolean canWrite(final Class<? extends DataStoreProvider> provider) {
if (provider != null) {
@@ -266,97 +260,6 @@ public final class StoreUtilities {
return null;
}
- /**
- * Converts the given sequence of options into a simplified set of standard options.
- * The returned set can contain combinations of
- * {@link StandardOpenOption#WRITE},
- * {@link StandardOpenOption#CREATE CREATE},
- * {@link StandardOpenOption#CREATE_NEW CREATE_NEW} and
- * {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}.
- * If the set is empty, then the data store should be read-only.
- * If both {@code TRUNCATE_EXISTING} and {@code CREATE_NEW} are specified,
- * then {@code CREATE_NEW} has precedence.
- * More specifically:
- *
- * <p>{@link StandardOpenOption#WRITE}<br>
- * means that the {@link DataStore} should be opened as writable resource.</p>
- *
- * <p>{@link StandardOpenOption#CREATE}<br>
- * means that the {@link DataStore} is allowed to create new files.
- * If this option is present, then {@code WRITE} is also present.
- * If this option is absent, then writable data stores should not create any new file.
- * This flag can be tested as below (this cover both the read-only case and the writable
- * case where the files must exist):</p>
- *
- * {@snippet lang="java" :
- * if (!options.contains(StandardOpenOption.CREATE)) {
- * // Throw an exception if the file does not exist.
- * }
- * }
- *
- * <p>{@link StandardOpenOption#CREATE_NEW}<br>
- * means that the {@link DataStore} should fail to open if the file already exists.
- * This mode is used when creating new writable resources, for making sure that we
- * do not modify existing resources.
- * If this option is present, then {@code WRITE} and {@code CREATE} are also present.</p>
- *
- * <p>{@link StandardOpenOption#TRUNCATE_EXISTING}<br>
- * means that the {@link DataStore} should overwrite the content of any pre-existing resources.
- * If this option is present, then {@code WRITE} and {@code CREATE} are also present.</p>
- *
- * @param options the open options, or {@code null}.
- * @return the open options as a bitmask.
- */
- @SuppressWarnings("fallthrough")
- public static EnumSet<StandardOpenOption> toStandardOptions(final OpenOption[] options) {
- final EnumSet<StandardOpenOption> set = EnumSet.noneOf(StandardOpenOption.class);
- if (options != null) {
- for (final OpenOption op : options) {
- if (op instanceof StandardOpenOption) {
- switch ((StandardOpenOption) op) { // Fallthrough in every cases.
- case CREATE_NEW: set.add(StandardOpenOption.CREATE_NEW);
- case TRUNCATE_EXISTING: set.add(StandardOpenOption.TRUNCATE_EXISTING);
- case CREATE: set.add(StandardOpenOption.CREATE);
- case APPEND: case WRITE: set.add(StandardOpenOption.WRITE);
- }
- }
- }
- if (set.contains(StandardOpenOption.CREATE_NEW)) {
- set.remove(StandardOpenOption.TRUNCATE_EXISTING);
- }
- }
- return set;
- }
-
- /**
- * Returns {@code true} if a sequence of bytes in the given encoding can be decoded as if they were ASCII,
- * ignoring values greater than 127. In case of doubt, this method conservatively returns {@code false}.
- *
- * @param encoding the encoding.
- * @return whether bytes less than 128 can be interpreted as ASCII.
- */
- public static boolean basedOnASCII(final Charset encoding) {
- return basedOnASCII.contains(encoding.name());
- }
-
- /**
- * Returns a provider for the given format name.
- *
- * @param format name of the format for which to get a provider.
- * @return first provider found for the given format name.
- * @throws UnsupportedStorageException if no provider is found for the specified format.
- *
- * @see StoreMetadata#formatName()
- */
- public static DataStoreProvider providerByFormatName(final String format) throws UnsupportedStorageException {
- for (DataStoreProvider provider : DataStores.providers()) {
- if (format.equalsIgnoreCase(getFormatName(provider))) {
- return provider;
- }
- }
- throw new UnsupportedStorageException(Errors.format(Errors.Keys.UnsupportedFormat_1, format));
- }
-
/**
* Copies all feature from the given source to the given target.
* We use this method as central point where such copy occur, in case we want to implement
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreProvider.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreProvider.java
index bb9c43aa92..82c5f9288b 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreProvider.java
@@ -24,6 +24,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.Buffer;
import java.nio.ByteOrder;
+import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.OpenOption;
import java.nio.file.StandardOpenOption;
@@ -47,6 +48,9 @@ import org.apache.sis.util.ArraysExt;
* All implementations <em>shall</em> supports the {@value #LOCATION} parameter.
* All other parameters are optional.
*
+ * <p>This class contains also a few static methods for data stores which read from an <abbr>URI</abbr>,
+ * not necessarily data stores extending {@link URIDataStore}.</p>
+ *
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
*/
@@ -160,6 +164,8 @@ public abstract class URIDataStoreProvider extends DataStoreProvider {
* @param ifNew whether to return {@code true} only if a new file would be created.
* @return whether the specified connector should open a writable data store.
* @throws DataStoreException if the storage object has already been used and cannot be reused.
+ *
+ * @see StoreUtilities#canWrite(Class)
*/
public static boolean isWritable(final StorageConnector connector, final boolean ifNew) throws DataStoreException {
final Object storage = connector.getStorage();
@@ -204,4 +210,18 @@ public abstract class URIDataStoreProvider extends DataStoreProvider {
}
return output;
}
+
+ /**
+ * Returns {@code true} if a sequence of bytes in the given encoding can be decoded as if they were ASCII,
+ * ignoring values greater than 127. In case of doubt, this method conservatively returns {@code false}.
+ *
+ * @param encoding the encoding.
+ * @return whether bytes less than 128 can be interpreted as ASCII.
+ */
+ public static boolean basedOnASCII(final Charset encoding) {
+ return ArraysExt.containsIgnoreCase(basedOnASCII, encoding.name());
+ }
+
+ /** Names of encoding where bytes less than 128 can be interpreted as <abbr>ASCII</abbr>. */
+ private static final String[] basedOnASCII = {"US-ASCII", "ISO-8859-1", "UTF-8"};
}
diff --git a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/base/StoreUtilitiesTest.java b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/base/StoreUtilitiesTest.java
index 26ec645b03..648158bb0f 100644
--- a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/base/StoreUtilitiesTest.java
+++ b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/base/StoreUtilitiesTest.java
@@ -16,7 +16,7 @@
*/
package org.apache.sis.storage.base;
-import java.nio.charset.StandardCharsets;
+import org.apache.sis.storage.UnsupportedStorageException;
// Test dependencies
import org.junit.jupiter.api.Test;
@@ -37,15 +37,12 @@ public final class StoreUtilitiesTest extends TestCase {
}
/**
- * Tests {@link StoreUtilities#basedOnASCII(Charset)}.
+ * Tests {@link StoreUtilities#providerByFormatName(String)}.
+ *
+ * @throws UnsupportedStorageException if no provider is found for the specified format.
*/
@Test
- public void testBasedOnASCII() {
- assertTrue (StoreUtilities.basedOnASCII(StandardCharsets.US_ASCII));
- assertTrue (StoreUtilities.basedOnASCII(StandardCharsets.ISO_8859_1));
- assertTrue (StoreUtilities.basedOnASCII(StandardCharsets.UTF_8));
- assertFalse(StoreUtilities.basedOnASCII(StandardCharsets.UTF_16));
- assertFalse(StoreUtilities.basedOnASCII(StandardCharsets.UTF_16BE));
- assertFalse(StoreUtilities.basedOnASCII(StandardCharsets.UTF_16LE));
+ public void testProviderByFormatName() throws UnsupportedStorageException {
+ assertInstanceOf(org.apache.sis.storage.csv.StoreProvider.class, StoreUtilities.providerByFormatName("CSV"));
}
}
diff --git a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/base/StoreUtilitiesTest.java b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/base/URIDataStoreProviderTest.java
similarity index 63%
copy from endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/base/StoreUtilitiesTest.java
copy to endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/base/URIDataStoreProviderTest.java
index 26ec645b03..f8ffd98066 100644
--- a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/base/StoreUtilitiesTest.java
+++ b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/base/URIDataStoreProviderTest.java
@@ -25,27 +25,27 @@ import org.apache.sis.test.TestCase;
/**
- * Tests {@link StoreUtilities}.
+ * Tests {@link URIDataStoreProvider}.
*
* @author Martin Desruisseaux (Geomatys)
*/
-public final class StoreUtilitiesTest extends TestCase {
+public final class URIDataStoreProviderTest extends TestCase {
/**
* Creates a new test case.
*/
- public StoreUtilitiesTest() {
+ public URIDataStoreProviderTest() {
}
/**
- * Tests {@link StoreUtilities#basedOnASCII(Charset)}.
+ * Tests {@link URIDataStoreProvider#basedOnASCII(Charset)}.
*/
@Test
public void testBasedOnASCII() {
- assertTrue (StoreUtilities.basedOnASCII(StandardCharsets.US_ASCII));
- assertTrue (StoreUtilities.basedOnASCII(StandardCharsets.ISO_8859_1));
- assertTrue (StoreUtilities.basedOnASCII(StandardCharsets.UTF_8));
- assertFalse(StoreUtilities.basedOnASCII(StandardCharsets.UTF_16));
- assertFalse(StoreUtilities.basedOnASCII(StandardCharsets.UTF_16BE));
- assertFalse(StoreUtilities.basedOnASCII(StandardCharsets.UTF_16LE));
+ assertTrue (URIDataStoreProvider.basedOnASCII(StandardCharsets.US_ASCII));
+ assertTrue (URIDataStoreProvider.basedOnASCII(StandardCharsets.ISO_8859_1));
+ assertTrue (URIDataStoreProvider.basedOnASCII(StandardCharsets.UTF_8));
+ assertFalse(URIDataStoreProvider.basedOnASCII(StandardCharsets.UTF_16));
+ assertFalse(URIDataStoreProvider.basedOnASCII(StandardCharsets.UTF_16BE));
+ assertFalse(URIDataStoreProvider.basedOnASCII(StandardCharsets.UTF_16LE));
}
}
(sis) 01/02: Remove `DataStoreProvider.TIMEZONE` because that parameter is optional while `DataStoreProvider` should declare only essential parameters.
Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
commit 6d513dd48196e5452e6482d99a302a7bf454f953
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue May 26 13:01:36 2026 +0200
Remove `DataStoreProvider.TIMEZONE` because that parameter is optional
while `DataStoreProvider` should declare only essential parameters.
This is an attempt to bring a little bit of order in the mapping between parameters and option keys,
at least for the most frequently used parameters and only for the internal data store implementations.
This is done with an `URIDataStoreOption` internal enumeration in replacement to some static methods
previously defined in `URIDataStoreProvider`.
---
.../org/apache/sis/console/OperationParser.java | 2 +-
.../apache/sis/storage/landsat/LandsatStore.java | 4 +-
.../sis/storage/landsat/LandsatStoreProvider.java | 4 +-
.../apache/sis/storage/geotiff/GeoTiffStore.java | 6 +-
.../sis/storage/geotiff/GeoTiffStoreProvider.java | 13 +-
.../org/apache/sis/storage/netcdf/NetcdfStore.java | 4 +-
.../sis/storage/netcdf/NetcdfStoreProvider.java | 10 +-
.../org/apache/sis/storage/gpx/StoreProvider.java | 16 +-
.../storage/xml/stream/StaxDataStoreProvider.java | 8 +-
.../main/org/apache/sis/storage/DataStore.java | 27 +-
.../org/apache/sis/storage/DataStoreProvider.java | 32 +-
.../org/apache/sis/storage/StorageConnector.java | 1 +
.../org/apache/sis/storage/base/PRJDataStore.java | 100 ++----
.../org/apache/sis/storage/base/URIDataStore.java | 96 ++++--
.../sis/storage/base/URIDataStoreOption.java | 367 +++++++++++++++++++++
.../sis/storage/base/URIDataStoreProvider.java | 158 +++------
.../main/org/apache/sis/storage/csv/Store.java | 27 +-
.../org/apache/sis/storage/csv/StoreProvider.java | 69 ++--
.../apache/sis/storage/esri/AsciiGridStore.java | 7 +-
.../sis/storage/esri/AsciiGridStoreProvider.java | 7 +-
.../org/apache/sis/storage/esri/RasterStore.java | 6 +-
.../apache/sis/storage/esri/RawRasterStore.java | 2 +-
.../sis/storage/esri/RawRasterStoreProvider.java | 7 +-
.../main/org/apache/sis/storage/folder/Store.java | 42 +--
.../apache/sis/storage/folder/StoreProvider.java | 90 ++---
.../apache/sis/storage/folder/WritableStore.java | 10 +-
.../sis/storage/image/WorldFileStoreProvider.java | 9 +-
.../org/apache/sis/storage/internal/Resources.java | 7 +-
.../sis/storage/internal/Resources.properties | 3 +-
.../sis/storage/internal/Resources_fr.properties | 3 +-
.../main/org/apache/sis/storage/wkt/Store.java | 10 +-
.../org/apache/sis/storage/wkt/StoreFormat.java | 2 +-
.../org/apache/sis/storage/wkt/StoreProvider.java | 63 ++--
.../apache/sis/storage/xml/AbstractProvider.java | 13 +-
.../org/apache/sis/storage/xml/StoreProvider.java | 2 +-
.../test/org/apache/sis/storage/csv/StoreTest.java | 3 +-
.../org/apache/sis/storage/folder/StoreTest.java | 2 +-
.../apache/sis/storage/wkt/StoreProviderTest.java | 6 +-
.../storage/coveragejson/CoverageJsonStore.java | 4 +-
.../coveragejson/CoverageJsonStoreProvider.java | 5 +-
.../apache/sis/storage/geoheif/GeoHeifStore.java | 4 +-
.../sis/storage/geoheif/GeoHeifStoreProvider.java | 9 +-
.../sis/storage/geopackage/GpkgStoreProvider.java | 7 +-
.../main/org/apache/sis/storage/gsf/GSFStore.java | 6 +-
.../apache/sis/storage/gsf/GSFStoreProvider.java | 25 +-
.../sis/storage/shapefile/ShapefileProvider.java | 45 +--
.../sis/storage/shapefile/ShapefileStore.java | 70 ++--
.../sis/storage/shapefile/ShapefileStoreTest.java | 27 +-
.../org/apache/sis/storage/shapefile/Snippets.java | 7 +-
.../org/apache/sis/gui/dataset/PathAction.java | 43 ++-
.../org/apache/sis/gui/dataset/ResourceCell.java | 3 +-
.../org/apache/sis/storage/gdal/GDALStore.java | 4 +-
.../apache/sis/storage/gdal/GDALStoreProvider.java | 7 +-
53 files changed, 861 insertions(+), 643 deletions(-)
diff --git a/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/OperationParser.java b/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/OperationParser.java
index e673da12c0..6730d9dd87 100644
--- a/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/OperationParser.java
+++ b/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/OperationParser.java
@@ -25,7 +25,7 @@ import org.apache.sis.storage.base.PRJDataStore;
/**
- * Reads a coordinate operation in GML or WKT format.
+ * Reads a coordinate operation in <abbr>GML</abbr> or <abbr>WKT</abbr> format.
*
* @author Martin Desruisseaux (Geomatys)
*/
diff --git a/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/LandsatStore.java b/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/LandsatStore.java
index 6a2d6b97f2..b2aadcec4c 100644
--- a/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/LandsatStore.java
+++ b/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/LandsatStore.java
@@ -48,7 +48,7 @@ import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.event.StoreEvent;
import org.apache.sis.storage.event.StoreListener;
import org.apache.sis.storage.event.WarningEvent;
-import org.apache.sis.storage.base.URIDataStore;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.storage.folder.ConcurrentCloser;
import org.apache.sis.util.iso.DefaultNameFactory;
import org.apache.sis.util.collection.Containers;
@@ -194,7 +194,7 @@ public class LandsatStore extends DataStore implements Aggregate {
*/
@Override
public Optional<ParameterValueGroup> getOpenParameters() {
- return Optional.ofNullable(URIDataStore.parameters(provider, location));
+ return Optional.ofNullable(URIDataStoreOption.createWithLocationOnly(provider, location));
}
/**
diff --git a/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/LandsatStoreProvider.java b/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/LandsatStoreProvider.java
index 53f33c75cd..8fa79319a9 100644
--- a/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/LandsatStoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage.earthobservation/main/org/apache/sis/storage/landsat/LandsatStoreProvider.java
@@ -29,7 +29,7 @@ import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.ProbeResult;
import org.apache.sis.storage.base.Capability;
import org.apache.sis.storage.base.StoreMetadata;
-import org.apache.sis.storage.base.URIDataStoreProvider;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.storage.wkt.FirstKeywordPeek;
@@ -64,7 +64,7 @@ public class LandsatStoreProvider extends DataStoreProvider {
/**
* The parameter descriptor to be returned by {@link #getOpenParameters()}.
*/
- private static final ParameterDescriptorGroup OPEN_DESCRIPTOR = URIDataStoreProvider.descriptor(NAME);
+ private static final ParameterDescriptorGroup OPEN_DESCRIPTOR = URIDataStoreOption.createForLocationOnly(NAME);
/**
* The object to use for verifying if the first keyword is the expected one.
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStore.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStore.java
index d51bdcebcd..e7b4c4dd79 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStore.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStore.java
@@ -50,7 +50,7 @@ import org.apache.sis.storage.IncompatibleResourceException;
import org.apache.sis.storage.IllegalNameException;
import org.apache.sis.storage.metadata.MetadataBuilder;
import org.apache.sis.storage.base.StoreUtilities;
-import org.apache.sis.storage.base.URIDataStore;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.storage.base.URIDataStoreProvider;
import org.apache.sis.storage.base.GridResourceWrapper;
import org.apache.sis.storage.event.StoreEvent;
@@ -320,7 +320,7 @@ public class GeoTiffStore extends DataStore implements Aggregate {
*/
@Override
public Optional<ParameterValueGroup> getOpenParameters() {
- final ParameterValueGroup param = URIDataStore.parameters(provider, location);
+ final ParameterValueGroup param = URIDataStoreOption.createWithLocationOnly(provider, location);
if (param != null) {
final Writer w = writer;
if (w != null) {
@@ -337,7 +337,7 @@ public class GeoTiffStore extends DataStore implements Aggregate {
}
/**
- * Returns the modifiers (BigTIFF, COG…) of this data store.
+ * Returns the modifiers (BigTIFF, <abbr>COG</abbr>…) of this data store.
*
* @return format modifiers of this data store.
*
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
index c43693b017..7c87fe709d 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
@@ -32,6 +32,7 @@ import org.apache.sis.storage.ProbeResult;
import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.base.StoreMetadata;
import org.apache.sis.storage.base.Capability;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.storage.base.URIDataStoreProvider;
import org.apache.sis.util.internal.shared.Constants;
import org.apache.sis.util.resources.Vocabulary;
@@ -44,7 +45,7 @@ import org.apache.sis.parameter.Parameters;
* Given a {@link StorageConnector} input, this class tries to instantiate a {@link GeoTiffStore}.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 1.5
+ * @version 1.7
*
* @see GeoTiffStore
*
@@ -56,12 +57,12 @@ import org.apache.sis.parameter.Parameters;
resourceTypes = {Aggregate.class, GridCoverageResource.class})
public class GeoTiffStoreProvider extends DataStoreProvider {
/**
- * The MIME type for GeoTIFF files.
+ * The <abbr>MIME</abbr> type for GeoTIFF files.
*/
private static final String MIME_TYPE = "image/tiff";
/**
- * The TIFF version.
+ * The <abbr>TIFF</abbr> version.
*/
private static final Version VERSION = new Version("6.0");
@@ -73,7 +74,7 @@ public class GeoTiffStoreProvider extends DataStoreProvider {
private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.geotiff");
/**
- * Name of the parameter for specifying the format modifiers (BigTIFF, COG…).
+ * Name of the parameter for specifying the format modifiers (BigTIFF, <abbr>COG</abbr>…).
*/
static final String MODIFIERS = "modifiers";
@@ -100,7 +101,7 @@ public class GeoTiffStoreProvider extends DataStoreProvider {
final var builder = new ParameterBuilder();
MODIFIERS_PARAM = builder.addName(MODIFIERS).setDescription(Vocabulary.formatInternational(Vocabulary.Keys.Options)).create(FormatModifier[].class, null);
COMPRESSION_PARAM = builder.addName(COMPRESSION).setDescription(Vocabulary.formatInternational(Vocabulary.Keys.Compression)).create(Compression.class, null);
- OPEN_DESCRIPTOR = builder.addName(Constants.GEOTIFF).createGroup(URIDataStoreProvider.LOCATION_PARAM, MODIFIERS_PARAM, COMPRESSION_PARAM);
+ OPEN_DESCRIPTOR = builder.addName(Constants.GEOTIFF).createGroup(URIDataStoreOption.LOCATION.getParameterDescriptor(), MODIFIERS_PARAM, COMPRESSION_PARAM);
}
/**
@@ -194,7 +195,7 @@ public class GeoTiffStoreProvider extends DataStoreProvider {
@Override
public DataStore open(final ParameterValueGroup parameters) throws DataStoreException {
final var p = Parameters.castOrWrap(parameters);
- final var connector = new StorageConnector(p.getValue(URIDataStoreProvider.LOCATION_PARAM));
+ final var connector = URIDataStoreOption.connector(this, parameters, null, null);
final FormatModifier[] modifiers = p.getValue(MODIFIERS_PARAM);
if (modifiers != null) {
connector.setOption(FormatModifier.OPTION_KEY, modifiers);
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStore.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStore.java
index 114e61e931..48793ae1ae 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStore.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStore.java
@@ -39,7 +39,7 @@ import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.Aggregate;
import org.apache.sis.storage.DataStoreClosedException;
import org.apache.sis.storage.Resource;
-import org.apache.sis.storage.base.URIDataStore;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.storage.netcdf.base.Decoder;
import org.apache.sis.storage.netcdf.base.RasterResource;
import org.apache.sis.storage.event.StoreEvent;
@@ -148,7 +148,7 @@ public class NetcdfStore extends DataStore implements Aggregate {
*/
@Override
public Optional<ParameterValueGroup> getOpenParameters() {
- return Optional.ofNullable(URIDataStore.parameters(provider, location));
+ return Optional.ofNullable(URIDataStoreOption.createWithLocationOnly(provider, location));
}
/**
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
index 8766ff3992..2af0c516bb 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
@@ -41,15 +41,15 @@ import org.apache.sis.storage.netcdf.base.Decoder;
import org.apache.sis.storage.netcdf.internal.Resources;
import org.apache.sis.storage.netcdf.classic.ChannelDecoder;
import org.apache.sis.storage.netcdf.ucar.DecoderWrapper;
-import org.apache.sis.io.stream.ChannelDataInput;
-import org.apache.sis.io.stream.IOUtilities;
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.base.URIDataStoreOption;
+import org.apache.sis.storage.event.StoreListeners;
+import org.apache.sis.io.stream.ChannelDataInput;
+import org.apache.sis.io.stream.IOUtilities;
import org.apache.sis.system.SystemListener;
import org.apache.sis.system.Modules;
import org.apache.sis.setup.GeometryLibrary;
-import org.apache.sis.storage.event.StoreListeners;
import org.apache.sis.util.Version;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.internal.shared.Constants;
@@ -94,7 +94,7 @@ public class NetcdfStoreProvider extends DataStoreProvider {
/**
* The parameter descriptor to be returned by {@link #getOpenParameters()}.
*/
- private static final ParameterDescriptorGroup OPEN_DESCRIPTOR = URIDataStoreProvider.descriptor(Constants.NETCDF);
+ private static final ParameterDescriptorGroup OPEN_DESCRIPTOR = URIDataStoreOption.createForLocationOnly(Constants.NETCDF);
/**
* The name of the {@link ucar.nc2.NetcdfFile} class, which is {@value}.
diff --git a/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/gpx/StoreProvider.java b/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/gpx/StoreProvider.java
index edbf8d835b..05f46ae753 100644
--- a/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/gpx/StoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/gpx/StoreProvider.java
@@ -49,7 +49,7 @@ public final class StoreProvider extends StaxDataStoreProvider {
public static final String NAME = "GPX";
/**
- * The logger used by GPX stores.
+ * The logger used by <abbr>GPX</abbr> stores.
*
* @see #getLogger()
*/
@@ -71,20 +71,22 @@ public final class StoreProvider extends StaxDataStoreProvider {
private static final Range<Version> VERSIONS = new Range<>(Version.class, V1_0, true, V1_1, true);
/**
- * The default factory instance.
+ * The default provider instance.
*/
private static final StoreProvider INSTANCE = new StoreProvider();
/**
* Returns the default provider instance.
* This method is invoked by Java service loader.
+ *
+ * @return the default provider instance.
*/
public static StoreProvider provider() {
return INSTANCE;
}
/**
- * Creates a new GPX store provider.
+ * Creates a new <abbr>GPX</abbr> store provider.
*/
public StoreProvider() {
super("GPX",
@@ -104,9 +106,9 @@ public final class StoreProvider extends StaxDataStoreProvider {
}
/**
- * Returns a GPX {@link Store} implementation associated with this provider.
+ * Returns a <abbr>GPX</abbr> {@link Store} implementation associated with this provider.
*
- * @param connector information about the storage (URL, stream, <i>etc</i>).
+ * @param connector information about the storage (<abbr>URL</abbr>, stream, <i>etc</i>).
* @return a data store implementation associated with this provider for the given storage.
* @throws DataStoreException if an error occurred while creating the data store instance.
*/
@@ -120,9 +122,9 @@ public final class StoreProvider extends StaxDataStoreProvider {
}
/**
- * Returns the JAXB context for the data store. This method is invoked at most once.
+ * Returns the <abbr>JAXB</abbr> context for the data store. This method is invoked at most once.
*
- * @return the JAXB context.
+ * @return the <abbr>JAXB</abbr> context.
* @throws JAXBException if an error occurred while creating the JAXB context.
*/
@Override
diff --git a/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/xml/stream/StaxDataStoreProvider.java b/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/xml/stream/StaxDataStoreProvider.java
index a880d4aaf9..7f1550f19c 100644
--- a/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/xml/stream/StaxDataStoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage.xml/main/org/apache/sis/storage/xml/stream/StaxDataStoreProvider.java
@@ -49,12 +49,12 @@ public abstract class StaxDataStoreProvider extends AbstractProvider {
}
/**
- * Returns the JAXB context for the data store, or {@code null} if the data stores
- * {@linkplain #open created} by this provided do not use JAXB.
+ * Returns the <abbr>JAXB</abbr> context for the data store, or {@code null} if the data stores
+ * {@linkplain #open created} by this provided do not use <abbr>JAXB</abbr>.
*
* <p>The default implementation returns {@code null}.</p>
*
- * @return the JAXB context, or {@code null} if none.
+ * @return the <abbr>JAXB</abbr> context, or {@code null} if none.
* @throws JAXBException if an error occurred while creating the JAXB context.
*/
protected JAXBContext getJAXBContext() throws JAXBException {
@@ -63,7 +63,7 @@ public abstract class StaxDataStoreProvider extends AbstractProvider {
/**
* Returns the (un)marshaller pool, creating it when first needed.
- * If the subclass does not define a JAXB context, then this method returns {@code null}.
+ * If the subclass does not define a <abbr>JAXB</abbr> context, then this method returns {@code null}.
*/
final MarshallerPool getMarshallerPool() throws JAXBException {
MarshallerPool pool = jaxb;
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java
index 714268025e..42439dc92e 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStore.java
@@ -124,21 +124,13 @@ public abstract class DataStore implements Resource, Localized, AutoCloseable {
* The {@code connector} argument is mandatory.
*
* @param provider the factory that created this {@code DataStore} instance, or {@code null} if unspecified.
- * @param connector information about the storage (URL, stream, reader instance, <i>etc</i>).
+ * @param connector information about the storage (<abbr>URL</abbr>, stream, reader instance, <i>etc</i>).
* @throws DataStoreException if an error occurred while creating the data store for the given storage.
*
* @since 0.8
*/
- @SuppressWarnings("this-escape") // `this` appears in a cyclic graph. Should not be accessible before completion.
protected DataStore(final DataStoreProvider provider, final StorageConnector connector) throws DataStoreException {
- this.provider = provider;
- this.displayName = connector.getDisplayName();
- this.locale = Locale.getDefault(Locale.Category.DISPLAY);
- this.listeners = new StoreListeners(connector.getOption(OptionKey.PARENT_LISTENERS), this);
- /*
- * Above locale is NOT OptionKey.LOCALE because we are not talking about the same locale.
- * The one in this DataStore is for warning and exception messages, not for parsing data.
- */
+ this(null, provider, connector, false);
}
/**
@@ -149,7 +141,7 @@ public abstract class DataStore implements Resource, Localized, AutoCloseable {
*
* @param parent the parent that contains this new {@code DataStore} component, or {@code null} if none.
* @param provider the factory that created this {@code DataStore} instance, or {@code null} if unspecified.
- * @param connector information about the storage (URL, stream, reader instance, <i>etc</i>).
+ * @param connector information about the storage (<abbr>URL</abbr>, stream, reader instance, <i>etc</i>).
* @param hidden {@code true} if this store will not be directly accessible from the parent.
* It is the case if this store is an {@link Aggregate} and the parent store will
* expose only some components of the aggregate instead of the aggregate itself.
@@ -158,8 +150,11 @@ public abstract class DataStore implements Resource, Localized, AutoCloseable {
* @since 1.1
*/
@SuppressWarnings("this-escape") // `this` appears in a cyclic graph. Should not be accessible before completion.
- protected DataStore(final DataStore parent, final DataStoreProvider provider, final StorageConnector connector,
- final boolean hidden) throws DataStoreException
+ protected DataStore(final DataStore parent,
+ final DataStoreProvider provider,
+ final StorageConnector connector,
+ final boolean hidden)
+ throws DataStoreException
{
this.provider = provider;
displayName = connector.getDisplayName();
@@ -172,8 +167,12 @@ public abstract class DataStore implements Resource, Localized, AutoCloseable {
}
forwardTo = parent.listeners;
} else {
+ /*
+ * Below locale is NOT OptionKey.LOCALE because we are not talking about the same locale.
+ * The one in this DataStore is for warning and exception messages, not for parsing data.
+ */
locale = Locale.getDefault(Locale.Category.DISPLAY);
- forwardTo = null;
+ forwardTo = connector.getOption(OptionKey.PARENT_LISTENERS);
}
listeners = new StoreListeners(forwardTo, this);
}
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStoreProvider.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStoreProvider.java
index 2c5b6ab820..9fd689247f 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/DataStoreProvider.java
@@ -28,7 +28,7 @@ import org.apache.sis.metadata.simple.SimpleFormat;
import org.apache.sis.metadata.iso.citation.DefaultCitation;
import org.apache.sis.metadata.iso.distribution.DefaultFormat;
import org.apache.sis.io.stream.Markable;
-import org.apache.sis.storage.base.URIDataStoreProvider;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.storage.internal.RewindableLineReader;
import org.apache.sis.measure.Range;
import org.apache.sis.util.Version;
@@ -61,7 +61,7 @@ import org.apache.sis.util.resources.Errors;
* @author Martin Desruisseaux (Geomatys)
* @author Johann Sorel (Geomatys)
* @author Alexis Manin (Geomatys)
- * @version 1.4
+ * @version 1.7
* @since 0.3
*/
public abstract class DataStoreProvider {
@@ -72,29 +72,16 @@ public abstract class DataStoreProvider {
*
* <p>Implementers are encouraged to define a parameter with this name
* to ensure a common and consistent definition among providers.
- * The parameter should be defined as mandatory and typed with a well-known Java class such as
- * {@link java.net.URI}, {@link java.nio.file.Path}, JDBC {@linkplain javax.sql.DataSource}, <i>etc</i>.
- * The type should have a compact textual representation, for serialization in XML or configuration files.
- * Consequently, {@link java.io.InputStream} and {@link java.nio.channels.Channel} should be avoided.</p>
+ * The parameter should be defined as mandatory and typed with a well-known Java class such as {@link java.net.URI},
+ * {@link java.nio.file.Path}, <abbr>JDBC</abbr> {@linkplain javax.sql.DataSource}, <i>etc</i>.
+ * The type should have a compact textual representation for serialization in <abbr>XML</abbr> or configuration files.
+ * Therefore, {@link java.io.InputStream} and {@link java.nio.channels.Channel} should be avoided.</p>
*
* @see #CREATE
* @see #getOpenParameters()
*/
public static final String LOCATION = "location";
- /**
- * Name of the parameter that specifies the data store time zone.
- * A parameter named {@value} should be included in the group of parameters returned by {@link #getOpenParameters()}.
- * The parameter value is often a {@link String} or a {@link ZoneId}, other types should not be allowed.
- *
- * <p>Implementers are encouraged to define a parameter with this name
- * to ensure a common and consistent definition among providers.</p>
- *
- * @see #CREATE
- * @see #getOpenParameters()
- */
- public static final String TIMEZONE = "timezone";
-
/**
* Name of the parameter that specifies whether to allow creation of a new {@code DataStore} if none exist
* at the given location. A parameter named {@value} may be included in the group of parameters returned by
@@ -119,6 +106,7 @@ public abstract class DataStoreProvider {
* are incompatible with this usage.
*
* @see #LOCATION
+ * @see OptionKey#OPEN_OPTIONS
* @see #getOpenParameters()
*/
public static final String CREATE = "create";
@@ -447,6 +435,7 @@ public abstract class DataStoreProvider {
* `InputStream` supports at most one mark. So we keep it for ourselves
* and wrap the stream in an object that prevent users from using marks.
*/
+ @SuppressWarnings("ConvertToTryWithResources")
final var stream = new ProbeInputStream(connector, (InputStream) input);
result = prober.test(type.cast(stream));
stream.close(); // No "try with resource". See `ProbeInputStream.close()` contract.
@@ -461,6 +450,7 @@ public abstract class DataStoreProvider {
result = prober.test(input);
r.protectedReset();
} else if (input instanceof Reader) {
+ @SuppressWarnings("ConvertToTryWithResources")
final var stream = new ProbeReader(connector, (Reader) input);
result = prober.test(type.cast(stream));
stream.close(); // No "try with resource". See `ProbeReader.close()` contract.
@@ -609,7 +599,7 @@ public abstract class DataStoreProvider {
*
* <h4>Implementation note</h4>
* The default implementation gets the value of a parameter named {@value #LOCATION}.
- * That value (typically a path or URL) is given to {@link StorageConnector} constructor,
+ * That value (typically a path or <abbr>URL</abbr>) is given to the {@link StorageConnector} constructor,
* which is then passed to {@link #open(StorageConnector)}.
*
* @param parameters opening parameters as defined by {@link #getOpenParameters()}.
@@ -624,7 +614,7 @@ public abstract class DataStoreProvider {
*/
public DataStore open(final ParameterValueGroup parameters) throws DataStoreException {
// IllegalOpenParameterException thrown if `parameters` is null.
- return open(URIDataStoreProvider.connector(this, parameters));
+ return open(URIDataStoreOption.connector(this, parameters, null, null));
}
/**
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 9d7f5a3c99..dbb18c71e4 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
@@ -632,6 +632,7 @@ public class StorageConnector implements Serializable {
* The object can be of any type, but the class javadoc lists the most typical ones.
*
* @param storage the input/output object as a <abbr>URL</abbr>, file, image input stream, <i>etc.</i>.
+ * @throws NullPointerException if {@code storage} is null.
*/
public StorageConnector(final Object storage) {
this.storage = Objects.requireNonNull(storage);
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/PRJDataStore.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/PRJDataStore.java
index a7bd5b81f9..7ae3a2d2a0 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/PRJDataStore.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/PRJDataStore.java
@@ -25,12 +25,9 @@ import java.nio.file.Path;
import java.nio.file.NoSuchFileException;
import java.text.ParseException;
import java.text.ParsePosition;
-import java.util.Objects;
import java.util.Optional;
import java.util.ArrayList;
import jakarta.xml.bind.JAXBException;
-import org.opengis.parameter.ParameterDescriptor;
-import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.apache.sis.storage.OptionKey;
@@ -42,24 +39,35 @@ import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.internal.Resources;
import org.apache.sis.storage.wkt.StoreFormat;
import org.apache.sis.io.wkt.Convention;
-import org.apache.sis.parameter.ParameterBuilder;
-import org.apache.sis.parameter.Parameters;
import org.apache.sis.util.Classes;
-import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.xml.internal.shared.ExceptionSimplifier;
/**
- * A data store for a file or URI accompanied by an auxiliary file of the same name with {@code .prj} extension.
- * If the auxiliary file is absent, {@link OptionKey#DEFAULT_CRS} is used as a fallback.
+ * A data store for a file or <abbr>URI</abbr> accompanied by an auxiliary file of the same name
+ * with {@code .prj} extension. If the auxiliary file is absent, {@link OptionKey#DEFAULT_CRS} is used as a fallback.
* The default WKT 1 variant used for parsing the {@code "*.prj"} file is the variant used by "World Files" and GDAL.
* This is not the standard specified by OGC 01-009 (they differ in there interpretation of units of measurement).
* This implementation accepts also WKT 2 (in which case the WKT 1 convention is ignored) and GML.
*
- * <p>The URI can be null if the only available storage is a {@link java.nio.channels.ReadableByteChannel},
- * {@link java.io.InputStream} or {@link java.io.Reader}. In such case, the CRS should be specified by the
+ * <p>The <abbr>URI</abbr> can be null if the only available storage is a {@link java.nio.channels.ReadableByteChannel},
+ * {@link java.io.InputStream} or {@link java.io.Reader}. In such case, the <abbr>CRS</abbr> should be specified by the
* {@link OptionKey#DEFAULT_CRS}.</p>
*
+ * <h2>Provider</h2>
+ * Data store providers should extend {@link URIDataStoreProvider} like below.
+ * The addition of {@code METADATA} should be omitted if this data store does not intend
+ * to invoke {@link #mergeAuxiliaryMetadata mergeAuxiliaryMetadata(…)}.
+ *
+ * {@snippet lang="java" :
+ * public final class MyProvider extends URIDataStoreProvider {
+ * public MyProvider() {
+ * supportedOptions.add(URIDataStoreOption.DEFAULT_CRS);
+ * supportedOptions.add(URIDataStoreOption.METADATA);
+ * }
+ * }
+ * }
+ *
* @author Martin Desruisseaux (Geomatys)
*/
public abstract class PRJDataStore extends URIDataStore {
@@ -71,8 +79,9 @@ public abstract class PRJDataStore extends URIDataStore {
protected static final String PRJ = "prj";
/**
- * The coordinate reference system. This is initialized on the value provided by {@link OptionKey#DEFAULT_CRS}
- * at construction time, and is modified later if a {@code "*.prj"} file is found.
+ * The coordinate reference system.
+ * This is initialized at construction time to the value provided by {@link OptionKey#DEFAULT_CRS},
+ * and is modified later if a {@code "*.prj"} file is found.
*/
protected CoordinateReferenceSystem crs;
@@ -126,9 +135,11 @@ public abstract class PRJDataStore extends URIDataStore {
}
/**
- * Reads an auxiliary file in WKT or GML format. Standard PRJ files use WKT only,
- * but the GML format is also accepted by this method as an extension specific to Apache SIS.
+ * Reads an auxiliary file in <abbr>WKT</abbr> or <abbr>GML</abbr> format.
+ * Standard <abbr>PRJ</abbr> files use <abbr>WKT</abbr> only, but the <abbr>GML</abbr> format
+ * is also accepted by this method as an extension specific to Apache <abbr>SIS</abbr>.
*
+ * @param <T> base class or interface of the object to read.
* @param caller the class to report as the warning source if a log record is created.
* @param method the method to report as the warning source if a log record is created.
* @param type base class or interface of the object to read.
@@ -188,7 +199,7 @@ public abstract class PRJDataStore extends URIDataStore {
* Writes the {@code "*.prj"} auxiliary file if {@link #crs} is non-null.
* If {@link #crs} is null and the auxiliary file exists, it is deleted.
*
- * <h4>WKT version used</h4>
+ * <h4><abbr>WKT</abbr> version used</h4>
* Current version writes the CRS in WKT 2 format. This is not the common practice, which uses WKT 1.
* But the WKT 1 variant used by the common practice is not the standard format defined by OGC 01-009.
* It is more like {@link Convention#WKT1_IGNORE_AXES}, which has many ambiguity problems. The WKT 2
@@ -265,64 +276,7 @@ public abstract class PRJDataStore extends URIDataStore {
@Override
public Optional<ParameterValueGroup> getOpenParameters() {
final Optional<ParameterValueGroup> op = super.getOpenParameters();
- op.ifPresent((pg) -> pg.parameter(Provider.CRS_NAME).setValue(crs));
+ op.ifPresent((pg) -> URIDataStoreOption.DEFAULT_CRS.setValueOf(pg, crs));
return op;
}
-
- /**
- * Provider for {@link PRJDataStore} instances.
- *
- * @author Martin Desruisseaux (Geomatys)
- */
- public abstract static class Provider extends URIDataStoreProvider {
- /**
- * Name of the {@link #DEFAULT_CRS} parameter.
- */
- static final String CRS_NAME = "defaultCRS";
-
- /**
- * Description of the optional parameter for the default coordinate reference system.
- */
- public static final ParameterDescriptor<CoordinateReferenceSystem> DEFAULT_CRS;
- static {
- final ParameterBuilder builder = new ParameterBuilder();
- DEFAULT_CRS = builder.addName(CRS_NAME)
- .setDescription(Vocabulary.formatInternational(Vocabulary.Keys.CoordinateRefSys))
- .create(CoordinateReferenceSystem.class, null);
- }
-
- /**
- * Creates a new provider.
- */
- protected Provider() {
- }
-
- /**
- * Invoked by {@link #getOpenParameters()} the first time that a parameter descriptor needs to be created.
- * When invoked, the parameter group name is set to a name derived from the {@link #getShortName()} value.
- * The default implementation creates a group containing {@link #LOCATION_PARAM} and {@link #DEFAULT_CRS}.
- * Subclasses can override if they need to create a group with more parameters.
- *
- * @param builder the builder to use for creating parameter descriptor. The group name is already set.
- * @return the parameters descriptor created from the given builder.
- */
- @Override
- protected ParameterDescriptorGroup build(final ParameterBuilder builder) {
- return builder.createGroup(LOCATION_PARAM, METADATA_PARAM, DEFAULT_CRS);
- }
-
- /**
- * Returns a data store implementation from the given parameters.
- *
- * @return a data store implementation associated with this provider for the given parameters.
- * @throws DataStoreException if an error occurred while creating the data store instance.
- */
- @Override
- public DataStore open(final ParameterValueGroup parameters) throws DataStoreException {
- final StorageConnector connector = connector(this, Objects.requireNonNull(parameters));
- final Parameters pg = Parameters.castOrWrap(parameters);
- connector.setOption(OptionKey.DEFAULT_CRS, pg.getValue(DEFAULT_CRS));
- return open(connector);
- }
- }
}
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStore.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStore.java
index 0e610d9174..94eb3141d2 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStore.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStore.java
@@ -16,8 +16,9 @@
*/
package org.apache.sis.storage.base;
-import java.util.HashMap;
import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashMap;
import java.util.Optional;
import java.util.Locale;
import java.util.logging.Level;
@@ -40,6 +41,9 @@ import javax.xml.transform.Source;
import jakarta.xml.bind.JAXBException;
import org.opengis.util.GenericName;
import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.GeneralParameterDescriptor;
import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.OptionKey;
import org.apache.sis.storage.DataStore;
@@ -60,9 +64,9 @@ import org.apache.sis.xml.internal.shared.ExceptionSimplifier;
/**
* A data store for a storage that may be represented by a {@link URI}.
- * The URI is stored in {@link #location} field and is used for populating some default metadata.
- * It is also use for resolving the path to auxiliary files, for example the CRS definition in PRJ file.
- * The URI can be null if the only available storage is a {@link java.nio.channels.ReadableByteChannel},
+ * The <abbr>URI</abbr> is stored in {@link #location} field and is used for populating some default metadata.
+ * It is also used for resolving the path to auxiliary files, for example the <abbr>CRS</abbr> definition in PRJ file.
+ * The <abbr>URI</abbr> can be null if the only available storage is a {@link java.nio.channels.ReadableByteChannel},
* {@link InputStream} or {@link java.io.Reader}.
*
* @author Johann Sorel (Geomatys)
@@ -90,7 +94,7 @@ public abstract class URIDataStore extends DataStore implements StoreResource {
private final Path metadataPath;
/**
- * User-specified character encoding, or {@code null} for the JVM default (usually UTF-8).
+ * User-specified character encoding, or {@code null} for the <abbr>JVM</abbr> default (usually <abbr>UTF</abbr>-8).
* Subclasses may replace this value by a value read from the data file.
*/
protected Charset encoding;
@@ -104,23 +108,40 @@ public abstract class URIDataStore extends DataStore implements StoreResource {
protected Locale dataLocale;
/**
- * User-specified timezone for dates, or {@code null} for UTC.
+ * User-specified timezone for dates, or {@code null} for <abbr>UTC</abbr>.
* Subclasses may replace this value by a value read from the data file.
*/
protected ZoneId timezone;
+ /**
+ * Creates a new data store with no parent.
+ *
+ * @param provider the factory that created this {@code URIDataStore} instance, or {@code null} if unspecified.
+ * @param connector information about the storage (URL, stream, reader instance, <i>etc</i>).
+ * @throws DataStoreException if an error occurred while creating the data store for the given storage.
+ */
+ protected URIDataStore(final DataStoreProvider provider, final StorageConnector connector) throws DataStoreException {
+ this(null, provider, connector, false);
+ }
+
/**
* Creates a new data store. This constructor does not open the file,
* so subclass constructors can decide whether to open in read-only or read/write mode.
* It is caller's responsibility to ensure that the {@link java.nio.file.OpenOption}
* are compatible with the capabilities (read-only or read/write) of this data store.
*
+ * @param parent the parent that contains this new {@code URIDataStore} component, or {@code null} if none.
* @param provider the factory that created this {@code URIDataStore} instance, or {@code null} if unspecified.
- * @param connector information about the storage (URL, stream, reader instance, <i>etc</i>).
+ * @param connector information about the storage (<abbr>URL</abbr>, stream, reader instance, <i>etc</i>).
+ * @param hidden {@code true} if this store will not be directly accessible from the parent.
+ * It is the case if this store is an {@link Aggregate} and the parent store will
+ * expose only some components of the aggregate instead of the aggregate itself.
* @throws DataStoreException if an error occurred while creating the data store for the given storage.
*/
- protected URIDataStore(final DataStoreProvider provider, final StorageConnector connector) throws DataStoreException {
- super(provider, connector);
+ protected URIDataStore(final DataStore parent, final DataStoreProvider provider, final StorageConnector connector,
+ final boolean hidden) throws DataStoreException
+ {
+ super(parent, provider, connector, hidden);
location = connector.getStorageAs(URI.class);
locationAsPath = connector.getStorageAs(Path.class);
if (locationAsPath != null || location != null) {
@@ -139,7 +160,7 @@ public abstract class URIDataStore extends DataStore implements StoreResource {
* @return {@code this}.
*/
@Override
- public final DataStore getOriginator() {
+ public DataStore getOriginator() {
return this;
}
@@ -205,29 +226,50 @@ public abstract class URIDataStore extends DataStore implements StoreResource {
}
/**
- * Returns the parameters used to open this data store.
- *
- * @return parameters used for opening this {@code DataStore}.
+ * Returns the supported options as declared by the provider.
+ * This method returns directly the internal map — do not modify.
+ * If this information is not provided, returns the mandatory parameters.
*/
- @Override
- public Optional<ParameterValueGroup> getOpenParameters() {
- return Optional.ofNullable(parameters(provider, location));
+ private EnumSet<URIDataStoreOption> getSupportedOptions() {
+ if (provider instanceof URIDataStoreProvider) {
+ return ((URIDataStoreProvider) provider).supportedOptions;
+ } else {
+ return EnumSet.of(URIDataStoreOption.LOCATION);
+ }
}
/**
- * Creates parameter value group for the current location, if non-null.
- * This convenience method is used for {@link DataStore#getOpenParameters()} implementations in public
- * {@code DataStore} that cannot extend {@code URIDataStore} directly, because this class is internal.
+ * Returns the parameters used to open this data store.
*
- * @param provider the provider of the data store for which to get open parameters.
- * @param location file opened by the data store.
- * @return parameters to be returned by {@link DataStore#getOpenParameters()}, or {@code null} if unknown.
+ * @return parameters used for opening this {@code DataStore}.
*/
- public static ParameterValueGroup parameters(final DataStoreProvider provider, final URI location) {
- if (location == null || provider == null) return null;
- final ParameterValueGroup pg = provider.getOpenParameters().createValue();
- pg.parameter(DataStoreProvider.LOCATION).setValue(location);
- return pg;
+ @Override
+ public Optional<ParameterValueGroup> getOpenParameters() {
+ if (provider != null) {
+ final ParameterDescriptorGroup descriptor = provider.getOpenParameters();
+ if (descriptor != null) {
+ final ParameterValueGroup pg = descriptor.createValue();
+ for (final URIDataStoreOption option : getSupportedOptions()) {
+ final Object value;
+ switch (option) {
+ default: continue;
+ case LOCATION: {
+ final GeneralParameterDescriptor gp = descriptor.descriptor(option.parameterName);
+ final boolean isPath = (gp instanceof ParameterDescriptor<?>) &&
+ Path.class.isAssignableFrom(((ParameterDescriptor<?>) gp).getValueClass());
+ value = isPath ? locationAsPath : location; break;
+ }
+ case METADATA: value = metadataPath; break;
+ case ENCODING: value = encoding; break;
+ case LOCALE: value = dataLocale; break;
+ case TIMEZONE: value = timezone; break;
+ }
+ option.setValueOf(pg, value);
+ }
+ return Optional.of(pg);
+ }
+ }
+ return Optional.empty();
}
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreOption.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreOption.java
new file mode 100644
index 0000000000..b76c848684
--- /dev/null
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreOption.java
@@ -0,0 +1,367 @@
+/*
+ * 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.base;
+
+import java.net.URI;
+import java.nio.file.Path;
+import java.nio.charset.Charset;
+import java.nio.file.StandardOpenOption;
+import java.time.ZoneId;
+import java.util.Locale;
+import java.util.EnumSet;
+import java.util.Collection;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.parameter.ParameterBuilder;
+import org.apache.sis.storage.DataStoreProvider;
+import org.apache.sis.storage.OptionKey;
+import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.storage.IllegalOpenParameterException;
+import org.apache.sis.storage.internal.Resources;
+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;
+
+
+/**
+ * Options supported by {@link URIDataStoreProvider}.
+ * This enumeration does the link between {@link ParameterDescriptor} and {@link OptionKey}.
+ * This enumeration contains all parameters used by all subclasses of {@link URIDataStore}
+ * in the Apache <abbr>SIS</abbr> code base. This is an enumeration for a closed universe,
+ * which is why it cannot be in exported <abbr>API</abbr>.
+ * This enumeration is useful for data stores that are containers of other data stores,
+ * such as the data store that read all files in a folder.
+ *
+ * <h4>Deferred construction of parameter descriptor</h4>
+ * Some parameters are used by only one {@link URIDataStore}. These parameters are constructed
+ * during the static initialization of the {@link URIDataStoreProvider} that use them.
+ *
+ * <h4>Future evolution</h4>
+ * This class is an attempt to bring a little bit of order in the mapping between parameters and option keys,
+ * at least for the most frequently used parameters. This class may change in any future <abbr>SIS</abbr>
+ * version according experience.
+ *
+ * @author Johann Sorel (Geomatys)
+ * @author Martin Desruisseaux (Geomatys)
+ */
+public enum URIDataStoreOption {
+ /**
+ * Description of the mandatory {@value URIDataStoreProvider#LOCATION} parameter.
+ * This is the only mandatory parameter in all {@link URIDataStoreProvider} implementations.
+ *
+ * @see URIDataStoreProvider#LOCATION
+ * @see #createForLocationOnly(String)
+ */
+ LOCATION(null, URIDataStoreProvider.LOCATION, Resources.Keys.DataStoreLocation, URI.class),
+
+ /**
+ * Description of the optional {@value URIDataStoreProvider#FORMAT} parameter.
+ *
+ * @see URIDataStoreProvider#FORMAT
+ */
+ FORMAT(null, URIDataStoreProvider.FORMAT, Resources.Keys.DirectoryContentFormatName, String.class),
+
+ /**
+ * Description of the optional {@value URIDataStoreProvider#CREATE} parameter of writable data stores.
+ *
+ * @see URIDataStoreProvider#CREATE
+ * @see OptionKey#OPEN_OPTIONS
+ */
+ CREATE(null, URIDataStoreProvider.CREATE, Resources.Keys.DataStoreCreate, Boolean.class),
+
+ /**
+ * Description of the optional parameter for character encoding used by the data store.
+ * This is used only when the data store does not have explicit encoding information.
+ *
+ * @see OptionKey#ENCODING
+ */
+ ENCODING(OptionKey.ENCODING, "encoding", Resources.Keys.DataStoreEncoding, Charset.class),
+
+ /**
+ * Description of the parameter for formatting conventions of dates and numbers.
+ * This is used only when the data store does not have explicit locale information.
+ *
+ * @see OptionKey#LOCALE
+ */
+ LOCALE(OptionKey.LOCALE, "locale", Resources.Keys.DataStoreLocale, Locale.class),
+
+ /**
+ * Description of the optional parameter for the time zone used by the data store.
+ * This is used only when the data store does not have explicit time zone information.
+ *
+ * @see OptionKey#TIMEZONE
+ */
+ TIMEZONE(OptionKey.TIMEZONE, "timezone", Resources.Keys.DataStoreTimeZone, ZoneId.class),
+
+ /**
+ * Description of the optional parameter for the default coordinate reference system.
+ * This is used only when the data store does not have explicit <abbr>CRS</abbr> information.
+ *
+ * @see OptionKey#DEFAULT_CRS
+ * @todo Use {@link CodeType} when parsing from text.
+ */
+ DEFAULT_CRS(OptionKey.DEFAULT_CRS, "defaultCRS", Resources.Keys.DefaultCRS, CoordinateReferenceSystem.class),
+
+ /**
+ * Description of the optional "metadata" parameter.
+ *
+ * @see OptionKey#METADATA_PATH
+ */
+ METADATA(OptionKey.METADATA_PATH, "metadata", Resources.Keys.MetadataLocation, Path.class),
+
+ /**
+ * Description of the optional parameter for specifying whether to assemble
+ * distinct lines into a single {@code Feature} instance forming a foliation.
+ */
+ FOLIATION(OptionKey.FOLIATION_REPRESENTATION, "foliation");
+
+ /**
+ * The parameter name. This is similar but not identical to the enumeration name.
+ */
+ final String parameterName;
+
+ /**
+ * The parameter descriptor for this option, or {@code null} if not yet constructed.
+ *
+ * @see #getParameterDescriptor()
+ * @see #initializeParameterDescriptor(Class, Object, short)
+ */
+ private volatile ParameterDescriptor<?> parameter;
+
+ /**
+ * The option key for storing the parameter value in a storage connector.
+ */
+ private final OptionKey<?> option;
+
+ /**
+ * Creates a new enumeration value with deferred construction of the parameter descriptor.
+ *
+ * @param option associated option in {@link StorageConnector}, or {@code null} if none.
+ * @param name name of the parameter to create.
+ */
+ private URIDataStoreOption(final OptionKey<?> option, final String name) {
+ this.option = option;
+ parameterName = name;
+ }
+
+ /**
+ * Creates a new enumeration value with immediate construction of the parameter descriptor.
+ *
+ * @param <V> for compile-time consistency check between {@code valueClass} and {@code option}.
+ * @param option associated option in {@link StorageConnector}, or {@code null} if none.
+ * @param name name of the parameter to create.
+ * @param description constant from {@link Resources} keys for the localized description.
+ * @param valueClass value of the parameter.
+ */
+ private <V> URIDataStoreOption(final OptionKey<V> option,
+ final String name,
+ final short description,
+ final Class<V> valueClass)
+ {
+ this(option, name);
+ initializeParameterDescriptor(valueClass, null, description);
+ }
+
+ /**
+ * Creates the parameter descriptor of this enumeration value.
+ *
+ * @param <V> for compile-time consistency check between {@code valueClass} and {@code option}.
+ * @param valueClass value of the parameter.
+ * @param defaultValue default value, or {@code null} if none.
+ * @param description constant from {@link Resources} keys for the localized description.
+ * @return the parameter descriptor.
+ * @throws IllegalStateException if this parameter descriptor is already initialized.
+ */
+ public final <V> ParameterDescriptor<V> initializeParameterDescriptor(
+ final Class<V> valueClass,
+ final V defaultValue,
+ final short description)
+ {
+ if (parameter != null) {
+ throw new IllegalStateException(name());
+ }
+ final ParameterDescriptor<V> descriptor = new ParameterBuilder()
+ .addName(parameterName)
+ .setDescription(Resources.formatInternational(description))
+ .setRequired(ordinal() == 0)
+ .create(valueClass, defaultValue);
+ parameter = descriptor;
+ return descriptor;
+ }
+
+ /**
+ * Returns the parameter associated to this enumeration.
+ *
+ * @return the parameter (never {@code null}).
+ * @throws IllegalStateException if the parameter has not yet been initialized.
+ */
+ public final ParameterDescriptor<?> getParameterDescriptor() {
+ final ParameterDescriptor<?> p = parameter;
+ if (p != null) {
+ return p;
+ }
+ throw new IllegalStateException(name());
+ }
+
+ /**
+ * Creates a parameter with the same name as this parameter but different type or remarks.
+ *
+ * @param builder the builder to use for creating the parameter.
+ * @param valueClass the new value class, or {@code null} for keeping the same class.
+ * @param remarks the new parameter remarks, or {@code null} for keeping the same remarks.
+ * @return parameter of the same name as {@link #parameter()} but the specified value class and remarks.
+ */
+ public final ParameterDescriptor<?> deriveParameterDescriptor(
+ final ParameterBuilder builder, Class<?> valueClass, CharSequence remarks)
+ {
+ ParameterDescriptor<?> p = getParameterDescriptor();
+ if (valueClass == null) valueClass = p.getValueClass();
+ if (remarks == null) remarks = p.getRemarks().orElse(null);
+ return builder.addName(p.getName())
+ .setDescription(p.getDescription().orElse(null))
+ .setRemarks(remarks)
+ .create(valueClass, null);
+ }
+
+ /**
+ * Creates a parameter descriptor group containing only the mandatory parameters.
+ * The mandatory parameter is: {@link #LOCATION}.
+ *
+ * @param name short name of the data store format.
+ * @return the descriptor for open parameters with only mandatory parameters.
+ *
+ * @see URIDataStoreProvider#createOpenParameters(ParameterBuilder)
+ */
+ public static ParameterDescriptorGroup createForLocationOnly(final String name) {
+ return new ParameterBuilder().addName(name).createGroup(LOCATION.getParameterDescriptor());
+ }
+
+ /**
+ * Returns a group of parameters set to the given mandatory values.
+ * This is a shortcut when only the mandatory parameters are defined.
+ * If the parameter descriptor group of the given provider contains parameters other than location,
+ * those additional parameters are present but without values.
+ *
+ * @param provider provider of the data store for which to get the parameters, or {@code null}.
+ * @param location value of {@link #LOCATION}, or {@code null} if none.
+ * @return the parameters with the given values, or {@code null} if {@code provider} or {@code location} is null.
+ */
+ public static ParameterValueGroup createWithLocationOnly(final DataStoreProvider provider, final URI location) {
+ if (provider != null && location != null) {
+ final ParameterDescriptorGroup descriptor = provider.getOpenParameters();
+ if (descriptor != null) {
+ final ParameterValueGroup pg = descriptor.createValue();
+ pg.parameter(LOCATION.parameterName).setValue(location);
+ return pg;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Sets the value of the parameter described by this enumeration value.
+ *
+ * @param parameters the parameters where to set the parameter.
+ * @param value the value to set, or {@code null} if none.
+ */
+ public final void setValueOf(final ParameterValueGroup parameters, final Object value) {
+ if (value != null) {
+ parameters.parameter(parameterName).setValue(value);
+ }
+ }
+
+ /**
+ * Creates a storage connector initialized to the location declared in the given parameters.
+ * The {@value #LOCATION} parameter is unconditionally requested. The other parameters to be
+ * requested are specified in the {@code options} collection.
+ * Missing optional parameters are ignored.
+ *
+ * @param provider the provider for which to create a storage connector (for error messages).
+ * @param parameters the parameters to use for creating a storage connector.
+ * @param options options to include, or {@code null} for only the mandatory parameters.
+ * @param openOptions where to store open options, or {@code null} for storing them in the storage connector.
+ * @return the storage connector initialized to the location specified in the parameters.
+ * @throws IllegalOpenParameterException if no {@value URIDataStoreProvider#LOCATION} parameter has been found.
+ */
+ public static StorageConnector connector(final DataStoreProvider provider,
+ final ParameterValueGroup parameters,
+ Collection<URIDataStoreOption> options,
+ EnumSet<StandardOpenOption> openOptions)
+ throws IllegalOpenParameterException
+ {
+ final StorageConnector connector;
+ try {
+ connector = new StorageConnector(parameters.parameter(URIDataStoreProvider.LOCATION).getValue());
+ } catch (ParameterNotFoundException | NullPointerException e) {
+ throw new IllegalOpenParameterException(
+ Resources.format(Resources.Keys.UndefinedParameter_2,
+ provider.getShortName(),
+ URIDataStoreProvider.LOCATION), e);
+ }
+ if (options != null) {
+ for (final URIDataStoreOption option : options) {
+ if (option.option == null) continue;
+ final Object value;
+ try {
+ value = parameters.parameter(option.parameterName).getValue();
+ } catch (ParameterNotFoundException e) {
+ Logging.ignorableException(provider.getLogger(), URIDataStoreOption.class, "connector", e);
+ continue;
+ }
+ if (value != null) try {
+ switch (option) {
+ case CREATE: {
+ final boolean store = (openOptions == null);
+ if (store) {
+ openOptions = EnumSet.of(StandardOpenOption.WRITE);
+ } else {
+ openOptions.add(StandardOpenOption.WRITE);
+ }
+ if (ObjectConverters.convert(value, Boolean.class)) {
+ openOptions.add(StandardOpenOption.CREATE);
+ }
+ if (store) {
+ connector.setOption(OptionKey.OPEN_OPTIONS, openOptions.toArray(StandardOpenOption[]::new));
+ }
+ break;
+ }
+ default: {
+ convertAndSet(option.option, value, connector);
+ break;
+ }
+ }
+ } catch (UnconvertibleObjectException e) {
+ throw new IllegalOpenParameterException(Errors.format(
+ Errors.Keys.IllegalOptionValue_2, option.parameterName, value), e);
+ }
+ }
+ }
+ return connector;
+ }
+
+ /**
+ * Set the given option to the given value in the given storage connector.
+ * Defined as a separated method for type-safety.
+ */
+ private static <V> void convertAndSet(final OptionKey<V> option, final Object value, final StorageConnector connector) {
+ connector.setOption(option, ObjectConverters.convert(value, option.getElementType()));
+ }
+}
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreProvider.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreProvider.java
index e8818cec6f..bb9c43aa92 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreProvider.java
@@ -16,7 +16,7 @@
*/
package org.apache.sis.storage.base;
-import java.util.Optional;
+import java.util.EnumSet;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
@@ -24,16 +24,12 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.Buffer;
import java.nio.ByteOrder;
-import java.net.URI;
import java.nio.file.Path;
import java.nio.file.OpenOption;
import java.nio.file.StandardOpenOption;
-import java.nio.charset.Charset;
-import java.time.ZoneId;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.parameter.ParameterNotFoundException;
import org.apache.sis.parameter.ParameterBuilder;
import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.OptionKey;
@@ -41,68 +37,55 @@ import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreProvider;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.IllegalOpenParameterException;
-import org.apache.sis.storage.Resource;
-import org.apache.sis.storage.internal.Resources;
import org.apache.sis.io.stream.ChannelDataOutput;
import org.apache.sis.io.stream.IOUtilities;
import org.apache.sis.util.ArraysExt;
-import org.apache.sis.util.logging.Logging;
/**
* Provider for {@link URIDataStore} instances.
+ * All implementations <em>shall</em> supports the {@value #LOCATION} parameter.
+ * All other parameters are optional.
*
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
*/
public abstract class URIDataStoreProvider extends DataStoreProvider {
/**
- * Description of the {@value #LOCATION} parameter.
+ * Name of the parameter for the name of the {@code DataStoreProvider} on which to delegate the work.
+ * This is used by data stores that are container for other data stores.
+ * It may be, for example, the data store for a whole directory content.
*/
- public static final ParameterDescriptor<URI> LOCATION_PARAM;
+ protected static final String FORMAT = "format";
/**
- * Description of the "metadata" parameter.
+ * Options that are supported. Shall contain at least {@link URIDataStoreOption#LOCATION}.
+ * For thread-safety reason, this set shall not be modified after construction.
*/
- public static final ParameterDescriptor<Path> METADATA_PARAM;
-
- /**
- * Description of the optional {@value #CREATE} parameter, which may be present in writable data store.
- * This parameter is not included in the descriptor created by {@link #build(ParameterBuilder)} default
- * implementation. It is subclass responsibility to add it if desired, only if supported.
- */
- public static final ParameterDescriptor<Boolean> CREATE_PARAM;
-
- /**
- * Description of the optional parameter for character encoding used by the data store.
- * This parameter is not included in the descriptor created by {@link #build(ParameterBuilder)}
- * default implementation. It is subclass responsibility to add it if desired.
- */
- public static final ParameterDescriptor<Charset> ENCODING;
- static {
- final ParameterBuilder builder = new ParameterBuilder();
- ENCODING = builder.addName("encoding").setDescription(Resources.formatInternational(Resources.Keys.DataStoreEncoding)).create(Charset.class, null);
- CREATE_PARAM = builder.addName( CREATE ).setDescription(Resources.formatInternational(Resources.Keys.DataStoreCreate )).create(Boolean.class, null);
- METADATA_PARAM = builder.addName("metadata").setDescription(Resources.formatInternational(Resources.Keys.MetadataLocation )).create(Path.class, null);
- LOCATION_PARAM = builder.addName( LOCATION ).setDescription(Resources.formatInternational(Resources.Keys.DataStoreLocation)).setRequired(true).create(URI.class, null);
- }
+ protected final EnumSet<URIDataStoreOption> supportedOptions;
/**
* The parameter descriptor to be returned by {@link #getOpenParameters()}.
* Created when first needed.
+ *
+ * @see #getOpenParameters()
*/
private volatile ParameterDescriptorGroup openDescriptor;
/**
- * Creates a new provider.
+ * Creates a new provider which initially supports only the {@value #LOCATION} parameter.
+ * The {@link #supportedOptions} set is initialized to {@link URIDataStoreOption#LOCATION}.
+ * Subclass shall add all other supported options (if any) in their constructor,
+ * and shall not modify that set after construction.
*/
protected URIDataStoreProvider() {
+ supportedOptions = EnumSet.of(URIDataStoreOption.LOCATION);
}
/**
* Returns a description of all parameters accepted by this provider for opening a data store.
- * This method creates the descriptor only when first needed. Subclasses can override the
- * {@link #build(ParameterBuilder)} method if they need to modify the descriptor to create.
+ * This method creates the descriptor only when first needed. Subclasses should initialize the
+ * content of the {@link #supportedOptions} set if they need to modify the descriptor.
*
* @return description of the parameters required or accepted for opening a {@link DataStore}.
*/
@@ -110,7 +93,8 @@ public abstract class URIDataStoreProvider extends DataStoreProvider {
public final ParameterDescriptorGroup getOpenParameters() {
ParameterDescriptorGroup desc = openDescriptor;
if (desc == null) {
- openDescriptor = desc = build(new ParameterBuilder().addName(getShortName()));
+ // No synchronization because not a big issue if created twice.
+ openDescriptor = desc = createOpenParameters(new ParameterBuilder().addName(getShortName()));
}
return desc;
}
@@ -118,98 +102,50 @@ public abstract class URIDataStoreProvider extends DataStoreProvider {
/**
* Invoked by {@link #getOpenParameters()} the first time that a parameter descriptor needs to be created.
* When invoked, the parameter group name is set to a name derived from the {@link #getShortName()} value.
- * The default implementation creates a group containing {@link #LOCATION_PARAM} and {@link #METADATA_PARAM}.
- * Subclasses can override if they need to create a group with more parameters.
+ * The default implementation creates a group containing {@link #supportedOptions}.
+ * Subclasses can override if they need to create a group with different parameters.
*
* @param builder the builder to use for creating parameter descriptor. The group name is already set.
* @return the parameters descriptor created from the given builder.
- */
- protected ParameterDescriptorGroup build(final ParameterBuilder builder) {
- return builder.createGroup(LOCATION_PARAM, METADATA_PARAM);
- }
-
- /**
- * Convenience method creating a parameter descriptor containing only {@link #LOCATION_PARAM}.
- * This convenience method is used for public providers that cannot extend this
- * {@code URIDataStoreProvider} class because it is internal.
- *
- * @param name short name of the data store format.
- * @return the descriptor for open parameters.
*
- * @todo Verify if non-exported classes in JDK9 are hidden from Javadoc, like package-private classes.
- * If true, we could remove this hack and extend {@code URIDataStore} even in public classes.
+ * @see URIDataStoreOption#createForLocationOnly(String)
*/
- public static ParameterDescriptorGroup descriptor(final String name) {
- return new ParameterBuilder().addName(name).createGroup(LOCATION_PARAM);
+ protected ParameterDescriptorGroup createOpenParameters(final ParameterBuilder builder) {
+ return builder.createGroup(supportedOptions.stream()
+ .map(URIDataStoreOption::getParameterDescriptor)
+ .toArray(ParameterDescriptor[]::new));
}
/**
- * Returns the location (path, URL, URI, <i>etc.</i>) of the given resource.
- * The type of the returned object can be any of the types documented in {@link DataStoreProvider#LOCATION}.
+ * Creates a data store from the given parameters by delegating to {@link #open(StorageConnector)}.
+ * The {@value #LOCATION} parameter is unconditionally requested. The other parameters to be requested
+ * are specified in the {@link #supportedOptions} set. Missing optional parameters are ignored.
*
- * @param resource the resource for which to get the location, or {@code null}.
- * @return location of the given resource, or {@code null} if none.
- * @throws DataStoreException if an error on the file system prevent the creation of the path.
+ * @param parameters opening parameters as defined by {@link #getOpenParameters()}.
+ * @return a data store implementation associated with this provider for the given parameters.
+ * @throws DataStoreException if an error occurred while creating the data store instance.
*/
- public static Object location(final Resource resource) throws DataStoreException {
- if (resource == null) {
- return null;
- }
- if (resource instanceof DataStore) {
- final Optional<ParameterValueGroup> p = ((DataStore) resource).getOpenParameters();
- if (p.isPresent()) try {
- return p.get().parameter(DataStoreProvider.LOCATION).getValue();
- } catch (ParameterNotFoundException e) {
- /*
- * This exception should not happen often since the "location" parameter is recommended.
- * Note that it does not mean the same thing as "parameter provided but value is null".
- * In that later case we want to return the null value as specified in the parameters.
- */
- Logging.recoverableException(StoreUtilities.LOGGER, URIDataStore.class, "location", e);
- }
- }
- /*
- * This fallback should not happen with `URIDataStore` implementation because the "location" parameter
- * is always present even if null. This fallback is for resources implementated by different classes.
- * The first path is presumed the main file.
- */
- return resource.getFileSet().flatMap((files) -> files.getPaths().stream().findFirst()).orElse(null);
+ @Override
+ public DataStore open(final ParameterValueGroup parameters) throws DataStoreException {
+ return open(connector(parameters, null));
}
/**
- * Creates a storage connector initialized to the location declared in given parameters.
- * This convenience method does not set any other parameters.
- * In particular, reading (or ignoring) the {@value #CREATE} parameter is left to callers,
- * because not all implementations may create data stores with {@link java.nio.file.StandardOpenOption}.
+ * Creates a storage connector initialized to the location declared in the given parameters.
+ * The {@value #LOCATION} parameter is unconditionally requested. The other parameters to be
+ * requested are specified in {@link #supportedOptions}.
+ * Missing optional parameters are ignored.
*
- * @param provider the provider for which to create a storage connector (for error messages).
- * @param parameters the parameters to use for creating a storage connector.
+ * @param parameters the parameters to use for creating a storage connector.
+ * @param openOptions where to store open options, or {@code null} for storing them in the storage connector.
* @return the storage connector initialized to the location specified in the parameters.
* @throws IllegalOpenParameterException if no {@value #LOCATION} parameter has been found.
*/
- public static StorageConnector connector(final DataStoreProvider provider, final ParameterValueGroup parameters)
+ protected final StorageConnector connector(final ParameterValueGroup parameters,
+ final EnumSet<StandardOpenOption> openOptions)
throws IllegalOpenParameterException
{
- ParameterNotFoundException cause = null;
- if (parameters != null) try {
- final Object location = parameters.parameter(LOCATION).getValue();
- if (location != null) {
- StorageConnector cnx = new StorageConnector(location);
- try {
- final Object zoneId = parameters.parameter(TIMEZONE).getValue();
- if (zoneId instanceof ZoneId) {
- cnx.setOption(org.apache.sis.setup.OptionKey.TIMEZONE, (ZoneId) zoneId);
- } else if (zoneId instanceof String) {
- cnx.setOption(org.apache.sis.setup.OptionKey.TIMEZONE, ZoneId.of((String) zoneId));
- }
- } catch (ParameterNotFoundException e) {}
- return cnx;
- }
- } catch (ParameterNotFoundException e) {
- cause = e;
- }
- throw new IllegalOpenParameterException(Resources.format(Resources.Keys.UndefinedParameter_2,
- provider.getShortName(), LOCATION), cause);
+ return URIDataStoreOption.connector(this, parameters, supportedOptions, openOptions);
}
/**
@@ -248,7 +184,7 @@ public abstract class URIDataStoreProvider extends DataStoreProvider {
}
/**
- * Creates a new output stream and set by the order to native order if is was not explicitly specified by the user.
+ * Creates a new output stream and set the order to native order if is was not explicitly specified by the user.
* The byte order is considered explicitly specified if the storage type is one of the types were the user could
* have specified that order.
*
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/Store.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/Store.java
index a773d56db7..a3d55d71a3 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/Store.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/Store.java
@@ -41,6 +41,7 @@ import org.opengis.metadata.Metadata;
import org.opengis.metadata.maintenance.ScopeCode;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.TemporalCRS;
+import org.opengis.parameter.ParameterValueGroup;
import org.apache.sis.feature.DefaultAttributeType;
import org.apache.sis.feature.DefaultFeatureType;
import org.apache.sis.feature.FoliationRepresentation;
@@ -63,6 +64,7 @@ import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.FeatureSet;
import org.apache.sis.storage.metadata.MetadataBuilder;
import org.apache.sis.storage.base.URIDataStore;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.storage.internal.RewindableLineReader;
import org.apache.sis.storage.internal.Resources;
import org.apache.sis.io.InvalidSeekException;
@@ -82,7 +84,8 @@ import org.opengis.feature.AttributeType;
/**
- * A data store which creates feature instances from a CSV file using the OGC Moving Features specification.
+ * A data store which creates feature instances from a <abbr>CSV</abbr>
+ * file using the <abbr>OGC</abbr> Moving Features specification.
* See package javadoc for more information on the syntax.
*
* @author Martin Desruisseaux (Geomatys)
@@ -212,10 +215,9 @@ final class Store extends URIDataStore implements FeatureSet {
private transient List<Feature> movingFeatures;
/**
- * Creates a new CSV store from the given file, URL or stream.
- *
- * <p>If the CSV file is known to be a Moving Feature file, then the given connector should
- * have an {@link OptionKey#ENCODING} value set to UTF-8.</p>
+ * Creates a new <abbr>CSV</abbr> store from the given file, <abbr>URL</abbr> or stream.
+ * If the <abbr>CSV</abbr> file is known to be a Moving Feature file, then the given
+ * connector should have an {@link OptionKey#ENCODING} value set to <abbr>UTF</abbr>-8.
*
* @param provider the factory that created this {@code DataStore} instance, or {@code null} if unspecified.
* @param connector information about the storage (URL, stream, <i>etc</i>).
@@ -606,6 +608,21 @@ final class Store extends URIDataStore implements FeatureSet {
return Foliation.TIME; // Default value.
}
+ /**
+ * Returns the parameters used to open this data store.
+ *
+ * @return parameters used for opening this {@code DataStore}.
+ */
+ @Override
+ public Optional<ParameterValueGroup> getOpenParameters() {
+ final Optional<ParameterValueGroup> pg = super.getOpenParameters();
+ pg.ifPresent((p) -> {
+ var foliation = dissociate ? FoliationRepresentation.FRAGMENTED : FoliationRepresentation.ASSEMBLED;
+ URIDataStoreOption.FOLIATION.setValueOf(p, foliation);
+ });
+ return pg;
+ }
+
/**
* Returns an identifier for this CSV data store.
* This method returns the {@link #getType() type} name, which is itself derived from the file name.
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/StoreProvider.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/StoreProvider.java
index 78c73053e4..78ddec4b75 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/StoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/csv/StoreProvider.java
@@ -17,14 +17,8 @@
package org.apache.sis.storage.csv;
import java.util.logging.Logger;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.parameter.ParameterDescriptor;
-import org.opengis.parameter.ParameterDescriptorGroup;
-import org.apache.sis.parameter.ParameterBuilder;
-import org.apache.sis.parameter.Parameters;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.storage.OptionKey;
import org.apache.sis.storage.ProbeResult;
import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.FeatureSet;
@@ -32,13 +26,14 @@ import org.apache.sis.feature.FoliationRepresentation;
import org.apache.sis.storage.internal.Resources;
import org.apache.sis.storage.base.Capability;
import org.apache.sis.storage.base.StoreMetadata;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.storage.base.URIDataStoreProvider;
import org.apache.sis.storage.wkt.FirstKeywordPeek;
/**
* The provider of {@link Store} instances. Given a {@link StorageConnector} input,
- * this class tries to instantiate a CSV {@code Store}.
+ * this class tries to instantiate a <abbr>CSV</abbr> {@code Store}.
*
* <h2>Thread safety</h2>
* The same {@code StoreProvider} instance can be safely used by many threads without synchronization on
@@ -57,7 +52,7 @@ public final class StoreProvider extends URIDataStoreProvider {
static final String NAME = "CSV", MOVING = "CSV-MF";
/**
- * The logger used by CSV stores.
+ * The logger used by <abbr>CSV</abbr> stores.
*
* @see #getLogger()
*/
@@ -117,23 +112,25 @@ public final class StoreProvider extends URIDataStoreProvider {
}
}
- /**
- * Description of the optional parameter for specifying whether the reader should assemble distinct CSV lines
- * into a single {@code Feature} instance forming a foliation. This is ignored if the CSV file does not seem
- * to contain moving features.
+ /*
+ * Creates the description of the optional parameter for specifying whether the reader should assemble
+ * distinct <abbr>CSV</abbr> lines into a single {@code Feature} instance forming a foliation.
+ * This is ignored if the <abbr>CSV</abbr> file does not seem to contain moving features.
*/
- private static final ParameterDescriptor<FoliationRepresentation> FOLIATION;
static {
- final ParameterBuilder builder = new ParameterBuilder();
- FOLIATION = builder.addName("foliation")
- .setDescription(Resources.formatInternational(Resources.Keys.FoliationRepresentation))
- .create(FoliationRepresentation.class, FoliationRepresentation.ASSEMBLED);
+ URIDataStoreOption.FOLIATION.initializeParameterDescriptor(
+ FoliationRepresentation.class,
+ FoliationRepresentation.ASSEMBLED,
+ Resources.Keys.FoliationRepresentation);
}
/**
* Creates a new provider.
*/
public StoreProvider() {
+ supportedOptions.add(URIDataStoreOption.METADATA);
+ supportedOptions.add(URIDataStoreOption.ENCODING);
+ supportedOptions.add(URIDataStoreOption.FOLIATION);
}
/**
@@ -147,13 +144,12 @@ public final class StoreProvider extends URIDataStoreProvider {
}
/**
- * Returns the MIME type if the given storage appears to be supported by CSV {@link Store}.
- * A {@linkplain ProbeResult#isSupported() supported} status does not guarantee that reading
- * or writing will succeed, only that there appears to be a reasonable chance of success
- * based on a brief inspection of the file header.
+ * Returns the <abbr>MIME</abbr> type if the given storage appears to be supported by <abbr>CSV</abbr> store.
+ * A {@linkplain ProbeResult#isSupported() supported} status does not guarantee that reading will succeed,
+ * only that there appears to be a reasonable chance of success based on a brief inspection of the file header.
*
- * @return a {@linkplain ProbeResult#isSupported() supported} status with the MIME type
- * if the given storage seems to be readable as a CSV file.
+ * @return a {@linkplain ProbeResult#isSupported() supported} status with the <abbr>MIME</abbr> type
+ * if the given storage seems to be readable as a <abbr>CSV</abbr> file.
* @throws DataStoreException if an I/O error occurred.
*/
@Override
@@ -162,7 +158,7 @@ public final class StoreProvider extends URIDataStoreProvider {
}
/**
- * Returns a CSV {@link Store} implementation associated with this provider.
+ * Returns a <abbr>CSV</abbr> {@link Store} implementation associated with this provider.
*
* @param connector information about the storage (URL, stream, <i>etc</i>).
* @return a data store implementation associated with this provider for the given storage.
@@ -173,31 +169,6 @@ public final class StoreProvider extends URIDataStoreProvider {
return new Store(this, connector);
}
- /**
- * Returns a CSV {@link Store} implementation from the given parameters.
- *
- * @return a data store implementation associated with this provider for the given parameters.
- * @throws DataStoreException if an error occurred while creating the data store instance.
- */
- @Override
- public DataStore open(final ParameterValueGroup parameters) throws DataStoreException {
- final StorageConnector connector = connector(this, parameters);
- final Parameters pg = Parameters.castOrWrap(parameters);
- connector.setOption(OptionKey.ENCODING, pg.getValue(ENCODING));
- connector.setOption(OptionKey.FOLIATION_REPRESENTATION, pg.getValue(FOLIATION));
- return new Store(this, connector);
- }
-
- /**
- * Invoked by {@link #getOpenParameters()} the first time that a parameter descriptor needs to be created.
- *
- * @return the parameters descriptor for CSV files.
- */
- @Override
- protected ParameterDescriptorGroup build(final ParameterBuilder builder) {
- return builder.createGroup(LOCATION_PARAM, METADATA_PARAM, ENCODING, FOLIATION);
- }
-
/**
* Returns the logger used by <abbr>CSV</abbr> stores.
*/
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/AsciiGridStore.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/AsciiGridStore.java
index 112b6237b7..6db61bb0f1 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/AsciiGridStore.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/AsciiGridStore.java
@@ -46,13 +46,13 @@ import org.apache.sis.util.resources.Errors;
/**
- * Data store implementation for ESRI ASCII grid format.
+ * Data store implementation for <abbr>ESRI</abbr> <abbr>ASCII</abbr> grid format.
* This is a very simple format for reading and writing single-banded raster data.
* As the "ASCII" name implies, files are text files in US-ASCII character encoding
* no matter what the {@link OptionKey#ENCODING} value is, and numbers are parsed or
* formatted according the US locale no matter what the {@link OptionKey#LOCALE} value is.
*
- * <p>ASCII grid files contains a header before the actual data.
+ * <p><abbr>ASCII</abbr> grid files contains a header before the actual data.
* The header contains (<var>key</var> <var>value</var>) pairs,
* one pair per line and using spaces as separator between keys and values.
* The valid keys are listed in the table below
@@ -240,6 +240,7 @@ class AsciiGridStore extends RasterStore {
* <p>Note: we don't do this initialization in the constructor
* for giving a chance for users to register listeners first.</p>
*/
+ @SuppressWarnings("UseSpecificCatch")
private void readHeader() throws DataStoreException {
if (gridGeometry == null) try {
final Map<String,String> header = input().readHeader();
@@ -417,6 +418,7 @@ cellsize: if (value != null) {
* @throws DataStoreException if an error occurred while reading the grid coverage data.
*/
@Override
+ @SuppressWarnings("UseSpecificCatch")
public synchronized GridCoverage read(final GridGeometry domain, final int... ranges) throws DataStoreException {
final RangeArgument bands = RangeArgument.validate(1, ranges, listeners);
if (coverage == null) try {
@@ -554,6 +556,7 @@ cellsize: if (value != null) {
* Closes this data store after an unrecoverable error occurred.
* The caller is expected to throw the given exception after this method call.
*/
+ @SuppressWarnings("UseSpecificCatch")
final void closeOnError(final Throwable e) {
try {
close();
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/AsciiGridStoreProvider.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/AsciiGridStoreProvider.java
index e0120b0c18..f23d78353d 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/AsciiGridStoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/AsciiGridStoreProvider.java
@@ -27,7 +27,8 @@ import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.GridCoverageResource;
import org.apache.sis.storage.base.Capability;
import org.apache.sis.storage.base.StoreMetadata;
-import org.apache.sis.storage.base.PRJDataStore;
+import org.apache.sis.storage.base.URIDataStoreOption;
+import org.apache.sis.storage.base.URIDataStoreProvider;
/**
@@ -44,7 +45,7 @@ import org.apache.sis.storage.base.PRJDataStore;
fileSuffixes = {"asc", "grd", "agr", "aig"},
capabilities = {Capability.READ, Capability.WRITE, Capability.CREATE},
resourceTypes = GridCoverageResource.class)
-public final class AsciiGridStoreProvider extends PRJDataStore.Provider {
+public final class AsciiGridStoreProvider extends URIDataStoreProvider {
/**
* The format names for ESRI ASCII grid files.
*/
@@ -61,6 +62,8 @@ public final class AsciiGridStoreProvider extends PRJDataStore.Provider {
* Creates a new provider.
*/
public AsciiGridStoreProvider() {
+ supportedOptions.add(URIDataStoreOption.DEFAULT_CRS);
+ supportedOptions.add(URIDataStoreOption.METADATA);
}
/**
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
index 225590bc00..2edabbc94b 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RasterStore.java
@@ -55,7 +55,7 @@ import org.apache.sis.math.Statistics;
/**
- * Base class for the implementation of ASCII Grid or raw binary store.
+ * Base class for the implementation of <abbr>ASCII</abbr> Grid or raw binary store.
* This base class manages the reading of following auxiliary files:
*
* <ul>
@@ -277,7 +277,7 @@ abstract class RasterStore extends PRJDataStore implements GridCoverageResource
private Statistics[] readStatistics(final String name, final SampleModel sm)
throws DataStoreException, URISyntaxException, IOException
{
- final Statistics[] stats = new Statistics[sm.getNumBands()];
+ final var stats = new Statistics[sm.getNumBands()];
for (final CharSequence line : CharSequences.splitOnEOL(readAuxiliaryFile(STX, false))) {
final int end = CharSequences.skipTrailingWhitespaces(line, 0, line.length());
final int start = CharSequences.skipLeadingWhitespaces(line, 0, end);
@@ -323,7 +323,7 @@ abstract class RasterStore extends PRJDataStore implements GridCoverageResource
* @throws DataStoreException if an error occurred while loading an auxiliary file.
*/
final void loadBandDescriptions(String name, final SampleModel sm, Statistics... stats) throws DataStoreException {
- final SampleDimension[] bands = new SampleDimension[sm.getNumBands()];
+ final var bands = new SampleDimension[sm.getNumBands()];
/*
* If the "*.stx" file is found, the statistics read from that file will replace the specified one.
* Otherwise the `stats` parameter will be left unchanged. We read statistics even if a color map
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RawRasterStore.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RawRasterStore.java
index f7a7a31a32..a165413074 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RawRasterStore.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RawRasterStore.java
@@ -56,7 +56,7 @@ import static org.apache.sis.pending.jdk.JDK18.ceilDiv;
/**
- * Data store implementation for BIL, BIP, and BSQ raster files.
+ * Data store implementation for <abbr>BIL</abbr>, <abbr>BIP</abbr>, and <abbr>BSQ</abbr> raster files.
* Sample values are provided in a raw binary files, without compression.
* Information about image layout is provided in a separated text files.
*
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RawRasterStoreProvider.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RawRasterStoreProvider.java
index 78d912fa71..cb8342a696 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RawRasterStoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/esri/RawRasterStoreProvider.java
@@ -27,7 +27,8 @@ import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.base.Capability;
import org.apache.sis.storage.base.StoreMetadata;
-import org.apache.sis.storage.base.PRJDataStore;
+import org.apache.sis.storage.base.URIDataStoreOption;
+import org.apache.sis.storage.base.URIDataStoreProvider;
import org.apache.sis.io.stream.IOUtilities;
@@ -46,7 +47,7 @@ import org.apache.sis.io.stream.IOUtilities;
fileSuffixes = {"bil", "bip", "bsq"},
capabilities = Capability.READ,
resourceTypes = GridCoverageResource.class)
-public final class RawRasterStoreProvider extends PRJDataStore.Provider {
+public final class RawRasterStoreProvider extends URIDataStoreProvider {
/**
* The format names for raw binary raster files.
*/
@@ -68,6 +69,8 @@ public final class RawRasterStoreProvider extends PRJDataStore.Provider {
* Creates a new provider.
*/
public RawRasterStoreProvider() {
+ supportedOptions.add(URIDataStoreOption.DEFAULT_CRS);
+ supportedOptions.add(URIDataStoreOption.METADATA);
}
/**
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 6e50f868da..6d377432cd 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
@@ -20,14 +20,11 @@ import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Locale;
import java.util.Optional;
import java.util.logging.Level;
import java.util.concurrent.ConcurrentHashMap;
-import java.time.ZoneId;
import java.io.IOException;
import java.io.UncheckedIOException;
-import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Files;
import java.nio.file.DirectoryStream;
@@ -52,6 +49,8 @@ import org.apache.sis.storage.aggregate.CoverageAggregator;
import org.apache.sis.storage.metadata.MetadataBuilder;
import org.apache.sis.storage.base.StoreUtilities;
import org.apache.sis.storage.base.StoreResource;
+import org.apache.sis.storage.base.URIDataStore;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.storage.internal.Resources;
import org.apache.sis.util.iso.DefaultNameFactory;
import org.apache.sis.util.collection.Containers;
@@ -77,18 +76,13 @@ import org.apache.sis.util.collection.BackingStoreException;
* @author Johann Sorel (Geomatys)
* @author Martin Desruisseaux (Geomatys)
*/
-class Store extends DataStore implements StoreResource, UnstructuredAggregate, DirectoryStream.Filter<Path> {
+class Store extends URIDataStore implements StoreResource, UnstructuredAggregate, DirectoryStream.Filter<Path> {
/**
* The data store for the root directory specified by the user.
* May be {@code this} if this store instance is for the root directory.
*/
private final Store originator;
- /**
- * The {@link StoreProvider#LOCATION} parameter value.
- */
- protected final Path location;
-
/**
* An identifier for this folder, or {@code null} if not yet created. Only the root folder specified by
* user has an initially null identifier. All sub-folders shall have a non-null identifier determined
@@ -108,7 +102,7 @@ class Store extends DataStore implements StoreResource, UnstructuredAggregate, D
* All data stores (including sub-folders) found in the directory structure, including the root directory.
* This is used for avoiding never-ending loop with symbolic links.
*/
- final Map<Path,DataStore> children;
+ final Map<Path, DataStore> children;
/**
* Information about the data store as a whole, created when first needed.
@@ -132,7 +126,7 @@ class Store extends DataStore implements StoreResource, UnstructuredAggregate, D
protected final DataStoreProvider componentProvider;
/**
- * {@code true} if {@link #sharedRepository(Path)} has already been invoked for {@link #location} path.
+ * {@code true} if {@link #sharedRepository(Path)} has already been invoked for {@link #locationAsPath}.
* This is used for avoiding to report the same message many times.
*/
private transient boolean sharedRepositoryReported;
@@ -159,13 +153,13 @@ class Store extends DataStore implements StoreResource, UnstructuredAggregate, D
* @throws DataStoreException if an error occurred while fetching the directory {@link Path}.
* @throws IOException if an error occurred while using the directory {@code Path}.
*/
+ @SuppressWarnings("LeakingThisInConstructor")
Store(final DataStoreProvider provider, final StorageConnector connector, final Path path, final DataStoreProvider format)
throws DataStoreException, IOException
{
super(provider, connector);
configuration = connector;
originator = this;
- location = path;
children = new ConcurrentHashMap<>();
children.put(path.toRealPath(), this);
componentProvider = format;
@@ -182,7 +176,6 @@ class Store extends DataStore implements StoreResource, UnstructuredAggregate, D
super(parent, parent.getProvider(), connector, false);
configuration = parent.configuration;
originator = parent;
- location = connector.commit(Path.class, StoreProvider.NAME);
children = parent.children;
componentProvider = parent.componentProvider;
identifier = nameFactory.createLocalName(parent.identifier(nameFactory).scope(), super.getDisplayName());
@@ -196,22 +189,21 @@ class Store extends DataStore implements StoreResource, UnstructuredAggregate, D
return originator;
}
+ /**
+ * For access to protected member from other instances.
+ */
+ final Path location() {
+ return locationAsPath;
+ }
+
/**
* Returns the parameters used to open this data store.
*/
@Override
public Optional<ParameterValueGroup> getOpenParameters() {
- 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);
- ZoneId 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);
- if (format != null) pg.parameter("format" ).setValue(format);
- return Optional.of(pg);
+ final Optional<ParameterValueGroup> parameters = super.getOpenParameters();
+ parameters.ifPresent((pg) -> URIDataStoreOption.FORMAT.setValueOf(pg, StoreUtilities.getFormatName(componentProvider)));
+ return parameters;
}
/**
@@ -293,7 +285,7 @@ class Store extends DataStore implements StoreResource, UnstructuredAggregate, D
if (components == null) {
final var resources = new ArrayList<DataStore>();
final var nameFactory = DefaultNameFactory.provider();
- try (DirectoryStream<Path> stream = Files.newDirectoryStream(location, this)) {
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(locationAsPath, this)) {
for (final Path candidate : stream) {
/*
* The candidate path may be a symbolic link to a file that we have previously read.
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/folder/StoreProvider.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/folder/StoreProvider.java
index bd40e74acf..d3a4571822 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/folder/StoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/folder/StoreProvider.java
@@ -17,11 +17,8 @@
package org.apache.sis.storage.folder;
import java.util.EnumSet;
-import java.util.Locale;
import java.util.logging.Logger;
-import java.time.ZoneId;
import java.io.IOException;
-import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Files;
import java.nio.file.FileAlreadyExistsException;
@@ -30,11 +27,8 @@ import java.nio.file.NoSuchFileException;
import java.nio.file.StandardOpenOption;
import org.opengis.util.InternationalString;
import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterDescriptorGroup;
import org.apache.sis.parameter.ParameterBuilder;
-import org.apache.sis.parameter.Parameters;
-import org.apache.sis.storage.OptionKey;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreProvider;
import org.apache.sis.storage.DataStoreException;
@@ -48,6 +42,7 @@ import org.apache.sis.storage.base.URIDataStoreProvider;
import org.apache.sis.storage.base.Capability;
import org.apache.sis.storage.base.StoreMetadata;
import org.apache.sis.storage.base.StoreUtilities;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.util.logging.Logging;
@@ -63,7 +58,7 @@ import org.apache.sis.util.logging.Logging;
capabilities = {Capability.READ, Capability.WRITE},
resourceTypes = {Aggregate.class, FeatureSet.class, GridCoverageResource.class},
yieldPriority = true)
-public final class StoreProvider extends DataStoreProvider {
+public final class StoreProvider extends URIDataStoreProvider {
/**
* A short name or abbreviation for the data format.
*/
@@ -77,53 +72,29 @@ public final class StoreProvider extends DataStoreProvider {
private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.folder");
/**
- * Description of the parameter for formatting conventions of dates and numbers.
+ * The default provider instance.
*/
- private static final ParameterDescriptor<Locale> LOCALE;
+ private static final StoreProvider INSTANCE = new StoreProvider();
/**
- * Description of the parameter for timezone of dates in the data store.
- */
- private static final ParameterDescriptor<ZoneId> TIMEZONE;
-
- /**
- * Description of the parameter for character encoding used by the data store.
- */
- private static final ParameterDescriptor<Charset> ENCODING;
-
- /**
- * Description of the parameter for name of format or {@code DataStoreProvider}
- * to use for reading or writing the directory content.
- */
- private static final ParameterDescriptor<String> FORMAT;
-
- /**
- * The group of parameter descriptors to be returned by {@link #getOpenParameters()}.
- */
- static final ParameterDescriptorGroup PARAMETERS;
- static {
- final ParameterDescriptor<Path> location;
- final ParameterBuilder builder = new ParameterBuilder();
- final InternationalString remark = Resources.formatInternational(Resources.Keys.UsedOnlyIfNotEncoded);
- ENCODING = annotate(builder, URIDataStoreProvider.ENCODING, remark);
- LOCALE = builder.addName("locale" ).setDescription(Resources.formatInternational(Resources.Keys.DataStoreLocale )).setRemarks(remark).create(Locale.class, null);
- TIMEZONE = builder.addName("timezone").setDescription(Resources.formatInternational(Resources.Keys.DataStoreTimeZone)).setRemarks(remark).create(ZoneId.class, null);
- FORMAT = builder.addName("format" ).setDescription(Resources.formatInternational(Resources.Keys.DirectoryContentFormatName)).create(String.class, null);
- location = new ParameterBuilder(URIDataStoreProvider.LOCATION_PARAM).create(Path.class, null);
- PARAMETERS = builder.addName(NAME).createGroup(location, LOCALE, TIMEZONE, ENCODING, FORMAT, URIDataStoreProvider.CREATE_PARAM);
- }
-
- /**
- * Creates a parameter descriptor equals to the given one except for the remarks which are set to the given value.
+ * Returns the default provider instance.
+ * This method is invoked by Java service loader.
+ *
+ * @return the default provider instance.
*/
- private static <T> ParameterDescriptor<T> annotate(ParameterBuilder builder, ParameterDescriptor<T> e, InternationalString remark) {
- return builder.addName(e.getName()).setDescription(e.getDescription().orElse(null)).setRemarks(remark).create(e.getValueClass(), null);
+ public static StoreProvider provider() {
+ return INSTANCE;
}
/**
* Creates a new provider.
*/
public StoreProvider() {
+ supportedOptions.add(URIDataStoreOption.CREATE);
+ supportedOptions.add(URIDataStoreOption.FORMAT);
+ supportedOptions.add(URIDataStoreOption.LOCALE);
+ supportedOptions.add(URIDataStoreOption.ENCODING);
+ supportedOptions.add(URIDataStoreOption.TIMEZONE);
}
/**
@@ -137,13 +108,22 @@ public final class StoreProvider extends DataStoreProvider {
}
/**
- * Returns a description of all parameters accepted by this provider for opening a data store.
+ * Invoked by {@link #getOpenParameters()} the first time that a parameter descriptor needs to be created.
*
- * @return description of the parameters for opening a {@link DataStore}.
+ * @param builder the builder to use for creating parameter descriptor. The group name is already set.
+ * @return the parameters descriptor created from the given builder.
*/
@Override
- public ParameterDescriptorGroup getOpenParameters() {
- return PARAMETERS;
+ protected ParameterDescriptorGroup createOpenParameters(final ParameterBuilder builder) {
+ final InternationalString remark = Resources.formatInternational(Resources.Keys.UsedOnlyIfNotEncoded);
+ final var p = new ParameterBuilder();
+ return builder.createGroup(
+ URIDataStoreOption.LOCATION.deriveParameterDescriptor(p, Path.class, null),
+ URIDataStoreOption.ENCODING.deriveParameterDescriptor(p, null, remark),
+ URIDataStoreOption.TIMEZONE.deriveParameterDescriptor(p, null, remark),
+ URIDataStoreOption.LOCALE .deriveParameterDescriptor(p, null, remark),
+ URIDataStoreOption.FORMAT.getParameterDescriptor(),
+ URIDataStoreOption.CREATE.getParameterDescriptor());
}
/**
@@ -274,16 +254,10 @@ public final class StoreProvider extends DataStoreProvider {
*/
@Override
public DataStore open(final ParameterValueGroup parameters) throws DataStoreException {
- final StorageConnector connector = URIDataStoreProvider.connector(this, parameters);
- final Parameters pg = Parameters.castOrWrap(parameters);
- connector.setOption(OptionKey.LOCALE, pg.getValue(LOCALE));
- connector.setOption(OptionKey.TIMEZONE, pg.getValue(TIMEZONE));
- connector.setOption(OptionKey.ENCODING, pg.getValue(ENCODING));
- final EnumSet<StandardOpenOption> options = EnumSet.of(StandardOpenOption.WRITE);
- if (Boolean.TRUE.equals(pg.getValue(URIDataStoreProvider.CREATE_PARAM))) {
- options.add(StandardOpenOption.CREATE);
- }
- return open(connector, pg.getValue(FORMAT), options);
+ final EnumSet<StandardOpenOption> openOptions = EnumSet.noneOf(StandardOpenOption.class);
+ final StorageConnector connector = connector(parameters, openOptions);
+ final Object format = parameters.parameter(FORMAT).getValue();
+ return open(connector, (format != null) ? format.toString() : null, openOptions);
}
/**
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 3c9cff1d44..4d329fcd0d 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
@@ -104,9 +104,9 @@ final class WritableStore extends Store implements WritableAggregate {
* Create new store/resource for write access, provided that no store already exist for the path.
* We use the CREATE_NEW option in order to intentionally fail if the resource already exists.
*/
- final Path path = location.resolve(filename);
+ final Path path = locationAsPath.resolve(filename);
if (!children.containsKey(path)) {
- final StorageConnector connector = new StorageConnector(configuration, path);
+ final var connector = new StorageConnector(configuration, path);
connector.setOption(OptionKey.OPEN_OPTIONS, new StandardOpenOption[] {
StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE
});
@@ -150,8 +150,8 @@ final class WritableStore extends Store implements WritableAggregate {
public synchronized void remove(final Resource resource) throws DataStoreException {
if (resource instanceof DataStore) try {
if (resource instanceof Store) {
- final Path path = ((Store) resource).location;
- if (Files.isSameFile(path.getParent(), location)) {
+ final Path path = ((Store) resource).location();
+ if (Files.isSameFile(path.getParent(), locationAsPath)) {
((Store) resource).close();
deleteRecursively(path, true);
children.remove(path);
@@ -162,7 +162,7 @@ final class WritableStore extends Store implements WritableAggregate {
if (fileset != null) {
for (Path root : fileset.getPaths()) {
root = root.getParent();
- if (root != null && Files.isSameFile(root, location)) {
+ if (root != null && Files.isSameFile(root, locationAsPath)) {
/*
* If we enter in this block, we have determined that the main file is located in the
* directory managed by this store - NOT in a subdirectory because they could be managed
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WorldFileStoreProvider.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WorldFileStoreProvider.java
index fd8e0463db..77cf587163 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WorldFileStoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/image/WorldFileStoreProvider.java
@@ -28,7 +28,8 @@ import org.apache.sis.storage.Aggregate;
import org.apache.sis.storage.ProbeResult;
import org.apache.sis.storage.base.Capability;
import org.apache.sis.storage.base.StoreMetadata;
-import org.apache.sis.storage.base.PRJDataStore;
+import org.apache.sis.storage.base.URIDataStoreOption;
+import org.apache.sis.storage.base.URIDataStoreProvider;
import org.apache.sis.io.stream.IOUtilities;
import org.apache.sis.util.ArraysExt;
@@ -42,7 +43,7 @@ import org.apache.sis.util.ArraysExt;
fileSuffixes = {"jpeg", "jpg", "png", "gif", "bmp"}, // Non-exhaustive list, intentionally excluding TIFF.
capabilities = {Capability.READ, Capability.WRITE, Capability.CREATE},
resourceTypes = {Aggregate.class, GridCoverageResource.class})
-public final class WorldFileStoreProvider extends PRJDataStore.Provider {
+public final class WorldFileStoreProvider extends URIDataStoreProvider {
/**
* The format name.
*/
@@ -77,7 +78,7 @@ public final class WorldFileStoreProvider extends PRJDataStore.Provider {
* Creates a new provider.
*/
public WorldFileStoreProvider() {
- allowSingleton = true;
+ this(true);
}
/**
@@ -90,6 +91,8 @@ public final class WorldFileStoreProvider extends PRJDataStore.Provider {
* instead of {@code Aggregate} instances.
*/
public WorldFileStoreProvider(final boolean allowSingleton) {
+ supportedOptions.add(URIDataStoreOption.DEFAULT_CRS);
+ supportedOptions.add(URIDataStoreOption.METADATA);
this.allowSingleton = allowSingleton;
}
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.java
index a3b4fc5f6b..7f2a153b78 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.java
@@ -214,10 +214,15 @@ public class Resources extends IndexedResourceBundle {
public static final short DataStoreLocation = 31;
/**
- * Timezone of dates in the data store.
+ * Timezone of local times in the data store.
*/
public static final short DataStoreTimeZone = 32;
+ /**
+ * Default coordinate reference system.
+ */
+ public static final short DefaultCRS = 88;
+
/**
* Name of the format to use for reading or writing the directory content.
*/
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.properties b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.properties
index 8d78743ee0..19613a17b4 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.properties
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources.properties
@@ -48,7 +48,8 @@ DataStoreCreate = Whether to allow new data store creation if
DataStoreEncoding = Character encoding used by the data store.
DataStoreLocale = Formatting conventions of dates and numbers.
DataStoreLocation = Data store location as a file or URL.
-DataStoreTimeZone = Timezone of dates in the data store.
+DataStoreTimeZone = Timezone of local times in the data store.
+DefaultCRS = Default coordinate reference system.
DirectoryContent_1 = Content of \u201c{0}\u201d directory.
DirectoryContentFormatName = Name of the format to use for reading or writing the directory content.
DuplicatedQueryProperty_3 = Query property \u201c{0}\u201d is duplicated at indices {1} and {2}.
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources_fr.properties b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources_fr.properties
index 187097a201..ad8399b738 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources_fr.properties
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/internal/Resources_fr.properties
@@ -53,7 +53,8 @@ DataStoreCreate = Indique si l\u2019on autorise la cr\u00e9ati
DataStoreEncoding = Encodage des caract\u00e8res utilis\u00e9 par la source de donn\u00e9es.
DataStoreLocale = Conventions d\u2019\u00e9criture des dates et des nombres.
DataStoreLocation = Chemin (fichier ou URL) vers la source de donn\u00e9es.
-DataStoreTimeZone = Fuseau horaire des dates dans les donn\u00e9es.
+DataStoreTimeZone = Fuseau horaire des heures locales dans les donn\u00e9es.
+DefaultCRS = Syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es par d\u00e9faut.
DirectoryContent_1 = Contenu du r\u00e9pertoire \u00ab\u202f{0}\u202f\u00bb.
DirectoryContentFormatName = Nom du format ou de la source de donn\u00e9es \u00e0 utiliser pour lire ou \u00e9crire le contenu du r\u00e9pertoire.
DuplicatedQueryProperty_3 = La propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb de la requ\u00eate est dupliqu\u00e9e aux indices {1} et {2}.
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/Store.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/Store.java
index 9b85043f16..aa2996c988 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/Store.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/Store.java
@@ -39,11 +39,11 @@ import org.apache.sis.util.CharSequences;
/**
- * A data store which creates data objects from a WKT definition.
+ * A data store which creates data objects from a <abbr>WKT</abbr> definition.
*
* <h4>Design note</h4>
- * this class differs from {@link org.apache.sis.storage.base.PRJDataStore} in that
- * the file containing WKT definition is the main file, not an auxiliary file.
+ * This class differs from {@link org.apache.sis.storage.base.PRJDataStore} in that the
+ * file containing <abbr>WKT</abbr> definition is the main file, not an auxiliary file.
*
* @author Martin Desruisseaux (Geomatys)
*/
@@ -124,8 +124,8 @@ final class Store extends URIDataStore {
* one WKT definitions, but this DataStore nevertheless allows an arbitrary number of consecutive
* definitions.
*/
- final ParsePosition pos = new ParsePosition(0);
- final StoreFormat parser = new StoreFormat(dataLocale, timezone, library, listeners);
+ final var pos = new ParsePosition(0);
+ final var parser = new StoreFormat(dataLocale, timezone, library, listeners);
do {
final Object obj = parser.parse(wkt, pos);
objects.add(obj);
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/StoreFormat.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/StoreFormat.java
index 7dec0e1fe7..df464ea39f 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/StoreFormat.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/StoreFormat.java
@@ -104,7 +104,7 @@ public final class StoreFormat extends WKTFormat {
*/
public CoordinateReferenceSystem parseCRS(final String... wkt) {
try {
- final CoordinateReferenceSystem[] components = new CoordinateReferenceSystem[wkt.length];
+ final var components = new CoordinateReferenceSystem[wkt.length];
int n = 0;
for (final String ct : wkt) {
if (ct != null) {
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/StoreProvider.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/StoreProvider.java
index 1ca162c9c5..63153b5148 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/StoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/StoreProvider.java
@@ -16,8 +16,6 @@
*/
package org.apache.sis.storage.wkt;
-import java.util.Collections;
-import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
import org.apache.sis.storage.DataStore;
@@ -26,13 +24,14 @@ import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.ProbeResult;
import org.apache.sis.storage.base.Capability;
import org.apache.sis.storage.base.StoreMetadata;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.storage.base.URIDataStoreProvider;
import org.apache.sis.referencing.internal.shared.WKTKeywords;
import org.apache.sis.util.Version;
/**
- * The provider of WKT {@link Store} instances.
+ * The provider of <abbr>WKT</abbr> {@link Store} instances.
*
* @author Martin Desruisseaux (Geomatys)
*/
@@ -68,45 +67,38 @@ public final class StoreProvider extends URIDataStoreProvider {
static final int MIN_LENGTH = 6;
/**
- * The set of WKT keywords for CRS definitions.
- * This set does not include the WKT keywords for coordinate operations,
- * because the WKT store can only return metadata and metadata can only store the CRS.
+ * The set of <abbr>WKT</abbr> keywords for <abbr>CRS</abbr> definitions.
+ * This set does not include the <abbr>WKT</abbr> keywords for coordinate operations,
+ * because the <abbr>WKT</abbr> store can only return metadata and metadata can only
+ * store the <abbr>CRS</abbr>s.
*/
- private final Set<String> keywords;
+ final Set<String> keywords;
/**
* Creates the unique instance.
*/
private Peek() {
super(14);
- final Set<String> s = new HashSet<>(22);
- s.add(WKTKeywords.GeodeticCRS);
- s.add(WKTKeywords.GeodCRS);
- s.add(WKTKeywords.GeogCS);
- s.add(WKTKeywords.GeocCS);
- s.add(WKTKeywords.VerticalCRS);
- s.add(WKTKeywords.VertCRS);
- s.add(WKTKeywords.Vert_CS);
- s.add(WKTKeywords.TimeCRS);
- s.add(WKTKeywords.ImageCRS);
- s.add(WKTKeywords.EngineeringCRS);
- s.add(WKTKeywords.EngCRS);
- s.add(WKTKeywords.Local_CS);
- s.add(WKTKeywords.CompoundCRS);
- s.add(WKTKeywords.Compd_CS);
- s.add(WKTKeywords.ProjectedCRS);
- s.add(WKTKeywords.ProjCRS);
- s.add(WKTKeywords.ProjCS);
- s.add(WKTKeywords.Fitted_CS);
- s.add(WKTKeywords.BoundCRS);
- keywords = s;
- }
-
- /**
- * Returns the keywords for test purpose.
- */
- final Set<String> keywords() {
- return Collections.unmodifiableSet(keywords);
+ keywords = Set.of(
+ WKTKeywords.GeodeticCRS,
+ WKTKeywords.GeodCRS,
+ WKTKeywords.GeogCS,
+ WKTKeywords.GeocCS,
+ WKTKeywords.VerticalCRS,
+ WKTKeywords.VertCRS,
+ WKTKeywords.Vert_CS,
+ WKTKeywords.TimeCRS,
+ WKTKeywords.ImageCRS,
+ WKTKeywords.EngineeringCRS,
+ WKTKeywords.EngCRS,
+ WKTKeywords.Local_CS,
+ WKTKeywords.CompoundCRS,
+ WKTKeywords.Compd_CS,
+ WKTKeywords.ProjectedCRS,
+ WKTKeywords.ProjCRS,
+ WKTKeywords.ProjCS,
+ WKTKeywords.Fitted_CS,
+ WKTKeywords.BoundCRS);
}
/**
@@ -152,6 +144,7 @@ public final class StoreProvider extends URIDataStoreProvider {
* Creates a new provider.
*/
public StoreProvider() {
+ supportedOptions.add(URIDataStoreOption.METADATA);
}
/**
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/AbstractProvider.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/AbstractProvider.java
index 56e3e53326..03ddd83baa 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/AbstractProvider.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/AbstractProvider.java
@@ -30,9 +30,9 @@ import org.apache.sis.storage.base.DocumentedStoreProvider;
/**
- * Base class for providers of {@link DataStore} implementations for XML files.
+ * Base class for providers of {@link DataStore} implementations for <abbr>XML</abbr> files.
* This base class does not assume that the data store will use any particular framework
- * (JAXB, StAX, <i>etc</i>).
+ * (<abbr>JAXB</abbr>, <abbr>StAX</abbr>, <i>etc</i>).
*
* @author Martin Desruisseaux (Geomatys)
*/
@@ -65,7 +65,7 @@ public abstract class AbstractProvider extends DocumentedStoreProvider {
* <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;
+ protected final Map<String, String> mimeForNameSpaces;
/**
* The mapping from root elements to MIME types. Used only if the root element is in
@@ -77,7 +77,7 @@ public abstract class AbstractProvider extends DocumentedStoreProvider {
* <tr><td>MD_Metadata</td> <td>application/vnd.iso.19139+xml</td></tr>
* </table>
*/
- protected final Map<String,String> mimeForRootElements;
+ protected final Map<String, String> mimeForRootElements;
/**
* Creates a new provider.
@@ -86,7 +86,10 @@ public abstract class AbstractProvider extends DocumentedStoreProvider {
* @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, final Map<String,String> mimeForNameSpaces, final Map<String,String> mimeForRootElements) {
+ protected AbstractProvider(final String name,
+ final Map<String, String> mimeForNameSpaces,
+ final Map<String, String> mimeForRootElements)
+ {
super(name);
this.mimeForNameSpaces = mimeForNameSpaces;
this.mimeForRootElements = mimeForRootElements;
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/StoreProvider.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/StoreProvider.java
index d3f522ca27..a8f9f8d6e8 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/StoreProvider.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/xml/StoreProvider.java
@@ -43,7 +43,7 @@ public final class StoreProvider extends AbstractProvider {
public static final String NAME = "XML";
/**
- * The logger used by XML stores.
+ * The logger used by <abbr>XML</abbr> stores.
*
* @see #getLogger()
*/
diff --git a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/csv/StoreTest.java b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/csv/StoreTest.java
index 7520a27c08..971ca53dd4 100644
--- a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/csv/StoreTest.java
+++ b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/csv/StoreTest.java
@@ -85,7 +85,8 @@ public final class StoreTest extends TestCase {
}
/**
- * Opens a CSV store on the test data for reading the lines as-is, without assembling them in a single trajectory.
+ * Opens a <abbr>CSV</abbr> store on the test data for reading the lines as-is,
+ * without assembling them in a single trajectory.
*/
private static Store open(final boolean fragmented) throws DataStoreException {
final var connector = new StorageConnector(testData());
diff --git a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/folder/StoreTest.java b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/folder/StoreTest.java
index 33b1d9041b..73fe86ca53 100644
--- a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/folder/StoreTest.java
+++ b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/folder/StoreTest.java
@@ -96,7 +96,7 @@ public final class StoreTest extends TestCaseWithLogs {
public void testSearchProviderParameter() throws URISyntaxException, DataStoreException, IOException {
final StoreProvider provider = new StoreProvider();
final Set<String> identifiers = new HashSet<>(List.of("Sample 1", "Sample 2", "Sample 3", "data4"));
- final ParameterValueGroup params = StoreProvider.PARAMETERS.createValue();
+ final ParameterValueGroup params = StoreProvider.provider().getOpenParameters().createValue();
params.parameter("location").setValue(testDirectory());
params.parameter("format").setValue("XML");
try (Store store = (Store) provider.open(params)) {
diff --git a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/wkt/StoreProviderTest.java b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/wkt/StoreProviderTest.java
index 9922e906be..5d9330d644 100644
--- a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/wkt/StoreProviderTest.java
+++ b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/wkt/StoreProviderTest.java
@@ -47,7 +47,7 @@ public final class StoreProviderTest extends TestCase {
public void testKeywordsMap() {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
- for (final String keyword : StoreProvider.Peek.INSTANCE.keywords()) {
+ for (final String keyword : StoreProvider.Peek.INSTANCE.keywords) {
final int length = keyword.length();
if (length < min) min = length;
if (length > max) max = length;
@@ -63,7 +63,7 @@ public final class StoreProviderTest extends TestCase {
*/
@Test
public void testProbeContentFromReader() throws DataStoreException {
- final StoreProvider p = new StoreProvider();
+ final var p = new StoreProvider();
testProbeContentFromReader(true, 1, p, StoreTest.WKT);
testProbeContentFromReader(true, 2, p, "GeodeticCRS[…]");
testProbeContentFromReader(true, 2, p, "GeodeticCRS(…)");
@@ -80,7 +80,7 @@ public final class StoreProviderTest extends TestCase {
private static void testProbeContentFromReader(final boolean isSupported, final int version,
final StoreProvider p, final String wkt) throws DataStoreException
{
- final StorageConnector c = new StorageConnector(new StringReader(wkt));
+ final var c = new StorageConnector(new StringReader(wkt));
final ProbeResult r = p.probeContent(c);
c.closeAllExcept(null);
assertEquals(isSupported, r.isSupported());
diff --git a/incubator/src/org.apache.sis.storage.coveragejson/main/org/apache/sis/storage/coveragejson/CoverageJsonStore.java b/incubator/src/org.apache.sis.storage.coveragejson/main/org/apache/sis/storage/coveragejson/CoverageJsonStore.java
index ebc5a6f9f5..b66562a3d0 100644
--- a/incubator/src/org.apache.sis.storage.coveragejson/main/org/apache/sis/storage/coveragejson/CoverageJsonStore.java
+++ b/incubator/src/org.apache.sis.storage.coveragejson/main/org/apache/sis/storage/coveragejson/CoverageJsonStore.java
@@ -45,7 +45,7 @@ import org.apache.sis.storage.coveragejson.binding.Coverage;
import org.apache.sis.storage.coveragejson.binding.CoverageCollection;
import org.apache.sis.storage.coveragejson.binding.CoverageJsonObject;
import org.apache.sis.storage.metadata.MetadataBuilder;
-import org.apache.sis.storage.base.URIDataStore;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.io.stream.IOUtilities;
@@ -81,7 +81,7 @@ public class CoverageJsonStore extends DataStore implements WritableAggregate {
@Override
public Optional<ParameterValueGroup> getOpenParameters() {
- return Optional.ofNullable(URIDataStore.parameters(provider, location));
+ return Optional.ofNullable(URIDataStoreOption.createWithLocationOnly(provider, location));
}
@Override
diff --git a/incubator/src/org.apache.sis.storage.coveragejson/main/org/apache/sis/storage/coveragejson/CoverageJsonStoreProvider.java b/incubator/src/org.apache.sis.storage.coveragejson/main/org/apache/sis/storage/coveragejson/CoverageJsonStoreProvider.java
index cbfca0a647..2cb2fce6c4 100644
--- a/incubator/src/org.apache.sis.storage.coveragejson/main/org/apache/sis/storage/coveragejson/CoverageJsonStoreProvider.java
+++ b/incubator/src/org.apache.sis.storage.coveragejson/main/org/apache/sis/storage/coveragejson/CoverageJsonStoreProvider.java
@@ -19,7 +19,6 @@ package org.apache.sis.storage.coveragejson;
import java.net.URI;
import java.util.logging.Logger;
import org.opengis.parameter.ParameterDescriptorGroup;
-import org.apache.sis.storage.Aggregate;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.DataStoreProvider;
@@ -29,7 +28,7 @@ import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.WritableAggregate;
import org.apache.sis.storage.base.Capability;
import org.apache.sis.storage.base.StoreMetadata;
-import org.apache.sis.storage.base.URIDataStoreProvider;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.util.Version;
@@ -66,7 +65,7 @@ public class CoverageJsonStoreProvider extends DataStoreProvider {
/**
* The parameter descriptor to be returned by {@link #getOpenParameters()}.
*/
- private static final ParameterDescriptorGroup OPEN_DESCRIPTOR = URIDataStoreProvider.descriptor(NAME);
+ private static final ParameterDescriptorGroup OPEN_DESCRIPTOR = URIDataStoreOption.createForLocationOnly(NAME);
public CoverageJsonStoreProvider() {
}
diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/GeoHeifStore.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/GeoHeifStore.java
index e93e85b050..0a1643f888 100644
--- a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/GeoHeifStore.java
+++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/GeoHeifStore.java
@@ -42,7 +42,7 @@ import org.apache.sis.storage.DataStoreClosedException;
import org.apache.sis.storage.Resource;
import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.metadata.MetadataBuilder;
-import org.apache.sis.storage.base.URIDataStore;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.storage.modifier.CoverageModifier;
import org.apache.sis.storage.event.StoreListeners;
import org.apache.sis.storage.isobmff.Root;
@@ -165,7 +165,7 @@ public class GeoHeifStore extends DataStore implements Aggregate {
*/
@Override
public Optional<ParameterValueGroup> getOpenParameters() {
- return Optional.ofNullable(URIDataStore.parameters(provider, location));
+ return Optional.ofNullable(URIDataStoreOption.createWithLocationOnly(provider, location));
}
/**
diff --git a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/GeoHeifStoreProvider.java b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/GeoHeifStoreProvider.java
index 1a42e93c39..1c22ec59df 100644
--- a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/GeoHeifStoreProvider.java
+++ b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/GeoHeifStoreProvider.java
@@ -18,7 +18,6 @@ package org.apache.sis.storage.geoheif;
import java.nio.ByteBuffer;
import org.opengis.parameter.ParameterDescriptorGroup;
-import org.apache.sis.parameter.ParameterBuilder;
import org.apache.sis.storage.Aggregate;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreException;
@@ -28,7 +27,7 @@ import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.GridCoverageResource;
import org.apache.sis.storage.base.Capability;
import org.apache.sis.storage.base.StoreMetadata;
-import org.apache.sis.storage.base.URIDataStoreProvider;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.storage.tiling.TiledResource;
import org.apache.sis.storage.isobmff.base.FileType;
@@ -58,11 +57,7 @@ public class GeoHeifStoreProvider extends DataStoreProvider {
/**
* The parameter descriptor to be returned by {@link #getOpenParameters()}.
*/
- private static final ParameterDescriptorGroup OPEN_DESCRIPTOR;
- static {
- final var builder = new ParameterBuilder();
- OPEN_DESCRIPTOR = builder.addName(NAME).createGroup(URIDataStoreProvider.LOCATION_PARAM);
- }
+ private static final ParameterDescriptorGroup OPEN_DESCRIPTOR = URIDataStoreOption.createForLocationOnly(NAME);
/**
* Creates a new provider.
diff --git a/incubator/src/org.apache.sis.storage.geopackage/main/org/apache/sis/storage/geopackage/GpkgStoreProvider.java b/incubator/src/org.apache.sis.storage.geopackage/main/org/apache/sis/storage/geopackage/GpkgStoreProvider.java
index 1217edb8e8..9f39cf1670 100644
--- a/incubator/src/org.apache.sis.storage.geopackage/main/org/apache/sis/storage/geopackage/GpkgStoreProvider.java
+++ b/incubator/src/org.apache.sis.storage.geopackage/main/org/apache/sis/storage/geopackage/GpkgStoreProvider.java
@@ -17,7 +17,6 @@
package org.apache.sis.storage.geopackage;
import java.util.HashMap;
-import java.util.Objects;
import java.util.logging.Logger;
import java.nio.ByteBuffer;
import java.nio.file.Path;
@@ -43,7 +42,7 @@ import org.apache.sis.storage.ProbeResult;
import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.base.Capability;
import org.apache.sis.storage.base.StoreMetadata;
-import org.apache.sis.storage.base.URIDataStoreProvider;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.metadata.sql.internal.shared.SQLUtilities;
import org.apache.sis.metadata.sql.internal.shared.Reflection;
import org.apache.sis.io.stream.InternalOptionKey;
@@ -136,7 +135,7 @@ public class GpkgStoreProvider extends DataStoreProvider {
.setDescription("PRAGMA statements encoded as \"name=value;name=value\".")
.setRemarks("See https://www.sqlite.org/pragma.html for a list of PRAGMAs.")
.create(CharSequence.class, null);
- OPEN_DESCRIPTOR = builder.addName(NAME).createGroup(URIDataStoreProvider.LOCATION_PARAM, PRAGMAS_PARAM);
+ OPEN_DESCRIPTOR = builder.addName(NAME).createGroup(URIDataStoreOption.LOCATION.getParameterDescriptor(), PRAGMAS_PARAM);
}
/**
@@ -256,7 +255,7 @@ public class GpkgStoreProvider extends DataStoreProvider {
*/
@Override
public DataStore open(final ParameterValueGroup parameters) throws DataStoreException {
- final StorageConnector connector = URIDataStoreProvider.connector(this, Objects.requireNonNull(parameters));
+ final StorageConnector connector = URIDataStoreOption.connector(this, parameters, null, null);
final CharSequence pragmas = Parameters.castOrWrap(parameters).getValue(PRAGMAS_PARAM);
if (pragmas != null) {
final var map = new HashMap<String,String>();
diff --git a/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSFStore.java b/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSFStore.java
index dd06969cb3..520bab94b0 100644
--- a/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSFStore.java
+++ b/incubator/src/org.apache.sis.storage.gsf/main/org/apache/sis/storage/gsf/GSFStore.java
@@ -21,12 +21,11 @@ import java.nio.file.Path;
import java.util.Optional;
import org.opengis.metadata.Metadata;
import org.opengis.parameter.ParameterValueGroup;
-import org.apache.sis.parameter.Parameters;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.metadata.MetadataBuilder;
-import org.apache.sis.storage.base.URIDataStore;
+import org.apache.sis.storage.base.URIDataStoreOption;
/**
@@ -72,8 +71,7 @@ public final class GSFStore extends DataStore {
@Override
public Optional<ParameterValueGroup> getOpenParameters() {
- final Parameters param = Parameters.castOrWrap(URIDataStore.parameters(provider, location));
- return Optional.ofNullable(param);
+ return Optional.ofNullable(URIDataStoreOption.createWithLocationOnly(provider, location));
}
@Override
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 f74d71e125..187cd7bf42 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
@@ -21,17 +21,14 @@ import java.util.Optional;
import java.util.logging.Logger;
import java.nio.file.Path;
import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.parameter.ParameterValueGroup;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.DataStoreProvider;
import org.apache.sis.storage.ProbeResult;
import org.apache.sis.storage.StorageConnector;
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.gsf.panama.LibraryStatus;
-import org.apache.sis.parameter.ParameterBuilder;
-import org.apache.sis.parameter.Parameters;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.system.Cleaners;
@@ -67,11 +64,7 @@ public class GSFStoreProvider extends DataStoreProvider {
/**
* The parameter descriptor to be returned by {@link #getOpenParameters()}.
*/
- private static final ParameterDescriptorGroup OPEN_DESCRIPTOR;
- static {
- final var builder = new ParameterBuilder();
- OPEN_DESCRIPTOR = builder.addName(NAME).createGroup(URIDataStoreProvider.LOCATION_PARAM);
- }
+ private static final ParameterDescriptorGroup OPEN_DESCRIPTOR = URIDataStoreOption.createForLocationOnly(NAME);
/**
* Handles to <abbr>GSF</abbr> native functions, or {@code null} for global.
@@ -188,20 +181,6 @@ public class GSFStoreProvider extends DataStoreProvider {
return new GSFStore(this, connector);
}
- /**
- * Creates a {@code GSFStore} instance from the given parameters.
- *
- * @param parameters opening parameters as defined by {@link #getOpenParameters()}.
- * @return a data store instance associated with this provider for the given parameters.
- * @throws DataStoreException if an error occurred while creating the data store instance.
- */
- @Override
- public GSFStore open(final ParameterValueGroup parameters) throws DataStoreException {
- final var p = Parameters.castOrWrap(parameters);
- final var connector = new StorageConnector(p.getValue(URIDataStoreProvider.LOCATION_PARAM));
- return open(connector);
- }
-
/**
* Returns the logger used by <abbr>GSF</abbr> stores.
*/
diff --git a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileProvider.java b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileProvider.java
index 89e4d9a001..32e3161d3d 100644
--- a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileProvider.java
+++ b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileProvider.java
@@ -16,16 +16,13 @@
*/
package org.apache.sis.storage.shapefile;
-import java.net.URI;
import java.nio.file.Path;
-import org.opengis.parameter.ParameterDescriptor;
-import org.opengis.parameter.ParameterDescriptorGroup;
-import org.apache.sis.parameter.ParameterBuilder;
import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.storage.DataStoreProvider;
import org.apache.sis.storage.ProbeResult;
import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.storage.base.URIDataStoreOption;
+import org.apache.sis.storage.base.URIDataStoreProvider;
/**
@@ -34,8 +31,7 @@ import org.apache.sis.storage.StorageConnector;
* @author Johann Sorel (Geomatys)
* @see <a href="http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf">ESRI Shapefile Specification</a>
*/
-public final class ShapefileProvider extends DataStoreProvider {
-
+public final class ShapefileProvider extends URIDataStoreProvider {
/**
* Format name.
*/
@@ -46,29 +42,6 @@ public final class ShapefileProvider extends DataStoreProvider {
*/
public static final String MIME_TYPE = "application/x-shapefile";
- /**
- * URI to the shp file.
- */
- public static final ParameterDescriptor<URI> PATH = new ParameterBuilder()
- .addName(LOCATION)
- .setRequired(true)
- .create(URI.class, null);
-
- /**
- * Timezone of the dbf date fields.
- */
- public static final ParameterDescriptor<String> ZONEID = new ParameterBuilder()
- .addName(TIMEZONE)
- .setRequired(false)
- .create(String.class, null);
-
- /**
- * Shapefile store creation parameters.
- */
- public static final ParameterDescriptorGroup PARAMETERS_DESCRIPTOR =
- new ParameterBuilder().addName(NAME).addName("EsriShapefileParameters").createGroup(
- PATH, ZONEID);
-
private static ShapefileProvider INSTANCE;
/**
@@ -90,6 +63,8 @@ public final class ShapefileProvider extends DataStoreProvider {
* Default constructor.
*/
public ShapefileProvider() {
+ supportedOptions.add(URIDataStoreOption.TIMEZONE);
+ supportedOptions.add(URIDataStoreOption.ENCODING);
}
/**
@@ -100,14 +75,6 @@ public final class ShapefileProvider extends DataStoreProvider {
return NAME;
}
- /**
- * {@inheritDoc }
- */
- @Override
- public ParameterDescriptorGroup getOpenParameters() {
- return PARAMETERS_DESCRIPTOR;
- }
-
/**
* {@inheritDoc }
*/
@@ -125,6 +92,6 @@ public final class ShapefileProvider extends DataStoreProvider {
*/
@Override
public DataStore open(StorageConnector connector) throws DataStoreException {
- return new ShapefileStore(connector);
+ return new ShapefileStore(this, connector);
}
}
diff --git a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
index 5bd2209ac6..b3c1e6b611 100644
--- a/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
+++ b/incubator/src/org.apache.sis.storage.shapefile/main/org/apache/sis/storage/shapefile/ShapefileStore.java
@@ -28,7 +28,6 @@ import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
-import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.AbstractMap;
import java.util.ArrayList;
@@ -63,14 +62,12 @@ import org.opengis.util.GenericName;
import org.opengis.geometry.Envelope;
import org.opengis.metadata.Metadata;
import org.opengis.metadata.Identifier;
-import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.TransformException;
import org.apache.sis.geometry.ImmutableEnvelope;
import org.apache.sis.geometry.Envelopes;
import org.apache.sis.geometry.GeneralEnvelope;
import org.apache.sis.feature.builder.AttributeRole;
-import org.apache.sis.feature.builder.AttributeTypeBuilder;
import org.apache.sis.feature.builder.FeatureTypeBuilder;
import org.apache.sis.feature.internal.shared.AttributeConvention;
import org.apache.sis.filter.DefaultFilterFactory;
@@ -84,13 +81,10 @@ import org.apache.sis.io.stream.IOUtilities;
import org.apache.sis.io.wkt.Convention;
import org.apache.sis.io.wkt.WKTFormat;
import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.parameter.Parameters;
import org.apache.sis.referencing.CRS;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.referencing.IdentifiedObjects;
-import org.apache.sis.storage.OptionKey;
import org.apache.sis.storage.AbstractFeatureSet;
-import org.apache.sis.storage.DataStore;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.FeatureQuery;
import org.apache.sis.storage.FeatureSet;
@@ -99,6 +93,7 @@ import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.UnsupportedQueryException;
import org.apache.sis.storage.WritableFeatureSet;
import org.apache.sis.storage.DataStoreProvider;
+import org.apache.sis.storage.base.URIDataStore;
import org.apache.sis.storage.shapefile.cpg.CpgFiles;
import org.apache.sis.storage.shapefile.dbf.DBFField;
import org.apache.sis.storage.shapefile.dbf.DBFHeader;
@@ -139,15 +134,12 @@ import org.opengis.feature.PropertyNotFoundException;
*
* @author Johann Sorel (Geomatys)
*/
-public final class ShapefileStore extends DataStore implements WritableFeatureSet {
+public final class ShapefileStore extends URIDataStore implements WritableFeatureSet {
private static final String GEOMETRY_NAME = "geometry";
private static final Logger LOGGER = Logger.getLogger("org.apache.sis.storage.shapefile");
- private final Path shpPath;
private final ShpFiles files;
- private final Charset userDefinedCharSet;
- private final ZoneId timezone;
/**
* Internal class to inherit AbstractFeatureSet.
@@ -159,40 +151,17 @@ public final class ShapefileStore extends DataStore implements WritableFeatureSe
*/
private final ReadWriteLock lock = new ReentrantReadWriteLock();
- /**
- * Construct store from given path.
- *
- * @param path path to .shp file
- */
- public ShapefileStore(Path path) {
- this.shpPath = path;
- this.userDefinedCharSet = null;
- this.timezone = null;
- this.files = new ShpFiles(shpPath);
- }
-
/**
* Construct store from given connector.
*
- * @param cnx not null
+ * @param provider the factory that created this {@code ShapefileStore} instance, or {@code null} if unspecified.
+ * @param connector information about the storage (URL, stream, reader instance, <i>etc</i>).
* @throws IllegalArgumentException if connector could not provide a valid Path instance
* @throws DataStoreException if connector could not provide a valid Path instance
*/
- public ShapefileStore(StorageConnector cnx) throws IllegalArgumentException, DataStoreException {
- this.shpPath = cnx.getStorageAs(Path.class);
- this.userDefinedCharSet = cnx.getOption(OptionKey.ENCODING);
- this.timezone = cnx.getOption(OptionKey.TIMEZONE);
- this.files = new ShpFiles(shpPath);
- }
-
- /**
- * {@inheritDoc }
- */
- @Override
- public Optional<ParameterValueGroup> getOpenParameters() {
- final Parameters parameters = Parameters.castOrWrap(ShapefileProvider.PARAMETERS_DESCRIPTOR.createValue());
- parameters.parameter(ShapefileProvider.LOCATION).setValue(shpPath.toUri());
- return Optional.of(parameters);
+ public ShapefileStore(final DataStoreProvider provider, final StorageConnector connector) throws DataStoreException {
+ super(provider, connector);
+ this.files = new ShpFiles(locationAsPath);
}
/**
@@ -354,17 +323,16 @@ public final class ShapefileStore extends DataStore implements WritableFeatureSe
@Override
public synchronized FeatureType getType() throws DataStoreException {
if (type == null) {
- if (!Files.isRegularFile(shpPath)) {
+ if (!Files.isRegularFile(locationAsPath)) {
throw new DataStoreException("Shape files do not exist. Update FeatureType first to initialize this empty datastore");
}
-
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
ftb.setName(files.baseName);
if (readShp) {
//read shp header to obtain geometry type
final Class geometryClass;
- try (final ShapeReader reader = new ShapeReader(ShpFiles.openReadChannel(shpPath), filter)) {
+ try (final ShapeReader reader = new ShapeReader(ShpFiles.openReadChannel(locationAsPath), filter)) {
final ShapeHeader header = reader.getHeader();
this.shpHeader = header;
geometryClass = ShapeGeometryEncoder.getEncoder(header.shapeType).getValueClass();
@@ -714,10 +682,9 @@ public final class ShapefileStore extends DataStore implements WritableFeatureSe
public synchronized void updateType(FeatureType newType) throws DataStoreException {
if (!isDefaultView()) throw new DataStoreException("Resource not writable in current filter state");
- if (Files.exists(shpPath)) {
+ if (Files.exists(locationAsPath)) {
throw new DataStoreException("Update type is possible only when files do not exist. It can be used to create a new shapefile but not to update one.");
}
-
final Class<?>[] supportedDateTypes; // All types other than the one at index 0 will lost information.
if (timezone == null) {
supportedDateTypes = new Class<?>[] {
@@ -736,7 +703,7 @@ public final class ShapefileStore extends DataStore implements WritableFeatureSe
final DBFHeader dbfHeader = new DBFHeader();
dbfHeader.lastUpdate = LocalDate.now();
dbfHeader.fields = new DBFField[0];
- final Charset charset = userDefinedCharSet == null ? StandardCharsets.UTF_8 : userDefinedCharSet;
+ final Charset charset = (encoding == null) ? StandardCharsets.UTF_8 : encoding;
CoordinateReferenceSystem crs = CommonCRS.WGS84.normalizedGeographic();
for (PropertyType pt : newType.getProperties(true)) {
@@ -860,8 +827,9 @@ public final class ShapefileStore extends DataStore implements WritableFeatureSe
@Override
public void add(Iterator<? extends Feature> features) throws DataStoreException {
if (!isDefaultView()) throw new DataStoreException("Resource not writable in current filter state");
- if (!Files.exists(shpPath)) throw new DataStoreException("FeatureType do not exist, use updateType before modifying features.");
-
+ if (!Files.exists(locationAsPath)) {
+ throw new DataStoreException("FeatureType do not exist, use updateType before modifying features.");
+ }
final Writer writer = new Writer(charset);
try {
//write existing features
@@ -891,8 +859,9 @@ public final class ShapefileStore extends DataStore implements WritableFeatureSe
@Override
public void removeIf(Predicate<? super Feature> filter) throws DataStoreException {
if (!isDefaultView()) throw new DataStoreException("Resource not writable in current filter state");
- if (!Files.exists(shpPath)) throw new DataStoreException("FeatureType do not exist, use updateType before modifying features.");
-
+ if (!Files.exists(locationAsPath)) {
+ throw new DataStoreException("FeatureType do not exist, use updateType before modifying features.");
+ }
final Writer writer = new Writer(charset);
try {
//write existing features not matching filter
@@ -916,8 +885,9 @@ public final class ShapefileStore extends DataStore implements WritableFeatureSe
@Override
public void replaceIf(Predicate<? super Feature> filter, UnaryOperator<Feature> updater) throws DataStoreException {
if (!isDefaultView()) throw new DataStoreException("Resource not writable in current filter state");
- if (!Files.exists(shpPath)) throw new DataStoreException("FeatureType do not exist, use updateType before modifying features.");
-
+ if (!Files.exists(locationAsPath)) {
+ throw new DataStoreException("FeatureType do not exist, use updateType before modifying features.");
+ }
final Writer writer = new Writer(charset);
try {
//write existing features applying modifications
diff --git a/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/ShapefileStoreTest.java b/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/ShapefileStoreTest.java
index 4d355a9c6c..3f8586bc93 100644
--- a/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/ShapefileStoreTest.java
+++ b/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/ShapefileStoreTest.java
@@ -39,6 +39,7 @@ import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.FeatureQuery;
import org.apache.sis.storage.FeatureSet;
import org.apache.sis.feature.internal.shared.AttributeConvention;
+import org.apache.sis.storage.StorageConnector;
// Test dependencies
import static org.junit.jupiter.api.Assertions.*;
@@ -62,10 +63,18 @@ public class ShapefileStoreTest {
private static final GeometryFactory GF = new GeometryFactory();
+ private static ShapefileStore create(final URL resource) throws URISyntaxException, DataStoreException {
+ return create(Paths.get(resource.toURI()));
+ }
+
+ private static ShapefileStore create(final Path temp) throws DataStoreException {
+ return new ShapefileStore(null, new StorageConnector(temp));
+ }
+
@Test
public void testStream() throws URISyntaxException, DataStoreException {
final URL url = ShapefileStoreTest.class.getResource("/org/apache/sis/storage/shapefile/point.shp");
- try (final ShapefileStore store = new ShapefileStore(Paths.get(url.toURI()))) {
+ try (final ShapefileStore store = create(url)) {
//check feature type
final FeatureType type = store.getType();
@@ -120,7 +129,7 @@ public class ShapefileStoreTest {
@Test
public void testEnvelopeFilter() throws URISyntaxException, DataStoreException {
final URL url = ShapefileStoreTest.class.getResource("/org/apache/sis/storage/shapefile/point.shp");
- try (final ShapefileStore store = new ShapefileStore(Paths.get(url.toURI()))) {
+ try (final ShapefileStore store = create(url)) {
final FilterFactory<Feature, Object, Object> ff = DefaultFilterFactory.forFeatures();
@@ -157,7 +166,7 @@ public class ShapefileStoreTest {
@Test
public void testFieldFilter() throws URISyntaxException, DataStoreException {
final URL url = ShapefileStoreTest.class.getResource("/org/apache/sis/storage/shapefile/point.shp");
- try (final ShapefileStore store = new ShapefileStore(Paths.get(url.toURI()))) {
+ try (final ShapefileStore store = create(url)) {
final FeatureQuery query = new FeatureQuery();
query.setProjection("text", "float");
FeatureSet featureset = store.subset(query);
@@ -184,7 +193,7 @@ public class ShapefileStoreTest {
@Test
public void testFiles() throws URISyntaxException, DataStoreException {
final URL url = ShapefileStoreTest.class.getResource("/org/apache/sis/storage/shapefile/point.shp");
- try (final ShapefileStore store = new ShapefileStore(Paths.get(url.toURI()))) {
+ try (final ShapefileStore store = create(url)) {
Iterator<Path> componentFiles = store.getFileSet().orElseThrow().getPaths().iterator();
assertTrue(componentFiles.next().toString().endsWith("point.shp"));
assertTrue(componentFiles.next().toString().endsWith("point.shx"));
@@ -202,7 +211,7 @@ public class ShapefileStoreTest {
public void testCreate(@TempDir final Path folder) throws URISyntaxException, DataStoreException, IOException {
final Path temp = folder.resolve("test.shp");
final String name = temp.getFileName().toString().split("\\.")[0];
- try (final ShapefileStore store = new ShapefileStore(temp)) {
+ try (final ShapefileStore store = new ShapefileStore(null, new StorageConnector(temp))) {
assertTrue(store.getFileSet().orElseThrow().getPaths().isEmpty());
{//create type
@@ -251,7 +260,7 @@ public class ShapefileStoreTest {
@Test
public void testAddFeatures(@TempDir final Path folder) throws URISyntaxException, DataStoreException, IOException {
final Path temp = folder.resolve("test.shp");
- try (final ShapefileStore store = new ShapefileStore(temp)) {
+ try (final ShapefileStore store = create(temp)) {
FeatureType type = createType();
store.updateType(type);
type = store.getType();
@@ -273,7 +282,7 @@ public class ShapefileStoreTest {
@Test
public void testRemoveFeatures(@TempDir final Path folder) throws DataStoreException, IOException {
final Path temp = folder.resolve("test.shp");
- try (final ShapefileStore store = new ShapefileStore(temp)) {
+ try (final ShapefileStore store = create(temp)) {
FeatureType type = createType();
store.updateType(type);
type = store.getType();
@@ -301,7 +310,7 @@ public class ShapefileStoreTest {
@Test
public void testReplaceFeatures(@TempDir final Path folder) throws DataStoreException, IOException {
final Path temp = folder.resolve("test.shp");
- try (final ShapefileStore store = new ShapefileStore(temp)) {
+ try (final ShapefileStore store = create(temp)) {
FeatureType type = createType();
store.updateType(type);
type = store.getType();
@@ -334,7 +343,7 @@ public class ShapefileStoreTest {
@Test
public void testGeneratedId() throws DataStoreException, IOException, URISyntaxException {
final URL url = ShapefileStoreTest.class.getResource("/org/apache/sis/storage/shapefile/noid.shp");
- try (final ShapefileStore store = new ShapefileStore(Paths.get(url.toURI()))) {
+ try (final ShapefileStore store = create(url)) {
final FeatureType type = store.getType();
final PropertyType generatedID = type.getProperty(AttributeConvention.IDENTIFIER);
diff --git a/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/Snippets.java b/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/Snippets.java
index ef5acb82c4..8cc67a88d7 100644
--- a/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/Snippets.java
+++ b/incubator/src/org.apache.sis.storage.shapefile/test/org/apache/sis/storage/shapefile/Snippets.java
@@ -17,7 +17,7 @@
package org.apache.sis.storage.shapefile;
import java.io.IOException;
-import java.nio.file.Paths;
+import java.nio.file.Path;
import java.util.List;
import java.util.stream.Stream;
import org.locationtech.jts.geom.Coordinate;
@@ -29,6 +29,7 @@ import org.apache.sis.geometry.GeneralEnvelope;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.FeatureQuery;
+import org.apache.sis.storage.StorageConnector;
// Specific to the geoapi-3.1 and geoapi-4.0 branches:
import org.opengis.feature.Feature;
@@ -46,7 +47,7 @@ final class Snippets {
public void read() throws IllegalArgumentException, DataStoreException, IOException{
// @start region="read"
//open datastore
- try (ShapefileStore store = new ShapefileStore(Paths.get("/path/to/file.shp"))) {
+ try (ShapefileStore store = new ShapefileStore(null, new StorageConnector(Path.of("/path/to/file.shp")))) {
//print feature type
System.out.println(store.getType());
@@ -80,7 +81,7 @@ final class Snippets {
public void write() throws IllegalArgumentException, DataStoreException, IOException{
// @start region="write"
//open a channel
- try (ShapefileStore store = new ShapefileStore(Paths.get("/path/to/file.shp"))) {
+ try (ShapefileStore store = new ShapefileStore(null, new StorageConnector(Path.of("/path/to/file.shp")))) {
//define the feature type
FeatureTypeBuilder ftb = new FeatureTypeBuilder();
diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/PathAction.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/PathAction.java
index 0255786d63..5a3fc16ceb 100644
--- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/PathAction.java
+++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/PathAction.java
@@ -20,6 +20,7 @@ import java.awt.Desktop;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Optional;
import java.io.File;
import java.nio.file.Path;
import java.net.URL;
@@ -30,11 +31,16 @@ import javafx.event.EventHandler;
import javafx.scene.control.TreeCell;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterNotFoundException;
import org.apache.sis.gui.internal.ExceptionReporter;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.Resource;
-import org.apache.sis.storage.base.URIDataStoreProvider;
import org.apache.sis.io.stream.IOUtilities;
+import org.apache.sis.storage.DataStore;
+import org.apache.sis.storage.DataStoreProvider;
+import org.apache.sis.util.logging.Logging;
+import static org.apache.sis.gui.internal.LogHandler.LOGGER;
/**
@@ -87,7 +93,7 @@ final class PathAction implements EventHandler<ActionEvent> {
final Resource resource = cell.getItem();
final Object path;
try {
- path = URIDataStoreProvider.location(resource);
+ path = location(resource);
} catch (DataStoreException e) {
ExceptionReporter.show(cell, null, null, e);
return;
@@ -174,4 +180,37 @@ final class PathAction implements EventHandler<ActionEvent> {
if (uri != null) content.putUrl(uri.toString());
Clipboard.getSystemClipboard().setContent(content);
}
+
+ /**
+ * Returns the location (path, <abbr>URL</abbr>, <abbr>URI</abbr>, <i>etc.</i>) of the given resource.
+ * The type of the returned object can be any of the types documented in {@link DataStoreProvider#LOCATION}.
+ *
+ * @param resource the resource for which to get the location, or {@code null}.
+ * @return location of the given resource, or {@code null} if none.
+ * @throws DataStoreException if an error on the file system prevent the creation of the path.
+ */
+ static Object location(final Resource resource) throws DataStoreException {
+ if (resource == null) {
+ return null;
+ }
+ if (resource instanceof DataStore) {
+ final Optional<ParameterValueGroup> p = ((DataStore) resource).getOpenParameters();
+ if (p.isPresent()) try {
+ return p.get().parameter(DataStoreProvider.LOCATION).getValue();
+ } catch (ParameterNotFoundException e) {
+ /*
+ * This exception should not happen often since the "location" parameter is recommended.
+ * Note that it does not mean the same thing as "parameter provided but value is null".
+ * In that later case we want to return the null value as specified in the parameters.
+ */
+ Logging.ignorableException(LOGGER, PathAction.class, "location", e);
+ }
+ }
+ /*
+ * This fallback should not happen with `URIDataStore` implementation because the "location" parameter
+ * is always present even if null. This fallback is for resources implementated by different classes.
+ * The first path is presumed the main file.
+ */
+ return resource.getFileSet().flatMap((files) -> files.getPaths().stream().findFirst()).orElse(null);
+ }
}
diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceCell.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceCell.java
index e9fc07f73c..157db86948 100644
--- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceCell.java
+++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceCell.java
@@ -26,7 +26,6 @@ import javafx.scene.control.TreeView;
import javafx.scene.paint.Color;
import org.apache.sis.storage.Resource;
import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.storage.base.URIDataStoreProvider;
import org.apache.sis.io.stream.IOUtilities;
import org.apache.sis.gui.internal.ExceptionReporter;
import org.apache.sis.gui.internal.Resources;
@@ -134,7 +133,7 @@ final class ResourceCell extends TreeCell<Resource> {
final boolean aggregatable = isRootResource && item.isViewSelectable(resource, TreeViewType.AGGREGATION);
Object path;
try {
- path = URIDataStoreProvider.location(resource);
+ path = PathAction.location(resource);
} catch (DataStoreException e) {
path = null;
ResourceTree.unexpectedException("updateItem", e);
diff --git a/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStore.java b/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStore.java
index 1a4144c569..a132392c13 100644
--- a/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStore.java
+++ b/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStore.java
@@ -48,7 +48,7 @@ import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.DataStoreClosedException;
import org.apache.sis.storage.StorageConnector;
import org.apache.sis.storage.metadata.MetadataBuilder;
-import org.apache.sis.storage.base.URIDataStore;
+import org.apache.sis.storage.base.URIDataStoreOption;
import org.apache.sis.util.collection.Containers;
import org.apache.sis.util.internal.shared.Constants;
import org.apache.sis.util.iso.DefaultNameFactory;
@@ -264,7 +264,7 @@ public class GDALStore extends DataStore implements Aggregate {
*/
@Override
public Optional<ParameterValueGroup> getOpenParameters() {
- final Parameters param = Parameters.castOrWrap(URIDataStore.parameters(provider, location));
+ final Parameters param = Parameters.castOrWrap(URIDataStoreOption.createWithLocationOnly(provider, location));
if (param != null) try {
param.getOrCreate(GDALStoreProvider.DRIVERS_PARAM).setValue(new String[] {
getDriver().getIdentifier()}
diff --git a/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStoreProvider.java b/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStoreProvider.java
index e1d83b43ec..e1c7ada1d1 100644
--- a/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStoreProvider.java
+++ b/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/GDALStoreProvider.java
@@ -36,7 +36,7 @@ import org.apache.sis.storage.ProbeResult;
import org.apache.sis.storage.StorageConnector;
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.base.URIDataStoreOption;
import org.apache.sis.storage.panama.LibraryStatus;
import org.apache.sis.storage.panama.Resources;
import org.apache.sis.io.stream.InternalOptionKey;
@@ -101,7 +101,8 @@ public class GDALStoreProvider extends DataStoreProvider {
DRIVERS_PARAM = builder.addName("drivers")
.setDescription(Resources.formatInternational(Resources.Keys.AllowedDrivers_1, Constants.GDAL))
.create(String[].class, null);
- OPEN_DESCRIPTOR = builder.addName(Constants.GDAL).createGroup(URIDataStoreProvider.LOCATION_PARAM, DRIVERS_PARAM);
+ OPEN_DESCRIPTOR = builder.addName(Constants.GDAL).createGroup(
+ URIDataStoreOption.LOCATION.getParameterDescriptor(), DRIVERS_PARAM);
}
/**
@@ -377,7 +378,7 @@ public class GDALStoreProvider extends DataStoreProvider {
@Override
public DataStore open(final ParameterValueGroup parameters) throws DataStoreException {
final var p = Parameters.castOrWrap(parameters);
- final var connector = new StorageConnector(p.getValue(URIDataStoreProvider.LOCATION_PARAM));
+ final var connector = URIDataStoreOption.connector(this, p, null, null);
final String[] drivers = p.getValue(DRIVERS_PARAM);
if (drivers != null) {
connector.setOption(DRIVERS_OPTION_KEY, drivers);