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

amanin 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 877b832e88 fix(Storage): fix GeoTiff resource finding
877b832e88 is described below

commit 877b832e886d4d4204f74d88c78e3ddf34e286b1
Author: Alexis Manin <[email protected]>
AuthorDate: Wed Jul 27 11:08:59 2022 +0200

    fix(Storage): fix GeoTiff resource finding
    
    Geotiff resource naming recently changed. Resources now provide a head in 
their names. The algorithm for finding resources must now check if user 
provided name contains a head, and if it matches datastore namespace.
---
 .../apache/sis/storage/geotiff/GeoTiffStore.java   | 53 +++++++++++++++++-----
 .../sis/storage/geotiff/SelfConsistencyTest.java   | 28 ++++++++++++
 2 files changed, 70 insertions(+), 11 deletions(-)

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 90c53e20c6..81b0b121cf 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
@@ -25,6 +25,9 @@ import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
 import java.nio.file.StandardOpenOption;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.NullArgumentException;
+import org.apache.sis.util.iso.Names;
 import org.opengis.util.NameSpace;
 import org.opengis.util.NameFactory;
 import org.opengis.util.GenericName;
@@ -473,22 +476,50 @@ public class GeoTiffStore extends DataStore implements 
Aggregate {
      */
     @Override
     public synchronized GridCoverageResource findResource(final String 
sequence) throws DataStoreException {
-        Exception cause;
-        int index;
         try {
-            index = Integer.parseInt(sequence);
-            cause = null;
-        } catch (NumberFormatException e) {
-            index = 0;
-            cause = e;
-        }
-        if (index > 0) try {
-            GridCoverageResource image = reader().getImage(index - 1);
+            final int index = parseIndex(sequence);
+            final GridCoverageResource image = reader().getImage(index - 1);
             if (image != null) return image;
+        } catch (NullArgumentException | IllegalArgumentException e) {
+            throw new 
IllegalNameException(StoreUtilities.resourceNotFound(this, sequence), e);
         } catch (IOException e) {
             throw errorIO(e);
         }
-        throw new IllegalNameException(StoreUtilities.resourceNotFound(this, 
sequence), cause);
+
+        throw new IllegalNameException(StoreUtilities.resourceNotFound(this, 
sequence));
+    }
+
+    /**
+     * Validate input resource name and extract the image index it should 
contain.
+     * We verify that:
+     * <ul>
+     *     <li>Input tip (last name part) is a strictly positive integer 
({@code > 0})</li>
+     *     <li>
+     *         If input provide more than a tip, i.e has more than one name 
part,
+     *         we verify that the part just before the tip matches this 
datastore namespace
+     *         (should be the name of the Geotiff file without its extension).
+     *     </li>
+     * </ul>
+     *
+     * @param resourceName A string representing the name of a resource 
present in this datastore.
+     * @return The index of the Geotiff image matching the requested resource.
+     * @throws IllegalArgumentException If input validation fails.
+     */
+    private int parseIndex(String resourceName) {
+        final GenericName name = Names.parseGenericName(null, null, 
resourceName);
+        final String tip = name.tip().toString();
+        ArgumentChecks.ensureNonEmpty("Resource name tip", tip);
+
+        final int depth = name.depth();
+        if (depth > 1) {
+            final GenericName userNameSpace = name.getParsedNames().get(depth 
- 2);
+            final GenericName storeNameSpace = namespace().name();
+            if (!userNameSpace.equals(storeNameSpace)) throw new 
IllegalArgumentException(
+                    "Input name head does not match this datastore context. 
Expected: " + storeNameSpace + " but received: " + userNameSpace);
+        }
+        final int index = Integer.parseInt(tip);
+        ArgumentChecks.ensureStrictlyPositive("Resource index", index);
+        return index;
     }
 
     /**
diff --git 
a/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/SelfConsistencyTest.java
 
b/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/SelfConsistencyTest.java
index bd9e820924..333402ae8a 100644
--- 
a/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/SelfConsistencyTest.java
+++ 
b/storage/sis-geotiff/src/test/java/org/apache/sis/storage/geotiff/SelfConsistencyTest.java
@@ -16,14 +16,21 @@
  */
 package org.apache.sis.storage.geotiff;
 
+import java.util.List;
 import java.util.Optional;
 import java.nio.file.Path;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.GridCoverageResource;
+import org.apache.sis.storage.IllegalNameException;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.test.OptionalTestData;
 import org.apache.sis.test.storage.CoverageReadConsistency;
 import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Assume;
 import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opengis.util.GenericName;
 
 import static org.junit.Assume.assumeNotNull;
 
@@ -82,4 +89,25 @@ public final strictfp class SelfConsistencyTest extends 
CoverageReadConsistency
     public SelfConsistencyTest() throws DataStoreException {
         super(store.components().iterator().next());
     }
+
+    @Test
+    public void findResourceByName() throws Exception {
+        final List<GridCoverageResource> datasets = store.components();
+        Assume.assumeFalse(datasets.isEmpty());
+        for (GridCoverageResource dataset : datasets) {
+            final GenericName name = dataset.getIdentifier()
+                    .orElseThrow(() -> new AssertionError("A component of the 
GeoTiff datastore is unnamed"));
+            GridCoverageResource foundResource = 
store.findResource(name.toString());
+            Assert.assertEquals(dataset, foundResource);
+            foundResource = store.findResource(name.tip().toString());
+            Assert.assertEquals(dataset, foundResource);
+        }
+
+        try {
+            final GridCoverageResource r = 
store.findResource("a_wrong_namespace:1");
+            Assert.fail("No dataset should be returned when user specify the 
wrong namespace. However, the datastore returned "+ r);
+        } catch (IllegalNameException e) {
+            // Expected behaviour
+        }
+    }
 }

Reply via email to