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 e4d0c384bba0d1bce5d6cd0b2f49cedb1810f591
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Fri Mar 24 16:38:25 2023 +0100

    Consolidation of argument checks.
---
 .../sis/coverage/grid/GridCoverageProcessor.java   |   2 +-
 .../org/apache/sis/coverage/grid/GridExtent.java   |   2 +-
 .../java/org/apache/sis/filter/LogicalFilter.java  |   5 +-
 .../java/org/apache/sis/image/BandSelectImage.java |   5 +-
 .../java/org/apache/sis/image/ImageProcessor.java  |   2 +-
 .../internal/coverage/j2d/SampleModelFactory.java  |   2 +-
 .../sis/internal/filter/sqlmm/SpatialFunction.java |  23 +----
 .../org/apache/sis/util/iso/DefaultScopedName.java |   2 +-
 .../operation/builder/LinearTransformBuilder.java  |   2 +-
 .../java/org/apache/sis/util/ArgumentChecks.java   | 112 +++++++++++++++------
 .../src/main/java/org/apache/sis/util/Version.java |   2 +-
 .../java/org/apache/sis/util/package-info.java     |   2 +-
 .../org/apache/sis/util/ArgumentChecksTest.java    |   6 +-
 .../java/org/apache/sis/storage/CoverageQuery.java |   2 +-
 14 files changed, 98 insertions(+), 71 deletions(-)

diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverageProcessor.java
 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverageProcessor.java
index fdeb1e48bc..ea557d7a04 100644
--- 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverageProcessor.java
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverageProcessor.java
@@ -336,7 +336,7 @@ public class GridCoverageProcessor implements Cloneable {
         ArgumentChecks.ensureNonNull("source",     source);
         ArgumentChecks.ensureNonNull("converters", converters);
         final List<SampleDimension> sourceBands = source.getSampleDimensions();
-        ArgumentChecks.ensureSizeBetween("converters", 1, sourceBands.size(), 
converters.length);
+        ArgumentChecks.ensureCountBetween("converters", true, 1, 
sourceBands.size(), converters.length);
         final SampleDimension[] targetBands = new 
SampleDimension[converters.length];
         final SampleDimension.Builder builder = new SampleDimension.Builder();
         if (sampleDimensionModifier == null) {
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
index fd8b7daadd..de45ba8a24 100644
--- 
a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
@@ -1344,7 +1344,7 @@ public class GridExtent implements GridEnvelope, 
LenientComparable, Serializable
     static int[] verifyDimensions(int[] indices, final int limit) {
         ArgumentChecks.ensureNonNull("indices", indices);
         final int n = indices.length;
-        ArgumentChecks.ensureSizeBetween("indices", 1, limit, n);
+        ArgumentChecks.ensureCountBetween("indices", false, 1, limit, n);
         indices = indices.clone();
         if (!ArraysExt.isSorted(indices, true)) {
             throw new 
IllegalArgumentException(Resources.format(Resources.Keys.NotStrictlyOrderedDimensions));
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/filter/LogicalFilter.java 
b/core/sis-feature/src/main/java/org/apache/sis/filter/LogicalFilter.java
index 2916fa227a..2aeb42d671 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/filter/LogicalFilter.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/filter/LogicalFilter.java
@@ -22,7 +22,6 @@ import java.util.LinkedHashSet;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
-import org.apache.sis.util.resources.Errors;
 
 // Branch-dependent imports
 import org.opengis.filter.Filter;
@@ -63,9 +62,7 @@ abstract class LogicalFilter<R> extends FilterNode<R> 
implements LogicalOperator
     LogicalFilter(final Collection<? extends Filter<? super R>> op) {
         ArgumentChecks.ensureNonEmpty("operands", op);
         operands = op.toArray(Filter[]::new);
-        if (operands.length < 2) {
-            throw new 
IllegalArgumentException(Errors.format(Errors.Keys.TooFewArguments_2, 2, 
operands.length));
-        }
+        ArgumentChecks.ensureCountBetween("operands", true, 2, 
Integer.MAX_VALUE, operands.length);
         for (int i=0; i<operands.length; i++) {
             ArgumentChecks.ensureNonNullElement("operands", i, operands[i]);
         }
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/image/BandSelectImage.java 
b/core/sis-feature/src/main/java/org/apache/sis/image/BandSelectImage.java
index 7a13fb98d3..5fb07dbb69 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/BandSelectImage.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/BandSelectImage.java
@@ -84,9 +84,8 @@ final class BandSelectImage extends SourceAlignedImage {
         if (bands.length == numBands && ArraysExt.isRange(0, bands)) {
             return source;
         }
-        ArgumentChecks.ensureNonEmpty("bands", bands, 0, numBands - 1, false);
-        final ColorModel cm = 
ColorModelFactory.createSubset(source.getColorModel(), bands)
-                .orElse(null);
+        ArgumentChecks.ensureNonEmptyBounded("bands", false, 0, numBands - 1, 
bands);
+        final ColorModel cm = 
ColorModelFactory.createSubset(source.getColorModel(), bands).orElse(null);
         /*
          * If the image is an instance of `BufferedImage`, create the subset 
immediately
          * (reminder: this operation will not copy pixel data). It allows us 
to return a
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/image/ImageProcessor.java 
b/core/sis-feature/src/main/java/org/apache/sis/image/ImageProcessor.java
index bf05f1e594..b01eede431 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/ImageProcessor.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/ImageProcessor.java
@@ -961,7 +961,7 @@ public class ImageProcessor implements Cloneable {
         ArgumentChecks.ensureNonNull("source", source);
         ArgumentChecks.ensureNonNull("converters", converters);
         ArgumentChecks.ensureNonNull("targetType", targetType);
-        ArgumentChecks.ensureSizeBetween("converters", 1, 
ImageUtilities.getNumBands(source), converters.length);
+        ArgumentChecks.ensureCountBetween("converters", true, 1, 
ImageUtilities.getNumBands(source), converters.length);
         converters = converters.clone();
         for (int i=0; i<converters.length; i++) {
             ArgumentChecks.ensureNonNullElement("converters", i, 
converters[i]);
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/SampleModelFactory.java
 
b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/SampleModelFactory.java
index 3091411a48..c25f458725 100644
--- 
a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/SampleModelFactory.java
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/SampleModelFactory.java
@@ -211,7 +211,7 @@ public final class SampleModelFactory {
      * @see SampleModel#createSubsetSampleModel(int[])
      */
     public void subsetAndCompress(final int[] bands) {
-        ArgumentChecks.ensureSizeBetween("bands", 1, numBands, bands.length);
+        ArgumentChecks.ensureCountBetween("bands", true, 1, numBands, 
bands.length);
         if (bankIndices != null) bankIndices = subset(bankIndices, bands, 
true);
         if (bandOffsets != null) bandOffsets = subset(bandOffsets, bands, 
bankIndices == null);
         if (bitMasks    != null) {
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/SpatialFunction.java
 
b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/SpatialFunction.java
index 91d83a5e22..9d46610846 100644
--- 
a/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/SpatialFunction.java
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/internal/filter/sqlmm/SpatialFunction.java
@@ -29,6 +29,7 @@ import org.apache.sis.feature.builder.FeatureTypeBuilder;
 import org.apache.sis.feature.builder.PropertyTypeBuilder;
 import org.apache.sis.feature.builder.AttributeTypeBuilder;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.iso.Names;
 
 // Branch-dependent imports
@@ -42,7 +43,7 @@ import org.opengis.filter.InvalidFilterValueException;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.4
  *
  * @param  <R>  the type of resources (e.g. {@link 
org.opengis.feature.Feature}) used as inputs.
  *
@@ -83,24 +84,8 @@ abstract class SpatialFunction<R> extends Node implements 
FeatureExpression<R,Ob
      */
     SpatialFunction(final SQLMM operation, final Expression<? super R, ?>[] 
parameters) {
         this.operation = operation;
-        final int n = parameters.length;
-        final int minParamCount = operation.minParamCount;
-        final String message;
-        if (n < minParamCount) {
-            if (n == 0) {
-                message = Errors.format(Errors.Keys.EmptyArgument_1, 
"parameters");
-            } else {
-                message = Errors.format(Errors.Keys.TooFewArguments_2, 
minParamCount, n);
-            }
-        } else {
-            final int maxParamCount = operation.maxParamCount;
-            if (n > maxParamCount) {
-                message = Errors.format(Errors.Keys.TooManyArguments_2, 
maxParamCount, n);
-            } else {
-                return;
-            }
-        }
-        throw new IllegalArgumentException(message);
+        ArgumentChecks.ensureCountBetween("parameters", true,
+                operation.minParamCount, operation.maxParamCount, 
parameters.length);
     }
 
     /**
diff --git 
a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
 
b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
index 65fc978371..9a35da78cb 100644
--- 
a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
+++ 
b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
@@ -116,7 +116,7 @@ public class DefaultScopedName extends AbstractName 
implements ScopedName {
     protected DefaultScopedName(final NameSpace scope, final List<? extends 
CharSequence> names) {
         ArgumentChecks.ensureNonNull("names", names);
         final int size = names.size();
-        ArgumentChecks.ensureSizeBetween("names", 2, Integer.MAX_VALUE, size);
+        ArgumentChecks.ensureCountBetween("names", true, 2, Integer.MAX_VALUE, 
size);
         DefaultNameSpace ns = DefaultNameSpace.castOrCopy(scope);
         final boolean global = ns.isGlobal();
         int i = 0;
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
index 2352825171..d329891ba3 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
@@ -227,7 +227,7 @@ public class LinearTransformBuilder extends 
TransformBuilder {
      * @since 0.8
      */
     public LinearTransformBuilder(int... gridSize) {
-        ArgumentChecks.ensureNonEmpty("gridSize", gridSize, 1, 
Integer.MAX_VALUE, false);
+        ArgumentChecks.ensureNonEmptyBounded("gridSize", false, 1, 
Integer.MAX_VALUE, gridSize);
         if (gridSize.length == 0) {
             this.gridSize = null;
             this.gridLength = 0;
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/util/ArgumentChecks.java 
b/core/sis-utility/src/main/java/org/apache/sis/util/ArgumentChecks.java
index dc4fc1ec68..800de42d5d 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/ArgumentChecks.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/ArgumentChecks.java
@@ -54,7 +54,8 @@ import org.opengis.coverage.grid.GridEnvelope;
  *     {@link #ensurePositive(String, int) ensurePositive},
  *     {@link #ensureStrictlyPositive(String, int) ensureStrictlyPositive},
  *     {@link #ensureBetween(String, int, int, int) ensureBetween},
- *     {@link #ensureSizeBetween(String, int, int, int) ensureBetween},
+ *     {@link #ensureCountBetween(String, boolean, int, int, int) 
ensureCountBetween},
+ *     {@link #ensureNonEmptyBounded(String, boolean, int, int, int[]) 
ensureNonEmptyBounded},
  *     {@link #ensureCanCast(String, Class, Object) ensureCanCast}.
  *   </td>
  * </tr><tr>
@@ -80,14 +81,14 @@ import org.opengis.coverage.grid.GridEnvelope;
  * </ul>
  *
  * <h2>Method Arguments</h2>
- * By convention, the value to check is always the last parameter given to 
every methods
- * in this class. The other parameters may include the programmatic name of 
the argument
- * being checked. This programmatic name is used for building an error message 
localized
- * in the {@linkplain java.util.Locale#getDefault() default locale} if the 
check failed.
+ * By convention, the value to check is always the last parameter given to 
every methods in this class.
+ * The other parameters may include the programmatic name of the argument 
being checked.
+ * This programmatic name is used for building an error message localized in 
the
+ * {@linkplain java.util.Locale#getDefault() default locale} if the check 
failed.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Alexis Manin (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  */
 public final class ArgumentChecks extends Static {
@@ -232,9 +233,36 @@ public final class ArgumentChecks extends Static {
      *         contains a value greater than {@code max}, or contains 
duplicated values while {@code distinct} is {@code true}.
      *
      * @since 1.0
+     *
+     * @deprecated Replaced by {@link #ensureNonEmptyBounded(String, boolean, 
int, int, int[])}.
      */
+    @Deprecated(since = "1.3", forRemoval = true)
     public static void ensureNonEmpty(final String name, final int[] values, 
final int min, final int max, final boolean distinct)
             throws IllegalArgumentException
+    {
+        ensureNonEmptyBounded(name, distinct, min, max, values);
+    }
+
+    /**
+     * Ensures that the given {@code values} array contains at least one 
element and that all elements are within bounds.
+     * The minimum and maximum values are inclusive. Optionaly, this method 
can also ensure that all values are distinct.
+     *
+     * <p>Note that a successful call to {@code ensureNonEmptyBounded(name, 
true, 0, max, values)}
+     * implies 1 ≤ {@code values.length} ≤ {@code max}.</p>
+     *
+     * @param  name      the name of the argument to be checked. Used only if 
an exception is thrown.
+     * @param  distinct  {@code true} if each value must be unique.
+     * @param  min       the minimal allowed value (inclusive), or {@link 
Integer#MIN_VALUE} if none.
+     * @param  max       the maximal allowed value (inclusive), or {@link 
Integer#MAX_VALUE} if none.
+     * @param  values    integer values to validate.
+     * @throws NullArgumentException if {@code values} is null.
+     * @throws IllegalArgumentException if {@code values} is empty, contains a 
value lower than {@code min},
+     *         contains a value greater than {@code max}, or contains 
duplicated values while {@code distinct} is {@code true}.
+     *
+     * @since 1.4
+     */
+    public static void ensureNonEmptyBounded(final String name, final boolean 
distinct, final int min, final int max, final int[] values)
+            throws IllegalArgumentException
     {
         if (values == null) {
             throw new 
NullArgumentException(Errors.format(Errors.Keys.NullArgument_1, name));
@@ -274,26 +302,19 @@ public final class ArgumentChecks extends Static {
     /**
      * Ensures that a method receiving a variable number of arguments got the 
expected count.
      * If {@code actual} = {@code expected}, then this method does nothing.
-     * Otherwise a message saying "Too few" or "Too many arguments" is thrown.
+     * Otherwise an exception saying "Too few" or "Too many arguments" is 
thrown.
      *
      * @param  name      the name of the argument to be checked. Used only if 
an exception is thrown.
      * @param  expected  expected number of arguments.
      * @param  actual    actual number of arguments.
      *
      * @since 1.0
+     *
+     * @deprecated Renamed {@link #ensureCountBetween(String, boolean, int, 
int, int)}.
      */
+    @Deprecated(since = "1.3", forRemoval = true)
     public static void ensureExpectedCount(final String name, final int 
expected, final int actual) {
-        if (actual != expected) {
-            final String message;
-            if (actual == 0) {
-                message = Errors.format(Errors.Keys.EmptyArgument_1, name);
-            } else if (actual < expected) {
-                message = Errors.format(Errors.Keys.TooFewArguments_2, 
expected, actual);
-            } else {
-                message = Errors.format(Errors.Keys.TooManyArguments_2, 
expected, actual);
-            }
-            throw new IllegalArgumentException(message);
-        }
+        ensureCountBetween(name, false, expected, expected, actual);
     }
 
     /**
@@ -362,7 +383,7 @@ public final class ArgumentChecks extends Static {
      * @throws IndexOutOfBoundsException if the given [{@code lower} … {@code 
upper}]
      *         range is out of the sequence index range.
      *
-     * @see #ensureSizeBetween(String, int, int, int)
+     * @see #ensureCountBetween(String, boolean, int, int, int)
      */
     public static void ensureValidIndexRange(final int length, final int 
lower, final int upper) throws IndexOutOfBoundsException {
         if (lower < 0 || upper < lower || upper > length) {
@@ -423,7 +444,7 @@ public final class ArgumentChecks extends Static {
     public static void ensurePositive(final String name, final float value)
             throws IllegalArgumentException
     {
-        if (!(value >= 0)) {                                                // 
Use '!' for catching NaN.
+        if (!(value >= 0)) {                                                // 
Use `!` for catching NaN.
             throw new IllegalArgumentException(Float.isNaN(value) ?
                     Errors.format(Errors.Keys.NotANumber_1, name) :
                     Errors.format(Errors.Keys.NegativeArgument_2, name, 
value));
@@ -444,7 +465,7 @@ public final class ArgumentChecks extends Static {
     public static void ensurePositive(final String name, final double value)
             throws IllegalArgumentException
     {
-        if (!(value >= 0)) {                                                // 
Use '!' for catching NaN.
+        if (!(value >= 0)) {                                                // 
Use `!` for catching NaN.
             throw new IllegalArgumentException(Double.isNaN(value) ?
                     Errors.format(Errors.Keys.NotANumber_1, name)  :
                     Errors.format(Errors.Keys.NegativeArgument_2, name, 
value));
@@ -501,7 +522,7 @@ public final class ArgumentChecks extends Static {
     public static void ensureStrictlyPositive(final String name, final float 
value)
             throws IllegalArgumentException
     {
-        if (!(value > 0)) {                                                 // 
Use '!' for catching NaN.
+        if (!(value > 0)) {                                                 // 
Use `!` for catching NaN.
             throw new IllegalArgumentException(Float.isNaN(value) ?
                     Errors.format(Errors.Keys.NotANumber_1, name) :
                     Errors.format(Errors.Keys.ValueNotGreaterThanZero_2, name, 
value));
@@ -522,7 +543,7 @@ public final class ArgumentChecks extends Static {
     public static void ensureStrictlyPositive(final String name, final double 
value)
             throws IllegalArgumentException
     {
-        if (!(value > 0)) {                                                 // 
Use '!' for catching NaN.
+        if (!(value > 0)) {                                                 // 
Use `!` for catching NaN.
             throw new IllegalArgumentException(Double.isNaN(value) ?
                     Errors.format(Errors.Keys.NotANumber_1, name)  :
                     Errors.format(Errors.Keys.ValueNotGreaterThanZero_2, name, 
value));
@@ -568,7 +589,7 @@ public final class ArgumentChecks extends Static {
      * of integer range checks:
      *
      * <ul>
-     *   <li>{@link #ensureSizeBetween(String, int, int, int) 
ensureSizeBetween(…)}
+     *   <li>{@link #ensureCountBetween(String, boolean, int, int, int) 
ensureCountBetween(…)}
      *       if the {@code value} argument is a collection size or an array 
length.</li>
      *   <li>{@link #ensureValidIndex(int, int) ensureValidIndex(…)} if the 
{@code value}
      *       argument is an index in a list or an array.</li>
@@ -580,7 +601,7 @@ public final class ArgumentChecks extends Static {
      * @param  value  the user argument to check.
      * @throws IllegalArgumentException if the given value is not in the given 
range.
      *
-     * @see #ensureSizeBetween(String, int, int, int)
+     * @see #ensureCountBetween(String, boolean, int, int, int)
      * @see #ensureValidIndex(int, int)
      * @see #ensureValidIndexRange(int, int, int)
      */
@@ -623,7 +644,7 @@ public final class ArgumentChecks extends Static {
     public static void ensureBetween(final String name, final float min, final 
float max, final float value)
             throws IllegalArgumentException
     {
-        if (!(value >= min && value <= max)) {                              // 
Use '!' for catching NaN.
+        if (!(value >= min && value <= max)) {                              // 
Use `!` for catching NaN.
             throw new IllegalArgumentException(Float.isNaN(value) ?
                     Errors.format(Errors.Keys.NotANumber_1, name) :
                     Errors.format(Errors.Keys.ValueOutOfRange_4, name, min, 
max, value));
@@ -642,7 +663,7 @@ public final class ArgumentChecks extends Static {
     public static void ensureBetween(final String name, final double min, 
final double max, final double value)
             throws IllegalArgumentException
     {
-        if (!(value >= min && value <= max)) {                              // 
Use '!' for catching NaN.
+        if (!(value >= min && value <= max)) {                              // 
Use `!` for catching NaN.
             throw new IllegalArgumentException(Double.isNaN(value) ?
                     Errors.format(Errors.Keys.NotANumber_1, name)  :
                     Errors.format(Errors.Keys.ValueOutOfRange_4, name, min, 
max, value));
@@ -660,21 +681,46 @@ public final class ArgumentChecks extends Static {
      * @param  size  the user collection size or array length to be checked.
      * @throws IllegalArgumentException if the given value is not in the given 
range.
      *
+     * @deprecated Renamed {@link #ensureCountBetween(String, boolean, int, 
int, int)}.
+     */
+    @Deprecated(since = "1.3", forRemoval = true)
+    public static void ensureSizeBetween(final String name, final int min, 
final int max, final int size)
+            throws IllegalArgumentException
+    {
+        ensureCountBetween(name, true, min, max, size);
+    }
+
+    /**
+     * Ensures that the given number of elements is between the given bounds, 
inclusive.
+     * This method performs the same check than {@link #ensureBetween(String, 
int, int, int)
+     * ensureBetween(…)}, but the error message is different in case of 
failure.
+     *
+     * @param  name   the name of the argument to be checked. Used only if an 
exception is thrown.
+     * @param  named  whether to use {@code name} as the name of a collection 
or array argument.
+     * @param  min    the minimal size (inclusive), or 0 if none.
+     * @param  max    the maximal size (inclusive), or {@link 
Integer#MAX_VALUE} if none.
+     * @param  count  the number of user-specified arguments, collection size 
or array length to be checked.
+     * @throws IllegalArgumentException if the given value is not in the given 
range.
+     *
      * @see #ensureBetween(String, int, int, int)
      * @see #ensureValidIndexRange(int, int, int)
+     *
+     * @since 1.4
      */
-    public static void ensureSizeBetween(final String name, final int min, 
final int max, final int size)
+    public static void ensureCountBetween(final String name, final boolean 
named, final int min, final int max, final int count)
             throws IllegalArgumentException
     {
         final String message;
-        if (size < min) {
-            if (min == 1) {
+        if (count < min) {
+            if (count == 0) {
                 message = Errors.format(Errors.Keys.EmptyArgument_1, name);
             } else {
-                message = 
Errors.format(Errors.Keys.TooFewCollectionElements_3, name, min, size);
+                message = named ? 
Errors.format(Errors.Keys.TooFewCollectionElements_3, name, min, count)
+                                : Errors.format(Errors.Keys.TooFewArguments_2, 
min, count);
             }
-        } else if (size > max) {
-            message = Errors.format(Errors.Keys.TooManyCollectionElements_3, 
name, max, size);
+        } else if (count > max) {
+            message = named ? 
Errors.format(Errors.Keys.TooManyCollectionElements_3, name, max, count)
+                            : Errors.format(Errors.Keys.TooManyArguments_2, 
max, count);
         } else {
             return;
         }
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/Version.java 
b/core/sis-utility/src/main/java/org/apache/sis/util/Version.java
index 355bc05a2b..606e2cebd6 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/Version.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/Version.java
@@ -120,7 +120,7 @@ public class Version implements CharSequence, 
Comparable<Version>, Serializable
      * @since 0.4
      */
     public static Version valueOf(final int... components) {
-        ArgumentChecks.ensureNonEmpty("components", components, 
Integer.MIN_VALUE, Integer.MAX_VALUE, false);
+        ArgumentChecks.ensureNonEmptyBounded("components", false, 
Integer.MIN_VALUE, Integer.MAX_VALUE, components);
         final Version version;
         final int major = components[0];
         if (components.length == 1) {
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/util/package-info.java 
b/core/sis-utility/src/main/java/org/apache/sis/util/package-info.java
index 10a71cabe2..5364256b1e 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/package-info.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/package-info.java
@@ -39,7 +39,7 @@
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Alexis Manin (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.3
  */
 package org.apache.sis.util;
diff --git 
a/core/sis-utility/src/test/java/org/apache/sis/util/ArgumentChecksTest.java 
b/core/sis-utility/src/test/java/org/apache/sis/util/ArgumentChecksTest.java
index 0b972a0543..dd108b4991 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/util/ArgumentChecksTest.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/util/ArgumentChecksTest.java
@@ -52,13 +52,13 @@ public final class ArgumentChecksTest extends TestCase {
     }
 
     /**
-     * Tests {@link ArgumentChecks#ensureNonEmpty(String, int[], int, int, 
boolean)}.
+     * Tests {@link ArgumentChecks#ensureNonEmptyBounded(String, boolean, int, 
int, int[])}.
      */
     @Test
     public void testEnsureBetweenAndDistinct() {
-        ArgumentChecks.ensureNonEmpty("dimensions", new int[] {2, 3, 0, 1}, 0, 
4, true);
+        ArgumentChecks.ensureNonEmptyBounded("dimensions", true, 0, 4, new 
int[] {2, 3, 0, 1});
         try {
-            ArgumentChecks.ensureNonEmpty("dimensions", new int[] {2, 3, 3, 
1}, 0, 4, true);
+            ArgumentChecks.ensureNonEmptyBounded("dimensions", true, 0, 4, new 
int[] {2, 3, 3, 1});
             fail("Expected an IllegalArgumentException");
         } catch (IllegalArgumentException e) {
             assertNotNull(e.getMessage());
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/storage/CoverageQuery.java 
b/storage/sis-storage/src/main/java/org/apache/sis/storage/CoverageQuery.java
index 89f227d1d2..190d2a2b8d 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/storage/CoverageQuery.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/storage/CoverageQuery.java
@@ -253,7 +253,7 @@ public class CoverageQuery extends Query implements 
Cloneable, Serializable {
     public void setProjection(int... range) {
         if (range != null) {
             range = range.clone();
-            ArgumentChecks.ensureNonEmpty("range", range, 0, 
Integer.MAX_VALUE, true);
+            ArgumentChecks.ensureNonEmptyBounded("range", true, 0, 
Integer.MAX_VALUE, range);
             // Assign only after we verified that the argument is valid.
         }
         this.range = range;

Reply via email to