<?xml version="1.0" encoding="UTF-8"?>
<!--
  +===========================================================================+
  |                                                                           |
  |                    NATIONAL GEOSPATIAL DIGITAL ARCHIVE                    |
  |                 University of California at Santa Barbara                 |
  |                                                                           |
  +===========================================================================+
-->
<!-- $Header: /export/home/gjanee/ngda/data-model/RCS/ingest.rnc,v 1.2 2006/02/15 18:58:28 gjanee Exp $ -->
<!--
  DESCRIPTION
  
      RELAX NG schema for ingest requests.
  
      An ingest request is submitted as an HTTP POST request to the
      archive server.  POST parameter "request" contains the request
      itself (i.e., an XML document that is an instance of this
      schema).  Other POST parameters may be specified and contain
      files to be uploaded.
  
      In this API, there is no direct correspondence between ingest
      requests and ingest of archival objects.  A single ingest
      request may ingest multiple archival objects; and a single
      archival object may be ingested over the course of multiple
      ingest requests.
  
      This API supports two styles of ingest: template-based and
      non-template-based.  Styles can be applied on a per-object
      basis.
  
      In template-based ingest, a template is specified when the
      archival object is created.  The template defines the directory
      structure of the object (which the archive server implicitly
      creates), provides file definitions that will be validated
      against, and may also specify relationships to other archival
      objects and lineage information.  Definitions supplied in
      subsequent ingest requests must match those in the template;
      relationships and lineage information supplied in subsequent
      requests augment comparable information in the template.
  
      In non-template-based ingest, the directory structure of the
      archival object can and must be explicitly created.
  
  AUTHOR
  
      Greg Janee
      gjanee@alexandria.ucsb.edu
  
  HISTORY
  
      $Log: ingest.rnc,v $
      Revision 1.2  2006/02/15 18:58:28  gjanee
      Parallel changes to match those made to manifest.rnc.  This
      schema is fully backward-compatible with the previous version
      except for the version change in the XML namespace.  (There is a
      new restriction on object identifiers that is not
      backward-compatible in theory, but in practice the change should
      have no implications.)
  
      Revision 1.1  2005/11/14 18:19:17  gjanee
      Initial revision
  
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="tag:ngda.org,2005:schemas/1.1/ingest" xmlns:ingest="tag:ngda.org,2005:schemas/1.1/ingest">
  <!-- An <ingest> element contains zero or more commands. -->
  <xs:element name="ingest">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="ingest:Command"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Command" abstract="true"/>
  <!--
    A <createTemplate> command creates a new template with the given
    identifier, which must not already be in use.  The <file> in the
    request is the template itself.
  -->
  <xs:element name="createTemplate" substitutionGroup="ingest:Command">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ingest:templateIdentifier"/>
        <xs:element ref="ingest:file"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="templateIdentifier" type="xs:anyURI"/>
  <!--
    A <createObject> command creates a new archival object with the
    given identifier, which must not already be in use.  Optionally, a
    template reference may be given; if so, an association between the
    object and the template will be made and the template will be used
    for validation.
  -->
  <xs:element name="createObject" substitutionGroup="ingest:Command">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ingest:objectIdentifier"/>
        <xs:element minOccurs="0" ref="ingest:templateRef"/>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="ingest:relationship"/>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="ingest:definitionRef"/>
        <xs:element minOccurs="0" ref="ingest:lineage"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="objectIdentifier" type="xs:anyURI"/>
  <xs:element name="templateRef" type="xs:anyURI"/>
  <!--
    A <createDirectory> command creates a directory in an existing
    archival object.  Parent directories of the directory, if any,
    must already exist.  The object must not have an associated
    template.
  -->
  <xs:element name="createDirectory" substitutionGroup="ingest:Command">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ingest:objectIdentifier"/>
        <xs:element ref="ingest:path"/>
        <xs:element ref="ingest:type"/>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="ingest:definitionRef"/>
        <xs:element minOccurs="0" ref="ingest:lineage"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="type">
    <xs:simpleType>
      <xs:restriction base="xs:token">
        <xs:enumeration value="subcomponents"/>
        <xs:enumeration value="alternatives"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:element>
  <!--
    An <uploadFile> command loads a file into an existing archival
    object.  If the object has an associated template, the path given
    in the command must identify a file component in the template.  If
    the object does not have a template, any directories in the path
    must already exist.
  -->
  <xs:element name="uploadFile" substitutionGroup="ingest:Command">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ingest:objectIdentifier"/>
        <xs:element ref="ingest:path"/>
        <xs:element ref="ingest:file"/>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="ingest:definitionRef"/>
        <xs:element minOccurs="0" ref="ingest:lineage"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <!--
    A <path> names a component in an archival object by a complete
    pathname relative to the object's root directory.  Syntactically,
    a path consists of one or more NCNames separated by forward ('/')
    or backward ('\') slashes.
  -->
  <xs:element name="path">
    <xs:simpleType>
      <xs:restriction base="xs:string">
        <xs:pattern value="[\p{L}_][\p{L}\p{N}._\-]*([/\\][\p{L}_][\p{L}\p{N}._\-]*)*"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:element>
  <!--
    A <file> describes a file that is retrievable from a named
    parameter in the HTTP POST request.  Optionally, the original
    filename or pathname may be given.  Optionally, the file's size in
    bytes and content signature may be supplied; if so, they will be
    used for validation.
  -->
  <xs:element name="file">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ingest:sourceParameter"/>
        <xs:element minOccurs="0" ref="ingest:originalFilename"/>
        <xs:element minOccurs="0" ref="ingest:size"/>
        <xs:element minOccurs="0" ref="ingest:signature"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="sourceParameter" type="xs:NCName"/>
  <xs:element name="originalFilename" type="xs:string"/>
  <xs:element name="size" type="xs:nonNegativeInteger"/>
  <xs:element name="signature">
    <xs:complexType mixed="true">
      <xs:attribute name="algorithm" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:token">
            <xs:enumeration value="MD5"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
  <!-- The following declarations are as in manifest.rnc. -->
  <xs:element name="relationship">
    <xs:complexType>
      <xs:attribute name="type" use="required"/>
      <xs:attribute name="targetObjectRef" use="required" type="xs:anyURI"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="definitionRef" type="xs:anyURI"/>
  <xs:element name="lineage">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="ingest:sourceComponentRef"/>
        <xs:element minOccurs="0" ref="ingest:notes"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="sourceComponentRef" type="xs:anyURI"/>
  <xs:element name="notes" type="xs:string"/>
</xs:schema>
