/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2011, Open Source Geospatial Foundation (OSGeo) * (C) 2004-2007 Open Geospatial Consortium Inc. * * All Rights Reserved. http://www.opengis.org/legal/ */ package org.opengis.feature; import java.util.Collection; import org.opengis.feature.type.ComplexType; import org.opengis.feature.type.Name; import org.opengis.filter.expression.Expression; /** * An instance of {@link ComplexType} which is composed of other properties. * <p> * A complex attribute is a container for other properties (attributes + * associations). The value of a complex attribute is a collection of those * contained properties. * </p> * <br/> * <p> * <h3>Property Access</h3> * The {@link #getValue()} method returns a collection of the properties * contained by the complex attribute. * * <pre> * ComplexAttribute attribute = ...; * * //loop through all the properties * for (Property p : attribute.getValue(); ) { * // do something with the property * } * </pre> * * <br> * Contained properties can also be fetched by name by {@link Name} with the * {@link #getProperties(Name)} and {@link #getProperties(String)} methods. * * <pre> * ComplexAttribute attribute = ...; * * //loop through all the "foo" attributes * for ( Property p : attribute.getProperties( "foo" ) ) { * p.getName().getLocalPart() == "foo"; * } * </pre> * * <br> * Often it is known in advance that a single instance of a particular property * exists. When this is the case the {@link #getProperty(Name)} and * {@link #getProperty(String)} methods can be used to get direct access to the * property. * * <pre> * ComplexAttribute attribute = ...; * * //get the single foo attribute * Property foo = attribute.getProperty( "foo" ); * </pre> * * </p> * <br> * <p> * <h3>Xpath and Query Language Access</h3> * The above property access methods perform an exact match on property name * against the name passed in. However, often it is necesary to access * properties via a query language such as xpath. * </p> * <br> * <p> * For instance.the expression <code>"//foo"</code> should return all the * properties named "foo". Or the expression <code>"foo/bar"</code> should * return the "bar" property nested inside of the "foo" property. In these * cases, an {@link Expression} must be used: * * <pre> * ComplexAttribute attribute = ...; * * //get the 'foo/bar' property * FilterFactory factory = ...; * PropertyName xpath = factory.property( "foo/bar" ); * Property bar = xpath.evaluate( attribute ); * </pre> * * </p> * * @author Jody Garnett, Refractions Research * @author Gabriel Roldan, Axios Engineering * @author Justin Deoliveira, The Open Planning Project * * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/library/opengis/src/main/java/org/opengis/feature/ComplexAttribute.java $ */ public interface ComplexAttribute extends Attribute { /** * Override of {@link Attribute#getType()} which type narrows to * {@link ComplexType}. * * @see Attribute#getType() */ ComplexType getType(); /** * Sets the contained properties of the complex attribute. * <p> * The <tt>values</tt> should match the structure defined by * <code>getDescriptor()</code>. * </p> */ void setValue(Collection<Property> values); /** * Override of {@link Property#getValue()} which returns the collection of * {@link Property} which make up the value of the complex attribute. */ Collection<? extends Property> getValue(); /** * Returns a subset of the properties of the complex attribute which match * the specified name. * <p> * The <tt>name</tt> parameter is matched against each contained * {@link Property#getName()}, those that are equal are returned. * </p> * * @param name * The name of the properties to return. * * @return The collection of properties which match the specified name, or * an empty collection if no such properties match. */ Collection<Property> getProperties(Name name); /** * Returns single property of the complex attribute which matches the * specified name. * <p> * Note: This method is a convenience and care should be taken when calling * it if more then a single property matches <tt>name</tt>. In such a * case the first encountered property in which {@link Property#getName()} * is equal to <tt>name</tt> is returned, and no order is guaranteed. * </p> * <p> * This method is a safe convenience for: * * <code>getProperties(name).iterator().next()</code>. * * In the event that no property matches the specified name * <code>null</code> is returned. * </p> * * @param name * The name of the property to return. * * @return The property matching the specified name, or <code>null</code>. */ Property getProperty(Name name); /** * Returns a subset of the properties of the complex attribute which match * the specified name. * <p> * This method is a convenience for {@link #getProperties(Name)} in which * {@link Name#getNamespaceURI()} is <code>null</code>. * </p> * <p> * Note: Special care should be taken when using this method in the case * that two properties with the same local name but different namespace uri * exist. For this reason using {@link #getProperties(Name)} is safer. * </p> * * @param name * The local name of the properties to return. * * @return The collection of properties which match the specified name, or * an empty collection if no such properties match. * * @see #getProperties(Name) */ Collection<Property> getProperties(String name); /** * Complete collection of properties. * <p> * This method is a convenience method for calling (Collection<Property>) getValue(). * </p> * @return The complete collection of properties. */ Collection<Property> getProperties(); /** * Returns single property of the complex attribute which matches the * specified name. * <p> * This method is a convenience for {@link #getProperty(Name)} in which * {@link Name#getNamespaceURI()} is <code>null</code>. * </p> * <p> * Note: This method is a convenience and care should be taken when calling * it if more then a single property matches <tt>name</tt>. In such a * case the first encountered property in which {@link Property#getName()} * is matches <tt>name</tt> is returned, and no order is guaranteed. * </p> * <p> * Note: Special care should be taken when using this method in the case * that two properties with the same local name but different namespace uri * exist. For this reason using {@link #getProperties(Name)} is safer. * </p> * * @param name * The local name of the property to return. * * @return The property matching the specified name, or <code>null</code>. */ Property getProperty(String name); /** * Check the properties against the constraints provided by their AttributeDescriptors. * <p> * Please note this method checks minOccurs and maxOccurs information; and calls each Attribute.validate * on each entry in turn (in order to check isNillable, binding and restrictions). * @throws IllegalAttributeException If any attribute fails validation */ void validate() throws IllegalAttributeException; }