<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:smooks="http://www.milyn.org/xsd/smooks-1.1.xsd"
           xmlns:smooks-javabean="http://www.milyn.org/xsd/smooks/javabean-1.3.xsd"
           targetNamespace="http://www.milyn.org/xsd/smooks/javabean-1.3.xsd"
           elementFormDefault="qualified">

    <xs:import namespace="http://www.milyn.org/xsd/smooks-1.1.xsd"/>

    <xs:annotation>
        <xs:documentation xml:lang="en">Smooks Java Binding Configuration</xs:documentation>
    </xs:annotation>

    <xs:element name="bean" substitutionGroup="smooks:abstract-resource-config" type="smooks-javabean:BeanVisitor">
    	<xs:annotation>
			<xs:documentation xml:lang="en">
				Javabean Bindings Configuration.
				<h3>Bean Instance Creation</h3>
				Instances of the class specified in the
				"class" attribute are created and bound into
				the bean context under the ID specified by
				the "beanId" attribute. The bean instance is
				created (and bound) when the element event
				specified in the "createOnElement" attribute
				is encountered in the Source data event
				stream (see also "createOnElementNS").
				<h3>Bean Property/Member Population</h3>
				Bean property/member population is
				controlled by the binding sub-elements
				nested inside this element. Use your IDE to
				discover these elements.
			</xs:documentation>
		</xs:annotation>
    </xs:element>

    <xs:element name="result" type="smooks-javabean:ResultVisitor" substitutionGroup="smooks:abstract-resource-config">
		<xs:annotation>
			<xs:documentation>Removes all beans from the bean context at the end of the filter process except for the beans that are defined in the 'retainBeans' attribute.</xs:documentation>
		</xs:annotation>
    </xs:element>

    <xs:element name="value" type="smooks-javabean:ValueVisitor" substitutionGroup="smooks:abstract-resource-config">
		<xs:annotation>
			<xs:documentation></xs:documentation>
		</xs:annotation>
    </xs:element>

	<xs:complexType name="BeanVisitor">
   		<xs:complexContent>
   			<xs:extension base="smooks:element-visitor">
   				<xs:sequence>
   					<xs:choice minOccurs="0" maxOccurs="unbounded">
   						<xs:element name="value" type="smooks-javabean:ValueBinding">
   							<xs:annotation>
						      <xs:documentation xml:lang="en">
						          Basic "value" based binding configuration.
						          <p/>
						          This binding type is used to bind data from the source message event stream.
						      </xs:documentation>
					     	</xs:annotation>
   						</xs:element>
   						<xs:element name="wiring" type="smooks-javabean:WireBinding">
   							<xs:annotation>
								<xs:documentation xml:lang="en">
								    Basic "value" based binding configuration.
								    <p/>
								    This binding type is used to bind data from the source message event stream.
								</xs:documentation>
					     	</xs:annotation>
   						</xs:element>
   						<xs:element name="expression" type="smooks-javabean:ExpressionBinding">
							<xs:annotation>
								<xs:documentation xml:lang="en">Expression based Configuration</xs:documentation>
							</xs:annotation>
   						</xs:element>
   					</xs:choice>
   				</xs:sequence>
   				<xs:attribute name="beanId" type="xs:string"
   					use="required">
   					<xs:annotation>
   						<xs:documentation xml:lang="en">
   							The ID under which the created bean is
   							to be bound in the bean context.
   						</xs:documentation>
   					</xs:annotation>
   				</xs:attribute>
   				<xs:attribute name="class" type="xs:string" use="required">
   					<xs:annotation>
   						<xs:documentation xml:lang="en">
   							The fully qualified bean Class name.
   						</xs:documentation>
   					</xs:annotation>
   				</xs:attribute>
                   <xs:attribute name="factory" type="xs:string">
                   	<xs:annotation>
                   		<xs:documentation xml:lang="en">
                   			The definition of a factory.
                   		</xs:documentation>
                   	</xs:annotation>
   				</xs:attribute>
                <xs:attribute name="createOnElement" type="xs:string">
   					<xs:annotation>
   						<xs:documentation xml:lang="en">
   							The Source data event stream element
   							event to use to control the timing of
   							the creating.
   							<p />
   							Think of this as the element path (in
   							the Source data) used to control
   							creation of the bean instance(s).
   							<h3>Example</h3>
   							If this attribute value is set to
   							"order/orderItem", an instance of the
   							class (specified in the "class"
   							attribute) will be created when an
   							element event for the element
   							"orderItem" (with a parent element of
   							"order") is encountered in the Source
   							data event stream. The created bean
   							instance will then be bound into the
   							bean context under the specified
   							"beanId".
   							<p />
   							If the createOnElement is not set then
   							no bean will be created. The existing
   							bean in the bean context will be used to
   							do the value binding, expression binding
   							and the object wiring on.
   						</xs:documentation>
   					</xs:annotation>
   				</xs:attribute>
   				<xs:attribute name="extendLifecycle" type="xs:boolean">
   					<xs:annotation>
   						<xs:documentation xml:lang="en">
   							Defines if this bindings bean wiring may
   							still wire beans after the element is
   							processed. This enables flat XML
   							support. The default value can be set
   							with the global-parameter
   							'bean-population.default.extend.lifecycle'.
   							Default the value is 'false'.
   						</xs:documentation>
   					</xs:annotation>
   				</xs:attribute>
   			</xs:extension>
   		</xs:complexContent>
   	</xs:complexType>

   	<xs:complexType name="ValueVisitor">
   		<xs:complexContent>
   			<xs:extension base="smooks:element-visitor">
				<xs:group ref="smooks-javabean:ValueElements" />
				<xs:attribute name="beanId" type="xs:string" use="required">
   					<xs:annotation>
   						<xs:documentation xml:lang="en">
   							The ID under which the created bean is
   							to be bound in the bean context.
   						</xs:documentation>
   					</xs:annotation>
   				</xs:attribute>
				<xs:attributeGroup ref="smooks-javabean:ValueAttributes" />
   			</xs:extension>
   		</xs:complexContent>
   	</xs:complexType>

    <xs:complexType name="ValueBinding">
        <xs:group ref="smooks-javabean:ValueElements" />
		<xs:attributeGroup ref="smooks-javabean:ValueAttributes" />
		<xs:attribute name="property" type="xs:string">
            <xs:annotation>
                <xs:documentation xml:lang="en">The class property to which the decoded data is to be bound.
                    <p/>
                    The property attribute does not need to be specified when the "class" type on the parent "bindings" element
                    is a List/Array or Map.  In the case of a List/Array, the bean is simply added.  In the case of Map, the
                    element name (from the element specified in the "data" attribute) is used.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="setterMethod" type="xs:string">
        	<xs:annotation>
    			<xs:documentation xml:lang="en">
    				The class method which is called to bind the data
    				to the object. Not needed when binding to a Collection.
    				<p/>
                    The setterMethod attribute does not need to be specified when the "class" type on the parent "bindings" element
                    is a List/Array or Map.  In the case of a List/Array, the bean is simply added.  In the case of Map, the
                    element name (from the element specified in the "data" attribute) is used.
    			</xs:documentation>
    		</xs:annotation>
        </xs:attribute>
    </xs:complexType>


	<xs:complexType name="WireBinding">
		<xs:annotation>
			<xs:documentation xml:lang="en">
				Wiring based binding configuration.
				<p />
				This binding type is used to "wire" beans together.
			</xs:documentation>
		</xs:annotation>
		<xs:attribute name="property" type="xs:string">
			<xs:annotation>
				<xs:documentation xml:lang="en">
					The class property to which the bean (specified
					by "beanIdRef") is to be bound.
					<p />
					The property attribute does not need to be
					specified when the "class" type on the parent
					"bindings" element is a List/Array or Map. In
					the case of a List/Array, the bean is simply
					added. In the case of Map, the element name
					(from the element specified in the "data"
					attribute) is used.
				</xs:documentation>
			</xs:annotation>
		</xs:attribute>
	    <xs:attribute name="setterMethod" type="xs:string">
	    	<xs:annotation>
				<xs:documentation xml:lang="en">
					The class method which is called to bind the data
					to the object. Not needed when binding to a Collection.
					<p/>
	                The setterMethod attribute does not need to be specified when the "class" type on the parent "bindings" element
	                is a List/Array or Map.  In the case of a List/Array, the bean is simply added.  In the case of Map, the
	                element name (from the element specified in the "data" attribute) is used.
				</xs:documentation>
			</xs:annotation>
	    </xs:attribute>
	    <xs:attribute name="beanIdRef" type="xs:string"
			use="required">
			<xs:annotation>
				<xs:documentation xml:lang="en">
					The beanId of the bean to be wired into the
					specified bean "property" (or List).
				</xs:documentation>
			</xs:annotation>
		</xs:attribute>
		<xs:attribute name="wireOnElement" type="xs:string">
			<xs:annotation>
				<xs:documentation xml:lang="en">
					The Source data event stream element event to
					use to control when the bean needs to be wired
					or when the cartridge needs to register a
					listener for the bean to be wired.
				</xs:documentation>
			</xs:annotation>
		</xs:attribute>
	</xs:complexType>

    <xs:complexType name="ExpressionBinding">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="property" type="xs:string">
                    <xs:annotation>
                        <xs:documentation xml:lang="en">The class property to which the expression evaluation result
                            is to be bound. Not needed when binding to a Collection.
                            <p/>
                            The property attribute does not need to be specified when the "class" type on the parent "bindings" element
                            is a List/Array or Map.  In the case of a List/Array, the bean is simply added.  In the case of Map, the
                            element name (from the element specified in the "data" attribute) is used.
                        </xs:documentation>
                    </xs:annotation>
            	</xs:attribute>
				<xs:attribute name="setterMethod" type="xs:string">
		          	<xs:annotation>
		      			<xs:documentation xml:lang="en">
		      				The class method which is called to bind the data
		      				to the object. Not needed when binding to a Collection.
		      				<p/>
		                            The setterMethod attribute does not need to be specified when the "class" type on the parent "bindings" element
		                            is a List/Array or Map.  In the case of a List/Array, the bean is simply added.  In the case of Map, the
		                            element name (from the element specified in the "data" attribute) is used.
		      			</xs:documentation>
		      		</xs:annotation>
		        </xs:attribute>
                <xs:attribute name="execOnElement" type="xs:string">
                    <xs:annotation>
                        <xs:documentation xml:lang="en">
                            The Source data event stream element event to use to control the execution of the expression
                            and binding of the result.
                            <p/>
                            Think of this as the element path (in the Source data) used to control execution of the
                            expression.
                            <h3>Example</h3>
                            If this attribute value is set to "order/orderItem", the expression will be executed (and
                            the result bound to the target property) when an "end" element event ("visitAfter")
                            for the element "orderItem" (with a parent element of "order") is encountered in the
                            Source data event stream.
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="initVal" type="xs:string">
                    <xs:annotation>
                        <xs:documentation xml:lang="en">Initial value for the property.</xs:documentation>
                    </xs:annotation>
                </xs:attribute>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

  	<xs:complexType  name="DecodeParam">
        <xs:simpleContent>
             <xs:extension base="xs:string">
                 <xs:attribute name="name" type="xs:string" use="required">
                     <xs:annotation>
                         <xs:documentation xml:lang="en">The name of the parameter.</xs:documentation>
                     </xs:annotation>
                 </xs:attribute>
             </xs:extension>
         </xs:simpleContent>
    </xs:complexType>

	<xs:complexType name="ResultVisitor">
		<xs:complexContent>
			<xs:extension base="smooks:element-visitor">
	            <xs:attribute name="retainBeans" type="xs:string" use="required">
	                <xs:annotation>
	                    <xs:documentation xml:lang="en">Comma separated list of beanIds to be retained in the Bean context.</xs:documentation>
	                </xs:annotation>
	            </xs:attribute>
	        </xs:extension>
	    </xs:complexContent>
	</xs:complexType>

	<xs:group name="ValueElements">
		<xs:sequence>
            <xs:element name="decodeParam" type="smooks-javabean:DecodeParam" minOccurs="0" maxOccurs="unbounded">
				<xs:annotation>
				    <xs:documentation xml:lang="en">
				        Data Decode Parameter.
				        <p/>
				        Some decoders may require parameters in order to complete the decoding process e.g. the
				        <a href="http://milyn.codehaus.org/javadoc/smooks/org/milyn/javabean/decoders/DateDecoder.html">DateDecoder</a>.
				        These parameters can be specified by adding &lt;decodeParam&gt; sub-elements to the &lt;value&gt;
				        binding element. Review the Decoder's Javadoc for details of the custom parameters.
				        <p/>
				        <u>Example:</u>
						<pre>
						&lt;jb:value property="date" data="header/date" decoder="<a href="http://milyn.codehaus.org/javadoc/smooks/org/milyn/javabean/decoders/DateDecoder.html">Date</a>"&gt;
						    &lt;jb:decodeParam name="format"&gt;EEE MMM dd HH:mm:ss z yyyy&lt;/jb:decodeParam&gt;
						    &lt;jb:decodeParam name="locale-language"&gt;en&lt;/jb:decodeParam&gt;
						    &lt;jb:decodeParam name="locale-country"&gt;IE&lt;/jb:decodeParam&gt;
						&lt;/jb:value&gt;
						</pre>
				    </xs:documentation>
				</xs:annotation>
            </xs:element>
        </xs:sequence>
	</xs:group>

	<xs:attributeGroup name="ValueAttributes">
        <xs:attribute name="data" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation xml:lang="en">
                    The data selector for the data value to be bound.
                    <p/>
                    Think of this as the element path (in the Source data) to the data.
                    <h3>Examples</h3>
                    <ul>
                        <li>
                            <b>Element Text Data:</b>
                            "order/orderid"
                        </li>
                        <li>
                            <b>Element Attribute Data:</b>
                            "order/header/@date"
                        </li>
                    </ul>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="decoder" type="xs:string">
            <xs:annotation>
                <xs:documentation xml:lang="en">
                    Data Decoder.
                    <p/>
                    This attribute specifies the
                    <a href="http://milyn.codehaus.org/javadoc/smooks/org/milyn/javabean/DataDecoder.html">DataDecoder</a>
                    to be used to decode the data (see "data" attribute) before setting it on the target bean
                    property(see "property" attribute).
                    <p/>
                    Smooks contains decoders for all of the main data types (Long, Integer etc). In these cases,
                    just specify the decoder as being "Long", "Integer", "Date" etc i.e. no need to specify the fully qualified
                    <a href="http://milyn.codehaus.org/javadoc/smooks/org/milyn/javabean/DataDecoder.html">DataDecoder</a>
                    class name. The fully qualified class name is only required for custom
                    <a href="http://milyn.codehaus.org/javadoc/smooks/org/milyn/javabean/DataDecoder.html">DataDecoder</a>
                    implementations.

                    <h3>Primitive Types</h3>
                    Smooks does not define special decoders for any of the primitive types. To decode a
                    primitive property type, just specify the Object equivalent decoder e.g. specify "Integer" for "int",
                    "Double" for "double" etc etc.

                    <h3>Decode Parameters</h3>
                    Some decoders may require parameters in order to complete the decoding process e.g. the
                    <a href="http://milyn.codehaus.org/javadoc/smooks/org/milyn/javabean/decoders/DateDecoder.html">DateDecoder</a>.
                    These parameters can be specified by adding &lt;decodeParam&gt; sub-elements to the &lt;value&gt;
                    binding element. Review the Decoder's Javadoc for details of the custom parameters.
                    <p/>
                    <u>Example:</u>
					<pre>
					    &lt;jb:value property="date" data="header/date" decoder="<a href="http://milyn.codehaus.org/javadoc/smooks/org/milyn/javabean/decoders/DateDecoder.html">Date</a>"&gt;
					        &lt;jb:decodeParam name="format"&gt;EEE MMM dd HH:mm:ss z yyyy&lt;/jb:decodeParam&gt;
					        &lt;jb:decodeParam name="locale-language"&gt;en&lt;/jb:decodeParam&gt;
					        &lt;jb:decodeParam name="locale-country"&gt;IE&lt;/jb:decodeParam&gt;
					    &lt;/jb:value&gt;
					</pre>

                    <h3>Custom Data Decoding</h3>
                    For custom data decoding, implement the
                    <a href="http://milyn.codehaus.org/javadoc/smooks/org/milyn/javabean/DataDecoder.html">
                        DataDecoder
                    </a>
                    interface and specify the decoder using the fully qualified class name of the new
                    implementation.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="default" type="xs:string">
            <xs:annotation>
                <xs:documentation xml:lang="en">The default data value, where a null/empty data String is returned
                    for the data element.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
	</xs:attributeGroup>
</xs:schema>
