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.List;
035 import java.util.Map;
036
037 import org.opengis.feature.Property;
038 import org.opengis.filter.Filter;
039 import org.opengis.util.InternationalString;
040
041 /**
042 * The type of a Property.
043 * <p>
044 * A property type defines information about the value of a property. This
045 * includes:
046 * <ul>
047 * <li>java class of the value of the property ((also known as the property "binding")
048 * <li>any restrictions on the value of the property
049 * <li>a description of the property
050 * <li>if the type is abstract or not
051 * </ul>
052 * </p>
053 * <br/>
054 * <p>
055 * <h3>Binding</h3>
056 * The {@link #getBinding()} method returns the java class of which the value
057 * of the property is an instance of.
058 * <pre>
059 * Property property = ...;
060 * property.getType().getBinding().isAssignableFrom(property.getValue().getClass());
061 * </pre>
062 * </p>
063 * <p>
064 * <h3>Restrictions</h3>
065 * The {@link #getRestrictions()} method returns a set of {@link Filter} objects
066 * which define additional restrictions on the value of the property.
067 * <pre>
068 * Property property = ...;
069 * for ( Filter restriction : property.getType().getRestrictions() ) {
070 * restriction.evaluate( property ) == true;
071 * }
072 * </pre>
073 * </p>
074 * <p>
075 * <h3>Inheritance</h3>
076 * A property type may extend from another property type. When this occurs any
077 * restrictions defined by the parent type are inherited by the child type. The
078 * binding declared by the super type may or may not be a super class of the
079 * binding declared by the child type.
080 * </p>
081 * <p>
082 * <h3>Abstract Types</h3>
083 * A property type may be abstract similar to how a java class can be abstract.
084 * Such property types are usually not referenced directly by a descriptor, but
085 * usually are the parent type of a non-abstract property type.
086 * </p>
087 * <p>
088 * <h3>Example</h3>
089 * Property, PropertyDescriptor, and PropertyType are very similar to concepts
090 * encountered in xml schema. Consider the following xml schema:
091 * <pre>
092 * < simpleType name="number"/>
093 *
094 * < simpleType name="integer"/>
095 *
096 * < complexType name="myComplexType"/>
097 * <element name="foo" type="integer"/>
098 * </complexType>
099 * </pre>
100 * <br>
101 * In the above, "number", "integer", and "myComplexType" all map to PropertyType.
102 * While "foo" maps to a PropertyDescriptor. Consider a complex attribute which is
103 * of type "myComplexType:
104 * <pre>
105 * ComplexAttribute complexAttribute = ...;
106 * ComplexType complexType = complexAttribute.getType();
107 *
108 * complexType.getName().getLocalPart() == "myComplexType";
109 *
110 * //the property descriptor
111 * PropertyDescriptor propertyDescriptor = complexType.getProperty( "foo" );
112 * propertyDescriptor.getName().getLocalPart() == "foo";
113 *
114 * //the property type
115 * PropertyType propertyType = propertyDescriptor.getType();
116 * propertyType.getName().getLocalPart() == "integer";
117 * propertyType.getBinding() == Integer.class;
118 * propertyType.getSuper().getName().getLocalPart() == "number";
119 * propertyType.getSuper().getBinding() == Number.class;
120 *
121 * //the property
122 * Property property = complexAttribute.getProperty( "foo" );
123 * property.getDescriptor() == propertyDescriptor;
124 * property.getType() == propertyType;
125 * property.getName().getLocalPart() == "foo";
126 * property.getValue() instanceof Integer;
127 * </pre>
128 * </p>
129
130 * @author Jody Garnett, Refractions Research, Inc.
131 * @author Justin Deoliveira, The Open Planning Project
132 */
133 public interface PropertyType {
134 /**
135 * The name of the property type.
136 * <p>
137 * Note that this is not the same name as {@link Property#getName()}, which
138 * is the name of the instance of the type, not the type itself.
139 * </p>
140 * <p>
141 * The returned name is a qualified name made up of two parts. The first
142 * a namespace uri ({@link Name#getNamespaceURI()}, and the second a local
143 * part ({@link Name#getLocalPart()}.
144 * </p>
145 * <p>
146 * This value is never <code>null</code>.
147 * </p>
148 * @return The name of the property type.
149 */
150 Name getName();
151
152 /**
153 * The java class that values of properties of the property type are bound
154 * to.
155 * <p>
156 * This value is never <code>null</code>.
157 * </p>
158 * @return The binding of the property type.
159 */
160 Class<?> getBinding();
161
162 /**
163 * The parent type of the property type.
164 * <p>
165 * This method returns <code>null</code> if no super type is defined.
166 * </p>
167 * <p>
168 * The super type may contain additional restrictions to be considered against
169 * properties of the the property type.
170 * </p>
171 *
172 * @return The parent or super type, or <code>null</code>.
173 */
174 PropertyType getSuper();
175
176 /**
177 * Flag indicating if the type is abstract or not.
178 *
179 * @return <code>true</code> if the type is abstract, otherwise <code>false</code>.
180 */
181 boolean isAbstract();
182
183 /**
184 * List of restrictions used define valid values for properties of this
185 * property type.
186 * <p>
187 * Each restriction is a {@link Filter} object in which the property is
188 * passed through. If {@link Filter#evaluate(Object)} returns <code>true</code>
189 * the restriction is met. If <code>false</code> is returned then the
190 * restriction has not been met and the property should be considered invalid.
191 * Remember to check getSuper().getRestrictions() as well.
192 * <p>
193 * This method returns an empty set in the case of no restrictions and should
194 * not return <code>null</code>.
195 * </p>
196 * @return List<Restriction> used to validate allowable values.
197 */
198 List<Filter> getRestrictions();
199
200 /**
201 * Human readable description of this property type.
202 *
203 * @return Human readable description of this property type.
204 */
205 InternationalString getDescription();
206
207 /**
208 * A map of "user data" which enables applications to store "application-specific"
209 * information against a property type.
210 * <p>
211 * As an example, consider an application that builds a PropertyType from an
212 * xml schema. A useful bit of information to attach to the PropertyType is
213 * the original schema itself, in whatever construct it might be stored in:
214 * <pre>
215 * <code>
216 * XSDComplexTypeDefinition complexTypeDef = ...;
217 * PropertyType type = buildPropertyType( complexTypeDef );
218 *
219 * type.getUserData().put( XSDComplexTypeDefintion.class, complexTypeDef );
220 * </code>
221 * </pre>
222 * </p>
223 *
224 * @return A map of user data.
225 */
226 Map<Object,Object> getUserData();
227
228 /**
229 * Equality based on property {@link #getName()}.
230 * </p>
231 *
232 * @return <code>true</code> if other is a PropertyType with the same name
233 */
234 @Override
235 boolean equals(Object other);
236
237 /**
238 * Hash code override based on {@link #getName()}.
239 *
240 * @return getName().hashCode()
241 */
242 @Override
243 int hashCode();
244 }