This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch geoapi-3.1 in repository https://gitbox.apache.org/repos/asf/sis.git
commit 45a58d0acf0d1845d3f99d95ba8e214e40d974bb Merge: 3b34cf323f dc78d5d1ab Author: Martin Desruisseaux <[email protected]> AuthorDate: Thu May 28 17:54:58 2026 +0200 Merge branch 'geoapi-4.0' into geoapi-3.1. .../org/apache/sis/console/OperationParser.java | 2 +- .../org/apache/sis/coverage/RegionOfInterest.java | 6 +- .../org/apache/sis/feature/FeatureOperations.java | 4 +- .../main/org/apache/sis/filter/base/Node.java | 5 +- .../sis/filter/sqlmm/FunctionDescription.java | 12 + .../geometry/wrapper/SpatialOperationContext.java | 3 +- .../org/apache/sis/metadata/AbstractMetadata.java | 36 +- .../main/org/apache/sis/metadata/CacheKey.java | 29 +- .../org/apache/sis/metadata/MetadataCopier.java | 10 +- .../org/apache/sis/metadata/MetadataStandard.java | 361 +++++++++++++-------- .../org/apache/sis/metadata/MetadataVisitor.java | 14 +- .../apache/sis/metadata/ModifiableMetadata.java | 11 +- .../org/apache/sis/metadata/PropertyAccessor.java | 2 +- .../main/org/apache/sis/metadata/Pruner.java | 2 +- .../sis/metadata/StandardImplementation.java | 6 +- .../main/org/apache/sis/metadata/StateChanger.java | 2 +- .../org/apache/sis/metadata/TitleProperty.java | 11 +- .../main/org/apache/sis/metadata/TreeNode.java | 41 ++- .../org/apache/sis/metadata/TreeNodeChildren.java | 78 +++-- .../apache/sis/metadata/ValueExistencePolicy.java | 1 + .../sis/metadata/internal/shared/Merger.java | 17 +- .../metadata/internal/shared/SecondaryTrait.java | 45 --- .../iso/DefaultApplicationSchemaInformation.java | 4 +- .../sis/metadata/iso/DefaultMetadataScope.java | 4 +- .../sis/metadata/iso/acquisition/DefaultEvent.java | 4 +- .../iso/acquisition/DefaultInstrument.java | 4 +- .../metadata/iso/acquisition/DefaultObjective.java | 2 +- .../metadata/iso/acquisition/DefaultOperation.java | 4 +- .../sis/metadata/iso/acquisition/DefaultPlan.java | 4 +- .../metadata/iso/acquisition/DefaultPlatform.java | 4 +- .../iso/acquisition/DefaultPlatformPass.java | 4 +- .../iso/acquisition/DefaultRequirement.java | 2 + .../sis/metadata/iso/acquisition/package-info.java | 2 +- .../iso/citation/DefaultOnlineResource.java | 4 +- .../sis/metadata/iso/citation/DefaultSeries.java | 4 +- .../metadata/iso/citation/DefaultTelephone.java | 4 +- .../sis/metadata/iso/citation/package-info.java | 2 +- .../iso/constraint/DefaultReleasability.java | 4 +- .../iso/constraint/DefaultSecurityConstraints.java | 4 +- .../sis/metadata/iso/constraint/package-info.java | 2 +- .../DefaultFeatureCatalogueDescription.java | 4 +- .../metadata/iso/distribution/DefaultDataFile.java | 8 +- .../metadata/iso/distribution/DefaultFormat.java | 4 +- .../metadata/iso/distribution/DefaultMedium.java | 4 +- .../metadata/iso/distribution/package-info.java | 2 +- .../iso/extent/DefaultGeographicDescription.java | 4 +- .../sis/metadata/iso/extent/package-info.java | 2 +- .../iso/identification/AbstractIdentification.java | 4 +- .../DefaultAggregateInformation.java | 4 +- .../identification/DefaultAssociatedResource.java | 4 +- .../iso/identification/DefaultBrowseGraphic.java | 4 +- .../identification/DefaultDataIdentification.java | 4 +- .../metadata/iso/identification/package-info.java | 2 +- .../sis/metadata/iso/lineage/DefaultAlgorithm.java | 4 +- .../sis/metadata/iso/lineage/DefaultLineage.java | 4 +- .../metadata/iso/lineage/DefaultProcessing.java | 4 +- .../sis/metadata/iso/lineage/package-info.java | 2 +- .../org/apache/sis/metadata/iso/package-info.java | 2 +- .../sis/metadata/iso/quality/AbstractElement.java | 4 +- .../iso/quality/DefaultConformanceResult.java | 4 +- .../iso/quality/DefaultEvaluationMethod.java | 4 +- .../DefaultEvaluationReportInformation.java | 4 +- .../iso/quality/DefaultSourceReference.java | 4 +- .../sis/metadata/iso/quality/package-info.java | 2 +- .../sis/metadata/iso/spatial/DefaultGCP.java | 2 +- .../metadata/iso/spatial/DefaultGCPCollection.java | 16 +- .../metadata/simple/SimpleIdentifiedObject.java | 23 +- .../apache/sis/metadata/simple/SimpleMetadata.java | 31 +- .../apache/sis/metadata/sql/MetadataSource.java | 14 +- .../apache/sis/metadata/sql/MetadataWriter.java | 30 +- .../org/apache/sis/temporal/DefaultInstant.java | 13 + .../org/apache/sis/temporal/DefaultPeriod.java | 13 + .../main/org/apache/sis/temporal/TemporalDate.java | 13 + .../sis/xml/bind/metadata/replace/Parameter.java | 15 +- .../metadata/replace/ReferenceSystemMetadata.java | 13 + .../apache/sis/metadata/MetadataStandardTest.java | 8 +- .../sis/metadata/ModifiableMetadataTest.java | 1 + .../sis/metadata/PropertyConsistencyCheck.java | 16 +- .../apache/sis/metadata/TreeNodeChildrenTest.java | 2 +- .../sis/openoffice/ReferencingFunctions.java | 11 +- .../gazetteer/AbstractLocationType.java | 12 + .../gazetteer/ReferencingByIdentifiers.java | 9 +- .../sis/referencing/gazetteer/package-info.java | 2 +- .../sis/coordinate/DefaultCoordinateMetadata.java | 15 +- .../main/org/apache/sis/io/wkt/WKTDictionary.java | 8 +- .../sis/parameter/AbstractParameterDescriptor.java | 8 +- .../sis/parameter/DefaultParameterDescriptor.java | 18 +- .../parameter/DefaultParameterDescriptorGroup.java | 15 +- .../sis/parameter/DefaultParameterValue.java | 15 +- .../apache/sis/parameter/ParameterizedType.java | 49 +++ .../main/org/apache/sis/parameter/Parameters.java | 17 +- .../org/apache/sis/parameter/package-info.java | 2 +- .../sis/referencing/AbstractIdentifiedObject.java | 65 ++-- .../sis/referencing/AbstractReferenceSystem.java | 8 +- .../main/org/apache/sis/referencing/Builder.java | 6 +- .../sis/referencing/DefaultObjectDomain.java | 15 +- .../apache/sis/referencing/GeodeticCalculator.java | 5 +- .../apache/sis/referencing/crs/AbstractCRS.java | 8 +- .../sis/referencing/crs/AbstractDerivedCRS.java | 2 +- .../sis/referencing/crs/AbstractSingleCRS.java | 5 +- .../sis/referencing/crs/DefaultCompoundCRS.java | 22 +- .../sis/referencing/crs/DefaultDerivedCRS.java | 29 +- .../sis/referencing/crs/DefaultEngineeringCRS.java | 15 +- .../sis/referencing/crs/DefaultGeocentricCRS.java | 10 +- .../sis/referencing/crs/DefaultGeodeticCRS.java | 10 +- .../sis/referencing/crs/DefaultGeographicCRS.java | 13 +- .../sis/referencing/crs/DefaultParametricCRS.java | 15 +- .../sis/referencing/crs/DefaultProjectedCRS.java | 15 +- .../sis/referencing/crs/DefaultTemporalCRS.java | 15 +- .../sis/referencing/crs/DefaultVerticalCRS.java | 15 +- .../apache/sis/referencing/crs/package-info.java | 2 +- .../org/apache/sis/referencing/cs/AbstractCS.java | 11 +- .../apache/sis/referencing/cs/DefaultAffineCS.java | 7 +- .../sis/referencing/cs/DefaultCartesianCS.java | 14 +- .../sis/referencing/cs/DefaultCompoundCS.java | 2 +- .../cs/DefaultCoordinateSystemAxis.java | 15 +- .../sis/referencing/cs/DefaultCylindricalCS.java | 14 +- .../sis/referencing/cs/DefaultEllipsoidalCS.java | 14 +- .../apache/sis/referencing/cs/DefaultLinearCS.java | 14 +- .../sis/referencing/cs/DefaultParametricCS.java | 14 +- .../apache/sis/referencing/cs/DefaultPolarCS.java | 14 +- .../sis/referencing/cs/DefaultSphericalCS.java | 14 +- .../apache/sis/referencing/cs/DefaultTimeCS.java | 12 +- .../sis/referencing/cs/DefaultVerticalCS.java | 14 +- .../org/apache/sis/referencing/cs/Normalizer.java | 2 +- .../sis/referencing/datum/AbstractDatum.java | 7 +- .../referencing/datum/DefaultDatumEnsemble.java | 26 +- .../sis/referencing/datum/DefaultEllipsoid.java | 15 +- .../referencing/datum/DefaultEngineeringDatum.java | 15 +- .../referencing/datum/DefaultGeodeticDatum.java | 15 +- .../referencing/datum/DefaultParametricDatum.java | 15 +- .../referencing/datum/DefaultPrimeMeridian.java | 15 +- .../referencing/datum/DefaultTemporalDatum.java | 15 +- .../referencing/datum/DefaultVerticalDatum.java | 15 +- .../factory/GeodeticAuthorityFactory.java | 3 +- .../referencing/factory/GeodeticObjectFactory.java | 2 +- .../referencing/internal/ParameterizedType.java | 118 +++++++ .../internal/shared/AffineTransform2D.java | 11 + .../internal/shared/ReferencingUtilities.java | 50 --- .../sis/referencing/legacy/DefaultImageCRS.java | 3 +- .../sis/referencing/legacy/DefaultImageDatum.java | 12 +- .../referencing/legacy/DefaultUserDefinedCS.java | 11 +- .../operation/AbstractCoordinateOperation.java | 6 +- .../apache/sis/referencing/operation/CRSPair.java | 3 +- .../operation/CoordinateOperationRegistry.java | 2 +- .../operation/DefaultConcatenatedOperation.java | 12 +- .../referencing/operation/DefaultConversion.java | 10 +- .../DefaultCoordinateOperationFactory.java | 6 +- .../operation/DefaultOperationMethod.java | 15 +- .../operation/DefaultPassThroughOperation.java | 15 +- .../referencing/operation/DefaultProjection.java | 2 +- .../operation/DefaultTransformation.java | 15 +- .../referencing/operation/matrix/MatrixSIS.java | 20 +- .../referencing/operation/matrix/package-info.java | 2 +- .../operation/transform/AbstractMathTransform.java | 20 +- .../operation/transform/package-info.java | 2 +- .../DefaultParameterDescriptorGroupTest.java | 20 +- .../parameter/DefaultParameterDescriptorTest.java | 119 +++---- .../sis/parameter/DefaultParameterValueTest.java | 46 +-- .../datum/DefaultDatumEnsembleTest.java | 99 ++++++ .../datum/DefaultGeodeticDatumTest.java | 6 +- .../sis/referencing/datum/HardCodedDatum.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 +- .../sis/storage/geotiff/writer/GeoEncoder.java | 6 +- .../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/sql/feature/Column.java | 3 +- .../apache/sis/storage/sql/feature/Database.java | 21 ++ .../sis/storage/sql/feature/InfoStatements.java | 8 +- .../apache/sis/storage/sql/postgis/Postgres.java | 23 ++ .../main/org/apache/sis/storage/gpx/Metadata.java | 6 +- .../main/org/apache/sis/storage/gpx/Store.java | 2 +- .../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 +- .../main/org/apache/sis/storage/OptionKey.java | 99 +++++- .../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 | 333 +++++++++++++++++++ .../sis/storage/base/URIDataStoreProvider.java | 178 ++++------ .../main/org/apache/sis/storage/csv/Store.java | 27 +- .../org/apache/sis/storage/csv/StoreProvider.java | 67 +--- .../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 +- .../org/apache/sis/measure/AbstractConverter.java | 21 +- .../main/org/apache/sis/measure/AbstractUnit.java | 25 +- .../apache/sis/measure/ConcatenatedConverter.java | 8 +- .../org/apache/sis/measure/LinearConverter.java | 8 +- .../main/org/apache/sis/measure/package-info.java | 10 +- .../main/org/apache/sis/util/Classes.java | 211 +++++++----- .../main/org/apache/sis/util/ComparisonMode.java | 3 + .../org/apache/sis/util/LenientComparable.java | 39 ++- .../sis/util/resources/IndexedResourceBundle.java | 3 + .../test/org/apache/sis/util/ClassesTest.java | 9 + .../test/org/apache/sis/util/UtilitiesTest.java | 7 + .../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 +- .../apache/sis/gui/referencing/FilterByDatum.java | 3 +- .../org/apache/sis/storage/gdal/GDALStore.java | 4 +- .../apache/sis/storage/gdal/GDALStoreProvider.java | 7 +- 238 files changed, 2776 insertions(+), 1864 deletions(-) diff --cc endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/DefaultApplicationSchemaInformation.java index be816d5c6b,42007ffc81..56181738ff --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/DefaultApplicationSchemaInformation.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/DefaultApplicationSchemaInformation.java @@@ -23,10 -23,12 +23,11 @@@ import jakarta.xml.bind.annotation.adap import org.opengis.metadata.ApplicationSchemaInformation; import org.opengis.metadata.citation.Citation; import org.opengis.metadata.citation.OnlineResource; + import org.apache.sis.metadata.TitleProperty; import org.apache.sis.xml.Namespaces; -// Specific to the geoapi-4.0 branch: -import org.apache.sis.xml.bind.gco.CharSequenceAdapter; -import org.apache.sis.xml.bind.metadata.CI_OnlineResource; +// Specific to the main and geoapi-3.1 branches: +import java.net.URI; /** diff --cc endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultPlatform.java index ab02dcb472,a820dc9f19..40896e1616 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultPlatform.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultPlatform.java @@@ -25,10 -25,11 +25,11 @@@ import org.opengis.metadata.acquisition import org.opengis.metadata.acquisition.Platform; import org.opengis.metadata.citation.Citation; import org.opengis.util.InternationalString; + import org.apache.sis.metadata.TitleProperty; import org.apache.sis.metadata.iso.ISOMetadata; -// Specific to the geoapi-4.0 branch: -import org.opengis.metadata.citation.Responsibility; +// Specific to the main and geoapi-3.1 branches: +import org.opengis.metadata.citation.ResponsibleParty; /** diff --cc endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequirement.java index c8e29c1e58,e37b0d4a29..bffe05b346 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequirement.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/acquisition/DefaultRequirement.java @@@ -27,12 -27,11 +27,13 @@@ import org.opengis.metadata.acquisition import org.opengis.metadata.acquisition.RequestedDate; import org.opengis.metadata.acquisition.Requirement; import org.opengis.metadata.citation.Citation; + import org.apache.sis.metadata.TitleProperty; import org.apache.sis.metadata.iso.ISOMetadata; -// Specific to the geoapi-4.0 branch: -import org.opengis.metadata.citation.Responsibility; +// Specific to the main and geoapi-3.1 branches: +import java.util.Date; +import org.opengis.metadata.citation.ResponsibleParty; +import org.apache.sis.temporal.TemporalDate; /** @@@ -65,9 -64,10 +66,10 @@@ * * @author Cédric Briançon (Geomatys) * @author Martin Desruisseaux (Geomatys) - * @version 2.0 + * @version 1.5 * @since 0.3 */ + @TitleProperty(name = "identifier") @XmlType(name = "MI_Requirement_Type", propOrder = { "citation", "identifier", diff --cc endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultDataFile.java index 85b4111de4,a8c0d6e559..8f186cab2e --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultDataFile.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultDataFile.java @@@ -22,17 -22,18 +22,18 @@@ import jakarta.xml.bind.annotation.XmlT import jakarta.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.opengis.util.InternationalString; import org.opengis.metadata.distribution.Format; import org.opengis.metadata.distribution.DataFile; +import org.opengis.util.InternationalString; - import org.apache.sis.xml.Namespaces; + import org.apache.sis.metadata.TitleProperty; import org.apache.sis.metadata.iso.ISOMetadata; + import org.apache.sis.xml.Namespaces; import org.apache.sis.xml.bind.FilterByVersion; - import org.apache.sis.xml.internal.shared.LegacyNamespaces; import org.apache.sis.xml.bind.gcx.MimeFileTypeAdapter; + import org.apache.sis.xml.internal.shared.LegacyNamespaces; -// Specific to the geoapi-4.0 branch: -import org.opengis.util.GenericName; +// Specific to the main and geoapi-3.1 branches: +import org.opengis.util.LocalName; /** diff --cc endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultMedium.java index a3c7498a39,21701bbe7e..5506b95521 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultMedium.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/distribution/DefaultMedium.java @@@ -33,9 -33,10 +33,10 @@@ import org.apache.sis.xml.bind.FilterBy import org.apache.sis.xml.bind.gco.GO_Real; import org.apache.sis.xml.bind.metadata.CI_Citation; import org.apache.sis.xml.bind.metadata.MD_Identifier; -import org.apache.sis.xml.internal.shared.LegacyNamespaces; + import org.apache.sis.metadata.TitleProperty; -import org.apache.sis.metadata.iso.legacy.LegacyPropertyAdapter; import org.apache.sis.metadata.internal.Dependencies; +import org.apache.sis.metadata.iso.legacy.LegacyPropertyAdapter; +import org.apache.sis.xml.internal.shared.LegacyNamespaces; import org.apache.sis.util.collection.Containers; import static org.apache.sis.metadata.internal.shared.ImplementationHelper.ensurePositive; diff --cc endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/lineage/DefaultLineage.java index 4faa4c3ed4,0929d48ebd..5c44d14f68 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/lineage/DefaultLineage.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/lineage/DefaultLineage.java @@@ -26,7 -26,8 +26,8 @@@ import org.opengis.metadata.citation.Ci import org.opengis.metadata.lineage.Source; import org.opengis.metadata.lineage.Lineage; import org.opengis.metadata.lineage.ProcessStep; +import org.opengis.metadata.maintenance.ScopeCode; + import org.apache.sis.metadata.TitleProperty; import org.apache.sis.metadata.iso.ISOMetadata; import org.apache.sis.metadata.iso.maintenance.DefaultScope; import org.apache.sis.xml.bind.FilterByVersion; diff --cc endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/simple/SimpleMetadata.java index 2a89923dcc,3357d29223..0c0d38f7d5 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/simple/SimpleMetadata.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/simple/SimpleMetadata.java @@@ -107,9 -113,11 +113,11 @@@ public class SimpleMetadata implements /** * Parties responsible for the metadata information. + * + * @return empty collection. */ @Override - public Collection<Responsibility> getContacts() { + public Collection<ResponsibleParty> getContacts() { return Collections.emptyList(); } diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/AbstractIdentifiedObject.java index 40eef73fc0,43076c6565..f3023924fa --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/AbstractIdentifiedObject.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/AbstractIdentifiedObject.java @@@ -800,20 -813,13 +818,25 @@@ public class AbstractIdentifiedObject e } } + /** - * Returns {@code true} if the given object implements the same GeoAPI interface as this object. ++ * Returns the type of the given object, ignoring the deprecated {@link Projection} class. ++ * Allows the code to hehave as of the deprecated interface didn't existed. + */ - private boolean implementsSameInterface(final Object object) { - Class<? extends IdentifiedObject> type = getInterface(); - if (Projection.class.isAssignableFrom(type)) { // Deprecated interface, behave as if it does not exist. ++ private static Type getStandardType(final LenientComparable object) { ++ Type type = object.getStandardType(); ++ if ((type instanceof Class<?>) && Projection.class.isAssignableFrom((Class<?>) type)) { + type = Conversion.class; + } - if (object instanceof AbstractIdentifiedObject) { - Class<?> other = ((AbstractIdentifiedObject) object).getInterface(); - if (Projection.class.isAssignableFrom(other)) { - other = Conversion.class; - } - return other == type; ++ return type; ++ } ++ + /** + * Returns {@code true} if the given object implements the same GeoAPI interface as this object. + */ + private boolean implementsSameInterface(final Object object) { - Type type = getStandardType(); ++ Type type = getStandardType(this); + if (object instanceof LenientComparable) { - return type.equals(((LenientComparable) object).getStandardType()); ++ return type.equals(getStandardType((LenientComparable) object)); } /* * Fallback for non-SIS implementations. @@@ -1071,10 -1078,11 +1095,11 @@@ if (identifiers != null) { propertyAlreadySet("setIdentifier", "identifier"); } else if (identifier != null) { - final Identifier id = identifier.getIdentifier(); + final ReferenceIdentifier id = identifier.getIdentifier(); if (id != null) { identifiers = Collections.singleton(id); - ScopedIdentifier<IdentifiedObject> key = new ScopedIdentifier<>(getInterface(), identifier.toString()); + Class<? extends IdentifiedObject> type = Classes.getStandardClass(this, IdentifiedObject.class); + ScopedIdentifier<IdentifiedObject> key = new ScopedIdentifier<>(type, identifier.toString()); key.store(IdentifiedObject.class, this, AbstractIdentifiedObject.class, "setIdentifier"); if (key != (key = key.rename(identifier.code))) { key.store(IdentifiedObject.class, this, null, null); // Shorter form without codespace. diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/Builder.java index 14602bfa74,efb262a864..b3a05802a3 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/Builder.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/Builder.java @@@ -276,8 -273,8 +276,8 @@@ public abstract class Builder<B extend this(); if (object != null) { properties.putAll(IdentifiedObjects.getProperties(object)); - final GenericName[] valueAlias = (GenericName[]) properties.remove(IdentifiedObject.ALIAS_KEY); - final ReferenceIdentifier[] valueIds = (ReferenceIdentifier[]) properties.remove(IdentifiedObject.IDENTIFIERS_KEY); + final var valueAlias = (GenericName[]) properties.remove(IdentifiedObject.ALIAS_KEY); - final var valueIds = (Identifier[]) properties.remove(IdentifiedObject.IDENTIFIERS_KEY); ++ final var valueIds = (ReferenceIdentifier[]) properties.remove(IdentifiedObject.IDENTIFIERS_KEY); if (valueAlias != null) Collections.addAll(aliases, valueAlias); if (valueIds != null) Collections.addAll(identifiers, valueIds); } diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultDerivedCRS.java index 70283c6670,da86912eaa..6158368b35 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultDerivedCRS.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultDerivedCRS.java @@@ -381,28 -382,15 +382,24 @@@ public class DefaultDerivedCRS extends } } + /** + * Returns the type of conversion associated to this {@code DefaultDerivedCRS}. + * Must be a hard-coded, constant value (not dependent on object state). + */ + @Override + final Class<Conversion> getConversionType() { + return Conversion.class; + } + /** - * Returns the GeoAPI interface implemented by this class. - * The SIS implementation returns {@code DerivedCRS.class}. - * - * <h4>Note for implementers</h4> - * Subclasses usually do not need to override this method since GeoAPI does not define {@code DerivedCRS} - * sub-interface. Overriding possibility is left mostly for implementers who wish to extend GeoAPI with - * their own set of interfaces. + * Returns the GeoAPI interface that defines the contract of this implementation class. + * This is the base type required by {@code equals(…)} methods for returning a potentially {@code true} value. * * @return {@code DerivedCRS.class} or a user-defined sub-interface. + * @since 1.7 */ @Override - public Class<? extends DerivedCRS> getInterface() { + public Type getStandardType() { return DerivedCRS.class; } diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java index 91115e1be5,5e0ee051f1..c221b6873b --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java @@@ -221,14 -218,15 +222,15 @@@ public class DefaultGeocentricCRS exten } /** - * Returns the GeoAPI interface implemented by this class. - * The SIS implementation returns {@code GeocentricCRS.class}. + * Returns the GeoAPI interface that defines the contract of this implementation class. + * This is the base type required by {@code equals(…)} methods for returning a potentially {@code true} value. * - * @return {@code GeodeticCRS.class} or a user-defined sub-interface. + * @return {@code GeocentricCRS.class} or a user-defined sub-interface. + * @since 1.7 */ @Override - public Class<? extends GeocentricCRS> getInterface() { + public Type getStandardType() { - return GeodeticCRS.class; + return GeocentricCRS.class; } /** diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultProjectedCRS.java index d1026ad824,7e3209d2d1..c6de7da338 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultProjectedCRS.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultProjectedCRS.java @@@ -197,28 -194,15 +198,24 @@@ public class DefaultProjectedCRS extend ? (DefaultProjectedCRS) object : new DefaultProjectedCRS(object); } + /** + * Returns the type of conversion associated to this {@code DefaultProjectedCRS}. + * Must be a hard-coded, constant value (not dependent on object state). + */ + @Override + final Class<Projection> getConversionType() { + return Projection.class; + } + /** - * Returns the GeoAPI interface implemented by this class. - * The SIS implementation returns {@code ProjectedCRS.class}. - * - * <h4>Note for implementers</h4> - * Subclasses usually do not need to override this method since GeoAPI does not define {@code ProjectedCRS} - * sub-interface. Overriding possibility is left mostly for implementers who wish to extend GeoAPI with - * their own set of interfaces. + * Returns the GeoAPI interface that defines the contract of this implementation class. + * This is the base type required by {@code equals(…)} methods for returning a potentially {@code true} value. * * @return {@code ProjectedCRS.class} or a user-defined sub-interface. + * @since 1.7 */ @Override - public Class<? extends ProjectedCRS> getInterface() { + public Type getStandardType() { return ProjectedCRS.class; } diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultImageCRS.java index 4034b5a263,370a464e6b..fb0dcfafba --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultImageCRS.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultImageCRS.java @@@ -167,8 -132,8 +168,8 @@@ public final class DefaultImageCRS exte * @return the coordinate reference system interface implemented by this class. */ @Override - public Class<? extends ImageCRS> getInterface() { + public Type getStandardType() { - return SingleCRS.class; + return ImageCRS.class; } /** diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultImageDatum.java index 9d706c2f6b,e8568f24e3..782194c540 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultImageDatum.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultImageDatum.java @@@ -18,6 -18,6 +18,7 @@@ package org.apache.sis.referencing.lega import java.util.Map; import java.util.Objects; ++import java.lang.reflect.Type; import jakarta.xml.bind.annotation.XmlType; import jakarta.xml.bind.annotation.XmlElement; import jakarta.xml.bind.annotation.XmlRootElement; @@@ -122,53 -122,6 +123,48 @@@ public final class DefaultImageDatum ex this.pixelInCell = Objects.requireNonNull(pixelInCell); } + /** + * Creates a new datum with the same values as the specified one. + * This copy constructor provides a way to convert an arbitrary implementation into a SIS one + * or a user-defined one (as a subclass), usually in order to leverage some implementation-specific API. + * + * <p>This constructor performs a shallow copy, i.e. the properties are not cloned.</p> + * + * @param datum the datum to copy. + * + * @see #castOrCopy(ImageDatum) + */ + protected DefaultImageDatum(final ImageDatum datum) { + super(datum); + pixelInCell = datum.getPixelInCell(); + } + + /** + * Returns a SIS datum implementation with the same values as the given arbitrary implementation. + * If the given object is {@code null}, then this method returns {@code null}. + * Otherwise if the given object is already a SIS implementation, then the given object is returned unchanged. + * Otherwise a new SIS implementation is created and initialized to the attribute values of the given object. + * + * @param object the object to get as a SIS implementation, or {@code null} if none. + * @return a SIS implementation containing the values of the given object (may be the + * given object itself), or {@code null} if the argument was null. + */ + public static DefaultImageDatum castOrCopy(final ImageDatum object) { + return (object == null) || (object instanceof DefaultImageDatum) + ? (DefaultImageDatum) object : new DefaultImageDatum(object); + } + + /** - * Returns the GeoAPI interface implemented by this class. - * The SIS implementation returns {@code ImageDatum.class}. - * - * <h4>Note for implementers</h4> - * Subclasses usually do not need to override this method since GeoAPI does not define {@code ImageDatum} - * sub-interface. Overriding possibility is left mostly for implementers who wish to extend GeoAPI with - * their own set of interfaces. ++ * Returns the GeoAPI interface that defines the contract of this implementation class. ++ * This is the base type required by {@code equals(…)} methods for returning a potentially {@code true} value. + * + * @return {@code ImageDatum.class} or a user-defined sub-interface. + */ + @Override - public Class<? extends ImageDatum> getInterface() { ++ public Type getStandardType() { + return ImageDatum.class; + } + /** * Specification of the way the image grid is associated with the image data attributes. * diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultUserDefinedCS.java index 99ff3a8e10,771156d8b2..2e35b393a2 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultUserDefinedCS.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/legacy/DefaultUserDefinedCS.java @@@ -116,51 -113,6 +116,46 @@@ public final class DefaultUserDefinedC super(properties, axis0, axis1, axis2); } + /** + * Creates a new coordinate system with the same values as the specified one. + * This copy constructor provides a way to convert an arbitrary implementation into a SIS one + * or a user-defined one (as a subclass), usually in order to leverage some implementation-specific API. + * + * <p>This constructor performs a shallow copy, i.e. the properties are not cloned.</p> + * + * @param original the coordinate system to copy. + * + * @see #castOrCopy(UserDefinedCS) + */ + protected DefaultUserDefinedCS(final UserDefinedCS original) { + super(original); + } + + /** + * Returns a SIS coordinate system implementation with the same values as the given arbitrary implementation. + * If the given object is {@code null}, then this method returns {@code null}. + * Otherwise if the given object is already a SIS implementation, then the given object is returned unchanged. + * Otherwise a new SIS implementation is created and initialized to the attribute values of the given object. + * + * @param object the object to get as a SIS implementation, or {@code null} if none. + * @return a SIS implementation containing the values of the given object (may be the + * given object itself), or {@code null} if the argument was null. + */ + public static DefaultUserDefinedCS castOrCopy(final UserDefinedCS object) { + return (object == null) || (object instanceof DefaultUserDefinedCS) + ? (DefaultUserDefinedCS) object : new DefaultUserDefinedCS(object); + } + + /** - * Returns the GeoAPI interface implemented by this class. - * The SIS implementation returns {@code UserDefinedCS.class}. - * - * <h4>Note for implementers</h4> - * Subclasses usually do not need to override this method since GeoAPI does not define {@code UserDefinedCS} - * sub-interface. Overriding possibility is left mostly for implementers who wish to extend GeoAPI with their - * own set of interfaces. ++ * Returns the GeoAPI interface that defines the contract of this implementation class. ++ * This is the base type required by {@code equals(…)} methods for returning a potentially {@code true} value. + * + * @return {@code UserDefinedCS.class} or a user-defined sub-interface. + */ + @Override - public Class<? extends UserDefinedCS> getInterface() { ++ public Class<? extends UserDefinedCS> getStandardType() { + return UserDefinedCS.class; + } diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java index 49ba178ccf,088f11239a..838108dad8 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java @@@ -468,19 -466,8 +469,19 @@@ check: for (int isTarget=0; ; isTa return new AbstractCoordinateOperation(object); } + /** + * Returns {@code true} if the given operation is a single operation but not a pass-through operation. + * In an older ISO 19111 model, {@link PassThroughOperation} extended {@link SingleOperation}, which + * was a problem for providing a value to the inherited {@link SingleOperation#getMethod()} method. + * This has been fixed in newer ISO 19111 model, but for safety with objects following the older model + * (e.g. GeoAPI 3.0) we are better to perform an explicit exclusion of {@link PassThroughOperation}. + */ + static boolean isSingleOperation(final CoordinateOperation operation) { + return (operation instanceof SingleOperation) && !(operation instanceof PassThroughOperation); + } + /** - * Returns the GeoAPI interface implemented by this class. + * Returns the GeoAPI interface that defines the contract of this implementation class. * The default implementation returns {@code CoordinateOperation.class}. * Subclasses implementing a more specific GeoAPI interface shall override this method. * diff --cc endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/DefaultProjection.java index fd914eddcc,0000000000..126cd4204f mode 100644,000000..100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/DefaultProjection.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/DefaultProjection.java @@@ -1,110 -1,0 +1,110 @@@ +/* + * 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.referencing.operation; + +import java.util.Map; +import jakarta.xml.bind.annotation.XmlTransient; +import org.opengis.util.FactoryException; +import org.opengis.referencing.operation.Conversion; +import org.opengis.referencing.operation.Projection; +import org.opengis.referencing.operation.OperationMethod; +import org.opengis.referencing.operation.MathTransform; +import org.opengis.referencing.operation.MathTransformFactory; +import org.opengis.referencing.crs.ProjectedCRS; +import org.opengis.referencing.crs.GeographicCRS; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.apache.sis.util.ArgumentChecks; + + +/** + * A conversion from (<var>longitude</var>, <var>latitude</var>) coordinates to Cartesian coordinates + * (<var>x</var>,<var>y</var>). + * + * @author Martin Desruisseaux (IRD, Geomatys) + * + * @see org.apache.sis.referencing.crs.DefaultProjectedCRS + */ +@XmlTransient +final class DefaultProjection extends DefaultConversion implements Projection { + /** + * Serial number for inter-operability with different versions. + */ + private static final long serialVersionUID = -7176751851369816864L; + + /** + * Creates a projection from the given properties. + * + * @param properties the properties to be given to the identified object. + * @param sourceCRS the source CRS. + * @param targetCRS the target CRS. + * @param method the coordinate operation method. + * @param transform transform from positions in the source CRS to positions in the target CRS. + */ + public DefaultProjection(final Map<String,?> properties, + final GeographicCRS sourceCRS, + final ProjectedCRS targetCRS, + final OperationMethod method, + final MathTransform transform) + { + super(properties, sourceCRS, targetCRS, null, method, transform); + } + + /** + * Creates a new projection with the same values as the specified one, together with the + * specified source and target CRS. While the source conversion can be an arbitrary one, + * it is typically a defining conversion. + * + * @param definition the defining conversion. + * @param sourceCRS the source CRS. + * @param targetCRS the target CRS. + * @param factory the factory to use for creating a transform from the parameters or for performing axis changes. + * @throws IllegalArgumentException if the source or targe CRS is not of the expected types. + */ + DefaultProjection(final Conversion definition, + final boolean normalized, + final CoordinateReferenceSystem sourceCRS, + final CoordinateReferenceSystem targetCRS, + final MathTransformFactory factory) throws FactoryException + { + super(definition, normalized, sourceCRS, targetCRS, factory); + ArgumentChecks.ensureCanCast("sourceCRS", GeographicCRS.class, sourceCRS); + ArgumentChecks.ensureCanCast("targetCRS", ProjectedCRS .class, targetCRS); + } + + /** + * Creates a new coordinate operation with the same values as the specified one. + * This copy constructor provides a way to convert an arbitrary implementation + * into a SIS one, usually in order to leverage some implementation-specific API. + * + * <p>This constructor performs a shallow copy, i.e. the properties are not cloned.</p> + * + * @param operation the coordinate operation to copy. + */ + protected DefaultProjection(final Projection operation) { + super(operation); + } + + /** + * Returns the GeoAPI interface implemented by this class. + * + * @return the conversion interface implemented by this class. + */ + @Override - public Class<? extends Projection> getInterface() { ++ public Class<? extends Projection> getStandardType() { + return Projection.class; + } +} diff --cc endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/URIDataStoreOption.java index 0000000000,2a11917c63..186806e78b mode 000000,100644..100644 --- 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 @@@ -1,0 -1,333 +1,333 @@@ + /* + * 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.StandardOpenOption; + 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.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(URIDataStoreProvider.LOCATION, Resources.Keys.DataStoreLocation, URI.class), + + /** + * Description of the optional {@value URIDataStoreProvider#FORMAT} parameter. + * + * @see URIDataStoreProvider#FORMAT + */ + FORMAT(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(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), + + /** + * 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), + + /** + * 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), + + /** + * 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), + + /** + * Description of the optional "metadata" parameter. + * + * @see OptionKey#METADATA_PATH + */ + METADATA(OptionKey.METADATA_PATH), + + /** + * 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); + + /** + * The option key for storing the parameter value in a storage connector, + * or {@code null} if none. + */ + private final OptionKey<?> option; + + /** + * The parameter descriptor for this option, or {@code null} if not yet constructed. + * + * @see #getParameterDescriptor() + */ + private volatile ParameterDescriptor<?> parameter; + + /** + * Creates a new enumeration value with deferred construction of the parameter descriptor. + * + * @param option associated option in {@link StorageConnector}. + */ + private URIDataStoreOption(final OptionKey<?> option) { + this.option = option; + } + + /** + * Creates a new enumeration value with immediate construction of the parameter descriptor. + * + * @param parameterName name of the parameter to create. + * @param description constant from {@link Resources} keys for the localized description. + * @param valueClass type of value of the parameter. + */ + private <V> URIDataStoreOption(final String parameterName, final short description, final Class<V> valueClass) { + option = null; + parameter = new ParameterBuilder() + .addName(parameterName) + .setDescription(Resources.formatInternational(description)) + .setRequired(ordinal() == 0) + .create(valueClass, null); + } + + /** + * 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() { + ParameterDescriptor<?> p = parameter; + if (p == null) { + p = option.asOpenParameter().orElseThrow(() -> new IllegalStateException(name())); + } + return p; + } + + /** + * Returns the parameter name. + */ + private String parameterName() { + return getParameterDescriptor().getName().getCode(); + } + + /** + * 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); ++ if (remarks == null) remarks = p.getRemarks(); + 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(URIDataStoreProvider.LOCATION).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())); + } + }
