<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.w3.org/2004/04/ws-chor/cdl"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.w3.org/2004/04/ws-chor/cdl WS-CDL2.xsd" name="TWIST_Example2" version="0.2" targetNamespace="http://www.w3.org/2004/04/ws-chor/cdl">

<!-- Information types and tokens used later on -->
    <informationType name="PlaceHolder">
    </informationType>
    
	<token name="sellerRef" informationType="tns:uriType"/>
	<token name="sellerConsolidatorRef" informationType="tns:uriType"/>
	<token name="buyerRef" informationType="tns:uriType"/>
	<token name="creditReponderRef" informationType="tns:uriType"/>
	<token name="creditRequestorRef" informationType="tns:uriType"/>
	<token name="transactionId" informationType="tns:uriType"/>
	<token name="creditTransactionId" informationType="tns:uriType"/>

<!-- Define the roles -->

    <role name="BuyerRole">
	    <behavior name="BuyerI" interface="tns:Some_WSDL_Thing"/>
    </role>
    <role name="SellerRole">
	    <behavior name="SellerI" interface="tns:Some_WSDL_Thing"/>
    </role>
    <role name="SellerConsolidatorRole">
	    <behavior name="SellerConsolidatorI" interface="tns:Some_WSDL_Thing"/>
    </role>
    <role name="CreditResponderRole">
	    <behavior name="CreditResponderI" interface="tns:Some_WSDL_Thing"/>
    </role>
    <role name="CreditRequestorRole">
	    <behavior name="CreditRequestorI" interface="tns:Some_WSDL_Thing"/>
    </role>

<!-- How the roles work together, which we call relationships -->

<!-- Connecting various roles together           -->
<!--     BuyerRole to SellerRole                 -->
<!--     BuyerRole to SellerConsolidatorRole     -->
<!--     CreditReqRole to CreditRespRole         -->
<!-- These 3 cover all of the static connections -->

    <relationship name="BuyerSeller">
	    <role type="BuyerRole" behavior="BuyerDummy" />
	    <role type="SellerRole" behavior="SellerI"/>
    </relationship>

    <relationship name="BuyerCondolidator">
        <role type="BuyerRole" behavior="BuyerDummy" />
        <role type="SellerConsolidatorRole" behavior="SellerConsolidatorI" />
    </relationship>

    <relationship name="CreditReqCreditResp">
	    <role type="CreditReqRole" behavior="CreditReqDummy"/>
	    <role type="CreditRespRole" behavior="CreditRespDummy"/>
    </relationship>

<!-- Participants are those entities that play more than one role -->

    <participant name="TS_Participant">
	    <role type="SellerConsolidatorRole"/>
	    <role type="BuyerRole"/>
	    <role type="CreditRequestorRole"/>
    </participant>
    
<!-- Define some channels on a per role basis                                 -->
<!-- This is fairly intuitive since the notion of a role and it's behaviour   -->
<!-- is akin to the notion of a channel and it's type                         -->
<!-- Don't forget that in some choreographies we wish to describe there may   -->
<!-- well be some dynamic relationships which need to be modelled which       -->
<!-- require channel passing. It is easy to forget these and so forget to     -->
<!-- to define the channel types that need to be passed and only concentrate  -->
<!-- on the static connections.                                               -->
<!-- In this example however we don't have any.                               -->

    <channelType name="SellerChannel" >
    <!-- usage, action, passing channel are for the Type System. In this example they are omitted -->
    	<role type="SellerRole"/>
        <!--About end points -->
    	<reference>
	    	<token name="tns:sellerRef"/>
    	</reference>
        <!--About Sessions -->	
    	<identity> 
		    <token name="tns:transactionId"/>
	    </identity>
    </channelType>

    <channelType name="BuyerChannel">
    	<role type="BuyerRole" />
	    <reference>
    		<token name="tns:sellerRef"/>
	    </reference>
    	<identity> 
		    <token name="tns:transactionId"/>
	    </identity>
    </channelType>

    <channelType name="SellerConsolidatorChannel">
    	<role type="SellerConsolidatorRole" />
    	<reference>
	    	<token name="tns:sellerConsolidatorRef"/>
    	</reference>
    	<identity> 
		    <token name="tns:transactionId"/>
	    </identity>
    </channelType>

    <channelType name="CreditResponderChannel">
	    <role type="CreditResponderRole" />
	    <reference> 
		    <token name="tns:creditResponderRef"/>
	    </reference>
	    <identity> 
		    <token name="tns:creditTransactionId"/>
	    </identity>
    </channelType>

    <channelType name="CreditRequestorChannel">
	    <role type="CreditRequestorRole" />
    	<reference>
		    <token name="tns:creditRequestorRef"/>
	    </reference>
    	<identity> 
		    <token name="tns:creditTransactionId"/>
	    </identity>
    </channelType>

<!-- Now define the choreography                                                 -->
<!-- The choreography describes the interaction between the roles on the basis   -->
<!-- of their behaviors.                                                         -->

<!-- PricesRequest choreography -->
    <choreography name="PricesRequest" root="true">
        <!-- Reference the relationship type so that we can refer back to the        -->
        <!-- behaviors.                                                              -->
        <relationship type="tns:BuyerConsolidator"/>
        <!-- Define the necessary role variables                                     -->
        <variableDefinitions>
            <variable name="Buyer" informationType="tns:channelType" silent-action="true" />
            <variable name="Condolidator" informationType="tns:channelType" slides-action="true" />
        </variableDefinitions>
    
        <!-- Now do the interaction between the roles.                               -->
        <!-- If we wanted to do state alignment and explicitly show exchanges and    -->
        <!-- record state for later use we would use the "exchange" and "record"     -->
        <!-- In this example we do not want to do that.                              -->
    
        <sequence>
            <interaction name="RequestPrice" channelVariable="tns:Buyer" operation="priceRequest" initiateChoreography="true">
                <participate relationship="tns:BuyerConsolidator" fromRole="tns:Buyer" toRole="tns:Consolidator"/>
            </interaction>
            <!-- We can reuse the CreditCheck choreography by simply performing it -->
            <perform choreographyName="CreditCheck">
                     <!-- Removed alias until we can fill in 'this' and 'free' elements.     &LTalias name="ConsolidatorCreditCheck"&GT
                &LT/alias&GT                             -->

            </perform>
            <interaction name="PriceResponses" channelVariable="tns:Consolidator" operation="priceResponses">
                <participate relationship="tns:BuyerConsolidator" fromRole="tns:Consolidator" toRole="tns:Buyer"/>       
            </interaction>
            <interaction name="AcceptPrice" channelVariable="tns:Buyer" operation="priceAcceptance">
                <participate relationship="tns:BuyerConsolidator" fromRole="tns:Buyer" toRole="tns:Consolidator"/>
            </interaction>
            <interaction name="AcceptPriceAck" channelVariable="tns:Consolidator" operation="priceAcceptanceAck">
                <participate relationship="tns:BuyerConsolidator" fromRole="tns:Consolidator" toRole="tns:Buyer"/>
            </interaction>
        </sequence>
    </choreography>

<!-- CreditCheck choreography -->
    <choreography name="CreditCheck" root="false">
        <relationship type="tns:CreditReqCreditResp"/>
        <variableDefinitions>
            <variable name="Requestor" informationType="tns:channelType" silent-action="true" />
            <variable name="Responder" informationType="tns:channelType" slides-action="true" />
        </variableDefinitions>
        <sequence>
            <interaction name="RequestCredit" channelVariable="tns:CreditRequestor" operation="creditRequest" initiateChoreography="false">
                <participate relationship="tns:CreditReqCreditResp" fromRole="tns:Requestor" toRole="Responder" />
            </interaction>    
            <interaction name="Credit Response" channelVariable="tns:CreditResponder" operation="creditResponse" initiateChoreography="false">
                <participate relationship="tns:CreditReqCreditResp" fromRole="tns:Responder" toRole="Requestor" />
            </interaction>
        </sequence>
    </choreography>
    
<!-- normal PriceRequest choreography -->
    <choreography name="PriceRequest" root="false">
	    <relationship type="tns:BuyerSeller"/>
        <!-- Two interactions with two channel variables for the two sellers -->
	    <variableDefinitions> 
	    	<variable name="SellerA" informationType="tns:channelType" silent-action="true" />
		    <variable name="SellerB" informationType="tns:channelType" silent-action="true" />  
	    </variableDefinitions>
	    <!-- We shall do the interaction with the Sellers in parallel so that we are not -->
        <!-- compromising scalability by doing a sequence of interactions. This means that -->
        <!-- SellerB could get it's interaction done before SellerA. Order of completion is underfined -->
        <parallel>
		    <interaction name="RequestPrice" channelVariable="tns:SellerA" operation="priceRequest" align="false" initiateChoreography="false"> 
			    <participate relationship="tns:BuyerSeller" fromRole="tns:Buyer" toRole="tns:Seller"/> 
		    	<!-- We could record the price at the buyer role for later consolidation into prices -->
		    	<!-- But because this is unobservable we shall omit it --> 
	    	</interaction> 
	    	    <!-- We can reuse the CreditCheck choreography by simply performing it -->
            <perform choreographyName="CreditCheck">
                <!-- Removed alias until we can fill in 'this' and 'free' elements.     &LTalias name="SellerCreditCheck"&GT
                &LT/alias&GT                             -->
             </perform>
		    <interaction name="RequestPrice" channelVariable="tns:SellerB" operation="priceRequest" align="false" initiateChoreography="true"> 
			    <participate relationship="tns:BuyerSeller" fromRole="tns:Buyer" toRole="tns:Seller"/> 
			    <!-- We could record the price at the buyer role for later consolidation into prices -->
			    <!-- But because this is unobservable we shall omit it -->
		    </interaction> 
	    </parallel>
    </choreography>
</package>

