001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-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.xml;
017:
018: import java.awt.List;
019:
020: import javax.xml.namespace.QName;
021:
022: import com.vividsolutions.jts.geom.MultiPolygon;
023:
024: /**
025: * A specialized handler for a specific type in an xml schema.
026: * <p>
027: * Bindings have the following responsibilities.
028: * <ul>
029: * <li>Parsing components from an instance document (elements and attributes)
030: * into model objects</li>
031: * <li>Encoding model objects as xml components</li>
032: * <li>Sorting themselves in case multiple bindings target the same type</li>
033: * </ul>
034: * </p>
035: *
036: * <p>
037: * <h3>Type Binding</h3>
038: *
039: * Binding objects correspond to xml schema types. A binding declares
040: * it target type by advertising the qualified name of the type it binds to.
041: * For instance, the following strategy binds itself to type <b>xsd:string</b>.
042: * </p>
043: *
044: * <pre>
045: * <code>
046: * class XSDStringStrategy {
047: *
048: * QName getTarget() {
049: * return new QName("http://www.w3.org/2001/XMLSchema","string");
050: * }
051: *
052: * ...
053: * </code>
054: * </pre>
055: *
056: * <p>
057: * The upshot is that whenever an element or attribute is encountered in an
058: * instance document that is of type xsd:string, this binding will be used to
059: * turn the string into an object representation.
060: * </p>
061: *
062: * <p>
063: * And on the other side of coin, when an instanceof String is encountered when
064: * serializing an object model, the binding will be used to encode the string as
065: * xml.
066: * </p>
067: *
068: * <p>
069: * <h3>Inheritance</h3>
070: *
071: * XML Schema supports Inheritance. As a concrete example, consider the simple
072: * xml schema simple types <b>decimal</b> and <b>integer</b>.
073: * </p>
074: *
075: * <pre>
076: * <code>
077: * <xs:simpleType name="decimal" id="decimal">
078: * <xs:annotation>
079: * <xs:appinfo>
080: * <hfp:hasFacet name="totalDigits"/>
081: * <hfp:hasFacet name="fractionDigits"/>
082: * <hfp:hasFacet name="pattern"/>
083: * <hfp:hasFacet name="whiteSpace"/>
084: * <hfp:hasFacet name="enumeration"/>
085: * <hfp:hasFacet name="maxInclusive"/>
086: * <hfp:hasFacet name="maxExclusive"/>
087: * <hfp:hasFacet name="minInclusive"/>
088: * <hfp:hasFacet name="minExclusive"/>
089: * <hfp:hasProperty name="ordered" value="total"/>
090: * <hfp:hasProperty name="bounded" value="false"/>
091: * <hfp:hasProperty name="cardinality" value="countably infinite"/>
092: * <hfp:hasProperty name="numeric" value="true"/>
093: * </xs:appinfo>
094: * <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#decimal"/>
095: * </xs:annotation>
096: * <xs:restriction base="xs:anySimpleType">
097: * <xs:whiteSpace fixed="true" value="collapse" id="decimal.whiteSpace"/>
098: * </xs:restriction>
099: * </xs:simpleType>
100: *
101: * <xs:simpleType name="integer" id="integer">
102: * <xs:annotation>
103: * <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#integer"/>
104: * </xs:annotation>
105: * <xs:restriction base="xs:decimal">
106: * <xs:fractionDigits fixed="true" value="0" id="integer.fractionDigits"/>
107: * <xs:pattern value="[\-+]?[0-9]+"/>
108: * </xs:restriction>
109: * </xs:simpleType>
110: * </code>
111: * </pre>
112: *
113: * <p>
114: * The above types define an inheiretance hierarcy. To model this relationship
115: * among the corresponding binding objects, an <B>execution mode</B> must be
116: * declared by each binding. The execution mode specifies wether a binding
117: * should be executed before, after, or totally override the binding for a
118: * direct parent.
119: * </p>
120: *
121: * <pre>
122: * <code>
123: * class DecimalBinding implements Binding {
124: * ...
125: *
126: * int getExecutionMode() {
127: * return OVERRIDE;
128: * }
129: * ...
130: * }
131: *
132: * class IntegerBinding implemnts Binding {
133: * ...
134: * int getExecutionMode() {
135: * return AFTER;
136: * }
137: * ...
138: * }
139: * </code>
140: * </pre>
141: *
142: * <p>
143: * In the above example, the decimal bidning declares its execution mode to
144: * be override. This means that no bindings for any of the base types of
145: * decimal will be executed. The integer binding declares its execution mode
146: * as AFTER. This means that the integer binding will be executed after the
147: * decimal strategy.
148: * </p>
149: *
150: * <p>
151: * <h3>Context</h3>
152: *
153: * Bindings are executed within a particular context or container. A binding
154: * can use its context to obtain objects that it depends on to perform a parse
155: * or encoding. A binding can declare a dependency by simply adding it to its
156: * constructor.
157: *
158: * This is known as
159: * <a href=http://www.martinfowler.com/articles/injection.html#ConstructorInjectionWithPicocontainer>
160: * Constructor Injection</a>.
161: *
162: * When the binding is created it is injected with all dependencies. The context is
163: * responsible for satisfying the dependencies of the binding. As an example
164: * consider the following complex type defintion.
165: *
166: * <pre>
167: * <code>
168: * <xsd:complexType name="collection">
169: * <xsd:sequence>
170: * <xsd:element name="item" type="xsd:any" minOccurs="0" maxOccurs="unbounded"/>
171: * </xsd:sequence>
172: * </xsd:complexType>
173: * </code>
174: * </pre>
175: *
176: * The associated binding must turn instances of this type into objects of
177: * type {@link java.util.Collection}. However, the question remains what
178: * concrete subclass of Collection to use. And perhaps we need this type to
179: * vary in different situations. The solution is to take the decision out of
180: * the hands of this binding, and into the hands of someone else. To acheive
181: * this the collection binding adds a dependency of type Collection.
182: *
183: * <pre>
184: * <code>
185: *class CollectionStrategy implements ComplexBinding {
186: *
187: * Collection collection;
188: * <b>
189: * CollectionStrategy(Collection collection) {
190: * this.collection = collection;
191: * }
192: * </b>
193: * QName getTarget() {
194: * return new QName("http://org/geotools/","collection");
195: * }
196: *
197: * int getExecutionMode() {
198: * return OVERRIDE;
199: * }
200: *
201: * <b>
202: * Object parse(Element instance, Node[] children, Node[] atts, Object value)
203: * throws Exception {
204: *
205: * for (int i = 0; i < children.length; i++) {
206: * collection.add(children[i].getValue());
207: * }
208: *
209: * return collection;
210: * }
211: * </b>
212: *}
213: * </code>
214: * </pre>
215: * </p>
216: *
217: * <h3>Conflict resolution</h3>
218: * In some cases multiple bindings are targetting the same java class. This happens, for example,
219: * in GML3 where {@link MultiPolygon} is associated to two different elements, gml:MultiPolygon
220: * and gml:MultiSurface (the former being deprecated and kept for backwards compatibility).
221: *
222: * <p>In such occasions, binding implementations must implement the {@link Comparable} interface,
223: * in case of doubt the bindings associated to a specific class will be sorted and the first
224: * element in the resulting {@link List} will be used.
225: *
226: *
227: * @author Justin Deoliveira,Refractions Research Inc.,jdeolive@refractions.net
228: *
229: */
230: public interface Binding {
231: /**
232: * Specifies that a binding should be executed after its direct parent
233: */
234: static final int AFTER = 0;
235:
236: /**
237: * Specifes that a binding should be executed before its direct parent.d
238: */
239: static final int BEFORE = 1;
240:
241: /**
242: * Specifies that a binding should totally override the execution of its
243: * direct parent.
244: */
245: static final int OVERRIDE = 2;
246:
247: /**
248: * @return The qualified name of the target for the binding.
249: */
250: QName getTarget();
251:
252: /**
253: * @return The java type this binding maps to.
254: */
255: Class getType();
256:
257: /**
258: * @return The execution mode of the binding, one of the constants AFTER,
259: * BEFORE, or OVERRIDE.
260: *
261: * @see Binding#AFTER
262: * @see Binding#BEFORE
263: * @see Binding#OVERRIDE
264: */
265: int getExecutionMode();
266: }
|