You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2017/05/23 15:18:44 UTC

svn commit: r1795919 - in /sis/branches/JDK8/core/sis-feature/src: main/java/org/apache/sis/feature/ test/java/org/apache/sis/feature/

Author: desruisseaux
Date: Tue May 23 15:18:44 2017
New Revision: 1795919

URL: http://svn.apache.org/viewvc?rev=1795919&view=rev
Log:
Clarify the error message and stack trace in case of invalid property.

Modified:
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java
    sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java?rev=1795919&r1=1795918&r2=1795919&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java [UTF-8] Tue May 23 15:18:44 2017
@@ -21,6 +21,7 @@ import java.util.Iterator;
 import java.util.Collection;
 import java.util.Collections;
 import java.io.Serializable;
+import org.opengis.util.ScopedName;
 import org.opengis.util.GenericName;
 import org.opengis.metadata.quality.DataQuality;
 import org.opengis.metadata.maintenance.ScopeCode;
@@ -242,7 +243,7 @@ public abstract class AbstractFeature im
         } else if (pt instanceof FeatureAssociationRole) {
             return ((FeatureAssociationRole) pt).newInstance();
         } else {
-            throw unsupportedPropertyType(pt.getName());
+            throw new IllegalArgumentException(unsupportedPropertyType(pt.getName()));
         }
     }
 
@@ -277,7 +278,7 @@ public abstract class AbstractFeature im
             final int maximumOccurs = ((FeatureAssociationRole) pt).getMaximumOccurs();
             return maximumOccurs > 1 ? Collections.EMPTY_LIST : null;       // No default value for associations.
         } else {
-            throw unsupportedPropertyType(pt.getName());
+            throw new IllegalArgumentException(unsupportedPropertyType(pt.getName()));
         }
     }
 
@@ -445,7 +446,7 @@ public abstract class AbstractFeature im
         } else if (property instanceof FeatureAssociation) {
             setAssociationValue((FeatureAssociation) property, value);
         } else {
-            throw unsupportedPropertyType(property.getName());
+            throw new IllegalArgumentException(unsupportedPropertyType(property.getName()));
         }
     }
 
@@ -473,7 +474,7 @@ public abstract class AbstractFeature im
                     } while ((element = it.next()) == null || base.isInstance(element));
                     // Found an illegal value. Exeption is thrown below.
                 }
-                throw illegalValueClass(pt, base, element);         // 'element' can not be null here.
+                throw new ClassCastException(illegalValueClass(pt, base, element));         // 'element' can not be null here.
             }
         }
         ((Attribute) attribute).setValue(value);
@@ -491,14 +492,14 @@ public abstract class AbstractFeature im
             if (value instanceof Feature) {
                 final FeatureType actual = ((Feature) value).getType();
                 if (base != actual && !DefaultFeatureType.maybeAssignableFrom(base, actual)) {
-                    throw illegalFeatureType(role, base, actual);
+                    throw new InvalidPropertyValueException(illegalFeatureType(role, base, actual));
                 }
             } else if (value instanceof Collection<?>) {
                 verifyAssociationValues(role, (Collection<?>) value);
                 association.setValues((Collection<? extends Feature>) value);
                 return;                                 // Skip the setter at the end of this method.
             } else {
-                throw illegalValueClass(role, Feature.class, value);
+                throw new ClassCastException(illegalValueClass(role, Feature.class, value));
             }
         }
         association.setValue((Feature) value);
@@ -565,7 +566,7 @@ public abstract class AbstractFeature im
                 return verifyAssociationValue((FeatureAssociationRole) pt, value);
             }
         } else {
-            throw unsupportedPropertyType(pt.getName());
+            throw new IllegalArgumentException(unsupportedPropertyType(pt.getName()));
         }
         return value;
     }
@@ -588,7 +589,7 @@ public abstract class AbstractFeature im
         } else if (!isSingleton && value instanceof Collection<?>) {
             return CheckedArrayList.castOrCopy((Collection<?>) value, valueClass);
         } else {
-            throw illegalValueClass(type, valueClass, value);
+            throw new ClassCastException(illegalValueClass(type, valueClass, value));
         }
     }
 
@@ -614,13 +615,13 @@ public abstract class AbstractFeature im
             if (base == valueType || DefaultFeatureType.maybeAssignableFrom(base, valueType)) {
                 return isSingleton ? value : singletonList(Feature.class, role.getMinimumOccurs(), value);
             } else {
-                throw illegalFeatureType(role, base, valueType);
+                throw new InvalidPropertyValueException(illegalFeatureType(role, base, valueType));
             }
         } else if (!isSingleton && value instanceof Collection<?>) {
             verifyAssociationValues(role, (Collection<?>) value);
             return CheckedArrayList.castOrCopy((Collection<?>) value, Feature.class);
         } else {
-            throw illegalValueClass(role, Feature.class, value);
+            throw new ClassCastException(illegalValueClass(role, Feature.class, value));
         }
     }
 
@@ -633,11 +634,11 @@ public abstract class AbstractFeature im
         for (final Object value : values) {
             ArgumentChecks.ensureNonNullElement("values", index, value);
             if (!(value instanceof Feature)) {
-                throw illegalValueClass(role, Feature.class, value);
+                throw new ClassCastException(illegalValueClass(role, Feature.class, value));
             }
             final FeatureType type = ((Feature) value).getType();
             if (base != type && !DefaultFeatureType.maybeAssignableFrom(base, type)) {
-                throw illegalFeatureType(role, base, type);
+                throw new InvalidPropertyValueException(illegalFeatureType(role, base, type));
             }
             index++;
         }
@@ -655,34 +656,57 @@ public abstract class AbstractFeature im
     }
 
     /**
-     * Returns the exception for a property type which is neither an attribute or an association.
+     * Returns the exception message for a property not found. The message will differ depending
+     * on whether the property is not found because ambiguous or because it does not exist.
+     *
+     * @param  feature   the name of the feature where a property where searched ({@link String} or {@link GenericName}).
+     * @param  property  the name of the property which has not been found.
+     */
+    static String propertyNotFound(final FeatureType type, final Object feature, final String property) {
+        GenericName ambiguous = null;
+        for (final IdentifiedType p : type.getProperties(true)) {
+            final GenericName next = p.getName();
+            GenericName name = next;
+            do {
+                if (property.equalsIgnoreCase(name.toString())) {
+                    if (ambiguous == null) {
+                        ambiguous = next;
+                    } else {
+                        return Errors.format(Errors.Keys.AmbiguousName_3, ambiguous, next, property);
+                    }
+                }
+            } while (name instanceof ScopedName && (name = ((ScopedName) name).tail()) != null);
+        }
+        return Resources.format(Resources.Keys.PropertyNotFound_2, feature, property);
+    }
+
+    /**
+     * Returns the exception message for a property type which is neither an attribute or an association.
      * This method is invoked after a {@link PropertyType} has been found for the user-supplied name,
      * but that property can not be stored in or extracted from a {@link Property} instance.
      */
-    static IllegalArgumentException unsupportedPropertyType(final GenericName name) {
-        return new IllegalArgumentException(Resources.format(Resources.Keys.CanNotInstantiateProperty_1, name));
+    static String unsupportedPropertyType(final GenericName name) {
+        return Resources.format(Resources.Keys.CanNotInstantiateProperty_1, name);
     }
 
     /**
-     * Returns the exception for a property value of wrong Java class.
+     * Returns the exception message for a property value of wrong Java class.
      *
      * @param  value  the value, which shall be non-null.
      */
-    private static ClassCastException illegalValueClass(
-            final IdentifiedType property, final Class<?> expected, final Object value)
-    {
-        return new ClassCastException(Resources.format(Resources.Keys.IllegalPropertyValueClass_3,
-                property.getName(), expected, value.getClass()));
+    private static String illegalValueClass(final IdentifiedType property, final Class<?> expected, final Object value) {
+        return Resources.format(Resources.Keys.IllegalPropertyValueClass_3,
+                                property.getName(), expected, value.getClass());
     }
 
     /**
-     * Returns the exception for an association value of wrong type.
+     * Returns the exception message for an association value of wrong type.
      */
-    private static InvalidPropertyValueException illegalFeatureType(
+    private static String illegalFeatureType(
             final FeatureAssociationRole association, final FeatureType expected, final FeatureType actual)
     {
-        return new InvalidPropertyValueException(Resources.format(Resources.Keys.IllegalFeatureType_3,
-                association.getName(), expected.getName(), actual.getName()));
+        return Resources.format(Resources.Keys.IllegalFeatureType_3,
+                                association.getName(), expected.getName(), actual.getName());
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java?rev=1795919&r1=1795918&r2=1795919&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java [UTF-8] Tue May 23 15:18:44 2017
@@ -822,7 +822,7 @@ public class DefaultFeatureType extends
         if (pt != null) {
             return pt;
         }
-        throw new PropertyNotFoundException(Resources.format(Resources.Keys.PropertyNotFound_2, getName(), name));
+        throw new PropertyNotFoundException(AbstractFeature.propertyNotFound(this, getName(), name));
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java?rev=1795919&r1=1795918&r2=1795919&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java [UTF-8] Tue May 23 15:18:44 2017
@@ -20,7 +20,6 @@ import java.util.Map;
 import java.util.Arrays;
 import org.opengis.metadata.maintenance.ScopeCode;
 import org.opengis.metadata.quality.DataQuality;
-import org.apache.sis.internal.feature.Resources;
 import org.apache.sis.internal.util.Cloner;
 import org.apache.sis.util.ArgumentChecks;
 
@@ -93,7 +92,7 @@ final class DenseFeature extends Abstrac
         if (index != null) {
             return index;
         }
-        throw new PropertyNotFoundException(Resources.format(Resources.Keys.PropertyNotFound_2, getName(), name));
+        throw new PropertyNotFoundException(propertyNotFound(type, getName(), name));
     }
 
     /**
@@ -196,7 +195,7 @@ final class DenseFeature extends Abstrac
                 } else if (element instanceof FeatureAssociation) {
                     return getAssociationValue((FeatureAssociation) element);
                 } else {
-                    throw unsupportedPropertyType(((Property) element).getName());
+                    throw new IllegalArgumentException(unsupportedPropertyType(((Property) element).getName()));
                 }
             }
         }

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java?rev=1795919&r1=1795918&r2=1795919&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java [UTF-8] Tue May 23 15:18:44 2017
@@ -22,7 +22,6 @@ import java.util.Objects;
 import java.util.ConcurrentModificationException;
 import org.opengis.metadata.maintenance.ScopeCode;
 import org.opengis.metadata.quality.DataQuality;
-import org.apache.sis.internal.feature.Resources;
 import org.apache.sis.internal.util.Cloner;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.CorruptedObjectException;
@@ -128,7 +127,7 @@ final class SparseFeature extends Abstra
         if (index != null) {
             return index;
         }
-        throw new PropertyNotFoundException(Resources.format(Resources.Keys.PropertyNotFound_2, getName(), name));
+        throw new PropertyNotFoundException(propertyNotFound(type, getName(), name));
     }
 
     /**
@@ -243,7 +242,7 @@ final class SparseFeature extends Abstra
             } else if (element instanceof FeatureAssociation) {
                 return getAssociationValue((FeatureAssociation) element);
             } else if (valuesKind == PROPERTIES) {
-                throw unsupportedPropertyType(((Property) element).getName());
+                throw new IllegalArgumentException(unsupportedPropertyType(((Property) element).getName()));
             } else {
                 throw new CorruptedObjectException(getName());
             }

Modified: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java?rev=1795919&r1=1795918&r2=1795919&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java [UTF-8] Tue May 23 15:18:44 2017
@@ -353,6 +353,15 @@ public final strictfp class DefaultFeatu
         } catch (IllegalArgumentException e) {
             final String message = e.getMessage();
             assertTrue(message, message.contains("name"));      // Property name.
+            assertTrue(message, message.contains("ns1:name"));  // Ambiguity 1.
+            assertTrue(message, message.contains("ns2:name"));  // Ambiguity 2.
+        }
+        try {
+            feature.getProperty("other");
+            fail("Expected no property.");
+        } catch (IllegalArgumentException e) {
+            final String message = e.getMessage();
+            assertTrue(message, message.contains("other"));     // Property name.
             assertTrue(message, message.contains("City"));      // Feature name.
         }
     }