sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 03/05: Consolidation of error messages related to duplicated values or key collision. Addition of an ArgumentChecks.ensureNonEmpty(…) method which also check against duplicated values.
Date Sat, 09 Mar 2019 22:59:19 GMT
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 4e26b7959320332e4065c8a39014248c029db19a
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Tue Mar 5 19:14:39 2019 +0100

    Consolidation of error messages related to duplicated values or key collision.
    Addition of an ArgumentChecks.ensureNonEmpty(…) method which also check against duplicated
values.
---
 .../org/apache/sis/feature/NamedFeatureType.java   |  3 +-
 .../apache/sis/internal/simple/SimpleCitation.java |  3 +-
 .../apache/sis/internal/simple/SimpleFormat.java   |  3 +-
 .../apache/sis/io/wkt/GeodeticObjectParser.java    |  3 +-
 .../metadata/iso/identification/OperationName.java |  3 +-
 .../apache/sis/util/iso/DefaultRecordSchema.java   |  3 +-
 .../src/main/java/org/apache/sis/xml/Pooled.java   |  3 +-
 .../org/apache/sis/coverage/grid/GridExtent.java   |  7 +-
 .../sis/internal/referencing/provider/NTv2.java    |  2 +-
 .../org/apache/sis/parameter/TensorParameters.java | 11 ++-
 .../sis/parameter/UninitializedParameter.java      |  3 +-
 .../factory/sql/InstallationScriptProvider.java    |  4 +-
 .../apache/sis/referencing/operation/CRSPair.java  |  3 +-
 .../java/org/apache/sis/util/ArgumentChecks.java   | 82 ++++++++++++++++++++++
 .../src/main/java/org/apache/sis/util/Version.java |  5 +-
 .../sis/util/collection/DefaultTreeTable.java      |  5 +-
 .../sis/util/collection/TreeTableFormat.java       |  4 +-
 .../java/org/apache/sis/util/resources/Errors.java | 12 +++-
 .../apache/sis/util/resources/Errors.properties    |  4 +-
 .../apache/sis/util/resources/Errors_fr.properties | 10 +--
 .../org/apache/sis/internal/util/CitationMock.java |  2 +-
 .../org/apache/sis/util/ArgumentChecksTest.java    | 16 ++++-
 .../org/apache/sis/storage/gdal/Proj4Parser.java   |  2 +-
 .../apache/sis/internal/netcdf/NamedElement.java   |  3 +-
 24 files changed, 150 insertions(+), 46 deletions(-)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/feature/NamedFeatureType.java b/core/sis-feature/src/main/java/org/apache/sis/feature/NamedFeatureType.java
index 0caa7cc..6255513 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/NamedFeatureType.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/NamedFeatureType.java
@@ -27,6 +27,7 @@ import org.opengis.feature.PropertyNotFoundException;
 import org.opengis.feature.FeatureInstantiationException;
 import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
+import org.apache.sis.internal.util.Strings;
 import org.apache.sis.internal.feature.Resources;
 
 
@@ -150,6 +151,6 @@ final class NamedFeatureType implements FeatureType, Serializable {
      */
     @Override
     public String toString() {
-        return "FeatureType[“" + name + "”]";
+        return Strings.bracket("FeatureType", name);
     }
 }
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/SimpleCitation.java
b/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/SimpleCitation.java
index 04fdeec..4b43b97 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/SimpleCitation.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/SimpleCitation.java
@@ -31,6 +31,7 @@ import org.opengis.metadata.citation.Series;
 import org.opengis.metadata.identification.BrowseGraphic;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.iso.SimpleInternationalString;
+import org.apache.sis.internal.util.Strings;
 
 
 /**
@@ -126,6 +127,6 @@ public class SimpleCitation implements Citation, Serializable {
      */
     @Override
     public String toString() {
-        return "Citation[“" + title + "”]";
+        return Strings.bracket("Citation", title);
     }
 }
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/SimpleFormat.java
b/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/SimpleFormat.java
index 3e68625..9b61b93 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/SimpleFormat.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/internal/simple/SimpleFormat.java
@@ -23,6 +23,7 @@ import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.distribution.Distributor;
 import org.opengis.metadata.distribution.Format;
 import org.opengis.metadata.distribution.Medium;
+import org.apache.sis.internal.util.Strings;
 
 
 /**
@@ -158,6 +159,6 @@ public class SimpleFormat extends SimpleCitation implements Format {
      */
     @Override
     public String toString() {
-        return "Format[“" + title + "”]";
+        return Strings.bracket("Format", title);
     }
 }
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
b/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
index b4914a5..ebf45df 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
@@ -73,6 +73,7 @@ import org.apache.sis.internal.metadata.TransformationAccuracy;
 import org.apache.sis.internal.metadata.EllipsoidalHeightCombiner;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.util.Numerics;
+import org.apache.sis.internal.util.Strings;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.iso.DefaultNameSpace;
@@ -1110,7 +1111,7 @@ class GeodeticObjectParser extends MathTransformParser implements Comparator<Coo
         }
         if (axisOrder.put(axis, n) != null) {   // Opportunist check, effective for instances
created by SIS factory.
             throw new UnparsableObjectException(errorLocale, Errors.Keys.DuplicatedElement_1,
-                    new Object[] {WKTKeywords.Axis + "[“" + name + "”]"}, element.offset);
+                    new Object[] {Strings.bracket(WKTKeywords.Axis, name)}, element.offset);
         }
         return axis;
     }
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/OperationName.java
b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/OperationName.java
index d4eba22..b7eef55 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/OperationName.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/OperationName.java
@@ -28,6 +28,7 @@ import org.opengis.metadata.identification.DistributedComputingPlatform;
 import org.opengis.metadata.identification.OperationMetadata;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.util.InternationalString;
+import org.apache.sis.internal.util.Strings;
 
 
 /**
@@ -73,7 +74,7 @@ final class OperationName implements OperationMetadata, Serializable {
      */
     @Override
     public String toString() {
-        return "OperationMetadata[“" + operationName + "”]";
+        return Strings.bracket("OperationMetadata", operationName);
     }
 
     /**
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
index 480aeb0..f277308 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
@@ -38,6 +38,7 @@ import org.apache.sis.util.collection.WeakValueHashMap;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.simple.SimpleAttributeType;
 import org.apache.sis.internal.converter.SurjectiveConverter;
+import org.apache.sis.internal.util.Strings;
 
 
 /**
@@ -253,6 +254,6 @@ public class DefaultRecordSchema implements RecordSchema {
      */
     @Override
     public String toString() {
-        return "RecordSchema[“" + getSchemaName() + "”]";
+        return Strings.bracket("RecordSchema", getSchemaName());
     }
 }
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/xml/Pooled.java b/core/sis-metadata/src/main/java/org/apache/sis/xml/Pooled.java
index e468a6b..26c40c4 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/xml/Pooled.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/xml/Pooled.java
@@ -37,6 +37,7 @@ import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.logging.WarningListener;
 import org.apache.sis.internal.util.CollectionsExt;
+import org.apache.sis.internal.util.Strings;
 import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.internal.xml.LegacyNamespaces;
 import org.apache.sis.internal.jaxb.TypeRegistration;
@@ -323,7 +324,7 @@ abstract class Pooled {
                             if (schema != null) {
                                 if (!(schema instanceof String)) {
                                     throw new PropertyException(Errors.format(Errors.Keys.IllegalPropertyValueClass_2,
-                                            name + "[\"" + key + "\"]", value.getClass()));
+                                            Strings.bracket(name, key), value.getClass()));
                                 }
                                 copy.put(key, (String) schema);
                             }
diff --git a/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridExtent.java b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
index 3eaa4ed..d16598b 100644
--- a/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
+++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
@@ -863,12 +863,7 @@ public class GridExtent implements Serializable {
     static int[] verifyDimensions(int[] dimensions, final int limit) {
         ArgumentChecks.ensureNonNull("dimensions", dimensions);
         final int n = dimensions.length;
-        if (n == 0) {
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1,
"dimensions"));
-        }
-        if (n > limit) {
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.TooManyOccurrences_2,
limit, "dimension"));
-        }
+        ArgumentChecks.ensureSizeBetween("dimensions", 1, limit, n);
         dimensions = dimensions.clone();
         if (!ArraysExt.isSorted(dimensions, true)) {
             throw new IllegalArgumentException(Resources.format(Resources.Keys.NotStrictlyOrderedDimensions));
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java
index 0003409..f6bdf37 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java
@@ -412,7 +412,7 @@ public final class NTv2 extends AbstractProvider {
                 }
                 final Object old = header.put(key, value);
                 if (old != null && !old.equals(value)) {
-                    throw new FactoryException(Errors.format(Errors.Keys.DuplicatedElement_1,
key));
+                    throw new FactoryException(Errors.format(Errors.Keys.KeyCollision_1,
key));
                 }
                 buffer.position(position += RECORD_LENGTH - KEY_LENGTH);
             }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/parameter/TensorParameters.java
b/core/sis-referencing/src/main/java/org/apache/sis/parameter/TensorParameters.java
index c2e186d..1900bec 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/parameter/TensorParameters.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/parameter/TensorParameters.java
@@ -320,13 +320,10 @@ public class TensorParameters<E> implements Serializable {
     public TensorParameters(final Class<E> elementType, final String prefix, final
String separator,
             final ParameterDescriptor<Integer>... dimensions)
     {
-        ArgumentChecks.ensureNonNull("elementType", elementType);
-        ArgumentChecks.ensureNonNull("prefix",      prefix);
-        ArgumentChecks.ensureNonNull("separator",   separator);
-        ArgumentChecks.ensureNonNull("dimensions",  dimensions);
-        if (dimensions.length == 0) {
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1,
"dimensions"));
-        }
+        ArgumentChecks.ensureNonNull ("elementType", elementType);
+        ArgumentChecks.ensureNonNull ("prefix",      prefix);
+        ArgumentChecks.ensureNonNull ("separator",   separator);
+        ArgumentChecks.ensureNonEmpty("dimensions",  dimensions);
         this.elementType = elementType;
         this.prefix      = prefix;
         this.separator   = separator;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/parameter/UninitializedParameter.java
b/core/sis-referencing/src/main/java/org/apache/sis/parameter/UninitializedParameter.java
index 5e3f78d..4c45685 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/parameter/UninitializedParameter.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/parameter/UninitializedParameter.java
@@ -20,6 +20,7 @@ import java.io.Serializable;
 import org.opengis.parameter.GeneralParameterDescriptor;
 import org.opengis.parameter.GeneralParameterValue;
 import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.internal.util.Strings;
 
 
 /**
@@ -74,6 +75,6 @@ final class UninitializedParameter implements GeneralParameterValue, Serializabl
      */
     @Override
     public String toString() {
-        return "Parameter[\"" + IdentifiedObjects.toString(descriptor.getName()) + "\"]";
+        return Strings.bracket("Parameter", IdentifiedObjects.toString(descriptor.getName()));
     }
 }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
index 99d0a6c..87ab62e 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
@@ -332,8 +332,8 @@ public abstract class InstallationScriptProvider extends InstallationResources
{
                                 if (name.contains(part)) {
                                     if (found[i] != null) {
                                         log(Errors.getResources(locale)
-                                                  .getLogRecord(Level.WARNING, Errors.Keys.DuplicatedElement_1,
part));
-                                        return;                         // Stop the search
because of duplicated file.
+                                                  .getLogRecord(Level.WARNING, Errors.Keys.DuplicatedFileReference_1,
part));
+                                        return;   // Stop the search because of duplicated
file.
                                     }
                                     found[i] = name;
                                 }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java
index 98b64dc..adc53e9 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java
@@ -23,6 +23,7 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.IdentifiedObject;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.internal.util.Strings;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Classes;
 
@@ -116,7 +117,7 @@ final class CRSPair {
                 }
                 name = CharSequences.trimWhitespaces(name, 0, i).toString() + '…';
             }
-            label = label + "[“" + name + "”]";
+            label = Strings.bracket(label, name);
         }
         return label;
     }
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 a171749..ceb6330 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
@@ -17,11 +17,13 @@
 package org.apache.sis.util;
 
 import java.util.Map;                                               // For javadoc
+import java.util.BitSet;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.geometry.MismatchedDimensionException;
+import org.apache.sis.internal.util.Strings;
 
 import org.apache.sis.util.resources.Errors;
 
@@ -165,6 +167,86 @@ public final class ArgumentChecks extends Static {
     }
 
     /**
+     * Makes sure that an array is non-null and non-empty. If the given {@code array} is
null,
+     * then a {@link NullArgumentException} is thrown. Otherwise if the array length is equals
+     * to 0, then an {@link IllegalArgumentException} is thrown.
+     *
+     * @param  name   the name of the argument to be checked. Used only if an exception is
thrown.
+     * @param  array  the user argument to check against null value and empty array.
+     * @throws NullArgumentException if {@code array} is null.
+     * @throws IllegalArgumentException if {@code array} is empty.
+     *
+     * @since 1.0
+     */
+    public static void ensureNonEmpty(final String name, final Object[] array)
+            throws NullArgumentException, IllegalArgumentException
+    {
+        if (array == null) {
+            throw new NullArgumentException(Errors.format(Errors.Keys.NullArgument_1, name));
+        }
+        if (array.length == 0) {
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1,
name));
+        }
+    }
+
+    /**
+     * Ensures that the given {@code values} array is non-null and non-empty. This method
can also ensures that all values
+     * are between the given bounds (inclusive) and are distinct. The distinct values requirement
is useful for validating
+     * arrays of spatio-temporal dimension indices, where dimensions can not be repeated.
+     *
+     * <p>Note that a successful call to {@code ensureNonEmpty(name, values, 0, max,
true)} 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  values    integer values to validate.
+     * @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  distinct  {@code true} if each value must be unique.
+     * @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.0
+     */
+    public static void ensureNonEmpty(final String name, final int[] values, final int min,
final int max, final boolean distinct)
+            throws IllegalArgumentException
+    {
+        if (values == null) {
+            throw new NullArgumentException(Errors.format(Errors.Keys.NullArgument_1, name));
+        }
+        if (values.length == 0) {
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1,
name));
+        }
+        long found = 0;                             // Cheap way to check for duplication
when (max - min) ≦ 64.
+        BitSet more = null;                         // Used only if above cheap way is not
sufficient.
+        for (int i=0; i<values.length; i++) {
+            final int index = values[i];
+            if (index < min || index > max) {
+                throw new IllegalArgumentException(Errors.format(
+                        Errors.Keys.ValueOutOfRange_4, Strings.toIndexed(name, i), min, max,
index));
+            }
+            if (distinct) {
+                int flag = index - min;
+                if (flag <= Long.SIZE) {
+                    if (found != (found |= 1L << flag)) {
+                        continue;                               // No collision for current
index.
+                    }
+                } else {
+                    flag -= Long.SIZE;
+                    if (more == null) {
+                        more = new BitSet();
+                    }
+                    if (!more.get(flag)) {
+                        more.set(flag);
+                        continue;                               // No collision for current
index.
+                    }
+                }
+                throw new IllegalArgumentException(Errors.format(Errors.Keys.DuplicatedNumber_1,
index));
+            }
+        }
+    }
+
+    /**
      * Ensures that the specified value is null or an instance assignable to the given type.
      * If this method does not thrown an exception, then the value can be casted to the class
      * represented by {@code expectedType} without throwing a {@link ClassCastException}.
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 ddbe487..09816be 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
@@ -18,7 +18,6 @@ package org.apache.sis.util;
 
 import java.io.Serializable;
 import java.util.StringTokenizer;
-import org.apache.sis.util.resources.Errors;
 
 import static org.apache.sis.internal.system.Modules.MAJOR_VERSION;
 import static org.apache.sis.internal.system.Modules.MINOR_VERSION;
@@ -122,9 +121,7 @@ public class Version implements CharSequence, Comparable<Version>,
Serializable
      * @since 0.4
      */
     public static Version valueOf(final int... components) {
-        if (components.length == 0) {
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1,
"components"));
-        }
+        ArgumentChecks.ensureNonEmpty("components", components, Integer.MIN_VALUE, Integer.MAX_VALUE,
false);
         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/collection/DefaultTreeTable.java
b/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
index 9e30788..70515fb 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
@@ -122,10 +122,7 @@ public class DefaultTreeTable implements TreeTable, Cloneable, Serializable
{
      * @param  columns  the list of table columns.
      */
     public DefaultTreeTable(TableColumn<?>... columns) {
-        ArgumentChecks.ensureNonNull("columns", columns);
-        if (columns.length == 0) {
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1,
"columns"));
-        }
+        ArgumentChecks.ensureNonEmpty("columns", columns);
         /*
          * Copy the array for safety against user changes, and also for forcing the element
type
          * to TableColumn, not a subclass, because of the UnmodifiableArrayList.wrap(E[])
contract.
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
b/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
index 77c3ae4..f730caa 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
@@ -267,9 +267,7 @@ public class TreeTableFormat extends TabularFormat<TreeTable> {
         if (columns == null) {
             columnIndices = null;
         } else {
-            if (columns.length == 0) {
-                throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1,
"columns"));
-            }
+            ArgumentChecks.ensureNonEmpty("columns", columns);
             columnIndices = DefaultTreeTable.createColumnIndices(columns);
         }
     }
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
index 88705aa..7ca6176 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
@@ -231,11 +231,21 @@ public final class Errors extends IndexedResourceBundle {
         public static final short DuplicatedElement_1 = 24;
 
         /**
+         * File “{0}” is referenced more than once.
+         */
+        public static final short DuplicatedFileReference_1 = 186;
+
+        /**
          * Name or identifier “{0}” is used more than once.
          */
         public static final short DuplicatedIdentifier_1 = 25;
 
         /**
+         * Value {0,number} is used more than once.
+         */
+        public static final short DuplicatedNumber_1 = 187;
+
+        /**
          * Option “{0}” is duplicated.
          */
         public static final short DuplicatedOption_1 = 26;
@@ -484,7 +494,7 @@ public final class Errors extends IndexedResourceBundle {
         public static final short InvalidVersionIdentifier_1 = 179;
 
         /**
-         * A different value is already associated to the “{0}” key.
+         * Key “{0}” is associated twice to different values.
          */
         public static final short KeyCollision_1 = 75;
 
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
index 9b8c0fe..75be8f1 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
@@ -57,7 +57,9 @@ DatabaseUpdateFailure_3           = Failed to {0,choice,0#insert|1#update}
recor
 DeadThread_1                      = Thread \u201c{0}\u201d is dead.
 DisposedInstanceOf_1              = This instance of \u2018{0}\u2019 has been disposed.
 DuplicatedElement_1               = Element \u201c{0}\u201d is duplicated.
+DuplicatedFileReference_1         = File \u201c{0}\u201d is referenced more than once.
 DuplicatedIdentifier_1            = Name or identifier \u201c{0}\u201d is used more than
once.
+DuplicatedNumber_1                = Value {0,number} is used more than once.
 DuplicatedOption_1                = Option \u201c{0}\u201d is duplicated.
 ElementAlreadyPresent_1           = Element \u201c{0}\u201d is already present.
 ElementNotFound_1                 = Element \u201c{0}\u201d has not been found.
@@ -107,7 +109,7 @@ IndexOutOfBounds_1                = Index {0} is out of bounds.
 IndicesOutOfBounds_2              = Indices ({0}, {1}) are out of bounds.
 InfiniteArgumentValue_1           = Argument \u2018{0}\u2019 can not take an infinite value.
 InvalidVersionIdentifier_1        = \u201c{0}\u201d is an invalid version identifier.
-KeyCollision_1                    = A different value is already associated to the \u201c{0}\u201d
key.
+KeyCollision_1                    = Key \u201c{0}\u201d is associated twice to different
values.
 MandatoryAttribute_2              = Attribute \u201c{0}\u201d is mandatory for an object
of type \u2018{1}\u2019.
 MismatchedArrayLengths            = Mismatched array lengths.
 MismatchedCRS                     = The coordinate reference system must be the same for
all objects.
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
index fcca9be..f87e89b 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
@@ -53,11 +53,13 @@ DatabaseError_2                   = Erreur de base de donn\u00e9es lors
de la cr
 DatabaseUpdateFailure_3           = \u00c9chec lors de {0,choice,0#l\u2019insertion|1#la
mise \u00e0 jour} de l\u2019enregistrement \u00ab\u202f{2}\u202f\u00bb dans la table \u00ab\u202f{1}\u202f\u00bb
de la base de donn\u00e9es.
 DeadThread_1                      = La t\u00e2che \u00ab\u202f{0}\u202f\u00bb est morte.
 DisposedInstanceOf_1              = Cette instance de \u2018{0}\u2019 a \u00e9t\u00e9 dispos\u00e9e.
-DuplicatedElement_1               = L\u2019\u00e9lement \u00ab\u202f{0}\u202f\u00bb est dupliqu\u00e9.
+DuplicatedElement_1               = L\u2019\u00e9l\u00e9ment \u00ab\u202f{0}\u202f\u00bb
est dupliqu\u00e9.
+DuplicatedFileReference_1         = Le fichier \u00ab\u202f{0}\u202f\u00bb est r\u00e9f\u00e9renc\u00e9
plus d\u2019une fois.
 DuplicatedIdentifier_1            = Le nom ou l\u2019identifiant \u00ab\u202f{0}\u202f\u00bb
est utilis\u00e9 plus d\u2019une fois.
+DuplicatedNumber_1                = La valeur {0,number} est utilis\u00e9e plus d\u2019une
fois.
 DuplicatedOption_1                = L\u2019option \u00ab\u202f{0}\u202f\u00bb est dupliqu\u00e9e.
-ElementAlreadyPresent_1           = L\u2019\u00e9lement \u00ab\u202f{0}\u202f\u00bb est d\u00e9j\u00e0
pr\u00e9sent.
-ElementNotFound_1                 = L\u2019\u00e9lement \u00ab\u202f{0}\u202f\u00bb n\u2019a
pas \u00e9t\u00e9 trouv\u00e9.
+ElementAlreadyPresent_1           = L\u2019\u00e9l\u00e9ment \u00ab\u202f{0}\u202f\u00bb
est d\u00e9j\u00e0 pr\u00e9sent.
+ElementNotFound_1                 = L\u2019\u00e9l\u00e9ment \u00ab\u202f{0}\u202f\u00bb
n\u2019a pas \u00e9t\u00e9 trouv\u00e9.
 EmptyArgument_1                   = L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre
vide.
 EmptyDictionary                   = Le dictionnaire doit contenir au moins une entr\u00e9e.
 EmptyEnvelope2D                   = L\u2019enveloppe doit avoir au moins deux dimensions
et ne pas \u00eatre vide.
@@ -104,7 +106,7 @@ IndexOutOfBounds_1                = L\u2019index {0} est en dehors des
limites p
 IndicesOutOfBounds_2              = Les index ({0}, {1}) sont en dehors des limites permises.
 InfiniteArgumentValue_1           = L\u2019argument \u2018{0}\u2019 ne peut pas prendre une
valeur infinie.
 InvalidVersionIdentifier_1        = \u00ab\u202f{0}\u202f\u00bb n\u2019est pas un identifiant
de version valide.
-KeyCollision_1                    = Une valeur diff\u00e9rente est d\u00e9j\u00e0 associ\u00e9e
\u00e0 la cl\u00e9 \u00ab\u202f{0}\u202f\u00bb.
+KeyCollision_1                    = La cl\u00e9 \u00ab\u202f{0}\u202f\u00bb est associ\u00e9e
deux fois \u00e0 des valeurs diff\u00e9rentes.
 MandatoryAttribute_2              = L\u2019attribut \u00ab\u202f{0}\u202f\u00bb est obligatoire
pour un objet de type \u2018{1}\u2019.
 MismatchedArrayLengths            = Les dimensions des tableaux ne correspondent pas.
 MismatchedCRS                     = Le syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es
doit \u00eatre le m\u00eame pour tous les objets.
diff --git a/core/sis-utility/src/test/java/org/apache/sis/internal/util/CitationMock.java
b/core/sis-utility/src/test/java/org/apache/sis/internal/util/CitationMock.java
index 5632c55..4a31d4a 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/internal/util/CitationMock.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/internal/util/CitationMock.java
@@ -100,6 +100,6 @@ final strictfp class CitationMock implements Citation, Identifier {
      */
     @Override
     public String toString() {
-        return "Citation[“" + title + "”]";
+        return Strings.bracket("Citation", title);
     }
 }
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 a11fbbf..64b2a98 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
@@ -27,7 +27,7 @@ import static org.junit.Assert.*;
  * Tests the {@link ArgumentChecks} static methods.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.4
+ * @version 1.0
  * @since   0.4
  * @module
  */
@@ -51,4 +51,18 @@ public final strictfp class ArgumentChecksTest extends TestCase {
             assertTrue(e.getMessage().contains("axes[2].unit"));
         }
     }
+
+    /**
+     * Tests {@link ArgumentChecks#ensureNonEmpty(String, int[], int, int, boolean)}.
+     */
+    @Test
+    public void testEnsureBetweenAndDistinct() {
+        ArgumentChecks.ensureNonEmpty("dimensions", new int[] {2, 3, 0, 1}, 0, 4, true);
+        try {
+            ArgumentChecks.ensureNonEmpty("dimensions", new int[] {2, 3, 3, 1}, 0, 4, true);
+            fail("Expected an IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            assertNotNull(e.getMessage());
+        }
+    }
 }
diff --git a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Parser.java b/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Parser.java
index 733f5c7..785587e 100644
--- a/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Parser.java
+++ b/storage/sis-gdal/src/main/java/org/apache/sis/storage/gdal/Proj4Parser.java
@@ -93,7 +93,7 @@ final class Proj4Parser {
                 if (!value.isEmpty()) {
                     final String old = parameters.put(keyword, value);
                     if (old != null && !old.equals(value)) {
-                        throw new InvalidGeodeticParameterException(Errors.format(Errors.Keys.DuplicatedElement_1,
keyword));
+                        throw new InvalidGeodeticParameterException(Errors.format(Errors.Keys.KeyCollision_1,
keyword));
                     }
                 }
             }
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/NamedElement.java
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/NamedElement.java
index 65ebaad..bffb3d8 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/NamedElement.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/NamedElement.java
@@ -23,6 +23,7 @@ import org.apache.sis.util.Characters;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.logging.WarningListeners;
 import org.apache.sis.internal.system.Modules;
+import org.apache.sis.internal.util.Strings;
 import org.apache.sis.util.resources.IndexedResourceBundle;
 
 
@@ -114,6 +115,6 @@ public abstract class NamedElement {
      */
     @Override
     public String toString() {
-        return getClass().getSimpleName() + "[\"" + getName() + "\"]";
+        return Strings.bracket(getClass().getSimpleName(), getName());
     }
 }


Mime
View raw message