// **********************************************************************
//
// Copyright (c) 2002
// IONA Technologies, Inc.
// Waltham, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#ifndef OCI_CLIENT_IDL
#define OCI_CLIENT_IDL

#include <OB/OCITypes.idl>
#include <OB/Policy.idl>

#pragma prefix "ooc.com"

module OCI
{

/**
 *
 * The OCI version. If an interface or implementation changes in
 * an incompatible way, this version will be changed.
 *
 **/

const string Version = "1.0";

/* TransportInfo forward declaration */
local interface TransportInfo;

/* ConnectorInfo forward declaration */
local interface ConnectorInfo;

/* AcceptorInfo forward declaration */
local interface AcceptorInfo;

/* ConFactoryInfo forward declaration */
local interface ConFactoryInfo;

/**
 *
 * The interface for a Plugin object, which is used to initialize
 * an OCI plug-in.
 *
 **/

local interface Plugin
{
    /** The plugin id. */
    readonly attribute PluginId id;

    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /**
     *
     * Initialize the client-side of the plug-in.
     *
     * @param params Plug-in specific parameters.
     *
     **/
    void init_client(in ParamSeq params);

    /**
     *
     * Initialize the server-side of the plug-in.
     *
     * @param params Plug-in specific parameters.
     *
     **/
    void init_server(in ParamSeq params);
};

/**
 *
 * 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
 *
 **/
 
local interface Transport
{
    /** The plugin id. */
    readonly attribute PluginId id;

    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /** The send/receive capabilities of this Transport. */
    readonly attribute SendReceiveMode mode;

    /**
     *
     * 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 OCI::Handle handle;

    /**
     *
     * Closes the Transport. After calling <code>close</code>, no
     * operations on this Transport object and its associated
     * TransportInfo object may be called. To ensure that no messages
     * get lost when <code>close</code> is called,
     * <code>shutdown</code> should be called first. Then dummy data
     * should be read from the Transport, using one of the
     * <code>receive</code> operations, until either an exception is
     * raised, or until connection closure is detected. After that its
     * save to call <code>close</code>, i.e., no messages can get
     * lost.
     *
     * @exception COMM_FAILURE In case of an error.
     *
     **/

    void close();

    /**
     *
     * Shutdown the Transport. Upon a successful shutdown, threads
     * blocking in the <code>receive</code> operations will return or
     * throw an exception. After calling <code>shutdown</code>, no
     * operations on associated TransportInfo object may be called. To
     * fully close the Transport, <code>close</code> must be called.
     *
     * @exception COMM_FAILURE In case of an error.
     *
     **/

    void shutdown();

    /**
     *
     * 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.
     *
     * @exception COMM_FAILURE In case of an error.
     *
     **/

    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>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.
     *
     * @exception COMM_FAILURE In case of an error.
     *
     **/

    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>.
     *
     * @exception COMM_FAILURE In case of an error.
     *
     **/

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

    /**
     *
     * Similar to <code>receive_timeout</code>, but it signals a
     * connection loss by returning <code>FALSE</code> instead of
     * raising <code>COMM_FAILURE</code>.
     *
     * @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>.
     *
     * @return <code>FALSE</code> if a connection loss is
     * detected, <code>TRUE</code> otherwise.
     *
     * @exception COMM_FAILURE In case of an error.
     *
     **/

    boolean receive_timeout_detect(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.
     *
     * @exception COMM_FAILURE In case of an error.
     *
     **/

    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>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.
     *
     * @exception COMM_FAILURE In case of an error.
     *
     **/

    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>.
     *
     * @exception COMM_FAILURE In case of an error.
     *
     **/

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

    /**
     *
     * Similar to <code>send_timeout</code>, but it signals a
     * connection loss by returning <code>FALSE</code> instead of
     * raising <code>COMM_FAILURE</code>.
     *
     * @param buf The buffer to fill.
     *
     * @param timeout The timeout value in milliseconds. A zero
     * timeout is equivalent to calling <code>send(buf, FALSE)</code>.
     *
     * @return <code>FALSE</code> if a connection loss is
     * detected, <code>TRUE</code> otherwise.
     *
     * @exception COMM_FAILURE In case of an error.
     *
     **/

    boolean send_timeout_detect(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 */
local 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
 *
 **/

local interface TransportInfo
{
    /** The plugin id. */
    readonly attribute PluginId id;

    /** 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;

    /**
     *
     * Returns a human readable description of the transport.
     *
     * @return The description.
     *
     **/

    string describe();

    /**
     *
     * 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
 *
 **/

local 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
 *
 **/
 
local interface Connector
{
    /** The plugin id. */
    readonly attribute PluginId id;

    /** 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.
     *
     * @exception TRANSIENT If the server cannot be contacted.
     * @exception COMM_FAILURE In case of other errors.
     *
     **/

    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.
     *
     * @exception TRANSIENT If the server cannot be contacted.
     * @exception COMM_FAILURE In case of other errors.
     *
     **/

    Transport connect_timeout(in unsigned long timeout);

    /**
     *
     * From the given IOR and list of policies, get basic information
     * about all profiles for which this Connector can be used.
     *
     * @param ref The IOR from which the profiles are taken.
     *
     * @param policies The policies that must be satisfied.
     *
     * @return The sequence of basic information about profiles. If
     * this sequence is empty, there is no profile in the IOR that
     * matches this Connector and the list of policies.
     *
     **/

    ProfileInfoSeq get_usable_profiles(in IOR ref,
				       in CORBA::PolicyList policies);

    /**
     *
     * Find out whether this Connector is equal to another
     * Connector. Two Connectors are considered equal if they are
     * interchangeable.
     *
     * @param con The connector to compare with.
     *
     * @return <code>TRUE</code> if the Connectors are equal,
     * <code>FALSE</code> otherwise.
     *
     **/

    boolean equal(in Connector con);
      
    /**
     *
     * Returns the information object associated with
     * the Connector.
     *
     * @return The Connector information object.
     *
     **/
    
    ConnectorInfo get_info();
};

/** Alias for a sequence of Connectors. */
typedef sequence< Connector > ConnectorSeq;

/* ConnectCB forward declaration */
local 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
 *
 **/

local interface ConnectorInfo
{
    /** The plugin id. */
    readonly attribute PluginId id;

    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /**
     *
     * Returns a human readable description of the transport.
     *
     * @return The description.
     *
     **/

    string describe();

    /**
     *
     * 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
 *
 **/

local 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;

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

local interface ConFactory
{
    /** The plugin id. */
    readonly attribute PluginId id;

    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /**
     *
     * Returns a description of the given tagged profile.
     *
     * @param prof The tagged profile.
     *
     * @return The profile description.
     *
     **/

    string describe_profile(in IOP::TaggedProfile prof);

    /**
     *
     * Returns a sequence of Connectors for a given IOR and a list of
     * policies. The sequence includes one or more Connectors for each
     * IOR profile that matches this Connector factory and satisfies
     * the list of policies.
     *
     * @param ref The IOR for which Connectors are returned.
     *
     * @param policies The policies that must be satisfied.
     *
     * @return The sequence of Connectors.
     *
     **/
    
    ConnectorSeq create_connectors(in IOR ref, 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 ref 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 ref, in unsigned long maximum);

    /**
     *
     * Returns the information object associated with the Connector
     * factory.
     *
     * @return The Connector 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
 *
 **/

local interface ConFactoryInfo
{
    /** The plugin id. */
    readonly attribute PluginId id;

    /** The profile id tag. */
    readonly attribute ProfileId tag;

    /**
     *
     * Returns a human readable description of the transport.
     *
     * @return The description.
     *
     **/

    string describe();

    /**
     *
     * 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 factory with the given plugin id already exists.
 *
 * @member id The plugin id.
 *
 **/

exception FactoryAlreadyExists
{
    PluginId id;
};

/**
 *
 * No factory with the given plugin id could be found.
 *
 * @member id The plugin id.
 *
 **/

exception NoSuchFactory
{
    PluginId id;
};

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

local interface ConFactoryRegistry
{
    /**
     *
     * Adds a Connector factory to the registry.
     *
     * @param factory The Connector factory to add.
     *
     * @exception FactoryAlreadyExists If a factory already exists with the
     * same plugin id as the given factory.
     *
     **/

    void add_factory(in ConFactory _factory)
        raises(FactoryAlreadyExists);

    /**
     *
     * Returns the factory with the given plugin id.
     *
     * @param id The plugin id.
     *
     * @return The Connector factory.
     *
     * @exception NoSuchFactory If no factory was found with a matching
     * plugin id.
     *
     **/

    ConFactory get_factory(in PluginId id)
        raises(NoSuchFactory);

    /**
     *
     * Returns all registered factories.
     *
     * @return The Connector factories.
     *
     **/

    ConFactorySeq get_factories();
};

}; // End module OCI

#endif
