001/*
002 *    GeoAPI - Java interfaces for OGC/ISO standards
003 *    Copyright © 2006-2024 Open Geospatial Consortium, Inc.
004 *    http://www.geoapi.org
005 *
006 *    Licensed under the Apache License, Version 2.0 (the "License");
007 *    you may not use this file except in compliance with the License.
008 *    You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *    Unless required by applicable law or agreed to in writing, software
013 *    distributed under the License is distributed on an "AS IS" BASIS,
014 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 *    See the License for the specific language governing permissions and
016 *    limitations under the License.
017 */
018package org.opengis.feature;
019
020import java.util.Map;
021import java.util.Collection;
022import org.opengis.util.GenericName;
023
024
025/**
026 * An instance of an {@link AttributeType} containing the value of an attribute in a feature.
027 * {@code Attribute} holds three main information:
028 *
029 * <ul>
030 *   <li>A {@linkplain #getType() reference to an attribute type}
031 *       which defines the base Java type and domain of valid values.</li>
032 *   <li>One or more {@linkplain #getValues() values}, which may be a singleton ([0 … 1] multiplicity)
033 *       or multi-valued ([0 … ∞] multiplicity).</li>
034 *   <li>Optional {@linkplain #characteristics() characteristics} about the attribute
035 *       (e.g. a <var>temperature</var> attribute may have a characteristic holding the measurement <var>accuracy</var>).
036 *       Characteristics are often, but not necessarily, constant for all attributes of the same type in a dataset.</li>
037 * </ul>
038 *
039 * <div class="note"><b>Analogy with Java language</b>:
040 * an attribute is similar to a "field" in a Java object. A field also brings together a field name, value and type,
041 * optionally completed by annotations. The value types are typically {@link String}, {@link Number} or collections
042 * of them, but other Java type are allowed except {@link Feature}.
043 * For storing a {@code Feature} value, use {@link FeatureAssociation} instead.
044 * </div>
045 *
046 * <p>{@code Attribute} can be instantiated by calls to {@link AttributeType#newInstance()}.</p>
047 *
048 * @param <V> the type of attribute values. If the attribute supports multi-occurrences,
049 *            then this is the type of elements (not the collection type).
050 *
051 * @author  Jody Garnett (Refractions Research, Inc.)
052 * @author  Justin Deoliveira (The Open Planning Project)
053 * @author  Martin Desruisseaux (Geomatys)
054 * @version 3.1
055 * @since   3.1
056 *
057 * @see AttributeType
058 * @see DynamicAttribute
059 */
060public interface Attribute<V> extends Property {
061    /**
062     * Returns the name of this attribute as defined by its {@linkplain #getType() type}.
063     * This convenience method delegates to {@link AttributeType#getName()}.
064     *
065     * @return the attribute name specified by its type.
066     */
067    @Override
068    GenericName getName();
069
070    /**
071     * Returns information about the attribute (base Java class, domain of values, <i>etc.</i>).
072     *
073     * @return information about the attribute.
074     */
075    AttributeType<V> getType();
076
077    /**
078     * Returns the attribute value, or {@code null} if none. This convenience method can be invoked
079     * in the common case where the {@linkplain AttributeType#getMaximumOccurs() maximum number}
080     * of attribute values is restricted to 1 or 0.
081     *
082     * @return the attribute value (may be {@code null}).
083     * @throws MultiValuedPropertyException if this attribute contains more than one value.
084     *
085     * @see Feature#getPropertyValue(String)
086     */
087    @Override
088    V getValue() throws MultiValuedPropertyException;
089
090    /**
091     * Sets the attribute value. All previous values are replaced by the given singleton.
092     *
093     * <h4>Note on validation</h4>
094     * The verifications performed by this method is implementation dependent.
095     * For performance reasons, an implementation may verify only the most basic constraints
096     * and offer another method for performing more extensive validation.
097     * Implementations should document their validation process.
098     *
099     * @param  value  the new value, or {@code null} for removing all values from this attribute.
100     * @throws InvalidPropertyValueException if this method verifies argument validity and the given value
101     *         does not met the attribute constraints.
102     *
103     * @see Feature#setPropertyValue(String, Object)
104     */
105    void setValue(V value) throws InvalidPropertyValueException;
106
107    /**
108     * Returns all attribute values, or an empty collection if none.
109     * This method supports arbitrary cardinality of attribute values.
110     * In the common case where the {@linkplain AttributeType#getMaximumOccurs() maximum number of occurrences}
111     * is restricted to 1, {@link #getValue()} is a convenient alternative.
112     *
113     * <h4>Note for implementers</h4>
114     * There is different approaches in the way that collection elements are related to this property values:
115     * <ul>
116     *   <li>The collection may be a snapshot of property values at the method invocation time.</li>
117     *   <li>The collection may be an unmodifiable view of properties values.</li>
118     *   <li>The collection may be <i>live</i> (changes in the collection are reflected in this attribute, and vis-versa).</li>
119     * </ul>
120     * This method does not mandate a particular approach.
121     * However, implementations should document which policy they choose.
122     *
123     * @return the attribute values.
124     */
125    Collection<V> getValues();
126
127    /**
128     * Sets the attribute values. All previous values are replaced by the given collection.
129     *
130     * <h4>Note on validation</h4>
131     * The verifications performed by this method is implementation dependent.
132     * For performance reasons, an implementation may verify only the most basic constraints
133     * and offer another method for performing more extensive validation.
134     * Implementations should document their validation process.
135     *
136     * @param  values  the new values.
137     * @throws InvalidPropertyValueException if this method verifies argument validity and the given values
138     *         do not met the attribute constraints.
139     */
140    void setValues(Collection<? extends V> values) throws InvalidPropertyValueException;
141
142    /**
143     * Other attributes that describe this attribute. For example if this attribute carries a measurement,
144     * then a characteristic of this attribute could be the measurement accuracy.
145     * See <cite>Attribute characterization</cite> in {@link AttributeType} Javadoc for more information.
146     *
147     * <p>Attributes having a value equals to their {@linkplain AttributeType#getDefaultValue() default value}
148     * do not need to appear in this characteristics map. For example all temperature measurements in a dataset
149     * may have the same accuracy, which can be specified only once in the {@link AttributeType#characteristics()}
150     * map instead of being repeated in every {@code Attribute.characteristics()} maps.</p>
151     *
152     * <p>The characteristic values are enumerated in the {@linkplain Map#values() map values}.
153     * The {@linkplain Map#keySet() map keys} are the {@code String} representations of
154     * characteristics {@linkplain AttributeType#getName() name}, for more convenient lookups.</p>
155     *
156     * @return other attribute types that describe this attribute type, or an empty map if none.
157     *
158     * @see AttributeType#characteristics()
159     */
160    Map<String,Attribute<?>> characteristics();
161}