// CosRelationships Module, p 9-21 CORBAservices, Relationship
// Service V1.0, 3/94

#ifndef __CosRelationships_IDL
#define __CosRelationships_IDL

#include <orb.idl>
#include <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;

        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 iterator);
                        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;
// the following isn't allowed in IDL,
//  readonly attribute sequence <CORBA::InterfaceDef> related_object_types;
			typedef sequence <CORBA::InterfaceDef> InterfaceDefSeq;
			readonly attribute InterfaceDefSeq related_object_types;
                        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
