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.type;
033    
034    import java.util.Collection;
035    
036    import org.opengis.feature.ComplexAttribute;
037    import org.opengis.feature.Property;
038    
039    /**
040     * The type of a complex attribute.
041     * <br/>
042     * <p>
043     * Similar to how a complex attribute is composed of other properties, a complex
044     * type is composed of property descriptors. A complex type is very much like a
045     * complex type from xml schema. Consider the following xml schema complex type:
046     * <pre>
047     * &lt;element name="myComplexElement" type="myComplexType"/>
048     * &lt;complexType name="myComplexType">
049     *   &lt;sequence>
050     *     &lt;element name="foo" type="xs:string" minOccurs="2" maxOccurs="4">
051     *     &lt;element name="bar" type="xs:int" nillable=false/>
052     *   &lt;/sequence>
053     * &lt;/complexType>
054     * </pre>
055     *
056     * The corresponding complex type that would emerge would be composed as follows:
057     * <pre>
058     *   ComplexType complexType = ...;
059     *   complexType.getProperties().size() == 2;
060     *
061     *   //the foo property descriptor
062     *   PropertyDescriptor foo = complexType.getProperty( "foo" );
063     *   foo.getName().getLocalPart() == "foo";
064     *   foo.getMinOccurs() == 2;
065     *   foo.getMaxOccurs() == 4;
066     *   foo.isNillable() == true;
067     *   foo.getType().getName().getLocalPart() == "string";
068     *
069     *   //the bar property descriptor
070     *   PropertyDescriptor bar = complexType.getProperty( "bar" );
071     *   foo.getName().getLocalPart() == "bar";
072     *   foo.getMinOccurs() == 1;
073     *   foo.getMaxOccurs() == 1;
074     *   foo.isNillable() == false;
075     *   foo.getType().getName().getLocalPart() == "int";
076     * </pre>
077     * </p>
078     * Now consider the following xml instance document:
079     * <pre>
080     * &lt;myComplexElement>
081     *   &lt;foo>one&lt;/foo>
082     *   &lt;foo>two&lt;/foo>
083     *   &lt;foo>three&lt;/foo>
084     *   &lt;bar>1&lt;/bar>
085     * &lt;/myComplexElement>
086     * </pre>
087     * <br>
088     * The resulting complex attribute would be composed as follows:
089     * <pre>
090     *   ComplexAttribute attribute = ...;
091     *   attribute.getName().getLocalPart() == "myComplexElement";
092     *   attribute.getType().getName().getLocalPart() == "myComplexType";
093     *
094     *   Collection foo = attribute.getProperties( "foo" );
095     *   foo.size() == 3;
096     *   foo.get(0).getValue() == "one";
097     *   foo.get(1).getValue() == "two";
098     *   foo.get(2).getValue() == "three";
099     *
100     *   Property bar = attribute.getProperty( "bar" );
101     *   bar.getValue() == 1;
102     * </pre>
103     * </p>
104     * @see ComplexAttribute
105     *
106     * @author Jody Garnett (Refractions Research)
107     * @author Justin Deoliveira (The Open Planning Project)
108     */
109    public interface ComplexType extends AttributeType {
110        /**
111         * Override and type narrow to Collection<Property>.class.
112         */
113        Class<Collection<Property>> getBinding();
114    
115        /**
116         * The property descriptor which compose the complex type.
117         * <p>
118         * A complex type can be composed of attributes and associations which means
119         * this collection returns instances of {@link AttributeDescriptor} and
120         * {@link AssociationDescriptor}.
121         * </p>
122         *
123         * @return Collection of descriptors representing the composition of the
124         * complex type.
125         */
126        Collection<PropertyDescriptor> getDescriptors();
127    
128        /**
129         * Describe a single property by name.
130         * <p>
131         * This method returns <code>null</code> if no such property is found.
132         * </p>
133         * @param name The name of the property to get.
134         *
135         * @return The property matching the specified name, or <code>null</code>.
136         */
137        PropertyDescriptor getDescriptor( Name name );
138    
139        /**
140         * Describe a single property by unqualified name.
141         * <p>
142         * Note: Special care should be taken when using this method in the case
143         * that two properties with the same local name but different namespace uri
144         * exist. For this reason using {@link #getDescriptor(Name)} is safer.
145         * </p>
146         * <p>
147         * This method returns <code>null</code> if no such property is found.
148         * </p>
149         * @param name The name of the property to get.
150         *
151         * @return The property matching the specified name, or <code>null</code>.
152         */
153        PropertyDescriptor getDescriptor( String name );
154    
155        /**
156         * Indicates ability of XPath to notice this attribute.
157         * <p>
158         * This facility is used to "hide" an attribute from XPath searches, while the compelx contents will still
159         * be navigated no additional nesting will be considered. It will be as if the content were "folded" inline
160         * resulting in a flatter nesting structure.
161         * </p>
162         * <p>
163         * Construct described using Java Interfaces:<pre><code>
164         * interface TestSample {
165         *     String name;
166         *     List<Measurement> measurement;
167         * }
168         * interface Measurement {
169         *     long timestamp;
170         *     Point point;
171         *     long reading;
172         * }
173         * </code></pre>
174         * The above is can hold the following information:<pre><code>
175         * [ name="survey1",
176         *   measurements=(
177         *       [timestamp=3,point=(2,3), reading=4200],
178         *       [timestamp=9,point=(2,4), reading=445600],
179         *   )
180         * ]
181         * </code></pre>
182         * Out of the box this is represented to XPath as the following tree:<pre><code>
183         * root/name: survey1
184         * root/measurement[0]/timestamp:3
185         * root/measurement[0]/point: (2,3)
186         * root/measurement[0]/reading: 4200
187         * root/measurement[1]/timestamp:9
188         * root/measurement[2]/point: (2,4)
189         * root/measurement[3]/reading: 445600
190         * </code></pre>
191         *
192         * By inlining Measurement we can achive the following:<pre><code>
193         * root/name: survey1
194         * root/timestamp[0]:3
195         * root/point[0]: (2,3)
196         * root/reading[0]: 4200
197         * root/timestamp[1]:9
198         * root/point[1]: (2,4)
199         * root/reading[1] 445600
200         * </code></pre>
201         *
202         * @return true if  attribute is to be considered transparent by XPath queries
203         */
204        boolean isInline();
205    
206        /**
207         * Describes allowable content, indicating containment.
208         * <p>
209         * A collection of AttributeDescriptors (name and AttributeType) is used.
210         * We make no restrictions as to attribute order. All attributes are considered
211         * accessable by name (and order is thus insignificant).
212         * </p>
213         * <p>
214         * If you are modling a typing system where attribute order is relevant
215         * you may make use of a List. Similarly if duplicate attributes are
216         * disallowed you may make use of a Set.
217         * </p>
218         * <p>
219         * This method follows JavaBeans naming convention indicating this is part of
220         * our data model.
221         * </p>
222         */
223        //Collection<AttributeDescriptor> attributes();
224    
225        /**
226         * Allowable associations, indicating non containment relationships.
227         */
228        //Collection<AssociationDescriptor> associations();
229    
230    }