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 <martin.desruisse...@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 {