sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1739012 - in /sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature: AbstractFeature.java AggregateOperation.java BoundsOperation.java FeatureOperations.java LinkOperation.java
Date Wed, 13 Apr 2016 21:59:55 GMT
Author: desruisseaux
Date: Wed Apr 13 21:59:55 2016
New Revision: 1739012

URL: http://svn.apache.org/viewvc?rev=1739012&view=rev
Log:
Javadoc and argument validations.

Modified:
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AggregateOperation.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/BoundsOperation.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java
    sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java?rev=1739012&r1=1739011&r2=1739012&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AbstractFeature.java
[UTF-8] Wed Apr 13 21:59:55 2016
@@ -228,7 +228,7 @@ public abstract class AbstractFeature im
     final Object getOperationValue(final String name) {
         final Operation operation = (Operation) type.getProperty(name);
         if (operation instanceof LinkOperation) {
-            return getPropertyValue(((LinkOperation) operation).propertyName);
+            return getPropertyValue(((LinkOperation) operation).referentName);
         }
         final Property result = operation.apply(this, null);
         if (result instanceof Attribute<?>) {
@@ -246,7 +246,7 @@ public abstract class AbstractFeature im
     final void setOperationValue(final String name, final Object value) {
         final Operation operation = (Operation) type.getProperty(name);
         if (operation instanceof LinkOperation) {
-            setPropertyValue(((LinkOperation) operation).propertyName, value);
+            setPropertyValue(((LinkOperation) operation).referentName, value);
         } else {
             final Property result = operation.apply(this, null);
             if (result != null) {

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AggregateOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AggregateOperation.java?rev=1739012&r1=1739011&r2=1739012&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AggregateOperation.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/AggregateOperation.java
[UTF-8] Wed Apr 13 21:59:55 2016
@@ -18,29 +18,37 @@ package org.apache.sis.feature;
 
 import java.util.Map;
 import java.util.Collections;
+import java.util.Set;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.util.GenericName;
+import org.apache.sis.internal.util.CollectionsExt;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.ObjectConverters;
+
+// Branch-dependent imports
 import org.opengis.feature.AttributeType;
 import org.opengis.feature.Feature;
 import org.opengis.feature.FeatureType;
 import org.opengis.feature.IdentifiedType;
 import org.opengis.feature.MultiValuedPropertyException;
 import org.opengis.feature.Property;
-import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.util.GenericName;
-import org.apache.sis.util.ObjectConverters;
 
 
 /**
- * An aggregate operation concatenating the values of multiple properties.
- * This operation is mainly used as an {@code id} generator for multiple properties used
as primary keys.
+ * An operation concatenating the string representations of the values of multiple properties.
+ * This operation can be used for creating a <cite>compound key</cite> as a {@link
String}
+ * that consists of two or more attribute values that uniquely identify a feature instance.
  *
- * <p>This operation support both reading and writing. When setting the operation value,
- * the value will be split and forwarded to each attribute element.</p>
+ * <p>This operation supports both reading and writing. When setting a value on the
attribute
+ * created by this operation, the value will be split and forwarded to each single attribute.</p>
  *
  * @author  Johann Sorel (Geomatys)
  * @since   0.7
  * @version 0.7
  * @module
+ *
+ * @see <a href="https://en.wikipedia.org/wiki/Compound_key">Compound key on Wikipedia</a>
  */
 final class AggregateOperation extends AbstractOperation {
     /**
@@ -52,28 +60,57 @@ final class AggregateOperation extends A
      * The type of the result returned by the aggregate operation.
      */
     private static final AttributeType<String> TYPE = new DefaultAttributeType<>(
-            Collections.singletonMap(DefaultAttributeType.NAME_KEY, "String"), String.class,
1, 1, null);
+            Collections.singletonMap(NAME_KEY, "String"), String.class, 1, 1, null);
 
     /**
      * The parameter descriptor for the "Aggregate" operation, which does not take any parameter.
      */
     private static final ParameterDescriptorGroup EMPTY_PARAMS = LinkOperation.parameters("Aggregate",
1);
 
-    private final GenericName[] attributeNames;
+    /**
+     * The name of the properties from which to get the values to concatenate.
+     */
+    private final String[] propertyNames;
+
+    /**
+     * The property names as an unmodifiable set, created when first needed.
+     */
+    private transient Set<String> dependencies;
+
+    /**
+     * The characters to use at the beginning of the concatenated string, or an empty string
if none.
+     */
     private final String prefix;
+
+    /**
+     * The characters to use at the end of the concatenated string, or an empty string if
none.
+     */
     private final String suffix;
+
+    /**
+     * The characters to use a delimiter between each single attribute value.
+     */
     private final String separator;
 
-    AggregateOperation(Map<String, ?> identification, String prefix, String suffix,
String separator, GenericName ... attributeNames) {
+    /**
+     * Creates a new operation for string concatenations using the given prefix, suffix and
delimeter.
+     */
+    AggregateOperation(final Map<String, ?> identification, final String prefix, final
String suffix,
+            final String separator, final GenericName[] singleProperties)
+    {
         super(identification);
-        this.attributeNames = attributeNames;
+        propertyNames = new String[singleProperties.length];
+        for (int i=0; i < singleProperties.length; i++) {
+            ArgumentChecks.ensureNonNullElement("singleProperties", i, singleProperties);
+            propertyNames[i] = singleProperties[i].toString();
+        }
         this.prefix = (prefix == null) ? "" : prefix;
         this.suffix = (suffix == null) ? "" : suffix;
         this.separator = separator;
     }
 
     /**
-     * Aggregation operation do not require any parameter.
+     * Concatenate operation do not require any parameter.
      *
      * @return empty parameter group.
      */
@@ -83,9 +120,9 @@ final class AggregateOperation extends A
     }
 
     /**
-     * Aggregation operation generates a String result.
+     * Concatenate operation generates a {@link String} result.
      *
-     * @return aggregation string type
+     * @return concatenated string type.
      */
     @Override
     public IdentifiedType getResult() {
@@ -93,16 +130,27 @@ final class AggregateOperation extends A
     }
 
     /**
-     * {@inheritDoc }
+     * Returns the names of feature properties that this operation needs for performing its
task.
+     */
+    @Override
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
+    public synchronized Set<String> getDependencies() {
+        if (dependencies == null) {
+            dependencies = CollectionsExt.immutableSet(true, propertyNames);
+        }
+        return dependencies;
+    }
+
+    /**
+     * Returns the concatenation of property values of the given feature.
      *
-     * @param  feature    The feature on which to execute the operation.
-     *                    Can not be {@code null}.
-     * @param  parameters The parameters to use for executing the operation.
-     *                    Can be {@code null}.
-     * @return The operation result, never null.
+     * @param  feature    the feature on which to execute the operation.
+     * @param  parameters ignored (can be {@code null}).
+     * @return the concatenation of feature property values.
      */
     @Override
     public Property apply(Feature feature, ParameterValueGroup parameters) {
+        ArgumentChecks.ensureNonNull("feature", feature);
         return new AggregateAttribute(feature);
     }
 
@@ -124,9 +172,9 @@ final class AggregateOperation extends A
             final StringBuilder sb = new StringBuilder();
             sb.append(prefix);
 
-            for (int i=0; i < attributeNames.length; i++) {
-                if (i!=0) sb.append(separator);
-                sb.append(feature.getPropertyValue(attributeNames[i].toString()));
+            for (int i=0; i < propertyNames.length; i++) {
+                if (i != 0) sb.append(separator);
+                sb.append(feature.getPropertyValue(propertyNames[i]));
             }
 
             sb.append(suffix);
@@ -144,7 +192,7 @@ final class AggregateOperation extends A
             }
 
             //split values, we don't use the regex split to avoid possible reserverd regex
characters
-            final Object[] values = new Object[attributeNames.length];
+            final Object[] values = new Object[propertyNames.length];
             int i = 0;
             int offset = 0;
             //remove prefix and suffix
@@ -154,14 +202,12 @@ final class AggregateOperation extends A
                     throw new IllegalArgumentException("Unvalid string, expected "+values.length+"
values, but found more");
                 }
                 final int idx = value.indexOf(separator, offset);
-                if (idx == -1) {
+                if (idx < 0) {
                     //last element
-                    values[i] = value.substring(offset);
-                    i++;
+                    values[i++] = value.substring(offset);
                     break;
                 } else {
-                    values[i] = value.substring(offset, idx);
-                    i++;
+                    values[i++] = value.substring(offset, idx);
                     offset = (idx + separator.length());
                 }
             }
@@ -173,7 +219,7 @@ final class AggregateOperation extends A
             //set values, convert them if necessary
             final FeatureType type = feature.getType();
             for (int k=0; k < values.length; k++) {
-                final String propName = attributeNames[k].toString();
+                final String propName = propertyNames[k];
                 final AttributeType<?> pt = (AttributeType<?>) type.getProperty(propName);
                 final Object val = ObjectConverters.convert(values[k], pt.getValueClass());
                 feature.setPropertyValue(propName, val);

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/BoundsOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/BoundsOperation.java?rev=1739012&r1=1739011&r2=1739012&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/BoundsOperation.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/BoundsOperation.java
[UTF-8] Wed Apr 13 21:59:55 2016
@@ -22,8 +22,6 @@ import java.util.Collections;
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import static org.apache.sis.feature.AbstractIdentifiedType.NAME_KEY;
-import static org.apache.sis.feature.LinkOperation.parameters;
 import org.apache.sis.geometry.Envelopes;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.opengis.feature.AttributeType;
@@ -52,7 +50,7 @@ import org.opengis.referencing.operation
  * crs will be used.
  * <br>
  * This operation can only be read, not setted.
- * 
+ *
  * @author Johann Sorel (Geomatys)
  * @since   0.7
  * @version 0.7
@@ -70,12 +68,12 @@ final class BoundsOperation extends Abst
     /**
      * The parameter descriptor for the "Bounds" operation, which does not take any parameter.
      */
-    private static final ParameterDescriptorGroup EMPTY_PARAMS = parameters("Link", 1);
+    private static final ParameterDescriptorGroup EMPTY_PARAMS = LinkOperation.parameters("Bounds",
1);
 
     private final CoordinateReferenceSystem crs;
 
     /**
-     * 
+     *
      * @param identification The name and other information to be given to this operation.
      * @param crs result envelope CRS, can be {@code null}
      */
@@ -198,5 +196,5 @@ final class BoundsOperation extends Abst
 
         return bounds;
     }
-    
+
 }

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java?rev=1739012&r1=1739011&r2=1739012&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureOperations.java
[UTF-8] Wed Apr 13 21:59:55 2016
@@ -17,56 +17,102 @@
 package org.apache.sis.feature;
 
 import java.util.Collections;
-import org.apache.sis.util.Static;
 import org.opengis.feature.Operation;
 import org.opengis.feature.PropertyType;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.util.GenericName;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.Static;
+
 
 /**
- * FeatureType operations utility methods.
+ * A set of pre-defined operations expecting a {@code Feature} as input and producing an
{@code Attribute} as output.
+ * Those operations can be used for creating <cite>dynamic properties</cite>
which compute their value on-the-fly
+ * from the values of other properties.
  *
- * @author Johann Sorel (Geomatys)
+ * <p>A flexible but relatively cumbersome way to define arbitrary computations is
to subclass {@link AbstractOperation}.
+ * This {@code FeatureOperations} class provides a more convenient way to get a few commonly-used
operations.</p>
+ *
+ * @author  Johann Sorel (Geomatys)
  * @since   0.7
  * @version 0.7
  * @module
  */
 public final class FeatureOperations extends Static {
+    /**
+     * Do not allow instantiation of this class.
+     */
+    private FeatureOperations() {
+    }
 
     /**
-     * Create a link operation property type.
+     * Creates an operation which is only an alias for another property.
      *
-     * @param name name of the property
-     * @param linkAttributeType linked property type
-     * @return Operation
+     * <div class="note"><b>Example:</b>
+     * features often have a property that can be used as identifier or primary key.
+     * But the name of that property may vary between features of different types.
+     * 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"}
+     * 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:
+     *
+     * {@preformat java
+     *   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);
+     * }
+     * </div>
+     *
+     * <div class="section">Read/write behavior</div>
+     * Since the {@link AbstractOperation#apply Operation.apply(…)} method returns directly
the property
+     * identified by the {@code referent} argument, the returned property is writable if
the referenced
+     * property is also writable.
+     *
+     * @param  name      name of the property to create.
+     * @param  referent  the referenced attribute or feature association.
+     * @return an operation which is an alias for the {@code referent} property.
      */
-    public static Operation link(GenericName name, PropertyType linkAttributeType){
-        return new LinkOperation(Collections.singletonMap("name", name), linkAttributeType);
+    public static Operation link(final GenericName name, final PropertyType referent) {
+        ArgumentChecks.ensureNonNull("referent", referent);
+        return new LinkOperation(Collections.singletonMap("name", name), referent);
     }
 
     /**
-     * Create an aggregation operation property type.
+     * Creates an operation concatenating the string representations of the values of multiple
properties.
+     * This operation can be used for creating a <cite>compound key</cite> as
a {@link String} that consists
+     * of two or more attribute values that uniquely identify a feature instance.
      *
-     * @param name name of the property
-     * @param prefix prefix of the resulting aggregated string
-     * @param suffix suffix of the resulting aggregated string
-     * @param separator separator between each value
-     * @param aggAttributeNames aggregated attribute values
-     * @return Operation
+     * <div class="section">Read/write behavior</div>
+     * This operation supports both reading and writing. When setting a value on the attribute
created by this
+     * operation, the given string value will be split around the {@code separator} and each
substring will be
+     * forwarded to the corresponding single property.
+     *
+     * @param  name       name of the property to create.
+     * @param  prefix     characters to use at the beginning of the concatenated string,
or {@code null} if none.
+     * @param  suffix     characters to use at the end of the concatenated string, or {@code
null} if none.
+     * @param  separator  the characters to use a delimiter between each single attribute
value.
+     * @param  singleProperties  identification of the single properties to concatenate.
+     * @return an operation which concatenates the string representations of all referenced
single attribute values.
+     *
+     * @see <a href="https://en.wikipedia.org/wiki/Compound_key">Compound key on Wikipedia</a>
      */
-    public static Operation aggregate(GenericName name, String prefix, String suffix, String
separator, GenericName ... aggAttributeNames){
-        return new AggregateOperation(Collections.singletonMap("name", name), prefix, suffix,
separator, aggAttributeNames);
+    public static Operation aggregate(GenericName name, String prefix, String suffix, String
separator, GenericName... singleProperties) {
+        ArgumentChecks.ensureNonEmpty("separator", separator);
+        ArgumentChecks.ensureNonNull("singleProperties", singleProperties);
+        return new AggregateOperation(Collections.singletonMap("name", name), prefix, suffix,
separator, singleProperties);
     }
 
     /**
-     * Create a calculate bounds operation type.
+     * Creates a calculate bounds operation type.
      *
      * @param name name of the property
      * @param baseCrs created envelope crs
      * @return Operation
      */
-    public static Operation bounds(GenericName name, CoordinateReferenceSystem baseCrs){
+    public static Operation bounds(GenericName name, CoordinateReferenceSystem baseCrs) {
         return new BoundsOperation(Collections.singletonMap("name", name), baseCrs);
     }
-
 }

Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java?rev=1739012&r1=1739011&r2=1739012&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/LinkOperation.java
[UTF-8] Wed Apr 13 21:59:55 2016
@@ -82,18 +82,18 @@ final class LinkOperation extends Abstra
     /**
      * The name of the referenced attribute or feature association.
      */
-    final String propertyName;
+    final String referentName;
 
     /**
      * Creates a new link to the given attribute or association.
      *
-     * @param identification The name of the link, together with optional information.
-     * @param propertyType   The referenced attribute or feature association.
+     * @param identification  the name of the link, together with optional information.
+     * @param referent        the referenced attribute or feature association.
      */
-    LinkOperation(final Map<String, ?> identification, final PropertyType propertyType)
{
+    LinkOperation(final Map<String, ?> identification, final PropertyType referent)
{
         super(identification);
-        result = propertyType;
-        propertyName = propertyType.getName().toString();
+        result = referent;
+        referentName = referent.getName().toString();
     }
 
     /**
@@ -117,19 +117,19 @@ final class LinkOperation extends Abstra
      */
     @Override
     public Set<String> getDependencies() {
-        return Collections.singleton(propertyName);
+        return Collections.singleton(referentName);
     }
 
     /**
      * Returns the property from the referenced attribute of feature association.
      *
-     * @param  feature    The feature from which to get the property.
-     * @param  parameters Ignored.
-     * @return The property from the given feature.
+     * @param  feature     the feature from which to get the property.
+     * @param  parameters  ignored (can be {@code null}).
+     * @return the linked property from the given feature.
      */
     @Override
     public Property apply(final Feature feature, final ParameterValueGroup parameters) {
         ArgumentChecks.ensureNonNull("feature", feature);
-        return feature.getProperty(propertyName);
+        return feature.getProperty(referentName);
     }
 }



Mime
View raw message