// **********************************************************************
//
// Copyright (c) 1999
// Object Oriented Concepts, Inc.
// Billerica, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#ifndef OCI_IDL
#define OCI_IDL

#include <IOP.idl>
#include <Policy.idl>
#include <Current.idl>
#include <OCIBuffer.idl>

#pragma prefix "ooc.com"

/**
 *
 * The Open Communications Interface (OCI). The definitions in this
 * module provide a uniform interface to network protocols. This
 * allows for easy plug-in of new protocols or other communication
 * mechanisms into ORBs that implement the OCI. Furthermore, protocol
 * implementations need only to be written once and can then be reused
 * with all OCI compliant ORBs. For more information, please see the
 * OCI documentation.
 *
 **/

module OCI
{
/** Alias for an IOR. */
typedef IOP::IOR IOR;
/** Alias for a profile id. */
typedef IOP::ProfileId ProfileId;
/** Alias for a sequence of profile ids. */
typedef sequence< ProfileId > ProfileIdSeq;
/** Alias for an object key, which is a sequence of octets. */
typedef sequence< octet > ObjectKey;
/** Alias for a system-specific handle type. */
typedef long Handle;

/* TransportInfo forward declaration */
interface TransportInfo;

/* ConnectorInfo forward declaration */
interface ConnectorInfo;

/* AcceptorInfo forward declaration */
interface AcceptorInfo;

/* ConFactoryInfo forward declaration */
interface ConFactoryInfo;

/**
 *
 * The interface for a Transport object, which provides operations
 * for sending and receiving octet streams. In addition, it is
 * possible to register callbacks with the Transport object, which
 * are invoked whenever data can be sent or received without
 * blocking.
 *
 * @see Connector
 * @see Acceptor
 *
 **/
 
interface Transport
{
    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /**
     *
     * The "handle" for this Transport. The handle may <em>only</em>
     * be used to determine whether the Transport object is ready to
     * send or to receive data, e.g., with <code>select()</code> on
     * Unix-based operating systems. All other uses (e.g., calls to
     * <code>read()</code>, <code>write()</code>,
     * <code>close()</code>) are strictly non-compliant. A handle
     * value of -1 indicates that the protocol plug-in does not
     * support "selectable" Transports.
     *
     **/

    readonly attribute Handle handle;

    /**
     *
     * The Transport's maximum packet size. The <code>send</code> and
     * <code>receive</code> operations must not be used to send packets
     * larger than this size within a single call. A value of 0 means
     * that there is no upper limit for the packet size.
     *
     **/

    readonly attribute unsigned long fragmentation;

    /**
     *
     * Closes the Transport. None of the <code>send</code> and
     * <code>receive</code> operations may be called after
     * <code>close</code> has been called.
     *
     * @param discard If set to <code>TRUE</code>, unsent data
     * buffered by the Transport may be discarded.
     *
     **/

    void close(in boolean discard);

    /**
     *
     * Unblock threads that are blocking in the <code>send</code> or
     * <code>recv</code> operations. After calling
     * <code>unblock_threads</code>, any further calls to the
     * <code>send</code> or <code>recv</code> operations may result in
     * a <code>CORBA::COMM_FAILURE</code> exception being raised.
     *
     * @param discard If set to <code>TRUE</code>, unsent data
     * buffered by the Transport may be discarded.
     *
     **/

    void unblock_threads(in boolean discard);

    /**
     *
     * Receives a buffer's contents.
     *
     * @param buf The buffer to fill.
     *
     * @param block If set to <code>TRUE</code>, the operation blocks
     * until the buffer is full. If set to <code>FALSE</code>, the
     * operation fills as much of the buffer as possible without
     * blocking.
     *
     **/

    void receive(in Buffer buf, in boolean block);

    /**
     *
     * Similar to <code>receive</code>, but it signals a connection
     * loss by returning <code>FALSE</code> instead of raising
     * <code>CORBA::COMM_FAILURE</code>.
     *
     * @param buf The buffer to fill.
     *
     * @param block If set to <code>TRUE</code>, the operation blocks
     * until the buffer is full. If set to <code>FALSE</code>, the
     * operation fills as much of the buffer as possible without
     * blocking.
     *
     * @return <code>FALSE</code> if a connection loss is
     * detected, <code>TRUE</code> otherwise.
     *
     **/

    boolean receive_detect(in Buffer buf, in boolean block);

    /**
     *
     * Similar to <code>receive</code>, but it is
     * possible to specify a timeout. On return the caller can test
     * whether there was a timeout by checking if the buffer has
     * been filled completely.
     *
     * @param buf The buffer to fill.
     *
     * @param timeout The timeout value in milliseconds. A zero
     * timeout is equivalent to calling <code>receive(buf, FALSE)</code>.
     *
     **/

    void receive_timeout(in Buffer buf, in unsigned long timeout);

    /**
     *
     * Sends a buffer's contents.
     *
     * @param buf The buffer to send.
     *
     * @param block If set to <code>TRUE</code>, the operation blocks
     * until the buffer has completely been sent. If set to
     * <code>FALSE</code>, the operation sends as much of the buffer's
     * data as possible without blocking.
     *
     **/

    void send(in Buffer buf, in boolean block);

    /**
     *
     * Similar to <code>send</code>, but it signals a connection loss
     * by returning <code>FALSE</code> instead of raising
     * <code>CORBA::COMM_FAILURE</code>.
     *
     * @param buf The buffer to fill.
     *
     * @param block If set to <code>TRUE</code>, the operation blocks
     * until the entire buffer has been sent. If set to
     * <code>FALSE</code>, the operation sends as much of the buffer's
     * data as possible without blocking.
     *
     * @return <code>FALSE</code> if a connection loss is
     * detected, <code>TRUE</code> otherwise.
     *
     **/

    boolean send_detect(in Buffer buf, in boolean block);

    /**
     *
     * Similar to <code>send</code>, but it is possible
     * to specify a timeout. On return the caller can test whether
     * there was a timeout by checking if the buffer has
     * been sent completely.
     *
     * @param buf The buffer to send.
     *
     * @param timeout The timeout value in milliseconds. A zero
     * timeout is equivalent to calling <code>send(buf, FALSE)</code>.
     *
     **/

    void send_timeout(in Buffer buf, in unsigned long timeout);

     /**
      *
      * Returns the information object associated with
      * the Transport.
      *
      * @return The Transport information object.
      *
      **/

    TransportInfo get_info();
};

/* CloseCB forward declaration */
interface CloseCB;

/**
 *
 * Information on an OCI Transport object. Objects of this type must
 * be narrowed to a Transport information object for a concrete
 * protocol implementation, for example to
 * <code>OCI::IIOP::TransportInfo</code> in case the plug-in
 * implements IIOP.
 *
 * @see Transport
 *
 **/

interface TransportInfo
{
    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /**
     *
     * The ConnectorInfo object for the Connector that created the
     * Transport object that this TransportInfo object belongs to.
     * If the Transport for this TransportInfo was not created by a
     * Connector, this attribute is set to the nil object reference.
     *
     **/

    readonly attribute ConnectorInfo connector_info;

    /**
     *
     * The AcceptorInfo object for the Acceptor that created the
     * Transport object that this TransportInfo object belongs to.
     * If the Transport for this TransportInfo was not created by an
     * Acceptor, this attribute is set to the nil object reference.
     *
     **/

    readonly attribute AcceptorInfo acceptor_info;

    /**
     *
     * Add a callback that is called before a connection is closed. If
     * the callback has already been registered, this method has no
     * effect.
     *
     * @param cb The callback to add.
     *
     **/

    void add_close_cb(in CloseCB cb);

    /**
     *
     * Remove a close callback. If the callback was not registered,
     * this method has no effect.
     *
     * @param cb The callback to remove.
     *
     **/

    void remove_close_cb(in CloseCB cb);
};

/**
 *
 * An interface for a close callback object.
 *
 * @see TransportInfo
 *
 **/

interface CloseCB
{
    /**
     *
     * Called before a connection is closed.
     *
     * @param transport_info The TransportInfo for the new closeion.
     *
     **/

    void close_cb(in TransportInfo transport_info);
};

/** Alias for a sequence of close callback objects. */
typedef sequence< CloseCB > CloseCBSeq;

/**
 *
 * An interface for Connector objects. A Connector is used by CORBA
 * clients to initiate a connection to a server. It also provides
 * operations for the management of IOR profiles.
 *
 * @see ConFactory
 * @see Transport
 *
 **/
 
interface Connector
{
    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /**
     *
     * Used by CORBA clients to establish a connection to a CORBA
     * server. It returns a Transport object, which can be used for
     * sending and receiving octet streams to and from the server.
     *
     * @return The new Transport object.
     *
     **/

    Transport connect();

    /**
     *
     * Similar to <code>connect</code>, but it is possible to specify
     * a timeout. On return the caller can test whether there was a
     * timeout by checking whether a nil object reference was returned.
     *
     * @param timeout The timeout value in milliseconds.
     *
     * @return The new Transport object.
     *
     **/

    Transport connect_timeout(in unsigned long timeout);

    /**
     *
     * Checks whether this Connector can be used for a specific
     * IOR. That is, the IOR must contain at least one profile that
     * matches this Connector.
     *
     * @param ior The IOR to check for.
     *
     * @return The object key of the matching profile if the Connector
     * can be used for the given IOR, or an empty object key
     * otherwise.
     *
     **/

    ObjectKey is_usable(in IOR ior);

    /**
     *
     * Checks whether this Connector can be used for a specific IOR
     * with a given set of polcies. That is, the IOR must contain at
     * least one profile that matches this Connector and the Connector
     * must also satisfy the provided list of policies for the given
     * IOR.
     *
     * @param ior The IOR to check for.
     *
     * @param policies The policies that must be satisfied.
     *
     * @return The object key of the matching profile if the Connector
     * can be used for the given IOR and policies, or an empty object
     * key otherwise.
     *
     **/

    ObjectKey is_usable_with_policies(in IOR ior,
				      in CORBA::PolicyList policies);

     /**
      *
      * Returns the information object associated with
      * the Connector.
      *
      * @return The Connector information object.
      *
      **/

    ConnectorInfo get_info();
};

/* ConnectCB forward declaration */
interface ConnectCB;

/**
 *
 * Information on a OCI Connector object. Objects of this type must be
 * narrowed to a Connector information object for a concrete protocol
 * implementation, for example to <code>OCI::IIOP::ConnectorInfo</code>
 * in case the plug-in implements IIOP.
 *
 * @see Connector
 *
 **/

interface ConnectorInfo
{
    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /**
     *
     * Add a callback that is called whenever a new connection is
     * established. If the callback has already been registered, this
     * method has no effect.
     *
     * @param cb The callback to add.
     *
     **/

    void add_connect_cb(in ConnectCB cb);

    /**
     *
     * Remove a connect callback. If the callback was not registered,
     * this method has no effect.
     *
     * @param cb The callback to remove.
     *
     **/

    void remove_connect_cb(in ConnectCB cb);
};

/**
 *
 * An interface for a connect callback object.
 *
 * @see ConnectorInfo
 *
 **/

interface ConnectCB
{
    /**
     *
     * Called after a new connection has been established. If the
     * application wishes to reject the connection
     * <code>CORBA::NO_PERMISSION</code> may be raised.
     *
     * @param transport_info The TransportInfo for the new connection.
     *
     **/

    void connect_cb(in TransportInfo transport_info);
};

/** Alias for a sequence of connect callback objects. */
typedef sequence< ConnectCB > ConnectCBSeq;

/**
 *
 * An interface for an Acceptor object, which is used by CORBA
 * servers to accept client connection requests. It also provides
 * operations for the management of IOR profiles.
 *
 * @see AccRegistry
 * @see Transport
 *
 **/
 
interface Acceptor
{
    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /**
     *
     * The "handle" for this Acceptor. Like with the handle for
     * Transports, the handle may <em>only</em> be used with
     * operations like <code>select()</code>. A handle value of -1
     * indicates that the protocol plug-in does not support
     * "selectable" Transports.
     *
     **/

    readonly attribute Handle handle;

    /**
     *
     * Closes the Acceptor. <code>accept</code> or <code>listen</code>
     * may not be called after <code>close</code> has been called.
     *
     **/

    void close();

    /**
     *
     * Unblock threads that are blocking in <code>accept</code>. After
     * calling <code>unblock_threads</code>, any further calls to
     * <code>accept</code> may result in a
     * <code>CORBA::COMM_FAILURE</code> exception being raised.
     *
     **/

    void unblock_threads();

    /**
     *
     * Sets the acceptor up to listen for incoming connections. Until
     * this method is called on the acceptor, new connection requests
     * should result in a connection request failure.
     *
     **/

    void listen();
    
    /**
     *
     * Used by CORBA servers to accept client connection requests. It
     * returns a Transport object, which can be used for sending and
     * receiving octet streams to and from the client.
     *
     * @return The new Transport object.
     *
     **/

    Transport accept();

    /**
     *
     * Adds a new profile that matches this Acceptor to an IOR.
     *
     * @param key The object key to use for the new profile.
     *
     * @param ior The IOR.
     *
     **/

    void add_profile(in ObjectKey key, inout IOR ior);

    /**
     *
     * Checks whether an IOR is for a local object, taking only
     * profiles into account matching this Acceptor.
     *
     * @param ior The IOR to check for.
     *
     * @return If the IOR is for a local object, the object key for
     * that local object, or an empty object key otherwise.
     *
     **/

    ObjectKey is_local(in IOR ior);

     /**
      *
      * Returns the information object associated with
      * the Acceptor.
      *
      * @return The Acceptor information object.
      *
      **/

    AcceptorInfo get_info();
};

/** Alias for a sequence of Acceptors. */
typedef sequence< Acceptor > AcceptorSeq;

/* AcceptCB forward declaration */
interface AcceptCB;

/**
 *
 * Information on an OCI Acceptor object. Objects of this type must be
 * narrowed to an Acceptor information object for a concrete protocol
 * implementation, for example to <code>OCI::IIOP::AcceptorInfo</code>
 * in case the plug-in implements IIOP.
 *
 * @see Acceptor
 *
 **/

interface AcceptorInfo
{
    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /**
     *
     * Add a callback that is called whenever a new connection is
     * accepted. If the callback has already been registered, this
     * method has no effect.
     *
     * @param cb The callback to add.
     *
     **/

    void add_accept_cb(in AcceptCB cb);

    /**
     *
     * Remove an accept callback. If the callback was not registered,
     * this method has no effect.
     *
     * @param cb The callback to remove.
     *
     **/

    void remove_accept_cb(in AcceptCB cb);
};

/**
 *
 * An interface for an accept callback object.
 *
 * @see AcceptorInfo
 *
 **/

interface AcceptCB
{
    /**
     *
     * Called after a new connection has been accepted. If the
     * application wishes to reject the connection
     * <code>CORBA::NO_PERMISSION</code> may be raised.
     *
     * @param transport_info The TransportInfo for the new connection.
     *
     **/

    void accept_cb(in TransportInfo transport_info);
};

/** Alias for a sequence of accept callback objects. */
typedef sequence< AcceptCB > AcceptCBSeq;

/**
 *
 * A factory for Connector objects.
 *
 * @see Connector
 * @see ConFactoryRegistry
 *
 **/

interface ConFactory
{
    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /**
     *
     * Creates a new Connector for a given IOR. All connection
     * specific data is taken from an IOR profile that matches this
     * Connector factory. If more than one profile matches, then which
     * of these profiles is used is implementation specific.
     *
     * @param ior The IOR from which the profile and connection data
     * are extracted.
     *
     * @return The new Connector. A nil object reference is returned
     * if the IOR does not contain a profile which matches this
     * Connector factory.
     *
     **/

    Connector create(in IOR ior);

    /**
     *
     * Creates a new Connector for a given IOR, satisfing a list of
     * policies. Like <code>create</code>, all connection specific
     * data is taken from an IOR profile that matches this Connector
     * factory, and if more than one profile matches, then which of
     * these profiles is used is implementation specific.
     *
     * @param ior The IOR from which the profile and connection data
     * are extracted.
     *
     * @param policies The policies that must be satisfied.
     *
     * @return The new Connector. A nil object reference is returned
     * if the IOR does not contain a profile which matches this
     * Connector factory or if the policies cannot be satisfied.
     *
     **/

    Connector create_with_policies(in IOR ior, in CORBA::PolicyList policies);

    /**
     *
     * Determines whether this Connector factory can create a
     * Connector for a given IOR and a given list of policies.
     *
     * @param ior The IOR to consider.
     *
     * @param policies The policies that must be satisfied.
     *
     * @return <code>TRUE</code> if a Connector can be created for the
     * IOR and the policies can be satisfied, <code>FALSE</code>
     * otherwise.
     *
     **/

    boolean consider_with_policies(in IOR ior, in CORBA::PolicyList policies);

   /**
     *
     * Checks whether two IORs are equivalent, taking only profiles
     * into account matching this Connector factory.
     *
     * @param ior1 The first IOR to check for equivalence.
     *
     * @param ior2 The second IOR to check for equivalence.
     *
     * @return <code>TRUE</code> if the IORs are equivalent,
     * <code>FALSE</code> otherwise.
     *
     **/

    boolean equivalent(in IOR ior1, in IOR ior2);

    /**
     *
     * Calculates a hash value for an IOR.
     *
     * @param ior The IOR to calculate a hash value for.
     *
     * @param maximum The maximum value of the hash value.
     *
     * @return The hash value.
     *
     **/

    unsigned long hash(in IOR ior, in unsigned long maximum);

    /**
     *
     * Returns the information object associated with the Connector
     * factory.
     *
     * @return The Connnector factory information object.
     *
     **/

    ConFactoryInfo get_info();
};

/** Alias for a sequence of Connector factories. */
typedef sequence< ConFactory > ConFactorySeq;

/**
 *
 * Information on an OCI ConFactory object.
 *
 * @see ConFactory
 *
 **/

interface ConFactoryInfo
{
    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /**
     *
     * Add a callback that is called whenever a new connection is
     * established. If the callback has already been registered, this
     * method has no effect.
     *
     * @param cb The callback to add.
     *
     **/

    void add_connect_cb(in ConnectCB cb);

    /**
     *
     * Remove a connect callback. If the callback was not registered,
     * this method has no effect.
     *
     * @param cb The callback to remove.
     *
     **/

    void remove_connect_cb(in ConnectCB cb);
};

/**
 *
 * A registry for Connector factories.
 *
 * @see Connector
 * @see ConFactory
 *
 **/

interface ConFactoryRegistry
{
    /**
     *
     * Adds a Connector factory to the registry.
     *
     * @param factory The Connector factory to add.
     *
     **/

    void add_factory(in ConFactory factory);

    /**
     *
     * Returns a suitable Connector factory for an
     * IOR.
     *
     * @param ior The IOR to for which a Connector factory is
     * requested.
     *
     * @return The Connector factory. A nil object reference is
     * returned if no Connector factory is registered which is able to
     * create a Connector for the given IOR.
     *
     **/

    ConFactory get_factory(in IOR ior);

    /**
     *
     * Returns a suitable Connector factory for an
     * IOR. The Connector factory returned must satisfy a list of
     * policies.
     *
     * @param ior The IOR for which a Connector factory is
     * requested.
     *
     * @param policies The list of policies which have to be
     * satisfied.
     *
     * @return The Connector factory. A nil object reference is
     * returned if no Connector factory is registered which is able to
     * create a Connector for the given IOR with the given list of
     * policies.
     *
     **/

    ConFactory get_factory_with_policies(in IOR ior,
					 in CORBA::PolicyList policies);

    /**
     *
     * Returns a sequence of all registered Connector
     * factories.
     *
     * @return A sequence with all registered Connector factories.
     *
     **/

    ConFactorySeq get_factories();

    /**
     *
     * Checks whether two IORs are equivalent. It calls the
     * <code>equivalent</code> operation of all registered Connector
     * factories. Two IORs are considered equivalent, if all these
     * calls return <code>TRUE</code>.
     *
     * @param ior1 The first IOR to check for equivalence.
     *
     * @param ior2 The second IOR to check for equivalence.
     *
     * @return <code>TRUE</code> if the IORs are equivalent,
     * <code>FALSE</code> otherwise.
     *
     **/

    boolean equivalent(in IOR ior1, in IOR ior2);

    /**
     *
     * Calculates an hash value for an IOR. This hash value is based on
     * the return values of the <code>hash</code> operations of all
     * registered Connector factories.
     *
     * @param ior The IOR to calculate an hash value for.
     *
     * @param maximum The maximum hash value that is allowed.
     *
     * @return The hash value.
     *
     **/

    unsigned long hash(in IOR ior, in unsigned long maximum);
};

/**
 *
 * A registry for Acceptors.
 *
 * @see Acceptor
 *
 **/

interface AccRegistry
{
    /**
     *
     * Adds an Acceptor to the registry.
     *
     * @param Acceptor The Acceptor to add.
     *
     **/

    void add_acceptor(in Acceptor Acceptor);

    /**
     *
     * Returns a sequence of all registered Acceptors.
     *
     * @return A sequence of all registered Acceptors.
     *
     **/

    AcceptorSeq get_acceptors();

    /**
     *
     * Adds new profiles to an IOR. For each registered
     * Acceptor a new profile is added by calling the Acceptor's
     * <code>add_profile</code> operation.
     *
     * @param key The object key to use for the new profiles.
     *
     * @param ior The IOR.
     *
     **/

    void add_profiles(in ObjectKey key, inout IOR ior);

    /**
     *
     * Checks whether an IOR is for a local object. It calls the
     * <code>is_local</code> operation of all registered Acceptors. An
     * IOR is considered local, if at least one of these calls returns
     * a non-empty object key.
     *
     * @param ior The IOR to check for.
     *
     * @return If the IOR is for a local object, the object key for
     * that local object, or an empty object key otherwise.
     *
     **/

    ObjectKey is_local(in IOR ior);
};

/**
 *
 * Interface to access Transport and Acceptor information objects
 * related to the current request.
 *
 **/

interface Current : CORBA::Current
{
    /**
     *
     * This method returns the Transport information object for the
     * Transport used to invoke the current request.
     *
     * @returns The Transport information object.
     *
     **/
    
    TransportInfo get_oci_transport_info();
    
    /**
     *
     * This method returns the Acceptor information object for the
     * Acceptor which created the Transport used to invoke the current
     * request.
     *
     * @returns The Acceptor information object.
     *
     **/
    
    AcceptorInfo get_oci_acceptor_info();
};

}; // End module OCI

#endif
