<?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 xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns="http://ofbiz.apache.org/Widget-Screen" targetNamespace="http://ofbiz.apache.org/Widget-Screen">
    <xs:include schemaLocation="http://ofbiz.apache.org/dtds/widget-common.xsd" />
    <xs:element name="screens">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" ref="screen" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="screen">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="section" />
            </xs:sequence>
            <xs:attribute type="xs:string" name="name" use="required" />
            <xs:attribute type="xs:string" name="transaction-timeout" use="optional">
                <xs:annotation>
                    <xs:documentation>Transaction timeout in seconds</xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute name="use-transaction" type="xs:boolean" default="true"/>
            <xs:attribute name="use-cache" type="xs:boolean" default="false"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="section" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="condition" type="ScreenConditionRootType" minOccurs="0" />
                <xs:element minOccurs="0" ref="actions" />
                <xs:element minOccurs="0" ref="widgets" />
                <xs:element minOccurs="0" ref="fail-widgets" />
            </xs:sequence>
            <xs:attribute type="xs:string" name="name" />
        </xs:complexType>
    </xs:element>

    <!-- ================ CONDITIONS ================ -->

    <xs:complexType name="ScreenConditionRootType">
        <xs:choice>
            <xs:element ref="and" />
            <xs:element ref="or" />
            <xs:element ref="xor" />
            <xs:element ref="not" />
            <xs:element ref="if-service-permission" />
            <xs:element ref="if-has-permission" />
            <xs:element ref="if-entity-permission" />
            <xs:element ref="if-validate-method" />
            <xs:element ref="if-compare" />
            <xs:element ref="if-compare-field" />
            <xs:element ref="if-regexp" />
            <xs:element ref="if-empty" />
            <xs:element ref="if-empty-section" />
        </xs:choice>
    </xs:complexType>

    <xs:element name="if-empty-section" substitutionGroup="AllConditionals">
        <xs:complexType>
            <xs:attribute type="xs:string" name="section-name" use="required" />
        </xs:complexType>
    </xs:element>

    <!-- ================ ACTIONS ================ -->

    <xs:element name="actions">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllActions" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="service" substitutionGroup="AllActions">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="field-map" />
            </xs:sequence>
            <xs:attribute type="xs:string" name="service-name" use="required" />
            <xs:attribute type="xs:string" name="result-map" />
            <xs:attribute type="xs:string" name="auto-field-map" default="true">
                <xs:annotation>
                    <xs:documentation>This can be "true", "false" or the name of a Map in the context to use as the source Map for the service context.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
    <xs:element name="entity-and" substitutionGroup="AllActions">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" ref="field-map" />
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="select-field" />
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="order-by" />
                <xs:choice minOccurs="0">
                    <xs:element ref="limit-range" />
                    <xs:element ref="limit-view" />
                    <xs:element ref="use-iterator" />
                </xs:choice>
            </xs:sequence>
            <xs:attribute type="xs:string" name="entity-name" use="required" />
            <xs:attribute name="use-cache" type="xs:boolean" default="false"/>
            <xs:attribute name="filter-by-date" type="xs:boolean" default="false"/>
            <xs:attribute type="xs:string" name="list" use="required" />
            <xs:attribute name="result-set-type" default="scroll">
                <xs:simpleType>
                    <xs:restriction base="xs:token">
                        <xs:enumeration value="forward" />
                        <xs:enumeration value="scroll" />
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
    <xs:element name="entity-condition" substitutionGroup="AllActions">
        <xs:complexType>
            <xs:sequence>
                <xs:choice minOccurs="0">
                    <xs:element ref="condition-expr" />
                    <xs:element ref="condition-list" />
                    <xs:element ref="condition-object" />
                </xs:choice>
                <xs:element minOccurs="0" ref="having-condition-list" />
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="select-field" />
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="order-by" />
                <xs:choice minOccurs="0">
                    <xs:element ref="limit-range" />
                    <xs:element ref="limit-view" />
                    <xs:element ref="use-iterator" />
                </xs:choice>
            </xs:sequence>
            <xs:attribute type="xs:string" name="entity-name" use="required" />
            <xs:attribute name="use-cache" type="xs:boolean" default="false"/>
            <xs:attribute name="filter-by-date" default="false">
                <xs:simpleType>
                    <xs:restriction base="xs:token">
                        <xs:enumeration value="true" />
                        <xs:enumeration value="false" />
                        <xs:enumeration value="by-name" />
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="distinct" type="xs:boolean" default="false"/>
            <xs:attribute type="xs:string" name="delegator-name" />
            <xs:attribute type="xs:string" name="list" use="required" />
            <xs:attribute name="result-set-type" default="scroll">
                <xs:simpleType>
                    <xs:restriction base="xs:token">
                        <xs:enumeration value="forward" />
                        <xs:enumeration value="scroll" />
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>

    <!-- ================ WIDGETS ================ -->

    <xs:element name="AllWidgets" abstract="true" />
    <xs:element name="widgets">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="fail-widgets">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="column-container" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="1" maxOccurs="unbounded" name="column">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets" />
                        </xs:sequence>
                        <xs:attribute type="xs:string" name="id" />
                        <xs:attribute type="xs:string" name="style" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute type="xs:string" name="id" />
            <xs:attribute type="xs:string" name="style" />
        </xs:complexType>
    </xs:element>

    <xs:element name="container" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets" />
            </xs:sequence>
            <xs:attribute type="xs:string" name="id" />
            <xs:attribute type="xs:string" name="style" />
            <xs:attribute type="xs:string" name="auto-update-target">
                <xs:annotation>
                    <xs:documentation>The URL to be called for periodic asynchronous area updates.
                        Some widget rendering environments support asynchronous updates.
                    </xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute type="xs:string" name="type">
                <xs:annotation>
                    <xs:documentation>With the type it is possible to render different containers
                        than div like section.
                    </xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute type="xs:string" name="auto-update-interval">
                <xs:annotation>
                    <xs:documentation>The auto-update interval, in seconds.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
    <xs:element name="horizontal-separator" substitutionGroup="AllWidgets">
        <xs:complexType mixed="true">
            <xs:attribute type="xs:string" name="id" />
            <xs:attribute type="xs:string" name="name" />
            <xs:attribute type="xs:string" name="style" />
        </xs:complexType>
    </xs:element>
    <xs:element name="image" substitutionGroup="AllWidgets">
        <xs:complexType mixed="true">
            <xs:attribute type="xs:string" name="src" />
            <xs:attribute type="xs:string" name="id" />
            <xs:attribute type="xs:string" name="style" />
            <xs:attribute type="xs:string" name="width" />
            <xs:attribute type="xs:string" name="height" />
            <xs:attribute type="xs:string" name="border" />
            <xs:attribute type="xs:string" name="alt" />
            <xs:attribute name="url-mode" default="content">
                <xs:simpleType>
                    <xs:restriction base="xs:token">
                        <xs:enumeration value="ofbiz" />
                        <xs:enumeration value="content" />
                        <xs:enumeration value="raw" />
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
    <xs:element name="label" substitutionGroup="AllWidgets">
        <xs:complexType mixed="true">
            <xs:attribute type="xs:string" name="text" />
            <xs:attribute type="xs:string" name="id" />
            <xs:attribute type="xs:string" name="style" />
        </xs:complexType>
    </xs:element>
    <xs:element name="link" type="link" substitutionGroup="AllWidgets"/>

    <xs:element name="screenlet" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets" />
            </xs:sequence>
            <xs:attribute type="xs:string" name="title">
                <xs:annotation>
                    <xs:documentation>Title text to be placed in the screenlet title bar.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute name="id" type="xs:string" />
            <xs:attribute name="name" type="xs:string" />
            <xs:attribute name="collapsible" type="xs:boolean" default="false"/>
            <xs:attribute name="initially-collapsed" type="xs:string" default="false">
                <xs:annotation>
                    <xs:documentation>When set to true, screenlet will be collapsed initially. Can be an expanded string to get the value from a variable. Defaults to false.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute name="save-collapsed" type="xs:boolean" default="true">
                <xs:annotation>
                    <xs:documentation>When set to true, screenlet collapse status is saved as user preference. Defaults to true.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute name="padded" type="xs:boolean" default="true">
                <xs:annotation>
                    <xs:documentation>When set to true, screenlet content will be padded. Defaults to true.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute type="xs:string" name="navigation-menu-name">
                <xs:annotation>
                    <xs:documentation>Name of the screenlet include-menu sub element that will be used for screenlet navigation.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute type="xs:string" name="navigation-form-name">
                <xs:annotation>
                    <xs:documentation>Name of the screenlet include-form sub element that will be used for screenlet navigation. The form's pagination menu will be included in the screenlet title bar.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute type="xs:string" name="tab-menu-name">
                <xs:annotation>
                    <xs:documentation>Name of the screenlet include-menu sub element that will be used for the screenlet tab bar.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
        </xs:complexType>
    </xs:element>

    <!-- ================ WIDGETS - Includers ================ -->

    <xs:element name="content" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:attribute type="xs:string" name="content-id" />
            <xs:attribute type="xs:string" name="dataresource-id" />
            <xs:attribute type="xs:string" name="edit-request" />
            <xs:attribute type="xs:string" name="edit-container-style" default="editWrapper" />
            <xs:attribute type="xs:string" name="enable-edit-name" default="enableEdit" />
            <xs:attribute name="xml-escape" type="xs:boolean" default="false"/>
            <xs:attribute type="xs:string" name="width">
                <xs:annotation>
                    <xs:documentation>Used if non-html content to specify width of iframe.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute type="xs:string" name="height">
                <xs:annotation>
                    <xs:documentation>Used if non-html content to specify height of iframe.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute type="xs:string" name="border">
                <xs:annotation>
                    <xs:documentation>Used if non-html content to specify border of iframe.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
    <xs:element name="decorator-screen" substitutionGroup="AllWidgets">
        <xs:annotation>
            <xs:documentation>
                Renders the named screen and includes the children of this elements at the point where it finds the decorator-section-include tag.
                Note that because of the recursive nature of this tag the share-scope attribute is not availalbe.
            </xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" ref="decorator-section" />
            </xs:sequence>
            <xs:attribute type="xs:string" name="name" use="required" />
            <xs:attribute type="xs:string" name="location" />
        </xs:complexType>
    </xs:element>
    <xs:element name="decorator-section">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets" />
            </xs:sequence>
            <xs:attribute type="xs:string" name="name" use="required" />
        </xs:complexType>
    </xs:element>
    <xs:element name="decorator-section-include" substitutionGroup="AllWidgets">
        <xs:annotation>
            <xs:documentation>This is just a place holder to tell the renderer to include the parent container's contents at this point.</xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:attribute type="xs:string" name="name" use="required" />
        </xs:complexType>
    </xs:element>
    <xs:element name="include-form" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:attribute type="xs:string" name="name" use="required" />
            <xs:attribute type="xs:string" name="location" use="required" />
            <xs:attribute name="share-scope" type="xs:boolean" default="false"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="include-grid" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:attribute type="xs:string" name="name" use="required" />
            <xs:attribute type="xs:string" name="location" use="required" />
            <xs:attribute name="share-scope" type="xs:boolean" default="false"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="include-menu" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:attribute type="xs:string" name="name" use="required" />
            <xs:attribute type="xs:string" name="location" use="required" />
        </xs:complexType>
    </xs:element>
    <xs:element name="include-screen" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:attribute type="xs:string" name="name" use="required" />
            <xs:attribute type="xs:string" name="location" />
            <xs:attribute name="share-scope" type="xs:boolean" default="false"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="include-tree" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:attribute type="xs:string" name="name" use="required" />
            <xs:attribute type="xs:string" name="location" use="required" />
            <xs:attribute name="share-scope" type="xs:boolean" default="false"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="include-portal-page" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:attribute type="xs:string" name="id" />
            <xs:attribute name="conf-mode" type="xs:boolean" default="false">
                <xs:annotation>
                    <xs:documentation>Show the portal in configuration mode.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
            <xs:attribute name="use-private" type="xs:boolean" default="true">
                <xs:annotation>
                    <xs:documentation>If a derived private PortalPage exists for the actual UserLogin than show the private PortalPage instead of the original.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
        </xs:complexType>
    </xs:element>

    <xs:element name="sub-content" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:attribute type="xs:string" name="content-id" use="required" />
            <xs:attribute type="xs:string" name="map-key" use="required" />
            <xs:attribute type="xs:string" name="edit-request" />
            <xs:attribute type="xs:string" name="edit-container-style" default="editWrapper" />
            <xs:attribute type="xs:string" name="enable-edit-name" default="enableEdit" />
            <xs:attribute name="xml-escape" type="xs:boolean" default="false"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="iterate-section" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="section" />
            </xs:sequence>
            <xs:attribute type="xs:string" name="entry" use="required" />
            <xs:attribute type="xs:string" name="list" use="required" />
            <xs:attribute type="xs:string" name="key" />
            <xs:attribute type="xs:string" name="view-size" />
            <xs:attribute type="xs:string" name="paginate-target" />
            <xs:attribute type="xs:string" name="paginate" default="${paginate}">
                <xs:annotation>
                    <xs:documentation>Indicate if this section is paginated or not, true by default.</xs:documentation>
                </xs:annotation>
            </xs:attribute>
        </xs:complexType>
    </xs:element>


    <!-- ============== Platform Specific Elements =============== -->
    <xs:element name="platform-specific" substitutionGroup="AllWidgets">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" ref="html" />
                <xs:element minOccurs="0" ref="swing" />
                <xs:element minOccurs="0" ref="xsl-fo" />
                <xs:element minOccurs="0" ref="xml" />
                <xs:element minOccurs="0" ref="text" />
                <xs:element minOccurs="0" ref="csv" />
                <xs:element minOccurs="0" ref="xls" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <!-- ============== HTML Specific Elements =============== -->
    <xs:element name="HtmlWidgets" abstract="true" />
    <xs:element name="html">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="xsl-fo">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="xml">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="xls">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="text">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="csv">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="html-template" substitutionGroup="HtmlWidgets">
        <xs:complexType>
            <xs:attributeGroup ref="attlist.html-template" />
        </xs:complexType>
    </xs:element>
    <xs:attributeGroup name="attlist.html-template">
        <xs:attribute type="xs:string" name="location" use="required" />
    </xs:attributeGroup>
    <xs:element name="html-template-decorator" substitutionGroup="HtmlWidgets">
        <xs:annotation>
            <xs:documentation>
                We don't really want to encourage the use of the html-template-decorator, should be done on the screen level.
                To include the sections in the decorator template just use the "render(sectionName)" method "sections" object, FTL example: ${sections.render("main")}.
                For more
                efficient use the sections.render(sectionName, writer) method should be used, in FTL this would be in a transform or something.
            </xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" ref="html-template-decorator-section" />
            </xs:sequence>
            <xs:attribute type="xs:string" name="location" use="required" />
        </xs:complexType>
    </xs:element>
    <xs:element name="html-template-decorator-section">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets" />
            </xs:sequence>
            <xs:attribute type="xs:string" name="name" use="required" />
        </xs:complexType>
    </xs:element>
    <!-- ============== Swing Specific Elements =============== -->
    <xs:element name="swing">
        <xs:complexType />
    </xs:element>
</xs:schema>
