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

#ifndef OB_NAMING_IMPL_H
#define OB_NAMING_IMPL_H

//
// Forward declarations
//
class NamingDatabase;

class NcOrObjBinding;
typedef NcOrObjBinding* NcOrObjBinding_ptr;
void OBDuplicate(NcOrObjBinding_ptr);
void OBRelease(NcOrObjBinding_ptr);
typedef OBObjVar< NcOrObjBinding > NcOrObjBinding_var;

//
// Declaration of NamingContextSet.
//
typedef OBHashtable< CORBA_String_var, CosNaming_NamingContext_ptr,
                     OB_LOCK_STRATEGY_SYNCHRONIZED > NamingContextSet;

//
// Implementation of CosNaming::OBNamingContext.
//
class CosNaming_OBNamingContext_impl
    : virtual public CosNaming_OBNamingContext_skel
{
#ifdef HAVE_JTC
    static JTCMutex countMut_; // Mutex for count.
#endif
    static int count_; // Running static count for keys.

    CORBA_ORB_var orb_;
    CORBA_String_var key_;

public: // Some compilers need this to be public

    typedef OBHashtable< CosNaming_NameComponent, NcOrObjBinding_var,
	                 OB_LOCK_STRATEGY_SYNCHRONIZED > BindingsHash;

private:

    BindingsHash* bindings_; // Set of bindings in this context.

    NamingContextSet* ncs_; // Global set of naming contexts.
    NamingDatabase* store_; // The database.
    bool noUpdates_; // No automatic updates?
    bool destroyed_; // Has the context been destroyed?

    //
    // Clients to which this service reports events.
    //
    CosNaming_BindingListenerSeq listeners_;
#ifdef HAVE_JTC
    JTCMutex listenersMutex_;
#endif

    CosNaming_NamingContext_var myRef_; // Object-reference to myself.

    void cleanup();

    void doBind(const CosNaming_Name& n,
		const CosNaming_OBNamingContext::NcOrObj&, bool, long);

    //
    // Support for BindingListener interface
    //
    void bindingAdded(const NcOrObj&, const CosNaming_Name&);
    void bindingRemoved(const CosNaming_Name&, bool isContext);
    void bindingChanged(const NcOrObj&, const CosNaming_Name&,
			const CosNaming_Name&);

    //
    // Add escapes for INS
    //
    static char* addEscapes(const char*);
    static char* addURLEscapes(const char*);

    CosNaming_OBNamingContext_impl* createNewContext();

public:

    CosNaming_OBNamingContext_impl(CORBA_ORB_ptr, NamingDatabase*,
				   NamingContextSet*, const char*, bool);
    ~CosNaming_OBNamingContext_impl();

    //
    // Standard IDL to C++ Mapping.
    //

    //
    // CosNaming::NamingContext.
    //
    virtual void
    bind(const CosNaming_Name&, CORBA_Object_ptr);

    virtual void
    rebind(const CosNaming_Name&, CORBA_Object_ptr);

    virtual void
    bind_context(const CosNaming_Name&,
		 CosNaming_NamingContext_ptr);

    virtual void
    rebind_context(const CosNaming_Name&, CosNaming_NamingContext_ptr);

    virtual CORBA_Object_ptr
    resolve(const CosNaming_Name&);

    virtual void
    unbind(const CosNaming_Name&);

    virtual CosNaming_NamingContext_ptr
    new_context();

    virtual CosNaming_NamingContext_ptr
    bind_new_context(const CosNaming_Name& n);

    virtual void
    destroy();

    virtual void
    list(CORBA_ULong, CosNaming_BindingList*&, CosNaming_BindingIterator_ptr&);

    //
    // CosNaming::NamingContextExt.
    //
    virtual CosNaming_NamingContextExt::StringName
    to_string(const CosNaming_Name&);

    virtual CosNaming_Name*
    to_name(const char*);

    virtual CosNaming_NamingContextExt::URLString
    to_url(const char*, const char*);

    virtual CORBA_Object_ptr
    resolve_str(const char*);

    //
    // CosNaming::OBNamingContext.
    //
    virtual CosNaming_OBNamingContext::ExtendedBindingList*
    list_extended();

    virtual void
    rename(const CosNaming_Name&, const CosNaming_Name&);

    virtual CORBA_Boolean
    add_listener(CosNaming_BindingListener_ptr);

    virtual CORBA_Boolean
    remove_listener(CosNaming_BindingListener_ptr);

    virtual CORBA_Boolean
    callbacks_active();

    //
    // ORBacus internal methods.
    //
    const char* _OB_getKey() const;

    void
    _OB_bindWithTimestamp(const CosNaming_Name&,
			  const CosNaming_OBNamingContext::NcOrObj&,
			  long);

    void _OB_releaseInternal();

    OB_MAKE_NARROW_IMPL(CosNaming_OBNamingContext_impl)
};

class CosNaming_BindingIterator_impl
    : virtual public CosNaming_BindingIterator_skel
      OB_COMMA_MONITOR
{
    CORBA_ORB_var orb_;
    CORBA_ULong idx_;
    CosNaming_BindingList bl_;

public:

    CosNaming_BindingIterator_impl(CORBA_ORB_ptr,
				   const CosNaming_BindingList&);

    //
    // Standard IDL to C++ Mapping.
    //
    virtual CORBA_Boolean
    next_one(CosNaming_Binding*&);

    virtual CORBA_Boolean
    next_n(CORBA_ULong, CosNaming_BindingList*&);

    virtual void
    destroy();
};

#endif
