/* DomainManagement.idl
   declares Domain, which manages domain members and domain policies
	    some policies used to manage domains
   $Id: DomainManagement.idl,v 1.5 2000/03/29 14:08:01 kiefer Exp $
*/


#include <orb.idl> 
module jacorb {
 module orb {
  module domain { // domain management

  /***** types *****/

  interface Domain;                      // forward declaration
  interface DomainFactory;               // forward declaration
  interface GraphNode;                   // forward declaration
  interface PolicyFactory;               // forward declaration

  typedef sequence <Domain> DomainList;
  typedef sequence <Object> ObjectList;

 /***** Domain *****/

  // a domain object manages two sets:
  // 1) set of object members
  // 2) set of domain policies

  interface Domain : CORBA::DomainManager, DomainFactory, GraphNode
    {

    // describes the domain informally
    attribute string description;

    // Policy operations

    // Every domain has a default policy type, which
    // indicates the main use of the domain. 
    // For example, if the default policy type is type access 
    // control the domain acts mainly as an access control domain.

    attribute CORBA::PolicyType defaultPolicyType;

    // sets the policy of the specified type
    void set_domain_policy(in CORBA::Policy policy);
    

    // operations for managing set of object members

    void    insertMember(in Object obj);
    void    deleteMember(in Object obj);
    boolean    hasMember(in Object obj);
    ObjectList getMembers();               // list all object members

    // obj -> list of domains
    DomainList getDomains(in Object obj);

    // obj -> Policy
    CORBA::Policy getPolicy(in Object obj, in CORBA::PolicyType type);

    // makes a copy of the object reference obj with newly associated policies
    Object set_policy_override(in Object obj, 
			       in CORBA::PolicyList ps, 
			       in boolean override);

  };

 interface DomainFactory 
  {

    // Creates a Domain object with "initialMembers" 
    // as initial members and "initialPolicies" as the policies to 
    // begin with. Both can be null which then means empty.
    // The default policy type "defaultPolicyType" has to be provided.
    Domain createDomain
      (
       in ObjectList        initialMembers, 
       in CORBA::PolicyList initialPolicies,
       in CORBA::PolicyType defaultPolicyType,
       in string            description
      );
  };

 /********* graph node ************************************************/
 // a graph node supports operation to walk a graph hierarchy up- and down

 interface GraphNode 
   {

     
    // returns True iff this domain manager has no parent domain services
    boolean isRoot();    

    
    // returns the root domain service in the scope of this domain manager
    Domain getRootDomain();

     // child domains
     
     /* inserts a domain into this domain as a (direct) child domain 
	Pre: NOT child.containsDomain(this) 
	    (to prevent cycles)
	    the precondition of Domain.addParent also needs to be satisfied
	Post: this.hasChild(child) AND child.hasParent(this)
     */
     void insertChild(in Domain child);
     
     // returns true iff domain "aDomain" is a direct child domain of this domain 
     boolean hasChild(in Domain aDomain);
     
     // returns true iff there exists a directed path from this domain 
     // downwards to the node "aDomain"           (used to prevent cicles)
     boolean containsDomain(in Domain aDomain);
     
     // returns the (direct) child domains registered at this domain 
     DomainList getChilds();

     // deletes a child domain 
     // Post:     NOT this.hasChild(domain_manager) 
     //       AND NOT domain_manager.hasParent(this)
     void deleteChild(in Domain child);

     // operations to walk and manage the domain hierarchy upwards

     // Pre :
     // Post: this.hasParent(parentDS) AND parentDS.hasChild(this)
     //       AND NOT this.isRoot() 
     //       AND parentDS.getRootDomainService() == this.getRootDomainService()
     //       (this is now a child domain of the parent domain parentDS and
     //        they have the same root domain service)
     void insertParent(in Domain parentDomain);

     // Post: NOT this.hasParent(parentDS) AND NOT parentDS.hasChild(this)
     void deleteParent(in Domain parentDomain);

     boolean    hasParent(in Domain parentDomain);
     DomainList getParents();



   };

 /************************* invariant ************************************
   all domain managers dm and all domain services ds must fullfill  
   the invariants 
        1)    dm.hasParent(ds) == ds.hasChild(dm), in other words
   dm and ds must agree if there is a parent-child relationship between them

	2)    Every two domain (managers) d1 and d2 must follow:
		a) NOT (d1.hasChildOfAnyLevel(d2) AND d2.hasChildOfAnyLevel(d1)
	           (there are no cycles in the domain graph)
		b) ( (d1.hasChildOfAnyLevel(d2) OR d2.hasChildOfAnyLevel(d1) )
		   => d1.getRoot() == d2.getRoot()
		   (if there exist a path between two nodes, they must have
		    the same unique root)  
  */	

 /***** ObjectDomainMapper (ODM) ****/
  
  // manages mappings of the form 
  //
  //          object reference -> [dm(1), dm(2), ..., dm(n)]
  //               where dm(i), i from 1 to n, are domain managers

  interface ObjectDomainMapper 
    {
      // Post: hasMapping(obj) AND  dms == getMapping(obj) 
      //       AND for all dm e dms: areMapped(obj, dm)
      void insertMapping(in Object obj, in DomainList dms);

      // Post: NOT hasMapping(object)
      void deleteMapping(in Object obj);
    
      // Pre : hasMapping(obj)
      // returns the domain manager list associated with object obj
      DomainList getMapping(in Object obj);

      // is there a mapping defined for obj ? (could also be the empty list)
      boolean hasMapping (in Object obj);

      // is obj mapped to dm ?
      boolean areMapped(in Object obj, in Domain dm);

      // Post: hasMapping(obj) AND areMapped(obj, dm)
      void addToMapping(in Object obj, in Domain dm);

      // Post: NOT areMapped(obj, dm)
      void removeFromMapping(in Object obj, in Domain dm);
    
    };
  
  // **************  policies  *******************

  // policy types
  const CORBA::PolicyType MANAGE_POLICY_ID = 110;
  const CORBA::PolicyType TEST_POLICY_ID = 113;
  const CORBA::PolicyType CONFLICT_RESOLUTION_POLICY_ID = 114;
  

  interface ManagePolicy : CORBA::Policy
    {
      // a human readable and very short (1-2 words) description of this
      // policy, may be displayed in list or tree views
      attribute string short_description;

      // a human readable description and explanation of this policy,
      // may be displayed in graphical (help or properties) dialogs
      attribute string long_description;

    };

  interface ConflictResolutionPolicy : ManagePolicy
    {
      // predifinded subtypes:
      const short SIMPLE = 1;
      // to be continued...
      
      // Pre: all the domain managers in the list overlappingDMs overlap in
      //      their policy of type overlapType
      // Post: returns the domain manager which policy is to be used
      Domain resolveConflict(in DomainList overlappingDMs,
		      in CORBA::PolicyType overlapType);
    };

  // decides to which domain managers a new object reference gets mapped
  interface InitialMapPolicy : ManagePolicy
    {
      // returns a list of domain managers, to which the newly created object
      // reference "newReference" shall be associated with in respect to
      // a given root
      // Pre : newReference isn't mapped to any domain manager
      //       AND rootDomain.isRoot()
      // Post: for all dm e returned list: 
      //                (dm == rootDomain  OR root.hasChildOfAnyLevel(dm)
      //           
      DomainList OnReferenceCreation(in Object newReference,
					    in Domain rootDomain);
    };
  
  interface PolicyFactory // : CORBA:PolicyFactory
    {
      CORBA::Policy create_policy(in CORBA::PolicyType type,
				  in any initValue);
	// raises (CORBA::PolicyError);
      
      InitialMapPolicy         createInitialMapPolicy(in short whichOne);
      ConflictResolutionPolicy createConflictResolutionPolicy(in short whichOne);
    };


  // a simple test policy
  interface TestPolicy : CORBA::Policy {
    attribute string description;
    string testFunction();
    string toString();
   };
  };
 };
};
