<schema
  xmlns='http://www.w3.org/2001/XMLSchema'
  targetNamespace='http://www.cygnets.co.uk/schemas/adl-0.xsd'
  xmlns:adl='http://www.cygnets.co.uk/schemas/adl-0.xsd'
  xmlns:html='http://www.w3.org/1999/xhtml'>

  <!--  ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  -->
  <!--						    											                                  -->
  <!--	adl-0.xsd    			    										                            -->
  <!--																		                                    -->
  <!--	Purpose:															                                -->
  <!--	XML Schema for Application Description Language. Note that this       -->
  <!--        is experimental; the DTD is still normative at this stage       -->
  <!--        This revision autoconverted using dtd2xsd.pl from               -->
  <!--        adl-0.dtd revision 1.2                                          -->
  <!--																		                                    -->
  <!--	Author:		Simon Brooke <simon@cygnets.co.uk>			  	                -->
  <!--	Created:	9th January 2008										                        -->
  <!--  $Revision: 1.2 $                                                      -->
  <!--	Copyright:	(c) 2008 Cygnet Solutions Ltd						                  -->
  <!--      							      									                            -->
  <!--  ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::  -->

  <!-- the application that the document describes: required top level element -->
  <element name='application'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
        <element ref='adl:content' minOccurs='0' maxOccurs='1'/>
        <element ref='adl:definition' minOccurs='0' maxOccurs='unbounded'/>
        <element ref='adl:group' minOccurs='0' maxOccurs='unbounded'/>
        <element ref='adl:entity' minOccurs='0' maxOccurs='unbounded'/>
      </sequence>
      <attribute name='name' type='string' use='required'/>
      <attribute name='version' type='string' use='optional'/>
    </complexType>
  </element>

  <!-- 
	the definition of a defined type. At this stage a defined type is either
	a string		in which case it must have size and pattern, or
	a scalar		in which case it must have minimum and/or maximum
	pattern must be a regular expression as interpreted by org.apache.regexp.RE
	minimum and maximum must be of appropriate format for the datatype specified.
	Validation may be done client-side and/or server-side at application layer
	and/or server side at database layer.

  name:     the name of this definition
  type:     the simple type on which this defined type is based
  size:     the data size of this defined type
  pattern:  a regular expression which values for this type must match
  minimum:  the minimum value for this type (if base type is scalar)
  maximum:  the maximum value for this type (if base type is scalar)
  -->
  <element name='definition'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
        <element ref='adl:help' minOccurs='0' maxOccurs='unbounded'/>
      </sequence>
      <attribute name='name' type='string' use='required'/>
      <attribute name='type' use='required'>
        <simpleType>
          <restriction base='string'>
            <enumeration value='string'/>
            <enumeration value='integer'/>
            <enumeration value='real'/>
            <enumeration value='money'/>
            <enumeration value='date'/>
            <enumeration value='time'/>
            <enumeration value='timestamp'/>
          </restriction>
        </simpleType>
      </attribute>
      <attribute name='size' type='string' use='optional'/>
      <attribute name='pattern' type='string' use='optional'/>
      <attribute name='minimum' type='string' use='optional'/>
      <attribute name='maximum' type='string' use='optional'/>
    </complexType>
  </element>

  <!-- 
  a group of people with similar permissions to one another 
  name: the name of this group
  parent: the name of a group of which this group is subset
  -->
  <element name='group'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
      </sequence>
      <attribute name='name' type='string' use='required'/>
      <attribute name='parent' type='string' use='optional'/>
    </complexType>
  </element>

  <!-- 
	an entity which has properties and relationships; maps onto a database
	table or a Java serialisable class - or, of course, various other things
  
  name:         obviously, the name of this entity
  natural-key:  if present, the name of a property of this entity which forms
                a natural primary key [NOTE: Only partly implemented. NOTE: much of
                the present implementation assumes all primary keys will be 
                integers. This needs to be fixed!]
-->
  <element name='entity'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
        <element ref='adl:content' minOccurs='0' maxOccurs='1'/>
        <element ref='adl:property' minOccurs='0' maxOccurs='unbounded'/>
        <element ref='adl:permission' minOccurs='0' maxOccurs='unbounded'/>
        <choice minOccurs='0' maxOccurs='unbounded'>
          <element ref='adl:form'/>
          <element ref='adl:page'/>
          <element ref='adl:list'/>
        </choice>
      </sequence>
      <attribute name='name' type='string' use='required'/>
      <attribute name='natural-key' type='string' use='optional'/>
    </complexType>
  </element>

  <!-- 
  contains documentation on the element which immediately contains it. TODO:
  should HTML markup within a documentation element be allowed? If so, are
  there restrictions?
-->
  <element name='documentation'>
    <complexType mixed='true'>
    </complexType>
  </element>

  <!-- 
	a property (field) of an entity (table) 
	
	name:			  the name of this property.
	type:			  the type of this property.
	default:		the default value of this property. There will probably be 
					    magic values of this!
	definition:	name of the definition to use, it type = 'defined'.
	distinct:		distinct='system' required that every value in the system 
					    will be distinct (i.e. natural primary key);
					    distinct='user' implies that the value may be used by users 
					    in distinguishing entities even if values are not formally 
					    unique; 
					    distinct='all' implies that the values are formally unique 
					    /and/ are user friendly (NOTE: not implemented).
	entity:			if type='entity', the name of the entity this property is 
					    a foreign key link to.
              if type='list', the name of the entity that has a foreign 
              key link to this entity
  farkey:     if type='list', the name of farside key in the listed 
              entity
	required:		whether this propery is required (i.e. 'not null').
	size: 			fieldwidth of the property if specified.
  concrete:   if set to 'false', this property is not stored in the 
              database but must be computed (manually written code must
              be provided to support this)
-->
  <element name='property'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
        <element ref='adl:permission' minOccurs='0' maxOccurs='unbounded'/>
        <element ref='adl:option' minOccurs='0' maxOccurs='unbounded'/>
        <element ref='adl:prompt' minOccurs='0' maxOccurs='unbounded'/>
        <element ref='adl:help' minOccurs='0' maxOccurs='unbounded'/>
        <element ref='adl:ifmissing' minOccurs='0' maxOccurs='unbounded'/>
      </sequence>
      <attribute name='name' type='string' use='required'/>
      <attribute name='type' use='required'>
        <simpleType>
          <restriction base='string'>
            <enumeration value='entity'/>
            <enumeration value='link'/>
            <enumeration value='list'/>
            <enumeration value='defined'/>
            <enumeration value='string'/>
            <enumeration value='integer'/>
            <enumeration value='real'/>
            <enumeration value='money'/>
            <enumeration value='date'/>
            <enumeration value='time'/>
            <enumeration value='timestamp'/>
            <enumeration value='boolean'/>
            <enumeration value='text'/>
          </restriction>
        </simpleType>
      </attribute>
      <attribute name='default' type='string' use='optional'/>
      <attribute name='definition' type='string' use='optional'/>
      <attribute name='distinct' use='optional'>
        <simpleType>
          <restriction base='string'>
            <enumeration value='none'/>
            <enumeration value='all'/>
            <enumeration value='user'/>
            <enumeration value='system'/>
          </restriction>
        </simpleType>
      </attribute>
      <attribute name='entity' type='string' use='optional'/>
      <attribute name='farkey' type='string' use='optional'/>
      <attribute name='required' use='optional'>
        <simpleType>
          <restriction base='string'>
            <enumeration value='true'/>
            <enumeration value='false'/>
          </restriction>
        </simpleType>
      </attribute>
      <attribute name='size' type='string' use='optional'/>
      <attribute name='concrete' use='optional'>
        <simpleType>
          <restriction base='string'>
            <enumeration value='true'/>
            <enumeration value='false'/>
          </restriction>
        </simpleType>
      </attribute>
    </complexType>
  </element>

  <!-- 
	one of an explicit list of optional values a property may have 
	NOTE: whether options get encoded at application layer or at database layer 
	is UNDEFINED; either behaviour is correct. If at database layer it's also 
	UNDEFINED whether they're encoded as a single reference data table or as 
	separate reference data tables for each property.
-->
  <element name='option'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
        <element ref='adl:prompt' minOccurs='0' maxOccurs='unbounded'/>
      </sequence>
      <attribute name='value' type='string' use='optional'/>
    </complexType>
  </element>

  <!-- 
	permissions policy on an entity, a page, form, list or field 
	
	group: 			the group to which permission is granted
	permission:		the permission which is granted to that group
-->
  <element name='permission'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
      </sequence>
      <attribute name='group' type='string' use='required'/>
      <attribute name='permission' use='required'>
        <simpleType>
          <restriction base='string'>
            <enumeration value='none'/>
            <enumeration value='read'/>
            <enumeration value='insert'/>
            <enumeration value='noedit'/>
            <enumeration value='edit'/>
            <enumeration value='all'/>
          </restriction>
        </simpleType>
      </attribute>
    </complexType>
  </element>

  <!--
  pragmatic advice to generators of lists and forms, in the form of 
  name/value pairs which may contain anything. Over time some pragmas
  will become 'well known', but the whole point of having a pragma
  architecture is that it is extensible.
-->
  <element name='pragma'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
      </sequence>
      <attribute name='name' type='string' use='required'/>
      <attribute name='value' type='string' use='required'/>
    </complexType>
  </element>

  <!-- 
	a prompt for a property or field; used as the prompt text for a widget 
	which edits it. Typically there will be only one of these per property
  per locale; if there are more than one all those matching the locale may
  be concatenated, or just one may be used.
	
	prompt:			the prompt to use
	locale:			the locale in which to prefer this prompt	
-->
  <element name='prompt'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
      </sequence>
      <attribute name='prompt' type='string' use='required'/>
      <attribute name='locale' type='string' use='required'/>
    </complexType>
  </element>

  <!-- 
	helptext about a property of an entity, or a field of a page, form or 
	list, or a definition. Typically there will be only one of these per property
  per locale; if there are more than one all those matching the locale may
  be concatenated, or just one may be used.

	locale:			the locale in which to prefer this prompt	
-->
  <element name='help'>
    <complexType mixed='true'>
      <attribute name='locale' type='string' use='required'/>
    </complexType>
  </element>

  <!--
  helpful text to be shown if a property value is missing, typically when 
  a form is submitted. Typically there will be only one of these per property
  per locale; if there are more than one all those matching the locale may
  be concatenated, or just one may be used. Later there may be more sophisticated
  behaviour here.
-->
  <element name='ifmissing'>
    <complexType mixed='true'>
      <attribute name='locale' type='string' use='required'/>
    </complexType>
  </element>

  <!-- a form through which an entity may be added or edited -->
  <element name='form'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
        <choice minOccurs='0' maxOccurs='unbounded'>
          <element ref='adl:head'/>
          <element ref='adl:top'/>
          <element ref='adl:foot'/>
          <element ref='adl:field'/>
          <element ref='adl:fieldgroup'/>
          <element ref='adl:auxlist'/>
          <element ref='adl:verb'/>
          <element ref='adl:permission'/>
          <element ref='adl:pragma'/>
        </choice>
      </sequence>
      <attribute name='name' type='string' use='required'/>
      <attribute name='properties' use='required'>
        <simpleType>
          <restriction base='string'>
            <enumeration value='all'/>
            <enumeration value='user-distict'/>
            <enumeration value='listed'/>
          </restriction>
        </simpleType>
      </attribute>
    </complexType>
  </element>

  <!-- a page on which an entity may be displayed -->
  <element name='page'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
        <choice minOccurs='0' maxOccurs='unbounded'>
          <element ref='adl:head'/>
          <element ref='adl:top'/>
          <element ref='adl:foot'/>
          <element ref='adl:field'/>
          <element ref='adl:fieldgroup'/>
          <element ref='adl:auxlist'/>
          <element ref='adl:verb'/>
          <element ref='adl:permission'/>
          <element ref='adl:pragma'/>
        </choice>
      </sequence>
      <attribute name='name' type='string' use='required'/>
      <attribute name='properties' use='required'>
        <simpleType>
          <restriction base='string'>
            <enumeration value='all'/>
            <enumeration value='user-distict'/>
            <enumeration value='listed'/>
          </restriction>
        </simpleType>
      </attribute>
    </complexType>
  </element>

  <!-- 
	a list on which entities of a given type are listed

	onselect:		name of form/page/list to go to when
					    a selection is made from the list 
-->
  <element name='list'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
        <choice minOccurs='0' maxOccurs='unbounded'>
          <element ref='adl:head'/>
          <element ref='adl:top'/>
          <element ref='adl:foot'/>
          <element ref='adl:field'/>
          <element ref='adl:fieldgroup'/>
          <element ref='adl:auxlist'/>
          <element ref='adl:verb'/>
          <element ref='adl:permission'/>
          <element ref='adl:pragma'/>
        </choice>
      </sequence>
      <attribute name='name' type='string' use='required'/>
      <attribute name='properties' use='required'>
        <simpleType>
          <restriction base='string'>
            <enumeration value='all'/>
            <enumeration value='user-distict'/>
            <enumeration value='listed'/>
          </restriction>
        </simpleType>
      </attribute>
      <attribute name='onselect' type='string' use='optional'/>
    </complexType>
  </element>

  <!--
  a subsidiary list, on which entities related to primary
  entities in the enclosing page or list are listed
  
  property:   the property of the enclosing entity that this
              list displays (obviously, must be of type='list')
  onselect:   the form or page of the listed entity to call
              when an item from the list is selected
  canadd:     true if the user should be able to add records
              to this list
  -->
  <element name='auxlist'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
        <choice minOccurs='0' maxOccurs='unbounded'>
          <element ref='adl:prompt'/>
          <element ref='adl:field'/>
          <element ref='adl:fieldgroup'/>
          <element ref='adl:auxlist'/>
          <element ref='adl:verb'/>
        </choice>
      </sequence>
      <attribute name='property' type='string' use='required'/>
      <attribute name='onselect' type='string' use='optional'/>
      <attribute name='canadd' use='optional'>
        <simpleType>
          <restriction base='string'>
            <enumeration value='true'/>
            <enumeration value='false'/>
          </restriction>
        </simpleType>
      </attribute>
    </complexType>
  </element>

  <!--
  a group of fields and other controls within a form or list, which the 
  renderer might render as a single pane in a tabbed display, for example.
  -->
  <element name='fieldgroup'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
        <choice minOccurs='0' maxOccurs='unbounded'>
          <element ref='adl:prompt'/>
          <element ref='adl:field'/>
          <element ref='adl:fieldgroup'/>
          <element ref='adl:auxlist'/>
          <element ref='adl:verb'/>
        </choice>
      </sequence>
      <attribute name='name' type='string' use='required'/>
    </complexType>
  </element>

  <!-- a field in a form or page

  property:   the property which this field displays/edits
  -->
  <element name='field'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
        <element ref='adl:prompt' minOccurs='0' maxOccurs='unbounded'/>
        <element ref='adl:help' minOccurs='0' maxOccurs='unbounded'/>
        <element ref='adl:permission' minOccurs='0' maxOccurs='unbounded'/>
      </sequence>
      <attribute name='property' type='string' use='required'/>
    </complexType>
  </element>

  <!-- a verb is something that may be done through a form. Probably the verbs 'store' 
  and 'delete' are implied, but maybe they need to be explicitly declared. The 'verb'
  attribute of the verb is what gets returned to the controller -->
  <element name='verb'>
    <complexType>
      <sequence>
        <element ref='adl:documentation' minOccurs='0' maxOccurs='1'/>
        <element ref='adl:prompt' minOccurs='0' maxOccurs='unbounded'/>
        <element ref='adl:help' minOccurs='0' maxOccurs='unbounded'/>
        <element ref='adl:permission' minOccurs='0' maxOccurs='unbounded'/>
      </sequence>
      <attribute name='verb' type='string' use='required'/>
      <attribute name='dangerous' use='required'>
        <simpleType>
          <restriction base='string'>
            <enumeration value='true'/>
            <enumeration value='false'/>
          </restriction>
        </simpleType>
      </attribute>
    </complexType>
  </element>

  <!-- a container for global content -->
  <element name='content'>
    <complexType>
      <choice minOccurs='0' maxOccurs='unbounded'>
        <element ref='adl:head'/>
        <element ref='adl:top'/>
        <element ref='adl:foot'/>
      </choice>
    </complexType>
  </element>

  <!-- 
	content to place in the head of the generated document; this is #PCDATA 
	because it will almost certainly belong to a different namespace 
	(usually HTML)
-->
  <element name='head'>
    <complexType>
      <sequence>
        <any namespace="http://www.w3.org/1999/xhtml"
             minOccurs="1" maxOccurs="unbounded"
             processContents="skip"/>
      </sequence>
    </complexType>
  </element>

  <!-- 
	content to place in the top of the body of the generated document; 
	this is #PCDATA because it will almost certainly belong to a different 
	namespace (usually HTML)
   
   Schema only: no harm in this being required to be contained in an HTML div
-->
  <element name='top'>
    <complexType>
      <sequence>
        <any namespace="http://www.w3.org/1999/xhtml"
             minOccurs="1" maxOccurs="unbounded"
             processContents="skip"/>
      </sequence>
    </complexType>
  </element>

  <!-- 
	content to place at the foot of the body of the generated document; 
	this is #PCDATA because it will almost certainly belong to a different 
	namespace (usually HTML)
   
   Schema only: no harm in this being required to be contained in an HTML div
-->
  <element name='foot'>
    <complexType>
      <sequence>
        <any namespace="http://www.w3.org/1999/xhtml"
             minOccurs="1" maxOccurs="unbounded"
             processContents="skip"/>
      </sequence>
    </complexType>
  </element>
</schema>