<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
    xmlns="http://www.mmbase.org/xmlns/datatypes"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:mmsq="http://www.mmbase.org/xmlns/searchquery"
    targetNamespace="http://www.mmbase.org/xmlns/datatypes"
    elementFormDefault="qualified"
    attributeFormDefault="unqualified"
    version="1.0">

  <xsd:import
      namespace="http://www.w3.org/XML/1998/namespace"
      schemaLocation="http://www.w3.org/2001/03/xml.xsd"
      />

  <xsd:import
      namespace="http://www.mmbase.org/xmlns/searchquery"
      schemaLocation="http://www.mmbase.org/xmlns/enumerationquery.xsd" />


  <xsd:complexType name="DataTypes">
    <xsd:sequence>
      <xsd:element ref="datatype" maxOccurs="11" minOccurs="0" /> <!-- 11: number of 'type_database' -->
    </xsd:sequence>
    <xsd:attribute name="id" type="xsd:ID" />
  </xsd:complexType>

  <xsd:complexType name="DataType">
    <xsd:sequence>
      <xsd:element ref="description" maxOccurs="unbounded" minOccurs="0" />
      <xsd:element ref="class"       maxOccurs="1" minOccurs="0" />

      <xsd:element name="property"  maxOccurs="unbounded" minOccurs="0">
        <xsd:annotation>
          <xsd:documentation>
            Generic property, calls set-method with given name on DataType.
          </xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
          <xsd:attribute name="name"  type="xsd:string" />
          <xsd:attribute name="value" type="xsd:string" />
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="default"  maxOccurs="1" minOccurs="0">
        <xsd:complexType>
          <xsd:attribute name="value" type="xsd:string" />
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="unique"   type="Condition" maxOccurs="1" minOccurs="0" />
      <xsd:element name="required" type="Condition" maxOccurs="1" minOccurs="0" />

      <xsd:choice minOccurs="0">
        <xsd:element name="minExclusive" type="Comparable" />
        <xsd:element name="minInclusive" type="Comparable" />
      </xsd:choice>
      <xsd:choice minOccurs="0">
        <xsd:element name="maxExclusive" type="Comparable" />
        <xsd:element name="maxInclusive" type="Comparable" />
      </xsd:choice>

      <xsd:element name="minLength"  type="Comparable" minOccurs="0" maxOccurs="1" />
      <xsd:element name="maxLength"  type="Comparable" minOccurs="0" maxOccurs="1" />
      <xsd:element name="length"     type="Comparable" minOccurs="0" maxOccurs="1" />

      <xsd:element name="pattern"    minOccurs="0" maxOccurs="unbounded">
        <xsd:annotation>
          <xsd:documentation>
            Currently, the pattern is interpreted as a Condition for Strings and for DateTimes it
            is interpreted a format indication (like the pattern of SimpleDateFormat). In this
            last case there can also be more than one pattern: for every locale a different one.
          </xsd:documentation>
        </xsd:annotation>
        <xsd:complexType>
          <xsd:complexContent>
            <xsd:extension base ="Comparable">
              <xsd:attribute ref="xml:lang" />
            </xsd:extension>
          </xsd:complexContent>
        </xsd:complexType>
      </xsd:element>

      <xsd:element name="password"  maxOccurs="1" minOccurs="0">
        <xsd:complexType>
          <xsd:attribute name="value" type="xsd:boolean" />
        </xsd:complexType>
      </xsd:element>
      <xsd:element ref="enumeration" maxOccurs="unbounded" minOccurs="0" />
      <xsd:element name="setprocessor"    type="Processor" maxOccurs="unbounded" minOccurs="0" />
      <xsd:element name="getprocessor"    type="Processor" maxOccurs="unbounded" minOccurs="0" />
      <xsd:element name="commitprocessor" type="Processor" maxOccurs="unbounded" minOccurs="0" />

      <xsd:element ref="specialization" maxOccurs="unbounded" minOccurs="0" />

    </xsd:sequence>
    <xsd:attribute name="id"   type="xsd:token" use="optional" /> <!-- optinal, because in builder xml exist 'anonymous' datatypes -->
    <xsd:attribute name="base" type="xsd:token" use="optional" />
  </xsd:complexType>


  <xsd:element name="datatypes"      type="DataTypes" />
  <xsd:element name="datatype"       type="DataType" />
  <xsd:element name="specialization" type="DataType"/>


  <xsd:complexType name="Restriction">
    <xsd:sequence>
      <xsd:element ref="description" maxOccurs="unbounded" minOccurs="0" />
    </xsd:sequence>
    <xsd:attribute name="fixed"    type="xsd:boolean" />
    <xsd:attribute name="enforce"  type="type_enforce" />
  </xsd:complexType>

  <xsd:complexType name="Comparable">
    <xsd:complexContent>
      <xsd:extension base ="Restriction">
        <xsd:attribute name="value"     type="xsd:string" />
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:complexType name="Condition">
    <xsd:complexContent>
      <xsd:extension base ="Restriction">
        <xsd:attribute name="value" type="xsd:boolean" />
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="description">
    <xsd:complexType>
      <xsd:simpleContent>
        <xsd:extension base="xsd:string">
          <xsd:attribute ref="xml:lang" />
        </xsd:extension>
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>


  <xsd:simpleType name="type_database">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="string" />
      <xsd:enumeration value="integer" />
      <xsd:enumeration value="binary" />
      <xsd:enumeration value="float" />
      <xsd:enumeration value="double" />
      <xsd:enumeration value="long" />
      <xsd:enumeration value="xml" />
      <xsd:enumeration value="node" />
      <xsd:enumeration value="datetime" />
      <xsd:enumeration value="boolean" />
      <xsd:enumeration value="list" />
      <xsd:enumeration value="*" />
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="type_enforce">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="absolute" />
      <xsd:enumeration value="always" />
      <xsd:enumeration value="onchange" />
      <xsd:enumeration value="oncreate" />
      <xsd:enumeration value="never" />
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:complexType name="Processor">
    <xsd:sequence>
      <xsd:element ref="class"  maxOccurs="unbounded" minOccurs="1" />
    </xsd:sequence>
    <xsd:attribute name="type" type="type_database" />
  </xsd:complexType>

  <xsd:element name="class">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="param" maxOccurs="unbounded" minOccurs="0" />
      </xsd:sequence>
      <xsd:attribute name="name" type="xsd:string" />
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="param">
    <xsd:complexType mixed="true">
      <xsd:sequence>
        <xsd:element ref="param" maxOccurs="unbounded" minOccurs="0" />
      </xsd:sequence>
      <xsd:attribute name="name" type="xsd:string" />
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="enumeration">
    <xsd:complexType>
      <xsd:complexContent>
        <xsd:extension base="Restriction">
          <xsd:sequence>
            <xsd:element ref="mmsq:query" minOccurs="0" maxOccurs="unbounded" />
            <xsd:element ref="entry"      minOccurs="0" maxOccurs="unbounded" />
          </xsd:sequence>
        </xsd:extension>
      </xsd:complexContent>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="entry">
    <xsd:complexType>
      <xsd:attribute name="value" type="xsd:string" />
      <xsd:attribute name="display" type="xsd:string" />
      <xsd:attribute ref="xml:lang" />
      <xsd:attribute name="basename"      type="xsd:string" />
      <xsd:attribute name="sorterclass"   type="xsd:string" />
      <xsd:attribute name="javaconstants" type="xsd:string" />
    </xsd:complexType>
  </xsd:element>


</xsd:schema>
