<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="http://www.globus.org/namespaces/2003/04/rsl/gram"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            xmlns:rsl="http://www.globus.org/namespaces/2003/04/rsl"
            xmlns:gram="http://www.globus.org/namespaces/2003/04/rsl/gram"
            xmlns="http://www.globus.org/namespaces/2003/04/rsl/gram"
            elementFormDefault="qualified">

    <xsd:import namespace="http://www.globus.org/namespaces/2003/04/rsl"
                schemaLocation="rsl.xsd"/>

    <!-- jobRun types -->
    <xsd:complexType name="jobRunEnumerationValueType">
        <xsd:choice>
            <xsd:element name="mpi"/>
            <xsd:element name="single"/>
            <xsd:element name="multiple"/>
            <xsd:element name="condor"/>
        </xsd:choice>
    </xsd:complexType>

    <xsd:complexType name="jobRunEnumerationElementType">
        <xsd:complexContent>
            <xsd:restriction base="rsl:enumerationElementType">
                <xsd:choice>
                    <xsd:element ref="rsl:substitutionRef"/>
                    <xsd:element name="enumerationValue"
                                 type="gram:jobRunEnumerationValueType"/>
                </xsd:choice>
            </xsd:restriction>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="jobRunEnumerationType">
        <xsd:complexContent>
            <xsd:restriction base="rsl:enumerationType">
                <xsd:sequence>
                    <xsd:element    name="enumeration"
                                    type="gram:jobRunEnumerationElementType"/>
                </xsd:sequence>
            </xsd:restriction>
        </xsd:complexContent>
    </xsd:complexType>


    <!-- gram myjob types types -->
    <xsd:complexType name="gramMyJobEnumerationValueType">
        <xsd:choice>
            <xsd:element name="collective"/>
            <xsd:element name="independent"/>
        </xsd:choice>
    </xsd:complexType>

    <xsd:complexType name="gramMyJobEnumerationElementType">
        <xsd:complexContent>
            <xsd:restriction base="rsl:enumerationElementType">
                <xsd:choice>
                    <xsd:element ref="rsl:substitutionRef"/>
                    <xsd:element name="enumerationValue"
                                 type="gram:gramMyJobEnumerationValueType"/>
                </xsd:choice>
            </xsd:restriction>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="gramMyJobEnumerationType">
        <xsd:complexContent>
            <xsd:restriction base="rsl:enumerationType">
                <xsd:sequence>
                    <xsd:element   name="enumeration"
                                   type="gram:gramMyJobEnumerationElementType"/>
                </xsd:sequence>
            </xsd:restriction>
        </xsd:complexContent>
    </xsd:complexType>


    <xsd:group  name="jobRestartElements">
        <xsd:sequence>
            <xsd:element    name="restart"
                            type="rsl:stringType"
                            minOccurs="1"
                            maxOccurs="1"/>
            <xsd:element    name="stdoutPosition"
                            type="rsl:integerType"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    name="stderrPosition"
                            type="rsl:integerType"
                            minOccurs="0"
                            maxOccurs="1"/>
        </xsd:sequence>
    </xsd:group>

    <!--=====================================================================-->
    <!--                  GRAM attribute definitions                         -->
    <!--=====================================================================-->

    <xsd:element name="executable" type="rsl:pathType">
        <xsd:annotation>
            <xsd:documentation>
                The name of the executable file to run on the remote
                machine. If the value is a GASS URL, the file is
                transferred to the remote gass cache before executing
                the job and removed after the job has terminated.

            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="directory" type="rsl:pathType">
        <xsd:annotation>
            <xsd:documentation>
                Specifies the path of the directory the jobmanager will
                use as the default directory for the requested job.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="arguments" type="rsl:stringArrayType">
        <xsd:annotation>
            <xsd:documentation>
                The command line arguments for the executable. Use
                quotes, if a space is required in a single argument.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="environment" type="rsl:hashtableType">
        <xsd:annotation>
            <xsd:documentation>
                The environment variables that will be defined for the
                executable in addition to default set that is given to
                the job by the jobmanager.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="stdin" type="rsl:pathType">
        <xsd:annotation>
            <xsd:documentation>
                The name of the file to be used as standard input for
                the executable on the remote machine. If the value is
                a GASS URL, the file is transferred to the remote gass
                cache before executing the job and removed after the
                job has terminated.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="stdout" type="rsl:pathArrayType">
        <xsd:annotation>
            <xsd:documentation>
                The name of the remote file to store the standard
                output from the job. If the value is a GASS URL, the
                standard output from the job is transferred dynamically
                during the execution of the job.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="stderr" type="rsl:pathArrayType">
        <xsd:annotation>
            <xsd:documentation>
                The name of the remote file to store the standard error
                from the job. If the value is a GASS URL, the standard
                error from the job is transferred dynamically during
                the execution of the job.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="count" type="rsl:integerType">
        <xsd:annotation>
            <xsd:documentation>
                The number of executions of the executable.
                Default: 1
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="libraryPath" type="rsl:pathArrayType">
        <xsd:annotation>
            <xsd:documentation>
                Specifies a list of paths to be appended to the
                system-specific library path environment variables.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="hostCount" type="rsl:integerType">
        <xsd:annotation>
            <xsd:documentation>
                Only applies to clusters of SMP computers, such as
                newer IBM SP systems. Defines the number of nodes
                pizza boxes") to distribute the "count" processes
                across.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="project" type="rsl:stringType">
        <xsd:annotation>
            <xsd:documentation>
                Target the job to be allocated to a project account as
                defined by the scheduler at the defined (remote)
                resource.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="queue" type="rsl:stringType">
        <xsd:annotation>
            <xsd:documentation>
                Target the job to a queue (class) name as defined by
                the scheduler at the defined (remote) resource.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="maxTime" type="rsl:longType">
        <xsd:annotation>
            <xsd:documentation>
                The maximum walltime or cputime for a single execution
                of the executable. Walltime or cputime is selected by
                the GRAM scheduler being interfaced. The units is in
                minutes. The value will go through an atoi() conversion
                in order to get an integer.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="maxWallTime" type="rsl:longType">
        <xsd:annotation>
            <xsd:documentation>
                Explicitly set the maximum walltime for a single
                execution of the executable. The units is in minutes.
                The value will go through an atoi() conversion in order
                to get an integer. If the GRAM scheduler cannot set
                walltime, then an error will be returned.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="maxCpuTime" type="rsl:longType">
        <xsd:annotation>
            <xsd:documentation>
                Explicitly set the maximum cputime for a single
                execution of the executable. The units is in minutes.
                The value will go through an atoi() conversion in order
                to get an integer. If the GRAM scheduler cannot set
                cputime, then an error will be returned.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="maxMemory" type="rsl:integerType">
        <xsd:annotation>
            <xsd:documentation>
                Explicitly set the maximum amount of memory for a
                single execution of the executable. The units is in
                Megabytes. The value will go through an atoi()
                conversion in order to get an integer. If the GRAM
                scheduler cannot set maxMemory, then an error will be
                returned.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="minMemory" type="rsl:integerType">
        <xsd:annotation>
            <xsd:documentation>
                Explicitly set the minimum amount of memory for a
                single execution of the executable. The units is in
                Megabytes. The value will go through an atoi()
                conversion in order to get an integer. If the GRAM
                scheduler cannot set minMemory, then an error will be
                returned.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="jobType" type="gram:jobRunEnumerationType">
        <xsd:annotation>
            <xsd:documentation>
                This specifies how the jobmanager should start the job.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="gramMyJobType" type="gram:gramMyJobEnumerationType">
        <xsd:annotation>
            <xsd:documentation>
                * unimplemented *
                This specifies how the gram myjob interface will
                behave in the started processes. Possible values are
                independent (Even if the count > 1, only start 1
                process or thread), or collective (gram_myjob_count()
                will return count for each of the processes.
                gram_myjob_rank() will return a unique value between 0
                and count-1 for each of the processes.)
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="dryRun" type="rsl:booleanType">
        <xsd:annotation>
            <xsd:documentation>
                * unimplemented *
                If dryrun = yes then the jobmanager will not submit the
                job for execution and will return success.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="remoteIoUrl" type="rsl:urlType">
        <xsd:annotation>
            <xsd:documentation>
                Writes the given value (a URL base string) to a file,
                and adds the path to that file to the environment
                through the GLOBUS_REMOTE_IO_URL environment variable.
                If this is specified as part of a job restart RSL, the
                job manager will update the file's contents. This is
                intended for jobs that want to access files via GASS,
                but the URL of the GASS server has changed due to a
                GASS server restart.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="fileStageIn" type="rsl:fileInputArrayType">
        <xsd:annotation>
            <xsd:documentation>
                Specifies a list of ("remote URL" "local file") pairs
                which indicate files to be staged to the nodes which
                will run the job.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="fileStageInShared" type="rsl:fileInputArrayType">
        <xsd:annotation>
            <xsd:documentation>
                Specifies a list of ("remote URL" "local file") pairs
                which indicate files to be staged into the cache. A
                symlink from the cache to the "local file" path will
                be made.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="fileStageOut" type="rsl:fileOutputArrayType">
        <xsd:annotation>
            <xsd:documentation>
                Specifies a list of ("local file" "remote URL") pairs
                which indicate files to be staged from the job to a
                GASS-compatible file server.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="gassCache" type="rsl:pathType">
        <xsd:annotation>
            <xsd:documentation>
                Specifies location to override the GASS cache location.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="fileCleanUp" type="rsl:pathArrayType">
        <xsd:annotation>
            <xsd:documentation>
                Specifies a list of files which will be removed after
                the job is completed.
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>

    <xsd:element name="scratchDir" type="rsl:pathType">
        <xsd:annotation>
            <xsd:documentation>
                Specifies the location to create a scratch subdirectory
                in. A SCRATCH_DIRECTORY RSL substitution will be filled
                with the name of the directory which is created
            </xsd:documentation>
        </xsd:annotation>
    </xsd:element>


    <!--=====================================================================-->
    <!--          model groups for GRAM attribute collections                -->
    <!--=====================================================================-->

    <!-- attributes directly related to the running of the executable -->
    <xsd:group name="executableAttributes">
        <xsd:sequence>
            <xsd:element    ref="gram:executable"
                            minOccurs="1"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:directory"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:arguments"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:environment"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:stdin"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:stdout"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:stderr"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:count"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:libraryPath"
                            minOccurs="0"
                            maxOccurs="1"/>
        </xsd:sequence>
    </xsd:group>

    <!-- attributes related to SMP jobs -->
    <xsd:group  name="smpAttributes">
        <xsd:sequence>
            <xsd:element    ref="gram:hostCount"
                            minOccurs="0"
                            maxOccurs="1"/>
        </xsd:sequence>
    </xsd:group>

    <!-- attributes for interfacing with schedulers -->
    <xsd:group  name="schedulerAttributes">
        <xsd:sequence>
            <xsd:element    ref="gram:project"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:queue"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:maxTime"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:maxWallTime"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:maxCpuTime"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:maxMemory"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:minMemory"
                            minOccurs="0"
                            maxOccurs="1"/>
        </xsd:sequence>
    </xsd:group>

    <!-- attributes for specifying the type of job to run -->
    <xsd:group  name="jobTypeAttributes">
        <xsd:sequence>
            <xsd:element    ref="gram:jobType"
                            minOccurs="0"
                            maxOccurs="1"/>
        </xsd:sequence>
    </xsd:group>

    <!-- attributes which were used before but are currently ignored
         because of currently unimplemented features -->
    <xsd:group  name="unimplementedAttributes">
        <xsd:sequence>
            <xsd:element    ref="gram:gramMyJobType"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:dryRun"
                            minOccurs="0"
                            maxOccurs="1"/>
        </xsd:sequence>
    </xsd:group>
        
    <!-- attributes related to the staging of files in or out -->
    <xsd:group  name="fileStagingAttributes">
        <xsd:sequence>
            <xsd:element    ref="gram:remoteIoUrl"
                            minOccurs="0"
                            maxOccurs="1"/>
            <xsd:element    ref="gram:fileStageIn"
                            minOccurs="0"
                            maxOccurs="1"/>

            <!-- Specifies a list of ("remote URL" "local file") pairs
                 which indicate files to be staged into the cache. A
                 symlink from the cache to the "local file" path will
                 be made.
              -->
            <xsd:element    ref="gram:fileStageInShared"
                            minOccurs="0"
                            maxOccurs="1"/>

            <!-- Specifies a list of ("local file" "remote URL") pairs
                 which indicate files to be staged from the job to a
                 GASS-compatible file server.
              -->
            <xsd:element    ref="gram:fileStageOut"
                            minOccurs="0"
                            maxOccurs="1"/>

            <!-- Specifies location to override the GASS cache location.
              -->
            <xsd:element    ref="gram:gassCache"
                            minOccurs="0"
                            maxOccurs="1"/>
        </xsd:sequence>
    </xsd:group>
        
    <!-- attributes related to job clean up -->
    <xsd:group  name="cleanUpAttributes">
        <xsd:sequence>
            <xsd:element    ref="gram:fileCleanUp"
                            minOccurs="0"
                            maxOccurs="1"/>
        </xsd:sequence>
    </xsd:group>

    <!-- attributes related to the setup of a job workspace -->
    <xsd:group  name="workspaceAttributes">
        <xsd:sequence>
            <xsd:element    ref="gram:scratchDir"
                             minOccurs="0"
                             maxOccurs="1"/>
        </xsd:sequence>
    </xsd:group>


    <!-- GRAM job attributes type definition -->
    <xsd:complexType name="jobType">
        <xsd:complexContent>
            <xsd:extension base="rsl:contentType">
                <xsd:sequence>
                    <xsd:group ref="gram:executableAttributes"/>
                    <xsd:group ref="gram:smpAttributes"/>
                    <xsd:group ref="gram:schedulerAttributes"/>
                    <xsd:group ref="gram:jobTypeAttributes"/>
                    <xsd:group ref="gram:fileStagingAttributes"/>
                    <xsd:group ref="gram:cleanUpAttributes"/>
                    <xsd:group ref="gram:workspaceAttributes"/>
                    <xsd:group ref="gram:unimplementedAttributes"/>
                </xsd:sequence>

                <!-- id and ref allow one job to refer to another job, used to
                     support parallelism/sequencing of jobs and for
                     barrier/rendezvous purposes.
                    Not immediatley apparent how they map to legacy rsl
                    semantics, but I am sure we will find a use for them -->
                <!-- <xsd:attribute name="id" type="xsd:ID" use="optional"/> -->
                <xsd:attribute name="id" type="xsd:string" use="optional"/>

                <!-- <xsd:attribute name="ref" type="xsd:IDREF" use="optional"/>
                -->
                <xsd:attribute name="ref" type="xsd:string" use="optional"/>

            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="jobAndAnyType">
        <xsd:complexContent>
            <xsd:extension base="gram:jobType">
                <xsd:sequence>
                    <xsd:any        namespace="##any"
                                    minOccurs="0"
                                    maxOccurs="unbounded"
                                    processContents="lax"/>
                </xsd:sequence>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>


    <xsd:element name="job"
                 type="gram:jobAndAnyType"
                 substitutionGroup="rsl:content"/>

</xsd:schema>

