<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema id="scopeSpecification" version="1.0" xml:lang="en"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:indus="http://indus.projects.cis.ksu.edu/indus"
    targetNamespace="http://indus.projects.cis.ksu.edu/indus"
    elementFormDefault="qualified"
    attributeFormDefault="qualified"
    blockDefault="restriction"
    finalDefault="restriction">

	<xsd:simpleType id="scopeExtensionType" name="scopeExtensionType">
      <xsd:annotation>
        <xsd:documentation>
          This represents the scope around the specified type.
          EXCLUSIVE_ values indicate the all relatives of the specified type except the specified type.
          INCLUSIVE_ values indicate the all relatives of the specified type including the specified type.
          IDENTITY indicates that only the specified type is considered.
          PRIMITIVE should only be used for java primitive types, void, and array types.
        </xsd:documentation>
      </xsd:annotation>
      <xsd:restriction base="xsd:token">
        <xsd:enumeration value="EXCLUSIVE_ANCESTORS"/>
        <xsd:enumeration value="EXCLUSIVE_DESCENDANTS"/>
        <xsd:enumeration value="INCLUSIVE_ANCESTORS"/>
        <xsd:enumeration value="INCLUSIVE_DESCENDANTS"/>
        <xsd:enumeration value="IDENTITY"/>
        <xsd:enumeration value="PRIMITIVE"/>
      </xsd:restriction>
    </xsd:simpleType>

	<xsd:simpleType id="accessSpecType" name="accessSpecType">
      <xsd:annotation>
        <xsd:documentation>
          This represents access specification type.
        </xsd:documentation>
      </xsd:annotation>
      <xsd:restriction base="xsd:token">
        <xsd:enumeration value="PRIVATE_ACCESS"/>
        <xsd:enumeration value="PROTECTED_ACCESS"/>
        <xsd:enumeration value="PUBLIC_ACCESS"/>
        <xsd:enumeration value="DEFAULT_ACCESS"/>
      </xsd:restriction>
    </xsd:simpleType>

	<xsd:complexType id="typeSpecType" name="typeSpecType">
		<xsd:annotation>
    	    <xsd:documentation>
    	    This represents the the name specification of the type along with the scope rooted at the matching types.
			Depending on the value of "scopeExtension" either the type or it's relatives are considered.
			"nameSpec" is a regex pattern that specifies the type name.
			If "scopeExtension" is PRIMITIVE then "nameSpec" should be one of the primitive types, void, or the array
			type such as java.lang.String[.
			For all values of "scopeExtension" other than IDENTITY, "nameSpec" will be treated as a string. Hence, in
			these cases, "nameSpec" value should be the FQN of the classes specified as types or the names of java
			primitive types.
			"nameSpec" can be treated as regex in case of EXCLUSIVE_ and INCLUSIVE_ scope, however, it would
			costly to evaluate the scope.
			In the case where "scopeExtension" is IDENTITY, "nameSpec" is treated as a regex pattern.
    	    </xsd:documentation>
    	</xsd:annotation>
		<xsd:attribute name="scopeExtension" type="indus:scopeExtensionType" use="required" />
		<xsd:attribute name="nameSpec" type="xsd:string" use="required" />
	</xsd:complexType>

	<xsd:element name="typeSpec" id="typeSpec" type="indus:typeSpecType"/>

	<xsd:complexType id="typeSpecSequenceType" name="typeSpecSequenceType">
		<xsd:sequence>
			<xsd:element ref="indus:typeSpec" minOccurs="0" maxOccurs="unbounded"/>
		</xsd:sequence>
	</xsd:complexType>

    <xsd:attribute name="specName" type="xsd:string"/>

	<xsd:complexType id="abstractSpecType" name="abstractSpecType">
		<xsd:annotation>
    	    <xsd:documentation>
        		This captures attributes common to all specification types.
    		</xsd:documentation>
	    </xsd:annotation>
	    <xsd:sequence>
	    	<xsd:element name="accessSpec" type="indus:accessSpecType" minOccurs="1" maxOccurs="4"/>
	    </xsd:sequence>
		<xsd:attribute ref="indus:specName" use="required"/>
		<xsd:attribute name="inclusion" type="xsd:boolean" use="optional" default="true">
			<xsd:annotation>
				<xsd:documentation>
				This indicates if this scope should be interpreted as inclusive or exclusive.
				</xsd:documentation>
			</xsd:annotation>
		</xsd:attribute>
	</xsd:complexType>

	<xsd:complexType id="classSpecType" name="classSpecType">
		<xsd:annotation>
    	    <xsd:documentation>
        		This captures class/interface-level scope information.
    		</xsd:documentation>
	    </xsd:annotation>
	    <xsd:complexContent>
		    <xsd:extension base="indus:abstractSpecType">
				<xsd:sequence>
					<xsd:element ref="indus:typeSpec" minOccurs="1" maxOccurs="1"/>
				</xsd:sequence>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

	<xsd:complexType id="methodSpecType" name="methodSpecType">
		<xsd:annotation>
    	    <xsd:documentation>
        		This captures method-level scope information.  The method name is a regular expression.
    		</xsd:documentation>
	    </xsd:annotation>
	    <xsd:complexContent>
  	    	<xsd:extension base="indus:abstractSpecType">
				<xsd:sequence>
					<xsd:element name="declaringClassSpec" type="indus:typeSpecType" minOccurs="1" maxOccurs="1"/>
					<xsd:element name="returnTypeSpec" type="indus:typeSpecType" minOccurs="1" maxOccurs="1"/>
					<xsd:element name="parameterSpecs" type="indus:typeSpecSequenceType" minOccurs="0"
						maxOccurs="1"/>
				</xsd:sequence>
				<xsd:attribute name="methodNameSpec" type="xsd:string" use="required" />
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

	<xsd:complexType id="fieldSpecType" name="fieldSpecType">
		<xsd:annotation>
    	    <xsd:documentation>
        		This captures field-level scope information.
    		</xsd:documentation>
	    </xsd:annotation>
   	    <xsd:complexContent>
		    <xsd:extension base="indus:abstractSpecType">
				<xsd:sequence>
					<xsd:element name="declaringClassSpec" type="indus:typeSpecType" minOccurs="1" maxOccurs="1"/>
					<xsd:element name="fieldTypeSpec" type="indus:typeSpecType" minOccurs="1" maxOccurs="1"/>
				</xsd:sequence>
				<xsd:attribute name="fieldNameSpec" type="xsd:string" use="required"/>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

    <xsd:element name="scopeSpec">
    	<xsd:complexType>
	    	<xsd:sequence>
    			<xsd:element name="classSpec" type="indus:classSpecType" minOccurs="0" maxOccurs="unbounded"/>
    			<xsd:element name="methodSpec" type="indus:methodSpecType" minOccurs="0" maxOccurs="unbounded"/>
    			<xsd:element name="fieldSpec" type="indus:fieldSpecType" minOccurs="0" maxOccurs="unbounded"/>
	    	</xsd:sequence>
    		<xsd:attribute ref="indus:specName" use="required"/>
    	</xsd:complexType>
    </xsd:element>

</xsd:schema>
