<?xml version="1.0" encoding="UTF-8"?>

<!--
  ~ Copyright The WildFly Authors
  ~ SPDX-License-Identifier: Apache-2.0
  -->

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
            targetNamespace="urn:jboss:domain:ee:4.0"
            xmlns="urn:jboss:domain:ee:4.0"
            elementFormDefault="qualified"
            attributeFormDefault="unqualified"
            version="4.0">

    <!-- The EE subsystem root element -->
    <xs:element name="subsystem" type="subsystem"/>

    <xs:complexType name="subsystem">
        <xs:sequence>
            <xs:element name="global-modules" type="modulesType" minOccurs="0" maxOccurs="1"/>
            <xs:element name="ear-subdeployments-isolated" default="false" type="ear-subdeployments-isolatedType" minOccurs="0" maxOccurs="1"/>
            <xs:element name="spec-descriptor-property-replacement" type="descriptor-property-replacementType" minOccurs="0" maxOccurs="1" />
            <xs:element name="jboss-descriptor-property-replacement" type="descriptor-property-replacementType" minOccurs="0" maxOccurs="1" />
            <xs:element name="annotation-property-replacement" type="annotation-property-replacementType" minOccurs="0" maxOccurs="1" />
            <xs:element name="concurrent" type="concurrentType" minOccurs="0" maxOccurs="1" />
            <xs:element name="default-bindings" type="defaultBindingsType" minOccurs="0" maxOccurs="1" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="modulesType">
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="module" type="moduleType"/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="moduleType">
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="slot" type="xs:string"/>
        <xs:attribute name="annotations" type="xs:boolean" use="optional" default="false"/>
        <xs:attribute name="meta-inf" type="xs:boolean" use="optional" default="false"/>
        <xs:attribute name="services" type="xs:boolean" use="optional" default="true"/>
    </xs:complexType>

    <xs:simpleType name="ear-subdeployments-isolatedType">
        <xs:annotation>
                <xs:documentation>
                    Flag indicating whether each of the subdeployments within a .ear can access classes belonging to
                    another subdeployment within the same .ear. Setting this to false, allows the subdeployments to
                    see classes belonging to other subdeployments within the .ear.
                    For example:
                    myapp.ear
                     |
                     |--- web.war
                     |
                     |--- ejb1.jar
                     |
                     |--- ejb2.jar

                    If the ear-subdeployments-isolated is set to false, then the classes in web.war can access classes
                    belonging to ejb1.jar and ejb2.jar. Similarly, classes from ejb1.jar can access classes from ejb2.jar
                    (and vice-versa).

                    *Note that this flag, has no effect on the isolated classloader of the .war file(s). i.e. irrespective
                    of whether this flag is set to true or false, the .war within a .ear will have a isolated classloader
                    and other subdeployments within that .ear will not be able to access classes from that .war. This is
                    as per spec*
                </xs:documentation>
        </xs:annotation>

        <xs:restriction base="xs:boolean"/>
    </xs:simpleType>

    <xs:simpleType name="descriptor-property-replacementType">
        <xs:annotation>
            <xs:documentation>
                Flag indicating whether system property replacement will be performed on a descriptor. This defaults to
                true, however it is disabled in the default configurations.

                Security Node: System properties etc are resolved in the security context of the application server
                itself, not the deployment that contains the file. This means that if you are running with a security
                manager and enable this property, a deployment can potentially access system properties or environment
                entries that the security manager would have otherwise prevented.
            </xs:documentation>
        </xs:annotation>

        <xs:restriction base="xs:boolean"/>
    </xs:simpleType>

    <xs:simpleType name="annotation-property-replacementType">
        <xs:annotation>
            <xs:documentation>
                Flag indicating whether system property replacement will be performed on an annotation. This defaults to
                true, however it is disabled in the default configurations.

                Security Node: System properties etc are resolved in the security context of the application server
                itself, not the deployment that contains the file. This means that if you are running with a security
                manager and enable this property, a deployment can potentially access system properties or environment
                entries that the security manager would have otherwise prevented.
            </xs:documentation>
        </xs:annotation>

        <xs:restriction base="xs:boolean"/>
    </xs:simpleType>

    <!-- EE Concurrent (JSR 236) XML elements and attributes definition -->

    <xs:complexType name="concurrentType">
        <xs:annotation>
            <xs:documentation>
                Configures EE Concurrent resources. If undefined, it turns off all EE Concurrent functionality.
            </xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="context-services" type="contextServicesType" minOccurs="0" maxOccurs="1"/>
            <xs:element name="managed-thread-factories" type="managedThreadFactoriesType" minOccurs="0" maxOccurs="1"/>
            <xs:element name="managed-executor-services" type="managedExecutorServicesType" minOccurs="0" maxOccurs="1"/>
            <xs:element name="managed-scheduled-executor-services" type="managedScheduledExecutorServicesType" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="contextServicesType">
        <xs:choice minOccurs="1" maxOccurs="unbounded">
            <xs:element name="context-service" type="contextServiceType"/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="contextServiceType">
        <xs:annotation>
            <xs:documentation>
                The context service (implementing javax.enterprise.concurrent.ContextService).
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="name" type="nameType" use="required"/>
        <xs:attribute name="jndi-name" type="jndiNameType" use="required"/>
        <xs:attribute name="use-transaction-setup-provider" type="xs:boolean" default="false">
            <xs:annotation>
                <xs:documentation>
                    The optional attribute that defines if the context service should use a transaction setup provider, which may be used to suspend and resume active transactions.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="managedThreadFactoriesType">
        <xs:choice minOccurs="1" maxOccurs="unbounded">
            <xs:element name="managed-thread-factory" type="managedThreadFactoryType"/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="managedThreadFactoryType">
        <xs:annotation>
            <xs:documentation>
                A managed thread factory (implementing javax.enterprise.concurrent.ManagedThreadFactory).
                The mandatory "name" attribute, which may not be empty or have the value "default", identifies the
                created thread factory.
                The optional "context-service" identifies which Context Service should be used by created threads.
                The optional "priority" attribute may be used to specify the priority of created threads.
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="name" type="nameType" use="required"/>
        <xs:attribute name="jndi-name" type="jndiNameType" use="required"/>
        <xs:attribute name="context-service" type="contextServiceNameType"/>
        <xs:attribute name="priority" type="priorityType" default="5"/>
    </xs:complexType>

    <xs:complexType name="managedExecutorServicesType">
        <xs:choice minOccurs="1" maxOccurs="unbounded">
            <xs:element name="managed-executor-service" type="managedExecutorServiceType"/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="managedExecutorServiceType">
        <xs:annotation>
            <xs:documentation>
                A managed executor service (implementing javax.enterprise.concurrent.ManagedExecutorService).
                If the "thread-factory" attribute is not defined a managed thread factory with no context service and
                normal thread priority will be created and used by the executor.
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="name" type="nameType" use="required"/>
        <xs:attribute name="jndi-name" type="jndiNameType" use="required"/>
        <xs:attribute name="context-service" type="contextServiceNameType"/>
        <xs:attribute name="thread-factory" type="threadFactoryType"/>
        <xs:attribute name="hung-task-threshold" type="hungTaskThresholdType" default="0"/>
        <xs:attribute name="long-running-tasks" type="longRunningTasksType" default="false"/>
        <xs:attribute name="core-threads" type="coreThreadsType">
            <xs:annotation>
                <xs:documentation>
                    The minimum number of threads to be used by the executor. If left undefined the default core-size
                    is calculated based on the number of processors. A value of zero is not advised and in some cases
                    invalid. See the queue-length attribute for details on how this value is used to determine the
                    queuing strategy.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="max-threads" type="maxThreadsType">
            <xs:annotation>
                <xs:documentation>The maximum number of threads to be used by the executor. If left undefined the value
                    from core-size will be used. This value is ignored if an unbounded queue is used (only core-threads
                    will be used in that case).
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="keepalive-time" type="keepAliveTimeType" default="60000"/>
        <xs:attribute name="queue-length" type="queueLengthType">
            <xs:annotation>
                <xs:documentation>
                    The executors task queue capacity. A length of 0 means direct hand-off and possible rejection will
                    occur. An undefined length (the default), or Integer.MAX_VALUE, indicates that an unbounded queue
                    should be used. All other values specify an exact queue size. If an unbounded queue or direct hand-off
                    is used, a core-threads value greater than zero is required.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:attribute name="reject-policy" type="rejectPolicyType" default="ABORT"/>
    </xs:complexType>

    <xs:complexType name="managedScheduledExecutorServicesType">
        <xs:choice minOccurs="1" maxOccurs="unbounded">
            <xs:element name="managed-scheduled-executor-service" type="managedScheduledExecutorServiceType"/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="managedScheduledExecutorServiceType">
        <xs:annotation>
            <xs:documentation>
                A managed scheduled executor service (implementing javax.enterprise.concurrent.ManagedScheduledExecutorService).
                If the "thread-factory" attribute is not defined a managed thread factory with no context service and normal thread priority will be created and used by the executor.
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="name" type="nameType" use="required"/>
        <xs:attribute name="jndi-name" type="jndiNameType" use="required"/>
        <xs:attribute name="context-service" type="contextServiceNameType"/>
        <xs:attribute name="thread-factory" type="threadFactoryType"/>
        <xs:attribute name="hung-task-threshold" type="hungTaskThresholdType" default="0"/>
        <xs:attribute name="long-running-tasks" type="longRunningTasksType" default="false"/>
        <xs:attribute name="core-threads" type="coreThreadsType"/>
        <xs:attribute name="keepalive-time" type="keepAliveTimeType" default="60000"/>
        <xs:attribute name="reject-policy" type="rejectPolicyType" default="ABORT"/>
    </xs:complexType>

    <xs:simpleType name="nonEmptyTokenType">
        <xs:annotation>
            <xs:documentation>
                A non empty token name.
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:token">
            <xs:minLength value="1"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="nameType">
        <xs:annotation>
            <xs:documentation>
                The name for an EE Concurrency resource.
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="nonEmptyTokenType" />
    </xs:simpleType>

    <xs:simpleType name="jndiNameType">
        <xs:annotation>
            <xs:documentation>
                The name of the entry in JNDI.
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="nonEmptyTokenType" />
    </xs:simpleType>

    <xs:simpleType name="contextServiceNameType">
        <xs:annotation>
            <xs:documentation>
                The name of the context service to be used.
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="nonEmptyTokenType" />
    </xs:simpleType>

    <xs:simpleType name="threadFactoryType">
        <xs:annotation>
            <xs:documentation>
                The name of the managed thread factory to be used by the executor.
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="nonEmptyTokenType" />
    </xs:simpleType>

    <xs:simpleType name="priorityType">
        <xs:annotation>
            <xs:documentation>
                A priority which can range from 1 to 10 (inclusive).  See http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#setPriority(int) for more information.
                This type matches EE Concurrent 1.0 Final Release attribute named "Priority", defined in sections 3.4.4.2
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:integer">
            <xs:minInclusive value="1"/>
            <xs:maxInclusive value="10"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="hungTaskThresholdType">
        <xs:annotation>
            <xs:documentation>
                The amount of time in milliseconds that a task can execute before it is considered hung. If zero then tasks are never considered hung.
                This xml attribute matches EE Concurrent 1.0 Final Release attribute named "Hung Task Threshold", defined in sections 3.1.4.2 and 3.2.4.2
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:long">
            <xs:minInclusive value="0"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="longRunningTasksType">
        <xs:annotation>
            <xs:documentation>
                If the application intends to run short vs. long-running tasks they can specify to use pooled or daemon threads.
                This xml attribute matches EE Concurrent 1.0 Final Release attribute named "Thread Use", defined in section 3.2.4.2
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:boolean"/>
    </xs:simpleType>

    <xs:simpleType name="coreThreadsType">
        <xs:annotation>
            <xs:documentation>
                The number of threads to keep in the executor's pool, even if they are idle.
                This type matches EE Concurrent 1.0 Final Release attribute named "Pool Info: Core Size", defined in sections 3.1.4.2 and 3.2.4.2
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:int">
            <xs:minInclusive value="0"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="maxThreadsType">
        <xs:annotation>
            <xs:documentation>
                The maximum number of threads to allow in the executor's pool.
                This type matches EE Concurrent 1.0 Final Release attribute named "Pool Info: Maximum Size", defined in section 3.1.4.2
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:int">
            <xs:minInclusive value="0"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="keepAliveTimeType">
        <xs:annotation>
            <xs:documentation>
                The time to allow threads to remain idle when the number of threads is greater than the core size.
                This type matches EE Concurrent 1.0 Final Release attribute named "Pool Info: Keep Alive", defined in sections 3.1.4.2 and 3.2.4.2
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:long">
            <xs:minInclusive value="0"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="queueLengthType">
        <xs:annotation>
            <xs:documentation>
                The number of tasks that can be stored in the input queue. Zero means the queue capacity is not limited.
                This type matches EE Concurrent 1.0 Final Release attribute named "Work Queue Capacity", defined in section 3.1.4.2
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:int">
            <xs:minInclusive value="0"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="rejectPolicyType">
        <xs:annotation>
            <xs:documentation>
                The policy to use when a task is to be rejected by the executor.
                This type matches EE Concurrent 1.0 Final Release attribute named "Reject Policy", defined in sections 3.1.4.2 and 3.2.4.2
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:token">
            <xs:enumeration value="ABORT">
                <xs:annotation>
                    <xs:documentation>
                        Throw an exception when rejected.
                    </xs:documentation>
                </xs:annotation>
            </xs:enumeration>
            <xs:enumeration value="RETRY_ABORT">
                <xs:annotation>
                    <xs:documentation>
                        Automatically resubmit and abort if it fails.
                    </xs:documentation>
                </xs:annotation>
            </xs:enumeration>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="defaultBindingsType">
        <xs:annotation>
            <xs:documentation>
                The JNDI names for the default resources on EE components/modules JNDI contexts.
                The optional context-service attribute defines the JNDI name of the EE Concurrency ContextService that should be bound at java:comp/DefaultContextService.
                The optional datasource attribute defines the JNDI name of the SQL DataSource that should be bound at java:comp/DefaultDataSource.
                The optional jms-connection-factory attribute defines the JNDI name of the JMS ConnectionFactory that should be bound at java:comp/DefaultJMSConnectionFactory.
                The optional managed-executor-service attribute defines the JNDI name of the EE Concurrency ManagedExecutorService that should be bound at java:comp/DefaultManagedExecutorService.
                The optional managed-scheduled-executor-service attribute defines the JNDI name of the EE Concurrency ManagedScheduledExecutorService that should be bound at java:comp/DefaultManagedScheduledExecutorService.
                The optional managed-thread-factory attribute defines the JNDI name of the EE Concurrency ManagedThreadFactory that should be bound at java:comp/DefaultManagedThreadFactory.
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="context-service" type="jndiNameType"/>
        <xs:attribute name="datasource" type="jndiNameType"/>
        <xs:attribute name="jms-connection-factory" type="jndiNameType"/>
        <xs:attribute name="managed-executor-service" type="jndiNameType"/>
        <xs:attribute name="managed-scheduled-executor-service" type="jndiNameType"/>
        <xs:attribute name="managed-thread-factory" type="jndiNameType"/>
    </xs:complexType>

</xs:schema>
