sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1686280 [1/4] - in /sis/branches/JDK6: ./ core/sis-feature/src/main/java/org/apache/sis/feature/ core/sis-feature/src/test/java/org/apache/sis/feature/ core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ core/sis-metadata/src...
Date Thu, 18 Jun 2015 17:15:31 GMT
Author: desruisseaux
Date: Thu Jun 18 17:15:30 2015
New Revision: 1686280

URL: http://svn.apache.org/r1686280
Log:
Merge from the JDK7 branch Feature bug fixes and WKT 2 partial work.

Added:
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
      - copied, changed from r1686269, sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Parser.java
      - copied unchanged from r1686269, sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Parser.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/VerticalInfo.java
      - copied unchanged from r1686269, sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/VerticalInfo.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java
      - copied, changed from r1686269, sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java
Removed:
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/WKTParser.java
Modified:
    sis/branches/JDK6/   (props changed)
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAssociation.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAttribute.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicMap.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/Field.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAssociation.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAttribute.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/NamedFeatureType.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/SingletonAssociation.java
    sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java
    sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java
    sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/WKTKeywords.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Element.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/FormattableObject.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/package-info.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultIdentifier.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicDescription.java
    sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
    sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/io/wkt/ElementTest.java
    sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java
    sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/mock/VerticalCRSMock.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AxesConvention.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
    sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultCompoundCRSTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultTemporalCRSTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
    sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/Characters.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
    sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
    sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java

Propchange: sis/branches/JDK6/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Jun 18 17:15:30 2015
@@ -1,4 +1,4 @@
 /sis/branches/Android:1430670-1480699
-/sis/branches/JDK7:1394913-1684688
-/sis/branches/JDK8:1584960-1684685
+/sis/branches/JDK7:1394913-1686269
+/sis/branches/JDK8:1584960-1686266
 /sis/trunk:1394364-1508466,1519089-1519674

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAssociation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAssociation.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAssociation.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAssociation.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -30,6 +30,8 @@ import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
 import org.opengis.feature.FeatureAssociation;
 import org.opengis.feature.FeatureAssociationRole;
+import org.opengis.feature.InvalidPropertyValueException;
+import org.opengis.feature.MultiValuedPropertyException;
 
 
 /**
@@ -47,7 +49,7 @@ import org.opengis.feature.FeatureAssoci
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  *
  * @see DefaultAssociationRole#newInstance()
@@ -130,12 +132,12 @@ public abstract class AbstractAssociatio
      * features is restricted to 1 or 0.
      *
      * @return The associated feature (may be {@code null}).
-     * @throws IllegalStateException if this association contains more than one value.
+     * @throws MultiValuedPropertyException if this association contains more than one value.
      *
      * @see AbstractFeature#getPropertyValue(String)
      */
     @Override
-    public abstract Feature getValue();
+    public abstract Feature getValue() throws MultiValuedPropertyException;
 
     /**
      * Returns all features, or an empty collection if none.
@@ -162,12 +164,12 @@ public abstract class AbstractAssociatio
      * A more exhaustive verification can be performed by invoking the {@link #quality()} method.
      *
      * @param  value The new value, or {@code null}.
-     * @throws IllegalArgumentException If the given feature is not valid for this association.
+     * @throws InvalidPropertyValueException If the given feature is not valid for this association.
      *
      * @see AbstractFeature#setPropertyValue(String, Object)
      */
     @Override
-    public abstract void setValue(final Feature value) throws IllegalArgumentException;
+    public abstract void setValue(final Feature value) throws InvalidPropertyValueException;
 
     /**
      * Sets the features. All previous values are replaced by the given collection.
@@ -176,10 +178,10 @@ public abstract class AbstractAssociatio
      * then delegates to {@link #setValue(Feature)}.</p>
      *
      * @param  values The new values.
-     * @throws IllegalArgumentException if the given collection contains too many elements.
+     * @throws InvalidPropertyValueException if the given collection contains too many elements.
      */
     @Override
-    public void setValues(final Collection<? extends Feature> values) throws IllegalArgumentException {
+    public void setValues(final Collection<? extends Feature> values) throws InvalidPropertyValueException {
         super.setValues(values);
     }
 
@@ -189,7 +191,7 @@ public abstract class AbstractAssociatio
      */
     final void ensureValid(final FeatureType base, final FeatureType type) {
         if (base != type && !DefaultFeatureType.maybeAssignableFrom(base, type)) {
-            throw new IllegalArgumentException(
+            throw new InvalidPropertyValueException(
                     Errors.format(Errors.Keys.IllegalArgumentClass_3, getName(), base.getName(), type.getName()));
         }
     }

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAttribute.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAttribute.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAttribute.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAttribute.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -35,6 +35,8 @@ import org.apache.sis.util.ArgumentCheck
 // Branch-dependent imports
 import org.opengis.feature.Attribute;
 import org.opengis.feature.AttributeType;
+import org.opengis.feature.InvalidPropertyValueException;
+import org.opengis.feature.MultiValuedPropertyException;
 import org.apache.sis.internal.jdk7.JDK7;
 
 
@@ -68,7 +70,7 @@ import org.apache.sis.internal.jdk7.JDK7
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  *
  * @see DefaultAttributeType#newInstance()
@@ -207,12 +209,12 @@ public abstract class AbstractAttribute<
      * of attribute values is restricted to 1 or 0.
      *
      * @return The attribute value (may be {@code null}).
-     * @throws IllegalStateException if this attribute contains more than one value.
+     * @throws MultiValuedPropertyException if this attribute contains more than one value.
      *
      * @see AbstractFeature#getPropertyValue(String)
      */
     @Override
-    public abstract V getValue() throws IllegalStateException;
+    public abstract V getValue() throws MultiValuedPropertyException;
 
     /**
      * Returns all attribute values, or an empty collection if none.
@@ -252,10 +254,10 @@ public abstract class AbstractAttribute<
      * then delegates to {@link #setValue(Object)}.</p>
      *
      * @param  values The new values.
-     * @throws IllegalArgumentException if the given collection contains too many elements.
+     * @throws InvalidPropertyValueException if the given collection contains too many elements.
      */
     @Override
-    public void setValues(final Collection<? extends V> values) throws IllegalArgumentException {
+    public void setValues(final Collection<? extends V> values) throws InvalidPropertyValueException {
         super.setValues(values);
     }
 

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -31,6 +31,8 @@ import org.apache.sis.internal.util.Chec
 // Branch-dependent imports
 import org.opengis.feature.Property;
 import org.opengis.feature.PropertyType;
+import org.opengis.feature.PropertyNotFoundException;
+import org.opengis.feature.InvalidPropertyValueException;
 import org.opengis.feature.Attribute;
 import org.opengis.feature.AttributeType;
 import org.opengis.feature.Feature;
@@ -130,13 +132,13 @@ public abstract class AbstractFeature im
      *
      * @param  name The property name.
      * @return The property of the given name (never {@code null}).
-     * @throws IllegalArgumentException If the given argument is not a property name of this feature.
+     * @throws PropertyNotFoundException if the given argument is not a property name of this feature.
      *
      * @see #getPropertyValue(String)
      * @see DefaultFeatureType#getProperty(String)
      */
     @Override
-    public abstract Property getProperty(final String name) throws IllegalArgumentException;
+    public abstract Property getProperty(final String name) throws PropertyNotFoundException;
 
     /**
      * Sets the property (attribute or feature association).
@@ -159,8 +161,9 @@ public abstract class AbstractFeature im
      * the {@link #setPropertyValue(String, Object)} method is preferred.</div>
      *
      * @param  property The property to set.
-     * @throws IllegalArgumentException if the type of the given property is not one of the types
-     *         known to this feature, or if the property can not be set of an other reason.
+     * @throws PropertyNotFoundException if the name of the given property is not a property name of this feature.
+     * @throws InvalidPropertyValueException if the value of the given property is not valid.
+     * @throws IllegalArgumentException if the property can not be set for another reason.
      *
      * @see #setPropertyValue(String, Object)
      */
@@ -193,11 +196,10 @@ public abstract class AbstractFeature im
      *
      * @param  name The name of the property to create.
      * @return A {@code Property} of the given name.
-     * @throws IllegalArgumentException If the given argument is not the name of an attribute or
+     * @throws PropertyNotFoundException if the given argument is not the name of an attribute or
      *         feature association of this feature.
      */
-    @SuppressWarnings({"unchecked","rawtypes"})
-    final Property createProperty(final String name) throws IllegalArgumentException {
+    final Property createProperty(final String name) throws PropertyNotFoundException {
         final PropertyType pt = type.getProperty(name);
         if (pt instanceof AttributeType<?>) {
             return ((AttributeType<?>) pt).newInstance();
@@ -262,9 +264,9 @@ public abstract class AbstractFeature im
      *
      * @param  name The name of the property for which to get the default value.
      * @return The default value for the {@code Property} of the given name.
-     * @throws IllegalArgumentException If the given argument is not an attribute or association name of this feature.
+     * @throws PropertyNotFoundException if the given argument is not an attribute or association name of this feature.
      */
-    final Object getDefaultValue(final String name) throws IllegalArgumentException {
+    final Object getDefaultValue(final String name) throws PropertyNotFoundException {
         final PropertyType pt = type.getProperty(name);
         if (pt instanceof AttributeType<?>) {
             return getDefaultValue((AttributeType<?>) pt);
@@ -308,12 +310,12 @@ public abstract class AbstractFeature im
      *
      * @param  name The property name.
      * @return The value for the given property, or {@code null} if none.
-     * @throws IllegalArgumentException If the given argument is not an attribute or association name of this feature.
+     * @throws PropertyNotFoundException if the given argument is not an attribute or association name of this feature.
      *
      * @see AbstractAttribute#getValue()
      */
     @Override
-    public abstract Object getPropertyValue(final String name) throws IllegalArgumentException;
+    public abstract Object getPropertyValue(final String name) throws PropertyNotFoundException;
 
     /**
      * Sets the value for the property of the given name.
@@ -326,8 +328,9 @@ public abstract class AbstractFeature im
      *
      * @param  name  The attribute name.
      * @param  value The new value for the given attribute (may be {@code null}).
-     * @throws ClassCastException If the value is not assignable to the expected value class.
-     * @throws IllegalArgumentException If the given value can not be assigned for an other reason.
+     * @throws PropertyNotFoundException if the given name is not an attribute or association name of this feature.
+     * @throws ClassCastException if the value is not assignable to the expected value class.
+     * @throws InvalidPropertyValueException if the given value is not valid for a reason other than its type.
      *
      * @see AbstractAttribute#setValue(Object)
      */
@@ -456,9 +459,11 @@ public abstract class AbstractFeature im
             throw illegalPropertyType(base.getName(), property.getClass());
         }
         if (pt != base) {
-            throw new IllegalArgumentException(base == null
-                    ? Errors.format(Errors.Keys.PropertyNotFound_2, getName(), name)
-                    : Errors.format(Errors.Keys.MismatchedPropertyType_1, name));
+            if (base == null) {
+                throw new PropertyNotFoundException(Errors.format(Errors.Keys.PropertyNotFound_2, getName(), name));
+            } else {
+                throw new InvalidPropertyValueException(Errors.format(Errors.Keys.MismatchedPropertyType_1, name));
+            }
         }
     }
 
@@ -567,9 +572,9 @@ public abstract class AbstractFeature im
     }
 
     /**
-     * Returns the exception for a property type which neither an attribute or an association.
+     * Returns the exception 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 a {@link Property} instance.
+     * but that property can not be stored in or extracted from a {@link Property} instance.
      */
     static IllegalArgumentException unsupportedPropertyType(final GenericName name) {
         return new IllegalArgumentException(Errors.format(Errors.Keys.CanNotInstantiate_1, name));
@@ -587,8 +592,8 @@ public abstract class AbstractFeature im
     /**
      * Returns the exception for a property value (usually a feature) of wrong type.
      */
-    private static IllegalArgumentException illegalPropertyType(final GenericName name, final Object value) {
-        return new IllegalArgumentException(Errors.format(Errors.Keys.IllegalPropertyClass_2, name, value));
+    private static InvalidPropertyValueException illegalPropertyType(final GenericName name, final Object value) {
+        return new InvalidPropertyValueException(Errors.format(Errors.Keys.IllegalPropertyClass_2, name, value));
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -38,7 +38,7 @@ import org.opengis.feature.IdentifiedTyp
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  */
 public class AbstractIdentifiedType implements IdentifiedType, Serializable {
@@ -165,9 +165,7 @@ public class AbstractIdentifiedType impl
      * @param  identification The name and other information to be given to this identified type.
      * @throws IllegalArgumentException if a property has an invalid value.
      */
-    protected AbstractIdentifiedType(final Map<String,?> identification)
-            throws IllegalArgumentException
-    {
+    protected AbstractIdentifiedType(final Map<String,?> identification) throws IllegalArgumentException {
         ensureNonNull("identification", identification);
         Object value = identification.get(NAME_KEY);
         if (value == null) {

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicMap.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicMap.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicMap.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/CharacteristicMap.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -27,6 +27,8 @@ import org.apache.sis.internal.util.Abst
 // Branch-dependent imports
 import org.opengis.feature.Attribute;
 import org.opengis.feature.AttributeType;
+import org.opengis.feature.InvalidPropertyValueException;
+import org.opengis.feature.PropertyNotFoundException;
 
 
 /**
@@ -35,7 +37,7 @@ import org.opengis.feature.AttributeType
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  */
 final class CharacteristicMap extends AbstractMap<String,Attribute<?>> implements Cloneable {
@@ -166,13 +168,13 @@ final class CharacteristicMap extends Ab
      *
      * @param  key The name for which to get the characteristic index.
      * @return The index for the characteristic of the given name.
-     * @throws IllegalArgumentException if the given key is not the name of a characteristic in this map.
+     * @throws PropertyNotFoundException if the given key is not the name of a characteristic in this map.
      */
     private int indexOf(final String key) {
         ArgumentChecks.ensureNonNull("key", key);
         final Integer index = types.indices.get(key);
         if (index == null) {
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.PropertyNotFound_2, source.getName(), key));
+            throw new PropertyNotFoundException(Errors.format(Errors.Keys.PropertyNotFound_2, source.getName(), key));
         }
         return index;
     }
@@ -190,7 +192,7 @@ final class CharacteristicMap extends Ab
         if (!expected.equals(type)) {
             final GenericName en = expected.getName();
             final GenericName an = type.getName();
-            throw new IllegalArgumentException(String.valueOf(en).equals(String.valueOf(an))
+            throw new InvalidPropertyValueException(String.valueOf(en).equals(String.valueOf(an))
                     ? Errors.format(Errors.Keys.MismatchedPropertyType_1, en)
                     : Errors.format(Errors.Keys.CanNotAssign_2, en.push(source.getName()), an));
         }

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -47,6 +47,8 @@ import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
 import org.opengis.feature.FeatureAssociationRole;
 import org.opengis.feature.Operation;
+import org.opengis.feature.FeatureInstantiationException;
+import org.opengis.feature.PropertyNotFoundException;
 
 
 /**
@@ -607,7 +609,7 @@ public class DefaultFeatureType extends
             final PropertyType other;
             try {
                 other = type.getProperty(entry.getKey());
-            } catch (IllegalArgumentException e) {
+            } catch (PropertyNotFoundException e) {
                 /*
                  * A property in this FeatureType does not exist in the given FeatureType.
                  * Catching exceptions is not an efficient way to perform this check, but
@@ -713,17 +715,17 @@ public class DefaultFeatureType extends
      *
      * @param  name The name of the property to search.
      * @return The property for the given name, or {@code null} if none.
-     * @throws IllegalArgumentException If the given argument is not a property name of this feature.
+     * @throws PropertyNotFoundException If the given argument is not a property name of this feature.
      *
      * @see AbstractFeature#getProperty(String)
      */
     @Override
-    public PropertyType getProperty(final String name) throws IllegalArgumentException {
+    public PropertyType getProperty(final String name) throws PropertyNotFoundException {
         final PropertyType pt = byName.get(name);
         if (pt != null) {
             return pt;
         }
-        throw new IllegalArgumentException(Errors.format(Errors.Keys.PropertyNotFound_2, getName(), name));
+        throw new PropertyNotFoundException(Errors.format(Errors.Keys.PropertyNotFound_2, getName(), name));
     }
 
     /**
@@ -742,12 +744,12 @@ public class DefaultFeatureType extends
      * then this method is equivalent to {@link Class#newInstance()}.</div>
      *
      * @return A new feature instance.
-     * @throws IllegalStateException if this feature type {@linkplain #isAbstract() is abstract}.
+     * @throws FeatureInstantiationException if this feature type {@linkplain #isAbstract() is abstract}.
      */
     @Override
-    public Feature newInstance() throws IllegalStateException {
+    public Feature newInstance() throws FeatureInstantiationException {
         if (isAbstract) {
-            throw new IllegalStateException(Errors.format(Errors.Keys.AbstractType_1, getName()));
+            throw new FeatureInstantiationException(Errors.format(Errors.Keys.AbstractType_1, getName()));
         }
         return isSparse ? new SparseFeature(this) : new DenseFeature(this);
     }

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/DenseFeature.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -28,6 +28,7 @@ import org.apache.sis.util.resources.Err
 import org.opengis.feature.Property;
 import org.opengis.feature.Attribute;
 import org.opengis.feature.FeatureAssociation;
+import org.opengis.feature.PropertyNotFoundException;
 
 
 /**
@@ -84,14 +85,14 @@ final class DenseFeature extends Abstrac
      * @param  name The property name.
      * @return The index for the property of the given name,
      *         or a negative value if the property is a parameterless operation.
-     * @throws IllegalArgumentException If the given argument is not a property name of this feature.
+     * @throws PropertyNotFoundException if the given argument is not a property name of this feature.
      */
-    private int getIndex(final String name) throws IllegalArgumentException {
+    private int getIndex(final String name) throws PropertyNotFoundException {
         final Integer index = indices.get(name);
         if (index != null) {
             return index;
         }
-        throw new IllegalArgumentException(Errors.format(Errors.Keys.PropertyNotFound_2, getName(), name));
+        throw new PropertyNotFoundException(Errors.format(Errors.Keys.PropertyNotFound_2, getName(), name));
     }
 
     /**
@@ -99,10 +100,10 @@ final class DenseFeature extends Abstrac
      *
      * @param  name The property name.
      * @return The property of the given name.
-     * @throws IllegalArgumentException If the given argument is not a property name of this feature.
+     * @throws PropertyNotFoundException If the given argument is not a property name of this feature.
      */
     @Override
-    public Property getProperty(final String name) throws IllegalArgumentException {
+    public Property getProperty(final String name) throws PropertyNotFoundException {
         ArgumentChecks.ensureNonNull("name", name);
         final int index = getIndex(name);
         if (index < 0) {
@@ -132,7 +133,7 @@ final class DenseFeature extends Abstrac
      *
      * @param  property The property to set.
      * @throws IllegalArgumentException if the type of the given property is not one of the types
-     *         known to this feature.
+     *         known to this feature, or if the property can not be set or another reason.
      */
     @Override
     public void setProperty(final Property property) throws IllegalArgumentException {
@@ -175,10 +176,10 @@ final class DenseFeature extends Abstrac
      *
      * @param  name The property name.
      * @return The value for the given property, or {@code null} if none.
-     * @throws IllegalArgumentException If the given argument is not an attribute or association name of this feature.
+     * @throws PropertyNotFoundException If the given argument is not an attribute or association name of this feature.
      */
     @Override
-    public Object getPropertyValue(final String name) throws IllegalArgumentException {
+    public Object getPropertyValue(final String name) throws PropertyNotFoundException {
         ArgumentChecks.ensureNonNull("name", name);
         final int index = getIndex(name);
         if (index < 0) {
@@ -207,7 +208,7 @@ final class DenseFeature extends Abstrac
      * @param  name  The attribute name.
      * @param  value The new value for the given attribute (may be {@code null}).
      * @throws ClassCastException If the value is not assignable to the expected value class.
-     * @throws IllegalArgumentException If the given value can not be assigned for an other reason.
+     * @throws IllegalArgumentException If the given value can not be assigned for another reason.
      */
     @Override
     public void setPropertyValue(final String name, Object value) throws IllegalArgumentException {
@@ -290,12 +291,36 @@ final class DenseFeature extends Abstrac
 
     /**
      * Returns a hash code value for this feature.
+     * This implementation computes the hash code using only the property values, not the {@code Property} instances,
+     * in order to keep the hash code value stable before and after the {@code properties} array is promoted from the
+     * {@code Object[]} type to the {@code Property[]} type.
      *
      * @return A hash code value.
      */
     @Override
     public int hashCode() {
-        return type.hashCode() + 37 * Arrays.hashCode(properties);
+        int code = 1;
+        if (properties != null) {
+            if (properties instanceof Property[]) {
+                for (final Property p : (Property[]) properties) {
+                    code = 31 * code;
+                    final Object value;
+                    if (p instanceof Attribute<?>) {
+                        value = getAttributeValue((Attribute<?>) p);
+                    } else if (p instanceof FeatureAssociation) {
+                        value = getAssociationValue((FeatureAssociation) p);
+                    } else {
+                        continue;
+                    }
+                    if (value != null) {
+                        code += value.hashCode();
+                    }
+                }
+            } else {
+                code = Arrays.hashCode(properties);
+            }
+        }
+        return type.hashCode() + code;
     }
 
     /**
@@ -310,7 +335,17 @@ final class DenseFeature extends Abstrac
         }
         if (obj instanceof DenseFeature) {
             final DenseFeature that = (DenseFeature) obj;
-            return type.equals(that.type) && Arrays.equals(properties, that.properties);
+            if (type.equals(that.type)) {
+                final boolean asProperties = (properties instanceof Property[]);
+                if (asProperties != (that.properties instanceof Property[])) {
+                    if (asProperties) {
+                        that.wrapValuesInProperties();
+                    } else {
+                        wrapValuesInProperties();
+                    }
+                }
+                return Arrays.equals(properties, that.properties);
+            }
         }
         return false;
     }

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -16,6 +16,9 @@
  */
 package org.apache.sis.feature;
 
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
 import java.util.Locale;
 import java.util.TimeZone;
 import java.io.IOException;
@@ -71,7 +74,7 @@ import org.opengis.feature.Operation;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  */
 public class FeatureFormat extends TabularFormat<Object> {
@@ -285,19 +288,28 @@ header: for (int i=0; ; i++) {
              * Column 3 - Value or default value.
              */
             if (value != null) {
-                final Format format = getFormat(valueClass);
-                if (format != null) {
-                    value = format.format(value, buffer, dummyFP);
-                } else if (value instanceof Feature && propertyType instanceof FeatureAssociationRole) {
-                    final String p = DefaultAssociationRole.getTitleProperty((FeatureAssociationRole) propertyType);
-                    if (p != null) {
-                        value = ((Feature) value).getPropertyValue(p);
+                final boolean isInstance = valueClass != null && valueClass.isInstance(value);
+                final Format format = isInstance ? getFormat(valueClass) : null;
+                final Iterator<?> it = (!isInstance && (value instanceof Collection<?>)
+                        ? (Collection<?>) value : Collections.singleton(value)).iterator();
+                String separator = "";
+                while (it.hasNext()) {
+                    value = it.next();
+                    if (value != null) {
+                        if (format != null) {
+                            value = format.format(value, buffer, dummyFP);
+                        } else if (value instanceof Feature && propertyType instanceof FeatureAssociationRole) {
+                            final String p = DefaultAssociationRole.getTitleProperty((FeatureAssociationRole) propertyType);
+                            if (p != null) {
+                                value = ((Feature) value).getPropertyValue(p);
+                                if (value == null) continue;
+                            }
+                        }
+                        table.append(separator).append(formatValue(value));
+                        buffer.setLength(0);
+                        separator = ", ";
                     }
                 }
-                if (value != null) {
-                    table.append(formatValue(value));
-                }
-                buffer.setLength(0);
             }
             /*
              * Column 4 - Characteristics.

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/Field.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/Field.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/Field.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/Field.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -23,6 +23,9 @@ import org.apache.sis.util.resources.Err
 
 // Branch-dependent imports
 import org.opengis.feature.Property;
+import org.opengis.feature.MultiValuedPropertyException;
+import org.opengis.feature.InvalidPropertyValueException;
+
 
 /**
  * Base class of property that can be stored in a {@link AbstractFeature} instance.
@@ -30,7 +33,7 @@ import org.opengis.feature.Property;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  */
 abstract class Field<V> implements Property {
@@ -55,12 +58,12 @@ abstract class Field<V> implements Prope
      * Returns the field feature or attribute value, or {@code null} if none.
      *
      * @return The feature or attribute value (may be {@code null}).
-     * @throws IllegalStateException if this field contains more than one value.
+     * @throws MultiValuedPropertyException if this field contains more than one value.
      *
      * @see AbstractFeature#getPropertyValue(String)
      */
     @Override
-    public abstract V getValue() throws IllegalStateException;
+    public abstract V getValue() throws MultiValuedPropertyException;
 
     /**
      * Returns all features or attribute values, or an empty collection if none.
@@ -89,16 +92,16 @@ abstract class Field<V> implements Prope
      * then delegates to {@link #setValue(Object)}.</p>
      *
      * @param values The new values.
-     * @throws IllegalArgumentException if the given collection contains too many elements.
+     * @throws InvalidPropertyValueException if the given collection contains too many elements.
      */
-    public void setValues(final Collection<? extends V> values) throws IllegalArgumentException {
+    public void setValues(final Collection<? extends V> values) throws InvalidPropertyValueException {
         V value = null;
         ArgumentChecks.ensureNonNull("values", values);
         final Iterator<? extends V> it = values.iterator();
         if (it.hasNext()) {
             value = it.next();
             if (it.hasNext()) {
-                throw new IllegalArgumentException(Errors.format(Errors.Keys.TooManyOccurrences_2, 1, getName()));
+                throw new InvalidPropertyValueException(Errors.format(Errors.Keys.TooManyOccurrences_2, 1, getName()));
             }
         }
         setValue(value);

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAssociation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAssociation.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAssociation.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAssociation.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -25,6 +25,7 @@ import org.apache.sis.util.resources.Err
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
 import org.opengis.feature.FeatureAssociationRole;
+import org.opengis.feature.MultiValuedPropertyException;
 
 
 /**
@@ -44,7 +45,7 @@ import org.opengis.feature.FeatureAssoci
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  *
  * @see DefaultAssociationRole
@@ -89,14 +90,14 @@ final class MultiValuedAssociation exten
      * Returns the feature, or {@code null} if none.
      *
      * @return The feature (may be {@code null}).
-     * @throws IllegalStateException if this association contains more than one value.
+     * @throws MultiValuedPropertyException if this association contains more than one value.
      */
     @Override
     public Feature getValue() {
         switch (values.size()) {
             case 0:  return null;
             case 1:  return values.get(0);
-            default: throw new IllegalStateException(Errors.format(Errors.Keys.NotASingleton_1, getName()));
+            default: throw new MultiValuedPropertyException(Errors.format(Errors.Keys.NotASingleton_1, getName()));
         }
     }
 

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAttribute.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAttribute.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAttribute.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/MultiValuedAttribute.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -23,6 +23,7 @@ import org.apache.sis.util.resources.Err
 
 // Branch-dependent imports
 import org.opengis.feature.AttributeType;
+import org.opengis.feature.MultiValuedPropertyException;
 
 
 /**
@@ -45,7 +46,7 @@ import org.opengis.feature.AttributeType
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  *
  * @see DefaultAttributeType
@@ -89,10 +90,13 @@ final class MultiValuedAttribute<V> exte
         final Class<V> valueClass = type.getValueClass();
         if (values == null) {
             this.values = new CheckedArrayList<V>(valueClass);
-        } else if (((CheckedArrayList<?>) values).getElementType() == valueClass) {
-            this.values = (CheckedArrayList<V>) values;
         } else {
-            throw new ClassCastException();
+            final Class<?> actual = ((CheckedArrayList<?>) values).getElementType();
+            if (actual == valueClass) {
+                this.values = (CheckedArrayList<V>) values;
+            } else {
+                throw new ClassCastException(Errors.format(Errors.Keys.IllegalArgumentClass_3, "values", valueClass, actual));
+            }
         }
     }
 
@@ -100,14 +104,14 @@ final class MultiValuedAttribute<V> exte
      * Returns the attribute value, or {@code null} if none.
      *
      * @return The attribute value (may be {@code null}).
-     * @throws IllegalStateException if this attribute contains more than one value.
+     * @throws MultiValuedPropertyException if this attribute contains more than one value.
      */
     @Override
     public V getValue() {
         switch (values.size()) {
             case 0:  return null;
             case 1:  return values.get(0);
-            default: throw new IllegalStateException(Errors.format(Errors.Keys.NotASingleton_1, getName()));
+            default: throw new MultiValuedPropertyException(Errors.format(Errors.Keys.NotASingleton_1, getName()));
         }
     }
 

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/NamedFeatureType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/NamedFeatureType.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/NamedFeatureType.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/NamedFeatureType.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -23,6 +23,8 @@ import java.io.Serializable;
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
 import org.opengis.feature.PropertyType;
+import org.opengis.feature.PropertyNotFoundException;
+import org.opengis.feature.FeatureInstantiationException;
 import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.resources.Errors;
@@ -35,7 +37,7 @@ import org.apache.sis.util.resources.Err
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  */
 final class NamedFeatureType implements FeatureType, Serializable {
@@ -86,11 +88,11 @@ final class NamedFeatureType implements
     }
 
     /**
-     * Always throws {@link IllegalArgumentException} since this feature type has no declared property yet.
+     * Always throws {@link PropertyNotFoundException} since this feature type has no declared property yet.
      */
     @Override
-    public PropertyType getProperty(final String name) throws IllegalArgumentException {
-        throw new IllegalArgumentException(Errors.format(Errors.Keys.PropertyNotFound_2, getName(), name));
+    public PropertyType getProperty(final String name) throws PropertyNotFoundException {
+        throw new PropertyNotFoundException(Errors.format(Errors.Keys.PropertyNotFound_2, getName(), name));
     }
 
     /**
@@ -121,8 +123,8 @@ final class NamedFeatureType implements
      * Unsupported operation, since the feature has not yet been resolved.
      */
     @Override
-    public Feature newInstance() throws IllegalStateException {
-        throw new IllegalStateException(Errors.format(Errors.Keys.UnresolvedFeatureName_1, getName()));
+    public Feature newInstance() throws FeatureInstantiationException {
+        throw new FeatureInstantiationException(Errors.format(Errors.Keys.UnresolvedFeatureName_1, getName()));
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/SingletonAssociation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/SingletonAssociation.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/SingletonAssociation.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/SingletonAssociation.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -20,6 +20,7 @@ package org.apache.sis.feature;
 import org.apache.sis.internal.jdk7.Objects;
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureAssociationRole;
+import org.opengis.feature.InvalidPropertyValueException;
 
 
 /**
@@ -36,7 +37,7 @@ import org.opengis.feature.FeatureAssoci
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  *
  * @see DefaultAssociationRole
@@ -91,10 +92,10 @@ final class SingletonAssociation extends
      * Sets the associated feature.
      *
      * @param  value The new value, or {@code null}.
-     * @throws IllegalArgumentException If the given feature is not valid for this association.
+     * @throws InvalidPropertyValueException If the given feature is not valid for this association.
      */
     @Override
-    public void setValue(final Feature value) {
+    public void setValue(final Feature value) throws InvalidPropertyValueException {
         if (value != null) {
             ensureValid(role.getValueType(), value.getType());
         }

Modified: sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/SparseFeature.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -27,9 +27,11 @@ import org.apache.sis.util.CorruptedObje
 import org.apache.sis.util.resources.Errors;
 
 // Branch-dependent imports
+import org.apache.sis.internal.jdk7.Objects;
 import org.opengis.feature.Property;
 import org.opengis.feature.Attribute;
 import org.opengis.feature.FeatureAssociation;
+import org.opengis.feature.PropertyNotFoundException;
 
 
 /**
@@ -118,14 +120,14 @@ final class SparseFeature extends Abstra
      * @param  name The property name.
      * @return The index for the property of the given name,
      *         or a negative value if the property is a parameterless operation.
-     * @throws IllegalArgumentException If the given argument is not a property name of this feature.
+     * @throws PropertyNotFoundException If the given argument is not a property name of this feature.
      */
-    private int getIndex(final String name) throws IllegalArgumentException {
+    private int getIndex(final String name) throws PropertyNotFoundException {
         final Integer index = indices.get(name);
         if (index != null) {
             return index;
         }
-        throw new IllegalArgumentException(Errors.format(Errors.Keys.PropertyNotFound_2, getName(), name));
+        throw new PropertyNotFoundException(Errors.format(Errors.Keys.PropertyNotFound_2, getName(), name));
     }
 
     /**
@@ -170,10 +172,10 @@ final class SparseFeature extends Abstra
      *
      * @param  name The property name.
      * @return The property of the given name.
-     * @throws IllegalArgumentException If the given argument is not a property name of this feature.
+     * @throws PropertyNotFoundException If the given argument is not a property name of this feature.
      */
     @Override
-    public Property getProperty(final String name) throws IllegalArgumentException {
+    public Property getProperty(final String name) throws PropertyNotFoundException {
         ArgumentChecks.ensureNonNull("name", name);
         requireMapOfProperties();
         return getPropertyInstance(name);
@@ -183,7 +185,7 @@ final class SparseFeature extends Abstra
      * Implementation of {@link #getProperty(String)} invoked when we know that the {@link #properties}
      * map contains {@code Property} instances (as opposed to their value).
      */
-    private Property getPropertyInstance(final String name) throws IllegalArgumentException {
+    private Property getPropertyInstance(final String name) throws PropertyNotFoundException {
         assert valuesKind == PROPERTIES : valuesKind;
         final Integer index = getIndex(name);
         if (index < 0) {
@@ -202,7 +204,7 @@ final class SparseFeature extends Abstra
      *
      * @param  property The property to set.
      * @throws IllegalArgumentException if the type of the given property is not one of the types
-     *         known to this feature.
+     *         known to this feature, or if the property can not be set for another reason.
      */
     @Override
     public void setProperty(final Property property) throws IllegalArgumentException {
@@ -222,10 +224,10 @@ final class SparseFeature extends Abstra
      *
      * @param  name The property name.
      * @return The value for the given property, or {@code null} if none.
-     * @throws IllegalArgumentException If the given argument is not an attribute or association name of this feature.
+     * @throws PropertyNotFoundException If the given argument is not an attribute or association name of this feature.
      */
     @Override
-    public Object getPropertyValue(final String name) throws IllegalArgumentException {
+    public Object getPropertyValue(final String name) throws PropertyNotFoundException {
         ArgumentChecks.ensureNonNull("name", name);
         final Integer index = getIndex(name);
         if (index < 0) {
@@ -257,7 +259,7 @@ final class SparseFeature extends Abstra
      * @param  name  The attribute name.
      * @param  value The new value for the given attribute (may be {@code null}).
      * @throws ClassCastException If the value is not assignable to the expected value class.
-     * @throws IllegalArgumentException If the given value can not be assigned for an other reason.
+     * @throws IllegalArgumentException If the given value can not be assigned for another reason.
      */
     @Override
     public void setPropertyValue(final String name, final Object value) throws IllegalArgumentException {
@@ -360,12 +362,32 @@ final class SparseFeature extends Abstra
 
     /**
      * Returns a hash code value for this feature.
+     * This implementation computes the hash code using only the property values, not the {@code Property} instances,
+     * in order to keep the hash code value stable before and after the {@code properties} map is (conceptually)
+     * promoted from the {@code Map<Integer,Object>} type to the {@code Map<Integer,Property>} type.
      *
      * @return A hash code value.
      */
     @Override
     public int hashCode() {
-        return type.hashCode() + 37 * properties.hashCode();
+        int code = type.hashCode() * 37;
+        if (valuesKind == PROPERTIES) {
+            for (final Map.Entry<Integer,Object> entry : properties.entrySet()) {
+                final Object p = entry.getValue();
+                final Object value;
+                if (p instanceof Attribute<?>) {
+                    value = getAttributeValue((Attribute<?>) p);
+                } else if (p instanceof FeatureAssociation) {
+                    value = getAssociationValue((FeatureAssociation) p);
+                } else {
+                    value = null;
+                }
+                code += Objects.hashCode(entry.getKey()) ^ Objects.hashCode(value);
+            }
+        } else {
+            code += properties.hashCode();
+        }
+        return code;
     }
 
     /**
@@ -380,7 +402,17 @@ final class SparseFeature extends Abstra
         }
         if (obj instanceof SparseFeature) {
             final SparseFeature that = (SparseFeature) obj;
-            return type.equals(that.type) && properties.equals(that.properties);
+            if (type.equals(that.type)) {
+                final boolean asProperties = (valuesKind == PROPERTIES);
+                if (asProperties != (that.valuesKind == PROPERTIES)) {
+                    if (asProperties) {
+                        that.requireMapOfProperties();
+                    } else {
+                        requireMapOfProperties();
+                    }
+                }
+                return properties.equals(that.properties);
+            }
         }
         return false;
     }

Modified: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.feature;
 
+import java.util.Arrays;
 import java.util.Locale;
 import java.util.Random;
 import org.apache.sis.test.DependsOn;
@@ -31,7 +32,7 @@ import static org.apache.sis.test.Assert
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  */
 @DependsOn({
@@ -66,7 +67,47 @@ public final strictfp class FeatureForma
     @Test
     public void testFeature() {
         final Random random = TestUtilities.createRandomNumberGenerator();
-        final AbstractFeature feature = FeatureTestCase.twinTown(random.nextBoolean());
+        final boolean isSparse = random.nextBoolean();
+
+        final DefaultFeatureType type = DefaultFeatureTypeTest.worldMetropolis();
+        final AbstractFeature feature = isSparse ? new SparseFeature(type) : new DenseFeature(type);
+        feature.setPropertyValue("city", "Tokyo");
+        feature.setPropertyValue("population", 13185502); // In 2011.
+        feature.setPropertyValue("universities", Arrays.asList("Waseda", "Keio"));
+
+        final FeatureFormat format = new FeatureFormat(Locale.US, null);
+        final String text = format.format(feature);
+        assertMultilinesEquals("World metropolis\n" +
+                "┌──────────────┬─────────────────────┬─────────────┬──────────────┬─────────────────┐\n" +
+                "│ Name         │ Type                │ Cardinality │ Value        │ Characteristics │\n" +
+                "├──────────────┼─────────────────────┼─────────────┼──────────────┼─────────────────┤\n" +
+                "│ city         │ String              │ [1 … 1]     │ Tokyo        │                 │\n" +
+                "│ population   │ Integer             │ [1 … 1]     │ 13,185,502   │                 │\n" +
+                "│ region       │ InternationalString │ [1 … 1]     │              │                 │\n" +
+                "│ isGlobal     │ Boolean             │ [1 … 1]     │              │                 │\n" +
+                "│ universities │ String              │ [0 … ∞]     │ Waseda, Keio │                 │\n" +
+                "│ temperature  │ Float               │ [1 … 1]     │              │ accuracy, units │\n" +
+                "└──────────────┴─────────────────────┴─────────────┴──────────────┴─────────────────┘\n", text);
+    }
+
+    /**
+     * Tests the formatting of an {@link AbstractFeature} with an association to another feature of the same type.
+     */
+    @Test
+    public void testFeatureWithAssociation() {
+        final Random random = TestUtilities.createRandomNumberGenerator();
+        final boolean isSparse = random.nextBoolean();
+
+        final DefaultFeatureType type = DefaultAssociationRoleTest.twinTownCity(false);
+        final AbstractFeature twinTown = isSparse ? new SparseFeature(type) : new DenseFeature(type);
+        twinTown.setPropertyValue("city", "Le Mans");
+        twinTown.setPropertyValue("population", 143240); // In 2011.
+
+        final AbstractFeature feature = isSparse ? new SparseFeature(type) : new DenseFeature(type);
+        feature.setPropertyValue("city", "Paderborn");
+        feature.setPropertyValue("population", 143174); // December 31th, 2011
+        feature.setPropertyValue("twin town", twinTown);
+
         final FeatureFormat format = new FeatureFormat(Locale.US, null);
         final String text = format.format(feature);
         assertMultilinesEquals("Twin town\n" +

Modified: sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureTestCase.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -38,7 +38,7 @@ import static org.apache.sis.test.Assert
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Marc le Bihan
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  */
 public abstract strictfp class FeatureTestCase extends TestCase {
@@ -60,23 +60,6 @@ public abstract strictfp class FeatureTe
     }
 
     /**
-     * Creates a feature for twin towns.
-     */
-    static AbstractFeature twinTown(final boolean isSparse) {
-        final DefaultFeatureType twinTown = DefaultAssociationRoleTest.twinTownCity(false);
-
-        final AbstractFeature leMans = isSparse ? new SparseFeature(twinTown) : new DenseFeature(twinTown);
-        leMans.setPropertyValue("city", "Le Mans");
-        leMans.setPropertyValue("population", 143240); // In 2011.
-
-        final AbstractFeature paderborn = isSparse ? new SparseFeature(twinTown) : new DenseFeature(twinTown);
-        paderborn.setPropertyValue("city", "Paderborn");
-        paderborn.setPropertyValue("population", 143174); // December 31th, 2011
-        paderborn.setPropertyValue("twin town", leMans);
-        return paderborn;
-    }
-
-    /**
      * Creates a new feature for the given type.
      */
     abstract AbstractFeature createFeature(final DefaultFeatureType type);
@@ -370,4 +353,31 @@ public abstract strictfp class FeatureTe
     private void testSerialization() {
         assertNotSame(feature, assertSerializedEquals(feature));
     }
+
+    /**
+     * Tests {@code equals(Object)}.
+     *
+     * @throws CloneNotSupportedException Should never happen.
+     */
+    @Test
+    @DependsOnMethod("testSimpleProperties")
+    public void testEquals() throws CloneNotSupportedException {
+        feature = createFeature(DefaultFeatureTypeTest.city());
+        feature.setPropertyValue("city", "Tokyo");
+        final AbstractFeature clone = cloneFeature();
+        assertEquals(feature, clone);
+        /*
+         * Force the conversion of a property value into a full Property object on one and only one of
+         * the Features to be compared. The implementation shall be able to wrap or unwrap the values.
+         */
+        assertEquals("Tokyo", clone.getProperty("city").getValue());
+        assertEquals("hashCode", feature.hashCode(), clone.hashCode());
+        assertEquals("equals", feature, clone);
+        /*
+         * For the other Feature instance to contain full Property object and test again.
+         */
+        assertEquals("Tokyo", feature.getProperty("city").getValue());
+        assertEquals("hashCode", feature.hashCode(), clone.hashCode());
+        assertEquals("equals", feature, clone);
+    }
 }

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -25,6 +25,7 @@ import org.opengis.parameter.ParameterDe
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.referencing.crs.DerivedCRS;
+import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CartesianCS;
 import org.opengis.referencing.cs.CoordinateSystem;
@@ -306,6 +307,17 @@ public class ReferencingServices extends
     ///////////////////////////////////////////////////////////////////////////////////////
 
     /**
+     * Returns a coordinate reference system for heights above the mean seal level.
+     *
+     * @return The "Mean Seal Level (MSL) height" coordinate reference system, or {@code null}.
+     *
+     * @since 0.6
+     */
+    public VerticalCRS getMSLH() {
+        throw moduleNotFound();
+    }
+
+    /**
      * Returns the Greenwich prime meridian.
      *
      * @return The Greenwich prime meridian.

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/WKTKeywords.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/WKTKeywords.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/WKTKeywords.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/WKTKeywords.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -60,7 +60,18 @@ public final class WKTKeywords extends S
             Anchor    = "Anchor",
             Scope     = "Scope",
             Area      = "Area",
-            Remarks   = "Remarks";
+            Remark    = "Remark";
+
+    /**
+     * Related to unit of measurements.
+     */
+    public static final String
+            Unit           = "Unit",
+            LengthUnit     = "LengthUnit",
+            AngleUnit      = "AngleUnit",
+            ScaleUnit      = "ScaleUnit",
+            TimeUnit       = "TimeUnit",
+            ParametricUnit = "ParametricUnit";
 
     /**
      * Related to {@link org.apache.sis.referencing.cs.AbstractCS}
@@ -86,6 +97,7 @@ public final class WKTKeywords extends S
             Datum       = "Datum",
             GeodeticCRS = "GeodeticCRS",
             BaseGeodCRS = "BaseGeodCRS",
+            GeodCRS     = "GeodCRS",
             GeogCS      = "GeogCS",
             GeocCS      = "GeocCS";
 

Copied: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java (from r1686269, sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java?p2=sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java&p1=sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java&r1=1686269&r2=1686280&rev=1686280&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -21,6 +21,8 @@ import java.util.List;
 import java.util.Date;
 import java.util.Locale;
 import java.util.LinkedHashMap;
+import java.util.Calendar;
+import java.util.TimeZone;
 import java.text.DateFormat;
 import java.text.NumberFormat;
 import java.text.DecimalFormat;
@@ -172,7 +174,7 @@ abstract class AbstractParser implements
         } else {
             exponentSymbol = null;
         }
-        ignoredElements = new LinkedHashMap<>();
+        ignoredElements = new LinkedHashMap<String, List<String>>();
     }
 
     /**
@@ -255,7 +257,38 @@ abstract class AbstractParser implements
         if (dateFormat == null) {
             dateFormat = new SimpleDateFormat(WKTFormat.DATE_PATTERN, symbols.getLocale());
         }
-        return dateFormat.parse(text, position);
+        /*
+         * Following is a workaround specific to the JDK6 branch. Since JDK6 does not understand the 'Z' suffix,
+         * we handle it in this method. The Apache SIS branch for JDK7 does not need this hack since JDK7 supports
+         * parsing the 'Z' suffix.
+         */
+        final Date date = dateFormat.parse(text, position);
+        if (date != null) {
+            final int p = position.getIndex();
+            if (p < text.length() && text.charAt(p) == 'Z') {
+                position.setIndex(p + 1);
+                final Calendar cal = dateFormat.getCalendar();
+                final int year   = cal.get(Calendar.YEAR);
+                final int month  = cal.get(Calendar.MONTH);
+                final int day    = cal.get(Calendar.DAY_OF_MONTH);
+                final int hour   = cal.get(Calendar.HOUR_OF_DAY);
+                final int minute = cal.get(Calendar.MINUTE);
+                final int second = cal.get(Calendar.SECOND);
+                final int millis = cal.get(Calendar.MILLISECOND);
+                final TimeZone timezone = cal.getTimeZone();
+                final long time;
+                try {
+                    cal.setTimeZone(TimeZone.getTimeZone("UTC"));
+                    cal.set(year, month, day, hour, minute, second);
+                    cal.set(Calendar.MILLISECOND, millis);
+                    time = cal.getTimeInMillis();
+                } finally {
+                    cal.setTimeZone(timezone);
+                }
+                date.setTime(time);
+            }
+        }
+        return date;
     }
 
     /**
@@ -277,7 +310,6 @@ abstract class AbstractParser implements
             try {
                 return Units.valueOf(text);
             } catch (IllegalArgumentException e2) {
-                e.addSuppressed(e2);
                 throw e;
             }
         }

Modified: sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java?rev=1686280&r1=1686279&r2=1686280&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java [UTF-8] Thu Jun 18 17:15:30 2015
@@ -38,15 +38,19 @@ import org.apache.sis.metadata.iso.citat
  *       according the OGC 01-009 (<cite>Coordinate transformation services</cite>) specification.</li>
  *   <li>An older specification — <cite>Simple Features</cite> — was unclear on this matter and has been
  *       interpreted by many softwares as fixing the unit to decimal degrees.</li>
+ *   <li>Some softwares support only (<var>longitude</var>, <var>latitude</var>) axis order
+ *       and ignore completely all {@code AXIS[…]} elements in the WKT.</li>
  * </ul>
  *
  * Despite the first interpretation being specified by both OGC 01-009 and ISO 19162 standards, the second
  * interpretation appears to be in wide use for WKT 1. Apache SIS uses the standard interpretation by default,
  * but the {@link #WKT1_COMMON_UNITS} enumeration allows parsing and formatting using the older interpretation.
+ * The {@link #WKT1_IGNORE_AXES} enumeration mimics the most minimalist WKT 1 parsers,
+ * but should be avoided when not imposed by compatibility reasons.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.6
  * @module
  *
  * @see WKTFormat#getConvention()
@@ -66,7 +70,7 @@ public enum Convention {
      *
      * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html">WKT 2 specification</a>
      */
-    WKT2(false),
+    WKT2(false, false),
 
     /**
      * The ISO 19162 format with omission of some optional elements. This convention is identical
@@ -91,7 +95,7 @@ public enum Convention {
      *
      * <p>This is the default convention used by {@link FormattableObject#toString()}.</p>
      */
-    WKT2_SIMPLIFIED(false),
+    WKT2_SIMPLIFIED(false, false),
 
     /**
      * The OGC 01-009 format, also known as “WKT 1”.
@@ -103,12 +107,14 @@ public enum Convention {
      * names when available.</p>
      *
      * <div class="section">Differences compared to WKT 2</div>
-     * WKT 1 and WKT 2 differ in their keywords and syntax, but also in more subtle ways regarding parameter
-     * and code list values. For {@link GeocentricCRS}, WKT 1 uses a legacy set of Cartesian axes which were
-     * defined in OGC 01-009. Those axes use the <var>Other</var>, <var>Easting</var> and <var>Northing</var>
-     * {@linkplain org.opengis.referencing.cs.AxisDirection axis directions} instead than the geocentric ones,
-     * as shown in the following table:
+     * WKT 1 and WKT 2 differ in their keywords and syntax, but also in more subtle ways regarding axis names,
+     * parameter and code list values. For example in  {@link GeocentricCRS}, WKT 1 uses a legacy set of Cartesian axes
+     * which were defined in OGC 01-009. Those axes use the <var>Other</var>, <var>Easting</var> and <var>Northing</var>
+     * {@linkplain org.opengis.referencing.cs.AxisDirection axis directions} instead than the geocentric ones.
+     * For more uniform handling of CRS objects in client code, SIS parser replaces some WKT 1 conventions by
+     * the ISO ones when possible.
      *
+     * <table class="compact" summary="Differences between current and legacy specifications"><tr><td>
      * <table class="sis">
      *   <caption>Geocentric axis directions</caption>
      *   <tr><th>ISO 19111</th>    <th>OGC 01-009</th> <th>Description</th></tr>
@@ -116,10 +122,20 @@ public enum Convention {
      *   <tr><td>Geocentric Y</td> <td>Easting</td>    <td>Toward 90°E longitude</td></tr>
      *   <tr><td>Geocentric Z</td> <td>Northing</td>   <td>Toward north pole</td></tr>
      * </table>
+     * </td><td>
+     * <table class="sis">
+     *   <caption>Coordinate system axis names</caption>
+     *   <tr><th>CRS type</th>   <th>WKT1 names</th>                               <th>ISO abbreviations</th></tr>
+     *   <tr><td>Geographic</td> <td>Lon, Lat</td>                                 <td>λ, φ</td></tr>
+     *   <tr><td>Vertical</td>   <td><var>H</var></td>                             <td><var>H</var> or <var>h</var></td></tr>
+     *   <tr><td>Projected</td>  <td><var>X</var>, <var>Y</var></td>               <td><var>E</var>, <var>N</var></td></tr>
+     *   <tr><td>Geocentric</td> <td><var>X</var>, <var>Y</var>, <var>Z</var></td> <td><var>X</var>, <var>Y</var>, <var>Z</var></td></tr>
+     * </table>
+     * </td></tr></table>
      *
      * @see <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html">Legacy WKT 1</a>
      */
-    WKT1(true),
+    WKT1(true, false),
 
     /**
      * The <cite>Simple Feature</cite> format, also known as “WKT 1”.
@@ -136,7 +152,24 @@ public enum Convention {
      *       (e.g. <cite>"meter"</cite> instead than <cite>"metre"</cite>).</li>
      * </ul>
      */
-    WKT1_COMMON_UNITS(true),
+    WKT1_COMMON_UNITS(true, true),
+
+    /**
+     * The <cite>Simple Feature</cite> format without parsing of axis elements.
+     * This convention is identical to {@link #WKT1_COMMON_UNITS} except that all {@code AXIS[…]} elements are ignored.
+     * Since the WKT 1 specification said that the default axis order shall be (<var>x</var>,<var>y</var>) or
+     * (<var>longitude</var>, <var>latitude</var>), ignoring {@code AXIS[…]} elements is equivalent to forcing
+     * the coordinate systems to that default order.
+     *
+     * <p>Note that {@code AXIS[…]} elements still need to be well formed even when parsing a text with this convention.
+     * Malformed axis elements will continue to cause a {@link java.text.ParseException} despite their content being ignored.</p>
+     *
+     * <p>This convention may be useful for compatibility with some other softwares that do not handle axis order correctly.
+     * But except when imposed by such compatibility reasons, this convention should be avoided as much as possible.</p>
+     *
+     * @since 0.6
+     */
+    WKT1_IGNORE_AXES(true, true),
 
     /**
      * A special convention for formatting objects as stored internally by Apache SIS.
@@ -167,7 +200,7 @@ public enum Convention {
      * @see org.apache.sis.referencing.operation.projection.NormalizedProjection#getParameterValues()
      */
     @Debug
-    INTERNAL(false);
+    INTERNAL(false, false);
 
     /**
      * The default conventions.
@@ -180,10 +213,24 @@ public enum Convention {
     private final boolean isWKT1;
 
     /**
+     * {@code true} for a frequently-used convention about units instead than the standard one.
+     * <ul>
+     *   <li>If {@code true}, forces {@code PRIMEM} and {@code PARAMETER} angular units to degrees
+     *       instead than inferring the unit from the context. The standard value is {@code false},
+     *       which means that the angular units are inferred from the context as required by the
+     *       WKT 1 specification.</li>
+     *   <li>If {@code true}, uses US unit names instead of the international names.
+     *       For example Americans said {@code "meter"} instead of {@code "metre"}.</li>
+     * </ul>
+     */
+    final boolean usesCommonUnits;
+
+    /**
      * Creates a new enumeration value.
      */
-    private Convention(final boolean isWKT1) {
+    private Convention(final boolean isWKT1, final boolean usesCommonUnits) {
         this.isWKT1 = isWKT1;
+        this.usesCommonUnits = usesCommonUnits;
     }
 
     /**
@@ -217,21 +264,6 @@ public enum Convention {
     }
 
     /**
-     * {@code true} for a frequently-used convention about units instead than the standard one.
-     * <ul>
-     *   <li>If {@code true}, forces {@code PRIMEM} and {@code PARAMETER} angular units to degrees
-     *       instead than inferring the unit from the context. The standard value is {@code false},
-     *       which means that the angular units are inferred from the context as required by the
-     *       WKT 1 specification.</li>
-     *   <li>If {@code true}, uses US unit names instead of the international names.
-     *       For example Americans said {@code "meter"} instead of {@code "metre"}.</li>
-     * </ul>
-     */
-    final boolean usesCommonUnits() {
-        return this == WKT1_COMMON_UNITS;
-    }
-
-    /**
      * Returns the default authority to look for when fetching identified object names and identifiers.
      * The difference between various authorities are most easily seen in projection and parameter names.
      * The value returned by this method can be overwritten by {@link WKTFormat#setNameAuthority(Citation)}.



Mime
View raw message