/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef _DBA_CORE_DEFINITIONCONTAINER_HXX_
#include "definitioncontainer.hxx"
#endif
#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
#include "dbastrings.hrc"
#endif
#ifndef _DBASHARED_APITOOLS_HXX_
#include "apitools.hxx"
#endif
#ifndef _DBA_CORE_RESOURCE_HXX_
#include "core_resource.hxx"
#endif
#ifndef _DBA_CORE_RESOURCE_HRC_
#include "core_resource.hrc"
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef TOOLS_DIAGNOSE_EX_H
#include <tools/diagnose_ex.h>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _COMPHELPER_ENUMHELPER_HXX_
#include <comphelper/enumhelper.hxx>
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_COMMANDINFO_HPP_
#include <com/sun/star/ucb/CommandInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_ERRORCONDITION_HPP_
#include <com/sun/star/sdb/ErrorCondition.hpp>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX
#include <ucbhelper/contentidentifier.hxx>
#endif


using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdb;
using namespace ::osl;
using namespace ::comphelper;
using namespace ::cppu;
using namespace ::com::sun::star::ucb;

//........................................................................
namespace dbaccess
{
//........................................................................

//==========================================================================
//= ODefinitionContainer_Impl
//==========================================================================
//--------------------------------------------------------------------------
void ODefinitionContainer_Impl::erase( TContentPtr _pDefinition )
{
    NamedDefinitions::iterator aPos = find( _pDefinition );
	if ( aPos != end() )
		m_aDefinitions.erase( aPos );
}

//--------------------------------------------------------------------------
ODefinitionContainer_Impl::const_iterator ODefinitionContainer_Impl::find( TContentPtr _pDefinition ) const
{
	return ::std::find_if(
        m_aDefinitions.begin(),
        m_aDefinitions.end(),
        ::std::compose1(
			::std::bind2nd( ::std::equal_to< TContentPtr >(), _pDefinition ),
            ::std::select2nd< NamedDefinitions::value_type >()
        )
    );
}

//--------------------------------------------------------------------------
ODefinitionContainer_Impl::iterator ODefinitionContainer_Impl::find( TContentPtr _pDefinition )
{
	return ::std::find_if(
        m_aDefinitions.begin(),
        m_aDefinitions.end(),
        ::std::compose1(
			::std::bind2nd( ::std::equal_to< TContentPtr >(), _pDefinition ),
            ::std::select2nd< NamedDefinitions::value_type >()
        )
    );
}

//==========================================================================
//= ODefinitionContainer
//==========================================================================
DBG_NAME(ODefinitionContainer)
//--------------------------------------------------------------------------
ODefinitionContainer::ODefinitionContainer(   const Reference< XMultiServiceFactory >& _xORB
											, const Reference< XInterface >&	_xParentContainer
											, const TContentPtr& _pImpl
                                            , bool _bCheckSlash
											)
	:OContentHelper(_xORB,_xParentContainer,_pImpl)
    ,m_aApproveListeners(m_aMutex)
	,m_aContainerListeners(m_aMutex)
	,m_bInPropertyChange(sal_False)
    ,m_bCheckSlash(_bCheckSlash)
{
	m_pImpl->m_aProps.bIsDocument = sal_False;
	m_pImpl->m_aProps.bIsFolder = sal_True;

	const ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
	ODefinitionContainer_Impl::const_iterator aEnd = rDefinitions.end();
	for	(	ODefinitionContainer_Impl::const_iterator aDefinition = rDefinitions.begin();
			aDefinition != aEnd;
			++aDefinition
		)
		m_aDocuments.push_back(
            m_aDocumentMap.insert(
                Documents::value_type( aDefinition->first, Documents::mapped_type() ) ).first );

	DBG_CTOR(ODefinitionContainer, NULL);
}

//--------------------------------------------------------------------------
void SAL_CALL ODefinitionContainer::disposing()
{
	OContentHelper::disposing();

	MutexGuard aGuard(m_aMutex);

	// say our listeners goobye
	EventObject aEvt(*this);
	m_aApproveListeners.disposeAndClear(aEvt);
	m_aContainerListeners.disposeAndClear(aEvt);

	// dispose our elements
	Documents::iterator aIter = m_aDocumentMap.begin();
	Documents::iterator aEnd = m_aDocumentMap.end();

	for	(; aIter != aEnd; ++aIter)
	{
		Reference<XContent> xProp = aIter->second;
		if ( xProp.is() )
		{
			removeObjectListener(xProp);
			::comphelper::disposeComponent(xProp);
		}
	}

	// remove our elements
	m_aDocuments.clear();
	//  !!! do this before clearing the map which the vector elements refer to !!!
	m_aDocumentMap.clear();
}

//--------------------------------------------------------------------------
ODefinitionContainer::~ODefinitionContainer()
{
	DBG_DTOR(ODefinitionContainer, NULL);
}

IMPLEMENT_FORWARD_XINTERFACE2( ODefinitionContainer,OContentHelper,ODefinitionContainer_Base)
IMPLEMENT_TYPEPROVIDER2(ODefinitionContainer,OContentHelper,ODefinitionContainer_Base);
// XServiceInfo
//--------------------------------------------------------------------------
::rtl::OUString SAL_CALL ODefinitionContainer::getImplementationName(  ) throw(RuntimeException)
{
	return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.ODefinitionContainer"));
}
//--------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL ODefinitionContainer::getSupportedServiceNames(  ) throw(RuntimeException)
{
	Sequence< ::rtl::OUString > aReturn(2);
	aReturn.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.DefinitionContainer"));
	aReturn.getArray()[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.Content"));
	return aReturn;
}

// XNameContainer
//--------------------------------------------------------------------------
void SAL_CALL ODefinitionContainer::insertByName( const ::rtl::OUString& _rName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
{
	ResettableMutexGuard aGuard(m_aMutex);

	// approve the new object
	Reference< XContent > xNewElement(aElement,UNO_QUERY);
	approveNewObject( _rName, xNewElement );  // will throw if necessary

    notifyByName( aGuard, _rName, xNewElement, NULL, E_INSERTED, ApproveListeners );
	implAppend( _rName, xNewElement );
	notifyByName( aGuard, _rName, xNewElement, NULL, E_INSERTED, ContainerListemers );
}

//--------------------------------------------------------------------------
void SAL_CALL ODefinitionContainer::removeByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
	ResettableMutexGuard aGuard(m_aMutex);

    // check the arguments
	if (!_rName.getLength())
		throw IllegalArgumentException();

	if (!checkExistence(_rName))
		throw NoSuchElementException(_rName,*this);

	// the old element (for the notifications)
	Reference< XContent > xOldElement = implGetByName( _rName, impl_haveAnyListeners_nothrow() );

	// do the removal
    notifyByName( aGuard, _rName, NULL, xOldElement, E_REMOVED, ApproveListeners );
	implRemove( _rName );
    notifyByName( aGuard, _rName, NULL, xOldElement, E_REMOVED, ContainerListemers );

	removeObjectListener( xOldElement );
    disposeComponent(xOldElement);
}

// XNameReplace
//--------------------------------------------------------------------------
void SAL_CALL ODefinitionContainer::replaceByName( const ::rtl::OUString& _rName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
{
	ResettableMutexGuard aGuard(m_aMutex);

	// let derived classes approve the new object
	Reference< XContent > xNewElement(aElement,UNO_QUERY);
	approveNewObject( _rName, xNewElement );    // will throw if necessary

	// the old element (for the notifications)
	Reference< XContent > xOldElement = implGetByName( _rName, impl_haveAnyListeners_nothrow() );

	notifyByName( aGuard, _rName, xNewElement, xOldElement, E_REPLACED, ApproveListeners );
    implReplace( _rName, xNewElement );
	notifyByName( aGuard, _rName, xNewElement, xOldElement, E_REPLACED, ContainerListemers );

	// and dispose it
    disposeComponent(xOldElement);
}

// -----------------------------------------------------------------------------
namespace
{
    typedef Reference< XVeto > ( SAL_CALL XContainerApproveListener::*ContainerApprovalMethod )( const ContainerEvent& );

    struct RaiseExceptionFromVeto
    {
    private:
        ContainerApprovalMethod m_pMethod;
        const ContainerEvent&   m_rEvent;

    public:
        RaiseExceptionFromVeto( ContainerApprovalMethod _pMethod, const ContainerEvent& _rEvent )
            :m_pMethod( _pMethod )
            ,m_rEvent( _rEvent )
        {
        }

        void operator()( const Reference< XContainerApproveListener >& _Listener ) const
        {
            Reference< XVeto > xVeto = (_Listener.get()->*m_pMethod)( m_rEvent );
            if ( !xVeto.is() )
                return;

            Any eVetoDetails = xVeto->getDetails();

            IllegalArgumentException aIllegalArgumentError;
            if ( eVetoDetails >>= aIllegalArgumentError )
                throw aIllegalArgumentError;

            WrappedTargetException aWrappedError;
            if ( eVetoDetails >>= aWrappedError )
                throw aWrappedError;

            throw WrappedTargetException( xVeto->getReason(), _Listener.get(), eVetoDetails );
        }
    };
}

// -----------------------------------------------------------------------------
void ODefinitionContainer::notifyByName( ResettableMutexGuard& _rGuard, const ::rtl::OUString& _rName,
        const Reference< XContent >& _xNewElement, const Reference< XContent >& _xOldElement,
        ContainerOperation _eOperation, ListenerType _eType )
{
    bool bApprove = ( _eType == ApproveListeners );

    ::cppu::OInterfaceContainerHelper& rContainer( bApprove ? m_aApproveListeners : m_aContainerListeners );
	if ( !rContainer.getLength() )
        return;

    ContainerEvent aEvent( *this, makeAny( _rName ), makeAny( _xNewElement ), makeAny( _xOldElement ) );

    _rGuard.clear();
	switch ( _eOperation )
	{
		case E_INSERTED:
            if ( bApprove )
                rContainer.forEach< XContainerApproveListener, RaiseExceptionFromVeto >(
                    RaiseExceptionFromVeto( &XContainerApproveListener::approveInsertElement, aEvent ) );
            else
                rContainer.notifyEach( &XContainerListener::elementInserted, aEvent );
			break;
		case E_REPLACED:
            if ( bApprove )
                rContainer.forEach< XContainerApproveListener, RaiseExceptionFromVeto >(
                    RaiseExceptionFromVeto( &XContainerApproveListener::approveReplaceElement, aEvent ) );
            else
                rContainer.notifyEach( &XContainerListener::elementReplaced, aEvent );
			break;
		case E_REMOVED:
            if ( bApprove )
                rContainer.forEach< XContainerApproveListener, RaiseExceptionFromVeto >(
                    RaiseExceptionFromVeto( &XContainerApproveListener::approveRemoveElement, aEvent ) );
            else
                rContainer.notifyEach( &XContainerListener::elementRemoved, aEvent );
			break;
	}

    if ( bApprove )
        _rGuard.reset();
}

//--------------------------------------------------------------------------
void SAL_CALL ODefinitionContainer::addContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
{
	if (_rxListener.is())
		m_aContainerListeners.addInterface(_rxListener);
}

//--------------------------------------------------------------------------
void SAL_CALL ODefinitionContainer::removeContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
{
	if (_rxListener.is())
		m_aContainerListeners.removeInterface(_rxListener);
}

//--------------------------------------------------------------------------
void SAL_CALL ODefinitionContainer::addContainerApproveListener( const Reference< XContainerApproveListener >& _Listener ) throw (RuntimeException)
{
    if ( _Listener.is() )
        m_aApproveListeners.addInterface( _Listener );
}

//--------------------------------------------------------------------------
void SAL_CALL ODefinitionContainer::removeContainerApproveListener( const Reference< XContainerApproveListener >& _Listener ) throw (RuntimeException)
{
    if ( _Listener.is() )
        m_aApproveListeners.removeInterface( _Listener );
}


// XElementAccess
//--------------------------------------------------------------------------
Type SAL_CALL ODefinitionContainer::getElementType( ) throw (RuntimeException)
{
	return ::getCppuType( static_cast< Reference< XContent >* >(NULL) );
}

//--------------------------------------------------------------------------
sal_Bool SAL_CALL ODefinitionContainer::hasElements( ) throw (RuntimeException)
{
	MutexGuard aGuard(m_aMutex);
	return !m_aDocuments.empty();
}

// XEnumerationAccess
//--------------------------------------------------------------------------
Reference< XEnumeration > SAL_CALL ODefinitionContainer::createEnumeration(  ) throw(RuntimeException)
{
	MutexGuard aGuard(m_aMutex);
	return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
}

//--------------------------------------------------------------------------
// XIndexAccess
sal_Int32 SAL_CALL ODefinitionContainer::getCount(  ) throw(RuntimeException)
{
	MutexGuard aGuard(m_aMutex);
	return m_aDocuments.size();
}

//--------------------------------------------------------------------------
Any SAL_CALL ODefinitionContainer::getByIndex( sal_Int32 _nIndex ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
{
	MutexGuard aGuard(m_aMutex);

	if ((_nIndex < 0) || (_nIndex >= (sal_Int32)m_aDocuments.size()))
		throw IndexOutOfBoundsException();

	Documents::iterator aPos = m_aDocuments[_nIndex];
	Reference<XContent> xProp = aPos->second;
	if (!xProp.is())
	{	// that's the first access to the object
		// -> create it
		xProp = createObject(aPos->first);
		aPos->second = Documents::mapped_type();
		// and update the name-access map
	}

	return makeAny(xProp);
}

//--------------------------------------------------------------------------
Any SAL_CALL ODefinitionContainer::getByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
	MutexGuard aGuard(m_aMutex);

	return makeAny( implGetByName( _rName, sal_True ) );
}

//--------------------------------------------------------------------------
Reference< XContent > ODefinitionContainer::implGetByName(const ::rtl::OUString& _rName, sal_Bool _bReadIfNeccessary) throw (NoSuchElementException)
{
	Documents::iterator aMapPos = m_aDocumentMap.find(_rName);
	if (aMapPos == m_aDocumentMap.end())
		throw NoSuchElementException(_rName,*this);

	Reference< XContent > xProp = aMapPos->second;

	if (_bReadIfNeccessary && !xProp.is())
	{	// the object has never been accessed before, so we have to read it now
		// (that's the expensive part)

		// create the object and insert it into the map
		xProp = createObject(_rName);
		aMapPos->second = xProp;
		addObjectListener(xProp);
	}

	return xProp;
}

//--------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL ODefinitionContainer::getElementNames(  ) throw(RuntimeException)
{
	MutexGuard aGuard(m_aMutex);

	Sequence< ::rtl::OUString > aNames(m_aDocumentMap.size());
	::rtl::OUString* pNames = aNames.getArray();
	Documents::iterator aEnd = m_aDocumentMap.end();
	for	(	Documents::iterator aNameIter = m_aDocumentMap.begin();
			aNameIter != aEnd;
			++pNames, ++aNameIter
		)
	{
		*pNames = aNameIter->first;
	}

	return aNames;
}

//--------------------------------------------------------------------------
sal_Bool SAL_CALL ODefinitionContainer::hasByName( const ::rtl::OUString& _rName ) throw(RuntimeException)
{
	MutexGuard aGuard(m_aMutex);

	return checkExistence(_rName);
}

//--------------------------------------------------------------------------
void SAL_CALL ODefinitionContainer::disposing( const EventObject& _rSource ) throw(RuntimeException)
{
	MutexGuard aGuard(m_aMutex);
	Reference< XContent > xSource(_rSource.Source, UNO_QUERY);
	// it's one of our documents ....
	Documents::iterator aIter = m_aDocumentMap.begin();
	Documents::iterator aEnd = m_aDocumentMap.end();
	for	(;aIter != aEnd;++aIter )
	{
		if ( xSource == aIter->second.get() )
		{
			removeObjectListener(xSource);
			// and clear our document map/vector, so the object will be recreated on next access
			aIter->second = Documents::mapped_type();
		}
	}
}

//--------------------------------------------------------------------------
void ODefinitionContainer::implRemove(const ::rtl::OUString& _rName)
{
	// from the object maps
	Documents::iterator aFind = m_aDocumentMap.find(_rName);
	if ( aFind != m_aDocumentMap.end() )
	{
		m_aDocuments.erase( ::std::find(m_aDocuments.begin(),m_aDocuments.end(),aFind));
		m_aDocumentMap.erase(aFind);

	    getDefinitions().erase( _rName );

		notifyDataSourceModified();
	}
}

//--------------------------------------------------------------------------
namespace
{
    bool    lcl_ensureName( const Reference< XContent >& _rxContent, const ::rtl::OUString& _rName )
    {
        if ( !_rxContent.is() )
            return true;

        // ..........................................................
        // obtain the current name. If it's the same as the new one,
        // don't do anything
        try
        {
            Reference< XPropertySet > xProps( _rxContent, UNO_QUERY );
            if ( xProps.is() )
            {
                ::rtl::OUString sCurrentName;
                OSL_VERIFY( xProps->getPropertyValue( PROPERTY_NAME ) >>= sCurrentName );
                if ( sCurrentName.equals( _rName ) )
                    return true;
            }
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "lcl_ensureName: caught an exception while obtaining the current name!" );
        }

        // ..........................................................
        // set the new name
        Reference< XRename > xRename( _rxContent, UNO_QUERY );
        OSL_ENSURE( xRename.is(), "lcl_ensureName: invalid content (not renameable)!" );
        if ( !xRename.is() )
            return false;
        try
        {
            xRename->rename( _rName );
            return true;
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "lcl_ensureName: caught an exception!" );
        }
        return false;
    }
}
//--------------------------------------------------------------------------
void ODefinitionContainer::implAppend(const ::rtl::OUString& _rName, const Reference< XContent >& _rxNewObject)
{
	MutexGuard aGuard(m_aMutex);
	try
	{
		Reference<XChild> xChild(_rxNewObject,UNO_QUERY);
		if ( xChild.is() )
			xChild->setParent(static_cast<OWeakObject*>(this));

	    ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
		ODefinitionContainer_Impl::const_iterator aFind = rDefinitions.find( _rName );
		if ( aFind == rDefinitions.end() )
		{
            // ensure that the new object thas the proper name.
            // Somebody could create an object with name "foo", and insert it as "bar"
            // into a container. In this case, we need to ensure that the object name
            // is also "bar"
            // #i44786# / 2005-03-11 / frank.schoenheit@sun.com
            lcl_ensureName( _rxNewObject, _rName );

			::rtl::Reference< OContentHelper > pContent = OContentHelper::getImplementation( _rxNewObject );
			if ( pContent.is() )
			{
				TContentPtr pImpl = pContent->getImpl();
                rDefinitions.erase( pImpl );
				pImpl->m_aProps.aTitle = _rName;
				rDefinitions.insert( _rName, pImpl );
			}
		}


		m_aDocuments.push_back(m_aDocumentMap.insert(Documents::value_type(_rName,_rxNewObject)).first);
		notifyDataSourceModified();
		// now update our structures
		if ( _rxNewObject.is() )
			addObjectListener(_rxNewObject);
	}
	catch(Exception&)
	{
		DBG_ERROR("ODefinitionContainer::implAppend: caught something !");
	}
}

//--------------------------------------------------------------------------
void ODefinitionContainer::implReplace(const ::rtl::OUString& _rName, const Reference< XContent >& _rxNewObject)
{
	DBG_ASSERT(checkExistence(_rName), "ODefinitionContainer::implReplace : invalid name !");

	Documents::iterator aFind = m_aDocumentMap.find(_rName);
	removeObjectListener(aFind->second);
	aFind->second = _rxNewObject;
	addObjectListener(aFind->second);
}

// -----------------------------------------------------------------------------
void ODefinitionContainer::approveNewObject(const ::rtl::OUString& _sName,const Reference< XContent >& _rxObject) const
{
	// check the arguments
	if ( !_sName.getLength() )
        throw IllegalArgumentException(
            DBA_RES( RID_STR_NAME_MUST_NOT_BE_EMPTY ),
            *this,
            0 );

    if ( m_bCheckSlash && _sName.indexOf( '/' ) != -1 )
        throw IllegalArgumentException(
            m_aErrorHelper.getErrorMessage( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES ),
            *this,
            0 );

	if ( !_rxObject.is() )
        throw IllegalArgumentException(
            DBA_RES( RID_STR_NO_NULL_OBJECTS_IN_CONTAINER ),
            *this,
            0 );

	const ODefinitionContainer_Impl& rDefinitions( getDefinitions() );
    if ( rDefinitions.find( _sName ) != rDefinitions.end() )
        throw ElementExistException(
            DBA_RES( RID_STR_NAME_ALREADY_USED ),
            *this );

    ::rtl::Reference< OContentHelper > pContent( OContentHelper::getImplementation( _rxObject ) );
    if ( !pContent.is() )
        throw IllegalArgumentException(
            DBA_RES( RID_STR_OBJECT_CONTAINER_MISMATCH ),
            *this,
            1 );

    if ( rDefinitions.find( pContent->getImpl() ) != rDefinitions.end() )
        throw ElementExistException(
            DBA_RES( RID_STR_OBJECT_ALREADY_CONTAINED ),
            *this );
}

// -----------------------------------------------------------------------------
// XPropertyChangeListener
void SAL_CALL ODefinitionContainer::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException)
{
	ClearableMutexGuard aGuard(m_aMutex);
    if(evt.PropertyName == (rtl::OUString) PROPERTY_NAME || evt.PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ))
	{
		m_bInPropertyChange = sal_True;
		try
		{
			::rtl::OUString sNewName,sOldName;
			evt.OldValue >>= sOldName;
			evt.NewValue >>= sNewName;
			Reference<XContent> xContent( evt.Source, UNO_QUERY );
			removeObjectListener( xContent );
            implRemove( sOldName );
			implAppend( sNewName, xContent );
		}
		catch(const Exception&)
		{
            DBG_UNHANDLED_EXCEPTION();
			throw RuntimeException();
		}
		m_bInPropertyChange = sal_False;
	}
}
// -----------------------------------------------------------------------------
// XVetoableChangeListener
void SAL_CALL ODefinitionContainer::vetoableChange( const PropertyChangeEvent& aEvent ) throw (PropertyVetoException, RuntimeException)
{
	MutexGuard aGuard(m_aMutex);

    if(aEvent.PropertyName == (rtl::OUString) PROPERTY_NAME || aEvent.PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
	{
		::rtl::OUString sNewName;
		aEvent.NewValue >>= sNewName;
		if(hasByName(sNewName))
			throw PropertyVetoException();
	}
}
// -----------------------------------------------------------------------------
void ODefinitionContainer::addObjectListener(const Reference< XContent >& _xNewObject)
{
	OSL_ENSURE(_xNewObject.is(),"ODefinitionContainer::addObjectListener: Object is null!");
	Reference<XPropertySet> xProp(_xNewObject,UNO_QUERY);
	if ( xProp.is() )
	{
		xProp->addPropertyChangeListener(PROPERTY_NAME, this);
		xProp->addVetoableChangeListener(PROPERTY_NAME, this);
	}
}
// -----------------------------------------------------------------------------
void ODefinitionContainer::removeObjectListener(const Reference< XContent >& _xNewObject)
{
	Reference<XPropertySet> xProp(_xNewObject,UNO_QUERY);
	if ( xProp.is() )
	{
		xProp->removePropertyChangeListener(PROPERTY_NAME, this);
		xProp->removeVetoableChangeListener(PROPERTY_NAME, this);
	}
}
// -----------------------------------------------------------------------------
sal_Bool ODefinitionContainer::checkExistence(const ::rtl::OUString& _rName)
{
	return m_aDocumentMap.find(_rName) != m_aDocumentMap.end();
}

//........................................................................
}
// namespace dbaccess
//........................................................................
