sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1593553 - in /sis/branches/JDK8/core/sis-feature/src: main/java/org/apache/sis/feature/ test/java/org/apache/sis/feature/
Date Fri, 09 May 2014 14:42:13 GMT
Author: desruisseaux
Date: Fri May  9 14:42:12 2014
New Revision: 1593553

URL: http://svn.apache.org/r1593553
Log:
Added AssociationRole and Operation (derived from ISO 19109). We are not yet sure about what will be the final
version of those types, but we are better to add them now in order to allow our code to take them in account.

Added:
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java
      - copied, changed from r1593420, sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultOperation.java   (with props)
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java
      - copied, changed from r1593420, sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java
Modified:
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttribute.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java
    sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java

Copied: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java (from r1593420, sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java?p2=sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java&p1=sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java&r1=1593420&r2=1593553&rev=1593553&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java [UTF-8] Fri May  9 14:42:12 2014
@@ -17,97 +17,35 @@
 package org.apache.sis.feature;
 
 import java.util.Map;
-import org.opengis.util.GenericName;
-import org.opengis.util.InternationalString;
 import org.apache.sis.util.Debug;
-import org.apache.sis.util.Classes;
-import org.apache.sis.util.resources.Errors;
-import org.apache.sis.internal.util.Numerics;
 
 import static org.apache.sis.util.ArgumentChecks.*;
 
-// Related to JDK7
-import java.util.Objects;
-
 
 /**
- * Definition of an attribute in a feature type.
- * The name of attribute type is mandatory. The name {@linkplain org.apache.sis.util.iso.AbstractName#scope() scope}
- * is typically the name of the {@linkplain DefaultFeatureType feature type} containing this attribute, but this is
- * not mandatory. The scope could also be defined by the ontology for example.
- *
- * <div class="note"><b>Note:</b>
- * Compared to the Java language, {@code AttributeType} is equivalent to {@link java.lang.reflect.Field}
- * while {@code FeatureType} is equivalent to {@link Class}.</div>
- *
- * <div class="warning"><b>Warning:</b>
- * This class is expected to implement a GeoAPI {@code AttributeType} interface in a future version.
- * When such interface will be available, most references to {@code DefaultAttributeType} in current
- * API will be replaced by references to the {@code AttributeType} interface.</div>
- *
- * {@section Value type}
- * Attributes can be used for both spatial and non-spatial properties.
- * Some examples are:
- *
- * <table class="sis">
- *   <caption>Attribute value type examples</caption>
- *   <tr><th>Attribute name</th>      <th>Value type</th></tr>
- *   <tr><td>Building shape</td>      <td>{@link org.opengis.geometry.Geometry}</td></tr>
- *   <tr><td>Building owner</td>      <td>{@link org.opengis.metadata.citation.ResponsibleParty}</td></tr>
- *   <tr><td>Horizontal accuracy</td> <td>{@link org.opengis.metadata.quality.PositionalAccuracy}</td></tr>
- * </table>
+ * Indicates the role played by the association between two features.
  *
- * {@section Immutability and thread safety}
- * Instances of this class are immutable if all properties ({@link GenericName} and {@link InternationalString}
- * instances) and all arguments (e.g. {@code defaultValue}) given to the constructor are also immutable.
- * Such immutable instances can be shared by many objects and passed between threads without synchronization.
- *
- * <p>In particular, the {@link #getDefaultValue()} method does <strong>not</strong> clone the returned value.
- * This means that the same {@code defaultValue} instance may be shared by many {@link DefaultAttribute} instances.
- * Consequently the default value should be immutable for avoiding unexpected behavior.</p>
- *
- * @param <T> The type of attribute values.
- *
- * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
  * @version 0.5
  * @module
  */
-public class DefaultAttributeType<T> extends PropertyType {
+public class DefaultAssociationRole extends FieldType {
     /**
      * For cross-version compatibility.
      */
-    private static final long serialVersionUID = 8215784957556648553L;
+    private static final long serialVersionUID = 1592712639262027124L;
 
     /**
-     * The class that describe the type of attribute values.
+     * The type of feature instances to be associated.
      *
-     * @see #getValueClass()
+     * @see #getValueType()
      */
-    private final Class<T> valueClass;
+    private final DefaultFeatureType valueType;
 
     /**
-     * The minimum number of occurrences of the property within its containing entity.
-     */
-    private final int minimumOccurs;
-
-    /**
-     * The maximum number of occurrences of the property within its containing entity,
-     * or {@link Integer#MAX_VALUE} if there is no limit.
-     */
-    private final int maximumOccurs;
-
-    /**
-     * The default value for the attribute, or {@code null} if none.
-     *
-     * @see #getDefaultValue()
-     */
-    private final T defaultValue;
-
-    /**
-     * Constructs an attribute type from the given properties. The properties map is given unchanged to
-     * the {@linkplain AbstractIdentifiedType#AbstractIdentifiedType(Map) super-class constructor}.
+     * Constructs an association role from the given properties. The properties map is given unchanged
+     * to the {@linkplain AbstractIdentifiedType#AbstractIdentifiedType(Map) super-class constructor}.
      * The following table is a reminder of main (not all) properties:
      *
      * <table class="sis">
@@ -139,95 +77,69 @@ public class DefaultAttributeType<T> ext
      *   </tr>
      * </table>
      *
-     * @param properties    The name and other properties to be given to this attribute type.
-     * @param valueClass    The type of attribute values.
-     * @param minimumOccurs The minimum number of occurrences of the property within its containing entity.
-     * @param maximumOccurs The maximum number of occurrences of the property within its containing entity,
+     * @param properties    The name and other properties to be given to this association role.
+     * @param valueType     The type of feature values.
+     * @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.
-     * @param defaultValue  The default value for the attribute, or {@code null} if none.
      */
-    public DefaultAttributeType(final Map<String,?> properties, final Class<T> valueClass,
-            final int minimumOccurs, final int maximumOccurs, final T defaultValue)
+    public DefaultAssociationRole(final Map<String,?> properties, final DefaultFeatureType valueType,
+            final int minimumOccurs, final int maximumOccurs)
     {
-        super(properties);
-        ensureNonNull("valueClass",   valueClass);
-        ensureCanCast("defaultValue", valueClass, defaultValue);
-        if (minimumOccurs < 0 || maximumOccurs < minimumOccurs) {
-            throw new IllegalArgumentException(Errors.format(
-                    Errors.Keys.IllegalRange_2, minimumOccurs, maximumOccurs));
-        }
-        this.valueClass    = valueClass;
-        this.minimumOccurs = minimumOccurs;
-        this.maximumOccurs = maximumOccurs;
-        this.defaultValue  = Numerics.cached(defaultValue);
+        super(properties, minimumOccurs, maximumOccurs);
+        ensureNonNull("valueType", valueType);
+        this.valueType = valueType;
     }
 
     /**
-     * Returns the type of attribute values.
+     * Returns the type of feature values.
      *
-     * @return The type of attribute values.
+     * <div class="warning"><b>Warning:</b> In a future SIS version, the return type may be changed
+     * to {@code org.opengis.feature.FeatureType}. This change is pending GeoAPI revision.</div>
+     *
+     * @return The type of feature values.
      */
-    public final Class<T> getValueClass() {
-        return valueClass;
+    public final DefaultFeatureType getValueType() {
+        return valueType;
     }
 
-    /*
-     * ISO 19109 properties omitted for now:
-     *
-     *   - valueDomain : CharacterString
-     *
-     * Rational: a CharacterString is hardly programmatically usable. A Range would be better but too specific.
-     * We could follow the GeoAPI path and define a "restrictions : Filter" property. That would be more generic,
-     * but we are probably better to wait for Filter to be implemented in SIS.
-     *
-     * Reference: https://issues.apache.org/jira/browse/SIS-175
-     */
 
     /**
-     * Returns the minimum number of occurrences of the property within its containing entity.
+     * Returns the minimum number of occurrences of the association within its containing entity.
      * The returned value is greater than or equal to zero.
      *
-     * @return The minimum number of occurrences of the property within its containing entity.
+     * @return The minimum number of occurrences of the association within its containing entity.
      */
-    public int getMinimumOccurs() {
-        return minimumOccurs;
+    @Override
+    public final int getMinimumOccurs() {
+        return super.getMinimumOccurs();
     }
 
     /**
-     * Returns the maximum number of occurrences of the property within its containing entity.
+     * Returns the maximum number of occurrences of the association within its containing entity.
      * The returned value is greater than or equal to the {@link #getMinimumOccurs()} value.
      * If there is no maximum, then this method returns {@link Integer#MAX_VALUE}.
      *
-     * @return The maximum number of occurrences of the property within its containing entity,
+     * @return The maximum number of occurrences of the association within its containing entity,
      *         or {@link Integer#MAX_VALUE} if none.
      */
-    public int getMaximumOccurs() {
-        return maximumOccurs;
-    }
-
-    /**
-     * Returns the default value for the attribute.
-     * This value is used when an attribute is created and no value for it is specified.
-     *
-     * @return The default value for the attribute, or {@code null} if none.
-     */
-    public T getDefaultValue() {
-        return defaultValue;
+    @Override
+    public final int getMaximumOccurs() {
+        return super.getMaximumOccurs();
     }
 
     /**
-     * Returns a hash code value for this attribute type.
+     * Returns a hash code value for this association role.
      *
      * @return {@inheritDoc}
      */
     @Override
     public int hashCode() {
-        return super.hashCode() + valueClass.hashCode() + 37*(minimumOccurs ^ maximumOccurs) +
-               Objects.hashCode(defaultValue);
+        return super.hashCode() + valueType.hashCode();
     }
 
     /**
-     * Compares this attribute type with the given object for equality.
+     * Compares this association role with the given object for equality.
      *
      * @return {@inheritDoc}
      */
@@ -237,11 +149,8 @@ public class DefaultAttributeType<T> ext
             return true;
         }
         if (super.equals(obj)) {
-            final DefaultAttributeType<?> that = (DefaultAttributeType<?>) obj;
-            return valueClass    == that.valueClass    &&
-                   minimumOccurs == that.minimumOccurs &&
-                   maximumOccurs == that.maximumOccurs &&
-                   Objects.equals(defaultValue, that.defaultValue);
+            final DefaultAssociationRole that = (DefaultAssociationRole) obj;
+            return valueType.equals(that.valueType);
         }
         return false;
     }
@@ -255,22 +164,6 @@ public class DefaultAttributeType<T> ext
     @Debug
     @Override
     public String toString() {
-        return toString("AttributeType").toString();
-    }
-
-    /**
-     * Implementation of {@link #toString()} to be shared by {@link DefaultAttribute#toString()}.
-     */
-    final StringBuilder toString(final String typeName) {
-        final StringBuilder buffer = new StringBuilder(40).append(typeName).append('[');
-        final GenericName name = super.getName();
-        if (name != null) {
-            buffer.append('“');
-        }
-        buffer.append(name);
-        if (name != null) {
-            buffer.append("” : ");
-        }
-        return buffer.append(Classes.getShortName(valueClass)).append(']');
+        return toString("AssociationRole", valueType.getName().toString()).toString();
     }
 }

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttribute.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttribute.java?rev=1593553&r1=1593552&r2=1593553&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttribute.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttribute.java [UTF-8] Fri May  9 14:42:12 2014
@@ -18,6 +18,7 @@ package org.apache.sis.feature;
 
 import java.io.Serializable;
 import org.apache.sis.util.Debug;
+import org.apache.sis.util.Classes;
 import org.apache.sis.util.ArgumentChecks;
 
 // Related to JDK7
@@ -199,6 +200,7 @@ public class DefaultAttribute<T> extends
     @Debug
     @Override
     public String toString() {
-        return type.toString("Attribute").append(" = ").append(value).toString();
+        return type.toString("Attribute", Classes.getShortName(type.getValueClass()))
+                .append(" = ").append(value).toString();
     }
 }

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java?rev=1593553&r1=1593552&r2=1593553&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java [UTF-8] Fri May  9 14:42:12 2014
@@ -21,7 +21,6 @@ import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.Debug;
 import org.apache.sis.util.Classes;
-import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.util.Numerics;
 
 import static org.apache.sis.util.ArgumentChecks.*;
@@ -74,7 +73,7 @@ import java.util.Objects;
  * @version 0.5
  * @module
  */
-public class DefaultAttributeType<T> extends PropertyType {
+public class DefaultAttributeType<T> extends FieldType {
     /**
      * For cross-version compatibility.
      */
@@ -88,17 +87,6 @@ public class DefaultAttributeType<T> ext
     private final Class<T> valueClass;
 
     /**
-     * The minimum number of occurrences of the property within its containing entity.
-     */
-    private final int minimumOccurs;
-
-    /**
-     * The maximum number of occurrences of the property within its containing entity,
-     * or {@link Integer#MAX_VALUE} if there is no limit.
-     */
-    private final int maximumOccurs;
-
-    /**
      * The default value for the attribute, or {@code null} if none.
      *
      * @see #getDefaultValue()
@@ -141,25 +129,19 @@ public class DefaultAttributeType<T> ext
      *
      * @param properties    The name and other properties to be given to this attribute type.
      * @param valueClass    The type of attribute values.
-     * @param minimumOccurs The minimum number of occurrences of the property within its containing entity.
-     * @param maximumOccurs The maximum number of occurrences of the property within its containing entity,
+     * @param minimumOccurs The minimum number of occurrences of the attribute within its containing entity.
+     * @param maximumOccurs The maximum number of occurrences of the attribute within its containing entity,
      *                      or {@link Integer#MAX_VALUE} if there is no restriction.
      * @param defaultValue  The default value for the attribute, or {@code null} if none.
      */
     public DefaultAttributeType(final Map<String,?> properties, final Class<T> valueClass,
             final int minimumOccurs, final int maximumOccurs, final T defaultValue)
     {
-        super(properties);
+        super(properties, minimumOccurs, maximumOccurs);
         ensureNonNull("valueClass",   valueClass);
         ensureCanCast("defaultValue", valueClass, defaultValue);
-        if (minimumOccurs < 0 || maximumOccurs < minimumOccurs) {
-            throw new IllegalArgumentException(Errors.format(
-                    Errors.Keys.IllegalRange_2, minimumOccurs, maximumOccurs));
-        }
-        this.valueClass    = valueClass;
-        this.minimumOccurs = minimumOccurs;
-        this.maximumOccurs = maximumOccurs;
-        this.defaultValue  = Numerics.cached(defaultValue);
+        this.valueClass   = valueClass;
+        this.defaultValue = Numerics.cached(defaultValue);
     }
 
     /**
@@ -189,8 +171,9 @@ public class DefaultAttributeType<T> ext
      *
      * @return The minimum number of occurrences of the property within its containing entity.
      */
-    public int getMinimumOccurs() {
-        return minimumOccurs;
+    @Override
+    public final int getMinimumOccurs() {
+        return super.getMinimumOccurs();
     }
 
     /**
@@ -201,8 +184,9 @@ public class DefaultAttributeType<T> ext
      * @return The maximum number of occurrences of the property within its containing entity,
      *         or {@link Integer#MAX_VALUE} if none.
      */
-    public int getMaximumOccurs() {
-        return maximumOccurs;
+    @Override
+    public final int getMaximumOccurs() {
+        return super.getMaximumOccurs();
     }
 
     /**
@@ -222,8 +206,7 @@ public class DefaultAttributeType<T> ext
      */
     @Override
     public int hashCode() {
-        return super.hashCode() + valueClass.hashCode() + 37*(minimumOccurs ^ maximumOccurs) +
-               Objects.hashCode(defaultValue);
+        return super.hashCode() + valueClass.hashCode() + Objects.hashCode(defaultValue);
     }
 
     /**
@@ -238,9 +221,7 @@ public class DefaultAttributeType<T> ext
         }
         if (super.equals(obj)) {
             final DefaultAttributeType<?> that = (DefaultAttributeType<?>) obj;
-            return valueClass    == that.valueClass    &&
-                   minimumOccurs == that.minimumOccurs &&
-                   maximumOccurs == that.maximumOccurs &&
+            return valueClass == that.valueClass &&
                    Objects.equals(defaultValue, that.defaultValue);
         }
         return false;
@@ -255,22 +236,6 @@ public class DefaultAttributeType<T> ext
     @Debug
     @Override
     public String toString() {
-        return toString("AttributeType").toString();
-    }
-
-    /**
-     * Implementation of {@link #toString()} to be shared by {@link DefaultAttribute#toString()}.
-     */
-    final StringBuilder toString(final String typeName) {
-        final StringBuilder buffer = new StringBuilder(40).append(typeName).append('[');
-        final GenericName name = super.getName();
-        if (name != null) {
-            buffer.append('“');
-        }
-        buffer.append(name);
-        if (name != null) {
-            buffer.append("” : ");
-        }
-        return buffer.append(Classes.getShortName(valueClass)).append(']');
+        return toString("AttributeType", Classes.getShortName(valueClass)).toString();
     }
 }

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java?rev=1593553&r1=1593552&r2=1593553&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java [UTF-8] Fri May  9 14:42:12 2014
@@ -46,6 +46,8 @@ import org.apache.sis.util.collection.Co
  * @since   0.5
  * @version 0.5
  * @module
+ *
+ * @see DefaultFeatureType
  */
 public class DefaultFeature implements Serializable {
     /**
@@ -65,14 +67,20 @@ public class DefaultFeature implements S
      * only the property <em>values</em>, and build the full {@code Property} objects only if they are
      * requested. The intend is to reduce the amount of allocated objects as much as possible, because
      * typical SIS applications may create a very large amount of features.
+     *
+     * @see #propertiesAreInstantiated
      */
     private final Map<String, Object> properties;
 
     /**
-     * {@code true} if the {@link #properties} map contains fully created {@link Property} instances,
-     * or {@code false} if the map contains only the property values.
+     * {@code true} if the values in the {@link #properties} map are {@link Property} instances,
+     * or {@code false} if the map contains only the "raw" property values.
+     *
+     * <p>This field is initially {@code false}, and will be set to {@code true} only if at least one
+     * {@code Property} instance has been requested. In such case, all property values will have been
+     * wrapped into their appropriate {@code Property} instance.</p>
      */
-    private boolean asPropertyInstances;
+    private boolean propertiesAreInstantiated;
 
     /**
      * Creates a new feature of the given type.
@@ -82,7 +90,7 @@ public class DefaultFeature implements S
     public DefaultFeature(final DefaultFeatureType type) {
         ArgumentChecks.ensureNonNull("type", type);
         this.type = type;
-        properties = new HashMap<>(Math.min(16, Containers.hashMapCapacity(type.characteristics().size())));
+        properties = new HashMap<>(Math.min(16, Containers.hashMapCapacity(type.getInstanceSize())));
     }
 
     /**
@@ -128,8 +136,8 @@ public class DefaultFeature implements S
          * Wraps values in Property objects for all entries in the properties map,
          * if not already done. This operation is execute at most once per feature.
          */
-        if (!asPropertyInstances) {
-            asPropertyInstances = true;
+        if (!propertiesAreInstantiated) {
+            propertiesAreInstantiated = true;
             if (!properties.isEmpty()) { // The map is typically empty when this method is first invoked.
                 for (final Map.Entry<String, Object> entry : properties.entrySet()) {
                     final String key      = entry.getKey();
@@ -187,7 +195,7 @@ public class DefaultFeature implements S
         ArgumentChecks.ensureNonNull("name", name);
         final Object element = properties.get(name);
         if (element != null) {
-            if (!asPropertyInstances) {
+            if (!propertiesAreInstantiated) {
                 return element;
             } else {
                 return ((DefaultAttribute<?>) element).getValue();
@@ -224,7 +232,7 @@ public class DefaultFeature implements S
      */
     public void setPropertyValue(final String name, final Object value) throws IllegalArgumentException {
         ArgumentChecks.ensureNonNull("name", name);
-        if (!asPropertyInstances) {
+        if (!propertiesAreInstantiated) {
             final Object previous = properties.put(name, value);
             /*
              * Slight optimisation: if we replaced a previous value of the same class, then we can skip the
@@ -354,7 +362,7 @@ public class DefaultFeature implements S
         for (final Map.Entry<String,Object> entry : properties.entrySet()) {
             final PropertyType pt;
             Object element = entry.getValue();
-            if (asPropertyInstances) {
+            if (propertiesAreInstantiated) {
                 pt = ((DefaultAttribute<?>) element).getType();
                 element = ((DefaultAttribute<?>) element).getValue();
             } else {

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java?rev=1593553&r1=1593552&r2=1593553&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java [UTF-8] Fri May  9 14:42:12 2014
@@ -24,7 +24,6 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.io.IOException;
 import java.io.ObjectInputStream;
-import java.lang.reflect.Field;
 import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.apache.sis.util.ArgumentChecks;
@@ -48,7 +47,7 @@ import org.apache.sis.internal.util.Unmo
  * <ul>
  *   <li>{@linkplain DefaultAttributeType    Attributes}</li>
  *   <li>{@linkplain DefaultAssociationRole  Associations to other feature types}</li>
- *   <li>{@linkplain DefaultFeatureOperation Operations}</li>
+ *   <li>{@linkplain DefaultOperation        Operations}</li>
  * </ul>
  *
  * The description of all those properties are collectively called {@linkplain #characteristics() characteristics}.
@@ -68,6 +67,8 @@ import org.apache.sis.internal.util.Unmo
  * @since   0.5
  * @version 0.5
  * @module
+ *
+ * @see DefaultFeature
  */
 public class DefaultFeatureType extends AbstractIdentifiedType {
     /**
@@ -83,6 +84,14 @@ public class DefaultFeatureType extends 
     private final boolean isAbstract;
 
     /**
+     * {@code true} if this feature type contains only attributes constrained to the [1 … 1] cardinality,
+     * or operations.
+     *
+     * @see #isSimple()
+     */
+    private transient boolean isSimple;
+
+    /**
      * The parents of this feature type, or an empty set if none.
      */
     private final Set<DefaultFeatureType> superTypes;
@@ -99,7 +108,16 @@ public class DefaultFeatureType extends 
      *
      * @see #getProperty(String)
      */
-    private final transient Map<String, PropertyType> byName;
+    private transient Map<String, PropertyType> byName;
+
+    /**
+     * Indices of properties in an array of properties similar to {@link #characteristics},
+     * but excluding operations.
+     *
+     * The size of this map may be smaller than the {@link #byName} size.
+     * This map shall not be modified after construction.
+     */
+    private transient Map<String, Integer> indices;
 
     /**
      * Constructs a feature type from the given properties. The properties map is given unchanged to
@@ -157,36 +175,48 @@ public class DefaultFeatureType extends 
                           CollectionsExt.<DefaultFeatureType>immutableSet(true, superTypes);
         this.characteristics = UnmodifiableArrayList.wrap(Arrays.copyOf(
                 characteristics, characteristics.length, PropertyType[].class));
-        byName = byName(this.characteristics);
+        computeTransientFields();
     }
 
     /**
-     * Creates a (<var>name</var>, <var>property</var>) map from the given list.
-     * This is used only for performance purpose when searching for attributes.
+     * Creates a (<var>name</var>, <var>property</var>) map from the characteristics list.
      *
      * <p>As a side effect, this method checks for missing or duplicated names.</p>
      *
-     * @param  characteristics The list to convert to a (<var>name</var>, <var>property</var>) map.
-     * @return The map of properties.
      * @throws IllegalArgumentException if two properties have the same name.
      */
-    private static Map<String, PropertyType> byName(final List<PropertyType> characteristics) {
+    private void computeTransientFields() {
         final int length = characteristics.size();
-        final Map<String, PropertyType> byName = new HashMap<>(Containers.hashMapCapacity(length));
+        final int capacity = Containers.hashMapCapacity(length);
+        byName   = new HashMap<>(capacity);
+        indices  = new HashMap<>(capacity);
+        isSimple = true;
+        int index = 0;
         for (int i=0; i<length; i++) {
-            final PropertyType c = characteristics.get(i);
-            ArgumentChecks.ensureNonNullElement("characteristics", i, c);
-            final GenericName name = c.getName();
+            final PropertyType property = characteristics.get(i);
+            ArgumentChecks.ensureNonNullElement("characteristics", i, property);
+            final GenericName name = property.getName();
             if (name == null) {
                 throw new IllegalArgumentException(Errors.format(
                         Errors.Keys.MissingValueForProperty_1, "characteristics[" + i + "].name"));
             }
             final String s = name.toString();
-            if (byName.put(s, c) != null) {
+            if (byName.put(s, property) != null) {
                 throw new IllegalArgumentException(Errors.format(Errors.Keys.DuplicatedIdentifier_1, s));
             }
+            if (!(property instanceof DefaultOperation)) {
+                if (property instanceof DefaultAttributeType<?>) {
+                    switch (((DefaultAttributeType<?>) property).getMaximumOccurs()) {
+                        case 0:  continue;
+                        case 1:  isSimple &= (((DefaultAttributeType<?>) property).getMinimumOccurs() == 1); break;
+                        default: isSimple = false; break;
+                    }
+                } else {
+                    isSimple = false;
+                }
+                indices.put(s, index++);
+            }
         }
-        return byName;
     }
 
     /**
@@ -198,13 +228,7 @@ public class DefaultFeatureType extends 
      */
     private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
         in.defaultReadObject();
-        try {
-            final Field field = DefaultFeatureType.class.getDeclaredField("byName");
-            field.setAccessible(true);
-            field.set(this, byName(characteristics));
-        } catch (ReflectiveOperationException e) {
-            throw new AssertionError(e);
-        }
+        computeTransientFields();
     }
 
     /**
@@ -217,6 +241,16 @@ public class DefaultFeatureType extends 
     }
 
     /**
+     * Returns {@code true} if this feature type contains only attributes constrained to the [1 … 1] cardinality,
+     * or operations. Such feature types can be handled as a {@link org.opengis.util.Record}s.
+     *
+     * @return {@code true} if this feature type contains only simple attributes or operations.
+     */
+    public boolean isSimple() {
+        return isSimple;
+    }
+
+    /**
      * Returns the parents of this feature type.
      *
      * <div class="warning"><b>Warning:</b>
@@ -254,6 +288,14 @@ public class DefaultFeatureType extends 
     }
 
     /**
+     * Returns the number of attributes and features (not operations) that instance will have
+     * if all attributes are handled as simple attributes (maximum occurrences of 1).
+     */
+    final int getInstanceSize() {
+        return indices.size();
+    }
+
+    /**
      * Returns a hash code value for this feature type.
      *
      * @return {@inheritDoc}

Added: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultOperation.java?rev=1593553&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultOperation.java (added)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultOperation.java [UTF-8] Fri May  9 14:42:12 2014
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.feature;
+
+import java.util.Map;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.apache.sis.util.ArgumentChecks;
+
+
+/**
+ * Describes the behaviour of a feature type as a function or a method.
+ * Operations can:
+ *
+ * <ul>
+ *   <li>Compute values from the attributes.</li>
+ *   <li>Perform actions that change the attribute values.</li>
+ * </ul>
+ *
+ * <div class="note"><b>Example:</b> a mutator operation may raise the height of a dam. This changes
+ * may affect other properties like the watercourse and the reservoir associated with the dam.</div>
+ *
+ * <div class="warning"><b>Warning:</b> this class is experimental and may change after we gained more
+ * experience on this aspect of ISO 19109.</div>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.5
+ * @version 0.5
+ * @module
+ */
+public class DefaultOperation extends PropertyType {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 6300319108116735764L;
+
+    /**
+     * A description of the input parameters.
+     */
+    private final ParameterDescriptorGroup parameters;
+
+    /**
+     * The type of the result, or {@code null} if none.
+     */
+    private final DefaultAttributeType<?> result;
+
+    /**
+     * Constructs an attribute type from the given properties. The properties map is given unchanged to
+     * the {@linkplain AbstractIdentifiedType#AbstractIdentifiedType(Map) super-class constructor}.
+     *
+     * @param properties The name and other properties to be given to this operation.
+     * @param parameters A description of the input parameters.
+     * @param result     The type of the result, or {@code null} if none.
+     */
+    public DefaultOperation(final Map<String,?> properties,
+            final ParameterDescriptorGroup parameters, final DefaultAttributeType<?> result)
+    {
+        super(properties);
+        ArgumentChecks.ensureNonNull("inputs", parameters);
+        this.parameters = parameters;
+        this.result     = result;
+    }
+
+    /**
+     * Returns a description of the input parameters.
+     *
+     * @return Description of the input parameters.
+     */
+    public ParameterDescriptorGroup getParameters() {
+        return parameters;
+    }
+
+    /**
+     * Returns the expected result type, or {@code null} if none.
+     *
+     * @return The type of the result, or {@code null} if none.
+     */
+    public DefaultAttributeType<?> getResult() {
+        return result;
+    }
+}

Propchange: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultOperation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultOperation.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Copied: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java (from r1593420, sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java?p2=sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java&p1=sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java&r1=1593420&r2=1593553&rev=1593553&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAttributeType.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java [UTF-8] Fri May  9 14:42:12 2014
@@ -18,55 +18,11 @@ package org.apache.sis.feature;
 
 import java.util.Map;
 import org.opengis.util.GenericName;
-import org.opengis.util.InternationalString;
-import org.apache.sis.util.Debug;
-import org.apache.sis.util.Classes;
 import org.apache.sis.util.resources.Errors;
-import org.apache.sis.internal.util.Numerics;
-
-import static org.apache.sis.util.ArgumentChecks.*;
-
-// Related to JDK7
-import java.util.Objects;
 
 
 /**
- * Definition of an attribute in a feature type.
- * The name of attribute type is mandatory. The name {@linkplain org.apache.sis.util.iso.AbstractName#scope() scope}
- * is typically the name of the {@linkplain DefaultFeatureType feature type} containing this attribute, but this is
- * not mandatory. The scope could also be defined by the ontology for example.
- *
- * <div class="note"><b>Note:</b>
- * Compared to the Java language, {@code AttributeType} is equivalent to {@link java.lang.reflect.Field}
- * while {@code FeatureType} is equivalent to {@link Class}.</div>
- *
- * <div class="warning"><b>Warning:</b>
- * This class is expected to implement a GeoAPI {@code AttributeType} interface in a future version.
- * When such interface will be available, most references to {@code DefaultAttributeType} in current
- * API will be replaced by references to the {@code AttributeType} interface.</div>
- *
- * {@section Value type}
- * Attributes can be used for both spatial and non-spatial properties.
- * Some examples are:
- *
- * <table class="sis">
- *   <caption>Attribute value type examples</caption>
- *   <tr><th>Attribute name</th>      <th>Value type</th></tr>
- *   <tr><td>Building shape</td>      <td>{@link org.opengis.geometry.Geometry}</td></tr>
- *   <tr><td>Building owner</td>      <td>{@link org.opengis.metadata.citation.ResponsibleParty}</td></tr>
- *   <tr><td>Horizontal accuracy</td> <td>{@link org.opengis.metadata.quality.PositionalAccuracy}</td></tr>
- * </table>
- *
- * {@section Immutability and thread safety}
- * Instances of this class are immutable if all properties ({@link GenericName} and {@link InternationalString}
- * instances) and all arguments (e.g. {@code defaultValue}) given to the constructor are also immutable.
- * Such immutable instances can be shared by many objects and passed between threads without synchronization.
- *
- * <p>In particular, the {@link #getDefaultValue()} method does <strong>not</strong> clone the returned value.
- * This means that the same {@code defaultValue} instance may be shared by many {@link DefaultAttribute} instances.
- * Consequently the default value should be immutable for avoiding unexpected behavior.</p>
- *
- * @param <T> The type of attribute values.
+ * Base class of property types having a value and a cardinality.
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
@@ -74,18 +30,11 @@ import java.util.Objects;
  * @version 0.5
  * @module
  */
-public class DefaultAttributeType<T> extends PropertyType {
+abstract class FieldType extends PropertyType {
     /**
      * For cross-version compatibility.
      */
-    private static final long serialVersionUID = 8215784957556648553L;
-
-    /**
-     * The class that describe the type of attribute values.
-     *
-     * @see #getValueClass()
-     */
-    private final Class<T> valueClass;
+    private static final long serialVersionUID = 1681767054884098122L;
 
     /**
      * The minimum number of occurrences of the property within its containing entity.
@@ -99,90 +48,24 @@ public class DefaultAttributeType<T> ext
     private final int maximumOccurs;
 
     /**
-     * The default value for the attribute, or {@code null} if none.
-     *
-     * @see #getDefaultValue()
-     */
-    private final T defaultValue;
-
-    /**
-     * Constructs an attribute type from the given properties. The properties map is given unchanged to
+     * Constructs a field type from the given properties. The properties map is given unchanged to
      * the {@linkplain AbstractIdentifiedType#AbstractIdentifiedType(Map) super-class constructor}.
-     * The following table is a reminder of main (not all) properties:
-     *
-     * <table class="sis">
-     *   <caption>Recognized properties (non exhaustive list)</caption>
-     *   <tr>
-     *     <th>Property name</th>
-     *     <th>Value type</th>
-     *     <th>Returned by</th>
-     *   </tr>
-     *   <tr>
-     *     <td>{@value org.apache.sis.feature.AbstractIdentifiedType#NAME_KEY}</td>
-     *     <td>{@link org.opengis.util.GenericName} or {@link String}</td>
-     *     <td>{@link #getName()}</td>
-     *   </tr>
-     *   <tr>
-     *     <td>{@value org.apache.sis.feature.AbstractIdentifiedType#DEFINITION_KEY}</td>
-     *     <td>{@link org.opengis.util.InternationalString} or {@link String}</td>
-     *     <td>{@link #getDefinition()}</td>
-     *   </tr>
-     *   <tr>
-     *     <td>{@value org.apache.sis.feature.AbstractIdentifiedType#DESIGNATION_KEY}</td>
-     *     <td>{@link org.opengis.util.InternationalString} or {@link String}</td>
-     *     <td>{@link #getDesignation()}</td>
-     *   </tr>
-     *   <tr>
-     *     <td>{@value org.apache.sis.feature.AbstractIdentifiedType#DESCRIPTION_KEY}</td>
-     *     <td>{@link org.opengis.util.InternationalString} or {@link String}</td>
-     *     <td>{@link #getDescription()}</td>
-     *   </tr>
-     * </table>
      *
-     * @param properties    The name and other properties to be given to this attribute type.
-     * @param valueClass    The type of attribute values.
+     * @param properties    The name and other properties to be given to this field type.
      * @param minimumOccurs The minimum number of occurrences of the property within its containing entity.
      * @param maximumOccurs The maximum number of occurrences of the property within its containing entity,
      *                      or {@link Integer#MAX_VALUE} if there is no restriction.
-     * @param defaultValue  The default value for the attribute, or {@code null} if none.
      */
-    public DefaultAttributeType(final Map<String,?> properties, final Class<T> valueClass,
-            final int minimumOccurs, final int maximumOccurs, final T defaultValue)
-    {
+    FieldType(final Map<String,?> properties, final int minimumOccurs, final int maximumOccurs) {
         super(properties);
-        ensureNonNull("valueClass",   valueClass);
-        ensureCanCast("defaultValue", valueClass, defaultValue);
         if (minimumOccurs < 0 || maximumOccurs < minimumOccurs) {
             throw new IllegalArgumentException(Errors.format(
                     Errors.Keys.IllegalRange_2, minimumOccurs, maximumOccurs));
         }
-        this.valueClass    = valueClass;
         this.minimumOccurs = minimumOccurs;
         this.maximumOccurs = maximumOccurs;
-        this.defaultValue  = Numerics.cached(defaultValue);
-    }
-
-    /**
-     * Returns the type of attribute values.
-     *
-     * @return The type of attribute values.
-     */
-    public final Class<T> getValueClass() {
-        return valueClass;
     }
 
-    /*
-     * ISO 19109 properties omitted for now:
-     *
-     *   - valueDomain : CharacterString
-     *
-     * Rational: a CharacterString is hardly programmatically usable. A Range would be better but too specific.
-     * We could follow the GeoAPI path and define a "restrictions : Filter" property. That would be more generic,
-     * but we are probably better to wait for Filter to be implemented in SIS.
-     *
-     * Reference: https://issues.apache.org/jira/browse/SIS-175
-     */
-
     /**
      * Returns the minimum number of occurrences of the property within its containing entity.
      * The returned value is greater than or equal to zero.
@@ -206,62 +89,34 @@ public class DefaultAttributeType<T> ext
     }
 
     /**
-     * Returns the default value for the attribute.
-     * This value is used when an attribute is created and no value for it is specified.
-     *
-     * @return The default value for the attribute, or {@code null} if none.
-     */
-    public T getDefaultValue() {
-        return defaultValue;
-    }
-
-    /**
-     * Returns a hash code value for this attribute type.
+     * Returns a hash code value for this property type.
      *
      * @return {@inheritDoc}
      */
     @Override
     public int hashCode() {
-        return super.hashCode() + valueClass.hashCode() + 37*(minimumOccurs ^ maximumOccurs) +
-               Objects.hashCode(defaultValue);
+        return super.hashCode() + 37*(minimumOccurs + 31*maximumOccurs);
     }
 
     /**
-     * Compares this attribute type with the given object for equality.
+     * Compares this property type with the given object for equality.
      *
      * @return {@inheritDoc}
      */
     @Override
     public boolean equals(final Object obj) {
-        if (obj == this) {
-            return true;
-        }
         if (super.equals(obj)) {
-            final DefaultAttributeType<?> that = (DefaultAttributeType<?>) obj;
-            return valueClass    == that.valueClass    &&
-                   minimumOccurs == that.minimumOccurs &&
-                   maximumOccurs == that.maximumOccurs &&
-                   Objects.equals(defaultValue, that.defaultValue);
+            final FieldType that = (FieldType) obj;
+            return minimumOccurs  == that.minimumOccurs  &&
+                   maximumOccurs  == that.maximumOccurs;
         }
         return false;
     }
 
     /**
-     * Returns a string representation of this attribute type.
-     * The returned string is for debugging purpose and may change in any future SIS version.
-     *
-     * @return A string representation of this attribute type for debugging purpose.
-     */
-    @Debug
-    @Override
-    public String toString() {
-        return toString("AttributeType").toString();
-    }
-
-    /**
-     * Implementation of {@link #toString()} to be shared by {@link DefaultAttribute#toString()}.
+     * Implementation of {@link #toString()} to be shared by subclasses and {@link DefaultAttribute#toString()}.
      */
-    final StringBuilder toString(final String typeName) {
+    final StringBuilder toString(final String typeName, final String valueName) {
         final StringBuilder buffer = new StringBuilder(40).append(typeName).append('[');
         final GenericName name = super.getName();
         if (name != null) {
@@ -271,6 +126,6 @@ public class DefaultAttributeType<T> ext
         if (name != null) {
             buffer.append("” : ");
         }
-        return buffer.append(Classes.getShortName(valueClass)).append(']');
+        return buffer.append(valueName).append(']');
     }
 }

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java?rev=1593553&r1=1593552&r2=1593553&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/package-info.java [UTF-8] Fri May  9 14:42:12 2014
@@ -21,19 +21,23 @@
  * The term “feature” may be used in different contexts:
  *
  * <ul>
- *   <li>{@linkplain org.apache.sis.feature.DefaultFeatureType Feature types} define the <em>structure</em> of
- *       real-world representations. A feature type lists the attributes, operations, or associations to other
- *       features (collectively called “characteristics”) that a feature can have.
- *
- *       <p style="font-size:small"><b>Analogy:</b> a {@code FeatureType} in a Spatial Information System is equivalent
- *       to a {@link java.lang.Class} in the Java language. By extension, {@code AttributeType} and {@code Operation}
- *       are equivalent to {@link java.lang.reflect.Field} and {@link java.lang.reflect.Method} respectively.</p></li>
- *
- *   <li>{@linkplain org.apache.sis.feature.DefaultFeature Feature instances} (often called only {@code Feature}s)
- *       hold the <em>content</em> (or values) that describe one specific real-world object.
- *
- *       <p style="font-size:small"><b>Example:</b> the “Eiffel tower” is a <em>feature instance</em> belonging
- *       to the “Tower” <em>feature type</em>.</p></li>
+ *   <li><p><b>{@linkplain org.apache.sis.feature.DefaultFeatureType Feature types}</b><br>
+ *       Define the <em>structure</em> of real-world representations. A feature type lists the attributes, operations,
+ *       or associations to other features (collectively called “characteristics”) that a feature can have.</p>
+ *
+ *       <div class="note"><b>Analogy:</b> a {@code FeatureType} in a Spatial Information System is equivalent to a
+ *       {@link java.lang.Class} in the Java language. By extension, {@code AttributeType} and {@code Operation} are
+ *       equivalent to {@link java.lang.reflect.Field} and {@link java.lang.reflect.Method} respectively.</div></li>
+ *
+ *   <li><p><b>{@linkplain org.apache.sis.feature.DefaultFeature Feature instances}</b> (often called only Features)<br>
+ *       Hold the <em>content</em> (or values) that describe one specific real-world object.</p>
+ *
+ *       <div class="note"><b>Example:</b> the “Eiffel tower” is a <em>feature instance</em> belonging
+ *       to the “Tower” <em>feature type</em>.</div></li>
+ *
+ *   <li><p><b>{@linkplain org.apache.sis.feature.DefaultFeatureType#isSimple() Simple features}</b><br>
+ *       Are instances of a feature type with no association to other features, and where all attributes
+ *       are constrained to the [1 … 1] cardinality. Such simple features are very common.</p></li>
  * </ul>
  *
  * {@section Class hierarchy}
@@ -51,7 +55,7 @@
  * {@code  └─}                                                                Property type<br>
  * {@code      ├─} {@linkplain org.apache.sis.feature.DefaultAttributeType    Attribute type}<br>
  * {@code      ├─} {@linkplain org.apache.sis.feature.DefaultAssociationRole  Feature association role}<br>
- * {@code      └─} {@linkplain org.apache.sis.feature.DefaultFeatureOperation Operation}<br>
+ * {@code      └─} {@linkplain org.apache.sis.feature.DefaultOperation        Operation}<br>
  * </td><td class="sep" style="width: 50%; white-space: nowrap">
  *             {@linkplain org.apache.sis.feature.DefaultFeature     Feature}<br>
  *                                                                   Property<br>

Modified: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java?rev=1593553&r1=1593552&r2=1593553&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTypeTest.java [UTF-8] Fri May  9 14:42:12 2014
@@ -42,8 +42,8 @@ public final strictfp class DefaultFeatu
      * Creates a simple feature type without super-types.
      */
     static DefaultFeatureType cityPopulation() {
-        final Map<String,Object> properties = new HashMap<>();
-        final DefaultAttributeType<String> city = DefaultAttributeTypeTest.city(properties);
+        final Map<String,Object>            properties = new HashMap<>();
+        final DefaultAttributeType<String>  city       = DefaultAttributeTypeTest.city(properties);
         final DefaultAttributeType<Integer> population = DefaultAttributeTypeTest.population(properties);
 
         properties.clear();
@@ -53,18 +53,22 @@ public final strictfp class DefaultFeatu
 
     /**
      * Tests the construction of a simple feature without super-types.
+     * A feature is said "simple" if the cardinality of all attributes is [1 … 1].
      */
     @Test
     public void testSimple() {
         final DefaultFeatureType simple = cityPopulation();
         assertEquals("name", "City population", simple.getName().toString());
+        assertEquals("instanceSize", 2, simple.getInstanceSize());
+        assertFalse ("isAbstract",      simple.isAbstract());
+        assertTrue  ("isSimple",        simple.isSimple());
         /*
          * Verify content.
          */
         final List<AbstractIdentifiedType> characteristics = simple.characteristics();
-        assertEquals("characteristics.size", 2, characteristics.size());
-        assertEquals("characteristics[0]", "city",       characteristics.get(0).getName().toString());
-        assertEquals("characteristics[1]", "population", characteristics.get(1).getName().toString());
+        assertEquals("characteristics.size", 2,            characteristics.size());
+        assertEquals("characteristics[0]",   "city",       characteristics.get(0).getName().toString());
+        assertEquals("characteristics[1]",   "population", characteristics.get(1).getName().toString());
         /*
          * Verify search by name.
          */
@@ -74,7 +78,54 @@ public final strictfp class DefaultFeatu
     }
 
     /**
-     * Ensures that we can not use two property with the same name.
+     * Tests the construction of a "complex" feature without super-types.
+     * A feature is said "complex" if it contains at least one attribute
+     * with a cardinality different than [0 … 0] and [1 … 1].
+     */
+    @Test
+    @DependsOnMethod("testSimple")
+    public void testComplex() {
+        final Map<String,Object>            properties = new HashMap<>();
+        final DefaultAttributeType<String>  city       = DefaultAttributeTypeTest.city(properties);
+        final DefaultAttributeType<Integer> population = DefaultAttributeTypeTest.population(properties);
+        properties.clear();
+        for (int i=0; i<=4; i++) {
+            final int minimumOccurs, maximumOccurs;
+            switch (i) {
+                case 0: minimumOccurs = 0; maximumOccurs = 0; break; // Simple
+                case 1: minimumOccurs = 0; maximumOccurs = 1; break;
+                case 2: minimumOccurs = 0; maximumOccurs = 2; break;
+                case 3: minimumOccurs = 1; maximumOccurs = 2; break;
+                case 4: minimumOccurs = 1; maximumOccurs = 1; break; // Simple
+                default: throw new AssertionError(i);
+            }
+            properties.put(DefaultAttributeType.NAME_KEY, "festival");
+            final DefaultAttributeType<String> festival = new DefaultAttributeType<>(
+                    properties, String.class, minimumOccurs, maximumOccurs, null);
+            /*
+             * Build the feature.
+             */
+            properties.put(DefaultAttributeType.NAME_KEY, "City festival");
+            final DefaultFeatureType complex = new DefaultFeatureType(properties, false, null, city, population, festival);
+            final List<AbstractIdentifiedType> characteristics = complex.characteristics();
+            /*
+             * Verify content.
+             */
+            assertEquals("name",                 "City festival",                complex.getName().toString());
+            assertFalse ("isAbstract",                                           complex.isAbstract());
+            assertEquals("isSimple",             maximumOccurs == minimumOccurs, complex.isSimple());
+            assertEquals("instanceSize",         maximumOccurs == 0 ? 2 : 3,     complex.getInstanceSize());
+            assertEquals("characteristics.size", 3,                              characteristics.size());
+            assertSame  ("characteristics[0]",   city,                           characteristics.get(0));
+            assertSame  ("characteristics[1]",   population,                     characteristics.get(1));
+            assertSame  ("characteristics[3]",   festival,                       characteristics.get(2));
+            assertEquals("minimumOccurs",        minimumOccurs,                  festival.getMinimumOccurs());
+            assertEquals("maximumOccurs",        maximumOccurs,                  festival.getMaximumOccurs());
+        }
+    }
+
+    /**
+     * Ensures that we can not use two properties with the same name.
      */
     @Test
     @DependsOnMethod("testSimple")



Mime
View raw message