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.