#ifndef COSNAMING_IDL
#define COSNAMING_IDL

/**
 * CORBA Common Object Services: Naming Service.
 * <p>
 * The detailed specification is available from the
 * <a href="http://www.omg.org">Object Management Group</a>.
 * 
 * @author OMG
 * @version Version 00-11-01
 */

#pragma prefix "omg.org"

module CosNaming
{
   typedef string Istring;

   struct NameComponent
   {
      Istring id;
      Istring kind;
   };

   typedef sequence <NameComponent> Name;

   enum BindingType
   {
      nobject,
      ncontext
   };

   struct Binding
   {
      Name binding_name;
      BindingType binding_type;
   };

   typedef sequence <Binding> BindingList;

   interface BindingIterator;

/**
 * The NamingContext interface provides operations which support the following:
 * <ul>
 * <li> binding objects
 * <li> name resolution
 * <li> unbinding
 * <li> creating naming contexts
 * <li> deleting contexts
 * <li> listing a naming context
 * </ul>
 */
 
   interface NamingContext
   {
      enum NotFoundReason
      {
         missing_node,
         not_context,
         not_object
      };

/** 
 * Indicates the name does not identify a binding.
 */

      exception NotFound
      {
         NotFoundReason why;
         Name rest_of_name;
      };

/**
 * Indicates that the implementation has given up for some reason. The
 * client, however, may be able to continue the operation at the returned
 * naming context.
 */
 
      exception CannotProceed
      {
         NamingContext cxt;
         Name rest_of_name;
      };

/** 
 * Indicates the name is invalid. (A name of length 0 is invalid;
 * implementations may place other restrictions on names.)
 */
 
      exception InvalidName  {};

/** 
 * Indicates an object is already bound to the specified name. Only one
 * object can be bound to a particular name in a context.
 */

      exception AlreadyBound {};

/**
 * Indicates that a naming context has bindings.
 */

      exception NotEmpty     {};

/**
 * Creates a binding of a name and an object in the naming
 * context. Naming contexts that are bound using bind do not
 * participate in name resolution when compound names are passed to be
 * resolved. A bind operation that is passed a compound name is
 * defined as follows:
 *
 * <pre>
 * ctx->bind(< c1 ; c2 ; ... ; cn >, obj) :=
 * (ctx->resolve(< c1 ; c2 ; ... ; cn-1 >))->bind(< cn >, obj)
 * </pre>
 *
 * @parm n - binding name.
 * @parm obj - object to bind.
 * @raises AlreadyBound - if the name is bound in the context.
 */
      void bind (in Name n, in Object obj)
         raises (NotFound, CannotProceed, InvalidName, AlreadyBound);

/** 
 * Creates a binding of a name and an object in the naming context
 * even if the name is already bound in the context. Naming contexts
 * that are bound using rebind do not participate in name resolution
 * when compound names are passed to be resolved.
 *
 * @parm n - binding name.
 * @parm obj - object to bind.
 */
      void rebind (in Name n, in Object obj)
         raises (NotFound, CannotProceed, InvalidName);

/** 
 * Names an object that is a naming context. Naming contexts that are
 * bound using bind_context() participate in name resolution when
 * compound names are passed to be resolved. A bind_context operation
 * that is passed a compound name is defined as follows:
 * <pre>
 * ctx->bind_context(< c1 ; c2 ; ... ; cn >, nc) :=
 * (ctx->resolve(< c1 ; c2 ; ... ; cn-1 >))->bind_context(< cn >, nc)
 * </pre>
 *
 * @parm n - binding name.
 * @parm nc - naming context to bind.
 * @raises AlreadyBound - if the name is bound in the context.
 */

      void bind_context (in Name n, in NamingContext nc)
         raises (NotFound, CannotProceed, InvalidName, AlreadyBound);

/** 
 * Creates a binding of a name and a naming context in the naming
 * context even if the name is already bound in the context. Naming
 * contexts that are bound using rebind_context() participate in name
 * resolution when compound names are passed to be resolved.
 *
 * @parm n - binding name.
 * @parm nc - naming context to bind.
 */

      void rebind_context (in Name n, in NamingContext nc)
         raises (NotFound, CannotProceed, InvalidName);

/** 
 * The resolve operation is the process of retrieving an object bound
 * to a name in a given context. The given name must exactly match the
 * bound name. The naming service does not return the type of the
 * object. Clients are responsible for "narrowing" the object to the
 * appropriate type. That is, clients typically cast the returned
 * object from Object to a more specialized interface. Names can have
 * multiple components; therefore, name resolution can traverse
 * multiple contexts.
 * A compound resolve is defined as follows:
 * <pre>
 * ctx->resolve(< c1 ; c2 ; ... ; cn >) :=
 * ctx->resolve(< c1 ; c2 ; ... ; cn-1 >)->resolve(< cn >)
 * </pre>
 *
 * @parm n - binding name.
 * @returns bound object.
 */

      Object resolve (in Name n)
         raises (NotFound, CannotProceed, InvalidName);

/** 
 * The unbind operation removes a name binding from a context.
 * A unbind operation that is passed a compound name is defined as follows:
 * <pre>
 * ctx->unbind(< c1 ; c2 ; ... ; cn >) :=
 * (ctx->resolve(< c1 ; c2 ; ... ; cn-1 >))->unbind(< cn >)
 * </pre>
 *
 * @parm n - binding name.
 */

      void unbind (in Name n)
         raises (NotFound, CannotProceed, InvalidName);

/** 
 * This operation returns a naming context implemented by the same
 * naming server as the context on which the operation was
 * invoked. The new context is not bound to any name.
 *
 * @returns new binding context.
 */

      NamingContext new_context ();

/** 
 * This operation creates a new context and binds it to the name
 * supplied as an argument. The newly-created context is implemented
 * by the same naming server as the context in which it was bound
 * (that is, the naming server that implements the context denoted by
 * the name argument excluding the last component). A bind_new_context
 * that is passed a compound name is defined as follows:
 * 
 * <pre>
 * ctx->bind_new_context(< c1 ; c2 ; ... ; cn >) :=
 * (ctx->resolve(< c1 ; c2 ; ... ; cn-1 >))->bind_new_context(< cn >)
 * </pre>
 *
 * @parm n - binding name.
 * @returns new binding context.
 * @raises AlreadyBound - if the name is bound in the context.
 */

      NamingContext bind_new_context (in Name n)
         raises (NotFound, CannotProceed, InvalidName, AlreadyBound);

/** 
 * The destroy operation deletes a naming context. The list operation
 * allows a client to iterate through a set of bindings in a naming
 * context.
 *
 * @raises NotEmpty - if the naming context contains bindings.
 */

      void destroy () raises (NotEmpty);

/**
 * The list operation returns at most the requested number of bindings in
 * BindingList bl.
 * <ul>
 * <li> If the naming context contains additional bindings, the list
 * operation returns a BindingIterator with the additional bindings.
 * <li> If the naming context does not contain additional bindings, the
 * binding iterator is a nil object reference.
 * </ul>
 *
 * @parm how_many - maximum number of binding to return in bl.
 * @parm bl - list of bindings.
 * @parm bi - iterator over remaining bindings.
 */

      void list (in unsigned long how_many,
                 out BindingList bl,
                 out BindingIterator bi);
   };

/**
 * The BindingIterator interface allows a client to iterate through the
 * bindings using the next_one or next_n operations.
 */

   interface BindingIterator
   {
/**
 * This operation returns the next binding. If there are no more
 * bindings, false is returned.
 *
 * @parm b - next binding.
 */

      boolean next_one (out Binding b);

/** 
 * This operation returns at most the requested number of bindings.
 *
 * @parm how_many - maximum number of binding to return in bl.
 * @parm bl - list of bindings.
 */

      boolean next_n (in unsigned long how_many, out BindingList bl);
/** 
 * This operation destroys the iterator.
 */

      void destroy ();
   };


/**
 * The NamingContextExt Interface provides the extensions to the 
 * NamingContext Interface as proposed by the Interoperable
 * Naming Service Extension.
 */
   interface NamingContextExt: NamingContext
   {
      typedef string StringName;
      typedef string Address;
      typedef string URLString;


/**
 * This operation accepts a Name and returns a stringified Name.
 *
 * @param n - Name (a sequence of NameComponents)
 * @raises InvalidName - if the Name is invalid.
 */
      StringName to_string (in Name n) 
         raises (InvalidName); 


/**
 * This operation accepts a StringifiedName and returns a Name.
 *
 * @param n - a StringifiedName
 * @raises InvalidName - if the Name is invalid.
 */
      Name to_name (in StringName sn) 
         raises (InvalidName); 

/**
 * Indicates a syntactically invalid address component.
 */
      exception InvalidAddress {};  

   
/**
 * This operation accepts a URL address component and a stringified
 * name and returns a URL string.
 *
 * @param n - a Stringified name.
 * @raises addr - URL address component.
 */
      URLString to_url (in Address addr, in StringName sn)
         raises (InvalidAddress, InvalidName);       

/**
 * This is a convenience operation that performs a resolve in the same
 * manner as NamingContext::resolve.
 *
 * @param n - a Stringified name.
 * @raises NotFound, CannotProceed, InvalidName
 */
      Object resolve_str (in StringName n)
         raises (NotFound, CannotProceed, InvalidName);

   }; 
};

#endif
