sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1791413 [1/2] - in /sis/branches/JDK9: ./ core/sis-feature/src/main/java/org/apache/sis/feature/ core/sis-feature/src/main/java/org/apache/sis/feature/builder/ core/sis-feature/src/main/java/org/apache/sis/internal/feature/ core/sis-featur...
Date Fri, 14 Apr 2017 20:47:46 GMT
Author: desruisseaux
Date: Fri Apr 14 20:47:45 2017
New Revision: 1791413

URL: http://svn.apache.org/viewvc?rev=1791413&view=rev
Log:
Merge from JDK8 branch.

Modified:
    sis/branches/JDK9/   (props changed)
    sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/EnvelopeOperation.java
    sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeRole.java
    sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeTypeBuilder.java
    sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
    sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java
    sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java
    sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/EnvelopeOperationTest.java
    sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java
    sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
    sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java
    sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java
    sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
    sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java
    sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/package-info.java
    sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/measure/ScalarTest.java
    sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java
    sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java
    sis/branches/JDK9/pom.xml
    sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureNaming.java
    sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/storage/FeatureNamingTest.java
    sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/GroupAsPolylineOperation.java
    sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Reader.java
    sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java
    sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Writer.java
    sis/branches/JDK9/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/ReaderTest.java
    sis/branches/JDK9/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java

Propchange: sis/branches/JDK9/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Apr 14 20:47:45 2017
@@ -1,4 +1,4 @@
 /sis/branches/Android:1430670-1480699
 /sis/branches/JDK6:1394913-1508480
-/sis/branches/JDK8:1773327-1790830
+/sis/branches/JDK8:1773327-1791412
 /sis/trunk:1394364-1508466,1519089-1519674

Modified: sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/EnvelopeOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/EnvelopeOperation.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/EnvelopeOperation.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/EnvelopeOperation.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -143,7 +143,7 @@ final class EnvelopeOperation extends Ab
                 final GenericName name = property.getName();
                 final String attributeName = (property instanceof LinkOperation)
                                              ? ((LinkOperation) property).referentName : name.toString();
-                final boolean isDefault = AttributeConvention.GEOMETRY_PROPERTY.equals(name.tip());
+                final boolean isDefault = AttributeConvention.GEOMETRY_PROPERTY.equals(name);
                 if (isDefault) {
                     defaultGeometry = attributeName;
                 }

Modified: sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeRole.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeRole.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeRole.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeRole.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -52,9 +52,9 @@ public enum AttributeRole {
      *
      * <ul>
      *   <li>If no attribute has this role, then no attribute is marked as feature identifier.</li>
-     *   <li>If exactly one attribute has this role, then a synthetic attribute named {@code "@identifier"}
+     *   <li>If exactly one attribute has this role, then a synthetic attribute named {@code "sis:identifier"}
      *       will be created as a {@linkplain FeatureOperations#link link} to the flagged attribute.</li>
-     *   <li>If more than one attribute have this role, then a synthetic attribute named {@code "@identifier"}
+     *   <li>If more than one attribute have this role, then a synthetic attribute named {@code "sis:identifier"}
      *       will be created as a {@linkplain FeatureOperations#compound compound key} made of all flagged
      *       attributes. The separator character can be modified by a call to
      *       {@link FeatureTypeBuilder#setIdentifierDelimiters(String, String, String)}</li>

Modified: sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeTypeBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeTypeBuilder.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeTypeBuilder.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeTypeBuilder.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -87,8 +87,8 @@ public final class AttributeTypeBuilder<
 
     /**
      * Whether this attribute will be used in a {@linkplain FeatureOperations#compound compound key} named
-     * {@code "@identifier"}. If only one attribute has this flag and {@link FeatureTypeBuilder#idPrefix} and
-     * {@code isSuffix} are null, then {@code "@identifier"} will be a {@linkplain FeatureOperations#link link}
+     * {@code "sis:identifier"}. If only one attribute has this flag and {@link FeatureTypeBuilder#idPrefix} and
+     * {@code isSuffix} are null, then {@code "sis:identifier"} will be a {@linkplain FeatureOperations#link link}
      * to {@code idAttributes[0]}.
      *
      * @see #addRole(AttributeRole)

Modified: sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -113,13 +113,13 @@ public class FeatureTypeBuilder extends
 
     /**
      * An optional prefix or suffix to insert before or after the {@linkplain FeatureOperations#compound compound key}
-     * named {@code "@identifier"}.
+     * named {@code "sis:identifier"}.
      */
     private String idPrefix, idSuffix;
 
     /**
      * The separator to insert between each single component in a {@linkplain FeatureOperations#compound compound key}
-     * named {@code "@identifier"}. This is ignored if {@link #identifierCount} is zero.
+     * named {@code "sis:identifier"}. This is ignored if {@link #identifierCount} is zero.
      */
     private String idDelimiter;
 
@@ -196,7 +196,7 @@ public class FeatureTypeBuilder extends
                 } else if (property instanceof FeatureAssociationRole) {
                     builder = new AssociationRoleBuilder(this, (FeatureAssociationRole) property);
                 } else {
-                    builder = null;     // Do not create OperationWrapper now - see below.
+                    builder = null;                             // Do not create OperationWrapper now - see below.
                 }
                 /*
                  * If the property name is one of our (Apache SIS specific) conventional names, try to reconstitute
@@ -211,7 +211,7 @@ public class FeatureTypeBuilder extends
                 } else if (AttributeConvention.GEOMETRY_PROPERTY.equals(name)) {
                     role = AttributeRole.DEFAULT_GEOMETRY;
                 } else if (AttributeConvention.ENVELOPE_PROPERTY.equals(name)) {
-                    // If "@envelope" is an operation, skip it completely.
+                    // If "sis:envelope" is an operation, skip it completely.
                     // It will be recreated if a default geometry exists.
                     role = null;
                 } else {
@@ -685,9 +685,9 @@ public class FeatureTypeBuilder extends
     public FeatureType build() throws IllegalStateException {
         if (feature == null) {
             /*
-             * Creates an initial array of property types with up to 3 slots reserved for @identifier, @geometry
-             * and @envelope operations. At first we presume that there is always an identifier.  The identifier
-             * slot will be removed later if there is none.
+             * Creates an initial array of property types with up to 3 slots reserved for sis:identifier, sis:geometry
+             * and sis:envelope operations. At first we presume that there is always an identifier. The identifier slot
+             * will be removed later if there is none.
              */
             final int numSpecified = properties.size();     // Number of explicitely specified properties.
             int numSynthetic;                               // Number of synthetic properties that may be generated.
@@ -723,8 +723,8 @@ public class FeatureTypeBuilder extends
                     identifierTypes[identifierCursor++] = instance;
                 }
                 /*
-                 * If there is a default geometry, add a link named "@geometry" to that geometry.
-                 * It may happen that the property created by the user is already named "@geometry",
+                 * If there is a default geometry, add a link named "sis:geometry" to that geometry.
+                 * It may happen that the property created by the user is already named "sis:geometry",
                  * in which case we will avoid to duplicate the property.
                  */
                 if (builder == defaultGeometry && geometryIndex >= 0) {
@@ -742,7 +742,7 @@ public class FeatureTypeBuilder extends
             /*
              * Create the "envelope" operation only after we created all other properties.
              * Actually it is okay if the 'propertyTypes' array still contains null elements not needed for envelope calculation
-             * like "@identifier", since FeatureOperations.envelope(…) constructor ignores any property which is not for a value.
+             * like "sis:identifier", since FeatureOperations.envelope(…) constructor ignores any property which is not for a value.
              */
             if (envelopeIndex >= 0) try {
                 propertyTypes[envelopeIndex] = FeatureOperations.envelope(name(AttributeConvention.ENVELOPE_PROPERTY), null, propertyTypes);
@@ -752,7 +752,7 @@ public class FeatureTypeBuilder extends
             /*
              * If a synthetic identifier need to be created, create it now as the first property.
              * It may happen that the user provided a single identifier component already named
-             * "@identifier", in which case we avoid to duplicate the property.
+             * "sis:identifier", in which case we avoid to duplicate the property.
              */
             if (identifierTypes != null) {
                 if (identifierCursor != identifierTypes.length) {

Modified: sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -19,11 +19,8 @@ package org.apache.sis.internal.feature;
 import org.opengis.util.LocalName;
 import org.opengis.util.ScopedName;
 import org.opengis.util.GenericName;
-import org.opengis.util.NameFactory;
-import org.opengis.util.NameSpace;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.apache.sis.internal.system.DefaultFactories;
-import org.apache.sis.internal.util.Constants;
+import org.apache.sis.util.iso.Names;
 import org.apache.sis.util.Static;
 
 // Branch-dependent imports
@@ -41,10 +38,10 @@ import org.opengis.feature.Property;
  * appropriate "real" property in the feature.
  *
  * <div class="note"><b>Example:</b>
- * one of the most frequently used synthetic property is {@code "@identifier"}, which contains a unique
+ * one of the most frequently used synthetic property is {@code "sis:identifier"}, which contains a unique
  * identifier (or primary key) for the feature. This property is usually (but not necessarily)
  * a {@linkplain org.apache.sis.feature.FeatureOperations#link link to an existing attribute}.
- * By using the {@code "@identifier"} alias, users do not need to know the name of the "real" attribute.
+ * By using the {@code "sis:identifier"} alias, users do not need to know the name of the "real" attribute.
  * </div>
  *
  * This class defines names for two kinds of usage:
@@ -66,15 +63,15 @@ import org.opengis.feature.Property;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.7
  * @module
  */
 public final class AttributeConvention extends Static {
     /**
-     * Namespace of all names defined by SIS convention.
+     * Scope of all names defined by SIS convention.
      */
-    private static final GenericName NAMESPACE;
+    private static final LocalName SCOPE;
 
     /**
      * Conventional name for a property used as a unique identifier.
@@ -90,7 +87,7 @@ public final class AttributeConvention e
      * <p>The {@linkplain org.apache.sis.feature.DefaultAttributeType#getValueClass() value class} is usually
      * {@link String}, {@link Integer}, {@link java.util.UUID} or other types commonly used as identifiers.</p>
      */
-    public static final LocalName IDENTIFIER_PROPERTY;
+    public static final ScopedName IDENTIFIER_PROPERTY;
 
     /**
      * Conventional name for a property containing the geometric object to use by default.
@@ -107,7 +104,7 @@ public final class AttributeConvention e
      *
      * @see #isGeometryAttribute(IdentifiedType)
      */
-    public static final LocalName GEOMETRY_PROPERTY;
+    public static final ScopedName GEOMETRY_PROPERTY;
 
     /**
      * Conventional name for fetching the envelope encompassing all geometries in a feature. Most {@code FeatureType}s
@@ -120,7 +117,7 @@ public final class AttributeConvention e
      * <p>The {@linkplain org.apache.sis.feature.DefaultAttributeType#getValueClass() value class} should be
      * {@link org.opengis.geometry.Envelope}.</p>
      */
-    public static final LocalName ENVELOPE_PROPERTY;
+    public static final ScopedName ENVELOPE_PROPERTY;
 
     /**
      * Conventional name for fetching the Coordinate Reference System (CRS) of a geometry or a coverage.
@@ -139,7 +136,7 @@ public final class AttributeConvention e
      *
      * @see #getCRSCharacteristic(Property)
      */
-    public static final LocalName CRS_CHARACTERISTIC;
+    public static final ScopedName CRS_CHARACTERISTIC;
 
     /**
      * Conventional name for fetching the maximal length of string values.
@@ -153,7 +150,7 @@ public final class AttributeConvention e
      *
      * @see #getMaximalLengthCharacteristic(Property)
      */
-    public static final LocalName MAXIMAL_LENGTH_CHARACTERISTIC;
+    public static final ScopedName MAXIMAL_LENGTH_CHARACTERISTIC;
 
     /**
      * Conventional name for fetching the enumeration of valid values.
@@ -162,18 +159,15 @@ public final class AttributeConvention e
      * {@linkplain org.apache.sis.feature.DefaultAttributeType#characteristics() characteristic} associated
      * to the attribute on which the restriction applies.
      */
-    public static final LocalName VALID_VALUES_CHARACTERISTIC;
-
+    public static final GenericName VALID_VALUES_CHARACTERISTIC;
     static {
-        final NameFactory factory = DefaultFactories.forBuildin(NameFactory.class);
-        NAMESPACE                     = factory.createGenericName(null, "Apache", Constants.SIS);
-        final NameSpace ns            = factory.createNameSpace(NAMESPACE, null);
-        IDENTIFIER_PROPERTY           = factory.createLocalName(ns, "@identifier");
-        GEOMETRY_PROPERTY             = factory.createLocalName(ns, "@geometry");
-        ENVELOPE_PROPERTY             = factory.createLocalName(ns, "@envelope");
-        CRS_CHARACTERISTIC            = factory.createLocalName(ns, "@crs");
-        MAXIMAL_LENGTH_CHARACTERISTIC = factory.createLocalName(ns, "@maximalLength");
-        VALID_VALUES_CHARACTERISTIC   = factory.createLocalName(ns, "@validValues");
+        SCOPE                         = Names.createLocalName("Apache", null, "sis");
+        IDENTIFIER_PROPERTY           = Names.createScopedName(SCOPE, null, "identifier");
+        GEOMETRY_PROPERTY             = Names.createScopedName(SCOPE, null, "geometry");
+        ENVELOPE_PROPERTY             = Names.createScopedName(SCOPE, null, "envelope");
+        CRS_CHARACTERISTIC            = Names.createScopedName(SCOPE, null, "crs");
+        MAXIMAL_LENGTH_CHARACTERISTIC = Names.createScopedName(SCOPE, null, "maximalLength");
+        VALID_VALUES_CHARACTERISTIC   = Names.createScopedName(SCOPE, null, "validValues");
     }
 
     /**
@@ -195,17 +189,14 @@ public final class AttributeConvention e
      * @param  name  the name of the property or characteristic to test, or {@code null}.
      * @return {@code true} if the given name is non-null and in the SIS namespace.
      */
-    public static boolean contains(final GenericName name) {
-        if (name == null) {
-            return false;
-        }
-        final GenericName scope;
-        if (name instanceof ScopedName) {
-            scope = ((ScopedName) name).path().toFullyQualifiedName();
-        } else {
-            scope = name.scope().name();
+    public static boolean contains(GenericName name) {
+        while (name instanceof ScopedName) {
+            if (SCOPE.equals(((ScopedName) name).path())) {
+                return true;
+            }
+            name = ((ScopedName) name).tail();
         }
-        return NAMESPACE.equals(scope);
+        return false;
     }
 
     /**

Modified: sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -48,6 +48,14 @@ import org.opengis.feature.AttributeType
 @DependsOn(DefaultAttributeTypeTest.class)
 public final strictfp class DefaultFeatureTypeTest extends TestCase {
     /**
+     * Convenience method returning the given name in a a property map
+     * to be given to {@link AbstractIdentifiedType} constructor.
+     */
+    private static Map<String,?> name(final Object name) {
+        return singletonMap(AbstractIdentifiedType.NAME_KEY, name);
+    }
+
+    /**
      * Creates a simple feature type without super-types.
      * The feature contains the following attributes:
      *
@@ -62,10 +70,7 @@ public final strictfp class DefaultFeatu
         final Map<String,Object> identification = new HashMap<>();
         final DefaultAttributeType<String>  city       = DefaultAttributeTypeTest.city(identification);
         final DefaultAttributeType<Integer> population = DefaultAttributeTypeTest.population(identification);
-
-        identification.clear();
-        assertNull(identification.put(DefaultFeatureType.NAME_KEY, "City"));
-        return new DefaultFeatureType(identification, false, null, city, population);
+        return new DefaultFeatureType(name("City"), false, null, city, population);
     }
 
     /**
@@ -81,7 +86,7 @@ public final strictfp class DefaultFeatu
      * @return the feature for an university city.
      */
     public static DefaultFeatureType universityCity() {
-        return new DefaultFeatureType(singletonMap(DefaultFeatureType.NAME_KEY, "University city"), false,
+        return new DefaultFeatureType(name("University city"), false,
                 new DefaultFeatureType[] {city()}, DefaultAttributeTypeTest.universities());
     }
 
@@ -98,7 +103,7 @@ public final strictfp class DefaultFeatu
      * @return the feature for a capital.
      */
     public static DefaultFeatureType capital() {
-        return new DefaultFeatureType(singletonMap(DefaultFeatureType.NAME_KEY, "Capital"), false,
+        return new DefaultFeatureType(name("Capital"), false,
                 new DefaultFeatureType[] {city()}, DefaultAttributeTypeTest.parliament());
     }
 
@@ -121,10 +126,8 @@ public final strictfp class DefaultFeatu
         assertNull(identification.put(DefaultFeatureType.NAME_KEY + "_fr", "Métropole"));
         return new DefaultFeatureType(identification, false,
                 new DefaultFeatureType[] {city()},
-                new DefaultAttributeType<>(singletonMap(DefaultAttributeType.NAME_KEY, "region"),
-                        CharSequence.class, 1, 1, null),
-                new DefaultAttributeType<>(singletonMap(DefaultAttributeType.NAME_KEY, "isGlobal"),
-                        Boolean.class, 1, 1, null));
+                new DefaultAttributeType<>(name("region"), CharSequence.class, 1, 1, null),
+                new DefaultAttributeType<>(name("isGlobal"),    Boolean.class, 1, 1, null));
     }
 
     /**
@@ -142,13 +145,13 @@ public final strictfp class DefaultFeatu
     private static DefaultFeatureType worldMetropolis(final DefaultFeatureType metropolis,
             final DefaultFeatureType universityCity, final DefaultAttributeType<?> temperature, final Class<?> regionType)
     {
-        return new DefaultFeatureType(singletonMap(DefaultFeatureType.NAME_KEY, "World metropolis"), false,
-                new DefaultFeatureType[] {          // Super types
+        return new DefaultFeatureType(name("World metropolis"), false,
+                new DefaultFeatureType[] {                                                  // Super types
                     metropolis,
                     universityCity
                 },
-                new DefaultAttributeType<?>[] {     // Properties
-                    new DefaultAttributeType<>(singletonMap(DefaultAttributeType.NAME_KEY, "region"), regionType, 1, 1, null),
+                new DefaultAttributeType<?>[] {                                             // Properties
+                    new DefaultAttributeType<>(name("region"), regionType, 1, 1, null),
                     temperature
                 });
     }
@@ -267,12 +270,10 @@ public final strictfp class DefaultFeatu
             final int minimumOccurs, final int maximumOccurs)
     {
         final DefaultAttributeType<String> festival = new DefaultAttributeType<>(
-                singletonMap(DefaultAttributeType.NAME_KEY, "festival"),
-                String.class, minimumOccurs, maximumOccurs, null);
+                name("festival"), String.class, minimumOccurs, maximumOccurs, null);
 
         final DefaultFeatureType complex = new DefaultFeatureType(
-                singletonMap(DefaultAttributeType.NAME_KEY, "Festival"),
-                false, null, city, population, festival);
+                name("Festival"), false, null, city, population, festival);
 
         assertUnmodifiable(complex);
         final Collection<PropertyType> properties = complex.getProperties(false);
@@ -300,16 +301,12 @@ public final strictfp class DefaultFeatu
     @Test
     @DependsOnMethod("testSimple")
     public void testNameCollision() {
-        final DefaultAttributeType<String> city = new DefaultAttributeType<>(
-                singletonMap(DefaultAttributeType.NAME_KEY, "name"), String.class, 1, 1, null);
-        final DefaultAttributeType<Integer> cityId = new DefaultAttributeType<>(
-                singletonMap(DefaultAttributeType.NAME_KEY, "name"), Integer.class, 1, 1, null);
-        final DefaultAttributeType<Integer> population = new DefaultAttributeType<>(
-                singletonMap(DefaultAttributeType.NAME_KEY, "population"), Integer.class, 1, 1, null);
+        final DefaultAttributeType<String>  city       = new DefaultAttributeType<>(name("name"),       String.class,  1, 1, null);
+        final DefaultAttributeType<Integer> cityId     = new DefaultAttributeType<>(name("name"),       Integer.class, 1, 1, null);
+        final DefaultAttributeType<Integer> population = new DefaultAttributeType<>(name("population"), Integer.class, 1, 1, null);
 
-        final Map<String,String> identification = singletonMap(DefaultAttributeType.NAME_KEY, "City");
         try {
-            final Object t = new DefaultFeatureType(identification, false, null, city, population, cityId);
+            final Object t = new DefaultFeatureType(name("City"), false, null, city, population, cityId);
             fail("Duplicated attribute names shall not be allowed:\n" + t);
         } catch (IllegalArgumentException e) {
             final String message = e.getMessage();
@@ -329,17 +326,16 @@ public final strictfp class DefaultFeatu
     public void testQualifiedNames() {
         final NameFactory factory = DefaultFactories.forBuildin(NameFactory.class);
         final DefaultAttributeType<String> city = new DefaultAttributeType<>(
-                singletonMap(DefaultAttributeType.NAME_KEY, factory.createGenericName(null, "ns1", "name")),
+                name(factory.createGenericName(null, "ns1", "name")),
                 String.class, 1, 1, null);
         final DefaultAttributeType<Integer> cityId = new DefaultAttributeType<>(
-                singletonMap(DefaultAttributeType.NAME_KEY, factory.createGenericName(null, "ns2", "name")),
+                name(factory.createGenericName(null, "ns2", "name")),
                 Integer.class, 1, 1, null);
         final DefaultAttributeType<Integer> population = new DefaultAttributeType<>(
-                singletonMap(DefaultAttributeType.NAME_KEY, factory.createGenericName(null, "ns1", "population")),
+                name(factory.createGenericName(null, "ns1", "population")),
                 Integer.class, 1, 1, null);
         final DefaultFeatureType feature = new DefaultFeatureType(
-                singletonMap(DefaultAttributeType.NAME_KEY, "City"),
-                false, null, city, cityId, population);
+                name("City"), false, null, city, cityId, population);
 
         final Iterator<PropertyType> it = feature.getProperties(false).iterator();
         assertSame ("properties[0]", city,       it.next());
@@ -362,13 +358,35 @@ public final strictfp class DefaultFeatu
     }
 
     /**
+     * Tests two names having the same tip, but where only one of the two names have a namespace.
+     *
+     * @since 0.8
+     */
+    @Test
+    @DependsOnMethod("testQualifiedNames")
+    public void testQualifiedAndUnqualifiedNames() {
+        final NameFactory factory = DefaultFactories.forBuildin(NameFactory.class);
+        final DefaultAttributeType<String> a1 = new DefaultAttributeType<>(
+                name(factory.createGenericName(null, "sis", "identifier")),
+                String.class, 1, 1, null);
+        final DefaultAttributeType<String> a2 = new DefaultAttributeType<>(
+                name(factory.createGenericName(null, "identifier")),
+                String.class, 1, 1, null);
+        final DefaultFeatureType feature = new DefaultFeatureType(
+                name("City"), false, null, a1, a2);
+
+        assertSame("sis:identifier", a1, feature.getProperty("sis:identifier"));
+        assertSame(    "identifier", a2, feature.getProperty(    "identifier"));
+    }
+
+    /**
      * Tests inclusion of a property of kind operation.
      */
     @Test
     public void testOperationProperty() {
-        final Map<String,String> featureName = singletonMap(DefaultFeatureType.NAME_KEY, "Identified city");
-        final Map<String,String> identifierName = singletonMap(DefaultAttributeType.NAME_KEY, "identifier");
-        final DefaultFeatureType[] parent = {city()};
+        final Map<String,?> featureName    = name("Identified city");
+        final Map<String,?> identifierName = name("identifier");
+        final DefaultFeatureType[] parent  = {city()};
         final DefaultFeatureType city = new DefaultFeatureType(featureName, false,
                 parent, new LinkOperation(identifierName, parent[0].getProperty("city")));
         assertPropertiesEquals(city, true, "city", "population", "identifier");
@@ -428,9 +446,9 @@ public final strictfp class DefaultFeatu
         final DefaultFeatureType metropolis   = metropolis();
         final DefaultFeatureType capital      = capital();      // Tested by 'testComplex()'.
         final DefaultFeatureType metroCapital = new DefaultFeatureType(
-                singletonMap(DefaultFeatureType.NAME_KEY, "Metropolis and capital"), false,
+                name("Metropolis and capital"), false,
                 new DefaultFeatureType[] {metropolis, capital},
-                new DefaultAttributeType<>(singletonMap(DefaultAttributeType.NAME_KEY, "country"),
+                new DefaultAttributeType<>(name("country"),
                         String.class, 1, 1, null));
 
         assertUnmodifiable(metroCapital);
@@ -508,7 +526,7 @@ public final strictfp class DefaultFeatu
     @DependsOnMethod("testPropertyOverride")
     public void testPropertyDuplication() {
         DefaultFeatureType city = city();
-        city = new DefaultFeatureType(singletonMap(DefaultFeatureType.NAME_KEY, "New-City"),
+        city = new DefaultFeatureType(name("New-City"),
                 false, new DefaultFeatureType[] {city()}, city.getProperty("city"));
 
         assertPropertiesEquals(city, false);

Modified: sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/EnvelopeOperationTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/EnvelopeOperationTest.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/EnvelopeOperationTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/EnvelopeOperationTest.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -59,7 +59,7 @@ public final strictfp class EnvelopeOper
      *   <li>{@code classes} as a {@link Polygon}</li>
      *   <li>{@code climbing wall} as a {@link Point}</li>
      *   <li>{@code gymnasium} as a {@link Polygon}</li>
-     *   <li>{@code @geometry} as a link to the default geometry</li>
+     *   <li>{@code sis:geometry} as a link to the default geometry</li>
      *   <li>{@code bounds} as the feature envelope attribute.</li>
      * </ul>
      *

Modified: sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -168,8 +168,8 @@ public final strictfp class FeatureTypeB
 
     /**
      * Tests {@link FeatureTypeBuilder#addAttribute(Class)} where one attribute is an identifier that already has
-     * the {@code "@identifier"} name. This is called "anonymous" because identifiers with an explicit name in the
-     * data file should use that name instead in the feature type.
+     * the {@code "sis:identifier"} name. This is called "anonymous" because identifiers with an explicit name in
+     * the data file should use that name instead in the feature type.
      */
     @Test
     @DependsOnMethod("testAddIdentifierAndGeometry")
@@ -191,8 +191,8 @@ public final strictfp class FeatureTypeB
 
     /**
      * Tests {@link FeatureTypeBuilder#addAttribute(Class)} where one attribute is a geometry that already has
-     * the {@code "@geometry"} name. This is called "anonymous" because geometries with an explicit name in the
-     * data file should use that name instead in the feature type.
+     * the {@code "sis:geometry"} name. This is called "anonymous" because geometries with an explicit name in
+     * the data file should use that name instead in the feature type.
      */
     @Test
     @DependsOnMethod("testAddIdentifierAndGeometry")
@@ -245,7 +245,7 @@ public final strictfp class FeatureTypeB
 
         final FeatureType type = builder.build();
         builder = new FeatureTypeBuilder(type);
-        assertEquals("name",       "City", builder.getName().toString());
+        assertEquals("name", "City", builder.getName().toString());
         assertEquals("superTypes", 0, builder.getSuperTypes().length);
 
         final Iterator<PropertyTypeBuilder> it = builder.properties().iterator();

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -59,7 +59,7 @@ import org.apache.sis.util.iso.DefaultNa
  *
  * <div class="section">NetCDF unit symbols</div>
  * The attributes in NetCDF files often merge the axis direction with the angular unit,
- * as in {@code "degrees_east"} or {@code "degrees_north"}.
+ * as in {@code "degrees_east"}, {@code "degrees_north"} or {@code "Degrees North"}.
  * This class ignores those suffixes and unconditionally returns {@link Units#DEGREE} for all axis directions.
  * In particular, the units for {@code "degrees_west"} and {@code "degrees_east"} do <strong>not</strong> have
  * opposite sign. It is caller responsibility to handle the direction of axes associated to NetCDF units.

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -271,7 +271,7 @@ public abstract class AbstractName imple
      * Returns the separator to write before the given name. If the scope of the given name
      * is a {@link DefaultNameSpace} instance, then this method returns its head separator.
      * We really want {@link DefaultNameSpace#headSeparator}, not {@link DefaultNameSpace#separator}.
-     * See {@link DefaultNameSpace#child(CharSequence)} for details.
+     * See {@link DefaultNameSpace#child(CharSequence, String)} for details.
      *
      * @param  name  the name after which to write a separator.
      * @return the separator to write after the given name.

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -51,7 +51,7 @@ import static org.apache.sis.util.Argume
  * remain safe to call from multiple threads and do not change any public {@code NameSpace} state.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.3
+ * @version 0.8
  *
  * @see DefaultScopedName
  * @see DefaultLocalName
@@ -345,10 +345,11 @@ public class DefaultNameSpace implements
      * but it is {@code "."} for all children ({@code "opengeospatial"} and {@code "org"}).</p>
      *
      * @param  name  the name of the child namespace.
+     * @param  sep   the separator to use (typically {@link #separator}).
      * @return the child namespace. It may be an existing instance.
      */
-    final DefaultNameSpace child(final CharSequence name) {
-        return child(key(name), name, separator, separator);
+    final DefaultNameSpace child(final CharSequence name, final String sep) {
+        return child(key(name), name, sep, sep);
     }
 
     /**

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -49,7 +49,7 @@ import org.apache.sis.internal.util.Unmo
  * state.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.3
+ * @version 0.8
  *
  * @see DefaultNameSpace
  * @see DefaultLocalName
@@ -133,7 +133,7 @@ public class DefaultScopedName extends A
         do {
             ArgumentChecks.ensureNonNullElement("names", i, name);
             locals[i++] = new DefaultLocalName(ns, name);
-            ns = ns.child(name);
+            ns = ns.child(name, ns.separator);
             name = it.next();
         } while (it.hasNext());
         /*
@@ -148,7 +148,7 @@ public class DefaultScopedName extends A
             tip.fullyQualified = fullyQualified = this;
         }
         locals[i++] = tip;
-        if (i != size) { // Paranoiac check.
+        if (i != size) {                                        // Paranoiac check.
             throw new ConcurrentModificationException(Errors.format(Errors.Keys.UnexpectedChange_1, "names"));
         }
         // Following line is safe because 'parsedNames' type is <? extends LocalName>.
@@ -162,15 +162,13 @@ public class DefaultScopedName extends A
      * @param path  the first part to concatenate.
      * @param tail  the second part to concatenate.
      */
-    @SuppressWarnings("SuspiciousToArrayCall")
     protected DefaultScopedName(final GenericName path, final GenericName tail) {
         ArgumentChecks.ensureNonNull("path", path);
         ArgumentChecks.ensureNonNull("tail", tail);
         final List<? extends LocalName> parsedPath = path.getParsedNames();
         final List<? extends LocalName> parsedTail = tail.getParsedNames();
         int index = parsedPath.size();
-        LocalName[] locals = new LocalName[index + parsedTail.size()];
-        locals = parsedPath.toArray(locals);
+        final LocalName[] locals = parsedPath.toArray(new LocalName[index + parsedTail.size()]);
         /*
          * We have copied the LocalNames from the path unconditionally.  Now we need to process the
          * LocalNames from the tail. If the tail scope follows the path scope, we can just copy the
@@ -193,7 +191,7 @@ public class DefaultScopedName extends A
             if (path instanceof LocalName) {
                 this.tail = tail;
             }
-            while (true) {
+            for (;;) {
                 locals[index++] = name;
                 if (!it.hasNext()) break;
                 name = it.next();
@@ -205,8 +203,8 @@ public class DefaultScopedName extends A
              */
             DefaultNameSpace scope = DefaultNameSpace.castOrCopy(lastScope);
             CharSequence label = name(lastName);
-            while (true) {
-                scope = scope.child(label);
+            for (;;) {
+                scope = scope.child(label, scope.separator);
                 label = name(name);
                 name  = new DefaultLocalName(scope, label);
                 locals[index++] = name;
@@ -225,6 +223,38 @@ public class DefaultScopedName extends A
     }
 
     /**
+     * Constructs a scoped name as the concatenation of the given generic name with a single character sequence.
+     * The scope of the new name will be the scope of the {@code path} argument.
+     * The tail is a local name created from the given character sequence.
+     *
+     * @param path       the first part to concatenate.
+     * @param separator  the separator between the head and the tail,
+     *                   or {@code null} for inheriting the same separator than the given path.
+     * @param tail       the second part to concatenate.
+     *
+     * @see Names#createScopedName(GenericName, String, CharSequence)
+     *
+     * @since 0.8
+     */
+    protected DefaultScopedName(final GenericName path, final String separator, final CharSequence tail) {
+        /*
+         * Following is the same code than DefaultScopedName(GenericName, GenericName)
+         * after simplification we can do because we create the LocalName ourselves.
+         */
+        ArgumentChecks.ensureNonNull("path", path);
+        ArgumentChecks.ensureNonNull("tail", tail);
+        final List<? extends LocalName> parsedPath = path.getParsedNames();
+        final int index = parsedPath.size();
+        final LocalName[] locals = parsedPath.toArray(new LocalName[index + 1]);
+        final LocalName lastName = locals[index - 1];
+        DefaultNameSpace scope = DefaultNameSpace.castOrCopy(lastName.scope());
+        scope = scope.child(name(lastName), separator != null ? separator : scope.separator);
+        locals[index] = new DefaultLocalName(scope, tail);
+        parsedNames = UnmodifiableArrayList.wrap(locals);
+        this.path = path;
+    }
+
+    /**
      * Returns the name to be given to {@link DefaultLocalName} constructors.
      */
     private static CharSequence name(final GenericName name) {

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -20,6 +20,7 @@ import java.util.Collections;
 import org.opengis.util.TypeName;
 import org.opengis.util.LocalName;
 import org.opengis.util.MemberName;
+import org.opengis.util.ScopedName;
 import org.opengis.util.GenericName;
 import org.opengis.util.NameSpace;
 import org.opengis.util.NameFactory;
@@ -127,6 +128,24 @@ public final class Names extends Static
     }
 
     /**
+     * Constructs a scoped name as the concatenation of the given generic name with a single character sequence.
+     * The scope of the new name will be the scope of the {@code path} argument.
+     * The tail is a local name created from the given character sequence.
+     *
+     * @param  scope      the first part to concatenate.
+     * @param  separator  the separator between the head and the tail,
+     *                    or {@code null} for inheriting the same separator than the given scope.
+     * @param  name       the second part to concatenate.
+     * @return a scoped name in the given namespace.
+     *
+     * @since 0.8
+     */
+    public static ScopedName createScopedName(final GenericName scope, final String separator, final CharSequence name) {
+        // Current version does not perform any caching, but this is something we could add in the future.
+        return new DefaultScopedName(scope, separator, name);
+    }
+
+    /**
      * Creates a name which is local in the given namespace.
      * The character sequences can be either {@link String} or {@link InternationalString} instances.
      * Those character sequences are taken verbatim; they are <em>not</em> parsed into their components.

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/package-info.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/package-info.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/util/iso/package-info.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -107,7 +107,7 @@
  * </table>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.3
  * @module
  */

Modified: sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/measure/ScalarTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/measure/ScalarTest.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/measure/ScalarTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/measure/ScalarTest.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -82,7 +82,7 @@ public final strictfp class ScalarTest e
 
     /**
      * Tests {@link Scalar#multiply(Quantity)}, {@link Scalar#divide(Quantity)} and {@link Quantity#inverse()}.
-     * Those tests depend on proper working of {@link Units#quantity(double, Unit)}, which depends in turn on
+     * Those tests depend on proper working of {@link Quantities#create(double, Unit)}, which depends in turn on
      * proper declarations of {@link ScalarFactory} in {@link Units} initialization.
      */
     @Test

Modified: sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/measure/UnitFormatTest.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -265,6 +265,7 @@ public final strictfp class UnitFormatTe
         assertSame(Units.DEGREE,        f.parse("degree"));
         assertSame(Units.DEGREE,        f.parse("degrees"));
         assertSame(Units.DEGREE,        f.parse("decimal degrees"));
+        assertSame(Units.DEGREE,        f.parse("Degrees North"));
         assertSame(Units.DEGREE,        f.parse("degrees north"));
         assertSame(Units.DEGREE,        f.parse("degree north"));
         assertSame(Units.DEGREE,        f.parse("degrees_east"));

Modified: sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/test/java/org/apache/sis/util/iso/NamesTest.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -27,6 +27,7 @@ import org.opengis.util.NameSpace;
 import org.opengis.util.ScopedName;
 import org.apache.sis.util.UnknownNameException;
 import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
@@ -38,13 +39,28 @@ import static org.junit.Assert.*;
  * Tests the {@link Names} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.5
+ * @version 0.8
  * @since   0.5
  * @module
  */
 @DependsOn(DefaultNameFactoryTest.class)
 public final strictfp class NamesTest extends TestCase {
     /**
+     * Tests {@link Names#createScopedName(GenericName, String, CharSequence)}.
+     */
+    @Test
+    @DependsOnMethod("testCreateLocalName")
+    public void testCreateScopedName() {
+        final LocalName scope = Names.createLocalName("Apache", null, "sis");
+        final ScopedName name = Names.createScopedName(scope, null, "identifier");
+        assertSame  ("path()",      scope,                   name.path());
+        assertEquals("tail()",      "identifier",            name.tail().toString());
+        assertEquals("toString()",  "sis:identifier",        name.toString());
+        assertEquals("full",        "Apache:sis:identifier", name.toFullyQualifiedName().toString());
+        assertEquals("tail().full", "Apache:sis:identifier", name.tail().toFullyQualifiedName().toString());
+    }
+
+    /**
      * Tests {@link Names#createLocalName(CharSequence, String, CharSequence)}.
      */
     @Test

Modified: sis/branches/JDK9/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/pom.xml?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/pom.xml (original)
+++ sis/branches/JDK9/pom.xml Fri Apr 14 20:47:45 2017
@@ -565,7 +565,7 @@ Apache SIS is a free software, Java lang
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
-        <version>2.19.1</version>
+        <version>2.20</version>
         <configuration>
           <includes>
             <include>**/*TestSuite.java</include>

Modified: sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureNaming.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureNaming.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureNaming.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/FeatureNaming.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -100,11 +100,12 @@ import org.apache.sis.internal.storage.R
 public class FeatureNaming<E> {
     /**
      * All aliases found for all names given to the {@link #add(DataStore, GenericName, Object)} method.
-     * Keys are aliases (never the explicitely given names) and values are names for which the key is an alias.
+     * Keys are aliases and values are the complete names for which the key is an alias.
      * Each {@code List<String>} instance contains exactly one name if there is no ambiguity.
      * If the list contains more than one name, this means that the alias is ambiguous.
      *
-     * <p>Note that this map always have less entries than {@link #values} map.</p>
+     * <p>For saving space in common cases, a missing entry in this map is interpreted as synonymous of
+     * {@code (name, Collections.singletonList(name))} entry.</p>
      */
     private final Map<String, List<String>> aliases;
 
@@ -185,27 +186,47 @@ public class FeatureNaming<E> {
         ArgumentChecks.ensureNonNull("name",  name);
         ArgumentChecks.ensureNonNull("value", value);
         final String key = name.toString();
-        if (values.putIfAbsent(key, value) != null) {
-            throw new IllegalNameException(locale(store), Resources.Keys.FeatureAlreadyPresent_2, name(store), key);
+        final E previous = values.put(key, value);
+        if (previous != null) {
+            final List<String> fullNames = aliases.get(key);            // Null is synonymous of singletonList(key).
+            if (fullNames == null || fullNames.contains(key)) {
+                /*
+                 * If we already had a value for the given name and if that value was associated to a user-specified
+                 * name (not to an alias of that name), then we have a name collision. Restore the previous value.
+                 */
+                if (values.put(key, previous) != value) {
+                    throw new ConcurrentModificationException(name(store).toString());              // Paranoiac check.
+                }
+                throw new IllegalNameException(locale(store), Resources.Keys.FeatureAlreadyPresent_2, name(store), key);
+            }
+            CollectionsExt.addToMultiValuesMap(aliases, key, key);
         }
+        /*
+         * At this point we associated the value to the given name. Now try to associate the same value to all aliases.
+         * In this process, we may discover that some slots are already filled by other values.
+         */
         while (name instanceof ScopedName) {
             name = ((ScopedName) name).tail();
             final String alias = name.toString();
-            if (CollectionsExt.addToMultiValuesMap(aliases, alias, key).size() > 1) {
+            final List<String> fullNames = CollectionsExt.addToMultiValuesMap(aliases, alias, key);
+            if (fullNames.size() > 1) {
                 /*
                  * If there is more than one GenericName for the same alias, we have an ambiguity.
-                 * Remove any value associated to that alias. The 'get' method in this class will
-                 * know that the value is missing because of ambiguous name.
+                 * Remove any value associated to that alias, unless the value was associated to
+                 * exactly the user-specified name (not an alias). The 'get' method in this class
+                 * will know when the value is missing because of ambiguous name.
                  */
-                values.remove(alias);
-            } else if (values.put(alias, value) != null) {
+                if (!fullNames.contains(alias)) {
+                    values.remove(alias);
+                }
+            } else if (values.putIfAbsent(alias, value) != null) {
                 /*
-                 * If no previous GenericName existed for that alias, then no value should exist for that alias.
-                 * If a previous value existed, then (assuming that we do not have a bug in our algorithm) this
-                 * object changed in a concurrent thread during this method execution.  We do not try to detect
-                 * all such errors, but this check is an easy one to perform opportunistically.
+                 * If a value already existed for that alias but the alias was not declared in the 'aliases' map,
+                 * this means that the list was implicitly Collections.singletonList(key). Since we now have an
+                 * additional value, we need to add explicitly the previously implicit value.
                  */
-                throw new ConcurrentModificationException(name(store).toString());
+                assert !fullNames.contains(alias) : alias;
+                CollectionsExt.addToMultiValuesMap(aliases, alias, alias);
             }
         }
     }
@@ -222,16 +243,28 @@ public class FeatureNaming<E> {
      *         representation, but for which {@link ScopedName#tail()} returns different values.
      */
     public boolean remove(final DataStore store, GenericName name) throws IllegalNameException {
-        ArgumentChecks.ensureNonNull("name",  name);
+        ArgumentChecks.ensureNonNull("name", name);
         final String key = name.toString();
         if (values.remove(key) == null) {
             return false;
         }
+        List<String> remaining = CollectionsExt.removeFromMultiValuesMap(aliases, key, key);
+        if (remaining != null && remaining.size() == 1) {
+            /*
+             * If there is exactly one remaining element, that element is a non-ambiguous alias.
+             * So we can associate the value to that alias.
+             */
+            final String select = remaining.get(0);
+            assert !select.equals(key) : select;     // Should have been removed by removeFromMultiValuesMap(…).
+            if (values.put(key, values.get(select)) != null) {
+                throw new ConcurrentModificationException(name(store).toString());          // Paranoiac check.
+            }
+        }
         boolean error = false;
         while (name instanceof ScopedName) {
             name = ((ScopedName) name).tail();
             final String alias = name.toString();
-            final List<String> remaining = CollectionsExt.removeFromMultiValuesMap(aliases, alias, key);
+            remaining = CollectionsExt.removeFromMultiValuesMap(aliases, alias, key);
             /*
              * The list of remaining GenericNames may be empty but should never be null unless the tail
              * is inconsistent with the one found by the 'add(…) method.  Otherwise if there is exactly

Modified: sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/storage/FeatureNamingTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/storage/FeatureNamingTest.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/storage/FeatureNamingTest.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/storage/FeatureNamingTest.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -23,6 +23,7 @@ import org.apache.sis.util.iso.Names;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
+import org.opengis.util.LocalName;
 
 
 /**
@@ -125,6 +126,39 @@ public final strictfp class FeatureNamin
     }
 
     /**
+     * Tests two names having the same tip, but where only one of the two names have a namespace.
+     *
+     * @throws IllegalNameException if an unexpected error occurred while adding or getting an element.
+     */
+    @Test
+    @DependsOnMethod("testAmbiguity")
+    public void testQualifiedAndUnqualifiedName() throws IllegalNameException {
+        final DataStoreMock store = new DataStoreMock("testDataStore");
+        final LocalName local = Names.createLocalName(null, null, "A");
+        FeatureNaming<Integer> map = new FeatureNaming<>();
+        map.add(store, local,  3);
+        map.add(store, A,      2);
+        map.add(store, B,      5);
+        map.add(store, otherA, 7);
+        assertEquals("B",       Integer.valueOf(5), map.get(store, "B"));
+        assertEquals("A",       Integer.valueOf(3), map.get(store, "A"));
+        assertEquals("myNS:A",  Integer.valueOf(2), map.get(store, "myNS:A"));
+        assertEquals("other:A", Integer.valueOf(7), map.get(store, "other:A"));
+        /*
+         * Same tests, but with elements added in different order.
+         */
+        map = new FeatureNaming<>();
+        map.add(store, otherA, 7);
+        map.add(store, B,      5);
+        map.add(store, A,      2);
+        map.add(store, local,  3);
+        assertEquals("B",       Integer.valueOf(5), map.get(store, "B"));
+        assertEquals("A",       Integer.valueOf(3), map.get(store, "A"));
+        assertEquals("myNS:A",  Integer.valueOf(2), map.get(store, "myNS:A"));
+        assertEquals("other:A", Integer.valueOf(7), map.get(store, "other:A"));
+    }
+
+    /**
      * Tests removing an entry. It should change the state about whether an alias is ambiguous or not.
      *
      * @throws IllegalNameException if an unexpected error occurred while adding or getting an element.

Modified: sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/GroupAsPolylineOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/GroupAsPolylineOperation.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/GroupAsPolylineOperation.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/GroupAsPolylineOperation.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -167,7 +167,7 @@ class GroupAsPolylineOperation extends A
                 boolean isFirst = true;
                 geometry = new Polyline();
                 for (final Object child : (Collection<?>) feature.getPropertyValue(association)) {
-                    addGeometry(geometry, ((Feature) child).getPropertyValue("@geometry"), isFirst);
+                    addGeometry(geometry, ((Feature) child).getPropertyValue("sis:geometry"), isFirst);
                     isFirst = false;
                 }
             }

Modified: sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Reader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Reader.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Reader.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Reader.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -409,8 +409,8 @@ parse:  while (reader.hasNext()) {
                     (lat == null) ? Attributes.LATITUDE : Attributes.LONGITUDE, tagName));
         }
         final Feature feature = ((Store) owner).types.wayPoint.newInstance();
-        feature.setPropertyValue("@identifier", index);
-        feature.setPropertyValue("@geometry", new Point(parseDouble(lon), parseDouble(lat)));
+        feature.setPropertyValue("sis:identifier", index);
+        feature.setPropertyValue("sis:geometry", new Point(parseDouble(lon), parseDouble(lat)));
         List<Link> links = null;
         while (true) {
             /*
@@ -474,7 +474,7 @@ parse:  while (reader.hasNext()) {
     private Feature parseRoute(final int index) throws Exception {
         assert reader.isStartElement() && Tags.ROUTES.equals(reader.getLocalName());
         final Feature feature = ((Store) owner).types.route.newInstance();
-        feature.setPropertyValue("@identifier", index);
+        feature.setPropertyValue("sis:identifier", index);
         List<Feature> wayPoints = null;
         List<Link> links = null;
         while (true) {
@@ -530,7 +530,7 @@ parse:  while (reader.hasNext()) {
     private Feature parseTrackSegment(final int index) throws Exception {
         assert reader.isStartElement() && Tags.TRACK_SEGMENTS.equals(reader.getLocalName());
         final Feature feature = ((Store) owner).types.trackSegment.newInstance();
-        feature.setPropertyValue("@identifier", index);
+        feature.setPropertyValue("sis:identifier", index);
         List<Feature> wayPoints = null;
         while (true) {
             /*
@@ -573,7 +573,7 @@ parse:  while (reader.hasNext()) {
     private Feature parseTrack(final int index) throws Exception {
         assert reader.isStartElement() && Tags.TRACKS.equals(reader.getLocalName());
         final Feature feature = ((Store) owner).types.track.newInstance();
-        feature.setPropertyValue("@identifier", index);
+        feature.setPropertyValue("sis:identifier", index);
         List<Feature> segments = null;
         List<Link> links = null;
         while (true) {

Modified: sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Types.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -21,7 +21,7 @@ import java.util.Collections;
 import java.util.Locale;
 import java.util.Map;
 import com.esri.core.geometry.Point;
-import org.opengis.util.LocalName;
+import org.opengis.util.ScopedName;
 import org.opengis.util.NameFactory;
 import org.opengis.util.FactoryException;
 import org.opengis.metadata.citation.OnlineResource;
@@ -108,20 +108,20 @@ final class Types extends Static {
      * @throws FactoryException if an error occurred while creating an "envelope bounds" operation.
      */
     Types(final NameFactory factory, final Locale locale) throws FactoryException, IllegalNameException {
-        final LocalName     geomName = AttributeConvention.GEOMETRY_PROPERTY;
+        final ScopedName    geomName = AttributeConvention.GEOMETRY_PROPERTY;
         final Map<String,?> geomInfo = Collections.singletonMap(AbstractIdentifiedType.NAME_KEY, geomName);
         final Map<String,?> envpInfo = Collections.singletonMap(AbstractIdentifiedType.NAME_KEY, AttributeConvention.ENVELOPE_PROPERTY);
         /*
          * The parent of all FeatureTypes to be created in this constructor.
-         * This parent has a single property, "@identifier" of type Integer,
+         * This parent has a single property, "sis:identifier" of type Integer,
          * which is not part of GPX specification.
          *
          * http://www.topografix.com/GPX/GPXEntity
-         * ┌─────────────┬─────────┬─────────────┐
-         * │ Name        │ Type    │ Cardinality │
-         * ├─────────────┼─────────┼─────────────┤
-         * │ @identifier │ Integer │   [1 … 1]   │      SIS-specific property
-         * └─────────────┴─────────┴─────────────┘
+         * ┌────────────────┬─────────┬─────────────┐
+         * │ Name           │ Type    │ Cardinality │
+         * ├────────────────┼─────────┼─────────────┤
+         * │ sis:identifier │ Integer │   [1 … 1]   │      SIS-specific property
+         * └────────────────┴─────────┴─────────────┘
          */
         FeatureTypeBuilder builder = new FeatureTypeBuilder(null, factory, locale);
         builder.setDefaultScope(Tags.NAMESPACE).setName("GPXEntity").setAbstract(true);
@@ -129,31 +129,31 @@ final class Types extends Static {
         final FeatureType parent = builder.build();
         /*
          * http://www.topografix.com/GPX/WayPoint ⇾ GPXEntity
-         * ┌───────────────┬────────────────┬────────────────────────┬─────────────┐
-         * │ Name          │ Type           │ XML type               │ Cardinality │
-         * ├───────────────┼────────────────┼────────────────────────┼─────────────┤
-         * │ @identifier   │ Integer        │                        │   [1 … 1]   │
-         * │ @envelope     │ Envelope       │                        │   [1 … 1]   │
-         * │ @geometry     │ Point          │ (lat,lon) attributes   │   [1 … 1]   │
-         * │ ele           │ Double         │ xsd:decimal            │   [0 … 1]   │
-         * │ time          │ Temporal       │ xsd:dateTime           │   [0 … 1]   │
-         * │ magvar        │ Double         │ gpx:degreesType        │   [0 … 1]   │
-         * │ geoidheight   │ Double         │ xsd:decimal            │   [0 … 1]   │
-         * │ name          │ String         │ xsd:string             │   [0 … 1]   │
-         * │ cmt           │ String         │ xsd:string             │   [0 … 1]   │
-         * │ desc          │ String         │ xsd:string             │   [0 … 1]   │
-         * │ src           │ String         │ xsd:string             │   [0 … 1]   │
-         * │ link          │ OnlineResource │ gpx:linkType           │   [0 … ∞]   │
-         * │ sym           │ String         │ xsd:string             │   [0 … 1]   │
-         * │ type          │ String         │ xsd:string             │   [0 … 1]   │
-         * │ fix           │ Fix            │ gpx:fixType            │   [0 … 1]   │
-         * │ sat           │ Integer        │ xsd:nonNegativeInteger │   [0 … 1]   │
-         * │ hdop          │ Double         │ xsd:decimal            │   [0 … 1]   │
-         * │ vdop          │ Double         │ xsd:decimal            │   [0 … 1]   │
-         * │ pdop          │ Double         │ xsd:decimal            │   [0 … 1]   │
-         * │ ageofdgpsdata │ Double         │ xsd:decimal            │   [0 … 1]   │
-         * │ dgpsid        │ Integer        │ gpx:dgpsStationType    │   [0 … 1]   │
-         * └───────────────┴────────────────┴────────────────────────┴─────────────┘
+         * ┌──────────────────┬────────────────┬────────────────────────┬─────────────┐
+         * │ Name             │ Type           │ XML type               │ Cardinality │
+         * ├──────────────────┼────────────────┼────────────────────────┼─────────────┤
+         * │ sis:identifier   │ Integer        │                        │   [1 … 1]   │
+         * │ sis:envelope     │ Envelope       │                        │   [1 … 1]   │
+         * │ sis:geometry     │ Point          │ (lat,lon) attributes   │   [1 … 1]   │
+         * │ ele              │ Double         │ xsd:decimal            │   [0 … 1]   │
+         * │ time             │ Temporal       │ xsd:dateTime           │   [0 … 1]   │
+         * │ magvar           │ Double         │ gpx:degreesType        │   [0 … 1]   │
+         * │ geoidheight      │ Double         │ xsd:decimal            │   [0 … 1]   │
+         * │ name             │ String         │ xsd:string             │   [0 … 1]   │
+         * │ cmt              │ String         │ xsd:string             │   [0 … 1]   │
+         * │ desc             │ String         │ xsd:string             │   [0 … 1]   │
+         * │ src              │ String         │ xsd:string             │   [0 … 1]   │
+         * │ link             │ OnlineResource │ gpx:linkType           │   [0 … ∞]   │
+         * │ sym              │ String         │ xsd:string             │   [0 … 1]   │
+         * │ type             │ String         │ xsd:string             │   [0 … 1]   │
+         * │ fix              │ Fix            │ gpx:fixType            │   [0 … 1]   │
+         * │ sat              │ Integer        │ xsd:nonNegativeInteger │   [0 … 1]   │
+         * │ hdop             │ Double         │ xsd:decimal            │   [0 … 1]   │
+         * │ vdop             │ Double         │ xsd:decimal            │   [0 … 1]   │
+         * │ pdop             │ Double         │ xsd:decimal            │   [0 … 1]   │
+         * │ ageofdgpsdata    │ Double         │ xsd:decimal            │   [0 … 1]   │
+         * │ dgpsid           │ Integer        │ gpx:dgpsStationType    │   [0 … 1]   │
+         * └──────────────────┴────────────────┴────────────────────────┴─────────────┘
          */
         builder = new FeatureTypeBuilder(null, factory, locale).setSuperTypes(parent);
         builder.setDefaultScope(Tags.NAMESPACE).setName("WayPoint");
@@ -182,21 +182,21 @@ final class Types extends Static {
         wayPoint = builder.build();
         /*
          * http://www.topografix.com/GPX/Route ⇾ GPXEntity
-         * ┌─────────────┬────────────────┬────────────────────────┬─────────────┐
-         * │ Name        │ Type           │ XML type               │ Cardinality │
-         * ├─────────────┼────────────────┼────────────────────────┼─────────────┤
-         * │ @identifier │ Integer        │                        │   [1 … 1]   │
-         * │ @envelope   │ Envelope       │                        │   [1 … 1]   │
-         * │ @geometry   │ Polyline       │                        │   [1 … 1]   │
-         * │ name        │ String         │ xsd:string             │   [0 … 1]   │
-         * │ cmt         │ String         │ xsd:string             │   [0 … 1]   │
-         * │ desc        │ String         │ xsd:string             │   [0 … 1]   │
-         * │ src         │ String         │ xsd:string             │   [0 … 1]   │
-         * │ link        │ OnlineResource │ gpx:linkType           │   [0 … ∞]   │
-         * │ number      │ Integer        │ xsd:nonNegativeInteger │   [0 … 1]   │
-         * │ type        │ String         │ xsd:string             │   [0 … 1]   │
-         * │ rtept       │ WayPoint       │ gpx:wptType            │   [0 … ∞]   │
-         * └─────────────┴────────────────┴────────────────────────┴─────────────┘
+         * ┌────────────────┬────────────────┬────────────────────────┬─────────────┐
+         * │ Name           │ Type           │ XML type               │ Cardinality │
+         * ├────────────────┼────────────────┼────────────────────────┼─────────────┤
+         * │ sis:identifier │ Integer        │                        │   [1 … 1]   │
+         * │ sis:envelope   │ Envelope       │                        │   [1 … 1]   │
+         * │ sis:geometry   │ Polyline       │                        │   [1 … 1]   │
+         * │ name           │ String         │ xsd:string             │   [0 … 1]   │
+         * │ cmt            │ String         │ xsd:string             │   [0 … 1]   │
+         * │ desc           │ String         │ xsd:string             │   [0 … 1]   │
+         * │ src            │ String         │ xsd:string             │   [0 … 1]   │
+         * │ link           │ OnlineResource │ gpx:linkType           │   [0 … ∞]   │
+         * │ number         │ Integer        │ xsd:nonNegativeInteger │   [0 … 1]   │
+         * │ type           │ String         │ xsd:string             │   [0 … 1]   │
+         * │ rtept          │ WayPoint       │ gpx:wptType            │   [0 … ∞]   │
+         * └────────────────┴────────────────┴────────────────────────┴─────────────┘
          */
         GroupAsPolylineOperation groupOp = new GroupPointsAsPolylineOperation(geomInfo, Tags.ROUTE_POINTS);
         builder = new FeatureTypeBuilder(null, factory, locale).setSuperTypes(parent);
@@ -215,14 +215,14 @@ final class Types extends Static {
         route = builder.build();
         /*
          * http://www.topografix.com/GPX/TrackSegment ⇾ GPXEntity
-         * ┌─────────────┬──────────┬─────────────┬─────────────┐
-         * │ Name        │ Type     │ XML type    │ Cardinality │
-         * ├─────────────┼──────────┼─────────────┼─────────────┤
-         * │ @identifier │ Integer  │             │   [1 … 1]   │
-         * │ @envelope   │ Envelope │             │   [1 … 1]   │
-         * │ @geometry   │ Polyline │             │   [1 … 1]   │
-         * │ trkpt       │ WayPoint │ gpx:wptType │   [0 … ∞]   │
-         * └─────────────┴──────────┴─────────────┴─────────────┘
+         * ┌────────────────┬──────────┬─────────────┬─────────────┐
+         * │ Name           │ Type     │ XML type    │ Cardinality │
+         * ├────────────────┼──────────┼─────────────┼─────────────┤
+         * │ sis:identifier │ Integer  │             │   [1 … 1]   │
+         * │ sis:envelope   │ Envelope │             │   [1 … 1]   │
+         * │ sis:geometry   │ Polyline │             │   [1 … 1]   │
+         * │ trkpt          │ WayPoint │ gpx:wptType │   [0 … ∞]   │
+         * └────────────────┴──────────┴─────────────┴─────────────┘
          */
         groupOp = new GroupPointsAsPolylineOperation(geomInfo, Tags.TRACK_POINTS);
         builder = new FeatureTypeBuilder(null, factory, locale).setSuperTypes(parent);
@@ -234,21 +234,21 @@ final class Types extends Static {
         trackSegment = builder.build();
         /*
          * http://www.topografix.com/GPX/Track ⇾ GPXEntity
-         * ┌─────────────┬────────────────┬────────────────────────┬─────────────┐
-         * │ Name        │ Type           │ XML type               │ Cardinality │
-         * ├─────────────┼────────────────┼────────────────────────┼─────────────┤
-         * │ @identifier │ Integer        │                        │   [1 … 1]   │
-         * │ @envelope   │ Envelope       │                        │   [1 … 1]   │
-         * │ @geometry   │ Polyline       │                        │   [1 … 1]   │
-         * │ name        │ String         │ xsd:string             │   [0 … 1]   │
-         * │ cmt         │ String         │ xsd:string             │   [0 … 1]   │
-         * │ desc        │ String         │ xsd:string             │   [0 … 1]   │
-         * │ src         │ String         │ xsd:string             │   [0 … 1]   │
-         * │ link        │ OnlineResource │ gpx:linkType           │   [0 … ∞]   │
-         * │ number      │ Integer        │ xsd:nonNegativeInteger │   [0 … 1]   │
-         * │ type        │ String         │ xsd:string             │   [0 … 1]   │
-         * │ trkseg      │ TrackSegment   │ gpx:trksegType         │   [0 … ∞]   │
-         * └─────────────┴────────────────┴────────────────────────┴─────────────┘
+         * ┌────────────────┬────────────────┬────────────────────────┬─────────────┐
+         * │ Name           │ Type           │ XML type               │ Cardinality │
+         * ├────────────────┼────────────────┼────────────────────────┼─────────────┤
+         * │ sis:identifier │ Integer        │                        │   [1 … 1]   │
+         * │ sis:envelope   │ Envelope       │                        │   [1 … 1]   │
+         * │ sis:geometry   │ Polyline       │                        │   [1 … 1]   │
+         * │ name           │ String         │ xsd:string             │   [0 … 1]   │
+         * │ cmt            │ String         │ xsd:string             │   [0 … 1]   │
+         * │ desc           │ String         │ xsd:string             │   [0 … 1]   │
+         * │ src            │ String         │ xsd:string             │   [0 … 1]   │
+         * │ link           │ OnlineResource │ gpx:linkType           │   [0 … ∞]   │
+         * │ number         │ Integer        │ xsd:nonNegativeInteger │   [0 … 1]   │
+         * │ type           │ String         │ xsd:string             │   [0 … 1]   │
+         * │ trkseg         │ TrackSegment   │ gpx:trksegType         │   [0 … ∞]   │
+         * └────────────────┴────────────────┴────────────────────────┴─────────────┘
          */
         groupOp = new GroupAsPolylineOperation(geomInfo, Tags.TRACK_SEGMENTS);
         builder = new FeatureTypeBuilder(null, factory, locale).setSuperTypes(parent);

Modified: sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Writer.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Writer.java?rev=1791413&r1=1791412&r2=1791413&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Writer.java [UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Writer.java [UTF-8] Fri Apr 14 20:47:45 2017
@@ -191,7 +191,7 @@ final class Writer extends StaxStreamWri
      */
     private void writeWayPoint(final Feature feature, final String tagName) throws XMLStreamException, JAXBException {
         if (feature != null) {
-            final Point pt = (Point) feature.getPropertyValue("@geometry");
+            final Point pt = (Point) feature.getPropertyValue("sis:geometry");
             writer.writeStartElement(tagName);
             writer.writeAttribute(Attributes.LATITUDE, Double.toString(pt.getY()));
             writer.writeAttribute(Attributes.LONGITUDE, Double.toString(pt.getX()));



Mime
View raw message