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

commit eb79398aaaf7b924d8f337033eb42c85be461241
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Wed Feb 16 11:58:33 2022 +0100

    Unify the way RuntimeException are translated to DataStoreException between 
GeoTIFF and netCDF readers.
---
 .../org/apache/sis/storage/geotiff/DataCube.java   |  2 +-
 .../apache/sis/internal/netcdf/RasterResource.java | 39 +++-----------
 .../sis/internal/storage/AbstractGridResource.java | 62 ++++++++++++----------
 .../sis/internal/storage/AbstractResource.java     | 20 +++----
 .../org/apache/sis/storage/CoverageSubset.java     |  6 ++-
 5 files changed, 59 insertions(+), 70 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 f8a510d..8bcefef 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 canNotRead("read", reader.input.filename, domain, e);
+            throw canNotRead(reader.input.filename, domain, e);
         }
         logReadOperation(reader.store.path, coverage.getGridGeometry(), 
startTime);
         return coverage;
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/RasterResource.java
 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/RasterResource.java
index 4fa11f7..9d615ae 100644
--- 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/RasterResource.java
+++ 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/RasterResource.java
@@ -41,12 +41,9 @@ import org.apache.sis.coverage.grid.GridCoverage;
 import org.apache.sis.coverage.grid.GridGeometry;
 import org.apache.sis.coverage.grid.GridDerivation;
 import org.apache.sis.coverage.grid.GridRoundingMode;
-import org.apache.sis.coverage.grid.DisjointExtentException;
 import org.apache.sis.coverage.IllegalSampleDimensionException;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreContentException;
-import org.apache.sis.storage.DataStoreReferencingException;
-import org.apache.sis.storage.NoSuchDataException;
 import org.apache.sis.storage.Resource;
 import org.apache.sis.math.MathFunctions;
 import org.apache.sis.measure.MeasurementRange;
@@ -622,12 +619,9 @@ public final class RasterResource extends 
AbstractGridResource implements Resour
      * @throws DataStoreException if an error occurred while reading the grid 
coverage data.
      */
     @Override
-    public GridCoverage read(GridGeometry domain, final int... range) throws 
DataStoreException {
+    public GridCoverage read(final GridGeometry domain, final int... range) 
throws DataStoreException {
         final long startTime = System.nanoTime();
         final RangeArgument rangeIndices = 
validateRangeArgument(ranges.length, range);
-        if (domain == null) {
-            domain = gridGeometry;
-        }
         final Variable first = data[bandDimension >= 0 ? 0 : 
rangeIndices.getFirstSpecified()];
         final DataType dataType = first.getDataType();
         if (bandDimension < 0) {
@@ -647,17 +641,18 @@ public final class RasterResource extends 
AbstractGridResource implements Resour
          *   • (bandDimension = 0): one variable containing all bands, with 
bands in the first dimension.
          *   • (bandDimension > 0): one variable containing all bands, with 
bands in the last dimension.
          */
+        final GridGeometry targetDomain;
         final DataBuffer imageBuffer;
         final SampleDimension[] bands = new 
SampleDimension[rangeIndices.getNumBands()];
         int[] bandOffsets = null;                                              
     // By default, all bands start at index 0.
         try {
             final GridDerivation targetGeometry = gridGeometry.derive()
                     .rounding(GridRoundingMode.ENCLOSING)
-                    .subgrid(domain);
+                    .subgrid((domain != null) ? domain : gridGeometry);
             GridExtent areaOfInterest = targetGeometry.getIntersection();      
     // Pixel indices of data to read.
             int[]      subsampling    = targetGeometry.getSubsampling();       
     // Slice to read or subsampling to apply.
             int        numBuffers     = bands.length;                          
     // By default, one variable per band.
-            domain = targetGeometry.build();                                   
     // Adjust user-specified domain to data geometry.
+            targetDomain = targetGeometry.build();                             
     // Adjust user-specified domain to data geometry.
             if (bandDimension >= 0) {
                 areaOfInterest = 
rangeIndices.insertBandDimension(areaOfInterest, bandDimension);
                 subsampling    = rangeIndices.insertSubsampling  (subsampling, 
   bandDimension);
@@ -718,17 +713,8 @@ public final class RasterResource extends 
AbstractGridResource implements Resour
              * Convert NIO Buffer into Java2D DataBuffer. May throw various 
RuntimeException.
              */
             imageBuffer = RasterFactory.wrap(dataType.rasterDataType, 
sampleValues);
-        } catch (IOException e) {
-            throw new DataStoreException(canNotReadFile(), e);
-        } catch (DisjointExtentException e) {
-            throw new NoSuchDataException(canNotReadFile(), e);
-        } catch (RuntimeException e) {                          // Many 
exceptions thrown by RasterFactory.wrap(…).
-            final Exception cause = getReferencingCause(e);
-            if (cause != null) {
-                throw new DataStoreReferencingException(canNotReadFile(), 
cause);
-            } else {
-                throw new DataStoreContentException(canNotReadFile(), e);
-            }
+        } catch (IOException | RuntimeException e) {
+            throw canNotRead(getFilename(), domain, e);
         }
         /*
          * At this point the I/O operation is completed and sample values have 
been stored in a NIO buffer.
@@ -738,23 +724,14 @@ public final class RasterResource extends 
AbstractGridResource implements Resour
             throw new 
DataStoreContentException(Errors.getResources(getLocale()).getString(Errors.Keys.UnsupportedType_1,
 dataType.name()));
         }
         final Variable main = data[visibleBand];
-        final Raster raster = new Raster(domain, 
UnmodifiableArrayList.wrap(bands), imageBuffer,
+        final Raster raster = new Raster(targetDomain, 
UnmodifiableArrayList.wrap(bands), imageBuffer,
                 String.valueOf(identifier), rangeIndices.getPixelStride(), 
bandOffsets, visibleBand,
                 main.decoder.convention().getColors(main));
-        logReadOperation(location, domain, startTime);
+        logReadOperation(location, targetDomain, startTime);
         return raster;
     }
 
     /**
-     * Returns the error message for a file that can not be read.
-     *
-     * @return default error message to use in exceptions.
-     */
-    private String canNotReadFile() {
-        return 
Errors.getResources(getLocale()).getString(Errors.Keys.CanNotRead_1, 
getFilename());
-    }
-
-    /**
      * Returns the name of the netCDF file. This is used for error messages.
      */
     private String getFilename() {
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 3b0754e..a3f95ad 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
@@ -33,14 +33,15 @@ import org.opengis.metadata.spatial.DimensionNameType;
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.util.FactoryException;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.DataStoreContentException;
 import org.apache.sis.storage.DataStoreReferencingException;
-import org.apache.sis.storage.GridCoverageResource;
 import org.apache.sis.storage.NoSuchDataException;
+import org.apache.sis.storage.GridCoverageResource;
+import org.apache.sis.storage.event.StoreListeners;
 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;
 import org.apache.sis.measure.Latitude;
 import org.apache.sis.measure.Longitude;
@@ -471,44 +472,51 @@ 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.
+     * outside the resource domain, 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  filename  some identification (typically a file name) of the 
data 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)
-    {
+    protected final DataStoreException canNotRead(final String filename, final 
GridGeometry request, Throwable cause) {
+        final int DOMAIN = 1, REFERENCING = 2, CONTENT = 3;
+        int type = 0;               // One of above constants, with 0 for 
"none of above".
         Envelope bounds = null;
-        final boolean isDisjoint = (cause instanceof DisjointExtentException);
-        if (isDisjoint && request != null && 
request.isDefined(GridGeometry.ENVELOPE)) {
-            bounds = request.getEnvelope();
+        if (cause instanceof DisjointExtentException) {
+            type = DOMAIN;
+            if (request != null && request.isDefined(GridGeometry.ENVELOPE)) {
+                bounds = request.getEnvelope();
+            }
+        } else if (cause instanceof RuntimeException) {
+            Throwable c = cause.getCause();
+            if (isReferencing(c)) {
+                type = REFERENCING;
+                cause = c;
+            } else if (cause instanceof ArithmeticException || cause 
instanceof RasterFormatException) {
+                type = CONTENT;
+            }
+        } else if (isReferencing(cause)) {
+            type = REFERENCING;
         }
-        final String message = createDisjointDomainMessage(caller, filename, 
bounds);
-        if (isDisjoint) {
-            return new NoSuchDataException(message, cause);
-        } else {
-            return new DataStoreException(message, cause);
+        final String message = createExceptionMessage(filename, bounds);
+        switch (type) {
+            case DOMAIN:      return new NoSuchDataException(message, cause);
+            case REFERENCING: return new 
DataStoreReferencingException(message, cause);
+            case CONTENT:     return new DataStoreContentException(message, 
cause);
+            default:          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}.
+     * Returns {@code true} if the given exception is {@link FactoryException} 
or {@link TransformException}.
+     * This is for deciding if an exception should be rethrown as an {@link 
DataStoreReferencingException}.
      *
-     * @param  e  the exception for which to inspect the cause.
-     * @return the cause if it is a referencing problem, or {@code null} 
otherwise.
+     * @param  cause  the exception to verify.
+     * @return whether the given exception is {@link FactoryException} or 
{@link TransformException}.
      */
-    protected static Exception getReferencingCause(final RuntimeException e) {
-        final Throwable cause = e.getCause();
-        if (cause instanceof FactoryException || cause instanceof 
TransformException) {
-            return (Exception) cause;
-        }
-        return null;
+    private static boolean isReferencing(final Throwable cause) {
+        return (cause instanceof FactoryException || cause instanceof 
TransformException);
     }
 
     /**
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 057254d..71e8357 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
@@ -225,15 +225,15 @@ 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.
+     * Creates an exception message for a resource that can not be read.
+     * If the error is potentially created by a request out of bounds,
+     * this method tries to build a message with the problematic coordinates.
      *
-     * @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}.
+     * @param  filename  some identification (typically a file name) of the 
data that can not be read.
+     * @param  request   the requested domain, or {@code null} if the problem 
is not a request out of bounds.
+     * @return the message to provide in an exception.
      */
-    final String createDisjointDomainMessage(final String caller, final String 
filename, Envelope request) {
+    final String createExceptionMessage(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);
@@ -254,8 +254,10 @@ public class AbstractResource extends StoreListeners 
implements Resource {
                         final String axis;
                         if (crs != null) {
                             axis = 
IdentifiedObjects.getDisplayName(crs.getCoordinateSystem().getAxis(i), 
getLocale());
+                        } else if (i < 3) {
+                            axis = String.valueOf((char) ('x' + i));
                         } else {
-                            axis = "#" + i;
+                            axis = "#" + (i+1);
                         }
                         if (buffer == null) {
                             buffer = new StringBuilder(message);
@@ -269,7 +271,7 @@ public class AbstractResource extends StoreListeners 
implements Resource {
                 }
             }
         } catch (DataStoreException | TransformException e) {
-            Logging.ignorableException(getLogger(), getClass(), caller, e);
+            Logging.ignorableException(getLogger(), AbstractResource.class, 
"createExceptionMessage", e);
         }
         return message;
     }
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/storage/CoverageSubset.java 
b/storage/sis-storage/src/main/java/org/apache/sis/storage/CoverageSubset.java
index bb5d96e..4c6aba3 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/storage/CoverageSubset.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/storage/CoverageSubset.java
@@ -18,6 +18,8 @@ package org.apache.sis.storage;
 
 import java.util.Arrays;
 import java.util.List;
+import org.opengis.util.FactoryException;
+import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.coverage.SampleDimension;
 import org.apache.sis.coverage.grid.GridCoverage;
 import org.apache.sis.coverage.grid.GridGeometry;
@@ -115,8 +117,8 @@ final class CoverageSubset extends AbstractGridResource {
         } catch (IllegalArgumentException | IllegalStateException e) {
             final String msg = Resources.forLocale(getLocale())
                     .getString(Resources.Keys.CanNotIntersectDataWithQuery_1, 
getSourceName());
-            final Exception cause = getReferencingCause(e);
-            if (cause != null) {
+            final Throwable cause = e.getCause();
+            if (cause instanceof FactoryException || cause instanceof 
TransformException) {
                 throw new DataStoreReferencingException(msg, cause);
             } else if (e instanceof DisjointExtentException) {
                 throw new NoSuchDataException(msg, e);

Reply via email to