Class AbstractFeature

java.lang.Object
org.apache.sis.feature.AbstractFeature
All Implemented Interfaces:
Serializable
Direct Known Subclasses:
DenseFeature, SparseFeature

public abstract class AbstractFeature extends Object implements Serializable
An instance of a feature type containing values for a real-world phenomena. Each feature instance can provide values for the following properties: AbstractFeature can be instantiated by calls to DefaultFeatureType.newInstance().

Simple features

A feature is said “simple” if it complies to the following conditions:
  • the feature allows only attributes and operations (no associations),
  • the cardinality of all attributes is constrained to [1 … 1].

Limitations

  • Multi-threading: AbstractFeature instances are not thread-safe. Synchronization, if needed, shall be done externally by the caller.
  • Serialization: serialized objects of this class are not guaranteed to be compatible with future versions. Serialization should be used only for short term storage or RMI between applications running the same SIS version.
Since:
0.5
Version:
1.2
See Also:
  • Field Details

  • Constructor Details

  • Method Details

    • getName

      final String getName()
      Return the type name as a non-null string. This is used mostly for formatting error message. This method shall not be invoked when a null name should be considered as an error.
    • getType

      public DefaultFeatureType getType()
      Returns information about the feature (name, characteristics, etc.).
      Warning: In a future SIS version, the return type may be changed to org.opengis.feature.FeatureType. This change is pending GeoAPI revision.
      Returns:
      information about the feature.
    • getProperty

      public Object getProperty(String name) throws IllegalArgumentException
      Returns the property (attribute, feature association or operation result) of the given name. If the property type is a parameterless operation, then this method may return the result of executing the operation on this feature, at implementation choice.

      This method returns the property instance. If only the property value is desired, then getPropertyValue(String) is preferred since it gives to SIS a chance to avoid the creation of AbstractAttribute or AbstractAssociation instances.

      Note for subclass implementers: the default implementation returns an instance that redirect all read and write operations to getPropertyValue(String) and setPropertyValue(String, Object) respectively. That default implementation is intended to make easier for developers to create their own customized AbstractFacture implementations, but has drawbacks: a new Property instance is created every time that this getProperty(String) method is invoked, and the returned Property implementation is not very efficient since it has to perform multiple lookups and type checks. Implementers are encouraged to override this method if they can provide a more efficient implementation. Note that this is already the case when using implementations created by DefaultFeatureType.newInstance().
      Warning: In a future SIS version, the return type may be changed to org.opengis.feature.Property. This change is pending GeoAPI revision.
      Parameters:
      name - the property name.
      Returns:
      the property of the given name (never null).
      Throws:
      IllegalArgumentException - if the given argument is not a property name of this feature.
      See Also:
    • setProperty

      public void setProperty(Object property) throws IllegalArgumentException
      Sets the property (attribute or feature association). The given property shall comply to the following conditions:
      • It must be non-null.
      • Its name shall be the name of the property to set in this feature.
      • Its type shall be the same instance than the property type defined by the feature type for the above name. In other words, the following condition shall hold:
      This method is useful for storing non-default Attribute or FeatureAssociation implementations in this feature. When default implementations are sufficient, the setPropertyValue(String, Object) method is preferred.
      Note for subclass implementers: the default implementation verifies that the given property has the expected type and a null or empty map of characteristics, then delegates to setPropertyValue(String, Object). That default implementation is intended to make easier for developers to create their own customized AbstractFacture implementations, but has drawbacks: the given Property instance is not stored (only its value is stored), and it cannot have custom characteristics. Implementers are encouraged to override this method if they can provide a better implementation. Note that this is already the case when using implementations created by DefaultFeatureType.newInstance().
      Warning: In a future SIS version, the argument may be changed to org.opengis.feature.Property. This change is pending GeoAPI revision.
      Parameters:
      property - the property to set.
      Throws:
      IllegalArgumentException - if the name of the given property is not a property name of this feature.
      IllegalArgumentException - if the value of the given property is not valid.
      IllegalArgumentException - if the property cannot be set for another reason.
      See Also:
    • createProperty

      final Property createProperty(String name, Object value)
      Wraps the given value in a Property object. This method is invoked only by getProperty(String) when it needs to converts its properties data.
      Parameters:
      name - the name of the property to create.
      value - the value to wrap.
      Returns:
      a Property wrapping the given value.
    • createProperty

      final Property createProperty(String name) throws IllegalArgumentException
      Creates a new property initialized to its default value.
      Parameters:
      name - the name of the property to create.
      Returns:
      a Property of the given name.
      Throws:
      IllegalArgumentException - if the given argument is not the name of an attribute or feature association of this feature.
    • getOperationResult

      final Object getOperationResult(String name)
      Executes the parameterless operation of the given name and returns its result.
      See Also:
    • getDefaultValue

      final Object getDefaultValue(String name) throws IllegalArgumentException
      Returns the default value to be returned by getPropertyValue(String) for the property of the given name.
      Parameters:
      name - the name of the property for which to get the default value.
      Returns:
      the default value for the Property of the given name.
      Throws:
      IllegalArgumentException - if the given argument is not an attribute or association name of this feature.
    • getDefaultValue

      private static <V> Object getDefaultValue(DefaultAttributeType<V> attribute)
      Returns the default value to be returned by getPropertyValue(String) for the given attribute type.
    • getPropertyValue

      public abstract Object getPropertyValue(String name) throws IllegalArgumentException
      Returns the value for the property of the given name. This convenience method is equivalent to invoking getProperty(String) for the given name, then to perform one of the following actions depending on the property type and the multiplicity:
      Class of returned value
      Property type max. occurs Method invoked Return type
      AttributeType 0 or 1 Attribute.getValue() Object
      AttributeType 2 or more Attribute.getValues() Collection<?>
      FeatureAssociationRole 0 or 1 FeatureAssociation.getValue() Feature
      FeatureAssociationRole 2 or more FeatureAssociation.getValues() Collection<Feature>
      Note: “max. occurs” is the maximum number of occurrences and does not depend on the actual number of values. If an attribute allows more than one value, then this method will always return a collection for that attribute even if the collection is empty.

      Multi-valued properties and collections

      In the case of multi-valued properties (“max. occurs” > 1), the collection returned by this method may or may not be modifiable, at implementation choice. Generally the caller cannot add new elements into the returned collection anyway since Collection<?> does not allow such operations, and more specific casts (e.g. Collection<String> cannot be checked at runtime (at least as of Java 8). If a type-safe modifiable collection is desired, the following approach can be used instead:
      Parameters:
      name - the property name.
      Returns:
      value of the specified property, or the default value (which may be null} if none.
      Throws:
      IllegalArgumentException - if the given argument is not an attribute or association name of this feature.
      See Also:
    • setPropertyValue

      public abstract void setPropertyValue(String name, Object value) throws IllegalArgumentException
      Sets the value for the property of the given name.

      Validation

      The amount of validation performed by this method is implementation dependent. Usually, only the most basic constraints are verified. This is so for performance reasons and also because some rules may be temporarily broken while constructing a feature. A more exhaustive verification can be performed by invoking the quality() method.
      Parameters:
      name - the attribute name.
      value - the new value for the given attribute (may be null).
      Throws:
      IllegalArgumentException - if the given name is not an attribute or association name of this feature.
      ClassCastException - if the value is not assignable to the expected value class.
      IllegalArgumentException - if the given value is not valid for a reason other than its type.
      See Also:
    • getValueOrFallback

      public abstract Object getValueOrFallback(String name, Object missingPropertyFallback)
      Returns the value for the property of the given name if that property exists, or a fallback value otherwise. This method is equivalent to the following code, but potentially more efficient when the property does not exist: Note that if a property of the given name exists but has no value, then this method returns the default value (which may be null). Property without value is not equivalent to non-existent property.
      Parameters:
      name - the property name.
      missingPropertyFallback - the (potentially null) value to return if no attribute or association of the given name exists.
      Returns:
      value or default value of the specified property, or missingPropertyFallback if no attribute or association of that name exists. This value may be null.
      Since:
      1.1
    • getOperationValue

      protected Object getOperationValue(String name)
      Executes the parameterless operation of the given name and returns the value of its result. This is a convenience method for sub-classes where some properties may be operations that depend on other properties of this Feature instance (for example a link to another property value). Invoking this method is equivalent to performing the following steps:
      Parameters:
      name - the name of the operation to execute. The caller is responsible to ensure that the property type for that name is an instance of AbstractOperation.
      Returns:
      the result value of the given operation, or null if none.
      Since:
      0.8
    • setOperationValue

      protected void setOperationValue(String name, Object value)
      Executes the parameterless operation of the given name and sets the value of its result. This method is the complement of getOperationValue(String) for subclasses where some properties may be operations. Not all operations accept assignments, but the link operation for instance does.
      Parameters:
      name - the name of the operation to execute. The caller is responsible to ensure that the property type for that name is an instance of AbstractOperation.
      value - the value to assign to the result of the named operation.
      Throws:
      IllegalStateException - if the operation of the given name does not accept assignment.
      Since:
      0.8
    • getAttributeValue

      static Object getAttributeValue(AbstractAttribute<?> property)
      Returns the value of the given attribute, as a singleton or as a collection depending on the maximum number of occurrences.
    • getAssociationValue

      static Object getAssociationValue(AbstractAssociation property)
      Returns the value of the given association, as a singleton or as a collection depending on the maximum number of occurrences.
    • setPropertyValue

      static void setPropertyValue(Property property, Object value)
      Sets the value of the given property, with some minimal checks.
    • setAttributeValue

      private static <V> void setAttributeValue(AbstractAttribute<V> attribute, Object value)
      Sets the attribute value after verification of its type. This method is invoked only for checking that we are not violating the Java parameterized type contract. For a more exhaustive validation, use Validator instead.
    • setAssociationValue

      private static void setAssociationValue(AbstractAssociation association, Object value)
      Sets the association value after verification of its type. For a more exhaustive validation, use Validator instead.
    • canSkipVerification

      static boolean canSkipVerification(Object previous, Object value)
      Returns true if the caller can skip the call to verifyPropertyValue(String, Object). This is a slight optimization for the case when we replaced an attribute value by a new value of the same class. Since the type check has already been done by the previous assignation, we do not need to perform it again.
      Parameters:
      previous - the previous value, or null.
      value - the new value, or null.
      Returns:
      true if the caller can skip the verification performed by verifyPropertyValue.
    • verifyPropertyType

      final void verifyPropertyType(String name, Property property)
      Verifies if the given property can be assigned to this feature.
      Parameters:
      name - shall be property.getName().toString().
      property - the property to verify.
    • verifyPropertyValue

      final Object verifyPropertyValue(String name, Object value)
      Verifies the validity of the given value for the property of the given name, then returns the value to store. The returned value is usually the same than the given one, except in the case of collections.
    • verifyAttributeValue

      private static <T> Object verifyAttributeValue(DefaultAttributeType<T> type, Object value)
      Verifies the validity of the given attribute value, and returns the value to store in the feature. An attribute:
      • May be a singleton, in which case the value class is verified.
      • May be a collection, in which case the class each elements in the collection is verified.
      Parameters:
      value - the value, which shall be non-null.
    • verifyAssociationValue

      private static Object verifyAssociationValue(DefaultAssociationRole role, Object value)
      Verifies the validity of the given association value, and returns the value to store in the feature. An association:
      • May be a singleton, in which case the feature type is verified.
      • May be a collection, in which case the class each elements in the collection is verified.
      Parameters:
      value - the value, which shall be non-null.
    • verifyAssociationValues

      private static void verifyAssociationValues(DefaultAssociationRole role, Collection<?> values)
      Verifies if all values in the given collection are valid instances of feature for the given association role.
    • singletonList

      private static <V> Collection<V> singletonList(Class<V> valueClass, int minimumOccurs, Object value)
      Creates a collection which will initially contain only the given value. At the difference of Collections.singletonList(Object), this method returns a modifiable list.
    • propertyNotFound

      static String propertyNotFound(FeatureType type, Object feature, String property)
      Returns the exception message for a property not found. The message will differ depending on whether the property is not found because ambiguous or because it does not exist.
      Parameters:
      feature - the name of the feature where a property where searched (String or GenericName).
      property - the name of the property which has not been found.
    • unsupportedPropertyType

      static String unsupportedPropertyType(org.opengis.util.GenericName name)
      Returns the exception message for a property type which is neither an attribute or an association. This method is invoked after a PropertyType has been found for the user supplied name, but that property cannot be stored in or extracted from a Property instance.
    • illegalValueClass

      private static String illegalValueClass(AbstractIdentifiedType property, Class<?> expected, Object value)
      Returns the exception message for a property value of wrong Java class.
      Parameters:
      value - the value, which shall be non-null.
    • illegalFeatureType

      private static String illegalFeatureType(DefaultAssociationRole association, FeatureType expected, FeatureType actual)
      Returns the exception message for an association value of wrong type.
    • quality

      public org.opengis.metadata.quality.DataQuality quality()
      Evaluates the quality of this feature at this method invocation time. The data quality reports may include information about whether the property values met the constraints defined by the property types, or any other criterion at implementation choice.

      The default implementation reports data quality with at least the following information:

      This feature is valid if this method does not report any conformance result having a pass value of false.
      Example: given a feature with an attribute named “population”. If this attribute is mandatory ([1 … 1] multiplicity) but no value has been assigned to it, then this quality() method will return the following data quality report:
      Returns:
      reports on all constraint violations found.
      See Also:
    • toString

      public String toString()
      Formats this feature in a tabular format.
      Overrides:
      toString in class Object
      Returns:
      a string representation of this feature in a tabular format.
      See Also:
    • comparisonStart

      final boolean comparisonStart()
      Notifies that a hashCode() or equals(Object) method started execution for the given feature and returns true if there is no recursion. This method must be invoked in a try ... finally block as below:
      Returns:
      true if hash code or equality comparison can proceed, or false if a recursivity is detected.
    • comparisonEnd

      final void comparisonEnd()
      Notifies that the comparison of this feature is finished.
    • hashCode

      public int hashCode()
      Returns a hash code value for this feature. The default implementation performs the following algorithm:
      • Iterate over all properties returned by type.getProperty(true) – thus including properties inherited from parent types (if any):
        • For each property type, get the value with getPropertyValue(String).
        • Compute the hash code from the property name and value, ignoring the properties having a null value.
      Subclasses should override this method with a more efficient algorithm for their internal structure. There is no need to reproduce the same hash code value than the one computed by this default method.
      Overrides:
      hashCode in class Object
      Returns:
      a hash code value.
      Since:
      0.8
    • equals

      public boolean equals(Object obj)
      Compares this feature with the given object for equality. The default implementation performs the following algorithm:
      • Verify that both objects are non-null and of the same class.
      • Iterate over all properties returned by type.getProperty(true) – thus including properties inherited from parent types (if any):
      Subclasses should override this method with a more efficient algorithm for their internal structure.
      Overrides:
      equals in class Object
      Returns:
      true if both objects are equal.
      Since:
      0.8