<commit_before>/*************************************************************************
 *
 *  $RCSfile: apitreeimplobj.cxx,v $
 *
 *  $Revision: 1.32 $
 *
 *  last change: $Author: jb $ $Date: 2002-10-10 09:32:23 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include <stdio.h>

#include "apitreeimplobj.hxx"

#ifndef CONFIGMGR_API_PROVIDERIMPL2_HXX_
#include "confproviderimpl2.hxx"
#endif
#ifndef CONFIGMGR_CONFIGNOTIFIER_HXX_
#include "confignotifier.hxx"
#endif
#ifndef CONFIGMGR_API_NOTIFIERIMPL_HXX_
#include "notifierimpl.hxx"
#endif
#ifndef CONFIGMGR_API_FACTORY_HXX_
#include "apifactory.hxx"
#endif
#ifndef CONFIGMGR_API_TREEACCESS_HXX_
#include "apitreeaccess.hxx"
#endif
#ifndef CONFIGMGR_CONFIGCHANGEINFO_HXX_
#include "nodechangeinfo.hxx"
#endif
#ifndef CONFIGMGR_API_BROADCASTER_HXX_
#include "broadcaster.hxx"
#endif
#ifndef CONFIGMGR_CHANGE_HXX
#include "change.hxx"
#endif
#ifndef CONFIGMGR_ROOTTREE_HXX_
#include "roottree.hxx"
#endif
#ifndef CONFIGMGR_CONFIGNODE_HXX_
#include "noderef.hxx"
#endif
#ifndef CONFIGMGR_CONFIGANYNODE_HXX_
#include "anynoderef.hxx"
#endif
#ifndef _CONFIGMGR_TRACER_HXX_
#include "tracer.hxx"
#endif

#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_
#include <cppuhelper/queryinterface.hxx>
#endif
#ifndef _VOS_REFERNCE_HXX_
#include <vos/refernce.hxx>
#endif

namespace configmgr
{
//-----------------------------------------------------------------------------
    namespace configapi
    {
//-----------------------------------------------------------------------------
        namespace lang = ::com::sun::star::lang;
//-----------------------------------------------------------------------------
        class Factory;
        class Notifier;
//-----------------------------------------------------------------------------
class ApiTreeImpl::ComponentAdapter : public lang::XEventListener
{
    osl::Mutex mutex;
    vos::ORefCount m_refs;

    ApiTreeImpl* pOwner;

    uno::Reference< lang::XComponent > xProvider;
    uno::Reference< lang::XComponent > xParent;
public:
    ComponentAdapter(ApiTreeImpl& rParent) : pOwner(&rParent) {}

    void clear();

    void setProvider(uno::Reference< lang::XComponent > const& xProvider);
    void setParent(uno::Reference< lang::XComponent > const& xParent);
    uno::Reference< lang::XComponent > getProvider() const;
    uno::Reference< lang::XComponent > getParent() const;

// XEventListener
    virtual void SAL_CALL acquire() throw();
    virtual void SAL_CALL release() throw();
private:
    void setComponent(uno::Reference< lang::XComponent >& rxSlot,uno::Reference< lang::XComponent > const& xComp);
    uno::Reference< lang::XComponent > getComponent(uno::Reference< lang::XComponent > const& rxSlot) const;

    virtual uno::Any SAL_CALL queryInterface(uno::Type const& rType) throw();
    virtual void SAL_CALL disposing(com::sun::star::lang::EventObject const& rEvt) throw();
};
//-----------------------------------------------------------------------------
inline
uno::Reference< lang::XComponent >
    ApiTreeImpl::ComponentAdapter::getComponent(
        uno::Reference< lang::XComponent > const& rxSlot
    ) const
{
    return rxSlot;
}
//-----------------------------------------------------------------------------
inline
void ApiTreeImpl::ComponentAdapter::setComponent(
        uno::Reference< lang::XComponent >& rxSlot,
        uno::Reference< lang::XComponent > const& xComp
    )
{
    osl::ClearableMutexGuard aGuard(mutex);

    uno::Reference< lang::XComponent > xOld = rxSlot;
    if (xOld != xComp)
    {
        rxSlot = xComp;

        aGuard.clear();

        if (xOld.is()) xOld->removeEventListener(this);
        if (xComp.is()) xComp->addEventListener(this);
    }
}
//-----------------------------------------------------------------------------
uno::Reference< lang::XComponent > ApiTreeImpl::ComponentAdapter::getProvider() const
{
    return this->getComponent( this->xProvider );
}
uno::Reference< lang::XComponent > ApiTreeImpl::ComponentAdapter::getParent() const
{
    return this->getComponent( this->xParent );
}
void ApiTreeImpl::ComponentAdapter::setProvider(uno::Reference< lang::XComponent > const& xProvider)
{
    this->setComponent( this->xProvider, xProvider);
}
void ApiTreeImpl::ComponentAdapter::setParent(uno::Reference< lang::XComponent > const& xParent)
{
    this->setComponent( this->xParent, xParent);
}
//-----------------------------------------------------------------------------

void SAL_CALL ApiTreeImpl::ComponentAdapter::acquire() throw()
{
    ++m_refs;
}
//-------------------------------------------------------------------------

void SAL_CALL ApiTreeImpl::ComponentAdapter::release() throw()
{
    if (--m_refs == 0)
        delete this;
}
//-------------------------------------------------------------------------

uno::Any SAL_CALL ApiTreeImpl::ComponentAdapter::queryInterface(uno::Type const& rType) throw()
{
    return cppu::queryInterface( rType
                , static_cast< com::sun::star::lang::XEventListener*>(this)
                , static_cast< uno::XInterface*>(this)
            );
}
//-------------------------------------------------------------------------

void SAL_CALL ApiTreeImpl::ComponentAdapter::disposing(com::sun::star::lang::EventObject const& rEvt) throw()
{
    osl::ClearableMutexGuard aGuard(mutex);
    if (this->pOwner != NULL)
    {
        CFG_TRACE_INFO("ApiTreeImpl:ComponentAdapter: Providing UNO object is disposed - relaying to my owner");
        UnoInterfaceRef xKeepAlive( this->pOwner->getUnoInstance() );

        aGuard.clear();

        pOwner->disposing( rEvt );

        osl::MutexGuard aClearGuard(mutex);
        if (rEvt.Source == this->xParent) this->xParent.clear();
        if (rEvt.Source == this->xProvider) this->xParent.clear();
    }
    else
        CFG_TRACE_INFO("ApiTreeImpl:ComponentAdapter: Providing UNO object is disposed - but my owner is already gone");
}

//-------------------------------------------------------------------------

void ApiTreeImpl::ComponentAdapter::clear()
{
    osl::ClearableMutexGuard aGuard(mutex);

    this->pOwner = 0;

    uno::Reference< lang::XComponent > xProvider = this->xProvider;
    uno::Reference< lang::XComponent > xParent  = this->xParent;
    this->xProvider = 0;
    this->xParent = 0;

    aGuard.clear();

    if (xParent.is()) xParent->removeEventListener(this);
    if (xProvider.is()) xProvider->removeEventListener(this);
}

//-----------------------------------------------------------------------------
class ApiRootTreeImpl::NodeListener : public INodeListener
{
    osl::Mutex mutex;
    ApiRootTreeImpl*    pParent;
    IConfigBroadcaster* pSource;

    vos::ORef< OOptions > m_xOptions;
    AbsolutePath          m_aLocationPath;
public:
    NodeListener(ApiRootTreeImpl& _rParent)
        : pParent(&_rParent)
        , pSource(NULL)
        , m_aLocationPath( AbsolutePath::root() )
    {}
    ~NodeListener()
    {
        unbind();
    }

    IConfigBroadcaster* getSource()
    {
        osl::MutexGuard aGuard(mutex);
        return pSource;
    }

    void setSource(IConfigBroadcaster* pNew)
    {
        osl::MutexGuard aGuard(mutex);
        if (pParent)
        {
            if (pNew != pSource)
            {
                if (pSource)
                    pSource->removeListener(m_xOptions, this);

                pSource = pNew;
                if (pNew)
                {
                    OSL_ENSURE(!m_aLocationPath.isRoot(), "Cannot register for notifications: no location set");
                    pNew->addListener(m_aLocationPath, m_xOptions, this);
                }
            }
        }
    }

    void setLocation(AbsolutePath const& _aLocation, vos::ORef< OOptions > const& _xOptions)
    {
        osl::MutexGuard aGuard(mutex);

        if (pSource && pParent)
            pSource->removeListener(m_xOptions, this);

        m_aLocationPath = _aLocation;
        m_xOptions = _xOptions;

        if (pSource && pParent)
            pSource->addListener(m_aLocationPath, m_xOptions, this);
    }

    void unbind()
    {
        osl::MutexGuard aGuard(mutex);
        OSL_ASSERT(pParent == 0);
        pParent = 0;
        if (pSource)
        {
            pSource->removeListener(m_xOptions, this);
            m_xOptions.unbind();
            m_aLocationPath = AbsolutePath::root();
        }

    }

    void clearParent()
    {
        osl::ClearableMutexGuard aGuard(mutex);
        if (pParent)
        {
            pParent = 0;

            if (pSource)
            {
                IConfigBroadcaster* pOrgSource = pSource;
                vos::ORef< OOptions > xOptions = m_xOptions;

                pSource = 0;
                m_xOptions.unbind();
                m_aLocationPath = AbsolutePath::root();

                aGuard.clear();

                pOrgSource->removeListener(xOptions, this);
            }
        }
    }

    // Interfaces
    virtual void disposing(IConfigBroadcaster* pSource);
    virtual void nodeChanged(data::Accessor const& _aChangedDataAccessor, Change const& aChange, AbsolutePath const& sPath, IConfigBroadcaster* pSource);
    virtual void nodeDeleted(data::Accessor const& _aChangedDataAccessor, AbsolutePath const& sPath, IConfigBroadcaster* pSource);
};

//-------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// API object implementation wrappers
//-------------------------------------------------------------------------
ApiProvider::ApiProvider(Factory& rFactory, OProviderImpl& rProviderImpl )
    : m_rFactory(rFactory)
    , m_rProviderImpl(rProviderImpl)
{}
//-------------------------------------------------------------------------

UnoTypeConverter ApiProvider::getTypeConverter() const
{
    return m_rProviderImpl.getTypeConverter();
}
//-------------------------------------------------------------------------
static
inline
configuration::DefaultProvider createDefaultProvider(
                                    ApiProvider& rProvider,
                                    configuration::Tree const& aTree,
                                    vos::ORef< OOptions >const& _xOptions
                               )
{
    OProviderImpl& rProviderImpl        = rProvider.getProviderImpl();
    rtl::Reference< IConfigDefaultProvider > xDefaultProvider  = rProviderImpl.getDefaultProvider();

    return configuration::DefaultProvider::create(aTree,_xOptions,xDefaultProvider,&rProviderImpl);
}
//-------------------------------------------------------------------------
static
inline
configuration::DefaultProvider extractDefaultProvider(ApiTreeImpl* pParentTree)
{
    if (pParentTree)
        return pParentTree->getDefaultProvider();

    else
        return configuration::DefaultProvider::createEmpty();
}
//-------------------------------------------------------------------------
ApiTreeImpl::ApiTreeImpl(UnoInterface* pInstance, configuration::TreeRef const& aTree, ApiTreeImpl& rParentTree)
: m_pInstance(pInstance)
, m_aTree(aTree)
, m_aDefaultProvider(rParentTree.getDefaultProvider())
, m_rProvider(rParentTree.getProvider())
, m_pParentTree(0)
, m_aNotifier(new NotifierImpl(aTree))
{
    setNodeInstance(aTree.getRootNode(), pInstance);
    init(&rParentTree);
}
//-------------------------------------------------------------------------
ApiTreeImpl::ApiTreeImpl(UnoInterface* pInstance, ApiProvider& rProvider, configuration::TreeRef const& aTree, ApiTreeImpl* pParentTree)
: m_pInstance(pInstance)
, m_aTree(aTree)
, m_aDefaultProvider(extractDefaultProvider(pParentTree))
, m_rProvider(rProvider)
, m_pParentTree(0)
, m_aNotifier(new NotifierImpl(aTree))
{
    OSL_ENSURE(pParentTree == NULL || &rProvider == &pParentTree->m_rProvider,"WARNING: Parent tree has a different provider - trouble may be ahead");
    setNodeInstance(aTree.getRootNode(), pInstance);
    init(pParentTree);
}
//-------------------------------------------------------------------------
ApiTreeImpl::ApiTreeImpl(UnoInterface* _pInstance, ApiProvider& _rProvider, configuration::TreeRef const& _aTree, DefaultProvider const& _aDefaultProvider)
: m_pInstance(_pInstance)
, m_aTree(_aTree)
, m_aDefaultProvider(_aDefaultProvider)
, m_rProvider(_rProvider)
, m_pParentTree(0)
, m_aNotifier(new NotifierImpl(_aTree))
{
    setNodeInstance(_aTree.getRootNode(), _pInstance);
    init(NULL);
}
//-------------------------------------------------------------------------

ApiTreeImpl::~ApiTreeImpl()
{
    OSL_ENSURE(m_aNotifier->m_aListeners.isDisposed(),"ApiTree Object was not disposed properly");
    deinit();
}
//-------------------------------------------------------------------------

ApiRootTreeImpl::ApiRootTreeImpl(UnoInterface* pInstance, ApiProvider& rProvider, configuration::Tree const& aTree, vos::ORef< OOptions >const& _xOptions)
: m_aTreeImpl(pInstance, rProvider, aTree.getRef(), createDefaultProvider(rProvider, aTree, _xOptions))
, m_pNotificationListener(NULL)
, m_xOptions(_xOptions)
, m_aLocationPath( configuration::Path::Rep() )
{
    implSetLocation(aTree);
    enableNotification(true);
}
//-------------------------------------------------------------------------
ApiRootTreeImpl::~ApiRootTreeImpl()
{
    if (m_pNotificationListener.isValid())
    {
        m_pNotificationListener->setSource(0);
        m_pNotificationListener->clearParent();
    }
}
//-------------------------------------------------------------------------

void ApiTreeImpl::setNodeInstance(configuration::NodeRef const& aNode, UnoInterface* pInstance)
{
    OSL_ENSURE(aNode.isValid(),"ERROR: adding invalid node to ApiTree");
    OSL_ENSURE(m_aTree.isValidNode(aNode),"ERROR: foreign node being added to ApiTree");
    m_aNotifier->m_aListeners.setObjectAt( configuration::NodeID(m_aTree, aNode).toIndex(), pInstance );
}

//-------------------------------------------------------------------------

bool ApiTreeImpl::isAlive() const
{
    return m_aNotifier->m_aListeners.isAlive();
}
//-------------------------------------------------------------------------
void ApiTreeImpl::checkAlive() const
{
    OSL_VERIFY( m_aNotifier->m_aListeners.checkAlive( getUnoInstance()) ); //, "Object is being disposed" );
}
//-------------------------------------------------------------------------

osl::Mutex& ApiTreeImpl::getApiLock() const
{
    return m_aNotifier->mutex();
}
//-------------------------------------------------------------------------

Notifier ApiTreeImpl::getNotifier() const
{
    return Notifier(m_aNotifier,this);
}
//-------------------------------------------------------------------------

bool ApiRootTreeImpl::enableNotification(bool bEnable)
{
    IConfigBroadcaster* pSource = bEnable ? getApiTree().getProvider().getProviderImpl().getNotifier() : 0;<commit_msg>#104243# Removed spurious assertion when object is used from a disposing()-Listener.<commit_after>/*************************************************************************
 *
 *  $RCSfile: apitreeimplobj.cxx,v $
 *
 *  $Revision: 1.33 $
 *
 *  last change: $Author: jb $ $Date: 2002-10-15 15:03:52 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include <stdio.h>

#include "apitreeimplobj.hxx"

#ifndef CONFIGMGR_API_PROVIDERIMPL2_HXX_
#include "confproviderimpl2.hxx"
#endif
#ifndef CONFIGMGR_CONFIGNOTIFIER_HXX_
#include "confignotifier.hxx"
#endif
#ifndef CONFIGMGR_API_NOTIFIERIMPL_HXX_
#include "notifierimpl.hxx"
#endif
#ifndef CONFIGMGR_API_FACTORY_HXX_
#include "apifactory.hxx"
#endif
#ifndef CONFIGMGR_API_TREEACCESS_HXX_
#include "apitreeaccess.hxx"
#endif
#ifndef CONFIGMGR_CONFIGCHANGEINFO_HXX_
#include "nodechangeinfo.hxx"
#endif
#ifndef CONFIGMGR_API_BROADCASTER_HXX_
#include "broadcaster.hxx"
#endif
#ifndef CONFIGMGR_CHANGE_HXX
#include "change.hxx"
#endif
#ifndef CONFIGMGR_ROOTTREE_HXX_
#include "roottree.hxx"
#endif
#ifndef CONFIGMGR_CONFIGNODE_HXX_
#include "noderef.hxx"
#endif
#ifndef CONFIGMGR_CONFIGANYNODE_HXX_
#include "anynoderef.hxx"
#endif
#ifndef _CONFIGMGR_TRACER_HXX_
#include "tracer.hxx"
#endif

#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_
#include <cppuhelper/queryinterface.hxx>
#endif
#ifndef _VOS_REFERNCE_HXX_
#include <vos/refernce.hxx>
#endif

namespace configmgr
{
//-----------------------------------------------------------------------------
    namespace configapi
    {
//-----------------------------------------------------------------------------
        namespace lang = ::com::sun::star::lang;
//-----------------------------------------------------------------------------
        class Factory;
        class Notifier;
//-----------------------------------------------------------------------------
class ApiTreeImpl::ComponentAdapter : public lang::XEventListener
{
    osl::Mutex mutex;
    vos::ORefCount m_refs;

    ApiTreeImpl* pOwner;

    uno::Reference< lang::XComponent > xProvider;
    uno::Reference< lang::XComponent > xParent;
public:
    ComponentAdapter(ApiTreeImpl& rParent) : pOwner(&rParent) {}

    void clear();

    void setProvider(uno::Reference< lang::XComponent > const& xProvider);
    void setParent(uno::Reference< lang::XComponent > const& xParent);
    uno::Reference< lang::XComponent > getProvider() const;
    uno::Reference< lang::XComponent > getParent() const;

// XEventListener
    virtual void SAL_CALL acquire() throw();
    virtual void SAL_CALL release() throw();
private:
    void setComponent(uno::Reference< lang::XComponent >& rxSlot,uno::Reference< lang::XComponent > const& xComp);
    uno::Reference< lang::XComponent > getComponent(uno::Reference< lang::XComponent > const& rxSlot) const;

    virtual uno::Any SAL_CALL queryInterface(uno::Type const& rType) throw();
    virtual void SAL_CALL disposing(com::sun::star::lang::EventObject const& rEvt) throw();
};
//-----------------------------------------------------------------------------
inline
uno::Reference< lang::XComponent >
    ApiTreeImpl::ComponentAdapter::getComponent(
        uno::Reference< lang::XComponent > const& rxSlot
    ) const
{
    return rxSlot;
}
//-----------------------------------------------------------------------------
inline
void ApiTreeImpl::ComponentAdapter::setComponent(
        uno::Reference< lang::XComponent >& rxSlot,
        uno::Reference< lang::XComponent > const& xComp
    )
{
    osl::ClearableMutexGuard aGuard(mutex);

    uno::Reference< lang::XComponent > xOld = rxSlot;
    if (xOld != xComp)
    {
        rxSlot = xComp;

        aGuard.clear();

        if (xOld.is()) xOld->removeEventListener(this);
        if (xComp.is()) xComp->addEventListener(this);
    }
}
//-----------------------------------------------------------------------------
uno::Reference< lang::XComponent > ApiTreeImpl::ComponentAdapter::getProvider() const
{
    return this->getComponent( this->xProvider );
}
uno::Reference< lang::XComponent > ApiTreeImpl::ComponentAdapter::getParent() const
{
    return this->getComponent( this->xParent );
}
void ApiTreeImpl::ComponentAdapter::setProvider(uno::Reference< lang::XComponent > const& xProvider)
{
    this->setComponent( this->xProvider, xProvider);
}
void ApiTreeImpl::ComponentAdapter::setParent(uno::Reference< lang::XComponent > const& xParent)
{
    this->setComponent( this->xParent, xParent);
}
//-----------------------------------------------------------------------------

void SAL_CALL ApiTreeImpl::ComponentAdapter::acquire() throw()
{
    ++m_refs;
}
//-------------------------------------------------------------------------

void SAL_CALL ApiTreeImpl::ComponentAdapter::release() throw()
{
    if (--m_refs == 0)
        delete this;
}
//-------------------------------------------------------------------------

uno::Any SAL_CALL ApiTreeImpl::ComponentAdapter::queryInterface(uno::Type const& rType) throw()
{
    return cppu::queryInterface( rType
                , static_cast< com::sun::star::lang::XEventListener*>(this)
                , static_cast< uno::XInterface*>(this)
            );
}
//-------------------------------------------------------------------------

void SAL_CALL ApiTreeImpl::ComponentAdapter::disposing(com::sun::star::lang::EventObject const& rEvt) throw()
{
    osl::ClearableMutexGuard aGuard(mutex);
    if (this->pOwner != NULL)
    {
        CFG_TRACE_INFO("ApiTreeImpl:ComponentAdapter: Providing UNO object is disposed - relaying to my owner");
        UnoInterfaceRef xKeepAlive( this->pOwner->getUnoInstance() );

        aGuard.clear();

        pOwner->disposing( rEvt );

        osl::MutexGuard aClearGuard(mutex);
        if (rEvt.Source == this->xParent) this->xParent.clear();
        if (rEvt.Source == this->xProvider) this->xParent.clear();
    }
    else
        CFG_TRACE_INFO("ApiTreeImpl:ComponentAdapter: Providing UNO object is disposed - but my owner is already gone");
}

//-------------------------------------------------------------------------

void ApiTreeImpl::ComponentAdapter::clear()
{
    osl::ClearableMutexGuard aGuard(mutex);

    this->pOwner = 0;

    uno::Reference< lang::XComponent > xProvider = this->xProvider;
    uno::Reference< lang::XComponent > xParent  = this->xParent;
    this->xProvider = 0;
    this->xParent = 0;

    aGuard.clear();

    if (xParent.is()) xParent->removeEventListener(this);
    if (xProvider.is()) xProvider->removeEventListener(this);
}

//-----------------------------------------------------------------------------
class ApiRootTreeImpl::NodeListener : public INodeListener
{
    osl::Mutex mutex;
    ApiRootTreeImpl*    pParent;
    IConfigBroadcaster* pSource;

    vos::ORef< OOptions > m_xOptions;
    AbsolutePath          m_aLocationPath;
public:
    NodeListener(ApiRootTreeImpl& _rParent)
        : pParent(&_rParent)
        , pSource(NULL)
        , m_aLocationPath( AbsolutePath::root() )
    {}
    ~NodeListener()
    {
        unbind();
    }

    IConfigBroadcaster* getSource()
    {
        osl::MutexGuard aGuard(mutex);
        return pSource;
    }

    void setSource(IConfigBroadcaster* pNew)
    {
        osl::MutexGuard aGuard(mutex);
        if (pParent)
        {
            if (pNew != pSource)
            {
                if (pSource)
                    pSource->removeListener(m_xOptions, this);

                pSource = pNew;
                if (pNew)
                {
                    OSL_ENSURE(!m_aLocationPath.isRoot(), "Cannot register for notifications: no location set");
                    pNew->addListener(m_aLocationPath, m_xOptions, this);
                }
            }
        }
    }

    void setLocation(AbsolutePath const& _aLocation, vos::ORef< OOptions > const& _xOptions)
    {
        osl::MutexGuard aGuard(mutex);

        if (pSource && pParent)
            pSource->removeListener(m_xOptions, this);

        m_aLocationPath = _aLocation;
        m_xOptions = _xOptions;

        if (pSource && pParent)
            pSource->addListener(m_aLocationPath, m_xOptions, this);
    }

    void unbind()
    {
        osl::MutexGuard aGuard(mutex);
        OSL_ASSERT(pParent == 0);
        pParent = 0;
        if (pSource)
        {
            pSource->removeListener(m_xOptions, this);
            m_xOptions.unbind();
            m_aLocationPath = AbsolutePath::root();
        }

    }

    void clearParent()
    {
        osl::ClearableMutexGuard aGuard(mutex);
        if (pParent)
        {
            pParent = 0;

            if (pSource)
            {
                IConfigBroadcaster* pOrgSource = pSource;
                vos::ORef< OOptions > xOptions = m_xOptions;

                pSource = 0;
                m_xOptions.unbind();
                m_aLocationPath = AbsolutePath::root();

                aGuard.clear();

                pOrgSource->removeListener(xOptions, this);
            }
        }
    }

    // Interfaces
    virtual void disposing(IConfigBroadcaster* pSource);
    virtual void nodeChanged(data::Accessor const& _aChangedDataAccessor, Change const& aChange, AbsolutePath const& sPath, IConfigBroadcaster* pSource);
    virtual void nodeDeleted(data::Accessor const& _aChangedDataAccessor, AbsolutePath const& sPath, IConfigBroadcaster* pSource);
};

//-------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// API object implementation wrappers
//-------------------------------------------------------------------------
ApiProvider::ApiProvider(Factory& rFactory, OProviderImpl& rProviderImpl )
    : m_rFactory(rFactory)
    , m_rProviderImpl(rProviderImpl)
{}
//-------------------------------------------------------------------------

UnoTypeConverter ApiProvider::getTypeConverter() const
{
    return m_rProviderImpl.getTypeConverter();
}
//-------------------------------------------------------------------------
static
inline
configuration::DefaultProvider createDefaultProvider(
                                    ApiProvider& rProvider,
                                    configuration::Tree const& aTree,
                                    vos::ORef< OOptions >const& _xOptions
                               )
{
    OProviderImpl& rProviderImpl        = rProvider.getProviderImpl();
    rtl::Reference< IConfigDefaultProvider > xDefaultProvider  = rProviderImpl.getDefaultProvider();

    return configuration::DefaultProvider::create(aTree,_xOptions,xDefaultProvider,&rProviderImpl);
}
//-------------------------------------------------------------------------
static
inline
configuration::DefaultProvider extractDefaultProvider(ApiTreeImpl* pParentTree)
{
    if (pParentTree)
        return pParentTree->getDefaultProvider();

    else
        return configuration::DefaultProvider::createEmpty();
}
//-------------------------------------------------------------------------
ApiTreeImpl::ApiTreeImpl(UnoInterface* pInstance, configuration::TreeRef const& aTree, ApiTreeImpl& rParentTree)
: m_pInstance(pInstance)
, m_aTree(aTree)
, m_aDefaultProvider(rParentTree.getDefaultProvider())
, m_rProvider(rParentTree.getProvider())
, m_pParentTree(0)
, m_aNotifier(new NotifierImpl(aTree))
{
    setNodeInstance(aTree.getRootNode(), pInstance);
    init(&rParentTree);
}
//-------------------------------------------------------------------------
ApiTreeImpl::ApiTreeImpl(UnoInterface* pInstance, ApiProvider& rProvider, configuration::TreeRef const& aTree, ApiTreeImpl* pParentTree)
: m_pInstance(pInstance)
, m_aTree(aTree)
, m_aDefaultProvider(extractDefaultProvider(pParentTree))
, m_rProvider(rProvider)
, m_pParentTree(0)
, m_aNotifier(new NotifierImpl(aTree))
{
    OSL_ENSURE(pParentTree == NULL || &rProvider == &pParentTree->m_rProvider,"WARNING: Parent tree has a different provider - trouble may be ahead");
    setNodeInstance(aTree.getRootNode(), pInstance);
    init(pParentTree);
}
//-------------------------------------------------------------------------
ApiTreeImpl::ApiTreeImpl(UnoInterface* _pInstance, ApiProvider& _rProvider, configuration::TreeRef const& _aTree, DefaultProvider const& _aDefaultProvider)
: m_pInstance(_pInstance)
, m_aTree(_aTree)
, m_aDefaultProvider(_aDefaultProvider)
, m_rProvider(_rProvider)
, m_pParentTree(0)
, m_aNotifier(new NotifierImpl(_aTree))
{
    setNodeInstance(_aTree.getRootNode(), _pInstance);
    init(NULL);
}
//-------------------------------------------------------------------------

ApiTreeImpl::~ApiTreeImpl()
{
    OSL_ENSURE(m_aNotifier->m_aListeners.isDisposed(),"ApiTree Object was not disposed properly");
    deinit();
}
//-------------------------------------------------------------------------

ApiRootTreeImpl::ApiRootTreeImpl(UnoInterface* pInstance, ApiProvider& rProvider, configuration::Tree const& aTree, vos::ORef< OOptions >const& _xOptions)
: m_aTreeImpl(pInstance, rProvider, aTree.getRef(), createDefaultProvider(rProvider, aTree, _xOptions))
, m_pNotificationListener(NULL)
, m_xOptions(_xOptions)
, m_aLocationPath( configuration::Path::Rep() )
{
    implSetLocation(aTree);
    enableNotification(true);
}
//-------------------------------------------------------------------------
ApiRootTreeImpl::~ApiRootTreeImpl()
{
    if (m_pNotificationListener.isValid())
    {
        m_pNotificationListener->setSource(0);
        m_pNotificationListener->clearParent();
    }
}
//-------------------------------------------------------------------------

void ApiTreeImpl::setNodeInstance(configuration::NodeRef const& aNode, UnoInterface* pInstance)
{
    OSL_ENSURE(aNode.isValid(),"ERROR: adding invalid node to ApiTree");
    OSL_ENSURE(m_aTree.isValidNode(aNode),"ERROR: foreign node being added to ApiTree");
    m_aNotifier->m_aListeners.setObjectAt( configuration::NodeID(m_aTree, aNode).toIndex(), pInstance );
}

//-------------------------------------------------------------------------

bool ApiTreeImpl::isAlive() const
{
    return m_aNotifier->m_aListeners.isAlive();
}
//-------------------------------------------------------------------------
void ApiTreeImpl::checkAlive() const
{
    m_aNotifier->m_aListeners.checkAlive( getUnoInstance() );
}
//-------------------------------------------------------------------------

osl::Mutex& ApiTreeImpl::getApiLock() const
{
    return m_aNotifier->mutex();
}
//-------------------------------------------------------------------------

Notifier ApiTreeImpl::getNotifier() const
{
    return Notifier(m_aNotifier,this);
}
//-------------------------------------------------------------------------

bool ApiRootTreeImpl::enableNotification(bool bEnable)
{
    IConfigBroadcaster* pSource = bEnable ? getApiTree().getProvider().getProviderImpl().getNotifier() : 0;
{'fraction_non_alphanumeric': 0.24519485099629695, 'fraction_numerical': 0.004761065067889261, 'mean_word_length': 2.1535681186283595, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 147, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1676140', 'n_tokens_mistral': 9271, 'n_tokens_neox': 9034, 'n_words': 2002}