<?xml version="1.0" encoding="UTF-8"?>
<!--
  _=_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_=
  Repose
  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
  Copyright (C) 2010 - 2015 Rackspace US, Inc.
  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  =_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_=_
  -->


<xs:schema xmlns:rms="http://docs.openrepose.org/repose/response-messaging/v1.0" xmlns:html="http://www.w3.org/1999/xhtml"
           xmlns:xerces="http://xerces.apache.org"
           xmlns:saxon="http://saxon.sf.net/"
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified"
           targetNamespace="http://docs.openrepose.org/repose/response-messaging/v1.0">

    <xs:element name="response-messaging" type="rms:ResponseMessagingConfiguration"/>

    <!-- Enumerations -->
    <xs:simpleType name="overwrite-type">
        <xs:annotation>
            <xs:documentation>
                <html:p>
                    Overwrite type specifies if RMS should always overwrite the response body or only
                    if the body is empty. Possible values are: ALWAYS, IF_EMPTY.
                    The overwrite attribute is optional and defaults to "IF_EMPTY" if not specified.
                </html:p>
            </xs:documentation>
        </xs:annotation>

        <xs:restriction base="xs:string">
            <xs:enumeration value="ALWAYS">
                <xs:annotation>
                    <xs:documentation>
                        <html:p>
                            If this is specified, response body will always be overwritten by response messaging
                            filter.
                        </html:p>
                    </xs:documentation>
                </xs:annotation>
            </xs:enumeration>
            <xs:enumeration value="IF_EMPTY">
                <xs:annotation>
                    <xs:documentation>
                        <html:p>
                            If this is specified, response body will be overwritten by response messaging
                            filter only if response body is empty.
                        </html:p>
                    </xs:documentation>
                </xs:annotation>
            </xs:enumeration>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="ResponseMessagingConfiguration">
        <xs:annotation>
            <xs:documentation>
                <html:p>
                    List of status codes, which allow Repose to intercept the response and return
                    a pre-configured message body.
                </html:p>
            </xs:documentation>
        </xs:annotation>

        <xs:sequence>
            <xs:element name="status-code" type="rms:StatusCodeMatcher" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:assert vc:minVersion="1.1" test="count(distinct-values(rms:status-code/@id)) = count(rms:status-code/@id)"
                   xerces:message="Status code ids must be unique"
                   saxon:message="Status code ids must be unique"/>
    </xs:complexType>

    <xs:complexType name="StatusCodeMatcher">
        <xs:annotation>
            <xs:documentation>
                <html:p>
                    Describes a status code that will be handled. The actual status code will be captured in
                    code-regex attribute (can be specified as a regular expression). Please refer to
                    <html:a href="http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html">Java
                        Regular Expression Api
                    </html:a>
                    for more information on regular expression syntax.
                    Id attribute must be unique.
                </html:p>
            </xs:documentation>
        </xs:annotation>


        <xs:sequence>
            <xs:element name="message" type="rms:Message" minOccurs="1" maxOccurs="unbounded"/>
        </xs:sequence>


        <xs:attribute name="id" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>
                    <html:p>
                        ID of the status code rewrite. Must be unique.
                    </html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:attribute name="code-regex" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>
                    <html:p>
                        Defines a regular expression that will be used to match status codes
                        against this declaration. Please refer to
                        <html:a href="http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html">Java
                            Regular Expression Api
                        </html:a>
                        for more information on regular expression syntax.
                    </html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:attribute name="overwrite" type="rms:overwrite-type" use="optional" default="IF_EMPTY">
            <xs:annotation>
                <xs:documentation>
                    <html:p>
                        Tells Repose what logic to use when determining whether or not to overwrite the response body
                        from the origin service with the configured message. If the overwrite value is set to
                        "IF_EMPTY" and the body is not empty Repose will not modify the response body. In all other
                        cases, Repose will overwrite the response body with the RMS message.
                    </html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>


    </xs:complexType>

    <xs:complexType name="Message">
        <xs:annotation>
            <xs:documentation>
                <html:p>
                    Defines a message that will be used when matching the parent status code.
                    Can either be linked via href attribute or defined in the message element.
                    XML messages should be included in CDATA inline.

                    The message body can contain template parameters that will be replaced by
                    request/response or other server values when a status code is matched.

                    The template parameters available for use in the message body are the same
                    as the parameters used by the Repose HTTP Logging Filter.
                </html:p>
            </xs:documentation>
        </xs:annotation>

        <xs:simpleContent>
            <xs:extension base="xs:string">

                <xs:attribute name="media-type" type="xs:string" use="required">
                    <xs:annotation>
                        <xs:documentation>
                            <html:p>
                                Matches the content type of the message coming from the origin service.
                                Allows different message formats for different response types.
                                Configuring a media-type of */* will configure that message object as a catch-all.
                            </html:p>
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>

                <xs:attribute name="content-type" type="xs:string" use="optional" default="text/plain">
                    <xs:annotation>
                        <xs:documentation>
                            <html:p>
                                Defines the content type on the response message returned to the client.
                            </html:p>
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>

                <xs:attribute name="href" type="xs:anyURI" use="optional">
                    <xs:annotation>
                        <xs:documentation>
                            <html:p>
                                Specifies a location to an external file which contains the message to be sent.
                                If the message element has a value and the href attribute is configured,
                                Response Messaging Service will use what is configured with href to send the message.
                                If the file to which an href attribute of a message element is pointed is modified,
                                Response Messaging Service will need to reload the configurations to
                                guarantee that the changes will appear in the responses.
                                Any changes to the config file itself will cause a configuration reload.
                            </html:p>
                        </xs:documentation>
                    </xs:annotation>
                </xs:attribute>

                <!-- Commenting out asserts as they are breaking our Jmeter regression tests -->
                <xs:assert vc:minVersion="1.1" test="if (text()) then not (@href) else true()"
                           xerces:message="Cannot define message inline and reference to external message file"
                           saxon:message="Cannot define message inline and reference to external message file"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
</xs:schema>
