﻿<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:sobek="http://sobekrepository.org/schemas/sobekcm_config"
  targetNamespace="http://sobekrepository.org/schemas/sobekcm_config" >
	<xs:element name="SobekCM_Config">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="Connections" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element maxOccurs="unbounded" name="Connection_String">
								<xs:complexType>
									<xs:simpleContent>
										<xs:extension base="xs:string">
											<xs:attribute name="name" type="xs:string" use="optional" />
											<xs:attribute name="type" type="sobek:databaseType" use="required" />
											<xs:attribute name="active" type="xs:boolean" use="optional" />
											<xs:attribute name="canAbort" type="xs:boolean" use="optional" />
											<xs:attribute name="isHosted" type="xs:boolean" use="optional" />
										</xs:extension>
									</xs:simpleContent>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
				<xs:element name="ErrorHandling" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="ErrorEmails" type="xs:string" maxOccurs="1" />
							<xs:element name="ErrorPage" type="xs:string" maxOccurs="1" />
						</xs:sequence>
					</xs:complexType>
				</xs:element>
				<xs:element name="Builder" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Ghostscript_Executable" type="xs:string" maxOccurs="1" />
							<xs:element name="Imagemagick_Executable" type="xs:string" maxOccurs="1" />
							<xs:element name="Pause_Between_Polls" type="xs:int" maxOccurs="1" minOccurs="0" />
							<xs:element name="Publish_Logs_Directory" type="xs:string" maxOccurs="1" />
						</xs:sequence>
					</xs:complexType>
				</xs:element>
        <xs:element name="Engine" minOccurs="0" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              
              <!-- Maps URLs to methods to perform the requested transactions -->
              <xs:element name="Mapping" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="RemoveAll" minOccurs="0" maxOccurs="1" />
                    <xs:element name="Path" type="sobek:enginePath" minOccurs="0" maxOccurs="unbounded"  />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              
              <!-- Components here hold the methods referred to in the mapping above -->
              <xs:element name="Components" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="Component">
                      <xs:complexType>
                        <xs:attribute name="ID" type="xs:string" use="required" />
                        <xs:attribute name="Assembly" type="xs:string" use="optional" />
                        <xs:attribute name="Namespace" type="xs:string" use="optional" />
                        <xs:attribute name="Class" type="xs:string" use="required" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              
              <!-- Restriction ranges here can be referenced in the mapping to restrict access  to individual endpoints (or HTTP verb request types under an endpoint) by IP -->
              <xs:element name="RestrictionRanges" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="Range">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element minOccurs="0" maxOccurs="1" name="RemoveAll" />
                          <xs:element maxOccurs="unbounded" name="IpRange">
                            <xs:complexType>
                              <xs:attribute name="Label" type="xs:string" use="required" />
                              <xs:attribute name="Start" type="xs:string" use="required" />
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                        <xs:attribute name="ID" type="xs:string" use="required" />
                        <xs:attribute name="Label" type="xs:string" use="required" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            
            <!-- Attribute on the main engine element would clear any pre-existing information -->
            <xs:attribute name="ClearAll" type="xs:boolean" use="optional" default="false" />
          </xs:complexType>
        </xs:element>
				<xs:element name="Metadata" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Metadata_File_ReaderWriters" type="sobek:metadataFileReaderWriterType" minOccurs="0" maxOccurs="1" />
							<xs:element name="METS_Sec_ReaderWriters" type="sobek:metsSectionReaderWritersType" minOccurs="0" maxOccurs="1" />
							<xs:element name="METS_Writing" type="sobek:metsWritingType" minOccurs="0" maxOccurs="1" />
							<xs:element name="Additional_Metadata_Modules" type="sobek:additionalMetadataModulesType" minOccurs="0" maxOccurs="1" />
						</xs:sequence>
					</xs:complexType>
				</xs:element>
				<xs:element name="QualityControl" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Profiles" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Clear" minOccurs="0" maxOccurs="1" />
										<xs:element maxOccurs="unbounded" name="Profile" type="sobek:qcProfileType" />
									</xs:sequence>
								</xs:complexType>
							</xs:element>
							<xs:element name="Errors" minOccurs="0" maxOccurs="1">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Profile">
											<xs:complexType>
												<xs:sequence>
													<xs:element name="ErrorCategories">
														<xs:complexType>
															<xs:sequence>
																<xs:element name="Clear" minOccurs="0" maxOccurs="1" />
																<xs:element maxOccurs="unbounded" name="ErrorCategory">
																	<xs:complexType>
																		<xs:sequence>
																			<xs:element maxOccurs="unbounded" name="ErrorType">
																				<xs:complexType>
																					<xs:sequence>
																						<xs:element maxOccurs="unbounded" name="Translation">
																							<xs:complexType>
																								<xs:attribute name="language" type="xs:string" use="required" />
																								<xs:attribute name="text" type="xs:string" use="required" />
																							</xs:complexType>
																						</xs:element>
																					</xs:sequence>
																					<xs:attribute name="ErrorID" type="xs:unsignedByte" use="required" />
																					<xs:attribute name="type" type="xs:string" use="required" />
																					<xs:attribute name="isOther" type="xs:boolean" use="required" />
																				</xs:complexType>
																			</xs:element>
																		</xs:sequence>
																		<xs:attribute name="ID" type="xs:unsignedByte" use="required" />
																		<xs:attribute name="type" type="xs:string" use="required" />
																	</xs:complexType>
																</xs:element>
															</xs:sequence>
														</xs:complexType>
													</xs:element>
												</xs:sequence>
												<xs:attribute name="isDefault" type="xs:boolean" use="required" />
												<xs:attribute name="name" type="xs:string" use="required" />
												<xs:attribute name="description" type="xs:string" use="required" />
											</xs:complexType>
										</xs:element>
									</xs:sequence>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
				<xs:element name="Authentication" minOccurs="0" maxOccurs="1">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Shibboleth">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="AttributeMapping" maxOccurs="1">
											<xs:complexType>
												<xs:sequence>
													<xs:element maxOccurs="unbounded" name="Mapping">
														<xs:complexType>
															<xs:attribute name="ServerVariable" type="xs:string" use="required" />
															<xs:attribute name="UserAttribute" type="sobek:userAttributeMappingType" use="required" />
														</xs:complexType>
													</xs:element>
												</xs:sequence>
											</xs:complexType>
										</xs:element>
										<xs:element name="Constants" maxOccurs="1">
											<xs:complexType>
												<xs:sequence>
													<xs:element maxOccurs="unbounded" name="Constant">
														<xs:complexType>
															<xs:simpleContent>
																<xs:extension base="xs:string">
																	<xs:attribute name="UserAttribute" type="sobek:userAttributeMappingType" use="required" />
																</xs:extension>
															</xs:simpleContent>
														</xs:complexType>
													</xs:element>
												</xs:sequence>
											</xs:complexType>
										</xs:element>
										<xs:element name="Logic" maxOccurs="1">
											<xs:complexType>
												<xs:sequence>
													<xs:element maxOccurs="unbounded" name="CanSubmit">
														<xs:complexType>
															<xs:attribute name="ServerVariable" type="xs:string" use="required" />
															<xs:attribute name="Value" type="xs:string" use="required" />
														</xs:complexType>
													</xs:element>
												</xs:sequence>
											</xs:complexType>
										</xs:element>
									</xs:sequence>
									<xs:attribute name="UserIdentityAttribute" type="xs:string" use="required" />
									<xs:attribute name="URL" type="xs:string" use="required" />
									<xs:attribute name="Label" type="xs:string" use="required" />
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>

	<!-- ============================== CONNECTIONS SPECIFIC TYPES ======================================== -->
	<xs:simpleType name="databaseType">
		<xs:restriction base="xs:string">
			<xs:enumeration value="MSSQL" />
		</xs:restriction>
	</xs:simpleType>
  
  
  <!-- ============================== ENGINE SPECIFIC TYPES ================================== -->
  <!-- Path definition for mapping endpoints to methods/components in the SobekCM engine -->
  <xs:complexType name="enginePath">
    <xs:sequence minOccurs="0" maxOccurs="1">
      <xs:element name="RemoveAll" minOccurs="0" maxOccurs="1" />
      <xs:element name="AutoDoc" type="sobek:engineAutoDoc" minOccurs="0" maxOccurs="1" />
      <xs:sequence minOccurs="0" maxOccurs="unbounded">
        <xs:choice>
          <xs:element name="Path" type="sobek:enginePath" />
          <xs:element name="Endpoint" type="sobek:engineSimpleEndpoint" />
          <xs:element name="ComplexEndpoint" type="sobek:engineComplexEndpoint" />
        </xs:choice>
      </xs:sequence>
    </xs:sequence>
    <xs:attribute name="Segment" type="xs:string" use="required" />
  </xs:complexType>

  <!-- A simple endpoint definition for the SobekCM engine, this exposes a method to a GET request only -->
  <xs:complexType name="engineSimpleEndpoint">
    <xs:sequence minOccurs="0">
      <xs:element name="AutoDoc" type="sobek:engineAutoDoc" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="Segment" type="xs:string" use="required" />
    
    <!-- Must reference a component id in some of the config files from the Engine/Components region -->
    <xs:attribute name="ComponentID" type="xs:string" use="required" />
    <xs:attribute name="Method" type="xs:string" use="required" />
    <xs:attribute name="Enabled" type="xs:boolean" use="optional" default="true" />
    <xs:attribute name="Protocol" type="sobek:engineProtocol" use="required" />
    
    <!-- Must reference a restriction range (or multiple) in the the Engine/RestrictionRanges region.  To refer to multiple, separate with a comma or pipe (|)                         -->
    <xs:attribute name="RestrictionRangeID" type="xs:string" use="optional" />
  </xs:complexType>

  <!-- Complex endpoint definition for the SobekCM engine, this exposes a number of methods to be called based on the HTTP verb, or exposes a single non-GET request endpoint                -->
  <xs:complexType name="engineComplexEndpoint">
    <xs:sequence minOccurs="0">
      <xs:element name="AutoDoc" type="sobek:engineAutoDoc" minOccurs="0" maxOccurs="1" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="VerbMapping">
        <xs:complexType>
          <xs:attribute name="Verb" type="sobek:engineHttpVerb" use="required" />
          
          <!-- Must reference a component id in some of the config files from the Engine/Components region -->
          <xs:attribute name="ComponentID" type="xs:string" use="required" />
          <xs:attribute name="Method" type="xs:string" use="required" />
          <xs:attribute name="Enabled" type="xs:boolean" use="optional" default="true" />
          <xs:attribute name="Protocol" type="sobek:engineProtocol" use="required" />
      
          <!-- Must reference a restriction range (or multiple) in the the Engine/RestrictionRanges region.  To refer to multiple, separate with a comma or pipe (|)                         -->
          <xs:attribute name="RestrictionRangeID" type="xs:string" use="optional" />
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="Segment" type="xs:string" use="required" />
    <xs:attribute name="Enabled" type="xs:boolean" use="optional" default="true" />
    
    <!-- Must reference a restriction range (or multiple) in the the Engine/RestrictionRanges region.  To refer to multiple, separate with a comma or pipe (|)                         -->
    <xs:attribute name="RestrictionRangeID" type="xs:string" use="optional" />
  </xs:complexType>

  <!-- Exposes some basic descriptive elements that can be utilitized to automatically generate documentation for the exposed SobekCM engine endpoints                                    -->
  <xs:complexType name="engineAutoDoc">
    <xs:sequence>
      <xs:element name="Description" type="xs:string" />
      <xs:element name="RequestType" type="xs:string" />
      <xs:element name="Arguments" type="xs:string" />
      <xs:element name="Returns" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  
  <!-- List of possible protocol types -->
  <xs:simpleType name="engineProtocol">
		<xs:restriction base="xs:string">
			<xs:enumeration value="JSON" />
			<xs:enumeration value="JSON-P" />
			<xs:enumeration value="PROTOBUF" />
			<xs:enumeration value="XML" />
		</xs:restriction>
  </xs:simpleType>

  <!-- List of HTTP verb types -->
  <xs:simpleType name="engineHttpVerb">
		<xs:restriction base="xs:string">
			<xs:enumeration value="DELETE" />
			<xs:enumeration value="GET" />
			<xs:enumeration value="POST" />
			<xs:enumeration value="PUT" />
		</xs:restriction>
  </xs:simpleType>  

	<!-- ============================== METADATA STANDARD SPECIFIC TYPES ================================== -->
	<xs:complexType name="metadataFileReaderWriterType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="ReaderWriter">
				<xs:complexType>
					<xs:sequence minOccurs="0">
						<xs:element name="Options">
							<xs:complexType>
								<xs:sequence>
									<xs:element maxOccurs="unbounded" name="Option">
										<xs:complexType>
											<xs:attribute name="key" type="xs:string" use="required" />
											<xs:attribute name="value" type="xs:string" use="required" />
										</xs:complexType>
									</xs:element>
								</xs:sequence>
							</xs:complexType>
						</xs:element>
					</xs:sequence>
					<xs:attribute name="mdtype" type="sobek:metadataFileStandardTypes" use="required" />
					<xs:attribute name="label" type="xs:string" use="required" />
					<xs:attribute name="canRead" type="xs:boolean" use="required" />
					<xs:attribute name="canWrite" type="xs:boolean" use="required" />
					<xs:attribute name="namespace" type="xs:string" use="required" />
					<xs:attribute name="class" type="xs:string" use="required" />
					<xs:attribute name="assembly" type="xs:string" use="optional" />
					<xs:attribute name="othermdtype" type="xs:string" use="optional" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="metsSectionReaderWritersType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="ReaderWriter">
				<xs:complexType>
					<xs:sequence minOccurs="0">
						<xs:element name="Options" minOccurs="0" maxOccurs="1">
							<xs:complexType>
								<xs:sequence>
									<xs:element maxOccurs="unbounded" name="Option">
										<xs:complexType>
											<xs:attribute name="key" type="xs:string" use="required" />
											<xs:attribute name="value" type="xs:string" use="required" />
										</xs:complexType>
									</xs:element>
								</xs:sequence>
							</xs:complexType>
						</xs:element>
						<xs:element name="Mappings" minOccurs="0" maxOccurs="1">
							<xs:complexType>
								<xs:sequence>
									<xs:element maxOccurs="unbounded" name="Mapping">
										<xs:complexType>
											<xs:attribute name="mdtype" type="xs:string" use="required" />
											<xs:attribute name="othermdtype" type="xs:string" use="optional" />
											<xs:attribute name="label" type="xs:string" use="optional" />
											<xs:attribute name="isDefault" type="xs:boolean" use="optional" default="false" />
										</xs:complexType>
									</xs:element>
								</xs:sequence>
							</xs:complexType>
						</xs:element>
					</xs:sequence>
					<xs:attribute name="ID" type="xs:string" use="optional" />
					<xs:attribute name="label" type="xs:string" use="required" />
					<xs:attribute name="namespace" type="xs:string" use="required" />
					<xs:attribute name="class" type="xs:string" use="required" />
					<xs:attribute name="assembly" type="xs:string" use="optional" />
					<xs:attribute name="isActive" type="xs:boolean" use="optional" default="true" />
					<xs:attribute name="section" type="sobek:metsSection" use="required"  />
					<xs:attribute name="amdSecType" type="sobek:amdSectionType" use="optional"  />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="metsWritingType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="Profile">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="Package_Scope" type="sobek:metsWriterScopeType" minOccurs="0" maxOccurs="1" />
						<xs:element name="Division_Scope" type="sobek:metsWriterScopeType" minOccurs="0" maxOccurs="1" />
						<xs:element name="File_Scope" type="sobek:metsWriterScopeType" minOccurs="0" maxOccurs="1"  />
					</xs:sequence>
					<xs:attribute name="isDefault" type="xs:boolean" use="optional" default="false" />
					<xs:attribute name="name" type="xs:string" use="required" />
					<xs:attribute name="description" type="xs:string" use="optional" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="additionalMetadataModulesType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="MetadataModule">
				<xs:complexType>
					<xs:attribute name="key" type="xs:string" use="required" />
					<xs:attribute name="assembly" type="xs:string" use="optional" />
					<xs:attribute name="namespace" type="xs:string" use="required" />
					<xs:attribute name="class" type="xs:string" use="required" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:simpleType name="metadataFileStandardTypes">
		<xs:restriction base="xs:string">
			<xs:enumeration value="DC" />
			<xs:enumeration value="EAD" />
			<xs:enumeration value="MARC21" />
			<xs:enumeration value="MARCXML" />
			<xs:enumeration value="METS" />
			<xs:enumeration value="MODS" />
			<xs:enumeration value="OTHER" />
		</xs:restriction>
	</xs:simpleType>

	<xs:complexType name="metsWriterScopeType">
		<xs:sequence>
			<xs:element name="dmdSec" type="sobek:metsWriterRefType" minOccurs="0" maxOccurs="1" />
			<xs:element name="amdSec" type="sobek:metsWriterRefType" minOccurs="0" maxOccurs="1" />
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="metsWriterRefType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="ReaderWriterRef">
				<xs:complexType>
					<xs:attribute name="ID" type="xs:string" use="required" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:simpleType name="metsSection">
		<xs:restriction base="xs:string">
			<xs:enumeration value="dmdSec" />
			<xs:enumeration value="amdSec" />
		</xs:restriction>
	</xs:simpleType>

	<xs:simpleType name="amdSectionType">
		<xs:restriction base="xs:string">
			<xs:enumeration value="rightsMD" />
			<xs:enumeration value="sourceMD" />
			<xs:enumeration value="digiProvMD" />
			<xs:enumeration value="techMD" />
		</xs:restriction>
	</xs:simpleType>

	<!-- ============================== QUALITY CONTROL SPECIFIC TYPES ================================== -->
	<xs:complexType name="qcProfileType">
		<xs:sequence>
			<xs:element maxOccurs="unbounded" name="DivisionType">
				<xs:complexType>
					<xs:sequence minOccurs="0">
						<xs:element maxOccurs="unbounded" name="Translation">
							<xs:complexType>
								<xs:attribute name="language" type="xs:string" use="required" />
								<xs:attribute name="text" type="xs:string" use="required" />
							</xs:complexType>
						</xs:element>
					</xs:sequence>
					<xs:attribute name="DivisionID" type="xs:int" use="required" />
					<xs:attribute name="type" type="xs:string" use="required" />
					<xs:attribute name="isActive" type="xs:boolean" use="optional" default="true" />
					<xs:attribute name="isNameable" type="xs:boolean" use="required" />
					<xs:attribute name="base" type="xs:string" use="optional" />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
		<xs:attribute name="isDefault" type="xs:boolean" use="optional" default="false" />
		<xs:attribute name="name" type="xs:string" use="required" />
		<xs:attribute name="description" type="xs:string" use="required" />
	</xs:complexType>



	<!-- ============================== AUTHENTICATION SPECIFIC TYPES ================================== -->
	<xs:simpleType name="userAttributeMappingType">
		<xs:restriction base="xs:string">
			<xs:enumeration value="USERNAME" />
			<xs:enumeration value="EMAIL" />
			<xs:enumeration value="FIRSTNAME" />
			<xs:enumeration value="LASTNAME" />
			<xs:enumeration value="NICKNAME" />
			<xs:enumeration value="NOTES" />
			<xs:enumeration value="ORGANIZATION" />
			<xs:enumeration value="ORGCODE" />
			<xs:enumeration value="COLLEGE" />
			<xs:enumeration value="DEPARTMENT" />		
		</xs:restriction>
	</xs:simpleType>
	
	
</xs:schema>