<?xml version="1.0" encoding="$xmlEncoding"?>
<!-- 
    Attention: Generated code! Do not modify by hand!
    Generated by: XmlSchema.vsl (FuGE milestone 3 version) 
         
##Notes for changes for generation of FuGE milestone 3:
## 
##    Note: the anyType[] code below can be changed in the XMLSchemaMappings file.
##    
##   Note 2: if classes are set as entities, they automatically get assigned the attribute ID, this should be removed but we need to be aware that Hibernate code will expect it to be there...
##    
##    Note 3: get rid of the "_"Assoc for associations - we should make this change in the model itself... In fact I don't know if this is needed at all... going to need different rules now for how to map to Database objects...
##    
##    Note 4: For milestone 3, I think we should get rid of extending associations and go back to a simpler schema...
##    
##    Note 5: Need to change a rule so we use the XMLAttribute stereotype as we will use this in the code and here for controlling the mapping... some things possibly shouldn't be attributes e.g. storage...
##    
##    Note 6: Have... <_genericprotocol protocol_ref=""/> for cases where end multiplicity is 1 or 0..1 (see FuGE mailing list for full rules)
##    			
##    Note 7: Got rid of abstract associations so that they do not appear in the XML schema at all - this is a UML only feature...			
  -->
<xsd:schema 
    targetNamespace="http://fuge.org/core"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:fuge="http://fuge.org/core"
    elementFormDefault="qualified">
#foreach ($type in $types)
#set ($typeName = "${type.fullyQualifiedName}Type")
  <xsd:complexType name="$typeName" abstract = "${type.abstract}">
     <xsd:annotation>
          <xsd:documentation>${type.getDocumentation("")}</xsd:documentation>
		 </xsd:annotation>
#if ($type.generalization) 
    <xsd:complexContent>
     <xsd:extension base="fuge:${type.generalization.fullyQualifiedName}Type">
#end

#set( $doSeq = true)

#if ($type.associationEnds)
#foreach ($associationEnd in $type.associationEnds) 
#set ($otherEnd = $associationEnd.otherEnd)
#if ($otherEnd.navigable && ($otherEnd.type.isEnumeration()==false) && ($otherEnd.hasExactStereotype("AbstractAssociation") == false))

  #if ($doSeq) 
   <xsd:sequence>
    #set ($doSeq = false)
  #end
       
       #if($associationEnd.composition &&  ($otherEnd.hasExactStereotype("MapAssocToElement") == true) )##For these cases, the association name is required in the schema
       <xsd:element name="${otherEnd.name}" minOccurs="${otherEnd.minOccurs}" maxOccurs="1">
         <xsd:annotation>
          <xsd:documentation>${otherEnd.association.getDocumentation("")}
          </xsd:documentation>
		 </xsd:annotation>
         <xsd:complexType>
          <xsd:sequence> 
           <xsd:element ref="fuge:${otherEnd.type.name}" minOccurs="1" maxOccurs="${otherEnd.maxOccurs}"/>
	         </xsd:sequence>
         </xsd:complexType>
        </xsd:element>
       #elseif($associationEnd.composition &&  ($otherEnd.hasExactStereotype("MapAssocToElement") ==false) )##For these cases, the association name is not required in the schema
       <xsd:element ref="fuge:${otherEnd.type.name}" minOccurs="${otherEnd.minOccurs}" maxOccurs="${otherEnd.maxOccurs}"/>##Note: Need to put another elseif in here to account for not composite and show element or not...
      #elseif(($associationEnd.composition==false) &&  ($otherEnd.hasExactStereotype("MapAssocToElement") ==true) )##This is for cases, for example where there are parallel assocaitions to the same object, or the association name is needed to qualify the referenced object
       <xsd:element name="${otherEnd.name}" minOccurs="${otherEnd.minOccurs}" maxOccurs="${otherEnd.maxOccurs}"> ##made a change to this part to simply a reference to elements e.g. rather than <_genericProtocol><Protocol_ref identifier_ref = "XYZ"/> It is now <_genericProtocol GenericProtocol_ref = ""/>
         <xsd:annotation>
          <xsd:documentation>This is a reference to an object (or its subclasses) of type: ${otherEnd.association.getDocumentation("")}</xsd:documentation>
		 </xsd:annotation>
               <xsd:complexType>
        			<xsd:attribute name="${otherEnd.type.name}_ref" use="required" type="xsd:string"/>
        	   </xsd:complexType>
        </xsd:element>
       #elseif(($associationEnd.composition==false) && $otherEnd.isMany()==true)##This is for the case of a many end on the association end... in these cases we do the same as above...
        <xsd:element name="${otherEnd.name}" minOccurs="${otherEnd.minOccurs}" maxOccurs="${otherEnd.maxOccurs}"> ##made a change to this part to simply a reference to elements e.g. rather than <_genericProtocol><Protocol_ref identifier_ref = "XYZ"/> It is now <_genericProtocol GenericProtocol_ref = ""/>
         <xsd:annotation>
          <xsd:documentation>This is a reference to an object (or its subclasses) of type: ${otherEnd.association.getDocumentation("")}</xsd:documentation>
		 </xsd:annotation>
               <xsd:complexType>
        			<xsd:attribute name="${otherEnd.type.name}_ref" use="required" type="xsd:string"/>
        	   </xsd:complexType>
        </xsd:element>
       #end
               
#end
#end


#if (!$doSeq) 
    </xsd:sequence> 
#set ($doSeq = true)
#end
#end

#foreach  ($attribute in $type.attributes)
#if(!($attribute.name  == "id"))
#if($attribute.type.isEnumeration())##use="require" is not correct...
	<xsd:attribute name="${attribute.name}" use="required">
		<xsd:simpleType>
			<xsd:restriction base="xsd:NMTOKEN">
			#set($enumValues = $attribute.type.getAttributes())
		#foreach($enum in $enumValues)
				<xsd:enumeration value="$enum.name"/>
		#end
			</xsd:restriction>
		</xsd:simpleType>
	</xsd:attribute>
#elseif($attribute.name == "storage")
 	<xsd:attribute name="storage" type="xsd:anySimpleType">
 	 <xsd:annotation>
      <xsd:documentation>${attribute.getDocumentation("")}</xsd:documentation>
	 </xsd:annotation>
    </xsd:attribute>	 
#else
#if($attribute.required) 
    <xsd:attribute name="${attribute.name}" use="required" type="xsd:${attribute.type.fullyQualifiedName}">
#else
    <xsd:attribute name="${attribute.name}" type="xsd:${attribute.type.fullyQualifiedName}">
#end
     <xsd:annotation>
      <xsd:documentation>${attribute.getDocumentation("")}</xsd:documentation>
	 </xsd:annotation>
    </xsd:attribute>	 
#end
#end##end of if for attribute "id"

#end##end of for loop for all attributes

#foreach ($associationEnd in $type.associationEnds) ##Need to run this loop again to create an attribute for any association ends with one cardinality, 
#set ($otherEnd = $associationEnd.otherEnd)
   #if(($associationEnd.composition==false) && $otherEnd.isMany()==false && ($otherEnd.hasExactStereotype("AbstractAssociation") == false) &&  $otherEnd.navigable && ($otherEnd.hasExactStereotype("MapAssocToElement") == false))##This is for the case of a many end on the association end... in these cases we do the same as above...
   #if($otherEnd.minOccurs == "1")##Note there is an error here... this is not working correctly...
    <xsd:attribute name="${otherEnd.type.name}_ref" use="required" type="xsd:string">  
  #else
    <xsd:attribute name="${otherEnd.type.name}_ref" type="xsd:string">
  #end
   <xsd:annotation>
      <xsd:documentation>${otherEnd.association.getDocumentation("")}</xsd:documentation>
	 </xsd:annotation>
    </xsd:attribute>	 
         #end

#end

#if ($type.generalization) 
    </xsd:extension>
    </xsd:complexContent>
#end

  </xsd:complexType>

  
#end

#foreach ($element in $types)
#set ($typeName = "${element.fullyQualifiedName}Type")
#if ($element.generalization) 
 <xsd:element name="$element.name" type="fuge:$typeName" abstract="$element.abstract" substitutionGroup="fuge:${element.generalization.name}" />
#else
 <xsd:element name="$element.name" type="fuge:$typeName" abstract="$element.abstract" />
#end
#end

</xsd:schema>     
