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 0704b92b5ebd2f50365b8b32a7eaf2ac2838e70b
Merge: 61ff831a8e ece63c46f5
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Tue Apr 1 18:20:10 2025 +0200

    Merge branch 'geoapi-4.0' into geoapi-3.1.
    Contains bug fixes in SQLStore.

 .../org/apache/sis/feature/AbstractOperation.java  |  18 +
 .../org/apache/sis/feature/EnvelopeOperation.java  |   3 +-
 .../apache/sis/feature/ExpressionOperation.java    |   3 +-
 .../sis/feature/GroupAsPolylineOperation.java      |   3 +-
 .../main/org/apache/sis/feature/LinkOperation.java |   3 +-
 .../apache/sis/feature/StringJoinOperation.java    |   3 +-
 .../org/apache/sis/feature/internal/Resources.java |   5 +
 .../sis/feature/internal/Resources.properties      |   1 +
 .../sis/feature/internal/Resources_fr.properties   |   1 +
 .../sis/feature/privy/AttributeConvention.java     |   6 +
 .../apache/sis/feature/privy/FeatureUtilities.java |  98 ------
 .../apache/sis/filter/BinaryGeometryFilter.java    |   2 +-
 .../main/org/apache/sis/filter/LeafExpression.java |   2 +-
 .../main/org/apache/sis/filter/internal/Node.java  |  24 +-
 .../sis/filter/privy/ListingPropertyVisitor.java   | 137 ++++++++
 .../org/apache/sis/filter/privy/WarningEvent.java  | 128 +++++++
 .../geometry/wrapper/jts/GeometryTransform.java    |  10 +-
 .../org/apache/sis/geometry/wrapper/jts/JTS.java   |  20 +-
 .../main/org/apache/sis/image/ImageProcessor.java  |   4 +-
 .../sis/geometry/wrapper/esri/FactoryTest.java     |   8 +-
 .../apache/sis/geometry/wrapper/jts/JTSTest.java   |   2 +-
 .../org/apache/sis/metadata/sql/privy/Dialect.java |  52 ++-
 .../apache/sis/metadata/sql/privy/SQLBuilder.java  | 116 +++++--
 .../sis/metadata/sql/privy/SQLUtilities.java       |  43 ++-
 .../org/apache/sis/metadata/sql/privy/Syntax.java  |  70 +++-
 .../org/apache/sis/temporal/LenientDateFormat.java |   6 +-
 .../main/org/apache/sis/temporal/TimeMethods.java  |   6 +-
 .../sis/metadata/sql/privy/SQLBuilderTest.java     |  97 ++++++
 .../sis/metadata/sql/privy/SQLUtilitiesTest.java   |  13 +-
 .../main/org/apache/sis/openoffice/CalcAddins.java |   2 +-
 .../coverage/MultiResolutionCoverageLoader.java    |   2 +-
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |  21 +-
 .../sis/referencing/operation/matrix/Matrices.java |  62 +++-
 .../referencing/operation/matrix/MatricesTest.java |  16 +
 .../apache/sis/storage/landsat/MetadataReader.java |  16 +-
 .../geotiff/reader/GridGeometryBuilder.java        |  13 +-
 .../sis/storage/geotiff/writer/GeoEncoder.java     |  85 ++++-
 .../sis/storage/netcdf/base/GridMapping.java       |   2 +-
 .../sis/storage/netcdf/ucar/DecoderWrapper.java    |   3 +-
 .../main/module-info.java                          |   1 +
 .../org/apache/sis/storage/sql/DataAccess.java     |   2 +
 .../main/org/apache/sis/storage/sql/SQLStore.java  |  43 ++-
 .../org/apache/sis/storage/sql/duckdb/DuckDB.java  |  88 +++++
 .../{postgis => duckdb}/ExtendedClauseWriter.java  |  14 +-
 .../sis/storage/sql/duckdb/package-info.java       |  60 ++++
 .../apache/sis/storage/sql/feature/Analyzer.java   | 112 ++++--
 .../org/apache/sis/storage/sql/feature/Column.java |  67 +++-
 .../apache/sis/storage/sql/feature/Database.java   | 191 ++++++++--
 .../sis/storage/sql/feature/FeatureAdapter.java    |   8 +-
 .../sis/storage/sql/feature/FeatureAnalyzer.java   |  12 +-
 .../sis/storage/sql/feature/FeatureIterator.java   |  87 ++++-
 .../sis/storage/sql/feature/FeatureStream.java     |  91 ++++-
 .../sis/storage/sql/feature/GeometryEncoding.java  |  25 +-
 .../sis/storage/sql/feature/GeometryGetter.java    | 103 ++++--
 .../sis/storage/sql/feature/InfoStatements.java    | 104 ++++--
 .../sis/storage/sql/feature/QueryAnalyzer.java     |   4 +-
 .../apache/sis/storage/sql/feature/Relation.java   |  48 ++-
 .../apache/sis/storage/sql/feature/Resources.java  |  15 +
 .../sis/storage/sql/feature/Resources.properties   |   3 +
 .../storage/sql/feature/Resources_fr.properties    |   5 +-
 .../sis/storage/sql/feature/SelectionClause.java   | 250 +++++++++++++-
 .../storage/sql/feature/SelectionClauseWriter.java |  38 +-
 .../sis/storage/sql/feature/SpatialSchema.java     |  73 +++-
 .../org/apache/sis/storage/sql/feature/Table.java  | 148 ++++++--
 .../sis/storage/sql/feature/TableAnalyzer.java     |  61 ++--
 .../sis/storage/sql/feature/TableReference.java    |   2 +-
 .../storage/sql/postgis/ExtendedClauseWriter.java  |   5 +
 .../sis/storage/sql/postgis/ExtendedInfo.java      |  32 +-
 .../sis/storage/sql/postgis/ExtentEstimator.java   |   2 +-
 .../apache/sis/storage/sql/postgis/Postgres.java   |  22 +-
 .../org/apache/sis/storage/sql/SQLStoreTest.java   |  22 +-
 .../storage/sql/feature/GeometryGetterTest.java    |   3 +-
 .../sis/storage/sql/postgis/PostgresTest.java      | 123 ++++++-
 .../sis/storage/sql/postgis/RasterReaderTest.java  |   5 +-
 .../sis/storage/sql/postgis/RasterWriterTest.java  |   4 +-
 .../sis/storage/sql/postgis/SpatialFeatures.sql    |   8 +
 .../apache/sis/io/stream/InternalOptionKey.java    |   2 +-
 .../main/org/apache/sis/storage/FeatureQuery.java  | 237 +++++--------
 .../main/org/apache/sis/storage/FeatureSubset.java |  37 +-
 .../org/apache/sis/storage/StorageConnector.java   |  28 +-
 .../apache/sis/storage/base/FeatureProjection.java | 383 +++++++++++++++++++++
 .../apache/sis/storage/base/MetadataBuilder.java   | 113 ++++--
 .../main/org/apache/sis/storage/csv/Store.java     |   2 +-
 .../org/apache/sis/storage/image/FormatFilter.java |   4 +-
 .../org/apache/sis/storage/image/FormatFinder.java |  67 +---
 .../apache/sis/storage/image/MultiImageStore.java  |   2 +-
 .../apache/sis/storage/image/SingleImageStore.java |   2 +-
 .../apache/sis/storage/image/WorldFileStore.java   |  31 +-
 .../apache/sis/storage/image/WritableStore.java    |   2 +-
 .../org/apache/sis/storage/wkt/StoreFormat.java    |   2 +-
 .../org/apache/sis/storage/FeatureQueryTest.java   |  24 ++
 .../sis/storage/image/SelfConsistencyTest.java     |   2 +-
 .../sis/storage/image/WorldFileStoreTest.java      |  13 +-
 .../services/org.apache.sis.util.ObjectConverter   |  11 +
 .../org/apache/sis/converter/StringConverter.java  |   2 +-
 .../main/org/apache/sis/setup/GeometryLibrary.java |  37 +-
 .../org/apache/sis/util/collection/WeakEntry.java  |   2 +-
 .../apache/sis/util/collection/WeakHashSet.java    |   1 +
 .../org/apache/sis/util/privy/CollectionsExt.java  |  18 +
 .../org/apache/sis/util/resources/Vocabulary.java  |   5 +
 .../sis/util/resources/Vocabulary.properties       |   1 +
 .../sis/util/resources/Vocabulary_fr.properties    |   1 +
 .../apache/sis/storage/geoheif/GeoHeifStore.java   |   2 +-
 .../storage/shapefile/ListingPropertyVisitor.java  |  82 -----
 .../sis/storage/shapefile/ShapefileStore.java      |   7 +-
 .../apache/sis/storage/shapefile/dbf/DBFField.java |  11 +-
 .../apache/sis/gui/coverage/CoverageCanvas.java    |  68 +++-
 .../gui/coverage/MultiResolutionImageLoader.java   |   2 +-
 .../main/org/apache/sis/gui/map/MapCanvas.java     |   6 +-
 .../main/org/apache/sis/gui/map/package-info.java  |   2 +-
 .../org/apache/sis/storage/gdal/FieldAccessor.java |   3 +-
 .../org/apache/sis/storage/gdal/GDALStore.java     |   4 +-
 112 files changed, 3197 insertions(+), 1006 deletions(-)

diff --cc 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java
index fff5aee952,9da2a6ded1..473d878140
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/GeodeticObjectParser.java
@@@ -2159,8 -2155,12 +2158,12 @@@ class GeodeticObjectParser extends Math
              cs = parseCoordinateSystem(element, WKTKeywords.Cartesian, 2, 
isWKT1, csUnit, geoCRS.getDatum());
              final Map<String,?> properties = parseMetadataAndClose(element, 
name, conversion);
              if (cs instanceof CartesianCS) {
+                 /*
+                  * TODO: if the CartesianCS is three-dimensional, we need to 
ensure that the base CRS is also
+                  * three-dimensional. We could do that by parsing the CS 
before to invoke `parseGeodeticCRS`.
+                  */
                  final CRSFactory crsFactory = factories.getCRSFactory();
 -                return crsFactory.createProjectedCRS(properties, 
(GeodeticCRS) geoCRS, conversion, (CartesianCS) cs);
 +                return crsFactory.createProjectedCRS(properties, 
(GeographicCRS) geoCRS, conversion, (CartesianCS) cs);
              }
          } catch (FactoryException exception) {
              throw element.parseFailed(exception);
diff --cc 
endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SelectionClause.java
index 819d204b07,aa0d7a92ab..72e55881ba
--- 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SelectionClause.java
+++ 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/feature/SelectionClause.java
@@@ -170,4 -308,90 +308,90 @@@ public final class SelectionClause exte
          }
          return true;
      }
+ 
+     /**
+      * Returns whether an error occurred while writing the <abbr>SQL</abbr> 
statement.
+      * If this method returns {@code true}, then the caller should truncate 
the SQL to
+      * the last length which was known to be valid and fallback on Java code 
for the rest.
+      */
+     final boolean isInvalid() {
+         return isInvalid;
+     }
+ 
+     /**
+      * Declares the SQL as invalid. It does not means that the whole SQL 
needs to be discarded.
+      * The SQL may be truncated to the last point where it was considered 
valid.
+      */
+     final void invalidate() {
+         isInvalid = true;
+     }
+ 
+     /**
+      * Returns the localized resources for warnings and error messages.
+      */
+     private Resources resources() {
+         return Resources.forLocale(table.database.listeners.getLocale());
+     }
+ 
+     /**
+      * Sets the logger, class and method names of the given record, then logs 
it.
+      * This method declares {@link FeatureSet#features(boolean)} as the 
public source of the log.
+      *
+      * @param  record  the record to configure and log.
+      */
+     private void log(final LogRecord record) {
+         record.setSourceClassName(FeatureSet.class.getName());
+         record.setSourceMethodName("features");
+         record.setLoggerName(Modules.SQL);
+         table.database.listeners.warning(record);
+     }
+ 
+     /**
+      * Invoked when a warning occurred during operations on filters or 
expressions.
+      *
+      * @param  event  the warning.
+      */
+     @Override
+     public void accept(final WarningEvent event) {
+         final LogRecord record = resources().getLogRecord(
+                 Level.WARNING,
+                 Resources.Keys.IncompatibleLiteralCRS_2,
 -                
event.getOperatorType().flatMap(CodeList::identifier).orElse("?"),
++                event.getOperatorType().map(CodeList::identifier).orElse("?"),
+                 
event.getParameter(ValueReference.class).map(ValueReference<?,?>::getXPath).orElse("?"));
+         record.setThrown(event.exception);
+         log(record);
+     }
+ 
+     /**
+      * Returns the <abbr>SQL</abbr> fragment built by this {@code 
SelectionClause}.
+      * This method completes the information that we deferred until a 
connection is established.
+      *
+      * @param  spatialInformation  a cache of statements for fetching spatial 
information, or {@code null}.
+      * @return the <abbr>SQL</abbr> fragment, or {@code null} if there is no 
{@code WHERE} clause to add.
+      * @throws Exception if an SQL error, parsing error or other error 
occurred.
+      */
+     final String query(final Connection connection, InfoStatements 
spatialInformation) throws Exception {
+         if (isEmpty()) {
+             return null;
+         }
+         boolean close = false;
+         for (int i = parameters.size(); --i >= 0;) {
+             if (spatialInformation == null) {
+                 spatialInformation = 
table.database.createInfoStatements(connection);
+                 close = true;
+             }
+             final var entry = parameters.get(i);
+             final int index = entry.getKey();
+             final int srid  = spatialInformation.findSRID(entry.getValue());
+             buffer.replace(index, index + 1, Integer.toString(srid));
+         }
+         if (close) {
+             /*
+              * We could put this in a `finally` block, but this method is 
already invoked
+              * in a context where the caller will close the connection in 
case of failure.
+              */
+             spatialInformation.close();
+         }
+         return buffer.toString();
+     }
  }
diff --cc 
endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/MetadataBuilder.java
index ef6d83a2bb,41a6938b8d..2d26e160c4
--- 
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
@@@ -1416,8 -1436,7 +1435,9 @@@ public class MetadataBuilder 
      public final void addOtherCitationDetails(final CharSequence details) {
          final InternationalString i18n = trim(details);
          if (i18n != null) {
 -            addIfNotPresent(citation().getOtherCitationDetails(), i18n);
++            @SuppressWarnings("LocalVariableHidesMemberVariable")
 +            final DefaultCitation citation = citation();
 +            
citation.setOtherCitationDetails(append(citation.getOtherCitationDetails(), 
i18n));
          }
      }
  
@@@ -3105,11 -3134,31 +3137,32 @@@
      }
  
      /**
-      * Adds a note about which reader is used. This method should not be 
invoked before
-      * the {@linkplain #addFormatName format name} has been set. Storage 
location is:
+      * Adds other information about the format. Apache SIS currently uses this
+      * location for specifying which software was used for reading the data.
+      * Storage location is:
+      *
+      * <ul>
+      *   <li>{@code 
metadata/identificationInfo/resourceFormat/formatSpecificationCitation/otherCitationDetails}</li>
+      * </ul>
+      *
+      * @param  details  other details about the format, or {@code null} for 
no-operation.
+      *
+      * @see #addOtherCitationDetails(CharSequence)
+      */
+     public final void addFormatCitationDetails(final CharSequence details) {
+         final InternationalString i18n = trim(details);
+         if (i18n != null) {
 -            addIfNotPresent(getFormatCitation().getOtherCitationDetails(), 
i18n);
++            final DefaultCitation c = getFormatCitation();
++            c.setOtherCitationDetails(append(c.getOtherCitationDetails(), 
i18n));
+         }
+     }
+ 
+     /**
+      * Adds a note about which reader is used. Apache SIS currently stores 
this information as other format
+      * citation details, but this location may change in a SIS future version 
if we find a better location.
+      * Storage location is as below, wrapped in a "Read by {0} version {1}" 
text:
       *
       * <ul>
-      *   <li>{@code 
metadata/identificationInfo/resourceFormat/formatSpecificationCitation/identifier}</li>
       *   <li>{@code 
metadata/identificationInfo/resourceFormat/formatSpecificationCitation/otherCitationDetails}</li>
       * </ul>
       *

Reply via email to