adl/schemas/adl-0-1-0.xsd

734 lines
26 KiB
XML
Executable file

<?xml version="1.0" encoding="utf-8"?>
<!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<!-- -->
<!-- adl-0-1-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 visual studio from -->
<!-- adl-0.dtd revision 1.14 -->
<!-- -->
<!-- Author: Simon Brooke <sb@cygnets.co.uk> -->
<!-- Created: 9th January 2008 -->
<!-- $Revision: 1.1 $ -->
<!-- Copyright: (c) 2008 Cygnet Solutions Ltd -->
<!-- -->
<!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns='http://www.cygnets.co.uk/schemas/adl-0-1-0.xsd'
targetNamespace='http://www.cygnets.co.uk/schemas/adl-0-1-0.xsd'
xmlns:adl='http://www.cygnets.co.uk/schemas/adl-0-1-0.xsd'
xmlns:html='http://www.w3.org/1999/xhtml'>
<!--
the application that the document describes: required top level element
name: the name of this application
version: the version number of this application
xmlns: XML namespace, in case required
-->
<xs:element name="application">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:element minOccurs="0" maxOccurs="1" ref="content" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="typedef" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="group" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="entity" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="version" type="xs:string" />
</xs:complexType>
</xs: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 typedef
type: the simple type on which this defined type is based; must be
present unless in-implementation children are supplied
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)
-->
<xs:element name="typedef">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="in-implementation" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="help" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="type">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="string" />
<xs:enumeration value="integer" />
<xs:enumeration value="real" />
<xs:enumeration value="money" />
<xs:enumeration value="date" />
<xs:enumeration value="time" />
<xs:enumeration value="timestamp" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="size" type="xs:string" />
<xs:attribute name="pattern" type="xs:string" />
<xs:attribute name="minimum" type="xs:string" />
<xs:attribute name="maximum" type="xs:string" />
</xs:complexType>
</xs:element>
<!--
information about how to translate a type into types known to different target
languages. TODO: Once again I'm not wholly comfortable with the name; I'm not
really comfortable that this belongs in ADL at all.
target: the target language
value: the type to use in that target language
kind: OK, I confess I don't understand this, but Andrew needs it...
-->
<xs:element name="in-implementation">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
</xs:sequence>
<xs:attribute name="target" type="xs:string" use="required" />
<xs:attribute name="value" type="xs:string" use="required" />
<xs:attribute name="kind" type="xs:string" />
</xs:complexType>
</xs: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
-->
<xs:element name="group">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="parent" type="xs:string" />
</xs:complexType>
</xs: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!] DEPRECATED: remove; replace with the
'key' element, below.
table: the name of the table in which this entity is stored. Defaults to same
as name of entity. Strongly recommend this is not used unless it needs
to be different from the name of the entity
foreign: this entity is part of some other system; no code will be generated
for it, although code which links to it will be generated
-->
<xs:element name="entity">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:element minOccurs="0" maxOccurs="1" ref="content" />
<xs:element minOccurs="0" maxOccurs="1" ref="key" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="property" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="permission" />
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="form" />
<xs:element ref="page" />
<xs:element ref="list" />
</xs:choice>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="natural-key" type="xs:string" />
<xs:attribute name="table" type="xs:string" />
<xs:attribute name="foreign">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="true" />
<xs:enumeration value="false" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs: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?
-->
<xs:element name="documentation">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
<!-- an explicit primary key, possibly compound -->
<xs:element name="key">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="property" />
</xs:sequence>
</xs:complexType>
</xs: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!
typedef: name of the typedef 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; if type='entity' and the farside field to join to
is not the farside primary key, then the name of that
farside field
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)
cascade: what action(s) on the parent entity should be cascaded to
entitie(s) linked on this property. Valid only if type='entity',
type='link' or type='list'.
column: name of the column in a SQL database table in which this property
is stored. If not present, use name. TODO: Think about this.
unsaved-value:
of a property whose persistent value is set on first being
committed to persistent store, the value which it holds before
it has been committed
-->
<xs:element name="property">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:element minOccurs="0" maxOccurs="1" ref="generator" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="permission" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="option" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="prompt" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="help" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="ifmissing" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="type" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="entity" />
<xs:enumeration value="link" />
<xs:enumeration value="list" />
<xs:enumeration value="defined" />
<xs:enumeration value="string" />
<xs:enumeration value="integer" />
<xs:enumeration value="real" />
<xs:enumeration value="money" />
<xs:enumeration value="date" />
<xs:enumeration value="time" />
<xs:enumeration value="timestamp" />
<xs:enumeration value="boolean" />
<xs:enumeration value="text" />
<xs:enumeration value="geopos" />
<xs:enumeration value="image" />
<xs:enumeration value="message" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="default" type="xs:string" />
<xs:attribute name="typedef" type="xs:string" />
<xs:attribute name="distinct">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="none" />
<xs:enumeration value="all" />
<xs:enumeration value="user" />
<xs:enumeration value="system" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="entity" type="xs:string" />
<xs:attribute name="farkey" type="xs:string" />
<xs:attribute name="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="true" />
<xs:enumeration value="false" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="size" type="xs:string" />
<xs:attribute name="column" type="xs:string" />
<xs:attribute name="concrete">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="true" />
<xs:enumeration value="false" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="cascade">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="all" />
<xs:enumeration value="all-delete-orphan" />
<xs:enumeration value="delete" />
<xs:enumeration value="manual" />
<xs:enumeration value="save-update" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<!--
marks a property which is auto-generated by some part of the system.
This is based on the Hibernate construct, except that the Hibernate
implementation folds both its internal generators and custom generators
onto the same attribute. This separates them onto two attributes so we
can police values for Hibernate's 'builtin' generators.
action: one of the supported Hibernate builtin generators, or
'manual'. 'native' is strongly recommended in most instances
class: if action is 'manual', the name of a manually maintained
class conforming to the Hibernate IdentifierGenerator
interface, or its equivalent in other languages
-->
<xs:element name="generator">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="param" />
</xs:sequence>
<xs:attribute name="action" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="assigned" />
<xs:enumeration value="guid" />
<xs:enumeration value="manual" />
<xs:enumeration value="native" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="class" type="xs:string" />
</xs:complexType>
</xs:element>
<!--
A parameter passed to the generator. Again, based on the Hibernate
implementation. TODO: #PCDATA is wrong as the content model, as embedded
markup is definitely not allowed!
name: the name of this parameter
-->
<xs:element name="param">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs: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.
value: the value of this option
-->
<xs:element name="option">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="prompt" />
</xs:sequence>
<xs:attribute name="value" type="xs:string" />
</xs:complexType>
</xs: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
-->
<xs:element name="permission">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
</xs:sequence>
<xs:attribute name="group" type="xs:string" use="required" />
<xs:attribute name="permission" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="none" />
<xs:enumeration value="read" />
<xs:enumeration value="insert" />
<xs:enumeration value="noedit" />
<xs:enumeration value="edit" />
<xs:enumeration value="all" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs: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.
-->
<xs:element name="pragma">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="value" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<!--
a prompt for a property or field; used as the prompt text for a widget
which edits it. Typically there will be at most 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
-->
<xs:element name="prompt">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
</xs:sequence>
<xs:attribute name="prompt" type="xs:string" use="required" />
<xs:attribute name="locale" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<!--
helptext about a property of an entity, or a field of a page, form or
list, or a typedef. Typically there will be at most 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
-->
<xs:element name="help">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="locale" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<!--
helpful text to be shown if a property value is missing, typically when
a form is submitted. Typically there will be at most 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.
-->
<xs:element name="ifmissing">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="locale" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<!--
a form through which an entity may be added or edited
-->
<xs:element name="form">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="head" />
<xs:element ref="top" />
<xs:element ref="foot" />
<xs:element ref="field" />
<xs:element ref="fieldgroup" />
<xs:element ref="auxlist" />
<xs:element ref="verb" />
<xs:element ref="permission" />
<xs:element ref="pragma" />
</xs:choice>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="properties" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="all" />
<xs:enumeration value="user-distinct" />
<xs:enumeration value="listed" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<!-- a page on which an entity may be displayed (i.e. like a form, but read only -->
<xs:element name="page">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="head" />
<xs:element ref="top" />
<xs:element ref="foot" />
<xs:element ref="field" />
<xs:element ref="fieldgroup" />
<xs:element ref="auxlist" />
<xs:element ref="verb" />
<xs:element ref="permission" />
<xs:element ref="pragma" />
</xs:choice>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="properties" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="all" />
<xs:enumeration value="user-distinct" />
<xs:enumeration value="listed" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs: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
-->
<xs:element name="list">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="head" />
<xs:element ref="top" />
<xs:element ref="foot" />
<xs:element ref="field" />
<xs:element ref="fieldgroup" />
<xs:element ref="auxlist" />
<xs:element ref="verb" />
<xs:element ref="permission" />
<xs:element ref="pragma" />
</xs:choice>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="properties" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="all" />
<xs:enumeration value="user-distinct" />
<xs:enumeration value="listed" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="onselect" type="xs:string" />
</xs:complexType>
</xs: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
-->
<xs:element name="auxlist">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="prompt" />
<xs:element ref="field" />
<xs:element ref="fieldgroup" />
<xs:element ref="auxlist" />
<xs:element ref="verb" />
</xs:choice>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="properties" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="all" />
<xs:enumeration value="user-distinct" />
<xs:enumeration value="listed" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="property" type="xs:string" use="required" />
<xs:attribute name="onselect" type="xs:string" />
<xs:attribute name="canadd">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="true" />
<xs:enumeration value="false" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs: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.
-->
<xs:element name="fieldgroup">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="prompt" />
<xs:element ref="field" />
<xs:element ref="fieldgroup" />
<xs:element ref="auxlist" />
<xs:element ref="verb" />
</xs:choice>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<!--
a field in a form or page
property: the property which this field displays/edits
-->
<xs:element name="field">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="prompt" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="help" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="permission" />
</xs:sequence>
<xs:attribute name="property" type="xs:string" use="required" />
</xs:complexType>
</xs: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
-->
<xs:element name="verb">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="documentation" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="prompt" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="help" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="permission" />
</xs:sequence>
<xs:attribute name="verb" type="xs:string" use="required" />
<xs:attribute name="dangerous" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="true" />
<xs:enumeration value="false" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<!-- a container for global content -->
<xs:element name="content">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="head" />
<xs:element ref="top" />
<xs:element ref="foot" />
</xs:choice>
</xs:complexType>
</xs: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).
NOTE: things which are legal in HTML HEAD only.
NOTE: it's questionable whether this should really be here at all.
-->
<xs:element name="head">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
<!--
content to place in the top of the body of the generated document;
this should be %Flow; which is any HTML block or inline level element.
-->
<xs:element name="top">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
<!--
content to place at the foot of the body of the generated document;
this should be %Flow; which is any HTML block or inline level element.
-->
<xs:element name="foot">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>