/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.xml;
import java.awt.List;
import javax.xml.namespace.QName;
/**
* A specialized handler for a specific type in an xml schema.
* <p>
* Bindings have the following responsibilities.
* <ul>
* <li>Parsing components from an instance document (elements and attributes)
* into model objects</li>
* <li>Encoding model objects as xml components</li>
* <li>Sorting themselves in case multiple bindings target the same type</li>
* </ul>
* </p>
*
* <p>
* <h3>Type Binding</h3>
*
* Binding objects correspond to xml schema types. A binding declares
* it target type by advertising the qualified name of the type it binds to.
* For instance, the following strategy binds itself to type <b>xsd:string</b>.
* </p>
*
* <pre>
* <code>
* class XSDStringStrategy {
*
* QName getTarget() {
* return new QName("http://www.w3.org/2001/XMLSchema","string");
* }
*
* ...
* </code>
* </pre>
*
* <p>
* The upshot is that whenever an element or attribute is encountered in an
* instance document that is of type xsd:string, this binding will be used to
* turn the string into an object representation.
* </p>
*
* <p>
* And on the other side of coin, when an instanceof String is encountered when
* serializing an object model, the binding will be used to encode the string as
* xml.
* </p>
*
* <p>
* <h3>Inheritance</h3>
*
* XML Schema supports Inheritance. As a concrete example, consider the simple
* xml schema simple types <b>decimal</b> and <b>integer</b>.
* </p>
*
* <pre>
* <code>
* <xs:simpleType name="decimal" id="decimal">
* <xs:annotation>
* <xs:appinfo>
* <hfp:hasFacet name="totalDigits"/>
* <hfp:hasFacet name="fractionDigits"/>
* <hfp:hasFacet name="pattern"/>
* <hfp:hasFacet name="whiteSpace"/>
* <hfp:hasFacet name="enumeration"/>
* <hfp:hasFacet name="maxInclusive"/>
* <hfp:hasFacet name="maxExclusive"/>
* <hfp:hasFacet name="minInclusive"/>
* <hfp:hasFacet name="minExclusive"/>
* <hfp:hasProperty name="ordered" value="total"/>
* <hfp:hasProperty name="bounded" value="false"/>
* <hfp:hasProperty name="cardinality" value="countably infinite"/>
* <hfp:hasProperty name="numeric" value="true"/>
* </xs:appinfo>
* <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#decimal"/>
* </xs:annotation>
* <xs:restriction base="xs:anySimpleType">
* <xs:whiteSpace fixed="true" value="collapse" id="decimal.whiteSpace"/>
* </xs:restriction>
* </xs:simpleType>
*
* <xs:simpleType name="integer" id="integer">
* <xs:annotation>
* <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#integer"/>
* </xs:annotation>
* <xs:restriction base="xs:decimal">
* <xs:fractionDigits fixed="true" value="0" id="integer.fractionDigits"/>
* <xs:pattern value="[\-+]?[0-9]+"/>
* </xs:restriction>
* </xs:simpleType>
* </code>
* </pre>
*
* <p>
* The above types define an inheiretance hierarcy. To model this relationship
* among the corresponding binding objects, an <B>execution mode</B> must be
* declared by each binding. The execution mode specifies wether a binding
* should be executed before, after, or totally override the binding for a
* direct parent.
* </p>
*
* <pre>
* <code>
* class DecimalBinding implements Binding {
* ...
*
* int getExecutionMode() {
* return OVERRIDE;
* }
* ...
* }
*
* class IntegerBinding implemnts Binding {
* ...
* int getExecutionMode() {
* return AFTER;
* }
* ...
* }
* </code>
* </pre>
*
* <p>
* In the above example, the decimal bidning declares its execution mode to
* be override. This means that no bindings for any of the base types of
* decimal will be executed. The integer binding declares its execution mode
* as AFTER. This means that the integer binding will be executed after the
* decimal strategy.
* </p>
*
* <p>
* <h3>Context</h3>
*
* Bindings are executed within a particular context or container. A binding
* can use its context to obtain objects that it depends on to perform a parse
* or encoding. A binding can declare a dependency by simply adding it to its
* constructor.
*
* This is known as
* <a href=http://www.martinfowler.com/articles/injection.html#ConstructorInjectionWithPicocontainer>
* Constructor Injection</a>.
*
* When the binding is created it is injected with all dependencies. The context is
* responsible for satisfying the dependencies of the binding. As an example
* consider the following complex type defintion.
*
* <pre>
* <code>
* <xsd:complexType name="collection">
* <xsd:sequence>
* <xsd:element name="item" type="xsd:any" minOccurs="0" maxOccurs="unbounded"/>
* </xsd:sequence>
* </xsd:complexType>
* </code>
* </pre>
*
* The associated binding must turn instances of this type into objects of
* type {@link java.util.Collection}. However, the question remains what
* concrete subclass of Collection to use. And perhaps we need this type to
* vary in different situations. The solution is to take the decision out of
* the hands of this binding, and into the hands of someone else. To acheive
* this the collection binding adds a dependency of type Collection.
*
* <pre>
* <code>
*class CollectionStrategy implements ComplexBinding {
*
* Collection collection;
* <b>
* CollectionStrategy(Collection collection) {
* this.collection = collection;
* }
* </b>
* QName getTarget() {
* return new QName("http://org/geotools/","collection");
* }
*
* int getExecutionMode() {
* return OVERRIDE;
* }
*
* <b>
* Object parse(Element instance, Node[] children, Node[] atts, Object value)
* throws Exception {
*
* for (int i = 0; i < children.length; i++) {
* collection.add(children[i].getValue());
* }
*
* return collection;
* }
* </b>
*}
* </code>
* </pre>
* </p>
*
* <h3>Conflict resolution</h3>
* In some cases multiple bindings are targetting the same java class. This happens, for example,
* in GML3 where {@link MultiPolygon} is associated to two different elements, gml:MultiPolygon
* and gml:MultiSurface (the former being deprecated and kept for backwards compatibility).
*
* <p>In such occasions, binding implementations must implement the {@link Comparable} interface,
* in case of doubt the bindings associated to a specific class will be sorted and the first
* element in the resulting {@link List} will be used.
*
*
* @author Justin Deoliveira,Refractions Research Inc.,jdeolive@refractions.net
*
*
* @source $URL$
*/
public interface Binding {
/**
* Specifies that a binding should be executed after its direct parent
*/
static final int AFTER = 0;
/**
* Specifes that a binding should be executed before its direct parent.d
*/
static final int BEFORE = 1;
/**
* Specifies that a binding should totally override the execution of its
* direct parent.
*/
static final int OVERRIDE = 2;
/**
* @return The qualified name of the target for the binding.
*/
QName getTarget();
/**
* @return The java type this binding maps to.
*/
Class getType();
/**
* @return The execution mode of the binding, one of the constants AFTER,
* BEFORE, or OVERRIDE.
*
* @see Binding#AFTER
* @see Binding#BEFORE
* @see Binding#OVERRIDE
*/
int getExecutionMode();
}