You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2022/12/17 10:46:38 UTC

[sis] branch 1.3-RC updated: Cherry-pick bug fixes for release candidate 2. Include a fix for a regression reported on the mailing list.

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

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


The following commit(s) were added to refs/heads/1.3-RC by this push:
     new 0d963477aa Cherry-pick bug fixes for release candidate 2. Include a fix for a regression reported on the mailing list.
0d963477aa is described below

commit 0d963477aa3d6b8f414ef3647b9ab748feb8d04a
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Sat Dec 17 11:40:05 2022 +0100

    Cherry-pick bug fixes for release candidate 2.
    Include a fix for a regression reported on the mailing list.
    
    https://lists.apache.org/thread/g206zssnxltdc88x2ovjg6zpdmtyb8qc
---
 .../apache/sis/cloud/aws/s3/CachedByteChannel.java |  4 +--
 .../java/org/apache/sis/referencing/CRSTest.java   | 21 ++++++++++++++-
 .../DefaultCoordinateOperationFactoryTest.java     | 19 ++++++++++++-
 .../sis/util/resources/IndexedResourceBundle.java  |  3 ++-
 .../sis/internal/storage/io/IOUtilities.java       | 13 +++++----
 .../sis/internal/storage/io/package-info.java      |  2 +-
 .../sis/storage/aggregate/GridSliceLocator.java    |  4 ++-
 .../sis/storage/aggregate/GroupAggregate.java      | 20 ++++++++++++++
 .../sis/storage/aggregate/GroupByTransform.java    | 17 +++++++-----
 .../sis/internal/storage/io/IOUtilitiesTest.java   |  4 ++-
 .../storage/aggregate/CoverageAggregatorTest.java} | 31 ++++++++++++++++------
 .../apache/sis/test/suite/StorageTestSuite.java    |  3 ++-
 12 files changed, 113 insertions(+), 28 deletions(-)

diff --git a/cloud/sis-cloud-aws/src/main/java/org/apache/sis/cloud/aws/s3/CachedByteChannel.java b/cloud/sis-cloud-aws/src/main/java/org/apache/sis/cloud/aws/s3/CachedByteChannel.java
index 8ca227467a..b89801a694 100644
--- a/cloud/sis-cloud-aws/src/main/java/org/apache/sis/cloud/aws/s3/CachedByteChannel.java
+++ b/cloud/sis-cloud-aws/src/main/java/org/apache/sis/cloud/aws/s3/CachedByteChannel.java
@@ -268,13 +268,13 @@ final class CachedByteChannel implements SeekableByteChannel {
             file.close();
         } catch (Throwable e) {
             try {
-                input.close();
+                input.abort();
             } catch (Throwable s) {
                 e.addSuppressed(s);
             }
             throw e;
         }
-        input.close();
+        input.abort();
     }
 
     /**
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java b/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java
index 9e01a2c727..0ddcfc19c4 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java
@@ -20,8 +20,8 @@ import java.util.Map;
 import java.util.HashMap;
 import java.util.Arrays;
 import java.util.List;
-import org.apache.sis.internal.system.Loggers;
 import org.opengis.util.FactoryException;
+import org.opengis.util.NoSuchIdentifierException;
 import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.crs.GeographicCRS;
@@ -33,6 +33,7 @@ import org.apache.sis.referencing.crs.DefaultGeographicCRS;
 import org.apache.sis.referencing.crs.DefaultProjectedCRS;
 import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
 import org.apache.sis.metadata.iso.extent.DefaultExtent;
+import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.Utilities;
 
@@ -218,6 +219,24 @@ public final strictfp class CRSTest extends TestCase {
         assertEquals("GCS WGS 1984", crs.getName().getCode());
     }
 
+    /**
+     * Verifies that parsing a WKT with an unknown operation method throws {@link NoSuchIdentifierException}.
+     *
+     * @throws FactoryException if an unexpected error occurred.
+     */
+    @Test
+    public void testFromInvalidWKT() throws FactoryException {
+        try {
+            CRS.fromWKT("PROJCS[\"Foo\", GEOGCS[\"Foo\", DATUM[\"Foo\", SPHEROID[\"Sphere\", 6371000, 0]], " +
+                        "UNIT[\"Degree\", 0.0174532925199433]], PROJECTION[\"I do not exist\"], " +
+                        "UNIT[\"MEtre\", 1]]");
+            fail("Expected NoSuchIdentifierException");
+        } catch (NoSuchIdentifierException e) {
+            final String message = e.getMessage();
+            assertTrue(message, message.contains("I do not exist"));
+        }
+    }
+
     /**
      * Tests {@link CRS#suggestCommonTarget(GeographicBoundingBox, CoordinateReferenceSystem...)}.
      *
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
index 840b6e2e87..6b1a6b19af 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.operation;
 import java.util.List;
 import java.text.ParseException;
 import org.opengis.util.FactoryException;
+import org.opengis.util.NoSuchIdentifierException;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.ConcatenatedOperation;
@@ -56,7 +57,7 @@ import static org.apache.sis.test.ReferencingAssert.*;
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.3
  * @since   0.7
  * @module
  */
@@ -352,4 +353,20 @@ public final strictfp class DefaultCoordinateOperationFactoryTest extends MathTr
                         CoordinateOperationFinderTest.expectedAGD66(false));
         validate();
     }
+
+    /**
+     * Verifies that requesting an unknown method throws {@link NoSuchIdentifierException}.
+     *
+     * @throws FactoryException if an unexpected error occurred.
+     */
+    @Test
+    public void testUnknownMethod() throws FactoryException {
+        try {
+            factory.getOperationMethod("I do not exist");
+            fail("Expected NoSuchIdentifierException");
+        } catch (NoSuchIdentifierException e) {
+            final String message = e.getMessage();
+            assertTrue(message, message.contains("I do not exist"));
+        }
+    }
 }
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java b/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
index 2acad2a709..84831e6820 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/IndexedResourceBundle.java
@@ -21,6 +21,7 @@ import java.io.BufferedInputStream;
 import java.io.DataInputStream;
 import java.io.IOException;
 import java.text.MessageFormat;
+import java.util.Arrays;
 import java.util.Map;
 import java.util.Enumeration;
 import java.util.Locale;
@@ -443,7 +444,7 @@ public class IndexedResourceBundle extends ResourceBundle implements Localized {
              */
             if (replacement != element) {
                 if (array == arguments) {
-                    array = array.clone();                  // Protect the user-provided array from change.
+                    array = Arrays.copyOf(array, array.length, Object[].class);
                 }
                 array[i] = replacement;
             }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/IOUtilities.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/IOUtilities.java
index 3df8039a40..fba5a3cd8d 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/IOUtilities.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/IOUtilities.java
@@ -59,7 +59,7 @@ import org.apache.sis.internal.storage.Resources;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.3
  * @module
  */
@@ -95,6 +95,7 @@ public final class IOUtilities extends Static {
      * instance. If the given argument is specialized type like {@code Path} or {@code File}, then this method uses
      * dedicated API like {@link Path#getFileName()}. Otherwise this method gets a string representation of the path
      * and returns the part after the last {@code '/'} or platform-dependent name separator character, if any.
+     * The returned string may be empty if the given path is empty or is the root directory.
      *
      * @param  path  the path as an instance of one of the above-cited types, or {@code null}.
      * @return the filename in the given path, or {@code null} if the given object is null or of unknown type.
@@ -149,13 +150,15 @@ public final class IOUtilities extends Static {
              */
             end = name.length();
             do {
-                fromIndex = name.lastIndexOf('/', --end) + 1;
+                if (--end < 0) return "";               // `end` is temporarily inclusive in this loop.
+                fromIndex = name.lastIndexOf('/', end);
                 if (separator != '/') {
                     // Search for platform-specific character only if the object is neither a URL or a URI.
-                    fromIndex = Math.max(fromIndex, CharSequences.lastIndexOf(name, separator, fromIndex, end+1) + 1);
+                    fromIndex = Math.max(fromIndex, name.lastIndexOf(separator, end));
                 }
-            } while (fromIndex > end);
-            end++;
+            } while (fromIndex == end);                 // Continue if '/' is the last character.
+            fromIndex++;                                // Character after the '/' separator.
+            end++;                                      // Make exclusive.
         }
         if (extension) {
             fromIndex = CharSequences.lastIndexOf(name, '.', fromIndex, end) + 1;
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/package-info.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/package-info.java
index de0e699a69..c3f8ad2eae 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/package-info.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/package-info.java
@@ -24,7 +24,7 @@
  * may change in incompatible ways in any future version without notice.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  * @module
  */
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GridSliceLocator.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GridSliceLocator.java
index b0c121c62e..3d59d252ef 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GridSliceLocator.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GridSliceLocator.java
@@ -77,7 +77,9 @@ final class GridSliceLocator {
     /**
      * Creates a new locator for slices at given coordinates.
      *
-     * @param searchDimension  the dimension on which the searches are done.
+     * @param slices           descriptions of the grid resources to use as slices in a multi-dimensional cube.
+     * @param searchDimension  the dimension on which the searches for grid slices are done.
+     * @param resources        an array of initially null elements where to store the resources.
      */
     GridSliceLocator(final List<GridSlice> slices, final int searchDimension, final GridCoverageResource[] resources) {
         this.searchDimension = searchDimension;
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupAggregate.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupAggregate.java
index 3e1997878b..1f52eb6890 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupAggregate.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupAggregate.java
@@ -114,6 +114,26 @@ final class GroupAggregate extends AbstractResource implements Aggregate, Aggreg
         this.name = name;
     }
 
+    /**
+     * Creates a new aggregate with the specified components, which will receive no further processing.
+     * This is invoked when the caller has not been able to group the slices in a multi-dimensional cube.
+     * The result stay an aggregate of heterogynous resources.
+     *
+     * @param listeners         listeners of the parent resource, or {@code null} if none.
+     * @param name              name of this aggregate, or {@code null} if none.
+     * @param components        the resources to uses as components of this aggregate.
+     * @param sampleDimensions  sample dimensions common to all grid coverage resources.
+     */
+    GroupAggregate(final StoreListeners listeners, final String name, final GridCoverageResource[] components,
+                   final List<SampleDimension> sampleDimensions)
+    {
+        super(listeners, true);
+        this.name = name;
+        this.components = components;
+        this.componentsAreLeaves = true;
+        this.sampleDimensions = sampleDimensions;
+    }
+
     /**
      * Creates a new resource with the same data than given resource but a different merge strategy.
      *
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupByTransform.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupByTransform.java
index 855d4c8878..346b7ff4b4 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupByTransform.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/aggregate/GroupByTransform.java
@@ -24,6 +24,7 @@ import java.text.FieldPosition;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.MathTransform;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
+import org.apache.sis.storage.Resource;
 import org.apache.sis.storage.GridCoverageResource;
 import org.apache.sis.storage.event.StoreListeners;
 import org.apache.sis.coverage.grid.GridGeometry;
@@ -148,16 +149,20 @@ final class GroupByTransform extends Group<GridSlice> {
      * @param  sampleDimensions  the sample dimensions of the resource to build.
      * @return the concatenated resource.
      */
-    final GridCoverageResource createResource(final StoreListeners parentListeners, final List<SampleDimension> ranges) {
+    final Resource createResource(final StoreListeners parentListeners, final List<SampleDimension> ranges) {
         final int n = members.size();
         if (n == 1) {
             return members.get(0).resource;
         }
+        final GridCoverageResource[] slices = new GridCoverageResource[n];
+        final String name = getName(parentListeners);
         final int[] dimensions = findConcatenatedDimensions();
-        final GridCoverageResource[] slices  = new GridCoverageResource[n];
-        final GridSliceLocator       locator = new GridSliceLocator(members, dimensions[0], slices);
-        final GridGeometry           domain  = locator.union(geometry, members, GridSlice::getGridExtent);
-        return new ConcatenatedGridResource(getName(parentListeners), parentListeners,
-                                            domain, ranges, slices, locator, strategy);
+        if (dimensions.length == 0) {
+            for (int i=0; i<n; i++) slices[i] = members.get(i).resource;
+            return new GroupAggregate(parentListeners, name, slices, ranges);
+        }
+        final GridSliceLocator locator = new GridSliceLocator(members, dimensions[0], slices);
+        final GridGeometry     domain  = locator.union(geometry, members, GridSlice::getGridExtent);
+        return new ConcatenatedGridResource(name, parentListeners, domain, ranges, slices, locator, strategy);
     }
 }
diff --git a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/io/IOUtilitiesTest.java b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/io/IOUtilitiesTest.java
index 4c2483388c..af7c998a7b 100644
--- a/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/io/IOUtilitiesTest.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/io/IOUtilitiesTest.java
@@ -35,7 +35,7 @@ import static org.junit.Assert.*;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.2
+ * @version 1.4
  * @since   0.3
  * @module
  */
@@ -53,6 +53,8 @@ public final strictfp class IOUtilitiesTest extends TestCase {
         assertEquals("Map.png", IOUtilities.filename(new URI ("file:/Users/name/Map.png")));
         assertEquals("Map.png", IOUtilities.filename(new URL ("file:/Users/name/Map.png")));
         assertEquals("name",    IOUtilities.filename(new URI ("file:/Users/name/")));
+        assertEquals("",        IOUtilities.filename("/"));
+        assertEquals("",        IOUtilities.filename(""));
         assertNull(IOUtilities.filename(Boolean.FALSE));
         assertNull(IOUtilities.filename(null));
     }
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/package-info.java b/storage/sis-storage/src/test/java/org/apache/sis/storage/aggregate/CoverageAggregatorTest.java
similarity index 56%
copy from storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/package-info.java
copy to storage/sis-storage/src/test/java/org/apache/sis/storage/aggregate/CoverageAggregatorTest.java
index de0e699a69..60aac56a41 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/io/package-info.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/storage/aggregate/CoverageAggregatorTest.java
@@ -14,18 +14,33 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.sis.storage.aggregate;
+
+import org.apache.sis.storage.Aggregate;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
 
 /**
- * Utility classes for the implementation of SIS storage classes.
- *
- * <STRONG>Do not use!</STRONG>
- *
- * This package is for internal use by SIS only. Classes in this package
- * may change in incompatible ways in any future version without notice.
+ * Tests {@link CoverageAggregator}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 1.3
- * @since   0.3
+ * @since   1.3
  * @module
  */
-package org.apache.sis.internal.storage.io;
+public final strictfp class CoverageAggregatorTest extends TestCase {
+    /**
+     * Tests an empty aggregator.
+     *
+     * @throws DataStoreException if an error occurred.
+     */
+    @Test
+    public void testEmpty() throws DataStoreException {
+        final CoverageAggregator aggregator = new CoverageAggregator(null);
+        assertTrue(((Aggregate) aggregator.build()).components().isEmpty());
+    }
+}
diff --git a/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java b/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
index ad3ab0fa51..a669c14342 100644
--- a/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
+++ b/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
@@ -26,7 +26,7 @@ import org.junit.BeforeClass;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Alexis Manin (Geomatys)
- * @version 1.2
+ * @version 1.3
  * @since   0.3
  * @module
  */
@@ -67,6 +67,7 @@ import org.junit.BeforeClass;
     org.apache.sis.internal.storage.folder.StoreTest.class,
     org.apache.sis.storage.aggregate.JoinFeatureSetTest.class,
     org.apache.sis.storage.aggregate.ConcatenatedFeatureSetTest.class,
+    org.apache.sis.storage.aggregate.CoverageAggregatorTest.class,
     org.apache.sis.storage.DataStoresTest.class
 })
 public final strictfp class StorageTestSuite extends TestSuite {