<?xml version="1.0" encoding="UTF-8"?>

<xs:schema version="2.0"
	targetNamespace="http://futurs.inria.fr/gemo/axml/"
	xmlns:axml="http://futurs.inria.fr/gemo/axml/"
	xmlns="http://futurs.inria.fr/gemo/axml/"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	elementFormDefault="qualified"
	attributeFormDefault="unqualified">
	
	<xs:annotation>
		<xs:documentation>
		This schema specifies how a service call should look like
		</xs:documentation>
	</xs:annotation>

	<!-- Service call -->
	<xs:element name="sc" type="ServiceCallType">
		<xs:annotation><xs:documentation>
			With this tag you can declare a service call inside a document. The service call then can be
			passed to the engine for materialization. The engine parses every service call tag in a document and
			proceeds with respect to what is declared within the tag, in other words this tag holds all the configuration
			needed for the execution engine. 
			
			As theoretically a service call looks like a call to a function on a web the syntax resembles 
			a function call in a programming language, for example:
			a) return void soap(http://address/to/Web/service)
			b) return append rest(http://address/to/Web/service)
		</xs:documentation></xs:annotation>
	</xs:element>
	
	<xs:complexType name="ServiceCallType" mixed="false">
		<xs:sequence>
			<xs:element minOccurs="0" name="meta">
				<xs:annotation><xs:documentation>
					Any descriptive information. For instance, 
					it could be used for giving a comment for a service call. Other systems that know about 
					active documents can use this part for passing meaningful information during the execution process, 
					e.g. an optimizer can append the details about where (which peer and document) 
					the service call is being executed.
					This tag does not affect the normal execution of the service call.
				</xs:documentation></xs:annotation>
				<xs:complexType mixed="true">
					<xs:sequence>
						<xs:any maxOccurs="unbounded" namespace="##other" processContents="lax"></xs:any>
					</xs:sequence>
				</xs:complexType>
			</xs:element>
			<xs:element minOccurs="0" name="activation" type="ActivationType">
				<xs:annotation><xs:documentation>
					The tag holds information about how the service call should be executed and what its current status.
					Materializing a service call means that it is first activated, then it is running and finally it terminates (or fails).
					Also some ordering constraints can be imposed for service calls, however, this feature should be used with caution in
					order to avoid loops.
					In the simplest case this tag can initially be absent.
				</xs:documentation></xs:annotation>			
			</xs:element>
			<xs:element name="return" minOccurs="0">
			<xs:annotation><xs:documentation>
				Roughly Web services can be split into two groups: IN-Only and IN-OUT (as defined in WSDL Message Exchange Patterns). 
				The former means that the Web service 
				does not return any message in a response (except faults), the latter means that a Web service 
				returns some message.
				Accordingly, service calls can be seen as OUT-Only and OUT-IN. The former means that the service call should not expect any results,
				while the latter means that results will arrive and will have to be merged into the document.
				The absence of this tag implies OUT-Only service call.
			</xs:documentation></xs:annotation>
				<xs:complexType>
					<xs:sequence>
						<xs:choice>
							<xs:element name="void">
								<xs:annotation><xs:documentation>
									Equivalent to not specifying the 'return' element at all. 
								</xs:documentation></xs:annotation>
								<xs:complexType>
									<xs:sequence></xs:sequence>
								</xs:complexType>
							</xs:element>
							<xs:group ref="MergeFunctions">
								<xs:annotation>
								<xs:documentation>There are many ways of merging incoming results into the document, the simplest 
								one is to append the results next to the service call.</xs:documentation>
								</xs:annotation>
							</xs:group>
						</xs:choice>
						<xs:element name="valid" minOccurs="0">
							<xs:annotation>
								<xs:documentation>
								The validity of results of a service call can be handled internally. This implementation 
								allows to specify the time interval when the result should be deleted. In the future 
								tracking of results might be delegated to a specialized service. For instance, some caching 
								service could be responsible for clearing the out-dated results.
								When nothing about validity is said, it is assumed that result is
								valid forever (but it means nothing if the results are not merged; see 'return' tag).
								</xs:documentation>
							</xs:annotation>
							<xs:complexType>
								<xs:choice>
									<xs:element name="for">
										<xs:complexType>
												<xs:attributeGroup ref="TimeIntervalSpecification">
													<xs:annotation>
													<xs:documentation>
														Here the actual values of the validity interval are specified.
													</xs:documentation>
													</xs:annotation>
												</xs:attributeGroup>
										</xs:complexType>
									</xs:element>
								</xs:choice>
							</xs:complexType>
						</xs:element>
					</xs:sequence>
					<xs:attribute name="materializer" use="optional">
						<xs:annotation>
						<xs:documentation>
						This is quite an advanced feature. It is sometimes the case that the default way of calling a 
						Web service is not enough or inefficient; for instance, theoretically every peer has SEND and RECEIVE 
						Web services used for passing data around, however, calling SEND using a service call is not the same as calling
						some other stateless service on the Web because of its streaming nature. 
						Therefore in this attribute different implementations of materialization behavior can be specified. 
						
						I.e. here we give the full calss name of the materializer. Currently these are subclasses of:
						fr.inria.gemo.axml.model.sc.materialization.AbstractOutOnlyMaterializer,
						fr.inria.gemo.axml.model.sc.materialization.AbstractOutInMaterializer
						
						When the attribute is not specified the default materializer is used:
						fr.inria.gemo.axml.model.sc.materialization.DefaultOutOnlyMaterializer,
						fr.inria.gemo.axml.model.sc.materialization.DefaultOutInMaterializer
						
						SEND, RECEIVE and QUERY services have their own materializers, and using the default materializer 
						with these services can cause unexpected outcome. The attribute is not designed for simple users but 
						rather for systems leveraging ActiveXML.
						</xs:documentation>
						</xs:annotation> 
					</xs:attribute>
				</xs:complexType>
			</xs:element>
			<xs:group ref="WebServiceInvocations" minOccurs="1">
				<xs:annotation>
				<xs:documentation>
				Here we mainly specify the endpoint and actual parameters of a Web service
				</xs:documentation>
				</xs:annotation>
			</xs:group>
		</xs:sequence>
		
		<!-- System attributes -->
		<xs:attributeGroup ref="SystemServiceCallAttributes"></xs:attributeGroup>
		
		<!-- P2P ids -->
		<xs:attribute ref="axml:peerID"  use="optional"></xs:attribute>
		<xs:attribute ref="axml:docID"  use="optional"></xs:attribute>
		<xs:attribute ref="axml:nodeID"  use="optional"></xs:attribute>
		
		<xs:anyAttribute namespace="##targetNamespace">
			<xs:annotation><xs:documentation>
				As service calls themselves can be a result of a service call they should be markable by the system namespace attributes, 
				since currently to identify a result node a couple of attributes are used (see 'result' tag)
			</xs:documentation></xs:annotation>
		</xs:anyAttribute>
	</xs:complexType>
	
	<!-- Current node id -->
	<xs:attribute name="id" type="xs:ID">
		<xs:annotation><xs:documentation>
			This is an id of a service call in a document, aka current-node-id. In a distributed environment a notion of currentID and
			originalID was introduced where the currentID is a tripple (current-peer-id, current-document-id, current-node-id).
			Since any node at any point of time is on some peer in some document on the implementation level it is enough to keep
			only the current-node-id attribute (that is this attribute). The originalID, on the other hand, has all the three attributes
			denoting the triple (original-peer-id, original-document-id, original-node-id) (see attributes 'peerID', 'docID', 'nodeID'). 
			The original ID is needed to have consistent referencing mechanism inside all the active documents in P2P system.
			  
			It is of the qualified form because there may be also other (non service call) nodes that 
			need a currentID. The engine assures that
			whenever this id changes the references to it (within the document) are also updated. This is important when data is travel 
			from one document to another inside the P2P network. For instance, when a service call is to be inserted into a document
			that already has another service call with the same id the incoming id must change to be unique within resulting document.
			
			So when the id changes the following things are updated:
			1) the results that belong to the service call that is being changed
			2) the constraints specified inside 'activation' tag
			The details are in UpdatingOperator class.
		</xs:documentation></xs:annotation>
	</xs:attribute>
	
	<!-- Original node id -->
	<xs:attribute name="nodeID" type="xs:string">
		<xs:annotation><xs:documentation>
			The value denotes the first id that the node was assigned (i.e. the first current-node-id)
		</xs:documentation></xs:annotation>
	</xs:attribute>
	
	<!-- Original document id -->
	<xs:attribute name="docID" type="xs:string">
		<xs:annotation><xs:documentation>
			The id of a document that the original service call belonged to (i.e. the first current-document-id)
		</xs:documentation></xs:annotation>
	</xs:attribute>
	
	<!-- Original peer id -->
	<xs:attribute name="peerID" type="xs:string">
		<xs:annotation><xs:documentation>
			The id of a peer that the document with the original service call belonged to (i.e. the first current-peer-id)
		</xs:documentation></xs:annotation>
	</xs:attribute>
	
	<xs:attributeGroup name="SystemServiceCallAttributes">
		<xs:attribute name="activated" type="xs:dateTime" use="optional" form="unqualified">
			<xs:annotation><xs:documentation>
				The timestamp of when the service call was activated (started to be materialized). The execution engine
				assigns this attribute. 
				It is useful for debugging, as well as for tracking the validity of service call results.
			</xs:documentation></xs:annotation>
		</xs:attribute>
		<xs:attribute ref="axml:id" use="required"></xs:attribute>
	</xs:attributeGroup>
	
	<!-- Web service invocations -->
	<xs:complexType name="SOAPWebServiceType" mixed="false">
		<xs:sequence minOccurs="1">
			<xs:any minOccurs="1" maxOccurs="1" namespace="##other" processContents="lax">
				<xs:annotation><xs:documentation>
					rpc/lit and doc/lit-wrapped messages in SOAP envelope body must be supported (this is the future of WSDL).
					This is pretty much enough because rpc/enc and doc/lit-unwrapped are not WS-I compliant.
					Thus here an actual message body (the payload) should go. According to conventions the element name coincides 
					with the Web service operation name.
				</xs:documentation></xs:annotation>
			</xs:any>
		</xs:sequence>
		<xs:attributeGroup ref="WebServiceSpecification"></xs:attributeGroup>
	</xs:complexType>
	
	<xs:complexType name="RESTWebServiceType" mixed="false">
		<xs:sequence minOccurs="0">
			<xs:any minOccurs="0" maxOccurs="1" namespace="##other" processContents="lax">
				<xs:annotation><xs:documentation>
					Here goes the message that is POST'ed to the service using 'application/xml' encoding. This is actually
					how the XForms are submitted by default.
				</xs:documentation></xs:annotation>
			</xs:any>			
		</xs:sequence>
		<xs:attributeGroup ref="WebServiceSpecification"></xs:attributeGroup>
	</xs:complexType>
	
	<xs:group name="WebServiceInvocations">
		<xs:choice>
			<xs:element name="ws-soap" type="SOAPWebServiceType">
				<xs:annotation><xs:documentation>
					Allows to call a Web service using SOAP by providing only the body of the message.
				</xs:documentation> </xs:annotation>
			</xs:element>
			<xs:element name="ws-rest" type="RESTWebServiceType">
				<xs:annotation>
					<xs:documentation>
						Allows to call a Web service the REST way. When the payload is given it is POST'ed otherwise
						it is GET'ed
					</xs:documentation>
				</xs:annotation>
			</xs:element>
			<!-- IMPORTANT:
			At least one more invocation method is needed, i.e. invocation via SOAP by passing the whole envelope. This 
			would provide the universal way of calling a Web service.
			-->
		</xs:choice>
	</xs:group>
	
	<xs:attributeGroup name="WebServiceSpecification">
		<xs:attribute name="wsdl" use="optional">
			<xs:annotation>
			<xs:documentation>
				Normally the wsdl is not needed. However, for some applications, like type checking or GUI it would be 
				crucial for consulting the types and validating. It also sometimes needed to extract some properties
				like soapAction in order to successfully call the Web service.
			</xs:documentation>
			</xs:annotation>
			<xs:simpleType>
				<xs:restriction base="xs:anyURI">
					<xs:whiteSpace value="collapse"/>
					<xs:minLength value="1"></xs:minLength>
				</xs:restriction>
			</xs:simpleType>
		</xs:attribute>
		<xs:attribute name="endpoint" use="required">
			<xs:annotation>
			<xs:documentation>
				The endpoint reference of the Web service. Normally it is an HTTP address. When other
				communication protocols are used additional configuration might be required for Axis2
			</xs:documentation>
			</xs:annotation>
			<xs:simpleType>
				<xs:restriction base="xs:anyURI">
					<xs:whiteSpace value="collapse"/>
					<xs:minLength value="1"></xs:minLength>
				</xs:restriction>
			</xs:simpleType>
		</xs:attribute>
	</xs:attributeGroup>
	
	<xs:attributeGroup name="TimeIntervalSpecification">
		<xs:attribute name="days" type="xs:nonNegativeInteger" use="optional" default="0"></xs:attribute>
		<xs:attribute name="hours" type="xs:nonNegativeInteger" use="optional" default="0"></xs:attribute>
		<xs:attribute name="minutes" type="xs:nonNegativeInteger" use="optional" default="60"></xs:attribute>
		<xs:attribute name="seconds" type="xs:nonNegativeInteger" use="optional" default="0"></xs:attribute>
	</xs:attributeGroup>
	
	<!-- Service call configuration -->
	<xs:complexType name="ActivationType">
		<xs:choice minOccurs="0">
			<xs:choice minOccurs="0">
				<xs:element name="once">
					<xs:annotation><xs:documentation>
							The service call will be (scheduled and) executed only if it does not have a marked execution time.
					</xs:documentation></xs:annotation>
					<xs:complexType>
						<xs:attribute name="on" type="xs:dateTime" use="optional"></xs:attribute>
					</xs:complexType>
				</xs:element>
				<xs:element name="every">
					<xs:annotation>
					<xs:documentation>
						Depends on the last execution of the service call. In terms of streams the recurrent nature of this way
						of activation means that the stream is never ending even if an end-of-stream message arrives 
						the scheduling is not canceled.
					</xs:documentation>
					</xs:annotation>
					<xs:complexType>
						<xs:attributeGroup ref="TimeIntervalSpecification"></xs:attributeGroup>
					</xs:complexType>
				</xs:element>
			</xs:choice>
			<xs:sequence>
				<xs:element name="afterActivated" minOccurs="0" maxOccurs="unbounded">
					<xs:annotation><xs:documentation>
						Serves to create a chain of execution. For non-streaming service calls this coincide with afterTerminated, otherwise 
						it means something like "after got 'OK' from server"
					</xs:documentation></xs:annotation>
					<xs:complexType>
						<xs:attribute name="sc" type="xs:string" use="required">
							<xs:annotation><xs:documentation>
								The xs:IDREF type is not used on purpose, because the whole document is normally not kept
								in memory, therefore the reference would not make sense.
							</xs:documentation></xs:annotation>
						</xs:attribute>
					</xs:complexType>		
				</xs:element>
				<xs:element name="afterTerminated" minOccurs="0" maxOccurs="unbounded">
					<xs:complexType>
						<xs:attribute name="sc" type="xs:string" use="required">
						</xs:attribute>
					</xs:complexType>	
				</xs:element>
			</xs:sequence>
		</xs:choice>
		<xs:attribute name="status" use="optional" default="ENABLED">
			<xs:annotation><xs:documentation>
				A service call is activated starting with a "click" until the end-of-stream. Then it becomes terminated.
				So on subscription to a stream the receiving service call must be marked as activated. A "running" document has
				at least one activated service call. For simple (non-streaming) service calls the termination coinsides with the first response.
				IMPORTANT [Not implemented]:
				When publishing a running document it first should be determined if the activated service calls inside it are really active.
				This usecase can appear when recovering a system from the failure or after turning it OFF and ON again.
			</xs:documentation></xs:annotation>
			<xs:simpleType>
				<xs:restriction base="xs:string">
					<xs:enumeration value="ENABLED"><xs:annotation><xs:documentation>
						Means that the service call can be activated
					</xs:documentation> </xs:annotation></xs:enumeration>
					<xs:enumeration value="DISABLED">
						<xs:annotation>
							<xs:documentation>
								It means that a service call is not activated at all. Its children are still evaluated.							
							</xs:documentation>
						</xs:annotation>
					</xs:enumeration>
					<xs:enumeration value="ACTIVATED">
						<xs:annotation>
							<xs:documentation>
								Means that the service call is running. Trying to materialize a service call in this state will not succeed.
							</xs:documentation>
						</xs:annotation>
					</xs:enumeration>
					<xs:enumeration value="TERMINATED">
						<xs:annotation>
							<xs:documentation>
								Coincides with the 'ENABLED' state just that it shows that the service call is terminated.
							</xs:documentation>
						</xs:annotation>
					</xs:enumeration>
					<xs:enumeration value="FAILED">
					<xs:annotation>
							<xs:documentation>
								Coincides with the 'ENABLED' state just that it shows that the service call failed.
							</xs:documentation>
						</xs:annotation>
					</xs:enumeration>
				</xs:restriction>
			</xs:simpleType>
		</xs:attribute>
	</xs:complexType>
	
	<!-- Merge functions -->
	<xs:complexType name="AppendMergeFunctionType">
		<xs:sequence></xs:sequence>
		<xs:attribute name="insert" use="optional" default="BELLOW">
			<xs:simpleType>
				<xs:restriction base="xs:string">
					<xs:enumeration value="ABOVE"></xs:enumeration>
					<xs:enumeration value="BELLOW"></xs:enumeration>
				</xs:restriction>
			</xs:simpleType>
		</xs:attribute>
	</xs:complexType>
	 
	<xs:group name="MergeFunctions">
		<xs:choice>
			<xs:element name="no-merge">
				<xs:annotation><xs:documentation>
					This merge function is useful for lazy OUT-IN operations, when one needs to specify that 
					the service returns result, but no merge is needed.
				</xs:documentation></xs:annotation>
				<xs:complexType>
					<xs:sequence></xs:sequence>
				</xs:complexType>
			</xs:element>
			<xs:element name="append">
				<xs:complexType>
					<xs:complexContent>
						<xs:extension base="AppendMergeFunctionType"></xs:extension>
					</xs:complexContent>
				</xs:complexType>
			</xs:element>
			
			<xs:element name="replace">
				<xs:annotation>
				<xs:documentation>
					Replaces all the earlier results with the incoming ones
				</xs:documentation>
				</xs:annotation>
				<xs:complexType>
					<xs:complexContent>
						<xs:extension base="AppendMergeFunctionType">
						</xs:extension>
					</xs:complexContent>
				</xs:complexType>
			</xs:element>
			<!--
			Other merge functions, e.g. fusion
			-->
		</xs:choice>
	</xs:group>
	
	<!-- XPath (a local service call) 
	<xs:element name="xpath">
		<xs:annotation>
			<xs:documentation>
				[NOT IMPLEMENTED]
				This element may appear anywhere in the Active XML document and is considered simply as a query on the same document.
				It is expanded lazily and may depend on other lazy service calls or XPath expressions.
				The XPath expression normally starts with '/' or '..', to select the document root or the parent (e.g. the service call element)
			</xs:documentation>
		</xs:annotation>
		<xs:complexType>
			<xs:simpleContent>
				<xs:extension base="xs:string">					
					<xs:attribute name="id" use="required" type="xs:ID">
						<xs:annotation><xs:documentation>
							As the element can appear anywhere in the document, it should be identifiable
						</xs:documentation></xs:annotation>
					</xs:attribute>
					<xs:attribute name="enabled" use="optional" type="xs:boolean" default="true">
						<xs:annotation><xs:documentation>
							A hint to use/ignore the expression
						</xs:documentation></xs:annotation>
					</xs:attribute>
				</xs:extension>
			</xs:simpleContent>
		</xs:complexType>
	</xs:element>
	-->
</xs:schema>