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 99563ce460f1ac5258fa0d27985f513c423384c9
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Sat Dec 16 12:07:43 2023 +0100

    Better error message when the components of a CompoundCRS cannot be 
obtained because they are nil.
---
 .../apache/sis/metadata/internal/Identifiers.java  | 27 ++++++++++++++++++++++
 .../apache/sis/xml/bind/IdentifierMapAdapter.java  |  2 +-
 .../sis/xml/bind/ModifiableIdentifierMap.java      |  2 +-
 .../sis/xml/bind/NonMarshalledAuthority.java       |  2 +-
 .../sis/referencing/crs/DefaultCompoundCRS.java    |  4 ++++
 .../sis/referencing/util/ReferencingUtilities.java | 18 +++++++++++++--
 .../main/org/apache/sis/util/resources/Errors.java |  5 ++++
 .../apache/sis/util/resources/Errors.properties    |  1 +
 .../apache/sis/util/resources/Errors_fr.properties |  1 +
 9 files changed, 57 insertions(+), 5 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/Identifiers.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/Identifiers.java
index c956d69cf1..5384d11d9e 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/Identifiers.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/internal/Identifiers.java
@@ -29,6 +29,9 @@ import org.apache.sis.util.internal.Constants;
 import org.apache.sis.util.internal.CollectionsExt;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.resources.Vocabulary;
+import org.apache.sis.xml.NilObject;
+import org.apache.sis.xml.NilReason;
 
 
 /**
@@ -269,4 +272,28 @@ public final class Identifiers extends Static {
                 ? Errors.format(Errors.Keys.MissingValueForProperty_1, 
property)
                 : Errors.format(Errors.Keys.MissingValueForProperty_2, owner, 
property);
     }
+
+    /**
+     * Returns a string representation of the reason why an object is nil.
+     * If the object provides a {@link NilReason}, then its string 
representation is returned.
+     * Otherwise, if the given object provides identifiers, then they are 
assumed unresolved references.
+     * Otherwise, this method returns "unspecified" in the default locale.
+     *
+     * @param  object  the object for which to get the nil reason.
+     * @return string representation of the nil reason.
+     */
+    public static String getNilReason(final NilObject object) {
+        NilReason reason = object.getNilReason();
+        if (reason != null) {
+            return reason.toString();
+        }
+        if (object instanceof org.apache.sis.xml.IdentifiedObject) {
+            for (String id : ((org.apache.sis.xml.IdentifiedObject) 
object).getIdentifierMap().values()) {
+                if (id != null && !id.isBlank()) {
+                    return "unresolved " + id;
+                }
+            }
+        }
+        return Vocabulary.format(Vocabulary.Keys.Unspecified);
+    }
 }
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/IdentifierMapAdapter.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/IdentifierMapAdapter.java
index 59cfd02abd..23528e0bca 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/IdentifierMapAdapter.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/IdentifierMapAdapter.java
@@ -39,7 +39,7 @@ import static 
org.apache.sis.util.collection.Containers.hashMapCapacity;
 
 /**
  * Implementation of the map of identifiers associated to {@link 
org.apache.sis.xml.IdentifiedObject} instances.
- * This base class implements an unmodifiable map, but the {@link 
ModifiableIdentifierMap} subclass add write
+ * This base class implements an unmodifiable map, but the {@link 
ModifiableIdentifierMap} subclass adds write
  * capabilities.
  *
  * <p>This class works as a wrapper around a collection of identifiers. 
Because all operations
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/ModifiableIdentifierMap.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/ModifiableIdentifierMap.java
index 74d9dc563b..38ce6214af 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/ModifiableIdentifierMap.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/ModifiableIdentifierMap.java
@@ -30,7 +30,7 @@ import org.apache.sis.xml.XLink;
 
 
 /**
- * A map of identifiers which support {@code put} and {@code remove} 
operations.
+ * A map of identifiers which supports {@code put} and {@code remove} 
operations.
  *
  * <h2>Thread safety</h2>
  * This class is thread safe if the underlying identifier collection is thread 
safe.
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/NonMarshalledAuthority.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/NonMarshalledAuthority.java
index 1c90143d2a..ca8370f599 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/NonMarshalledAuthority.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/bind/NonMarshalledAuthority.java
@@ -289,7 +289,7 @@ public final class NonMarshalledAuthority<T> extends 
CitationConstant.Authority<
                 case XLINK: candidate = IdentifierSpace.XLINK; break;
                 default: return super.readResolve();
             }
-        } while (!((NonMarshalledAuthority<?>) 
candidate).getName().equals(name));
+        } while (!candidate.getName().equals(name));
         return candidate;
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
index b8ff5e5768..3b304451cd 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
@@ -179,6 +179,7 @@ public class DefaultCompoundCRS extends AbstractCRS 
implements CompoundCRS {
      *
      * @param  properties  the properties to be given to the coordinate 
reference system.
      * @param  components  the sequence of coordinate reference systems making 
this compound CRS.
+     * @throws ClassCastException if a CRS is neither a {@link SingleCRS} or a 
{@link CompoundCRS}.
      * @throws IllegalArgumentException if the given array does not contain at 
least two components,
      *         or if two consecutive components are a geographic CRS with an 
ellipsoidal height.
      *
@@ -266,6 +267,7 @@ public class DefaultCompoundCRS extends AbstractCRS 
implements CompoundCRS {
      * <p>This constructor performs a shallow copy, i.e. the properties are 
not cloned.</p>
      *
      * @param  crs  the coordinate reference system to copy.
+     * @throws ClassCastException if a CRS is neither a {@link SingleCRS} or a 
{@link CompoundCRS}.
      */
     protected DefaultCompoundCRS(final CompoundCRS crs) {
         super(crs);
@@ -366,6 +368,8 @@ public class DefaultCompoundCRS extends AbstractCRS 
implements CompoundCRS {
      * <p><strong>WARNING:</strong> this method is invoked by <em>before</em> 
the {@linkplain #components}
      * field is set. Do not use that field in this method.</p>
      *
+     * @throws ClassCastException if a CRS is neither a {@link SingleCRS} or a 
{@link CompoundCRS}.
+     *
      * @see #getSingleComponents()
      */
     private boolean setSingleComponents(final List<? extends 
CoordinateReferenceSystem> crs) {
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/ReferencingUtilities.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/ReferencingUtilities.java
index bc78e61497..7c4001d119 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/ReferencingUtilities.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/ReferencingUtilities.java
@@ -55,6 +55,8 @@ import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.cs.DefaultEllipsoidalCS;
 import 
org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
 import 
org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory.Context;
+import org.apache.sis.metadata.internal.Identifiers;
+import org.apache.sis.xml.NilObject;
 
 
 /**
@@ -229,9 +231,21 @@ public final class ReferencingUtilities extends Static {
             if (candidate instanceof CompoundCRS) {
                 getSingleComponents(((CompoundCRS) candidate).getComponents(), 
addTo);
                 sameContent = false;
-            } else {
-                // Intentional CassCastException here if the candidate is not 
a SingleCRS.
+            } else if (candidate instanceof SingleCRS) {
                 addTo.add((SingleCRS) candidate);
+            } else {
+                /*
+                 * Illegal class. Try to provide a better error message, in 
particular when the CRS component
+                 * is nil because it is an unresolved xlink in a GML document. 
Nil objects are proxies, which
+                 * have hard to understand class names.
+                 */
+                final String message;
+                if (candidate instanceof NilObject) {
+                    message = Errors.format(Errors.Keys.NilObject_1, 
Identifiers.getNilReason((NilObject) candidate));
+                } else {
+                    message = 
Errors.format(Errors.Keys.NestedElementNotAllowed_1, getInterface(candidate));
+                }
+                throw new ClassCastException(message);
             }
         }
         return sameContent;
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java
index d16fde9d42..81f54b604e 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.java
@@ -654,6 +654,11 @@ public class Errors extends IndexedResourceBundle {
          */
         public static final short NestedElementNotAllowed_1 = 94;
 
+        /**
+         * The object is nil for the following reason: {0}.
+         */
+        public static final short NilObject_1 = 204;
+
         /**
          * No value is associated to “{0}”.
          */
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.properties
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.properties
index ee3182a5bc..46fab02978 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.properties
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors.properties
@@ -142,6 +142,7 @@ NativeInterfacesNotFound_2        = Native interfaces 
\u201c{1}\u201d not availa
 NegativeArgument_2                = Argument \u2018{0}\u2019 shall not be 
negative. The given value was {1}.
 NegativeArrayLength_1             = Cannot create a \u201c{0}\u201d array of 
negative length.
 NestedElementNotAllowed_1         = Nested \u201c{0}\u201d elements are not 
allowed.
+NilObject_1                       = The object is nil for the following 
reason: {0}.
 NodeChildOfItself_1               = Node \u201c{0}\u201d cannot be a child of 
itself.
 NodeHasAnotherParent_1            = Node \u201c{0}\u201d already has another 
parent.
 NodeHasNoParent_1                 = Node \u201c{0}\u201d has no parent.
diff --git 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors_fr.properties
 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors_fr.properties
index 0abec550f7..c5cb2922ab 100644
--- 
a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors_fr.properties
+++ 
b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/resources/Errors_fr.properties
@@ -139,6 +139,7 @@ NativeInterfacesNotFound_2        = Les interfaces natives 
\u00ab\u202f{1}\u202f
 NegativeArgument_2                = L\u2019argument \u2018{0}\u2019 ne doit 
pas \u00eatre n\u00e9gatif. La valeur donn\u00e9e \u00e9tait {1}.
 NegativeArrayLength_1             = Ne peut pas cr\u00e9er un tableau 
\u00ab\u202f{0}\u202f\u00bb de longueur n\u00e9gative.
 NestedElementNotAllowed_1         = L\u2019imbrication 
d\u2019\u00e9l\u00e9ments \u00ab\u202f{0}\u202f\u00bb n\u2019est pas 
autoris\u00e9e.
+NilObject_1                       = L\u2019objet est nul pour la raison 
suivante\u00a0: {0}.
 NodeChildOfItself_1               = Le n\u0153ud \u00ab\u202f{0}\u202f\u00bb 
ne peut pas \u00eatre un enfant de lui-m\u00eame.
 NodeHasAnotherParent_1            = Le n\u0153ud \u00ab\u202f{0}\u202f\u00bb a 
d\u00e9j\u00e0 un autre parent.
 NodeHasNoParent_1                 = Le n\u0153ud \u00ab\u202f{0}\u202f\u00bb 
n\u2019a pas de parent.

Reply via email to