<?xml version="1.0" encoding="UTF-8"?>
<!--
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    this work for additional information regarding copyright ownership.
    The ASF licenses this file to You 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 targetNamespace="http://geronimo.apache.org/xml/ns/deployment-1.2"
    xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.2"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    attributeFormDefault="unqualified">

    <xs:annotation>
        <xs:documentation>
            This is an XML Schema Definition for Geronimo service deployment
            plan. This deployment plan is used for deploying service modules
            which contains non-application GBeans like thread pool, the
            tomcat/jetty container, security manager, etc. In case the Service
            deployment plan is provided internally in the java archive, it
            should be named META-INF/geronimo-service.xml. In case the Service
            deployment plan is provided externally, the deployment descriptor
            can be named anything and provided to the deploy tool. All the
            Service deployment plan must specify the top level element as module
            with namespace specified as 
            xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2". The default
            location for this document is
            http://geronimo.apache.org/xml/ns/deployment-1.2

            Typical Geronimo Service Deployment plan will look like this:
            <![CDATA[
            <?xml version="1.0" encoding="UTF-8"?>
            <module
                xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2">
                <environment>
                    ...
                </environment>
                <gbean>
                    ...
                </gbean>
            </module>
            ]]>
        </xs:documentation>
    </xs:annotation>

    <xs:element name="module" type="sys:moduleType">
        <xs:annotation>
            <xs:documentation>
                The module element is the root element of the deployment plan
                for the Geronimo Service module. Note that the sub-elements of
                this element should be as in the given order in a sequence. It
                includes two basic sections, environment section to provide
                information like moduleName, dependencies, etc. and gbean
                section to provide information about individual beans contained
                in this module.
            </xs:documentation>
        </xs:annotation>
    </xs:element>

    <xs:complexType name="moduleType">
        <xs:sequence>
            <xs:element ref="sys:environment">
                <xs:annotation>
                    <xs:documentation>
                        Reference to environment element defined later in this
                        xsd.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element ref="sys:service" minOccurs="0" maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>
                        Reference to service element defined later in this xsd.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:element name="environment" type="sys:environmentType">
        <xs:annotation>
            <xs:documentation>
                The environment element defines elements to store information
                like moduleId, dependencies, and classloader Info for the
                module. This element is used in all the Services and application
                modules deployment plans.
            </xs:documentation>
        </xs:annotation>

        <!-- TODO figure out why this doesn't work
            <xs:key name="name-key-key">
            <xs:annotation>
            <xs:documentation>
            name-key-key assures that key-values for the names of services in this module will
            have unique key names.
            </xs:documentation>
            </xs:annotation>
            <xs:selector xpath="sys:name-key"/>
            <xs:field xpath="sys:name-key/key"/>
            </xs:key>
        -->

    </xs:element>
    <xs:element name="client-environment" type="sys:environmentType">
        <xs:annotation>
            <xs:documentation>
                The client-environment element is used only by Application
                Client modules to provide client module environment setting. It
                defines elements to store information like moduleId,
                dependencies, and classloader Info for the client-side
                application module. This information is used to identify the
                module in the client container only and it should not be
                directly used by deployment process.
            </xs:documentation>
        </xs:annotation>
    </xs:element>

    <xs:element name="server-environment" type="sys:environmentType">
        <xs:annotation>
            <xs:documentation>
                The server-environment element is used only by Application
                Client modules to define server side module environment
                settings. It defines elements to store information like
                moduleId, dependencies, and classloader Info for the server-side
                of client application module. This information is used to
                identify the module in the server environment only.
            </xs:documentation>
        </xs:annotation>
    </xs:element>

    <xs:complexType name="environmentType">
        <xs:sequence>
            <xs:element name="moduleId" type="sys:artifactType" minOccurs="0">
                <xs:annotation>
                    <xs:documentation>
                        "moduleId" holds elements for the groupId, artifactId,
                        and version of the module version can be ommitted in
                        which case a timestamp is used. Module IDs are normally
                        printed with slashes between the four components, such
                        as GroupID/ArtifactID/Version/Type.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="dependencies" type="sys:dependenciesType"
                minOccurs="0">
                <xs:annotation>
                    <xs:documentation>
                        "dependencies" holds all classloader and dependency
                        information for the module
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="hidden-classes" type="sys:classFilterType"
                minOccurs="0">
                <xs:annotation>
                    <xs:documentation>
                        A list of classes which will never be loaded from parent
                        ClassLoaders of this module. For example, if Log4J was
                        listed here, the module would never see Geronimo's copy
                        of Log4J. If the module provided it's own Log4J JAR it
                        would use that, otherwise it would not be able to load
                        Log4J at all.

                        The classes are specified in zero or more child "filter"
                        elements where each filter element specifies a
                        fully-qualified class name or prefix. Essentially, any
                        class that starts with one of the prefixes listed here
                        will be treated as hidden. For example, if you specify
                        two filter elements containing "java.util" and
                        "java.lang" then you would really screw up your
                        application. :)
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="non-overridable-classes"
                type="sys:classFilterType" minOccurs="0">
                <xs:annotation>
                    <xs:documentation>
                        A list of classes which will only be loaded from parent
                        ClassLoaders of this module (never from the module's own
                        ClassLoader). For example, this is used to prevent a web
                        application from redefining "javax.servlet", so those
                        classes will *always* be loaded from the server instead
                        of from the web web application's own ClassPath.

                        The classes are specified in zero or more child "filter"
                        elements where each filter element specifies a
                        fully-qualified class name or prefix. Essentially, any
                        class that starts with one of the prefixes listed here
                        will be treated as hidden. For example, specifying two
                        filter elements containing "javax.servlet" and
                        "javax.ejb" would protect some of the core J2EE classes
                        from being overridden.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="private-classes"
                type="sys:classFilterType" minOccurs="0">
                <xs:annotation>
                    <xs:documentation>
                        A list of classes which will only be loaded from the
                        ClassLoader of this module or from parent ClassLoaders.
                        
                        This is used to prevent children configurations to see
                        specific classes from its parents. The same effect can
                        be achieved by using hidden-classes. However,
                        private-classes is the preferred approach to hide 
                        specific classes from all children configurations. 
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="inverse-classloading" type="sys:emptyType"
                minOccurs="0">
                <xs:annotation>
                    <xs:documentation>
                        If the "inverse-classloading" element is specified, the
                        standard class loading delegation model is to be
                        reversed for this module.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="suppress-default-environment" type="sys:emptyType"
                minOccurs="0">
                <xs:annotation>
                    <xs:documentation>
                        If the "suppress-default-environment" element is
                        specified then any default environment build by a
                        builder when deploying the plan will be suppressed.

                        An example of where this is useful is when deploying a
                        connector on an app client in a separate (standalone)
                        module (not as part of a client plan).

                        The connector builder defaultEnvironment includes some
                        server modules that won't work on an app client, so you
                        need to suppress the default environment and supply a
                        complete environment including all parents for a
                        non-app-client module you want to run on an app client
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:element name="dependencies" type="sys:dependenciesType" />

    <xs:complexType name="dependenciesType">
        <xs:sequence>
            <xs:element name="dependency" type="sys:dependencyType"
                minOccurs="0" maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>
                        "dependency" holds an artifact locating an artifact in a
                        repository. Depending on the type of artifact and value
                        of the import element, the artifact may be included in
                        the current classpath, be loaded as a parent, may
                        require the services in the artifact to be started, or
                        may not be added to the classpath.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="emptyType" />

    <xs:element name="service" type="sys:abstract-serviceType">
        <xs:annotation>
            <xs:documentation>
                An empty generic element to be extended by gbean and other
                module types.
            </xs:documentation>
        </xs:annotation>
    </xs:element>

    <xs:complexType name="abstract-serviceType" abstract="true">
        <xs:sequence></xs:sequence>
    </xs:complexType>

    <xs:element name="gbean" type="sys:gbeanType"
        substitutionGroup="sys:service">
        <xs:annotation>
            <xs:documentation>
                Adds a new custom component to the server. The component will be
                deployed when this application module is deployed, but it is not
                in any way protected, so once it is up and running, other
                modules can refer to it normally.
            </xs:documentation>
        </xs:annotation>
    </xs:element>

    <xs:complexType name="classFilterType">
        <xs:sequence>
            <xs:element name="filter" type="xs:string" minOccurs="0"
                maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>
                        A fully-qualified class name or prefix to be filtered.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="artifactType">
        <xs:annotation>
            <xs:documentation>
                <![CDATA[
                Refers to either another module running in the server, or
                an entry in the server's Repository.  In either case this effectively uses a
                URI.

                When this is pointing to a repository entry, the URI must have a form
                acceptable to the repository, which is currently a URI consisting of
                Maven-style identifiers separated by slashes (groupId/artifactId/version/type,
                for example, the URI "postgresql/postgresql-8.0-jdbc/313/jar" for a file like
                "repository/postgresql/postgresql-8.0-jdbc-313.jar").

                When this is pointing to a module, the URI should match the
                module's moduleId.  This also looks
                like a Maven-style URI discussed above.

                The artifactType element can take either a straight URI (as in the examples
                above), or maven-style identifier fragments (groupId, type, artifactId, and
                version), which it will compose into a URI by adding up the fragments with
                slashes in between.

                There is a correspondence between the xml format and a URI.  For example, the URI

                postgresql/postgresql-8.0-jdbc/313/jar

                corresponds to the xml:

                <groupId>postgresql</groupId>
                <artifactId>postgresql-8.0-jdbc</artifactId>
                <version>313</version>
                <type>jar</type>
	            ]]>
            </xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <!-- TODO not sure if groupId can in fact be optional -->
            <xs:element name="groupId" type="xs:string" minOccurs="0">
                <xs:annotation>
                    <xs:documentation>
                        The name for group containing this module. By default,
                        it is considered 'default' for declaration and wild card
                        '*' for dependencies.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="artifactId" type="xs:string">
                <xs:annotation>
                    <xs:documentation>
                        The name for module in a specified group. All the
                        artifactId's should be unique within a group. If no
                        articfactId is provided it will be defaulted to file
                        name of the module file.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="version" type="xs:string" minOccurs="0">
                <xs:annotation>
                    <xs:documentation>
                        The version number for the module formatted by dot
                        separated numbers. If no version is provided it will be
                        defaulted to numeric timestamp generated by
                        System.currentTimeMillis() at deploy time. In case of
                        dependencies latest available version will be used.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="type" type="xs:string" minOccurs="0">
                <xs:annotation>
                    <xs:documentation>
                        This element defines the type of the module. The type
                        could be 'CAR', 'JAR', EAR', 'WAR', etc. If no type is
                        provided it will be defaulted appropriately by the
                        deployer depending upon type of deployed module.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="dependencyType">
        <xs:complexContent>
            <xs:extension base="sys:artifactType">
                <xs:annotation>
                    <xs:documentation>
                        DependencyType includes all the elements defined in
                        artifactType.
                    </xs:documentation>
                </xs:annotation>
                <xs:sequence>
                    <xs:element name="import" type="sys:importType"
                        minOccurs="0">
                        <xs:annotation>
                            <xs:documentation>
                                The import element is restrictive element to
                                defined type of dependency. The default (when
                                omitted) is to include the specified dependency
                                in the classloader (as a parent or URL). If
                                defined as "classes" means that the classes must
                                be included in the current module's classloader
                                but the dependency does not need to be started.
                                Specifying "services" means that the dependency
                                (a module) must be started before the current
                                module, but it is not included as a parent
                                classloader.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                </xs:sequence>

            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:simpleType name="importType">
        <xs:annotation>
            <xs:documentation>
                <![CDATA[
            The import element is restrictive.  The default (when omitted) is to include the specified dependency in
            the classloader (as a parent or URL) and (if the dependency is a module) make sure it is started
            before starting the current module.  Specifying "classes" means that the classes must be included
            in the current module's classloader but the dependency does not need to be started. (I'm not sure this
            is actually possible, but it is what is meant).  Specifying "services" means that the dependency (a module)
            must be started before the current module, but it is not included as a parent classloader.

            You probably never need to use the import element.
                ]]>
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:enumeration value="classes">
                <xs:annotation>
                    <xs:documentation>
                        The value "classes" means that the classes must be
                        included in the current module's classloader but the
                        dependency does not need to be started.
                    </xs:documentation>
                </xs:annotation>
            </xs:enumeration>
            <xs:enumeration value="services">
                <xs:annotation>
                    <xs:documentation>
                        The value "services" means that the dependency (a
                        module) must be started before the current module, but
                        it is not included as a parent classloader.
                    </xs:documentation>
                </xs:annotation>
            </xs:enumeration>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="gbeanType">
        <xs:complexContent>
            <xs:extension base="sys:abstract-serviceType">
                <xs:annotation>
                    <xs:documentation>
                        gbeanType includes all the elements defined in
                        abstract-serviceType.
                    </xs:documentation>
                </xs:annotation>

                <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element name="attribute" type="sys:attributeType">
                        <xs:annotation>
                            <xs:documentation>
                                The attribute provide the name-value pair of
                                various attributes for this GBean. The value of
                                the attributes is specified by value of this
                                element.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                    <xs:element name="xml-attribute"
                        type="sys:xml-attributeType">
                        <xs:annotation>
                            <xs:documentation>
                                The xml-attribute specifies the value of
                                particular attribute in XML format, which will
                                be interpreted by a component running in the
                                system, which convert it to single value for
                                this attribute.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                    <xs:element name="reference" type="sys:referenceType">
                        <xs:annotation>
                            <xs:documentation>
                                The "reference" element specifies the value of a
                                particular reference for this GBean in simplest
                                form. It holds the reference to the GBean that
                                matches the single pattern specified here, if no
                                value is specified it will refer to all the
                                matching GBeans.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                    <xs:element name="references" type="sys:referencesType">
                        <xs:annotation>
                            <xs:documentation>
                                The "references" element specifies the value of
                                a particular reference for this GBean matching
                                multiple pattern elements.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                    <xs:element name="xml-reference"
                        type="sys:xml-attributeType">
                        <xs:annotation>
                            <xs:documentation>
                                The xml-reference specifies the value of
                                particular reference in XML format, which will
                                be interpreted by a component running in the
                                system, which convert it to single value for
                                this reference.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                    <xs:element name="dependency" type="sys:patternType">
                        <xs:annotation>
                            <xs:documentation>
                                The element "dependency" is used to resolve
                                dependencies at GBean level. This is normally
                                only used if for some reason the GBeans within a
                                module must be started in a certain order that
                                is not reflected in the references between them.
                            </xs:documentation>
                        </xs:annotation>
                    </xs:element>
                </xs:choice>
                <xs:attribute name="name" type="xs:string" use="required">
                    <xs:annotation>
                        <xs:documentation>
                            A unique name for this GBean within this module,
                            this name will be used as a name component in
                            AbstractName, hence AbstractName will be unique
                            server wide.
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="class" type="xs:string" use="required">
                    <xs:annotation>
                        <xs:documentation>
                            The fully-qualified name of the class containing the
                            GBeanInfo for this GBean.
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="attributeType">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="name" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>
                            The name for the current attribute. This name should
                            be same as specified in GBeanInfo for this GBean.
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
                <xs:attribute name="type" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>
                            The type of the current attribute. Again this should
                            be same as one provided in GBeanInfo hence optional.
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="xml-attributeType">
        <xs:sequence>
            <xs:any namespace="##any" processContents="lax" />
        </xs:sequence>
        <xs:attribute name="name" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    The name for the current attribute. This name should be same
                    as specified in GBeanInfo for this GBean.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="referencesType">
        <xs:sequence>
            <xs:element name="pattern" type="sys:patternType" minOccurs="1"
                maxOccurs="unbounded">
                <xs:annotation>
                    <xs:documentation>
                        The pattern used for matching the referenced GBean.
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
        <xs:attribute name="name" type="xs:string">
            <xs:annotation>
                <xs:documentation>
                    The name for the current reference. This name should be same
                    as specified in GBeanInfo for this GBean.
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:complexType name="patternType">
        <xs:annotation>
            <xs:documentation>
                This group contains the components of an abstract name
            </xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:sequence>
                <xs:element name="groupId" type="xs:string" minOccurs="0">
                    <xs:annotation>
                        <xs:documentation>
                            The name for group containing module to match. By
                            default is it considered wild card '*'.
                        </xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="artifactId" type="xs:string" minOccurs="0">
                    <xs:annotation>
                        <xs:documentation>
                            The name for module in a specified group to be
                            matched.
                        </xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="version" type="xs:string" minOccurs="0">
                    <xs:annotation>
                        <xs:documentation>
                            The version number for the module formatted by dot
                            separated numbers. If no version is provided it will
                            be defaulted latest available version matching other
                            criterions.
                        </xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="module" type="xs:string" minOccurs="0">
                    <xs:annotation>
                        <xs:documentation>
                            The value specified here should match the file name
                            of the module referenced.
                        </xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="type" type="xs:string" minOccurs="0">
                    <xs:annotation>
                        <xs:documentation>
                            This element defines the type of the module to be
                            matched. The type could be 'CAR', 'JAR', EAR',
                            'WAR', etc. If no type is provided it will be
                            defaulted wild card char '*'.
                        </xs:documentation>
                    </xs:annotation>
                </xs:element>
                <xs:element name="name" type="xs:string" minOccurs="0">
                    <xs:annotation>
                        <xs:documentation>
                            The name element to identify the referenced GBean by
                            name.
                        </xs:documentation>
                    </xs:annotation>
                </xs:element>
            </xs:sequence>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="referenceType">
        <xs:complexContent>
            <xs:extension base="sys:patternType">
                <xs:annotation>
                    <xs:documentation>
                        referenceType includes all the elements defined in
                        patternType.
                    </xs:documentation>
                </xs:annotation>
                <xs:attribute name="name" type="xs:string">
                    <xs:annotation>
                        <xs:documentation>
                            The name for the current reference. This name should
                            be same as specified in GBeanInfo for this GBean.
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <!--<xs:element name="service" type="sys:serviceType"/>-->
    <!--<xs:complexType name="serviceType">-->
    <!--<xs:sequence>-->
    <!--<xs:element name="dependency" type="sys:artifactType" minOccurs="0" maxOccurs="unbounded"/>-->
    <!--</xs:sequence>-->
    <!--</xs:complexType>-->

</xs:schema>
