
#ifndef __CosRelationships_idl__
#define __CosRelationships_idl__

#include <mico/ir.idl>
#include <mico/CosObjectIdentity.idl>

#pragma prefix "omg.org"

module CosRelationships {

  interface RoleFactory;
  interface RelationshipFactory;
  interface Relationship;
  interface Role;
  interface RelationshipIterator;

  typedef Object RelatedObject;
  typedef sequence<Role> Roles;
  typedef string RoleName;
  typedef sequence<RoleName> RoleNames;

  // My Update
  typedef sequence<::CORBA::InterfaceDef> InterfaceDefs;
  // end of update

  struct NamedRole {RoleName name; Role aRole;};
  typedef sequence<NamedRole> NamedRoles;

  struct RelationshipHandle {
    Relationship the_relationship;
    CosObjectIdentity::ObjectIdentifier
    constant_random_id;
  };

  typedef sequence<RelationshipHandle>
    RelationshipHandles;

  interface RelationshipFactory {
    struct NamedRoleType {
      RoleName name;
      ::CORBA::InterfaceDef named_role_type;
    };

    typedef sequence<NamedRoleType>
      NamedRoleTypes;

    readonly attribute ::CORBA::InterfaceDef relationship_type;
    readonly attribute unsigned short degree;
    readonly attribute NamedRoleTypes named_role_types;

    exception RoleTypeError {NamedRoles culprits;};
    exception MaxCardinalityExceeded {NamedRoles culprits;};
    exception DegreeError {unsigned short required_degree;};
    exception DuplicateRoleName {NamedRoles culprits;};
    exception UnknownRoleName {NamedRoles culprits;};

    Relationship create (in NamedRoles named_roles)
      raises (RoleTypeError, MaxCardinalityExceeded, DegreeError,
	      DuplicateRoleName, UnknownRoleName);

  };
  
  interface Relationship : CosObjectIdentity::IdentifiableObject {
    exception CannotUnlink {Roles offending_roles;};

    readonly attribute NamedRoles named_roles;

    void destroy () raises(CannotUnlink);
  };
  
  interface Role {
    exception UnknownRoleName {};
    exception UnknownRelationship {};
    exception RelationshipTypeError {};
    exception CannotDestroyRelationship {RelationshipHandles offenders;};
    exception ParticipatingInRelationship {
      RelationshipHandles the_relationships;
    };

    readonly attribute RelatedObject related_object;

    RelatedObject get_other_related_object (in RelationshipHandle rel,
					    in RoleName target_name)
      raises (UnknownRoleName, UnknownRelationship);

    Role get_other_role (in RelationshipHandle rel, in RoleName target_name)
      raises (UnknownRoleName, UnknownRelationship);

    void get_relationships (in unsigned long how_many,
			    out RelationshipHandles rels,
			    out RelationshipIterator iter);

    void destroy_relationships()
      raises(CannotDestroyRelationship);

    void destroy()
      raises(ParticipatingInRelationship);

    boolean check_minimum_cardinality ();

    void link (in RelationshipHandle rel,
	       in NamedRoles named_roles)
      raises(RelationshipFactory::MaxCardinalityExceeded,
	     RelationshipTypeError);

    void unlink (in RelationshipHandle rel)
      raises (UnknownRelationship);
  };
  
  interface RoleFactory {
    exception NilRelatedObject {};
    exception RelatedObjectTypeError {};

    readonly attribute ::CORBA::InterfaceDef role_type;
    readonly attribute unsigned long max_cardinality;
    readonly attribute unsigned long min_cardinality;
    // My Update !!!
    //           readonly attribute sequence <::CORBA::InterfaceDef>
    //                                related_object_types;
    readonly attribute InterfaceDefs related_object_types;
    // end of update
    
    Role create_role (in RelatedObject
		      related_object)
      raises (NilRelatedObject,
	      RelatedObjectTypeError);
  };

  interface RelationshipIterator {
    boolean next_one (out RelationshipHandle rel);
    boolean next_n (in unsigned long how_many,
		    out RelationshipHandles rels);
    void destroy ();
  };

};



#endif


