001 /*
002 * GeoAPI - Java interfaces for OGC/ISO standards
003 * http://www.geoapi.org
004 *
005 * Copyright (C) 2006-2012 Open Geospatial Consortium, Inc.
006 * All Rights Reserved. http://www.opengeospatial.org/ogc/legal
007 *
008 * Permission to use, copy, and modify this software and its documentation, with
009 * or without modification, for any purpose and without fee or royalty is hereby
010 * granted, provided that you include the following on ALL copies of the software
011 * and documentation or portions thereof, including modifications, that you make:
012 *
013 * 1. The full text of this NOTICE in a location viewable to users of the
014 * redistributed or derivative work.
015 * 2. Notice of any changes or modifications to the OGC files, including the
016 * date changes were made.
017 *
018 * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE
019 * NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
020 * TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
021 * THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
022 * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
023 *
024 * COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
025 * CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
026 *
027 * The name and trademarks of copyright holders may NOT be used in advertising or
028 * publicity pertaining to the software without specific, written prior permission.
029 * Title to copyright in this software and any associated documentation will at all
030 * times remain with copyright holders.
031 */
032 package org.opengis.feature;
033
034 import java.util.Collection;
035
036 import org.opengis.feature.type.ComplexType;
037 import org.opengis.feature.type.Name;
038 import org.opengis.filter.expression.Expression;
039
040 /**
041 * An instance of {@link ComplexType} which is composed of other properties.
042 * <p>
043 * A complex attribute is a container for other properties (attributes +
044 * associations). The value of a complex attribute is a collection of those
045 * contained properties.
046 * </p>
047 * <br/>
048 * <p>
049 * <h3>Property Access</h3>
050 * The {@link #getValue()} method returns a collection of the properties
051 * contained by the complex attribute.
052 *
053 * <pre>
054 * ComplexAttribute attribute = ...;
055 *
056 * //loop through all the properties
057 * for (Property p : attribute.getValue(); ) {
058 * // do something with the property
059 * }
060 * </pre>
061 *
062 * <br>
063 * Contained properties can also be fetched by name by {@link Name} with the
064 * {@link #getProperties(Name)} and {@link #getProperties(String)} methods.
065 *
066 * <pre>
067 * ComplexAttribute attribute = ...;
068 *
069 * //loop through all the "foo" attributes
070 * for ( Property p : attribute.getProperties( "foo" ) ) {
071 * p.getName().getLocalPart() == "foo";
072 * }
073 * </pre>
074 *
075 * <br>
076 * Often it is known in advance that a single instance of a particular property
077 * exists. When this is the case the {@link #getProperty(Name)} and
078 * {@link #getProperty(String)} methods can be used to get direct access to the
079 * property.
080 *
081 * <pre>
082 * ComplexAttribute attribute = ...;
083 *
084 * //get the single foo attribute
085 * Property foo = attribute.getProperty( "foo" );
086 * </pre>
087 *
088 * </p>
089 * <br>
090 * <p>
091 * <h3>Xpath and Query Language Access</h3>
092 * The above property access methods perform an exact match on property name
093 * against the name passed in. However, often it is necesary to access
094 * properties via a query language such as xpath.
095 * </p>
096 * <br>
097 * <p>
098 * For instance.the expression <code>"//foo"</code> should return all the
099 * properties named "foo". Or the expression <code>"foo/bar"</code> should
100 * return the "bar" property nested inside of the "foo" property. In these
101 * cases, an {@link Expression} must be used:
102 *
103 * <pre>
104 * ComplexAttribute attribute = ...;
105 *
106 * //get the 'foo/bar' property
107 * FilterFactory factory = ...;
108 * PropertyName xpath = factory.property( "foo/bar" );
109 * Property bar = xpath.evaluate( attribute );
110 * </pre>
111 *
112 * </p>
113 *
114 * @author Jody Garnett, Refractions Research
115 * @author Gabriel Roldan, Axios Engineering
116 * @author Justin Deoliveira, The Open Planning Project
117 */
118 public interface ComplexAttribute extends Attribute {
119
120 /**
121 * Override of {@link Attribute#getType()} which type narrows to
122 * {@link ComplexType}.
123 *
124 * @see Attribute#getType()
125 */
126 ComplexType getType();
127
128 /**
129 * Sets the contained properties of the complex attribute.
130 * <p>
131 * The <tt>values</tt> should match the structure defined by
132 * <code>getDescriptor()</code>.
133 * </p>
134 */
135 void setValue(Collection<Property> values);
136
137 /**
138 * Override of {@link Property#getValue()} which returns the collection of
139 * {@link Property} which make up the value of the complex attribute.
140 */
141 Collection<? extends Property> getValue();
142
143 /**
144 * Returns a subset of the properties of the complex attribute which match
145 * the specified name.
146 * <p>
147 * The <tt>name</tt> parameter is matched against each contained
148 * {@link Property#getName()}, those that are equal are returned.
149 * </p>
150 *
151 * @param name
152 * The name of the properties to return.
153 *
154 * @return The collection of properties which match the specified name, or
155 * an empty collection if no such properties match.
156 */
157 Collection<Property> getProperties(Name name);
158
159 /**
160 * Returns single property of the complex attribute which matches the
161 * specified name.
162 * <p>
163 * Note: This method is a convenience and care should be taken when calling
164 * it if more then a single property matches <tt>name</tt>. In such a
165 * case the first encountered property in which {@link Property#getName()}
166 * is equal to <tt>name</tt> is returned, and no order is guaranteed.
167 * </p>
168 * <p>
169 * This method is a safe convenience for:
170 *
171 * <code>getProperties(name).iterator().next()</code>.
172 *
173 * In the event that no property matches the specified name
174 * <code>null</code> is returned.
175 * </p>
176 *
177 * @param name
178 * The name of the property to return.
179 *
180 * @return The property matching the specified name, or <code>null</code>.
181 */
182 Property getProperty(Name name);
183
184 /**
185 * Returns a subset of the properties of the complex attribute which match
186 * the specified name.
187 * <p>
188 * This method is a convenience for {@link #getProperties(Name)} in which
189 * {@link Name#getNamespaceURI()} is <code>null</code>.
190 * </p>
191 * <p>
192 * Note: Special care should be taken when using this method in the case
193 * that two properties with the same local name but different namespace uri
194 * exist. For this reason using {@link #getProperties(Name)} is safer.
195 * </p>
196 *
197 * @param name
198 * The local name of the properties to return.
199 *
200 * @return The collection of properties which match the specified name, or
201 * an empty collection if no such properties match.
202 *
203 * @see #getProperties(Name)
204 */
205 Collection<Property> getProperties(String name);
206
207 /**
208 * Complete collection of properties.
209 * <p>
210 * This method is a convenience method for calling (Collection<Property>) getValue().
211 * </p>
212 * @return The complete collection of properties.
213 */
214 Collection<Property> getProperties();
215
216 /**
217 * Returns single property of the complex attribute which matches the
218 * specified name.
219 * <p>
220 * This method is a convenience for {@link #getProperty(Name)} in which
221 * {@link Name#getNamespaceURI()} is <code>null</code>.
222 * </p>
223 * <p>
224 * Note: This method is a convenience and care should be taken when calling
225 * it if more then a single property matches <tt>name</tt>. In such a
226 * case the first encountered property in which {@link Property#getName()}
227 * is matches <tt>name</tt> is returned, and no order is guaranteed.
228 * </p>
229 * <p>
230 * Note: Special care should be taken when using this method in the case
231 * that two properties with the same local name but different namespace uri
232 * exist. For this reason using {@link #getProperties(Name)} is safer.
233 * </p>
234 *
235 * @param name
236 * The local name of the property to return.
237 *
238 * @return The property matching the specified name, or <code>null</code>.
239 */
240 Property getProperty(String name);
241
242 /**
243 * Check the properties against the constraints provided by their AttributeDescriptors.
244 * <p>
245 * Please note this method checks minOccurs and maxOccurs information; and calls each Attribute.validate
246 * on each entry in turn (in order to check isNillable, binding and restrictions).
247 * @throws IllegalAttributeException If any attribute fails validation
248 */
249 void validate() throws IllegalAttributeException;
250 }