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

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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 9b98358  When data can not be read because the request does not 
intersect the domain, provide more details about which axis does not intersect.
9b98358 is described below

commit 9b98358600b265dde9996a4d2ab9cb806d2d348b
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Tue Feb 15 20:31:14 2022 +0100

    When data can not be read because the request does not intersect the 
domain, provide more details about which axis does not intersect.
---
 .../org/apache/sis/storage/geotiff/DataCube.java   |  2 +-
 .../apache/sis/storage/geotiff/GeoTiffStore.java   |  4 +-
 .../sis/internal/storage/AbstractGridResource.java | 30 +++++++++++-
 .../sis/internal/storage/AbstractResource.java     | 56 ++++++++++++++++++++++
 .../org/apache/sis/internal/storage/Resources.java |  5 ++
 .../sis/internal/storage/Resources.properties      |  1 +
 .../sis/internal/storage/Resources_fr.properties   |  1 +
 7 files changed, 95 insertions(+), 4 deletions(-)

diff --git 
a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataCube.java
 
b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataCube.java
index bd10a69..f8a510d 100644
--- 
a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataCube.java
+++ 
b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/DataCube.java
@@ -205,7 +205,7 @@ abstract class DataCube extends TiledGridResource 
implements ResourceOnFileSyste
                 coverage = preload(coverage);
             }
         } catch (RuntimeException e) {
-            throw reader.store.errorIO(e);
+            throw canNotRead("read", reader.input.filename, domain, e);
         }
         logReadOperation(reader.store.path, coverage.getGridGeometry(), 
startTime);
         return coverage;
diff --git 
a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
 
b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
index f0fdbc9..0ef534a 100644
--- 
a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
+++ 
b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
@@ -363,10 +363,10 @@ public class GeoTiffStore extends DataStore implements 
Aggregate {
     }
 
     /**
-     * Returns the exception to throw when an I/O or other kind of error 
occurred.
+     * Returns the exception to throw when an I/O error occurred.
      * This method wraps the exception with a {@literal "Can not read 
<filename>"} message.
      */
-    final DataStoreException errorIO(final Exception e) {
+    final DataStoreException errorIO(final IOException e) {
         return new 
DataStoreException(errors().getString(Errors.Keys.CanNotRead_1, 
reader.input.filename), e);
     }
 
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractGridResource.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractGridResource.java
index 6ed632f..3b0754e 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractGridResource.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractGridResource.java
@@ -35,8 +35,10 @@ import org.opengis.util.FactoryException;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreReferencingException;
 import org.apache.sis.storage.GridCoverageResource;
+import org.apache.sis.storage.NoSuchDataException;
 import org.apache.sis.coverage.grid.GridGeometry;
 import org.apache.sis.coverage.grid.GridExtent;
+import org.apache.sis.coverage.grid.DisjointExtentException;
 import org.apache.sis.coverage.SampleDimension;
 import org.apache.sis.storage.event.StoreListeners;
 import org.apache.sis.math.MathFunctions;
@@ -72,7 +74,7 @@ import org.apache.sis.internal.jdk9.JDK9;
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   0.8
  * @module
  */
@@ -468,6 +470,32 @@ public abstract class AbstractGridResource extends 
AbstractResource implements G
     }
 
     /**
+     * Creates an exception for a failure to load data. If the failure may be 
caused by an envelope
+     * outside the domain of validity, that envelope will be inferred from the 
{@code request} argument.
+     *
+     * @param  caller    the method invoking this method, for logging purposes 
only.
+     * @param  filename  name of the file that can not be read.
+     * @param  request   the requested domain, or {@code null} if unspecified.
+     * @param  cause     the cause of the failure, or {@code null} if none.
+     * @return the exception to throw.
+     */
+    protected final DataStoreException canNotRead(final String caller, final 
String filename,
+                                                  final GridGeometry request, 
final Exception cause)
+    {
+        Envelope bounds = null;
+        final boolean isDisjoint = (cause instanceof DisjointExtentException);
+        if (isDisjoint && request != null && 
request.isDefined(GridGeometry.ENVELOPE)) {
+            bounds = request.getEnvelope();
+        }
+        final String message = createDisjointDomainMessage(caller, filename, 
bounds);
+        if (isDisjoint) {
+            return new NoSuchDataException(message, cause);
+        } else {
+            return new DataStoreException(message, cause);
+        }
+    }
+
+    /**
      * If the given exception is caused by a {@link FactoryException} or 
{@link TransformException},
      * returns that cause. Otherwise returns {@code null}. This is a 
convenience method for deciding
      * if an exception should be rethrown as an {@link 
DataStoreReferencingException}.
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
index 8888341..057254d 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractResource.java
@@ -25,6 +25,10 @@ import org.opengis.util.InternationalString;
 import org.opengis.metadata.Metadata;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.operation.TransformException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.geometry.Envelopes;
+import org.apache.sis.referencing.CRS;
 import org.apache.sis.storage.Resource;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.event.StoreEvent;
@@ -32,6 +36,8 @@ import org.apache.sis.storage.event.StoreListener;
 import org.apache.sis.storage.event.StoreListeners;
 import org.apache.sis.storage.event.WarningEvent;
 import org.apache.sis.util.AbstractInternationalString;
+import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.CharSequences;
 
 
@@ -219,6 +225,56 @@ public class AbstractResource extends StoreListeners 
implements Resource {
     }
 
     /**
+     * Creates an error message for a request outside the resource domain.
+     * This is used for creating the message of the exception to be thrown.
+     *
+     * @param  caller    the method invoking this method, for logging purposes 
only.
+     * @param  filename  name of the file that can not be read.
+     * @param  request   the requested domain, or {@code null} if unknown.
+     * @return the message if this method found a dimension that does not 
intersect, or {@code null}.
+     */
+    final String createDisjointDomainMessage(final String caller, final String 
filename, Envelope request) {
+        String message = 
Errors.getResources(getLocale()).getString(Errors.Keys.CanNotRead_1, filename);
+        if (request != null) try {
+            Envelope envelope = getEnvelope().orElse(null);
+            if (envelope != null) {
+                final CoordinateReferenceSystem crs = 
CRS.suggestCommonTarget(null,
+                        envelope.getCoordinateReferenceSystem(),
+                        request.getCoordinateReferenceSystem());
+                request  = Envelopes.transform(request,  crs);
+                envelope = Envelopes.transform(envelope, crs);
+                final int dimension = request.getDimension();
+                StringBuilder buffer = null;
+                for (int i=0; i<dimension; i++) {
+                    final double rmin =  request.getMinimum(i);
+                    final double rmax =  request.getMaximum(i);
+                    final double vmin = envelope.getMinimum(i);
+                    final double vmax = envelope.getMaximum(i);
+                    if (rmax < vmin || rmin > vmax) {
+                        final String axis;
+                        if (crs != null) {
+                            axis = 
IdentifiedObjects.getDisplayName(crs.getCoordinateSystem().getAxis(i), 
getLocale());
+                        } else {
+                            axis = "#" + i;
+                        }
+                        if (buffer == null) {
+                            buffer = new StringBuilder(message);
+                        }
+                        buffer.append(System.lineSeparator()).append(" • 
").append(Resources.forLocale(getLocale())
+                                
.getString(Resources.Keys.RequestOutOfBounds_5, axis, vmin, vmax, rmin, rmax));
+                    }
+                }
+                if (buffer != null) {
+                    message = buffer.toString();
+                }
+            }
+        } catch (DataStoreException | TransformException e) {
+            Logging.ignorableException(getLogger(), getClass(), caller, e);
+        }
+        return message;
+    }
+
+    /**
      * Returns a log filter that removes the stack trace of filtered given log.
      * It can be used as argument in a call to {@link 
StoreListeners#warning(LogRecord, Filter)}
      * if the caller was to trim the stack trace in log files or console 
outputs.
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
index 8fb8ce2..d7d24a0 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java
@@ -297,6 +297,11 @@ public final class Resources extends IndexedResourceBundle 
{
         public static final short ProcessingExecutedOn_1 = 12;
 
         /**
+         * The request [{3} … {4}] is outside the [{1} … {2}] domain for “{0}” 
axis.
+         */
+        public static final short RequestOutOfBounds_5 = 64;
+
+        /**
          * A resource already exists at “{0}”.
          */
         public static final short ResourceAlreadyExists_1 = 48;
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
index f825e40..ec8ebc2 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties
@@ -69,6 +69,7 @@ ProcessingExecutedOn_1            = Processing executed on 
{0}.
 ResourceAlreadyExists_1           = A resource already exists at 
\u201c{0}\u201d.
 ResourceIdentifierCollision_2     = More than one resource have the 
\u201c{1}\u201d identifier in the \u201c{0}\u201d data store.
 ResourceNotFound_2                = No resource found for the \u201c{1}\u201d 
identifier in the \u201c{0}\u201d data store.
+RequestOutOfBounds_5              = The request [{3} \u2026 {4}] is outside 
the [{1} \u2026 {2}] domain for \u201c{0}\u201d axis.
 ShallBeDeclaredBefore_2           = The \u201c{1}\u201d element must be 
declared before \u201c{0}\u201d.
 SharedDirectory_1                 = The \u201c{0}\u201d directory is used more 
than once because of symbolic links.
 StoreIsReadOnly                   = Write operations are not supported.
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
index 9f77b1c..6cbf683 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties
@@ -74,6 +74,7 @@ ProcessingExecutedOn_1            = Traitement 
ex\u00e9cut\u00e9 sur {0}.
 ResourceAlreadyExists_1           = Une ressource existe d\u00e9j\u00e0 \u00e0 
l\u2019emplacement \u00ab\u202f{0}\u202f\u00bb.
 ResourceIdentifierCollision_2     = Plusieurs ressources utilisent 
l\u2019identifiant \u00ab\u202f{1}\u202f\u00bb dans les donn\u00e9es de 
\u00ab\u202f{0}\u202f\u00bb.
 ResourceNotFound_2                = Aucune ressource n\u2019a \u00e9t\u00e9 
trouv\u00e9e pour l\u2019identifiant \u00ab\u202f{1}\u202f\u00bb dans les 
donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb.
+RequestOutOfBounds_5              = La demande [{3} \u2026 {4}] est en dehors 
du domaine [{1} \u2026 {2}] pour l\u2019axe \u00ab\u202f{0}\u202f\u00bb.
 ShallBeDeclaredBefore_2           = L\u2019\u00e9l\u00e9ment 
\u00ab\u202f{1}\u202f\u00bb doit \u00eatre d\u00e9clar\u00e9 avant 
\u00ab\u202f{0}\u202f\u00bb.
 SharedDirectory_1                 = Le r\u00e9pertoire 
\u00ab\u202f{0}\u202f\u00bb est utilis\u00e9 plus d\u2019une fois \u00e0 cause 
des liens symboliques.
 StoreIsReadOnly                   = Les op\u00e9rations d\u2019\u00e9criture 
ne sont pas support\u00e9es.

Reply via email to