<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://drools.org/schema/kie-spring"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:spring="http://www.springframework.org/schema/beans"
            targetNamespace="http://drools.org/schema/kie-spring"
            elementFormDefault="qualified"
            attributeFormDefault="unqualified">

  <xsd:import namespace="http://www.springframework.org/schema/beans"
              schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"/>

  <xsd:element name="kmodule">
    <xsd:complexType>
      <xsd:complexContent>
      <xsd:extension base="identifiedType">
        <xsd:group ref="kmoduleElements"/>
      </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>
  </xsd:element>

  <!-- base types-->
  <!-- this can be removed and we can use the type declared in the spring xsd -->
  <!-- once we upgrade to Spring 3.1+ -->
  <xsd:complexType name="identifiedType" abstract="true">
    <xsd:annotation>
      <xsd:documentation><![CDATA[
	The unique identifier for a bean. The scope of the identifier
	is the enclosing bean factory.
			]]></xsd:documentation>
    </xsd:annotation>
    <xsd:attribute name="id" type="xsd:string">
      <xsd:annotation>
        <xsd:documentation><![CDATA[
	The unique identifier for a bean.
				]]></xsd:documentation>
      </xsd:annotation>
    </xsd:attribute>
  </xsd:complexType>

  <xsd:group name="kmoduleElements">
    <xsd:sequence>
      <xsd:element ref="kbase" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:group>

  <xsd:element name="kbase">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element type="ksessionComplexType" name="ksession" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
      <xsd:attribute name="name" use="required" type="xsd:string"/>
      <xsd:attribute name="includes" type="xsd:string"/>
      <xsd:attribute name="packages" type="xsd:string"/>
      <xsd:attribute name="default" type="xsd:boolean"/>
      <xsd:attribute name="scope" type="xsd:string"/>
      <xsd:attribute name="equalsBehavior" type="insertBehaviorEnum"/>
      <xsd:attribute name="eventProcessingMode" type="eventModeEnum"/>
      <xsd:attribute name="declarativeAgenda" type="declarativeAgendaEnum" />
    </xsd:complexType>
  </xsd:element>

  <xsd:complexType name="ksessionComplexType">
    <xsd:sequence>
      <xsd:sequence minOccurs="0" maxOccurs="unbounded">
        <xsd:element ref="agendaEventListener" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="processEventListener" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="ruleRuntimeEventListener" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
      <xsd:sequence minOccurs="0" maxOccurs="unbounded">
        <xsd:element ref="consoleLogger" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="fileLogger" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
      <xsd:element name="batch" minOccurs="0" maxOccurs="1">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element ref="command" minOccurs="0" maxOccurs="unbounded"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="configuration" type="configurationType" minOccurs="0" maxOccurs="1"/>
      <xsd:element ref="workItemHandlers" minOccurs="0" maxOccurs="1"/>
      <xsd:element ref="listeners" minOccurs="0" maxOccurs="1"/>
    </xsd:sequence>
    <xsd:attribute name="name" use="required" type="xsd:string"/>
    <xsd:attribute name="type" type="ksessionType"/>
    <xsd:attribute name="default" type="xsd:boolean"/>
    <xsd:attribute name="scope" type="xsd:string"/>
    <xsd:attribute name="clockType" type="clockTypeEnum"/>
    <xsd:attribute name="listeners-ref" use="optional" type="xsd:IDREF"/>
  </xsd:complexType>

  <!-- Persistence -->
  <xsd:complexType name="classesType">
    <xsd:sequence>
      <xsd:element name="class" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="persisterType">
    <xsd:attribute name="for-class" use="required" type="xsd:string"/>
    <xsd:attribute name="implementation" use="required" type="xsd:string"/>
  </xsd:complexType>

  <xsd:complexType name="variablePersistersType">
    <xsd:sequence>
      <xsd:element name="persister" type="persisterType" minOccurs="1" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:element name="jpaSessionServiceFactory">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="variablePersisters" type="variablePersistersType" minOccurs="0" maxOccurs="1"/>
      </xsd:sequence>
      <xsd:attribute name="id" use="optional" type="xsd:string"/>
      <xsd:attribute name="kbase" use="required" type="xsd:string"/>
      <xsd:attribute name="entityManagerFactory" use="required" type="xsd:string"/>
      <xsd:attribute name="transactionManager" use="required" type="xsd:string"/>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="persistence" type="persistenceType" abstract="true"/>

  <xsd:complexType name="persistenceType">
  </xsd:complexType>

  <xsd:element name="jpa-persistence" substitutionGroup="persistence">
    <xsd:complexType>
      <xsd:complexContent>
        <xsd:extension base="persistenceType">
          <xsd:all>
            <xsd:element name="variable-persisters" type="variablePersistersType" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="transaction-manager" minOccurs="0" maxOccurs="1">
              <xsd:complexType>
                <xsd:attribute name="ref" use="optional" type="xsd:string"/>
              </xsd:complexType>
            </xsd:element>
            <xsd:element name="entity-manager-factory" minOccurs="1" maxOccurs="1">
              <xsd:complexType>
                <xsd:attribute name="ref" use="required" type="xsd:string"/>
              </xsd:complexType>
            </xsd:element>
          </xsd:all>
          <xsd:attribute name="load" use="optional" type="xsd:integer"/>
        </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>
  </xsd:element>

  <xsd:complexType name="configurationType">
    <xsd:all minOccurs="0">
      <xsd:element ref="persistence" minOccurs="0"/>

      <xsd:element name="keep-reference" minOccurs="0">
        <xsd:complexType>
          <xsd:attribute name="enabled" type="xsd:boolean"/>
        </xsd:complexType>
      </xsd:element>

      <xsd:element name="clock-type" minOccurs="0">
        <xsd:complexType>
          <xsd:attribute name="type" type="clockTypeEnum"/>
        </xsd:complexType>
      </xsd:element>

      <xsd:element name="work-item-handlers" minOccurs="0">
        <xsd:complexType>
          <xsd:choice>
            <xsd:element name="work-item-handler" minOccurs="0" maxOccurs="unbounded">
              <xsd:complexType>
                <xsd:attribute name="name" use="required" type="xsd:string"/>
                <xsd:attribute name="ref" use="required" type="xsd:string"/>
              </xsd:complexType>
            </xsd:element>
          </xsd:choice>
        </xsd:complexType>
      </xsd:element>
    </xsd:all>
  </xsd:complexType>

  <xsd:element name="kstore">
    <xsd:complexType>
      <xsd:attribute name="id" use="required" type="xsd:string"/>
    </xsd:complexType>
  </xsd:element>

  <!-- Commands -->
  <xsd:element name="command" type="commandType" abstract="true"/>

  <xsd:complexType name="commandType">
  </xsd:complexType>

  <xsd:element name="insert-object" substitutionGroup="command">
    <xsd:complexType>
      <xsd:complexContent>
        <xsd:extension base="commandType">
          <xsd:choice minOccurs="0" maxOccurs="1">
            <xsd:element ref="spring:bean"/>
            <xsd:element ref="spring:ref"/>
            <xsd:element ref="spring:idref"/>
            <xsd:element ref="spring:value"/>
            <xsd:element ref="spring:null"/>
            <xsd:element ref="spring:list"/>
            <xsd:element ref="spring:set"/>
            <xsd:element ref="spring:map"/>
            <xsd:element ref="spring:props"/>
          </xsd:choice>
          <xsd:attribute name="ref" use="optional" type="xsd:string"/>
        </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="set-global" substitutionGroup="command">
    <xsd:complexType>
      <xsd:complexContent>
        <xsd:extension base="commandType">
          <xsd:choice minOccurs="0" maxOccurs="1">
            <xsd:element ref="spring:bean"/>
            <xsd:element ref="spring:ref"/>
            <xsd:element ref="spring:idref"/>
            <xsd:element ref="spring:value"/>
            <xsd:element ref="spring:null"/>
            <xsd:element ref="spring:list"/>
            <xsd:element ref="spring:set"/>
            <xsd:element ref="spring:map"/>
            <xsd:element ref="spring:props"/>
          </xsd:choice>
          <xsd:attribute name="ref" use="optional" type="xsd:string"/>
          <xsd:attribute name="identifier" use="required" type="xsd:string"/>
        </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="fire-all-rules" substitutionGroup="command">
    <xsd:complexType>
      <xsd:complexContent>
        <xsd:extension base="commandType">
          <xsd:attribute name="max" use="optional" type="xsd:integer"/>
        </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="fire-until-halt" substitutionGroup="command">
    <xsd:complexType>
      <xsd:complexContent>
        <xsd:extension base="commandType">
        </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="start-process" substitutionGroup="command">
    <xsd:complexType>
      <xsd:complexContent>
        <xsd:extension base="commandType">
          <xsd:sequence>
            <xsd:element name="parameter" minOccurs="0" maxOccurs="unbounded">
              <xsd:complexType>
                <xsd:choice minOccurs="0" maxOccurs="1">
                  <xsd:element ref="spring:bean"/>
                  <xsd:element ref="spring:ref"/>
                  <xsd:element ref="spring:idref"/>
                  <xsd:element ref="spring:value"/>
                  <xsd:element ref="spring:null"/>
                  <xsd:element ref="spring:list"/>
                  <xsd:element ref="spring:set"/>
                  <xsd:element ref="spring:map"/>
                  <xsd:element ref="spring:props"/>
                </xsd:choice>
              </xsd:complexType>
            </xsd:element>
          </xsd:sequence>
          <xsd:attribute name="process-id" use="required" type="xsd:string"/>
        </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="signal-event" substitutionGroup="command">
    <xsd:complexType>
      <xsd:complexContent>
        <xsd:extension base="commandType">
          <xsd:choice minOccurs="0" maxOccurs="1">
            <xsd:element ref="spring:bean"/>
            <xsd:element ref="spring:ref"/>
            <xsd:element ref="spring:idref"/>
            <xsd:element ref="spring:value"/>
            <xsd:element ref="spring:null"/>
            <xsd:element ref="spring:list"/>
            <xsd:element ref="spring:set"/>
            <xsd:element ref="spring:map"/>
            <xsd:element ref="spring:props"/>
          </xsd:choice>
          <xsd:attribute name="ref" use="optional" type="xsd:string"/>
          <xsd:attribute name="event-type" use="required" type="xsd:string"/>
          <xsd:attribute name="process-instance-id" use="optional" type="xsd:integer"/>
        </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="consoleLogger">
    <xsd:complexType>
      <xsd:attribute name="id" use="optional" type="xsd:ID"/>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="fileLogger">
    <xsd:complexType>
      <xsd:attribute name="file" use="required" type="xsd:string"/>
      <xsd:attribute name="threaded" use="optional" type="xsd:boolean" default="false"/>
      <xsd:attribute name="interval" use="optional" type="xsd:int" default="30"/>
      <xsd:attribute name="id" use="optional" type="xsd:ID"/>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="listeners">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="ruleRuntimeEventListener" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="agendaEventListener" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="processEventListener" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="workItemHandlers">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="workItemHandler" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="workItemHandler">
    <xsd:complexType>
      <xsd:attribute name="name" use="required" type="xsd:string"/>
      <xsd:attribute name="type" use="required" type="xsd:string"/>
    </xsd:complexType>
  </xsd:element>

  <xsd:simpleType name="ksessionType">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="stateless"/>
      <xsd:enumeration value="stateful"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="eventModeEnum">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="stream"/>
      <xsd:enumeration value="cloud"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="insertBehaviorEnum">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="identity"/>
      <xsd:enumeration value="equality"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="declarativeAgendaEnum">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="enabled" />
      <xsd:enumeration value="disabled" />
      <xsd:enumeration value="true" />
      <xsd:enumeration value="false" />
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="clockTypeEnum">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="realtime"/>
      <xsd:enumeration value="pseudo"/>
    </xsd:restriction>
  </xsd:simpleType>

  <!-- additions for environment JBRULES-3553 -->
  <xsd:element name="environment">
    <xsd:complexType>
      <xsd:all>
        <xsd:element ref="transaction-manager" minOccurs="0" maxOccurs="1"/>
        <xsd:element ref="entity-manager-factory" minOccurs="0" maxOccurs="1"/>
        <xsd:element ref="globals" minOccurs="0" maxOccurs="1"/>
        <xsd:element ref="object-marshalling-strategies" minOccurs="0" maxOccurs="1"/>
        <xsd:element ref="scoped-entity-manager" minOccurs="0" maxOccurs="1"/>
        <xsd:element ref="date-formats" minOccurs="0" maxOccurs="1"/>
        <xsd:element ref="calendars" minOccurs="0" maxOccurs="1"/>
      </xsd:all>
      <xsd:attribute name="id" use="required" type="xsd:ID"/>
    </xsd:complexType>
  </xsd:element>

  <xsd:complexType name="generic-ref-or-nested-type">
    <xsd:choice minOccurs="0" maxOccurs="1">
      <xsd:element ref="spring:bean"/>
    </xsd:choice>
    <xsd:attribute name="ref" use="optional" type="xsd:IDREF"/>
  </xsd:complexType>

  <xsd:complexType name="generic-scoped-entitymanager">
    <xsd:choice minOccurs="0" maxOccurs="1">
      <xsd:element ref="spring:bean"/>
    </xsd:choice>
    <xsd:attribute name="scope" use="required" type="scopedEntityManagerTypeEnum"/>
    <xsd:attribute name="ref" use="optional" type="xsd:IDREF"/>
  </xsd:complexType>

  <xsd:simpleType name="scopedEntityManagerTypeEnum">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="app"/>
      <xsd:enumeration value="cmd"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:element name="scoped-entity-manager" type="generic-scoped-entitymanager"/>

  <xsd:element name="transaction-manager" type="generic-ref-or-nested-type"/>
  <xsd:element name="entity-manager-factory" type="generic-ref-or-nested-type"/>
  <xsd:element name="globals" type="generic-ref-or-nested-type"/>
  <xsd:element name="date-formats" type="generic-ref-or-nested-type"/>
  <xsd:element name="calendars" type="generic-ref-or-nested-type"/>

  <xsd:element name="object-marshalling-strategies">
    <xsd:complexType>
      <xsd:all>
        <xsd:element ref="serializable-placeholder-resolver-strategy" minOccurs="0" maxOccurs="1"/>
        <xsd:element ref="jpa-placeholder-resolver-strategy" minOccurs="0" maxOccurs="1"/>
        <xsd:element ref="identity-placeholder-resolver-strategy" minOccurs="0" maxOccurs="1"/>
        <xsd:element ref="process-instance-resolver-strategy" minOccurs="0" maxOccurs="1"/>
        <xsd:element ref="custom-marshalling-strategy" minOccurs="0"/>
      </xsd:all>
      <xsd:attribute name="ref" use="optional" type="xsd:string"/>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="jpa-placeholder-resolver-strategy">
    <xsd:complexType>
      <xsd:attribute name="env-ref" use="optional" type="xsd:IDREF"/>
    </xsd:complexType>
  </xsd:element>

  <xsd:complexType name="generic-resolver-strategy">
    <xsd:choice minOccurs="0" maxOccurs="1">
      <xsd:element ref="strategy-acceptor"/>
    </xsd:choice>
    <xsd:attribute name="strategy-acceptor-ref" use="optional" type="xsd:IDREF"/>
  </xsd:complexType>

  <xsd:element name="serializable-placeholder-resolver-strategy" type="generic-resolver-strategy"/>
  <xsd:element name="identity-placeholder-resolver-strategy" type="generic-resolver-strategy"/>
  <xsd:element name="process-instance-resolver-strategy"/>

  <xsd:element name="strategy-acceptor">
    <xsd:complexType>
      <xsd:choice minOccurs="0" maxOccurs="1">
        <xsd:element ref="spring:bean"/>
      </xsd:choice>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="custom-marshalling-strategy" type="generic-ref-or-nested-type"/>
  <!-- end of additions for environment -->

  <!-- additions for ksession listeners -->
  <xsd:complexType name="eventListener">
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="spring:bean"/>
    </xsd:choice>
    <xsd:attribute name="ref" use="optional" type="xsd:string"/>
  </xsd:complexType>

  <xsd:element name="agendaEventListener" type="eventListener"/>
  <xsd:element name="ruleRuntimeEventListener" type="eventListener"/>
  <xsd:element name="processEventListener" type="eventListener"/>

  <xsd:element name="eventListeners">
    <xsd:complexType>
      <xsd:all maxOccurs="1" minOccurs="0">
        <xsd:element ref="agendaEventListener"/>
        <xsd:element ref="ruleRuntimeEventListener"/>
        <xsd:element ref="processEventListener"/>
      </xsd:all>
      <xsd:attribute name="id" use="required" type="xsd:ID"/>
    </xsd:complexType>
  </xsd:element>
  <!-- end of additions for ksession listeners -->

  <!-- kie import -->
  <xsd:element name="releaseId">
    <xsd:complexType>
      <xsd:attribute name="groupId" use="required" type="xsd:string"/>
      <xsd:attribute name="artifactId" use="required" type="xsd:string"/>
      <xsd:attribute name="version" use="required" type="xsd:string"/>
      <xsd:attribute name="id" use="required" type="xsd:ID"/>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="import">
    <xsd:complexType>
      <xsd:attribute name="releaseId-ref" use="optional" type="xsd:string"/>
      <xsd:attribute name="enableScanner" use="optional" type="xsd:boolean"/>
      <xsd:attribute name="scannerInterval" use="optional" type="xsd:int" default="30"/>
    </xsd:complexType>
  </xsd:element>

  <!-- end of kie-import -->

</xsd:schema>