This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-3.1
in repository https://gitbox.apache.org/repos/asf/sis.git

commit eb20f53e20d2f678e87ac4aa4481d4db2628708e
Merge: b6af5d3997 409c3a3234
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Sun Dec 17 10:59:41 2023 +0100

    Merge branch 'geoapi-4.0' into geoapi-3.1.
    Contains initial version of shapefile writer and improvement in JShell 
environment.

 .../main/org/apache/sis/console/AboutCommand.java  |   10 +-
 .../main/org/apache/sis/console/Command.java       |   26 +-
 .../main/org/apache/sis/console/CommandRunner.java |  127 +-
 .../apache/sis/console/FormattedOutputCommand.java |   25 +-
 .../org/apache/sis/console/IdentifierCommand.java  |   12 +-
 .../main/org/apache/sis/console/InfoCommand.java   |    2 +-
 .../org/apache/sis/console/MetadataCommand.java    |    5 +-
 .../main/org/apache/sis/console/Option.java        |    5 +
 .../main/org/apache/sis/console/Options.properties |    7 +-
 .../org/apache/sis/console/Options_fr.properties   |    7 +-
 .../apache/sis/console/ResourcesDownloader.java    |    3 +-
 .../main/org/apache/sis/console/SIS.java           |   69 +-
 .../org/apache/sis/console/TransformCommand.java   |   49 +-
 .../org/apache/sis/console/TranslateCommand.java   |    4 +-
 .../org/apache/sis/coverage/grid/GridGeometry.java |   14 +-
 .../org/apache/sis/feature/FeatureOperations.java  |    3 +-
 .../apache/sis/metadata/internal/Identifiers.java  |   27 +
 .../apache/sis/metadata/internal/NameMeaning.java  |    4 +-
 .../sis/metadata/internal/ReferencingServices.java |   35 +-
 .../apache/sis/metadata/internal/Resources.java    |    9 +-
 .../sis/metadata/internal/Resources.properties     |    2 +-
 .../sis/metadata/internal/Resources_fr.properties  |    2 +-
 .../sis/metadata/iso/extent/DefaultExtent.java     |    4 +-
 .../iso/extent/DefaultGeographicBoundingBox.java   |    4 +-
 .../iso/extent/DefaultSpatialTemporalExtent.java   |    4 +-
 .../metadata/iso/extent/DefaultTemporalExtent.java |    4 +-
 .../metadata/iso/extent/DefaultVerticalExtent.java |    4 +-
 .../iso/extent/NotSpatioTemporalException.java     |   86 ++
 .../sis/metadata/iso/extent/package-info.java      |    2 +-
 .../apache/sis/xml/bind/IdentifierMapAdapter.java  |    2 +-
 .../sis/xml/bind/ModifiableIdentifierMap.java      |    2 +-
 .../sis/xml/bind/NonMarshalledAuthority.java       |    2 +-
 .../sis/xml/CharSequenceSubstitutionTest.java      |   19 +-
 .../test/org/apache/sis/xml/LegacyCodesTest.java   |   98 +-
 .../org/apache/sis/xml/MarshallerPoolTest.java     |    2 +-
 .../test/org/apache/sis/xml/NamespacesTest.java    |   15 +-
 .../apache/sis/xml/NilReasonMarshallingTest.java   |   41 +-
 .../test/org/apache/sis/xml/TransformerTest.java   |   28 +-
 .../apache/sis/xml/TransformingNamespacesTest.java |    4 +-
 .../org/apache/sis/xml/UUIDMarshallingTest.java    |   35 +-
 .../org/apache/sis/xml/ValueConverterTest.java     |    2 +-
 .../org/apache/sis/xml/XLinkMarshallingTest.java   |    9 +-
 .../test/org/apache/sis/xml/XLinkTest.java         |   96 +-
 .../test/org/apache/sis/xml/XPointerTest.java      |    2 +-
 .../org/apache/sis/geometry/EnvelopeReducer.java   |    2 +
 .../apache/sis/geometry/WraparoundAdjustment.java  |    4 +-
 .../main/org/apache/sis/io/wkt/AbstractParser.java |    3 +-
 .../org/apache/sis/io/wkt/FormattableObject.java   |   17 +-
 .../main/org/apache/sis/io/wkt/Formatter.java      |   60 +-
 .../main/org/apache/sis/io/wkt/WKTDictionary.java  |    2 +-
 .../main/org/apache/sis/io/wkt/WKTFormat.java      |   12 +-
 .../main/org/apache/sis/io/wkt/package-info.java   |    2 +-
 .../sis/parameter/DefaultParameterValue.java       |    1 +
 .../org/apache/sis/parameter/ParameterFormat.java  |   11 +-
 .../main/org/apache/sis/parameter/Parameters.java  |    6 +-
 .../main/org/apache/sis/referencing/CRS.java       |   31 +-
 .../apache/sis/referencing/IdentifiedObjects.java  |    4 +-
 .../sis/referencing/ImmutableIdentifier.java       |    2 +-
 .../sis/referencing/crs/DefaultCompoundCRS.java    |    4 +
 .../sis/referencing/crs/DefaultGeodeticCRS.java    |    1 +
 .../cs/DefaultCoordinateSystemAxis.java            |    6 +-
 .../sis/referencing/datum/DefaultEllipsoid.java    |    1 +
 .../sis/referencing/factory/CacheRecord.java       |    5 +-
 .../referencing/factory/CommonAuthorityCode.java   |    3 +-
 .../factory/ConcurrentAuthorityFactory.java        |   24 +-
 .../referencing/factory/sql/EPSGDataAccess.java    |    2 +-
 .../sis/referencing/factory/sql/SQLTranslator.java |   14 +-
 .../apache/sis/referencing/internal/Resources.java |   33 +-
 .../sis/referencing/internal/Resources.properties  |    5 +-
 .../referencing/internal/Resources_fr.properties   |    5 +-
 .../referencing/internal/ServicesForMetadata.java  |   85 +-
 .../operation/transform/MathTransformProvider.java |   35 +-
 .../sis/referencing/util/ReferencingUtilities.java |   18 +-
 .../test/org/apache/sis/io/wkt/FormatterTest.java  |   11 -
 .../internal/ServicesForMetadataTest.java          |   30 +-
 .../referencing/util/j2d/ShapeUtilitiesViewer.java |    5 +-
 .../sis/storage/netcdf/base/RasterResource.java    |    2 +-
 .../org/apache/sis/storage/gpx/WritableStore.java  |    2 +-
 .../services/java.nio.file.spi.FileTypeDetector    |    2 +-
 .../org.apache.sis.storage/main/module-info.java   |    2 +-
 .../sis/io/stream/ChannelImageOutputStream.java    |    2 -
 .../main/org/apache/sis/io/stream/IOUtilities.java |   62 +-
 .../apache/sis/io/stream/OutputStreamAdapter.java  |    2 +-
 .../main/org/apache/sis/storage/DataOptionKey.java |   47 +-
 .../org/apache/sis/storage/DataStoreProvider.java  |   10 +-
 .../org/apache/sis/storage/DataStoreRegistry.java  |    3 +-
 .../main/org/apache/sis/storage/ProbeReader.java   |    2 +-
 .../org/apache/sis/storage/StorageConnector.java   |   10 +-
 .../apache/sis/storage/base/MetadataBuilder.java   |  193 ++-
 .../org/apache/sis/storage/base/PRJDataStore.java  |   44 +-
 .../org/apache/sis/storage/base/URIDataStore.java  |  203 ++-
 .../main/org/apache/sis/storage/csv/Store.java     |    3 +-
 .../org/apache/sis/storage/csv/StoreProvider.java  |    2 +-
 .../org/apache/sis/storage/esri/RasterStore.java   |    4 +-
 .../apache/sis/storage/esri/RawRasterStore.java    |    3 +-
 .../sis/storage/esri/RawRasterStoreProvider.java   |    5 +-
 .../apache/sis/storage/folder/WritableStore.java   |    3 +-
 .../apache/sis/storage/image/WorldFileStore.java   |   20 +-
 .../apache/sis/storage/image/WritableStore.java    |    7 +
 .../internal}/InputStreamAdapter.java              |   15 +-
 .../org/apache/sis/storage/internal/Resources.java |    5 +
 .../sis/storage/internal/Resources.properties      |    1 +
 .../sis/storage/internal/Resources_fr.properties   |    1 +
 .../internal}/RewindableLineReader.java            |    2 +-
 .../{internal => services}/StoreTypeDetector.java  |    2 +-
 .../apache/sis/storage/services/package-info.java  |   19 +-
 .../main/org/apache/sis/storage/wkt/Store.java     |    2 +
 .../main/org/apache/sis/storage/xml/Store.java     |    1 +
 .../org/apache/sis/io/stream/IOUtilitiesTest.java  |   15 +-
 .../org/apache/sis/storage/DataOptionKeyTest.java  |   33 +-
 .../apache/sis/storage/StorageConnectorTest.java   |   81 +-
 .../test/org/apache/sis/storage/esri/BIL.prj       |    7 +
 .../test/org/apache/sis/storage/esri/BIP.prj       |    7 +
 .../test/org/apache/sis/storage/esri/BSQ.prj       |    7 +
 .../internal}/RewindableLineReaderTest.java        |   39 +-
 .../org/apache/sis/io/IdentifiedObjectFormat.java  |    3 +-
 .../main/org/apache/sis/measure/AbstractUnit.java  |    3 +-
 .../main/org/apache/sis/measure/UnitFormat.java    |   62 +-
 .../main/org/apache/sis/measure/UnitRegistry.java  |    3 +-
 .../main/org/apache/sis/pending/jdk/JDK21.java     |   62 +
 .../main/org/apache/sis/setup/OptionKey.java       |   28 +-
 .../main/org/apache/sis/setup/package-info.java    |    2 +-
 .../main/org/apache/sis/system/DataDirectory.java  |    3 +-
 .../main/org/apache/sis/system/Environment.java    |   87 ++
 .../main/org/apache/sis/util/ArraysExt.java        |   83 +-
 .../main/org/apache/sis/util/Printable.java        |   42 +
 .../org/apache/sis/util/internal/Constants.java    |    5 +
 .../apache/sis/util/internal/DefinitionURI.java    |   81 +-
 .../main/org/apache/sis/util/internal/Strings.java |   11 +
 .../main/org/apache/sis/util/resources/Errors.java |    5 +
 .../apache/sis/util/resources/Errors.properties    |    1 +
 .../apache/sis/util/resources/Errors_fr.properties |    1 +
 .../sis/util/resources/IndexedResourceBundle.java  |    2 +-
 .../org/apache/sis/measure/UnitFormatTest.java     |  117 +-
 .../test/org/apache/sis/setup/OptionKeyTest.java   |    4 +-
 .../test/org/apache/sis/util/ArraysExtTest.java    |   26 +-
 .../sis/util/internal/DefinitionURITest.java       |  190 +--
 .../main/module-info.java                          |    7 +-
 .../storage/shapefile/DataStoreQueryException.java |   50 -
 .../shapefile/DataStoreQueryResultException.java   |   50 -
 .../shapefile/DbaseFileNotFoundException.java      |   50 -
 .../sis/storage/shapefile/InputFeatureStream.java  |  379 ------
 .../shapefile/InputFeatureStream.properties        |    9 -
 .../shapefile/InputFeatureStream_fr.properties     |    9 -
 .../shapefile/InvalidDbaseFileFormatException.java |   34 -
 .../shapefile/InvalidShapefileFormatException.java |   50 -
 .../apache/sis/storage/shapefile/ShapeFile.java    |  206 ----
 .../sis/storage/shapefile/ShapeTypeEnum.java       |   73 --
 .../shapefile/ShapefileNotFoundException.java      |   50 -
 .../sis/storage/shapefile/ShapefileProvider.java   |   24 +
 .../sis/storage/shapefile/ShapefileStore.java      |  105 +-
 .../shapefile/{jdbc/sql => cpg}/package-info.java  |    5 +-
 .../apache/sis/storage/shapefile/dbf/DBFField.java |  147 ++-
 .../sis/storage/shapefile/dbf/DBFHeader.java       |   63 +-
 .../sis/storage/shapefile/dbf/DBFReader.java       |   48 +-
 .../sis/storage/shapefile/dbf/DBFWriter.java       |   39 +-
 .../dbf/{DBFRecord.java => package-info.java}      |   28 +-
 .../storage/shapefile/internal/AutoChecker.java    |  184 ---
 ...nvalidRecordNumberForDirectAccessException.java |   62 -
 .../SQLNoDirectAccessAvailableException.java       |   47 -
 .../internal/SQLShapefileNotFoundException.java    |   47 -
 .../shapefile/internal/ShapefileByteReader.java    |  464 -------
 .../internal/ShapefileByteReader.properties        |   36 -
 .../internal/ShapefileByteReader_fr.properties     |   36 -
 .../shapefile/internal/ShapefileDescriptor.java    |  198 ---
 .../storage/shapefile/internal/package-info.java   |   22 -
 .../shapefile/jdbc/AbstractDbase3ByteReader.java   |  281 -----
 .../jdbc/AbstractDbase3ByteReader.properties       |   14 -
 .../jdbc/AbstractDbase3ByteReader_fr.properties    |   14 -
 .../sis/storage/shapefile/jdbc/AbstractJDBC.java   |  158 ---
 .../storage/shapefile/jdbc/AbstractJDBC.properties |   23 -
 .../shapefile/jdbc/AbstractJDBC_fr.properties      |    1 -
 .../storage/shapefile/jdbc/CommonByteReader.java   |  129 --
 .../shapefile/jdbc/CommonByteReader.properties     |    3 -
 .../sis/storage/shapefile/jdbc/DBFDriver.java      |  141 ---
 .../shapefile/jdbc/DBase3FieldDescriptor.java      |  146 ---
 .../jdbc/DBase3FieldDescriptor.properties          |    7 -
 .../jdbc/DBase3FieldDescriptor_fr.properties       |    1 -
 .../sis/storage/shapefile/jdbc/DBaseDataType.java  |   99 --
 .../storage/shapefile/jdbc/Dbase3ByteReader.java   |  132 --
 .../storage/shapefile/jdbc/MappedByteReader.java   |  307 -----
 .../shapefile/jdbc/MappedByteReader.properties     |   30 -
 .../shapefile/jdbc/MappedByteReader_fr.properties  |   30 -
 .../jdbc/SQLConnectionClosedException.java         |   64 -
 .../jdbc/SQLInvalidDbaseFileFormatException.java   |   47 -
 .../jdbc/connection/AbstractConnection.java        |  414 -------
 .../jdbc/connection/AbstractConnection.properties  |    6 -
 .../connection/AbstractConnection_fr.properties    |    6 -
 .../shapefile/jdbc/connection/DBFConnection.java   |  332 -----
 .../jdbc/connection/DBFConnection.properties       |   49 -
 .../jdbc/connection/DBFConnection_fr.properties    |   39 -
 .../connection/SQLClosingIOFailureException.java   |   64 -
 .../shapefile/jdbc/connection/package-info.java    |   19 -
 .../jdbc/metadata/AbstractDatabaseMetaData.java    |  202 ---
 .../jdbc/metadata/DBFDatabaseMetaData.java         | 1300 --------------------
 .../jdbc/metadata/DBFResultSetMataData.java        |  473 -------
 .../jdbc/metadata/DBFResultSetMataData.properties  |   14 -
 .../metadata/DBFResultSetMataData_fr.properties    |    4 -
 .../shapefile/jdbc/metadata/package-info.java      |   21 -
 .../jdbc/resultset/AbstractResultSet.java          |  703 -----------
 .../jdbc/resultset/AbstractResultSet.properties    |    1 -
 .../jdbc/resultset/AbstractResultSet_fr.properties |    1 -
 .../jdbc/resultset/BuiltInMemoryResultSet.java     |  192 ---
 ...iltInMemoryResultSetForCatalogNamesListing.java |   51 -
 ...DBFBuiltInMemoryResultSetForColumnsListing.java |  460 -------
 ...ltInMemoryResultSetForColumnsListing.properties |    8 -
 ...nMemoryResultSetForColumnsListing_fr.properties |    8 -
 .../DBFBuiltInMemoryResultSetForSchemaListing.java |   51 -
 .../DBFBuiltInMemoryResultSetForTablesListing.java |   88 --
 ...iltInMemoryResultSetForTablesListing.properties |    2 -
 ...uiltInMemoryResultSetForTablesTypesListing.java |   74 --
 ...MemoryResultSetForTablesTypesListing.properties |    2 -
 .../jdbc/resultset/DBFRecordBasedResultSet.java    |  609 ---------
 .../resultset/DBFRecordBasedResultSet.properties   |   28 -
 .../DBFRecordBasedResultSet_fr.properties          |   28 -
 .../shapefile/jdbc/resultset/DBFResultSet.java     |  965 ---------------
 .../jdbc/resultset/DBFResultSet.properties         |   10 -
 .../jdbc/resultset/DBFResultSet_fr.properties      |    4 -
 .../resultset/SQLIllegalColumnIndexException.java  |   77 --
 .../jdbc/resultset/SQLNoResultException.java       |   64 -
 .../jdbc/resultset/SQLNoSuchFieldException.java    |   77 --
 .../jdbc/resultset/SQLNotDateException.java        |   90 --
 .../jdbc/resultset/SQLNotNumericException.java     |   90 --
 .../shapefile/jdbc/resultset/package-info.java     |   21 -
 .../storage/shapefile/jdbc/sql/ClauseResolver.java |  391 ------
 .../shapefile/jdbc/sql/ClauseResolver.properties   |   25 -
 .../jdbc/sql/ClauseResolver_fr.properties          |   16 -
 .../jdbc/sql/ConditionalClauseResolver.java        |   39 -
 .../storage/shapefile/jdbc/sql/CrudeSQLParser.java |  137 ---
 .../shapefile/jdbc/sql/CrudeSQLParser.properties   |   12 -
 .../jdbc/sql/SQLIllegalParameterException.java     |   90 --
 .../jdbc/sql/SQLInvalidStatementException.java     |   64 -
 .../sql/SQLUnsupportedParsingFeatureException.java |   64 -
 .../jdbc/statement/AbstractStatement.java          |  304 -----
 .../shapefile/jdbc/statement/DBFStatement.java     |  240 ----
 .../jdbc/statement/DBFStatement.properties         |   22 -
 .../jdbc/statement/DBFStatement_fr.properties      |   12 -
 .../apache/sis/storage/shapefile/package-info.java |   23 +-
 .../shapefile/shp/ShapeGeometryEncoder.java        |  151 ++-
 .../sis/storage/shapefile/shp/ShapeHeader.java     |   15 +-
 .../sis/storage/shapefile/shp/ShapeReader.java     |   29 +
 .../sis/storage/shapefile/shp/ShapeRecord.java     |   55 +-
 .../sis/storage/shapefile/shp/ShapeType.java       |   83 +-
 .../sis/storage/shapefile/shp/ShapeWriter.java     |   48 +-
 .../shapefile/{jdbc => shp}/package-info.java      |   14 +-
 .../sis/storage/shapefile/shx/IndexReader.java     |   27 +-
 .../sis/storage/shapefile/shx/IndexWriter.java     |   37 +-
 .../{jdbc/statement => shx}/package-info.java      |    6 +-
 .../shapefile/ABRALicenseePt_4326_clipped.dbf      |  Bin 5861 -> 0 bytes
 .../shapefile/ABRALicenseePt_4326_clipped.prj      |    1 -
 .../shapefile/ABRALicenseePt_4326_clipped.shp      |  Bin 184 -> 0 bytes
 .../shapefile/ABRALicenseePt_4326_clipped.shx      |  Bin 124 -> 0 bytes
 .../test/org/apache/sis/storage/shapefile/NOTES.md |   12 -
 .../sis/storage/shapefile/ShapeFileTest.java       |  209 ----
 .../sis/storage/shapefile/ShapefileStoreTest.java  |   89 +-
 .../shapefile/SignedBikeRoute_4326_clipped.dbf     |  Bin 7363 -> 0 bytes
 .../shapefile/SignedBikeRoute_4326_clipped.prj     |    1 -
 .../shapefile/SignedBikeRoute_4326_clipped.shp     |  Bin 1148 -> 0 bytes
 .../shapefile/SignedBikeRoute_4326_clipped.shx     |  Bin 148 -> 0 bytes
 .../org/apache/sis/storage/shapefile/Snippets.java |  106 ++
 .../sis/storage/shapefile/dbf/DBFIOTest.java       |   46 +-
 .../apache/sis/storage/shapefile/dbf/Snippets.java |   95 ++
 .../jdbc/AbstractTestBaseForInternalJDBC.java      |   73 --
 .../storage/shapefile/jdbc/DBFConnectionTest.java  |   93 --
 .../storage/shapefile/jdbc/DBFResultSetTest.java   |  206 ----
 .../storage/shapefile/jdbc/DBFStatementTest.java   |   98 --
 .../apache/sis/storage/shapefile/jdbc/README.md    |   60 -
 .../shapefile/jdbc/sql/WhereClauseTest.java        |  147 ---
 .../sis/storage/shapefile/shp/ShapeIOTest.java     |    4 +-
 .../apache/sis/storage/shapefile/shp/Snippets.java |   81 ++
 .../src/org.apache.sis.gui/bundle/conf/imports.jsh |    1 +
 271 files changed, 3078 insertions(+), 13991 deletions(-)

diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/ParameterFormat.java
index 3c83d68e83,3e13498216..565bacfc57
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/ParameterFormat.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/ParameterFormat.java
@@@ -51,15 -52,12 +52,15 @@@ import org.apache.sis.util.ArgumentChec
  import org.apache.sis.util.iso.Types;
  import org.apache.sis.util.resources.Errors;
  import org.apache.sis.util.resources.Vocabulary;
- import org.apache.sis.referencing.IdentifiedObjects;
- import org.apache.sis.metadata.internal.NameToIdentifier;
  import org.apache.sis.util.internal.CollectionsExt;
  import org.apache.sis.util.internal.X364;
+ import org.apache.sis.referencing.IdentifiedObjects;
+ import org.apache.sis.metadata.internal.NameToIdentifier;
  import static org.apache.sis.util.collection.Containers.hashMapCapacity;
  
 +// Specific to the main and geoapi-3.1 branches:
 +import org.opengis.referencing.ReferenceIdentifier;
 +
  // Specific to the geoapi-3.1 and geoapi-4.0 branches:
  import org.opengis.util.ControlledVocabulary;
  
diff --cc 
endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/MetadataBuilder.java
index 852b17066c,24953fbd3a..c2863733cb
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/MetadataBuilder.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/MetadataBuilder.java
@@@ -3250,9 -3284,13 +3287,13 @@@ parse:      for (int i = 0; i < length;
          for (final Identification info : component.getIdentificationInfo()) {
              final Citation c = info.getCitation();
              if (c != null) {
-                 // Title, identifiers and series are assumed to not apply 
(see Javadoc).
+                 // Title (except first one), identifiers and series are 
assumed to not apply (see Javadoc).
+                 @SuppressWarnings("LocalVariableHidesMemberVariable")
                  final DefaultCitation citation = citation();
+                 if (citation.getTitle() == null) {
+                     citation.setTitle(c.getTitle());
+                 }
 -                for (Responsibility r : c.getCitedResponsibleParties()) {
 +                for (ResponsibleParty r : c.getCitedResponsibleParties()) {
                      addIfNotPresent(citation.getCitedResponsibleParties(), r);
                  }
                  for (OnlineResource r : c.getOnlineResources()) {
@@@ -3353,6 -3407,81 +3411,81 @@@
          return true;
      }
  
+     /**
+      * Replaces any null metadata element by the last element from the parent.
+      * This is used for continuing the edition of an existing metadata.
+      */
+     private void useParentElements() {
+         if (identification      == null) identification      = last 
(DefaultDataIdentification.class,          metadata,            
DefaultMetadata::getIdentificationInfo);
+         if (gridRepresentation  == null) gridRepresentation  = last 
(DefaultGridSpatialRepresentation.class,   metadata,            
DefaultMetadata::getSpatialRepresentationInfo);
+         if (coverageDescription == null) coverageDescription = last 
(DefaultCoverageDescription.class,         metadata,            
DefaultMetadata::getContentInfo);
+         if (featureDescription  == null) featureDescription  = last 
(DefaultFeatureCatalogueDescription.class, metadata,            
DefaultMetadata::getContentInfo);
+         if (acquisition         == null) acquisition         = last 
(DefaultAcquisitionInformation.class,      metadata,            
DefaultMetadata::getAcquisitionInformation);
+         if (lineage             == null) lineage             = last 
(DefaultLineage.class,                     metadata,            
DefaultMetadata::getResourceLineages);
 -        if (distribution        == null) distribution        = last 
(DefaultDistribution.class,                metadata,            
DefaultMetadata::getDistributionInfo);
++        if (distribution        == null) distribution        = 
fetch(DefaultDistribution.class,                metadata,            
DefaultMetadata::getDistributionInfo);
+         if (citation            == null) citation            = 
fetch(DefaultCitation.class,                    identification,      
AbstractIdentification::getCitation);
+         if (extent              == null) extent              = last 
(DefaultExtent.class,                      identification,      
AbstractIdentification::getExtents);
+         if (constraints         == null) constraints         = last 
(DefaultLegalConstraints.class,            identification,      
AbstractIdentification::getResourceConstraints);
 -        if (responsibility      == null) responsibility      = last 
(DefaultResponsibility.class,              citation,            
DefaultCitation::getCitedResponsibleParties);
++        if (responsibility      == null) responsibility      = last 
(DefaultResponsibleParty.class,            citation,            
DefaultCitation::getCitedResponsibleParties);
+         if (party               == null) party               = last 
(AbstractParty.class,                      responsibility,      
DefaultResponsibility::getParties);
+         if (attributeGroup      == null) attributeGroup      = last 
(DefaultAttributeGroup.class,              coverageDescription, 
DefaultCoverageDescription::getAttributeGroups);
+         if (sampleDimension     == null) sampleDimension     = last 
(DefaultSampleDimension.class,             attributeGroup,      
DefaultAttributeGroup::getAttributes);
+         if (format              == null) format              = last 
(DefaultFormat.class,                      distribution,        
DefaultDistribution::getDistributionFormats);
+         if (platform            == null) platform            = last 
(DefaultPlatform.class,                    acquisition,         
DefaultAcquisitionInformation::getPlatforms);
+         if (processStep         == null) processStep         = last 
(DefaultProcessStep.class,                 lineage,             
DefaultLineage::getProcessSteps);
+         if (processing          == null) processing          = 
fetch(DefaultProcessing.class,                  processStep,         
DefaultProcessStep::getProcessingInformation);
+     }
+ 
+     /**
+      * Returns the element of the given source metadata if it is of the 
desired class.
+      * This method is equivalent to {@link #last(Class, Object, Function)} 
but for a singleton.
+      *
+      * @param  <S>     the type of the source metadata.
+      * @param  <E>     the type of metadata element provided by the source.
+      * @param  <T>     the type of the desired metadata element.
+      * @param  target  the type of the desired metadata element.
+      * @param  source  the source metadata, or {@code null} if none.
+      * @param  getter  the getter to use for fetching elements from the 
source metadata.
+      * @return the metadata element from the source, or {@code null} if none.
+      */
+     private static <S extends ISOMetadata, E, T extends E> T fetch(final 
Class<T> target, final S source,
+             final Function<S,E> getter)
+     {
+         if (source != null) {
+             final E last = getter.apply(source);
+             if (target.isInstance(last)) {
+                 return target.cast(last);
+             }
+         }
+         return null;
+     }
+ 
+     /**
+      * Returns the element of the given source metadata if it is of the 
desired class.
+      * This method is equivalent to {@link #fetch(Class, Object, Function)} 
but for a collection.
+      *
+      * @param  <S>     the type of the source metadata.
+      * @param  <E>     the type of metadata element provided by the source.
+      * @param  <T>     the type of the desired metadata element.
+      * @param  target  the type of the desired metadata element.
+      * @param  source  the source metadata, or {@code null} if none.
+      * @param  getter  the getter to use for fetching elements from the 
source metadata.
+      * @return the metadata element from the source, or {@code null} if none.
+      */
+     private static <S extends ISOMetadata, E, T extends E> T last(final 
Class<T> target, final S source,
+             final Function<S,Collection<E>> getter)
+     {
+         if (source != null) {
+             // If not a sequenced collection, the iteration may be in any 
order.
+             for (final E last : JDK21.reversed(getter.apply(source))) {
+                 if (target.isInstance(last)) {
+                     return target.cast(last);
+                 }
+             }
+         }
+         return null;
+     }
+ 
      /**
       * Writes all pending metadata objects into the {@link DefaultMetadata} 
root class.
       * Then all {@link #identification}, {@link #gridRepresentation}, 
<i>etc.</i> fields

Reply via email to