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

#ifndef OB_OAINTERFACE_H
#define OB_OAINTERFACE_H

#include <OB/OAInterface_fwd.h>
#include <OB/Upcall_fwd.h>

#include <OB/Any.h> // Since OCI depends on Any
#include <OB/OCITypes.h>
#include <OB/OCIClient_fwd.h>
#include <OB/Object.h> // For CORBA::Policy
#include <OB/Policy.h>

namespace OB
{

//
// The OAInterface class
//
class OAInterface : public OB::RefCount
{
public:
    
    virtual ~OAInterface() { }

    static inline OAInterface_ptr _duplicate(OAInterface_ptr p)
    { if(p) p -> _OB_incRef(); return p; }
    static inline OAInterface_ptr _nil()
    { return 0; }

    //
    // Create new Upcall object
    //
    // Note: For efficiency reasons, this operation assumes ownership
    // for all parameter marked with "/**/"
    //
    virtual Upcall_ptr createUpcall(UpcallReturn_ptr,
				    /**/ OCI::ProfileInfo*,
				    /**/ OCI::TransportInfo_ptr,
				    CORBA::ULong requestId,
				    /**/ char*,
				    /**/ InputStream_ptr,
				    /**/ IOP::ServiceContextList*)
	throw() = 0;

    //
    // Determine if an object with the provided object key exists
    //
    // This enumeration mirrors the GIOP::LocateStatusType_1_2
    //
    enum LocateStatus
    {
        UNKNOWN_OBJECT = 0,
        OBJECT_HERE = 1,
        OBJECT_FORWARD = 2,
        OBJECT_FORWARD_PERM = 3
    };
    virtual LocateStatus findByKey(const OCI::ObjectKey&,
                                   RefCountIOR_out)
	throw() = 0;

    //
    // Get all profiles that are usable with this OAInterface
    //
    virtual OCI::ProfileInfoSeq* getUsableProfiles(const OCI::IOR&,
						   const CORBA::PolicyList&)
	throw() = 0;

    //
    // Discard all incoming requests with a TRANSIENT exception
    //
    virtual void discard()
	throw() = 0;

    //
    // Allow associated POAs to receive requests
    //
    virtual void activate()
	throw() = 0;
};

} // End of namespace OB

namespace CORBA
{

inline void
release(OB::OAInterface_ptr p)
{
    if(p)
	p -> _OB_decRef();
}

inline Boolean
is_nil(OB::OAInterface_ptr p)
{
    return p == 0;
}

} // End namespace CORBA

#endif
