<?xml version="1.0"?>
<!--
  Author:  Jeff Larkin
  $Id: restpackage.xsd,v 1.53 2005/04/08 15:23:26 larkin Exp $
  
  Description:
    This file declares the ReST package installation instructions.
  
-->
<xs:schema targetNamespace="http://icl.cs.utk.edu/ReST/Package/1.0"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="http://icl.cs.utk.edu/ReST/Package/1.0">
           
  <!-- THESE ARE COMMONLY USED ELEMENTS -->
  <xs:element name="name" type="xs:string"/>
  <xs:element name="base" type="xs:string"/>
  <xs:element name="title">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute name="role" type="xs:string"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
  <xs:element name="description" type="xs:string"/>
  <xs:element name="uri" type="xs:anyURI"/>
  <xs:element name="version" type="xs:string"/>
  <xs:element name="packagedir" type="xs:string"/>
  <xs:element name="packagesrc">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:anyURI">
          <!--<xs:attribute name="dir" type="xs:boolean"/>-->
          <xs:attribute name="filter" type="xs:string"/>
          <xs:attribute name="mode" type="xs:string"/>
        </xs:extension>
      </xs:simpleContent>      
    </xs:complexType>
  </xs:element>
  <xs:element name="patch" type="xs:anyURI"/>
  <xs:element name="license">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute name="forceaccept" type="xs:boolean"/>
        </xs:extension>
      </xs:simpleContent>      
    </xs:complexType>
  </xs:element>
  <xs:element name="licenseuri">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:anyURI">
          <xs:attribute name="forceaccept" type="xs:boolean"/>
        </xs:extension>
      </xs:simpleContent>      
    </xs:complexType>
  </xs:element>
  <xs:element name="info" type="xs:string"/>
  <xs:element name="infouri" type="xs:anyURI"/>
  <xs:element name="checksumuri">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:anyURI">
          <xs:attribute name="forcechecksum" type="xs:boolean"/>
        </xs:extension>
      </xs:simpleContent>      
    </xs:complexType>
  </xs:element>
  <xs:element name="command">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="option" minOccurs="0" maxOccurs="unbounded"/>
      
        <!-- Allow for future extensions of the mark-up -->
        <xs:any  minOccurs="0" maxOccurs="unbounded" processContents="lax"
                 namespace="##any"/>
      </xs:sequence>
      
      <!-- This is what would be typed at the command prompt -->
      <xs:attribute name="value" type="xs:string" use="required"/>
      
      <!-- The shell to run the command in, /bin/sh if nothing is defined. -->
      <xs:attribute name="shell" type="xs:string" use="optional"/>
      
      <!-- Is this command optional or required?  We assume required if nothing
           is stated here.  This would have been called optional, except that
           could be confused by the <option> tag -->
      <xs:attribute name="required" type="xs:boolean" use="optional"/>
      
      <!-- If a command is grouped, it's only run once per logical group.  We
           assume ungrouped if this is not explicitly set. -->
      <xs:attribute name="grouped" type="xs:boolean" use="optional"/>
      
      <!-- the next 2 attributes are used for intra-package dependencies.  
       id - an arbitrary string to identify a command or option
       depends - a comman-separated list of ids on which a command or 
                 option depends -->
      <xs:attribute name="id" type="xs:string" use="optional"/>
      <xs:attribute name="depends" type="xs:string" use="optional"/>
      
      <!-- Provide an error message to display if this command fails -->
      <xs:attribute name="errormsg" type="xs:string" use="optional"/>
      
      <!-- Provide a status message to display while this command executes -->
      <xs:attribute name="statusmsg" type="xs:string" use="optional"/>
      
      <!-- Description of the command -->
      <xs:attribute name="description" type="xs:string" use="optional"/>
      
      <!-- Should the user be forced to configure the command options? -->
      <xs:attribute name="forceconfigure" type="xs:boolean" use="optional"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="option">
    <xs:complexType>
      <xs:attribute name="name" type="xs:string" use="required"/>
      
      <!-- What type of option is this?  text, boolean, and choice are supported
           by gsap without modification -->
      <xs:attribute name="type" type="xs:string" use="required"/>
      
      <!-- this get's appended to the command as a cli option, but prepended
           to the value of the text area or choice.  This is useful for
           ./configure scripts. -->
      <!--<xs:attribute name="use" type="xs:string" use="required"/>-->
      
      <!-- if the option is of type choice, this is a command-separated list
           of choices -->
      <xs:attribute name="choices" type="xs:string" use="optional"/>

      <!-- if the type is choice, this is used to control if the user can enter
           a custom choice -->
      <xs:attribute name="customChoice" type="xs:boolean" use="optional"/>
      
      <!-- the default value of the option -->
      <xs:attribute name="default" type="xs:string" use="optional"/>
      
      <!-- the next 2 attributes are used for intra-package dependencies.  
       id - an arbitrary string to identify a command or option
       depends - a comman-separated list of ids on which a command or 
                 option depends -->
      <xs:attribute name="id" type="xs:string" use="optional"/>
      <xs:attribute name="depends" type="xs:string" use="optional"/>
      
      <!-- Should this be enabled by default?  Assumed false if missing. -->
      <xs:attribute name="enabled" type="xs:boolean" use="optional"/>
      
      <!-- Description of the command -->
      <xs:attribute name="description" type="xs:string" use="optional"/>
      
      <!-- appended to the command if enabled is true -->
      <xs:attribute name="truevalue" type="xs:string" use="required"/>
      <!-- appended to the command if enabled is false -->
      <xs:attribute name="falsevalue" type="xs:string" use="optional"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="packager">
    <xs:complexType>
      <xs:sequence>
        <!-- The name of the person who prepared the package. -->
        <xs:element ref="name"/>
        <!-- A URI about the packager, this should normally be a mailto:
          link, but could also be a website. -->
        <xs:element ref="uri"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  
  <!-- THIS IS THE ROOT ELEMENT -->
  <xs:element name="package">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="header"/>
        <xs:element ref="preparation"/>
        <xs:element ref="configuration"/>
        <xs:element ref="compilation"/>
        <xs:element ref="installation"/>
        <xs:element ref="completion"/>
        <xs:element ref="uninstallation" minOccurs="0"/>
      </xs:sequence>
      <!-- This is the rest package version, the version of the packaged
        software is contained in the package header. -->
      <xs:attribute name="version" type="xs:string" use="optional"/>
      <!-- Sets the version of ReST for which this package was designed. 
           Example: rest="1.0" -->
      <xs:attribute name="rest" type="xs:string" use="optional"/>
      <!-- if this is true, then simple mode will be disabled in the 
           installer. -->
      <xs:attribute name="forceadvanced" type="xs:boolean" use="optional"/>
      <!-- Allow users to create additional attributes that they find userful-->
      <xs:anyAttribute namespace="##any"/>
    </xs:complexType>
  </xs:element>
  
  <!-- THIS IS THE PACKAGE HEADER -->
  <xs:element name="header">
    <xs:complexType>
      <xs:sequence>
        <xs:sequence>
          <!-- The title to appear in the installer toolbar -->
          <xs:element ref="title" minOccurs="0" maxOccurs="unbounded"/>

          <!-- The base of the software package (must be alpha-numeric 
               and can include '-' and '_' -->
          <xs:element ref="base"/>
        
          <!-- The version of the software, not the gsi package. -->
          <xs:element ref="version"/>
        
          <!-- A description of the software -->
          <xs:element ref="description" minOccurs="0"/>
        
          <!-- A uri for additional information -->
          <xs:element ref="uri" minOccurs="0" maxOccurs="unbounded"/>
          
          <!-- Space for a readme or additional information to display -->
          <xs:element ref="info" minOccurs="0"/>
          <xs:element ref="infouri" minOccurs="0"/>
        
          <!-- Licensing information about the software.  The license could
               be entered explicitly or a uri can be given. -->
          <xs:element ref="license" minOccurs="0"/>
          <xs:element ref="licenseuri" minOccurs="0"/>
          
          <!-- This should be a package checksum as provided when creating a 
	       package using GSAPPackager. -->
	  <xs:element ref="checksumuri" minOccurs="0"/>
        
          <!-- Information about the person who created this GSI package -->
          <xs:element ref="packager" minOccurs="0"/>
          <xs:element ref="actions" minOccurs="0"/>
          <xs:element ref="predefs" minOccurs="0"/>
        </xs:sequence>
        <xs:sequence minOccurs="0" maxOccurs="unbounded"> 
          <!-- These directories are in the package file and will be created
               remotely. -->
          <xs:element ref="packagedir" minOccurs="0" maxOccurs="unbounded"/>
          <!-- These sources can be remote or included in the package file -->
          <xs:element ref="packagesrc" minOccurs="0" maxOccurs="unbounded"/>

          <!-- Configuration files that need editing -->
          <xs:element ref="configfile" minOccurs="0" maxOccurs="unbounded"/>

          <!-- The user could patch by including the patch source and issuing
               the patch command, but this will ultimately provide an easy, 
               unified way to patch sources -->
          <xs:element ref="patch" minOccurs="0" maxOccurs="unbounded"/>

        </xs:sequence>
        <!-- Attributes to customize the installer/explorer/monitor -->
        <xs:element ref="installerattributes" minOccurs="0"/>
        <xs:element ref="explorerattributes" minOccurs="0"/>
        <xs:element ref="monitorattributes" minOccurs="0"/>
        
        <!-- Allow users to add additional tags that we don't define -->
        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##any" 
                processContents="lax"/>
      </xs:sequence>
      
      <!-- Allow users to add attributes to header that we haven't defined -->
      <xs:anyAttribute namespace="##any"/>
    </xs:complexType>
  </xs:element>  
  
  <!-- The package may contain configuration files that need editing.  
       Attribute packagefile is the name of the file contained in the package.
       Attribute remotefile is the name of the file including path from
         the base directory for the file on the remote location. -->
  <xs:element name="configfile">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="sub" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="packagefile" type="xs:anyURI" use="required"/>
      <xs:attribute name="remotefile" type="xs:anyURI" use="required"/>
      <xs:attribute name="description" type="xs:string" use="required"/>
      
      <!-- Should the user be forced to configure the file substitutions? -->
      <xs:attribute name="forceconfigure" type="xs:boolean" use="optional"/>
    </xs:complexType>
  </xs:element>
  
  <xs:element name="sub">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute name="name" type="xs:string" use="required"/>
          <xs:attribute name="description" type="xs:string" use="optional"/>
          <xs:attribute name="format" type="xs:string" use="optional"/>
          <xs:attribute name="default" type="xs:string" use="required"/>
          <xs:attribute name="type" type="xs:string" use="required"/>
          <xs:attribute name="truevalue" type="xs:string" use="optional"/>
          <xs:attribute name="falsevalue" type="xs:string" use="optional"/>
          <!-- if the type is choice, this is a command-separated list
               of choices -->
          <xs:attribute name="choices" type="xs:string" use="optional"/>
          <!-- if the type is choice, this is used to control if the user can enter
               a custom choice -->
          <xs:attribute name="customChoice" type="xs:boolean" use="optional"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
  
  <!-- Elements used to customize the applications -->
  <!-- Background image and color to use -->
  <xs:element name="backgroundimage" type="xs:anyURI"/>
  <xs:element name="backgroundcolor">
    <xs:simpleType>
     <xs:restriction base="xs:hexBinary">
       <xs:length value="3"/>
     </xs:restriction>
   </xs:simpleType>
  </xs:element>
  <!-- Window icon to use -->
  <xs:element name="icon" type="xs:anyURI"/>
  
  <xs:complexType name="appAttrs">
    <xs:sequence>
      <xs:sequence>
        <xs:element ref="backgroundimage" minOccurs="0"/>
        <xs:element ref="backgroundcolor" minOccurs="0"/>
        <xs:element ref="icon" minOccurs="0"/>
      </xs:sequence>
      <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##any" 
              processContents="lax"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="installerattributes" type="appAttrs"/>
  <xs:element name="explorerattributes" type="appAttrs"/>
  <xs:element name="monitorattributes" type="appAttrs"/>
  
  <!--  The elements below are in the order that they will be executed
    when installing a package on a server.  They are all essentially the
    same, but provide logical groupings of what is done to install
    the software -->
  <xs:element name="preparation">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="command" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="configuration">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="command" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="compilation">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="command" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="installation">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="command" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="completion">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="command" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  
  <!-- Optional information about how to uninstall the package later -->
  <xs:element name="uninstallation">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="command" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element> 
  
  <!-- Things that the user can do once the package is installed -->
  <xs:element name="action">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="command" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="tooltip" type="xs:string" use="optional"/>
      
      <!-- the next 2 attributes are used for intra-package dependencies.  
       id - an arbitrary string to identify a command or option
       depends - a comman-separated list of ids on which a command or 
       option depends -->
      <xs:attribute name="id" type="xs:string" use="optional"/>
      <xs:attribute name="depends" type="xs:string" use="optional"/>
    </xs:complexType>
  </xs:element>
  
  <xs:element name="actions">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="action" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  
  <xs:element name="predefs">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="pre" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  
  <xs:element name="pre">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="def" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="id" type="xs:string" use="optional"/>
      <xs:attribute name="description" type="xs:string" use="optional"/>
    </xs:complexType>
  </xs:element>
  
  <xs:element name="def">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <!-- is this for a sub or an option? -->
          <xs:attribute name="type" type="xs:string" use="required"/>
          <!-- the id of the sub or option to predefine -->
          <xs:attribute name="ref" type="xs:string" use="required"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
    
</xs:schema>
