<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2012,2013 International Business Machines Corp. See the NOTICE 
	file distributed with this work for additional information regarding copyright 
	ownership. Licensed under the Apache License, Version 2.0 (the "License"); 
	you may not use this file except in compliance with the License. You may 
	obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
	Unless required by applicable law or agreed to in writing, software distributed 
	under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
	OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
	the specific language governing permissions and limitations under the License. -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	elementFormDefault="qualified" targetNamespace="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:jsl="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">

	<xs:annotation>
		<xs:documentation>
			Job Specification Language (JSL) specifies a job,
			its steps, and directs their execution.
			JSL also can be referred to as "Job XML".
		</xs:documentation>
	</xs:annotation>

	<xs:simpleType name="artifactRef">
		<xs:annotation>
			<xs:documentation>
				This is a helper type. Though it is not otherwise
				called out by this name
				in the specification, it captures the fact
				that the xs:string value refers
				to a batch artifact, across numerous
				other JSL type definitions.
			</xs:documentation>
		</xs:annotation>
		<xs:restriction base="xs:string" />
	</xs:simpleType>

	<xs:complexType name="Job">
		<xs:annotation>
			<xs:documentation>
				The type of a job definition, whether concrete or
				abstract. This is the type of the root element of any JSL document.
			</xs:documentation>
		</xs:annotation>
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1">
				<xs:annotation>
					<xs:documentation>
						The job-level properties, which are accessible
						via the JobContext.getProperties() API in a batch artifact.
					</xs:documentation>
				</xs:annotation>
			</xs:element>
			<xs:element name="listeners" type="jsl:Listeners"
				minOccurs="0" maxOccurs="1">
				<xs:annotation>
					<xs:documentation>
						Note that "listeners" sequence order in XML does
						not imply order of execution by
						the batch runtime, per the
						specification.
					</xs:documentation>
				</xs:annotation>
			</xs:element>
			<xs:choice minOccurs="0" maxOccurs="unbounded">
				<xs:element name="decision" type="jsl:Decision" />
				<xs:element name="flow" type="jsl:Flow" />
				<xs:element name="split" type="jsl:Split" />
				<xs:element name="step" type="jsl:Step" />
			</xs:choice>
		</xs:sequence>
        <xs:attribute name="version" use="required" type="xs:string" fixed="1.0" />
		<xs:attribute name="id" use="required" type="xs:ID" />
		<xs:attribute name="restartable" use="optional" type="xs:string" />
	</xs:complexType>

	<xs:element name="job" type="jsl:Job">
		<xs:annotation>
			<xs:documentation>
				The definition of an job, whether concrete or
				abstract. This is the
				type of the root element of any JSL document.
			</xs:documentation>
		</xs:annotation>
	</xs:element>

	<xs:complexType name="Listener">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="ref" use="required" type="jsl:artifactRef" />
	</xs:complexType>

	<xs:complexType name="Split">
		<xs:sequence>
			<xs:element name="flow" type="jsl:Flow" minOccurs="0" maxOccurs="unbounded" />
		</xs:sequence>
		<xs:attribute name="id" use="required" type="xs:ID" />
		<xs:attribute name="next" use="optional" type="xs:string" />
	</xs:complexType>

	<xs:complexType name="Flow">
		<xs:sequence>
			<xs:choice minOccurs="0" maxOccurs="unbounded">
				<xs:element name="decision" type="jsl:Decision" />
				<xs:element name="flow" type="jsl:Flow" />
				<xs:element name="split" type="jsl:Split" />
				<xs:element name="step" type="jsl:Step" />
			</xs:choice>
			<xs:group ref="jsl:TransitionElements" minOccurs="0" maxOccurs="unbounded" />
		</xs:sequence>
		<xs:attribute name="id" use="required" type="xs:ID" />
		<xs:attribute name="next" use="optional" type="xs:string" />
	</xs:complexType>

	<xs:group name="TransitionElements">
		<xs:annotation>
			<xs:documentation>
				This grouping provides allows for the reuse of the
				'end', 'fail', 'next', 'stop' element sequences which
				may appear at the end of a 'step', 'flow', 'split' or 'decision'.
				The term 'TransitionElements' does not formally appear in the spec, it is
				a schema convenience.			
			</xs:documentation>
		</xs:annotation>
		<xs:choice>
			<xs:element name="end" type="jsl:End" />
			<xs:element name="fail" type="jsl:Fail" />
			<xs:element name="next" type="jsl:Next" />
			<xs:element name="stop" type="jsl:Stop" />
		</xs:choice>
	</xs:group>

	<xs:complexType name="Decision">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1" />
			<xs:group ref="jsl:TransitionElements" minOccurs="0" maxOccurs="unbounded" />
		</xs:sequence>
		<xs:attribute name="id" use="required" type="xs:ID" />
		<xs:attribute name="ref" use="required" type="jsl:artifactRef" />
	</xs:complexType>

	<xs:attributeGroup name="TerminatingAttributes">
		<xs:attribute name="on" use="required" type="xs:string" />
		<xs:attribute name="exit-status" use="optional" type="xs:string" />
	</xs:attributeGroup>

	<xs:complexType name="Fail">
		<xs:attributeGroup ref="jsl:TerminatingAttributes" />
	</xs:complexType>

	<xs:complexType name="End">
		<xs:attributeGroup ref="jsl:TerminatingAttributes" />
	</xs:complexType>

	<xs:complexType name="Stop">
		<xs:attributeGroup ref="jsl:TerminatingAttributes" />
		<xs:attribute name="restart" use="optional" type="xs:string" />
	</xs:complexType>

	<xs:complexType name="Next">
		<xs:attribute name="on" use="required" type="xs:string" />
		<xs:attribute name="to" use="required" type="xs:string" />
	</xs:complexType>

	<xs:complexType name="CheckpointAlgorithm">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="ref" use="required" type="jsl:artifactRef" />
	</xs:complexType>

	<xs:complexType name="ExceptionClassFilter">
		<xs:sequence>
			<xs:element name="include" minOccurs="0" maxOccurs="unbounded">
				<xs:complexType>
					<xs:sequence />
					<xs:attribute name="class" use="required" type="xs:string" />
				</xs:complexType>
			</xs:element>
			<xs:element name="exclude" minOccurs="0" maxOccurs="unbounded">
				<xs:complexType>
					<xs:sequence />
					<xs:attribute name="class" use="required" type="xs:string" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="Step">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1" />
			<xs:element name="listeners" type="jsl:Listeners"
				minOccurs="0" maxOccurs="1">
				<xs:annotation>
					<xs:documentation>
						Note that "listeners" sequence order in XML does
						not imply order of execution by
						the batch runtime, per the
						specification.
					</xs:documentation>
				</xs:annotation>
			</xs:element>
			<xs:choice minOccurs="0" maxOccurs="1"> 
				<xs:element name="batchlet" type="jsl:Batchlet" />
				<xs:element name="chunk" type="jsl:Chunk" />
			</xs:choice>
			<xs:element name="partition" type="jsl:Partition"
				minOccurs="0" maxOccurs="1" />
			<xs:group ref="jsl:TransitionElements" minOccurs="0" maxOccurs="unbounded" />
		</xs:sequence>
		<xs:attribute name="id" use="required" type="xs:ID" />
		<xs:attribute name="start-limit" use="optional" type="xs:string" />
		<xs:attribute name="allow-start-if-complete" use="optional"
			type="xs:string" />
		<xs:attribute name="next" use="optional" type="xs:string" />
	</xs:complexType>

	<xs:complexType name="Batchlet">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="ref" use="required" type="jsl:artifactRef" />
	</xs:complexType>

	<xs:complexType name="Chunk">
		<xs:sequence>
			<xs:element name="reader" type="jsl:ItemReader" />
			<xs:element name="processor" type="jsl:ItemProcessor"
				minOccurs="0" maxOccurs="1" />
			<xs:element name="writer" type="jsl:ItemWriter" />
			<xs:element name="checkpoint-algorithm" type="jsl:CheckpointAlgorithm"
				minOccurs="0" maxOccurs="1" />
			<xs:element name="skippable-exception-classes" type="jsl:ExceptionClassFilter"
				minOccurs="0" maxOccurs="1" />
			<xs:element name="retryable-exception-classes" type="jsl:ExceptionClassFilter"
				minOccurs="0" maxOccurs="1" />
			<xs:element name="no-rollback-exception-classes" type="jsl:ExceptionClassFilter"
				minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="checkpoint-policy" use="optional"
			type="xs:string">
			<xs:annotation>
				<xs:documentation>
					Specifies the checkpoint policy that governs
					commit behavior for this chunk.
					Valid values are: "item" or
					"custom". The "item" policy means the
					chunk is checkpointed after a
					specified number of items are
					processed. The "custom" policy means
					the chunk is checkpointed
					according to a checkpoint algorithm
					implementation. Specifying
					"custom" requires that the
					checkpoint-algorithm element is also
					specified. It is an optional
					attribute. The default policy is
					"item". However, we chose not to define
					a schema-specified default for this attribute.
				</xs:documentation>
			</xs:annotation>
		</xs:attribute>
		<xs:attribute name="item-count" use="optional" type="xs:string">
			<xs:annotation>
				<xs:documentation>
					Specifies the number of items to process per chunk
					when using the item
					checkpoint policy. It must be valid XML integer.
					It is an optional
					attribute. The default is 10. The item-count
					attribute is ignored
					for "custom" checkpoint policy. However, to
					make it easier for implementations to support JSL inheritance
					we
					abstain from defining a schema-specified default for this
					attribute.
				</xs:documentation>
			</xs:annotation>
		</xs:attribute>
		<xs:attribute name="time-limit" use="optional" type="xs:string">
			<xs:annotation>
				<xs:documentation>
					Specifies the amount of time in seconds before
					taking a checkpoint for the
					item checkpoint policy. It must be valid
					XML integer. It is an
					optional attribute. The default is 0, which
					means no limit. However, to
					make it easier for implementations to
					support JSL inheritance
					we abstain from defining a schema-specified
					default for this attribute.
					When a value greater than zero is
					specified, a checkpoint is taken when
					time-limit is reached or
					item-count items have been processed,
					whichever comes first. The
					time-limit attribute is ignored for
					"custom" checkpoint policy.
				</xs:documentation>
			</xs:annotation>
		</xs:attribute>
		<xs:attribute name="skip-limit" use="optional" type="xs:string">
			<xs:annotation>
				<xs:documentation>
					Specifies the number of exceptions a step will
					skip if any configured
					skippable exceptions are thrown by chunk
					processing. It must be a
					valid XML integer value. It is an optional
					attribute. The default
					is no limit.
				</xs:documentation>
			</xs:annotation>
		</xs:attribute>
		<xs:attribute name="retry-limit" use="optional" type="xs:string">
			<xs:annotation>
				<xs:documentation>
					Specifies the number of times a step will retry if
					any configured retryable
					exceptions are thrown by chunk processing.
					It must be a valid XML
					integer value. It is an optional attribute.
					The default is no
					limit.
				</xs:documentation>
			</xs:annotation>
		</xs:attribute>
	</xs:complexType>

	<xs:complexType name="ItemReader">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="ref" use="required" type="jsl:artifactRef" />
	</xs:complexType>

	<xs:complexType name="ItemProcessor">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="ref" use="required" type="jsl:artifactRef" />
	</xs:complexType>

	<xs:complexType name="ItemWriter">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="ref" use="required" type="jsl:artifactRef" />
	</xs:complexType>

	<xs:complexType name="Property">
		<xs:attribute name="name" type="xs:string" use="required" />
		<xs:attribute name="value" type="xs:string" use="required" />
	</xs:complexType>

	<xs:complexType name="Properties">
		<xs:sequence>
			<xs:element name="property" type="jsl:Property" maxOccurs="unbounded" minOccurs="0" />
		</xs:sequence>
		<xs:attribute name="partition" use="optional" type="xs:string" />
	</xs:complexType>

	<xs:complexType name="Listeners">
		<xs:sequence>
			<xs:element name="listener" type="jsl:Listener" maxOccurs="unbounded" minOccurs="0" />
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="Partition">
		<xs:sequence>
			<xs:choice minOccurs="0" maxOccurs="1"> 
				<xs:element name="mapper" type="jsl:PartitionMapper" />
				<xs:element name="plan" type="jsl:PartitionPlan" />
			</xs:choice>
			<xs:element name="collector" type="jsl:Collector"
				minOccurs="0" maxOccurs="1" />
			<xs:element name="analyzer" type="jsl:Analyzer" minOccurs="0"
				maxOccurs="1" />
			<xs:element name="reducer" type="jsl:PartitionReducer"
				minOccurs="0" maxOccurs="1" />
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="PartitionPlan">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="unbounded" />
		</xs:sequence>
		<xs:attribute name="partitions" use="optional" type="xs:string" />
		<xs:attribute name="threads" use="optional" type="xs:string" />
	</xs:complexType>

	<xs:complexType name="PartitionMapper">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="ref" use="required" type="jsl:artifactRef" />
	</xs:complexType>

	<xs:complexType name="Collector">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="ref" use="required" type="jsl:artifactRef" />
	</xs:complexType>

	<xs:complexType name="Analyzer">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="ref" use="required" type="jsl:artifactRef" />
	</xs:complexType>

	<xs:complexType name="PartitionReducer">
		<xs:sequence>
			<xs:element name="properties" type="jsl:Properties"
				minOccurs="0" maxOccurs="1" />
		</xs:sequence>
		<xs:attribute name="ref" use="required" type="jsl:artifactRef" />
	</xs:complexType>

</xs:schema>
