/**
  * File: DomainGroupHandler.idl
  * Content: UMA corba definition for the Domain Group Handler
  * Author: LuisM Pena
  * Date: 28th November 2000
  * Version: 0.51.00
  * Last change:
  *         12th April 2001: state transfer inclusion
  *
  *
  **/

#ifndef DOMAIN_GROUP_HANDLER_IDL
#define DOMAIN_GROUP_HANDLER_IDL

#include "Concurrency.idl"
#include "Properties.idl"

module sensei
{

  module middleware
  {

    module domains
    {

      //bringing some declarations into scope ...
      typedef sensei::middleware::gms::GroupHandler GroupHandler;

      /***********************************************************************/
      /************************* DOMAIN EXPULSION REASON *********************/
      /***********************************************************************/

      enum DomainExpulsionReason
      {
        GMSLeaveEvent, //event coming from the GMS, perhaps because the application has requested to leave the group
        WrongPropertyAllowance, //the member uses a differente Properties policy that the group
        WrongStaticSubgroupsComposition, //the member has not defined the same static subgroups that the group
        WrongCoordinatorElectionPolicy,  //the member uses a differente Coordinator election policy that the group
        WrongBehaviourMode,  //the member uses a differente Behaviour mode that the group
        WrongDynamicPolicy,  //the member uses a differente dynamic policy that the group
        WrongSubgroupsTypes, //the member has for one or more subgroups different state transfer types than requested
        SubgroupError //an error has been reported about a subgroup (exception accesing it)
      };

      /***********************************************************************/
      /********************** SYNC CAST DOMAIN MESSAGE PROCESSED EXCEPTION ***/
      /***********************************************************************/

      exception SyncCastDomainMessageProcessedException
      {
      };

      /***********************************************************************/
      /************************* DOMAIN GROUP USER ***************************/
      /***********************************************************************/

      /**
       * Interface to be implemented optionally by members using domains
       */
      interface DomainGroupUser
      {
        /**
         * Invoked when the DomainGroup is accepted into its subgroup
         */
        void domainAccepted(in GroupMemberId id);

        /**
         * Invoked when the DomainGroup is expulsed from its subgroup
         */
        void domainExpulsed(in DomainExpulsionReason reason);

        /**
         * Invoked when the DomainGroup is considered to have state
         * @param assumed set to true if this member is assuming state, i.e, is not transfered
         */
        void stateObtained(in boolean assumed);

        /**
         * Invoked when the a subgroup in the domain is not reachable. This
         * call will be followed by a domainExpulsed call eventually.
         * @param subgroupId the identity of the subgroup causing the problem
         * @param reason an string explaining the problem
         */
        void offendingSubgroup(in SubgroupId subgroup, in string reason);

      };

      /***********************************************************************/
      /************************* DOMAIN GROUP HANDLER ************************/
      /***********************************************************************/

      /**
        * GroupMember targetted as central instance to handle several subgroups
        * Messages sent through this class must belong to the DomainMessage hierarchy
        *
        *   -	It allows to define several subgroups to be handled separately by one group.
        *   - The subgroups can be created/removed dynamically.
        *   -	It includes the abstraction group/subgroups or domain/groups
        * It supports several special features:
        * -The sending of messages blocks the caller until the message is received
        * -Reception of cast messages sent by the own member are not propagated to the
        *    subgroups: they just unblock the message sending.
        * -PTP messages can be sent to all the subgroups in the group
        * -State transfer support
        * -Replica properties support
        * -Transactions support
        **/
      interface DomainGroupHandler : GroupHandler, GroupMember, PropertiesHandler, SubgroupsHandler, TransactionsHandler
      {
        /**
         * Sets the mode under view changes. It can only be set before the domain Group Handler joins a group,
         * or an exception is thrown
         */
        void setBehaviourMode(in BehaviourOnViewChanges mode)
          raises (MemberStateException);

        /**
         * Sets a coordinator elector. It must be set before the DomainGroupHandler joins a group, or an
         * exception is raised
         */
        void setCoordinatorElector(in CoordinatorElector elector)
          raises (MemberStateException);

        /**
         * Sets a listener to DomainGroup events. It must be set before the DomainGroupHandler joins a group, or an
         * exception is raised
         */
        void setDomainGroupUser(in DomainGroupUser user)
          raises (MemberStateException);

        /**
         * Returns the list of stateful members. This operation can only be invoked on stateful members,
         * or an exception is thrown
         */
        GroupMemberIdList getStatefulMembers()
          raises (MemberStateException);

        /**
          * Cast a message to the subgroup, and blocks until it is processed.
          * @param normalProcessing set to true if the message is to be received through the normal
          *        processCastMessage. In that case, this call blocks until the message is processed.
          *        If it is false, the call blocks until the caller can process the operation, and
          *        when it finishes, it must call to syncCastDomainMessageProcessed
          **/
        boolean syncCastDomainMessage(in DomainMessage message, in boolean normalProcessing)
          raises (MemberStateException);

        /**
          * Confirms that a message has been processed. Failing to call to this method after
          *   requesting syncCastDomainMessage with normalProcessing equal to false will avoid the
          *   normal flow of messages into the application, excluding eventually the member from the group
          **/
        void syncCastDomainMessageProcessed() raises(MemberStateException, SyncCastDomainMessageProcessedException);

      };
    };
  };
};

#endif