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.