001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.feature;
017:
018: /**
019: * A simple feature is one that does not have any nested attributes, and that
020: * has no multiplicity for each attribute. In non xml speak this means that
021: * the attributes returned are guaranteed to be the Objects you would expect -
022: * not Lists as is the case when Features are non-simple. This is thus a
023: * constraining extension - it essentially allows you to make a few more
024: * assumptions about the nature of the {@link Feature} you are getting back.
025: *
026: * <p>
027: * The notion of a Simple Feature is drawn from the OGC's Simple Features for
028: * SQL specification - where a simple feature represents a single row in a
029: * database table. This extends beyond databases though, to flat files, for
030: * example. A database does not necessarily only return simple features -
031: * indeed by relying on foreign keys much more complex structures can be
032: * created. But at the time of the creation of this class all GeoTools
033: * datastores return Simple Features - they just were not explicitly called
034: * that. Making explicit that they are Simple should hopefully encourage more
035: * complex Features to be returned.
036: * </p>
037: *
038: * <p>
039: * The assumptions one can make with Simple Features are as follows:
040: * </p>
041: *
042: * <ul>
043: * <li>
044: * If {@link #getAttribute(int)} is called then it will always return an
045: * actual object, instead of a List, as is common in the parent Feature
046: * class. That is to say a Simple Feature will never have more than one
047: * attribute in any of its positions, so the interface just assumes that you
048: * want the actual object, instead of a List containing just the object.
049: * </li>
050: * <li>
051: * If {@link #setAttribute(int, Object)} is called then a similar assumption is
052: * made about the object being set - it need be a List, will default to
053: * setting the attribute itself.
054: * </li>
055: * <li>
056: * {@link #getAttribute(String)} and {@link #setAttribute(String, Object)}
057: * implicitly append a [0], as that's the behavior implementors expect - to
058: * name an attribute and get it back.
059: * </li>
060: * </ul>
061: *
062: * <p>
063: * To figure out if a Feature is a SimpleFeature one may call instanceof. For
064: * a number of Features returned from a DataStore it will save much energy if
065: * instanceof is called on the FeatureType, to check if it is a {@link
066: * SimpleFeatureType}. And in the future we should have FeatureCollections
067: * that know their types.
068: * </p>
069: *
070: * @author David Zwiers, Refractions
071: * @author Chris Holmes, TOPP
072: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/feature/SimpleFeature.java $
073: * @version $Id: SimpleFeature.java 20651 2006-07-21 07:51:54Z jgarnett $
074: *
075: * @task REVISIT: I am not sure that I like getAttribute returning the object
076: * straight away. It might be better to have a getFirstAttribute()
077: * method in Feature.java, and move people to get used to calling that,
078: * or else to expect a List (which in a SimpleFeature would always only
079: * contain one Object). This would seem to make the api a bit cleaner
080: * in my mind.
081: * @since 2.1
082: */
083: public interface SimpleFeature extends Feature {
084: /**
085: * Gets a reference to the schema for this feature. This method should
086: * always return DefaultFeatureType Object. This will be explicitly
087: * posible in Java 1.5 (dz)
088: *
089: * @return A reference to this simple feature's schema.
090: */
091: FeatureType getFeatureType();
092:
093: /**
094: * Sets all attributes for this feature, passed as a complex object array.
095: * Note that this array must conform to the internal schema for this
096: * feature, or it will throw an exception. Checking this is, of course,
097: * left to the feature to do internally. Well behaved features should
098: * always fully check the passed attributes against thier schema before
099: * adding them. Since this is a SimpleFeature, the number of attributes
100: * will be exactly the same as the number of attribute types. Attribute
101: * values will be paired with attribute types based on array indexes.
102: *
103: * @param attributes All feature attributes.
104: *
105: * @throws IllegalAttributeException Passed attributes do not match schema.
106: */
107: void setAttributes(Object[] attributes)
108: throws IllegalAttributeException;
109:
110: /**
111: * This is the same as the parent declaration, except that when the
112: * instance is not specified for the xPath, [0] will be added as there is
113: * only ever one Attribute value for an AttributeType
114: *
115: * @param xPath XPath representation of attribute location.
116: *
117: * @return A copy of the requested attribute, null if the requested xpath
118: * is not found, or NULL_ATTRIBUTE.
119: *
120: * @see Feature#getAttribute(String)
121: */
122: Object getAttribute(String xPath);
123:
124: /**
125: * Gets an attribute by the given zero-based index. Unlike the parent
126: * interface, this index is guaranteed to match the index of
127: * AttributeType in the FeatureType.
128: *
129: * @param index The requested index. Must be 0 <= idx <
130: * getNumberOfAttributes().
131: *
132: * @return A copy of the requested attribute, or NULL_ATTRIBUTE.
133: */
134: Object getAttribute(int index);
135:
136: /**
137: * Sets an attribute by the given zero-based index. Unlike the parent
138: * interface, this index is guaranteed to match the index of
139: * AttributeType in the FeatureType.
140: *
141: * @param position The requested index. Must be 0 <= idx <
142: * getNumberOfAttributes()
143: * @param val An object representing the attribute being set
144: *
145: * @throws IllegalAttributeException if the passed in val does not validate
146: * against the AttributeType at that position.
147: * @throws ArrayIndexOutOfBoundsException if an invalid position is given
148: */
149: void setAttribute(int position, Object val)
150: throws IllegalAttributeException,
151: ArrayIndexOutOfBoundsException;
152:
153: /**
154: * Allows this feature to turn itself to a Complex Feature - that is one
155: * with multiplicity. This is used so that clients can choose to deal
156: * with all Complex Features if they would like - always getting lists
157: * back when they ask for objects. Of course when a SimpleFeature turns
158: * itself into a Complex Feature then all its lists will be of length 1.
159: * Am leaving this commented out since it's approved in the api yet -ch
160: */
161:
162: //Feature toComplex();
163: }
|