<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
    xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
    datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
    xmlns:amplee="http://purl.oclc.org/DEFUZE/amplee" xmlns:dc="http://purl.org/dc/elements/1.1/">

    <dc:title>RELAX NG schema of amplee's configuration scheme</dc:title>
    <dc:author>Sylvain Hellegouarch</dc:author>

    <start>
        <ref name="ampleeConfig"/>
    </start>

    <define name="ampleeConfig">
        <element name="amplee:config">
            <ref name="ampleeStore"/>
        </element>
    </define>

    <define name="ampleeStore">
        <element name="amplee:store">
            <interleave>
                <!-- the amplee:lock element, if present, means that amplee will use thread locking on the store object -->
                <optional>
                    <element name="amplee:lock">
                        <empty/>
                    </element>
                </optional>
                <oneOrMore>
                    <choice>
                        <ref name="ampleeFilesystemStorage"/>
                        <ref name="ampleeSubversionStorage"/>
                        <ref name="ampleeDejavuStorage"/>
                        <ref name="ampleeZODBStorage"/>
                        <ref name="ampleeTarStorage"/>
                        <ref name="ampleeS3Storage"/>
                    </choice>
                </oneOrMore>
                <zeroOrMore>
                    <ref name="ampleeCache"/>
                </zeroOrMore>
            </interleave>
        </element>
    </define>

    <define name="ampleeStorageAttributes">
        <attribute name="target">
            <choice>
                <value>member</value>
                <value>media</value>
            </choice>
        </attribute>
        <attribute name="type">
            <choice>
                <value>filesystem</value>
                <value>subversion</value>
                <value>zodb</value>
                <value>s3</value>
                <value>dejavu</value>
                <value>tar</value>
            </choice>
        </attribute>
    </define>

    <define name="ampleeEncoding">
        <element name="amplee:encoding">
            <text/>
        </element>
    </define>

    <define name="ampleeBasePath">
        <element name="amplee:basepath">
            <text/>
        </element>
    </define>

    <define name="ampleeFilesystemStorage">
        <element name="amplee:storage">
            <ref name="ampleeStorageAttributes"/>
            <interleave>
                <ref name="ampleeEncoding"/>
                <ref name="ampleeBasePath"/>
                <optional>
                    <ref name="ampleeCacheRef"/>
                </optional>
            </interleave>
        </element>
    </define>

    <define name="ampleeSubversionStorage">
        <element name="amplee:storage">
            <ref name="ampleeStorageAttributes"/>
            <interleave>
                <element name="amplee:repository-uri">
                    <text/>
                </element>
                <element name="amplee:workingcopy-path">
                    <text/>
                </element>
                <element name="amplee:username">
                    <text/>
                </element>
                <element name="amplee:password">
                    <text/>
                </element>
                <optional>
                    <ref name="ampleeCacheRef"/>
                </optional>
            </interleave>
        </element>
    </define>

    <define name="ampleeDejavuStorage">
        <element name="amplee:storage">
            <ref name="ampleeStorageAttributes"/>
            <interleave>
                <element name="amplee:dbtype">
                    <text/>
                </element>
                <element name="amplee:capitalize">
                    <empty/>
                </element>
                <element name="amplee:dbconf">
                    <text/>
                </element>
                <optional>
                    <ref name="ampleeCacheRef"/>
                </optional>
            </interleave>
        </element>
    </define>

    <define name="ampleeTarStorage">
        <element name="amplee:storage">
            <ref name="ampleeStorageAttributes"/>
            <interleave>
                <ref name="ampleeEncoding"/>
                <ref name="ampleeBasePath"/>
                <element name="amplee:compression">
                    <choice>
                        <value>gz</value>
                        <value>bz2</value>
                        <value/>
                    </choice>
                </element>
            </interleave>
        </element>
    </define>

    <define name="ampleeS3Storage">
        <element name="amplee:storage">
            <ref name="ampleeStorageAttributes"/>
            <interleave>
                <optional>
                    <choice>
                        <group>
                            <element name="amplee:public-key">
                                <text/>
                            </element>
                            <element name="amplee:private-key">
                                <text/>
                            </element>
                        </group>
                        <group>
                            <element name="amplee:aws-key-lookup">
                                <element name="amplee:module">
                                    <text/>
                                </element>
                                <element name="amplee:callable">
                                    <text/>
                                </element>
                                <element name="amplee:aws-keys-path">
                                    <text/>
                                </element>
                            </element>
                        </group>
                    </choice>
                </optional>
                <element name="amplee:bucket-prefix">
                    <text/>
                </element>
                <ref name="ampleeEncoding"/>
                <optional>
                    <ref name="ampleeCacheRef"/>
                </optional>
            </interleave>
        </element>
    </define>

    <define name="ampleeZODBStorage">
        <element name="amplee:storage">
            <ref name="ampleeStorageAttributes"/>
            <interleave>
                <element name="amplee:fstype">
                    <choice>
                        <value>filestorage</value>
                        <value>clientstorage</value>
                    </choice>
                </element>
                <element name="amplee:fspath">
                    <text/>
                </element>
                <element name="amplee:address">
                    <text/>
                </element>
                <element name="amplee:top-level-node">
                    <text/>
                </element>
                <optional>
                    <ref name="ampleeCacheRef"/>
                </optional>
            </interleave>
        </element>
    </define>

    <define name="ampleeCacheRef">
        <element name="amplee:cache">
            <!-- the ref value matches the id attribute of one of the the /config/store/cache elements -->
            <attribute name="ref">
                <text/>
            </attribute>
        </element>
    </define>

    <define name="ampleeCache">
        <element name="amplee:cache">
            <attribute name="id">
                <text/>
            </attribute>
            <element name="amplee:servers">
                <element name="amplee:server">
                    <attribute name="ip">
                        <text/>
                    </attribute>
                    <attribute name="port">
                        <data type="nonNegativeInteger"></data>
                    </attribute>
                </element>
            </element>
        </element>
    </define>

</grammar>