sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1753294 [1/3] - in /sis/trunk: ./ core/sis-build-helper/src/main/ant/ 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/inter...
Date Mon, 18 Jul 2016 17:47:23 GMT
Author: desruisseaux
Date: Mon Jul 18 17:47:22 2016
New Revision: 1753294

URL: http://svn.apache.org/viewvc?rev=1753294&view=rev
Log:
Merge from the JDK6 branch.

Added:
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/
      - copied from r1753266, sis/branches/JDK6/core/sis-feature/src/main/java/org/apache/sis/feature/builder/
    sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/builder/
      - copied from r1753266, sis/branches/JDK6/core/sis-feature/src/test/java/org/apache/sis/feature/builder/
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LambertCylindricalEqualArea.java
      - copied unchanged from r1753266, sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LambertCylindricalEqualArea.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LambertCylindricalEqualAreaSpherical.java
      - copied unchanged from r1753266, sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LambertCylindricalEqualAreaSpherical.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/CylindricalEqualArea.java
      - copied unchanged from r1753266, sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/CylindricalEqualArea.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/EqualAreaProjection.java
      - copied unchanged from r1753266, sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/EqualAreaProjection.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/CylindricalEqualAreaTest.java
      - copied, changed from r1753266, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/CylindricalEqualAreaTest.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/UncheckedIOException.java
      - copied unchanged from r1753266, sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/UncheckedIOException.java
Removed:
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Builder.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/internal/feature/FeatureTypeBuilder.java
    sis/trunk/core/sis-feature/src/test/java/org/apache/sis/internal/feature/FeatureTypeBuilderTest.java
Modified:
    sis/trunk/   (props changed)
    sis/trunk/core/sis-build-helper/src/main/ant/prepare-release.xml
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAssociation.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAttribute.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractOperation.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/EnvelopeOperation.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/StringJoinOperation.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AssociationRoleBuilder.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeTypeBuilder.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/CharacteristicTypeBuilder.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/PropertyTypeBuilder.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/TypeBuilder.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java
    sis/trunk/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
    sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/AbstractOperationTest.java
    sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/EnvelopeOperationTest.java
    sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java
    sis/trunk/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/DefaultMetadata.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AbstractStereographic.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricAffine.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LambertConformal2SP.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/MapProjection.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Mercator2SP.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/ObliqueStereographic.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicA.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicB.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PolarStereographicSouth.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/RegionalMercator.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/TransverseMercator.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/package-info.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterBuilder.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/package-info.java
    sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransformTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MolodenskyTransformTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/HTMLGenerator.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/package-info.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/math/MathFunctions.java
    sis/trunk/ide-project/NetBeans/build.xml

Propchange: sis/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jul 18 17:47:22 2016
@@ -1,4 +1,4 @@
 /sis/branches/Android:1430670-1480699
-/sis/branches/JDK6:1394364-1750766
-/sis/branches/JDK7:1394913-1750764
-/sis/branches/JDK8:1584960-1750763
+/sis/branches/JDK6:1394364-1753266
+/sis/branches/JDK7:1394913-1753262
+/sis/branches/JDK8:1584960-1753248

Modified: sis/trunk/core/sis-build-helper/src/main/ant/prepare-release.xml
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-build-helper/src/main/ant/prepare-release.xml?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-build-helper/src/main/ant/prepare-release.xml (original)
+++ sis/trunk/core/sis-build-helper/src/main/ant/prepare-release.xml Mon Jul 18 17:47:22 2016
@@ -32,7 +32,7 @@
     <!-- Ensure that the "sis-build-helper" plugin used by the build is the released version. -->
     <replaceregexp file = "${user.dir}/pom.xml"
                   match = "&lt;sis\.plugin\.version&gt;.+&lt;/sis\.plugin\.version&gt;"
-                replace = "&lt;sis.plugin.version&gt;${sis.version}-SNAPSHOT&lt;/sis.plugin.version&gt;"/>
+                replace = "&lt;sis.plugin.version&gt;${branch.version}-SNAPSHOT&lt;/sis.plugin.version&gt;"/>
                 <!-- The -SNAPSHOT part will be removed later, at tag creation. -->
 
     <!-- Replace the version number in Java code. -->
@@ -44,9 +44,9 @@
     <replace dir="${user.dir}" failOnNoReplacements="true">
       <include name="**/pom.xml"/>
       <replacefilter token="svn.apache.org/repos/asf/sis/trunk"
-                     value="svn.apache.org/repos/asf/sis/branches/${sis.version}"/>
+                     value="svn.apache.org/repos/asf/sis/branches/${branch.version}"/>
       <replacefilter token="svn.apache.org/viewvc/sis/trunk"
-                     value="svn.apache.org/viewvc/sis/branches/${sis.version}"/>
+                     value="svn.apache.org/viewvc/sis/branches/${branch.version}"/>
     </replace>
   </target>
 
@@ -58,18 +58,18 @@
     <!-- Replace URL to branch by URL to the branch on Subversion. -->
     <replace dir="${user.dir}" failOnNoReplacements="true">
       <include name="**/pom.xml"/>
-      <replacefilter token="svn.apache.org/repos/asf/sis/branches/${sis.version}"
+      <replacefilter token="svn.apache.org/repos/asf/sis/branches/${branch.version}"
                      value="svn.apache.org/repos/asf/sis/tags/${sis.version}"/>
-      <replacefilter token="svn.apache.org/viewvc/sis/branches/${sis.version}"
+      <replacefilter token="svn.apache.org/viewvc/sis/branches/${branch.version}"
                      value="svn.apache.org/viewvc/sis/tags/${sis.version}"/>
     </replace>
 
     <!-- Replace version numbers. Note that no snapshot other than SIS can exist at this point. -->
     <replace dir="${user.dir}" failOnNoReplacements="true">
       <include name="**/pom.xml"/>
-      <replacefilter token="&lt;version&gt;${sis.version}-SNAPSHOT&lt;/version&gt;"
+      <replacefilter token="&lt;version&gt;${branch.version}-SNAPSHOT&lt;/version&gt;"
                      value="&lt;version&gt;${sis.version}&lt;/version&gt;"/>
-      <replacefilter token="&lt;sis.plugin.version&gt;${sis.version}-SNAPSHOT&lt;/sis.plugin.version&gt;"
+      <replacefilter token="&lt;sis.plugin.version&gt;${branch.version}-SNAPSHOT&lt;/sis.plugin.version&gt;"
                      value="&lt;sis.plugin.version&gt;${sis.version}&lt;/sis.plugin.version&gt;"/>
     </replace>
   </target>

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAssociation.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAssociation.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAssociation.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAssociation.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -44,7 +44,8 @@ import org.apache.sis.util.resources.Err
  * @version 0.6
  * @module
  *
- * @see DefaultAssociationRole#newInstance()
+ * @see AbstractFeature
+ * @see DefaultAssociationRole
  */
 public abstract class AbstractAssociation extends Field<AbstractFeature> implements Cloneable, Serializable {
     /**

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAttribute.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAttribute.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAttribute.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractAttribute.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -69,7 +69,8 @@ import org.apache.sis.internal.jdk7.JDK7
  * @version 0.6
  * @module
  *
- * @see DefaultAttributeType#newInstance()
+ * @see AbstractFeature
+ * @see DefaultAttributeType
  */
 public abstract class AbstractAttribute<V> extends Field<V> implements Cloneable, Serializable {
     /**

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractIdentifiedType.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -232,7 +232,7 @@ public class AbstractIdentifiedType impl
      * Returns a natural language designator for the element.
      * This can be used as an alternative to the {@linkplain #getName() name} in user interfaces.
      *
-     * @return Natural language designator for the element.
+     * @return Natural language designator for the element, or {@code null} if none.
      */
     public InternationalString getDesignation() {
         return designation;

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractOperation.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractOperation.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractOperation.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractOperation.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -25,6 +25,7 @@ import org.opengis.parameter.GeneralPara
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.parameter.ParameterValueGroup;
 import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.util.Classes;
 import org.apache.sis.util.Debug;
 
 // Branch-dependent imports
@@ -51,8 +52,10 @@ import org.apache.sis.internal.jdk7.Obje
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
- * @version 0.6
+ * @version 0.8
  * @module
+ *
+ * @see DefaultFeatureType
  */
 public abstract class AbstractOperation extends AbstractIdentifiedType {
     /**
@@ -78,7 +81,11 @@ public abstract class AbstractOperation
 
     /**
      * Returns a map that can be used for creating the {@link #getResult()} type.
-     * This method can be invoked for subclass constructor.
+     * This method can be invoked for subclass constructor with the user-supplied map in argument.
+     * If the given map contains at least one key prefixed by {@value #RESULT_PREFIX}, then the values
+     * associated to those keys will be used.
+     *
+     * @param identification the map given by user to sub-class constructor.
      */
     final Map<String,Object> resultIdentification(final Map<String,?> identification) {
         final Map<String,Object> properties = new HashMap<String,Object>(6);
@@ -203,12 +210,12 @@ public abstract class AbstractOperation
      * Returns a string representation of this operation.
      * The returned string is for debugging purpose and may change in any future SIS version.
      *
-     * @return A string representation of this operation for debugging purpose.
+     * @return a string representation of this operation for debugging purpose.
      */
     @Debug
     @Override
     public String toString() {
-        final StringBuilder buffer = new StringBuilder(40).append("Operation").append('[');
+        final StringBuilder buffer = new StringBuilder(40).append(Classes.getShortClassName(this)).append('[');
         final GenericName name = getName();
         if (name != null) {
             buffer.append('“');
@@ -222,13 +229,31 @@ public abstract class AbstractOperation
             buffer.append(separator).append(IdentifiedObjects.toString(param.getName()));
             separator = ", ";
         }
-        if (separator == ", ") { // Identity comparaison is okay here.
+        if (separator == ", ") {                    // Identity comparaison is okay here.
             buffer.append(')');
         }
         final AbstractIdentifiedType result = getResult();
         if (result != null) {
-            buffer.append(" : ").append(result.getName());
+            final Object type;
+            if (result instanceof DefaultAttributeType<?>) {
+                type = Classes.getShortName(((DefaultAttributeType<?>) result).getValueClass());
+            } else {
+                type = result.getName();
+            }
+            buffer.append(" : ").append(type);
         }
-        return buffer.append(']').toString();
+        formatResultFormula(buffer.append(']'));
+        return buffer.toString();
+    }
+
+    /**
+     * Appends a string representation of the "formula" used for computing the result.
+     * The "formula" may be for example a link to another property.
+     *
+     * @param  buffer where to format the "formula".
+     * @return {@code true} if this method has formatted a formula, or {@code false} otherwise.
+     */
+    boolean formatResultFormula(Appendable buffer) {
+        return false;
     }
 }

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -50,6 +50,7 @@ import static org.apache.sis.util.Argume
  * @version 0.5
  * @module
  *
+ * @see DefaultFeatureType
  * @see AbstractAssociation
  */
 public class DefaultAssociationRole extends FieldType {
@@ -113,6 +114,8 @@ public class DefaultAssociationRole exte
      * @param minimumOccurs  The minimum number of occurrences of the association within its containing entity.
      * @param maximumOccurs  The maximum number of occurrences of the association within its containing entity,
      *                       or {@link Integer#MAX_VALUE} if there is no restriction.
+     *
+     * @see org.apache.sis.feature.builder.AssociationRoleBuilder
      */
     public DefaultAssociationRole(final Map<String,?> identification, final DefaultFeatureType valueType,
             final int minimumOccurs, final int maximumOccurs)

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -105,6 +105,7 @@ import org.apache.sis.internal.jdk7.Obje
  * @version 0.5
  * @module
  *
+ * @see DefaultFeatureType
  * @see AbstractAttribute
  */
 public class DefaultAttributeType<V> extends FieldType {
@@ -179,6 +180,8 @@ public class DefaultAttributeType<V> ext
      *                        For example if this new {@code DefaultAttributeType} describes a measurement,
      *                        then {@code characterizedBy} could holds the measurement accuracy.
      *                        See <cite>"Attribute characterization"</cite> in class Javadoc for more information.
+     *
+     * @see org.apache.sis.feature.builder.AttributeTypeBuilder
      */
     public DefaultAttributeType(final Map<String,?> identification, final Class<V> valueClass,
             final int minimumOccurs, final int maximumOccurs, final V defaultValue,

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -79,6 +79,12 @@ import org.apache.sis.internal.jdk8.JDK8
  * which are implicitly <cite>covariant</cite> (i.e. {@code String[]} can be casted to {@code CharSequence[]}, which
  * is safe for read operations but not for write operations — the later may throw {@link ArrayStoreException}).</div>
  *
+ * <div class="section">Instantiation</div>
+ * {@code DefaultFeatureType} can be instantiated directly by a call to its {@linkplain #DefaultFeatureType constructor}.
+ * But a more convenient approach may be to use the {@link org.apache.sis.feature.builder.FeatureTypeBuilder} instead,
+ * which provides shortcuts for frequently-used operations like creating various {@link org.opengis.util.GenericName}
+ * instances sharing the same namespace.
+ *
  * <div class="section">Immutability and thread safety</div>
  * Instances of this class are immutable if all properties ({@link GenericName} and {@link InternationalString}
  * instances) and all arguments ({@link AttributeType} instances) given to the constructor are also immutable.
@@ -90,6 +96,8 @@ import org.apache.sis.internal.jdk8.JDK8
  * @version 0.6
  * @module
  *
+ * @see DefaultAttributeType
+ * @see DefaultAssociationRole
  * @see AbstractFeature
  */
 public class DefaultFeatureType extends AbstractIdentifiedType implements FeatureType {
@@ -236,6 +244,8 @@ public class DefaultFeatureType extends
      * @param superTypes     The parents of this feature type, or {@code null} or empty if none.
      * @param properties     Any feature operation, any feature attribute type and any feature
      *                       association role that carries characteristics of a feature type.
+     *
+     * @see org.apache.sis.feature.builder.FeatureTypeBuilder
      */
     @SuppressWarnings("ThisEscapedInObjectConstruction")
     public DefaultFeatureType(final Map<String,?> identification, final boolean isAbstract,

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/EnvelopeOperation.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/EnvelopeOperation.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/EnvelopeOperation.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/EnvelopeOperation.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -136,7 +136,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.DEFAULT_GEOMETRY_PROPERTY.equals(name.tip());
+                final boolean isDefault = AttributeConvention.GEOMETRY_PROPERTY.equals(name.tip());
                 if (isDefault) {
                     defaultGeometry = attributeName;
                 }

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -32,6 +32,7 @@ import org.opengis.util.InternationalStr
 import org.opengis.util.GenericName;
 import org.apache.sis.io.TableAppender;
 import org.apache.sis.io.TabularFormat;
+import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.resources.Vocabulary;
@@ -202,7 +203,7 @@ header: for (int i=0; ; i++) {
         final StringBuffer  buffer  = new StringBuffer();
         final FieldPosition dummyFP = new FieldPosition(-1);
         for (final AbstractIdentifiedType propertyType : featureType.getProperties(true)) {
-            Object value;
+            Object value = null;
             if (feature != null) {
                 value = feature.getPropertyValue(propertyType.getName().toString());
                 if (value == null) {
@@ -212,8 +213,11 @@ header: for (int i=0; ; i++) {
                 }
             } else if (propertyType instanceof DefaultAttributeType<?>) {
                 value = ((DefaultAttributeType<?>) propertyType).getDefaultValue();
-            } else {
-                value = null;
+            } else if (propertyType instanceof AbstractOperation) {
+                if (((AbstractOperation) propertyType).formatResultFormula(buffer)) {
+                    value = CharSequences.trimWhitespaces(buffer).toString();
+                    buffer.setLength(0);
+                }
             }
             /*
              * Column 0 - Name.
@@ -223,31 +227,31 @@ header: for (int i=0; ; i++) {
             /*
              * Column 1 and 2 - Type and cardinality.
              */
-            final String   valueType;
-            final Class<?> valueClass;
-            final int minimumOccurs, maximumOccurs;
-            if (propertyType instanceof DefaultAttributeType<?>) {
-                final DefaultAttributeType<?> pt = (DefaultAttributeType<?>) propertyType;
+            final String   valueType;                       // The value to write in the type column.
+            final Class<?> valueClass;                      // AttributeType.getValueClass() if applicable.
+            final int minimumOccurs, maximumOccurs;         // Negative values mean no cardinality.
+            final AbstractIdentifiedType resultType;        // Result of operation if applicable.
+            if (propertyType instanceof AbstractOperation) {
+                resultType = ((AbstractOperation) propertyType).getResult();
+            } else {
+                resultType = propertyType;
+            }
+            if (resultType instanceof DefaultAttributeType<?>) {
+                final DefaultAttributeType<?> pt = (DefaultAttributeType<?>) resultType;
                 minimumOccurs = pt.getMinimumOccurs();
                 maximumOccurs = pt.getMaximumOccurs();
                 valueClass    = pt.getValueClass();
                 valueType     = getFormat(Class.class).format(valueClass, buffer, dummyFP).toString();
                 buffer.setLength(0);
-            } else if (propertyType instanceof DefaultAssociationRole) {
-                final DefaultAssociationRole pt = (DefaultAssociationRole) propertyType;
+            } else if (resultType instanceof DefaultAssociationRole) {
+                final DefaultAssociationRole pt = (DefaultAssociationRole) resultType;
                 minimumOccurs = pt.getMinimumOccurs();
                 maximumOccurs = pt.getMaximumOccurs();
                 valueType     = toString(DefaultAssociationRole.getValueTypeName(pt));
                 valueClass    = AbstractFeature.class;
-            } else if (propertyType instanceof AbstractOperation) {
-                final AbstractIdentifiedType resultType = ((AbstractOperation) propertyType).getResult();
-                valueType   = toString(resultType.getName());
-                valueClass  = null;
-                minimumOccurs = -1;
-                maximumOccurs = -1;
             } else {
-                valueType   = "";
-                valueClass  = null;
+                valueType  = toString(resultType.getName());
+                valueClass = null;
                 minimumOccurs = -1;
                 maximumOccurs = -1;
             }
@@ -305,7 +309,7 @@ header: for (int i=0; ; i++) {
                         Object c = attribute.getDefaultValue();
                         if (feature != null) {
                             final Object p = feature.getProperty(propertyType.getName().toString());
-                            if (p instanceof AbstractAttribute<?>) {    // Should always be true, but we are paranoiac.
+                            if (p instanceof AbstractAttribute<?>) {      // Should always be true, but we are paranoiac.
                                 c = ((AbstractAttribute<?>) p).characteristics().get(attribute.getName().toString());
                             }
                         }

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -129,7 +129,7 @@ public final class FeatureOperations ext
      * For example features of type <b>Country</b> may have identifiers named “ISO country code”
      * while features of type <b>Car</b> may have identifiers named “license plate number”.
      * In order to simplify identifier usages regardless of their name,
-     * an application could choose to add in all features a virtual property named {@code "@id"}
+     * an application could choose to add in all features a virtual property named {@code "identifier"}
      * which links to whatever property is used as an identifier in an arbitrary feature.
      * So the definition of the <b>Car</b> feature could contain the following code:
      *
@@ -137,7 +137,7 @@ public final class FeatureOperations ext
      *   AttributeType licensePlateNumber = ...;            // Attribute creation omitted for brevity
      *   FeatureType car = new DefaultFeatureType(...,      // Arguments omitted for brevity
      *           licensePlateNumber, model, owner,
-     *           FeatureOperations.link(singletonMap(NAME_KEY, "@id"), licensePlateNumber);
+     *           FeatureOperations.link(singletonMap(NAME_KEY, "identifier"), licensePlateNumber);
      * }
      * </div>
      *

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -20,6 +20,7 @@ import java.util.Set;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Collections;
+import java.io.IOException;
 import org.opengis.metadata.Identifier;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptor;
@@ -28,6 +29,9 @@ import org.apache.sis.parameter.DefaultP
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.util.ArgumentChecks;
 
+// Branch-dependent imports
+import org.apache.sis.internal.jdk8.UncheckedIOException;
+
 
 /**
  * A link operation, which is like a redirection or an alias.
@@ -145,4 +149,20 @@ final class LinkOperation extends Abstra
         // 'this.result' is compared (indirectly) by the super class.
         return super.equals(obj) && referentName.equals(((LinkOperation) obj).referentName);
     }
+
+    /**
+     * Appends a string representation of the "formula" used for computing the result.
+     *
+     * @param  buffer where to format the "formula".
+     * @return {@code true} since this method has formatted a formula.
+     */
+    @Override
+    boolean formatResultFormula(final Appendable buffer) {
+        try {
+            buffer.append(" → ").append(referentName);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+        return true;
+    }
 }

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/StringJoinOperation.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/StringJoinOperation.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/StringJoinOperation.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/StringJoinOperation.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -19,6 +19,7 @@ package org.apache.sis.feature;
 import java.util.Arrays;
 import java.util.Map;
 import java.util.Set;
+import java.io.IOException;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.util.GenericName;
@@ -33,6 +34,7 @@ import org.apache.sis.util.Classes;
 
 // Branch-dependent imports
 import org.apache.sis.internal.jdk7.Objects;
+import org.apache.sis.internal.jdk8.UncheckedIOException;
 
 
 /**
@@ -414,4 +416,26 @@ final class StringJoinOperation extends
         }
         return false;
     }
+
+    /**
+     * Appends a string representation of the "formula" used for computing the result.
+     *
+     * @param  buffer where to format the "formula".
+     * @return {@code true} since this method has formatted a formula.
+     */
+    @Override
+    boolean formatResultFormula(final Appendable buffer) {
+        try {
+            buffer.append(" → ");
+            String separator = "(";
+            for (final String element : attributeNames) {
+                buffer.append(separator).append(element);
+                separator = ", ";
+            }
+            buffer.append(')');
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+        return true;
+    }
 }

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AssociationRoleBuilder.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AssociationRoleBuilder.java?rev=1753294&r1=1753266&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AssociationRoleBuilder.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AssociationRoleBuilder.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -18,9 +18,10 @@ package org.apache.sis.feature.builder;
 
 import org.opengis.util.GenericName;
 import org.apache.sis.feature.DefaultAssociationRole;
-import org.opengis.feature.FeatureType;
-import org.opengis.feature.PropertyType;
-import org.opengis.feature.FeatureAssociationRole;
+
+// Branch-dependent imports
+import org.apache.sis.feature.AbstractIdentifiedType;
+import org.apache.sis.feature.DefaultFeatureType;
 
 
 /**
@@ -43,7 +44,7 @@ public final class AssociationRoleBuilde
     /**
      * The target feature type, or {@code null} if unknown.
      */
-    private final FeatureType type;
+    private final DefaultFeatureType type;
 
     /**
      * Name of the target feature type (never null).
@@ -56,7 +57,7 @@ public final class AssociationRoleBuilde
      *
      * @param owner  the builder of the {@code FeatureType} for which to add this property.
      */
-    AssociationRoleBuilder(final FeatureTypeBuilder owner, final FeatureType type, final GenericName typeName) {
+    AssociationRoleBuilder(final FeatureTypeBuilder owner, final DefaultFeatureType type, final GenericName typeName) {
         super(owner, null);
         this.type     = type;
         this.typeName = typeName;
@@ -67,7 +68,7 @@ public final class AssociationRoleBuilde
      *
      * @param owner  the builder of the {@code FeatureType} for which to add this property.
      */
-    AssociationRoleBuilder(final FeatureTypeBuilder owner, final FeatureAssociationRole template) {
+    AssociationRoleBuilder(final FeatureTypeBuilder owner, final DefaultAssociationRole template) {
         super(owner, template);
         minimumOccurs = template.getMinimumOccurs();
         maximumOccurs = template.getMaximumOccurs();
@@ -165,7 +166,7 @@ public final class AssociationRoleBuilde
      * Creates a new property type from the current setting.
      */
     @Override
-    final PropertyType create() {
+    final AbstractIdentifiedType create() {
         if (type != null) {
             return new DefaultAssociationRole(identification(), type, minimumOccurs, maximumOccurs);
         } else {

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeTypeBuilder.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeTypeBuilder.java?rev=1753294&r1=1753266&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeTypeBuilder.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/AttributeTypeBuilder.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -31,9 +31,7 @@ import org.apache.sis.util.Classes;
 
 // Branch-dependent imports
 import java.util.Objects;
-import org.opengis.feature.AttributeType;
-import org.opengis.feature.Feature;
-import org.opengis.feature.PropertyType;
+import org.apache.sis.feature.AbstractIdentifiedType;
 
 
 /**
@@ -89,13 +87,13 @@ public final class AttributeTypeBuilder<
      *
      * @param owner  the builder of the {@code FeatureType} for which to add this property.
      */
-    AttributeTypeBuilder(final FeatureTypeBuilder owner, final AttributeType<V> template) {
+    AttributeTypeBuilder(final FeatureTypeBuilder owner, final DefaultAttributeType<V> template) {
         super(owner, template);
         minimumOccurs = template.getMinimumOccurs();
         maximumOccurs = template.getMaximumOccurs();
         valueClass    = template.getValueClass();
         defaultValue  = template.getDefaultValue();
-        for (final AttributeType<?> c : template.characteristics().values()) {
+        for (final DefaultAttributeType<?> c : template.characteristics().values()) {
             characteristics.add(new CharacteristicTypeBuilder(this, c));
         }
     }
@@ -255,9 +253,6 @@ public final class AttributeTypeBuilder<
      * @see #characteristics()
      */
     public <C> CharacteristicTypeBuilder<C> addCharacteristic(final Class<C> type) {
-        if (valueClass == Feature.class) {
-            throw new UnsupportedOperationException(errors().getString(Errors.Keys.IllegalOperationForValueClass_1, valueClass));
-        }
         ensureNonNull("type", type);
         final CharacteristicTypeBuilder<C> characteristic = new CharacteristicTypeBuilder<C>(this, type);
         characteristics.add(characteristic);
@@ -269,13 +264,17 @@ public final class AttributeTypeBuilder<
      * Adds another attribute type that describes this attribute type, using an existing one as a template.
      * See <cite>"Attribute characterization"</cite> in {@link DefaultAttributeType} Javadoc for more information.
      *
+     * <div class="warning"><b>Warning:</b>
+     * The {@code template} argument type will be changed to {@code AttributeType} if and when such interface
+     * will be defined in GeoAPI.</div>
+     *
      * @param  <C>       the compile-time type of values in the {@code template} argument.
      * @param  template  an existing attribute type to use as a template.
      * @return a builder for a characteristic of this attribute, initialized with the values of the given template.
      *
      * @see #characteristics()
      */
-    public <C> CharacteristicTypeBuilder<C> addCharacteristic(final AttributeType<C> template) {
+    public <C> CharacteristicTypeBuilder<C> addCharacteristic(final DefaultAttributeType<C> template) {
         ensureNonNull("template", template);
         final CharacteristicTypeBuilder<C> characteristic = new CharacteristicTypeBuilder<C>(this, template);
         characteristics.add(characteristic);
@@ -380,8 +379,8 @@ public final class AttributeTypeBuilder<
      * Creates a new property type from the current setting.
      */
     @Override
-    final PropertyType create() {
-        final AttributeType<?>[] chrts = new AttributeType<?>[characteristics.size()];
+    final AbstractIdentifiedType create() {
+        final DefaultAttributeType<?>[] chrts = new DefaultAttributeType<?>[characteristics.size()];
         for (int i=0; i<chrts.length; i++) {
             chrts[i] = characteristics.get(i).build();
         }

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/CharacteristicTypeBuilder.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/CharacteristicTypeBuilder.java?rev=1753294&r1=1753266&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/CharacteristicTypeBuilder.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/CharacteristicTypeBuilder.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -22,7 +22,6 @@ import org.apache.sis.util.Classes;
 
 // Branch-dependent imports
 import java.util.Objects;
-import org.opengis.feature.AttributeType;
 
 
 /**
@@ -63,7 +62,7 @@ public final class CharacteristicTypeBui
      * The characteristic created by this builder, or {@code null} if not yet created.
      * This field must be cleared every time that a setter method is invoked on this builder.
      */
-    private transient AttributeType<V> characteristic;
+    private transient DefaultAttributeType<V> characteristic;
 
     /**
      * Creates a new characteristic builder for values of the given class.
@@ -82,7 +81,7 @@ public final class CharacteristicTypeBui
      *
      * @param owner  the builder of the {@code AttributeType} for which to add this property.
      */
-    CharacteristicTypeBuilder(final AttributeTypeBuilder<?> owner, final AttributeType<V> template) {
+    CharacteristicTypeBuilder(final AttributeTypeBuilder<?> owner, final DefaultAttributeType<V> template) {
         super(template, owner.getLocale());
         this.owner     = owner;
         valueClass     = template.getValueClass();
@@ -210,7 +209,7 @@ public final class CharacteristicTypeBui
     /**
      * Creates a new characteristic from the current setting.
      */
-    final AttributeType<V> build() {
+    final DefaultAttributeType<V> build() {
         if (characteristic == null) {
             characteristic = new DefaultAttributeType<V>(identification(), valueClass, 0, 1, defaultValue);
         }

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java?rev=1753294&r1=1753266&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -36,11 +36,10 @@ import org.apache.sis.util.ArraysExt;
 
 // Branch-dependent imports
 import java.util.Objects;
-import org.opengis.feature.AttributeType;
-import org.opengis.feature.Feature;
-import org.opengis.feature.FeatureType;
-import org.opengis.feature.PropertyType;
-import org.opengis.feature.FeatureAssociationRole;
+import org.apache.sis.feature.AbstractFeature;
+import org.apache.sis.feature.AbstractIdentifiedType;
+import org.apache.sis.feature.DefaultAssociationRole;
+import org.apache.sis.feature.DefaultAttributeType;
 
 
 /**
@@ -74,7 +73,7 @@ public class FeatureTypeBuilder extends
     /**
      * The parent of the feature to create. By default, new features have no parent.
      */
-    private final List<FeatureType> superTypes;
+    private final List<DefaultFeatureType> superTypes;
 
     /**
      * Whether the feature type is abstract. The default value is {@code false}.
@@ -138,7 +137,7 @@ public class FeatureTypeBuilder extends
      * The object created by this builder, or {@code null} if not yet created.
      * This field must be cleared every time that a setter method is invoked on this builder.
      */
-    private transient FeatureType feature;
+    private transient DefaultFeatureType feature;
 
     /**
      * Creates a new builder instance using the default name factory.
@@ -150,27 +149,35 @@ public class FeatureTypeBuilder extends
     /**
      * Creates a new builder instance using the given feature type as a template.
      *
+     * <div class="warning"><b>Warning:</b>
+     * The {@code template} argument type will be changed to {@code FeatureType} if and when such interface
+     * will be defined in GeoAPI.</div>
+     *
      * @param template  an existing feature type to use as a template, or {@code null} if none.
      */
-    public FeatureTypeBuilder(final FeatureType template) {
+    public FeatureTypeBuilder(final DefaultFeatureType template) {
         this(template, null, null);
     }
 
     /**
      * Creates a new builder instance using the given name factory, template and locale for formatting error messages.
      *
+     * <div class="warning"><b>Warning:</b>
+     * The {@code template} argument type will be changed to {@code FeatureType} if and when such interface
+     * will be defined in GeoAPI.</div>
+     *
      * @param template  an existing feature type to use as a template, or {@code null} if none.
      * @param factory   the factory to use for creating names, or {@code null} for the default factory.
      * @param locale    the locale to use for formatting error messages, or {@code null} for the default locale.
      */
-    public FeatureTypeBuilder(final FeatureType template, NameFactory factory, final Locale locale) {
+    public FeatureTypeBuilder(final DefaultFeatureType template, NameFactory factory, final Locale locale) {
         super(template, locale);
         if (factory == null) {
             factory = DefaultFactories.forBuildin(NameFactory.class);
         }
         nameFactory = factory;
         properties  = new ArrayList<PropertyTypeBuilder>();
-        superTypes  = new ArrayList<FeatureType>();
+        superTypes  = new ArrayList<DefaultFeatureType>();
         idDelimiter = ":";
         defaultMinimumOccurs = 1;
         defaultMaximumOccurs = 1;
@@ -178,12 +185,12 @@ public class FeatureTypeBuilder extends
             feature    = template;
             isAbstract = template.isAbstract();
             superTypes.addAll(template.getSuperTypes());
-            for (final PropertyType p : template.getProperties(false)) {
+            for (final AbstractIdentifiedType p : template.getProperties(false)) {
                 final PropertyTypeBuilder builder;
-                if (p instanceof AttributeType<?>) {
-                    builder = new AttributeTypeBuilder(this, (AttributeType<?>) p);
-                } else if (p instanceof FeatureAssociationRole) {
-                    builder = new AssociationRoleBuilder(this, (FeatureAssociationRole) p);
+                if (p instanceof DefaultAttributeType<?>) {
+                    builder = new AttributeTypeBuilder(this, (DefaultAttributeType<?>) p);
+                } else if (p instanceof DefaultAssociationRole) {
+                    builder = new AssociationRoleBuilder(this, (DefaultAssociationRole) p);
                 } else {
                     continue;           // Skip unknown types.
                 }
@@ -231,24 +238,32 @@ public class FeatureTypeBuilder extends
     /**
      * Returns the direct parents of the feature type to create.
      *
+     * <div class="warning"><b>Warning:</b>
+     * The return type will be changed to {@code FeatureType[]} if and when such interface
+     * will be defined in GeoAPI.</div>
+     *
      * @return the parents of the feature type to create, or an empty array if none.
      *
      * @see DefaultFeatureType#getSuperTypes()
      */
-    public FeatureType[] getSuperTypes() {
-        return superTypes.toArray(new FeatureType[superTypes.size()]);
+    public DefaultFeatureType[] getSuperTypes() {
+        return superTypes.toArray(new DefaultFeatureType[superTypes.size()]);
     }
 
     /**
      * Sets the parent types (or super-type) from which to inherit properties.
      * If this method is not invoked, then the default value is to have no parent.
      *
+     * <div class="warning"><b>Warning:</b>
+     * The {@code parents} argument type will be changed to {@code FeatureType...} if and when such interface
+     * will be defined in GeoAPI.</div>
+     *
      * @param  parents  the parent types from which to inherit properties, or an empty array if none.
      * @return {@code this} for allowing method calls chaining.
      */
-    public FeatureTypeBuilder setSuperTypes(final FeatureType... parents) {
+    public FeatureTypeBuilder setSuperTypes(final DefaultFeatureType... parents) {
         ensureNonNull("parents", parents);
-        final List<FeatureType> asList = Arrays.asList(parents);
+        final List<DefaultFeatureType> asList = Arrays.asList(parents);
         if (!superTypes.equals(asList)) {
             superTypes.clear();
             superTypes.addAll(asList);
@@ -444,7 +459,7 @@ public class FeatureTypeBuilder extends
      */
     public <V> AttributeTypeBuilder<V> addAttribute(final Class<V> valueClass) {
         ensureNonNull("valueClass", valueClass);
-        if (Feature.class.isAssignableFrom(valueClass)) {
+        if (AbstractFeature.class.isAssignableFrom(valueClass)) {
             // We disallow Feature.class because that type shall be handled as association instead than attribute.
             throw new IllegalArgumentException(errors().getString(Errors.Keys.IllegalArgumentValue_2, "valueClass", valueClass));
         }
@@ -457,13 +472,17 @@ public class FeatureTypeBuilder extends
     /**
      * Creates a new {@code AttributeType} builder initialized to the same characteristics than the given template.
      *
+     * <div class="warning"><b>Warning:</b>
+     * The {@code template} argument type will be changed to {@code AttributeType} if and when such interface
+     * will be defined in GeoAPI.</div>
+     *
      * @param  <V>       the compile-time type of values in the {@code template} argument.
      * @param  template  an existing attribute type to use as a template.
      * @return a builder for an {@code AttributeType}, initialized with the values of the given template.
      *
      * @see #properties()
      */
-    public <V> AttributeTypeBuilder<V> addAttribute(final AttributeType<V> template) {
+    public <V> AttributeTypeBuilder<V> addAttribute(final DefaultAttributeType<V> template) {
         ensureNonNull("template", template);
         final AttributeTypeBuilder<V> property = new AttributeTypeBuilder<V>(this, template);
         properties.add(property);
@@ -476,12 +495,16 @@ public class FeatureTypeBuilder extends
      * The default association name is the name of the given type, but callers should invoke one
      * of the {@code AssociationRoleBuilder.setName(…)} methods on the returned instance with a better name.
      *
+     * <div class="warning"><b>Warning:</b>
+     * The {@code type} argument type will be changed to {@code FeatureType} if and when such interface
+     * will be defined in GeoAPI.</div>
+     *
      * @param  type  the type of feature values.
      * @return a builder for a {@code FeatureAssociationRole}.
      *
      * @see #properties()
      */
-    public AssociationRoleBuilder addAssociation(final FeatureType type) {
+    public AssociationRoleBuilder addAssociation(final DefaultFeatureType type) {
         ensureNonNull("type", type);
         final AssociationRoleBuilder property = new AssociationRoleBuilder(this, type, type.getName());
         properties.add(property);
@@ -511,12 +534,16 @@ public class FeatureTypeBuilder extends
      * Creates a new {@code FeatureAssociationRole} builder initialized to the same characteristics
      * than the given template.
      *
+     * <div class="warning"><b>Warning:</b>
+     * The {@code template} argument type will be changed to {@code FeatureAssociationRole} if and when such interface
+     * will be defined in GeoAPI.</div>
+     *
      * @param  template  an existing feature association to use as a template.
      * @return a builder for an {@code FeatureAssociationRole}, initialized with the values of the given template.
      *
      * @see #properties()
      */
-    public AssociationRoleBuilder addAssociation(final FeatureAssociationRole template) {
+    public AssociationRoleBuilder addAssociation(final DefaultAssociationRole template) {
         ensureNonNull("template", template);
         final AssociationRoleBuilder property = new AssociationRoleBuilder(this, template);
         properties.add(property);
@@ -556,11 +583,15 @@ public class FeatureTypeBuilder extends
      * One of the {@code setName(…)} methods must have been invoked before this {@code build()} method (mandatory).
      * All other methods are optional, but some calls to a {@code add} method are usually needed.
      *
+     * <div class="warning"><b>Warning:</b>
+     * The return type will be changed to {@code FeatureType} if and when such interface
+     * will be defined in GeoAPI.</div>
+     *
      * @return the new feature type.
      * @throws IllegalStateException if the feature type contains incompatible
      *         {@linkplain AttributeTypeBuilder#setCRS CRS characteristics}.
      */
-    public FeatureType build() throws IllegalStateException {
+    public DefaultFeatureType build() throws IllegalStateException {
         if (feature == null) {
             /*
              * Creates an initial array of property types with up to 3 slots reserved for @identifier, @geometry
@@ -571,25 +602,25 @@ public class FeatureTypeBuilder extends
             int numSynthetic;                               // Number of synthetic properties that may be generated.
             int envelopeIndex = -1;
             int geometryIndex = -1;
-            final PropertyType[] identifierTypes;
+            final AbstractIdentifiedType[] identifierTypes;
             if (identifierCount == 0) {
                 numSynthetic    = 0;
                 identifierTypes = null;
             } else {
                 numSynthetic    = 1;
-                identifierTypes = new PropertyType[identifierCount];
+                identifierTypes = new AbstractIdentifiedType[identifierCount];
             }
             if (defaultGeometry != null) {
                 envelopeIndex = numSynthetic;
                 geometryIndex = numSynthetic + 1;
                 numSynthetic += 2;
             }
-            final PropertyType[] propertyTypes = new PropertyType[numSynthetic + numSpecified];
+            final AbstractIdentifiedType[] propertyTypes = new AbstractIdentifiedType[numSynthetic + numSpecified];
             int propertyCursor = numSynthetic;
             int identifierCursor = 0;
             for (int i=0; i<numSpecified; i++) {
                 final PropertyTypeBuilder builder = properties.get(i);
-                final PropertyType instance = builder.build();
+                final AbstractIdentifiedType instance = builder.build();
                 propertyTypes[propertyCursor] = instance;
                 /*
                  * Collect the attributes to use as identifier components while we loop over all properties.
@@ -649,7 +680,7 @@ public class FeatureTypeBuilder extends
                 }
             }
             feature = new DefaultFeatureType(identification(), isAbstract(),
-                    superTypes.toArray(new FeatureType[superTypes.size()]),
+                    superTypes.toArray(new DefaultFeatureType[superTypes.size()]),
                     ArraysExt.resize(propertyTypes, propertyCursor));
         }
         return feature;
@@ -671,7 +702,7 @@ public class FeatureTypeBuilder extends
             buffer.insert(buffer.indexOf("[") + 1, "abstract ");
         }
         String separator = " : ";
-        for (final FeatureType parent : superTypes) {
+        for (final DefaultFeatureType parent : superTypes) {
             buffer.append(separator).append('“').append(parent.getName()).append('”');
             separator = ", ";
         }

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/PropertyTypeBuilder.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/PropertyTypeBuilder.java?rev=1753294&r1=1753266&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/PropertyTypeBuilder.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/PropertyTypeBuilder.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -18,10 +18,9 @@ package org.apache.sis.feature.builder;
 
 import org.opengis.util.GenericName;
 import org.apache.sis.util.resources.Errors;
-import org.opengis.feature.AttributeType;
-import org.opengis.feature.FeatureType;
-import org.opengis.feature.PropertyType;
-import org.opengis.feature.FeatureAssociationRole;
+
+// Branch-dependent imports
+import org.apache.sis.feature.AbstractIdentifiedType;
 
 
 /**
@@ -69,7 +68,7 @@ public abstract class PropertyTypeBuilde
      * The attribute or association created by this builder, or {@code null} if not yet created.
      * This field must be cleared every time that a setter method is invoked on this builder.
      */
-    private transient PropertyType property;
+    private transient AbstractIdentifiedType property;
 
     /**
      * Creates a new {@code PropertyType} builder initialized to the values of an existing property.
@@ -77,7 +76,7 @@ public abstract class PropertyTypeBuilde
      * @param owner     the builder of the {@code FeatureType} for which to add this property.
      * @param template  an existing property to use as a template, or {@code null} if none.
      */
-    PropertyTypeBuilder(final FeatureTypeBuilder owner, final PropertyType template) {
+    PropertyTypeBuilder(final FeatureTypeBuilder owner, final AbstractIdentifiedType template) {
         super(template, owner.getLocale());
         this.owner    = owner;
         minimumOccurs = owner.defaultMinimumOccurs;
@@ -138,7 +137,7 @@ public abstract class PropertyTypeBuilde
      * Returns the property type from the current setting.
      * This method may return an existing property if it was already created.
      */
-    final PropertyType build() {
+    final AbstractIdentifiedType build() {
         if (property == null) {
             property = create();
         }
@@ -148,5 +147,5 @@ public abstract class PropertyTypeBuilde
     /**
      * Creates a new property type from the current setting.
      */
-    abstract PropertyType create();
+    abstract AbstractIdentifiedType create();
 }

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/TypeBuilder.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/TypeBuilder.java?rev=1753294&r1=1753266&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/TypeBuilder.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/builder/TypeBuilder.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -30,7 +30,6 @@ import org.apache.sis.util.Debug;
 
 // Branch-dependent imports
 import java.util.Objects;
-import org.opengis.feature.IdentifiedType;
 
 
 /**
@@ -66,7 +65,7 @@ public abstract class TypeBuilder implem
     /**
      * Creates a new builder initialized to the values of an existing type.
      */
-    TypeBuilder(final IdentifiedType template, final Locale locale) {
+    TypeBuilder(final AbstractIdentifiedType template, final Locale locale) {
         putIfNonNull(Errors.LOCALE_KEY, locale);
         if (template != null) {
             putIfNonNull(AbstractIdentifiedType.NAME_KEY,        template.getName());

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -72,17 +72,29 @@
  * {@code      ├─} {@linkplain org.apache.sis.feature.DefaultAssociationRole  Feature association role}<br>
  * {@code      └─} {@linkplain org.apache.sis.feature.AbstractOperation       Operation}<br>
  * </td><td class="sep" style="width: 50%; white-space: nowrap">
- *             {@linkplain org.apache.sis.feature.AbstractFeature     Feature}             (<cite>sparse</cite> or <cite>dense</cite>)<br>
- *                                                                    Property<br>
- * {@code  ├─} {@linkplain org.apache.sis.feature.AbstractAttribute   Attribute}           (<cite>singleton</cite> or <cite>multi-valued</cite>)<br>
- * {@code  └─} {@linkplain org.apache.sis.feature.AbstractAssociation Feature association} (<cite>singleton</cite> or <cite>multi-valued</cite>)<br>
+ *                 Object<br>
+ * {@code  ├─}     {@linkplain org.apache.sis.feature.AbstractFeature     Feature}             (<cite>sparse</cite> or <cite>dense</cite>)<br>
+ * {@code  └─}                                                            Property<br>
+ * {@code      ├─} {@linkplain org.apache.sis.feature.AbstractAttribute   Attribute}           (<cite>singleton</cite> or <cite>multi-valued</cite>)<br>
+ * {@code      └─} {@linkplain org.apache.sis.feature.AbstractAssociation Feature association} (<cite>singleton</cite> or <cite>multi-valued</cite>)<br>
  * </td></tr></table>
  *
+ * <div class="section">Instantiation</div>
+ * Classes defined in this package are rarely instantiated directly (by a {@code new} statement).
+ * Instead those classes are instantiated indirectly by invoking a method on a parent container,
+ * or by using a builder. The starting point is {@code FeatureType}, which may be created by a
+ * {@link org.apache.sis.feature.builder.FeatureTypeBuilder} or may be provided by a
+ * {@link org.apache.sis.storage.DataStore} reading a data file.
+ * Once a {@code FeatureType} has been obtained, {@code Feature}s can be instantiated by calls to the
+ * {@link org.apache.sis.feature.DefaultFeatureType#newInstance() FeatureType.newInstance()} method.
+ * Once a {@code Feature} instance has been obtained, {@code Attribute}s can be instantiated indirectly
+ * by calls to the {@link org.apache.sis.feature.AbstractFeature#setPropertyValue Feature.setPropertyValue(…)} method.
+ *
  * @author  Travis L. Pinney
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.8
  * @module
  */
 package org.apache.sis.feature;

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/internal/feature/AttributeConvention.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -40,10 +40,10 @@ import org.apache.sis.feature.DefaultAtt
  * appropriate "real" property in the feature.
  *
  * <div class="note"><b>Example:</b>
- * one of the most frequently used synthetic property is {@code "@id"}, which contains a unique
+ * one of the most frequently used synthetic property is {@code "@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 "@id"} alias, users do not need to know the name of the "real" attribute.
+ * By using the {@code "@identifier"} alias, users do not need to know the name of the "real" attribute.
  * </div>
  *
  * This class defines names for two kinds of usage:
@@ -60,7 +60,7 @@ import org.apache.sis.feature.DefaultAtt
  * but we may refactor this class in future SIS versions if there is a need to support different conventions.
  *
  * <p>In order to reduce the risk of name collision with properties in user-defined features
- * (e.g. the user may already have an attribute named {@code "id"} for his own purpose),
+ * (e.g. the user may already have an attribute named {@code "identifier"} for his own purpose),
  * all names defined in this class begin with the {@code "@"} character.</p>
  *
  * @author  Johann Sorel (Geomatys)
@@ -89,7 +89,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 ID_PROPERTY;
+    public static final LocalName IDENTIFIER_PROPERTY;
 
     /**
      * Conventional name for a property containing the geometric object to use by default.
@@ -106,11 +106,11 @@ public final class AttributeConvention e
      *
      * @see #isGeometryAttribute(IdentifiedType)
      */
-    public static final LocalName DEFAULT_GEOMETRY_PROPERTY;
+    public static final LocalName GEOMETRY_PROPERTY;
 
     /**
      * Conventional name for fetching the envelope encompassing all geometries in a feature. Most {@code FeatureType}s
-     * have at most one geometry, which is also the {@linkplain #DEFAULT_GEOMETRY_PROPERTY default geometry}.
+     * have at most one geometry, which is also the {@link #GEOMETRY_PROPERTY default geometry}.
      * But if several geometries exist, then the value for this synthetic property is the union of all geometries.
      *
      * <p>Properties of this name are usually
@@ -125,10 +125,10 @@ public final class AttributeConvention e
      * Conventional name for fetching the Coordinate Reference System (CRS) of a geometry or a coverage.
      * This characteristic is typically an entry in the map returned by a call to the
      * {@link org.apache.sis.feature.DefaultAttributeType#characteristics()} method
-     * on the attribute referenced by {@link #DEFAULT_GEOMETRY_PROPERTY}.
+     * on the attribute referenced by {@link #GEOMETRY_PROPERTY}.
      *
      * <p>While it is technically possible to have different CRS for different feature instances,
-     * in most cases the CRS is the same for all geometries found in {@code DEFAULT_GEOMETRY_PROPERTY}.
+     * in most cases the CRS is the same for all geometries found in {@code GEOMETRY_PROPERTY}.
      * In such cases, the CRS can be specified only once as the
      * {@linkplain org.apache.sis.feature.DefaultAttributeType#getDefaultValue() default value}
      * of this {@code CRS_CHARACTERISTIC}.</p>
@@ -167,8 +167,8 @@ public final class AttributeConvention e
         final NameFactory factory = DefaultFactories.forBuildin(NameFactory.class);
         NAMESPACE                     = factory.createGenericName(null, "Apache", Constants.SIS);
         NameSpace ns                  = factory.createNameSpace(NAMESPACE, null);
-        ID_PROPERTY                   = factory.createLocalName(ns, "@identifier");
-        DEFAULT_GEOMETRY_PROPERTY     = factory.createLocalName(ns, "@geometry");
+        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");
@@ -222,7 +222,7 @@ public final class AttributeConvention e
      * @return {@code true} if the given type is (directly or indirectly) an attribute type
      *         for one of the recognized geometry types.
      *
-     * @see #DEFAULT_GEOMETRY_PROPERTY
+     * @see #GEOMETRY_PROPERTY
      */
     public static boolean isGeometryAttribute(AbstractIdentifiedType type) {
         while (type instanceof AbstractOperation) {
@@ -252,7 +252,7 @@ public final class AttributeConvention e
      * @throws ClassCastException if {@link #CRS_CHARACTERISTIC} has been found but is associated
      *         to an object which is not a {@link CoordinateReferenceSystem} instance.
      *
-     * @see org.apache.sis.internal.feature.FeatureTypeBuilder.Property#setCRSCharacteristic(CoordinateReferenceSystem)
+     * @see org.apache.sis.feature.builder.AttributeTypeBuilder#setCRS(CoordinateReferenceSystem)
      */
     public static CoordinateReferenceSystem getCRSCharacteristic(final Object attribute) {
         return (CoordinateReferenceSystem) getCharacteristic(attribute, CRS_CHARACTERISTIC.toString());
@@ -279,7 +279,7 @@ public final class AttributeConvention e
      * @throws ClassCastException if {@link #MAXIMAL_LENGTH_CHARACTERISTIC} has been found but is associated
      *         to an object which is not an {@link Integer} instance.
      *
-     * @see org.apache.sis.internal.feature.FeatureTypeBuilder.Property#setMaximalLengthCharacteristic(Integer)
+     * @see org.apache.sis.feature.builder.AttributeTypeBuilder#setMaximalLength(Integer)
      */
     public static Integer getMaximalLengthCharacteristic(final Object attribute) {
         return (Integer) getCharacteristic(attribute, MAXIMAL_LENGTH_CHARACTERISTIC.toString());

Modified: sis/trunk/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Geometries.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -16,10 +16,15 @@
  */
 package org.apache.sis.internal.feature;
 
+import java.util.logging.Level;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import com.esri.core.geometry.Geometry;
 import com.esri.core.geometry.Envelope2D;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.util.Static;
+import org.apache.sis.util.logging.Logging;
+import org.apache.sis.internal.system.Loggers;
 
 
 /**
@@ -32,11 +37,52 @@ import org.apache.sis.util.Static;
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
- * @version 0.7
+ * @version 0.8
  * @module
  */
 public final class Geometries extends Static {
     /**
+     * The geometry object from Java Topology Suite (JTS),
+     * or {@code null} if the JTS library is not on the classpath.
+     */
+    private static final Class<?> JTS;
+
+    /**
+     * Getter methods on JTS envelopes, or {@code null} if the JTS library is not on the classpath.
+     * Each methods take no argument and return a {@code double} value.
+     */
+    private static final Method INTERNAL, MIN_X, MIN_Y, MAX_X, MAX_Y;
+
+    static {
+        Class<?> type;
+        Method genv, xmin, ymin, xmax, ymax;
+        try {
+            final Class<?> envt;
+            type = Class.forName("com.vividsolutions.jts.geom.Geometry");
+            genv = type.getMethod("getEnvelopeInternal", (Class[]) null);
+            envt = genv.getReturnType();
+            xmin = envt.getMethod("getMinX", (Class[]) null);
+            ymin = envt.getMethod("getMinY", (Class[]) null);
+            xmax = envt.getMethod("getMaxX", (Class[]) null);
+            ymax = envt.getMethod("getMaxY", (Class[]) null);
+        } catch (Exception e) {     // (ClassNotFoundException | NoSuchMethodException) on the JDK7 branch.
+            Logging.getLogger(Loggers.GEOMETRY).log(Level.CONFIG, e.toString());
+            type = null;
+            genv = null;
+            xmin = null;
+            xmax = null;
+            ymin = null;
+            ymax = null;
+        }
+        JTS = type;
+        INTERNAL = genv;
+        MIN_X = xmin;
+        MIN_Y = ymin;
+        MAX_X = xmax;
+        MAX_Y = ymax;
+    }
+
+    /**
      * Do not allow instantiation of this class.
      */
     private Geometries() {
@@ -49,7 +95,7 @@ public final class Geometries extends St
      * @return {@code true} if the given type is one of the geometry type known to SIS.
      */
     public static boolean isKnownType(final Class<?> type) {
-        return Geometry.class.isAssignableFrom(type);
+        return Geometry.class.isAssignableFrom(type) || (JTS != null && JTS.isAssignableFrom(type));
     }
 
     /**
@@ -61,16 +107,43 @@ public final class Geometries extends St
      *         a recognized geometry or its envelope is empty.
      */
     public static GeneralEnvelope getEnvelope(final Object geometry) {
+        final double xmin, ymin, xmax, ymax;
         if (geometry instanceof Geometry) {
             final Envelope2D bounds = new Envelope2D();
             ((Geometry) geometry).queryEnvelope2D(bounds);
-            if (!bounds.isEmpty()) {                                    // Test if there is NaN values.
-                final GeneralEnvelope env = new GeneralEnvelope(2);
-                env.setRange(0, bounds.xmin, bounds.xmax);
-                env.setRange(1, bounds.ymin, bounds.ymax);
-                return env;
+            if (bounds.isEmpty()) {                                     // Test if there is NaN values.
+                return null;
+            }
+            xmin = bounds.xmin;
+            ymin = bounds.ymin;
+            xmax = bounds.xmax;
+            ymax = bounds.ymax;
+        } else if (JTS != null && JTS.isInstance(geometry)) {
+            try {
+                final Object env = INTERNAL.invoke(geometry, (Object[]) null);
+                xmin = (Double) MIN_X.invoke(env, (Object[]) null);
+                ymin = (Double) MIN_Y.invoke(env, (Object[]) null);
+                xmax = (Double) MAX_X.invoke(env, (Object[]) null);
+                ymax = (Double) MAX_Y.invoke(env, (Object[]) null);
+            } catch (ReflectiveOperationException e) {
+                if (e instanceof InvocationTargetException) {
+                    final Throwable cause = e.getCause();
+                    if (cause instanceof RuntimeException) {
+                        throw (RuntimeException) cause;
+                    }
+                    if (cause instanceof Error) {
+                        throw (Error) cause;
+                    }
+                }
+                // Should never happen unless JTS's API changed.
+                throw (Error) new IncompatibleClassChangeError(e.toString()).initCause(e);
             }
+        } else {
+            return null;
         }
-        return null;
+        final GeneralEnvelope env = new GeneralEnvelope(2);
+        env.setRange(0, xmin, xmax);
+        env.setRange(1, ymin, ymax);
+        return env;
     }
 }

Modified: sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/AbstractOperationTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/AbstractOperationTest.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/AbstractOperationTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/AbstractOperationTest.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -31,7 +31,7 @@ import static org.apache.sis.test.Assert
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
- * @version 0.6
+ * @version 0.8
  * @module
  */
 @DependsOn(SingletonAttributeTest.class)
@@ -62,6 +62,6 @@ public final strictfp class AbstractOper
      */
     @Test
     public void testToString() {
-        assertEquals("Operation[“found city” (founder) : city]", foundCity().toString());
+        assertEquals("NoOperation[“found city” (founder) : String]", foundCity().toString());
     }
 }

Modified: sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/EnvelopeOperationTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/EnvelopeOperationTest.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/EnvelopeOperationTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/EnvelopeOperationTest.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -78,7 +78,7 @@ public final strictfp class EnvelopeOper
             null,
             null
         };
-        attributes[4] = FeatureOperations.link(name(AttributeConvention.DEFAULT_GEOMETRY_PROPERTY), attributes[defaultGeometry]);
+        attributes[4] = FeatureOperations.link(name(AttributeConvention.GEOMETRY_PROPERTY), attributes[defaultGeometry]);
         attributes[5] = FeatureOperations.envelope(name("bounds"), null, attributes);
         return new DefaultFeatureType(name("school"), false, null, attributes);
     }

Modified: sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java?rev=1753294&r1=1753266&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/test/java/org/apache/sis/feature/builder/FeatureTypeBuilderTest.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -19,20 +19,20 @@ package org.apache.sis.feature.builder;
 import java.util.Iterator;
 import com.esri.core.geometry.Geometry;
 import com.esri.core.geometry.Point;
+import org.apache.sis.internal.feature.AttributeConvention;
+import org.apache.sis.feature.DefaultFeatureTypeTest;
 import org.apache.sis.referencing.crs.HardCodedCRS;
 import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.test.TestUtilities;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
 
 // Branch-dependent imports
-import org.opengis.feature.AttributeType;
-import org.opengis.feature.FeatureType;
-import org.opengis.feature.PropertyType;
-import org.apache.sis.feature.DefaultFeatureTypeTest;
-import org.apache.sis.internal.feature.AttributeConvention;
-import org.apache.sis.test.TestUtilities;
+import org.apache.sis.feature.AbstractIdentifiedType;
+import org.apache.sis.feature.DefaultAttributeType;
+import org.apache.sis.feature.DefaultFeatureType;
 
 
 /**
@@ -54,7 +54,7 @@ public final strictfp class FeatureTypeB
         assertEquals("default name", "string", builder.getName().toString());
 
         builder.setName("myScope", "myName");
-        final AttributeType<?> att = (AttributeType<?>) builder.build();
+        final DefaultAttributeType<?> att = (DefaultAttributeType<?>) builder.build();
 
         assertEquals("name", "myScope:myName",   att.getName().toString());
         assertEquals("valueClass", String.class, att.getValueClass());
@@ -88,7 +88,7 @@ public final strictfp class FeatureTypeB
      */
     private static void testEmptyFeature(final FeatureTypeBuilder builder) {
         builder.setName("scope", "test");
-        final FeatureType type = builder.build();
+        final DefaultFeatureType type = builder.build();
 
         assertEquals("name", "scope:test",   type.getName().toString());
         assertFalse ("isAbstract",           type.isAbstract());
@@ -110,7 +110,7 @@ public final strictfp class FeatureTypeB
         builder.setDefaultValue("test default value.");
         builder.setCardinality(10, 60);
         builder.setMaximalLength(80);
-        final AttributeType<?> att = (AttributeType<?>) builder.build();
+        final DefaultAttributeType<?> att = (DefaultAttributeType<?>) builder.build();
 
         assertEquals("name",          "myScope:myName",      att.getName().toString());
         assertEquals("definition",    "test definition",     att.getDefinition().toString());
@@ -148,18 +148,18 @@ public final strictfp class FeatureTypeB
         builder.addAttribute(Point  .class).setName("location").setCRS(HardCodedCRS.WGS84);
         builder.addAttribute(Double .class).setName("score").setDefaultValue(10.0).setCardinality(5, 50);
 
-        final FeatureType type = builder.build();
+        final DefaultFeatureType type = builder.build();
         assertEquals("name",        "myScope:myName",   type.getName().toString());
         assertEquals("definition",  "test definition",  type.getDefinition().toString());
         assertEquals("description", "test description", type.getDescription().toString());
         assertEquals("designation", "test designation", type.getDesignation().toString());
         assertTrue  ("isAbstract",                      type.isAbstract());
 
-        final Iterator<? extends PropertyType> it = type.getProperties(true).iterator();
-        final AttributeType<?> a0 = (AttributeType<?>) it.next();
-        final AttributeType<?> a1 = (AttributeType<?>) it.next();
-        final AttributeType<?> a2 = (AttributeType<?>) it.next();
-        final AttributeType<?> a3 = (AttributeType<?>) it.next();
+        final Iterator<? extends AbstractIdentifiedType> it = type.getProperties(true).iterator();
+        final DefaultAttributeType<?> a0 = (DefaultAttributeType<?>) it.next();
+        final DefaultAttributeType<?> a1 = (DefaultAttributeType<?>) it.next();
+        final DefaultAttributeType<?> a2 = (DefaultAttributeType<?>) it.next();
+        final DefaultAttributeType<?> a3 = (DefaultAttributeType<?>) it.next();
         assertFalse("properties count", it.hasNext());
 
         assertEquals("name", "name",     a0.getName().toString());
@@ -208,16 +208,16 @@ public final strictfp class FeatureTypeB
                 .setCRS(HardCodedCRS.WGS84)
                 .addRole(AttributeRole.DEFAULT_GEOMETRY);
 
-        final FeatureType type = builder.build();
+        final DefaultFeatureType type = builder.build();
         assertEquals("name", "scope:test", type.getName().toString());
         assertFalse ("isAbstract", type.isAbstract());
 
-        final Iterator<? extends PropertyType> it = type.getProperties(true).iterator();
-        final PropertyType a0 = it.next();
-        final PropertyType a1 = it.next();
-        final PropertyType a2 = it.next();
-        final PropertyType a3 = it.next();
-        final PropertyType a4 = it.next();
+        final Iterator<? extends AbstractIdentifiedType> it = type.getProperties(true).iterator();
+        final AbstractIdentifiedType a0 = it.next();
+        final AbstractIdentifiedType a1 = it.next();
+        final AbstractIdentifiedType a2 = it.next();
+        final AbstractIdentifiedType a3 = it.next();
+        final AbstractIdentifiedType a4 = it.next();
         assertFalse("properties count", it.hasNext());
 
         assertEquals("name", AttributeConvention.IDENTIFIER_PROPERTY, a0.getName());

Modified: sis/trunk/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java?rev=1753294&r1=1753293&r2=1753294&view=diff
==============================================================================
--- sis/trunk/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java [UTF-8] (original)
+++ sis/trunk/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java [UTF-8] Mon Jul 18 17:47:22 2016
@@ -49,7 +49,7 @@ import org.junit.BeforeClass;
     org.apache.sis.feature.FeatureFormatTest.class,
     org.apache.sis.feature.FeaturesTest.class,
     org.apache.sis.internal.feature.AttributeConventionTest.class,
-    org.apache.sis.internal.feature.FeatureTypeBuilderTest.class
+    org.apache.sis.feature.builder.FeatureTypeBuilderTest.class
 })
 public final strictfp class FeatureTestSuite extends TestSuite {
     /**




Mime
View raw message