//File: CosRelationships.idl
//Part of the Relationship Service
//OMG File: 98-10-35

#ifndef _COS_RELATIONSHIPS_IDL_
#define _COS_RELATIONSHIPS_IDL_

#ifdef _PRE_3_0_COMPILER_
#include <orb.idl>
#include <CosObjectIdentity.idl>
#pragma prefix "omg.org"
#else
import ::CORBA;
import ::CosObjectIdentity;
#endif // _PRE_3_0_COMPILER_

module CosRelationships {

#ifndef _PRE_3_0_COMPILER_
	typeprefix CosRelationships "omg.org";
#endif // _PRE_3_0_COMPILER_

	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,
					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;
		typedef sequence<CORBA::InterfaceDef> InterfaceDefs;
		readonly attribute InterfaceDefs 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 /* ifndef _COS_RELATIONSHIPS_IDL_ */
