/**************************************************************
 * 
 * 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_connectivity.hxx"

#include <algorithm>
#include <stdio.h>
#include "connectivity/sdbcx/VCollection.hxx"
#include "connectivity/sdbcx/VDescriptor.hxx"
#include "connectivity/dbexception.hxx"
#include <comphelper/enumhelper.hxx>
#include <comphelper/container.hxx>
#include <comphelper/types.hxx>
#include <comphelper/property.hxx>
#include "TConnection.hxx"
#include <rtl/ustrbuf.hxx>
#include "resource/common_res.hrc"
#include "resource/sharedresources.hxx"

using namespace connectivity::sdbcx;
using namespace connectivity;
using namespace comphelper;
using namespace ::cppu;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::util;

namespace
{
	template < typename T> class OHardRefMap : public connectivity::sdbcx::IObjectCollection
	{
		typedef ::std::multimap< ::rtl::OUString, T , ::comphelper::UStringMixLess> ObjectMap;
		typedef typename ObjectMap::iterator   ObjectIter;
		typedef typename ObjectMap::value_type ObjectEntry;

	//	private:
		// this combination of map and vector is used to have a fast name and index access
		::std::vector< ObjectIter >				m_aElements;		// hold the iterators which point to map
		ObjectMap								m_aNameMap;			// hold the elements and a name
	public:
		OHardRefMap(sal_Bool _bCase) 
			: m_aNameMap(_bCase ? true : false)
		{
		}
        virtual ~OHardRefMap()
        {
        }

		virtual void reserve(size_t nLength)
		{
			m_aElements.reserve(nLength);
		}
		// -----------------------------------------------------------------------------
		virtual bool exists(const ::rtl::OUString& _sName )
		{
			return m_aNameMap.find(_sName) != m_aNameMap.end();
		}
		// -----------------------------------------------------------------------------
		virtual bool empty()
		{
			return m_aNameMap.empty();
		}
		// -----------------------------------------------------------------------------
		virtual void swapAll()
		{
			::std::vector< ObjectIter >(m_aElements).swap(m_aElements);
			ObjectMap(m_aNameMap).swap(m_aNameMap);
		}
		// -----------------------------------------------------------------------------
		virtual void swap()
		{
			::std::vector< ObjectIter >().swap(m_aElements);

			OSL_ENSURE( m_aNameMap.empty(), "swap: what did disposeElements do?" );
			ObjectMap( m_aNameMap ).swap( m_aNameMap );
				// Note that it's /important/ to construct the new ObjectMap from m_aNameMap before
				// swapping. This way, it's ensured that the compare object held by these maps is preserved
				// during the swap. If we would not do this, the UStringMixLess instance which is used would be
				// default constructed (instead of being constructed from the same instance in m_aNameMap), and
				// it's case-sensitive flag would have an unpredictable value.
				// 2002-01-09 - #106589# - fs@openoffice.org
		}
		// -----------------------------------------------------------------------------
		virtual void clear()
		{
			m_aElements.clear();
			m_aNameMap.clear();
		}
		// -----------------------------------------------------------------------------
		virtual void insert(const ::rtl::OUString& _sName,const ObjectType& _xObject)
		{
			m_aElements.push_back(m_aNameMap.insert(m_aNameMap.begin(), ObjectEntry(_sName,_xObject)));
		}
		// -----------------------------------------------------------------------------
		virtual void reFill(const TStringVector &_rVector)
		{
			OSL_ENSURE(!m_aNameMap.size(),"OCollection::reFill: collection isn't empty");
			m_aElements.reserve(_rVector.size());
			
			for(TStringVector::const_iterator i=_rVector.begin(); i != _rVector.end();++i)
				m_aElements.push_back(m_aNameMap.insert(m_aNameMap.begin(), ObjectEntry(*i,ObjectType())));
		}
		// -----------------------------------------------------------------------------
		virtual bool rename(const ::rtl::OUString _sOldName,const ::rtl::OUString _sNewName)
		{
			bool bRet = false;
			ObjectIter aIter = m_aNameMap.find(_sOldName);
			if ( aIter != m_aNameMap.end() )
			{
				typename ::std::vector< ObjectIter >::iterator aFind = ::std::find(m_aElements.begin(),m_aElements.end(),aIter);
				if(m_aElements.end() != aFind)
				{
					(*aFind) = m_aNameMap.insert(m_aNameMap.begin(), ObjectEntry(_sNewName,(*aFind)->second));
					m_aNameMap.erase(aIter);

					bRet = true;
				}
			}
			return bRet;
		}
		// -----------------------------------------------------------------------------
		virtual sal_Int32 size()
		{
			return static_cast<sal_Int32>(m_aNameMap.size());
		}
		// -----------------------------------------------------------------------------
		virtual Sequence< ::rtl::OUString > getElementNames()
		{
			Sequence< ::rtl::OUString > aNameList(m_aElements.size());

			::rtl::OUString* pStringArray = aNameList.getArray();
            typename ::std::vector< ObjectIter >::const_iterator aEnd = m_aElements.end();
			for(typename ::std::vector< ObjectIter >::const_iterator aIter = m_aElements.begin(); aIter != aEnd;++aIter,++pStringArray)
				*pStringArray = (*aIter)->first;

			return aNameList;
		}
		// -----------------------------------------------------------------------------
		virtual ::rtl::OUString getName(sal_Int32 _nIndex)
		{
			return m_aElements[_nIndex]->first;
		}
		// -----------------------------------------------------------------------------
		virtual void disposeAndErase(sal_Int32 _nIndex)
		{
			OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
			Reference<XComponent> xComp(m_aElements[_nIndex]->second.get(),UNO_QUERY);
			::comphelper::disposeComponent(xComp);
			m_aElements[_nIndex]->second = T();
	
			::rtl::OUString sName = m_aElements[_nIndex]->first;
			m_aElements.erase(m_aElements.begin()+_nIndex);
			m_aNameMap.erase(sName);	
		}
		// -----------------------------------------------------------------------------
		virtual void disposeElements()
		{
			for( ObjectIter aIter = m_aNameMap.begin(); aIter != m_aNameMap.end(); ++aIter)
			{
				Reference<XComponent> xComp(aIter->second.get(),UNO_QUERY);
				if ( xComp.is() )
				{
					::comphelper::disposeComponent(xComp);
					(*aIter).second = T();
				}
			}
			m_aElements.clear();
			m_aNameMap.clear();			
		}
		// -----------------------------------------------------------------------------
		virtual sal_Int32 findColumn( const ::rtl::OUString& columnName )
		{
			ObjectIter aIter = m_aNameMap.find(columnName);
			OSL_ENSURE(aIter != m_aNameMap.end(),"findColumn:: Illegal name!");
			return m_aElements.size() - (m_aElements.end() - ::std::find(m_aElements.begin(),m_aElements.end(),aIter));
		}
		// -----------------------------------------------------------------------------
		virtual ::rtl::OUString findColumnAtIndex(  sal_Int32 _nIndex)
		{
			OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
			return m_aElements[_nIndex]->first;
		}
		// -----------------------------------------------------------------------------
		virtual ObjectType getObject(sal_Int32 _nIndex)
		{
			OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
			return m_aElements[_nIndex]->second;
		}
		// -----------------------------------------------------------------------------
		virtual ObjectType getObject(const ::rtl::OUString& columnName)
		{
			return m_aNameMap.find(columnName)->second;
		}
		// -----------------------------------------------------------------------------
		virtual void setObject(sal_Int32 _nIndex,const ObjectType& _xObject)
		{
			OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
			m_aElements[_nIndex]->second = _xObject;
		}
		// -----------------------------------------------------------------------------
		sal_Bool isCaseSensitive() const 
		{ 
			return m_aNameMap.key_comp().isCaseSensitive(); 
		}
		// -----------------------------------------------------------------------------
	};
}
// -----------------------------------------------------------------------------

IMPLEMENT_SERVICE_INFO(OCollection,"com.sun.star.sdbcx.VContainer" , "com.sun.star.sdbcx.Container")

OCollection::OCollection(::cppu::OWeakObject& _rParent
						 , sal_Bool _bCase
						 , ::osl::Mutex& _rMutex
						 , const TStringVector &_rVector
						 , sal_Bool _bUseIndexOnly
						 , sal_Bool _bUseHardRef)
                     :m_aContainerListeners(_rMutex)
					 ,m_aRefreshListeners(_rMutex)
					 ,m_rParent(_rParent)
					 ,m_rMutex(_rMutex)
					 ,m_bUseIndexOnly(_bUseIndexOnly)
{
	if ( _bUseHardRef )
	{
		m_pElements.reset(new OHardRefMap< ObjectType >(_bCase));
	}
	else
	{
		m_pElements.reset(new OHardRefMap< WeakReference< XPropertySet> >(_bCase));
	}
	m_pElements->reFill(_rVector);
}
// -------------------------------------------------------------------------
OCollection::~OCollection()
{
}
// -----------------------------------------------------------------------------
Any SAL_CALL OCollection::queryInterface( const Type & rType ) throw (RuntimeException)
{
	if ( m_bUseIndexOnly && rType == ::getCppuType(static_cast< Reference< XNameAccess > *> (NULL)) )
	{
		return Any();
	}
	return OCollectionBase::queryInterface( rType );
}
// -----------------------------------------------------------------------------
Sequence< Type > SAL_CALL OCollection::getTypes() throw (RuntimeException)
{
	if ( m_bUseIndexOnly )
	{
		Sequence< Type > aTypes(OCollectionBase::getTypes());
		Type* pBegin	= aTypes.getArray();
		Type* pEnd		= pBegin + aTypes.getLength();

		::std::vector<Type> aOwnTypes;
		aOwnTypes.reserve(aTypes.getLength());
		Type aType = ::getCppuType(static_cast< Reference<XNameAccess> *>(NULL));
		for(;pBegin != pEnd; ++pBegin)
		{
			if ( *pBegin != aType )
				aOwnTypes.push_back(*pBegin);
		}
		Type* pTypes = aOwnTypes.empty() ? 0 : &aOwnTypes[0];
		return Sequence< Type >(pTypes,aOwnTypes.size());
	}
	return OCollectionBase::getTypes( );
}
// -------------------------------------------------------------------------
void OCollection::clear_NoDispose()
{
	::osl::MutexGuard aGuard(m_rMutex);

	m_pElements->clear();
	m_pElements->swapAll();
}

// -------------------------------------------------------------------------
void OCollection::disposing(void)
{
	m_aContainerListeners.disposeAndClear(EventObject(static_cast<XTypeProvider*>(this)));
	m_aRefreshListeners.disposeAndClear(EventObject(static_cast<XTypeProvider*>(this)));

	::osl::MutexGuard aGuard(m_rMutex);
	
	disposeElements();

	m_pElements->swap();
}
// -------------------------------------------------------------------------
Any SAL_CALL OCollection::getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
{
	::osl::MutexGuard aGuard(m_rMutex);
	if (Index < 0 || Index >= m_pElements->size() )
		throw IndexOutOfBoundsException(::rtl::OUString::valueOf(Index),static_cast<XTypeProvider*>(this));

	return makeAny(getObject(Index));
}
// -------------------------------------------------------------------------
Any SAL_CALL OCollection::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
	::osl::MutexGuard aGuard(m_rMutex);

	if ( !m_pElements->exists(aName) )
    {
        ::connectivity::SharedResources aResources;
        const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(
                STR_NO_ELEMENT_NAME,
                "$name$", aName
             ) );
		throw NoSuchElementException( sError, static_cast< XTypeProvider* >( this ) );
    }

	return makeAny(getObject(m_pElements->findColumn(aName)));
}
// -------------------------------------------------------------------------
Sequence< ::rtl::OUString > SAL_CALL OCollection::getElementNames(  ) throw(RuntimeException)
{
	::osl::MutexGuard aGuard(m_rMutex);
	return m_pElements->getElementNames();
}
// -------------------------------------------------------------------------
void SAL_CALL OCollection::refresh(  ) throw(RuntimeException)
{
	::osl::MutexGuard aGuard(m_rMutex);
	
	disposeElements();	

	impl_refresh();
	EventObject aEvt(static_cast<XTypeProvider*>(this));
    m_aRefreshListeners.notifyEach( &XRefreshListener::refreshed, aEvt );
}
// -----------------------------------------------------------------------------
void OCollection::reFill(const TStringVector &_rVector)
{
	m_pElements->reFill(_rVector);
}
// -------------------------------------------------------------------------
// XDataDescriptorFactory
Reference< XPropertySet > SAL_CALL OCollection::createDataDescriptor(  ) throw(RuntimeException)
{
	::osl::MutexGuard aGuard(m_rMutex);

	return createDescriptor();
}
// -----------------------------------------------------------------------------
::rtl::OUString OCollection::getNameForObject(const ObjectType& _xObject)
{
    OSL_ENSURE(_xObject.is(),"OCollection::getNameForObject: Object is NULL!");
    ::rtl::OUString sName;
    _xObject->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= sName;
    return sName;
}
// -------------------------------------------------------------------------
// XAppend
void SAL_CALL OCollection::appendByDescriptor( const Reference< XPropertySet >& descriptor ) throw(SQLException, ElementExistException, RuntimeException)
{
	::osl::ClearableMutexGuard aGuard(m_rMutex);

    ::rtl::OUString sName = getNameForObject( descriptor );

	if ( m_pElements->exists(sName) )
		throw ElementExistException(sName,static_cast<XTypeProvider*>(this));

    ObjectType xNewlyCreated = appendObject( sName, descriptor );
	if ( !xNewlyCreated.is() )
        throw RuntimeException();

    ODescriptor* pDescriptor = ODescriptor::getImplementation( xNewlyCreated );
	if ( pDescriptor )
		pDescriptor->setNew( sal_False );

    sName = getNameForObject( xNewlyCreated );
	if ( !m_pElements->exists( sName ) ) // this may happen when the drived class included it itself
		m_pElements->insert( sName, xNewlyCreated );

    // notify our container listeners
	ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(sName), makeAny(xNewlyCreated), Any());
    aGuard.clear();
    m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
}
// -------------------------------------------------------------------------
// XDrop
void SAL_CALL OCollection::dropByName( const ::rtl::OUString& elementName ) throw(SQLException, NoSuchElementException, RuntimeException)
{
	::osl::MutexGuard aGuard(m_rMutex);

	if ( !m_pElements->exists(elementName) )
		throw NoSuchElementException(elementName,static_cast<XTypeProvider*>(this));

	dropImpl(m_pElements->findColumn(elementName));
}
// -------------------------------------------------------------------------
void SAL_CALL OCollection::dropByIndex( sal_Int32 index ) throw(SQLException, IndexOutOfBoundsException, RuntimeException)
{
	::osl::MutexGuard aGuard(m_rMutex);
	if(index <0 || index >= getCount())
		throw IndexOutOfBoundsException(::rtl::OUString::valueOf(index),static_cast<XTypeProvider*>(this));

	dropImpl(index);
}
// -----------------------------------------------------------------------------
void OCollection::dropImpl(sal_Int32 _nIndex,sal_Bool _bReallyDrop)
{
	::rtl::OUString elementName = m_pElements->getName(_nIndex);

	if ( _bReallyDrop )
		dropObject(_nIndex,elementName);

	m_pElements->disposeAndErase(_nIndex);

	// notify our container listeners
	notifyElementRemoved(elementName);
}
// -----------------------------------------------------------------------------
void OCollection::notifyElementRemoved(const ::rtl::OUString& _sName)
{
	ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(_sName), Any(), Any());
	// note that xExistent may be empty, in case somebody removed the data source while it is not alive at this moment
	OInterfaceIteratorHelper aListenerLoop(m_aContainerListeners);
	while (aListenerLoop.hasMoreElements())
		static_cast<XContainerListener*>(aListenerLoop.next())->elementRemoved(aEvent);
}
// -------------------------------------------------------------------------
sal_Int32 SAL_CALL OCollection::findColumn( const ::rtl::OUString& columnName ) throw(SQLException, RuntimeException)
{
	if ( !m_pElements->exists(columnName) )
    {
        ::connectivity::SharedResources aResources;
        const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(
                            STR_UNKNOWN_COLUMN_NAME,
                            "$columnname$", columnName
                         ) );
		::dbtools::throwGenericSQLException(sError,static_cast< XIndexAccess*>(this));
    }

	return m_pElements->findColumn(columnName) + 1; // because columns start at one
}
// -------------------------------------------------------------------------
Reference< XEnumeration > SAL_CALL OCollection::createEnumeration(  ) throw(RuntimeException)
{
	::osl::MutexGuard aGuard(m_rMutex);
    return new OEnumerationByIndex( static_cast< XIndexAccess*>(this));
}
// -----------------------------------------------------------------------------
void SAL_CALL OCollection::addContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
{
	m_aContainerListeners.addInterface(_rxListener);
}

//------------------------------------------------------------------------------
void SAL_CALL OCollection::removeContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
{
	m_aContainerListeners.removeInterface(_rxListener);
}
// -----------------------------------------------------------------------------
void SAL_CALL OCollection::acquire() throw()
{
	m_rParent.acquire();
}
// -----------------------------------------------------------------------------
void SAL_CALL OCollection::release() throw()
{
	m_rParent.release();
}
// -----------------------------------------------------------------------------
Type SAL_CALL OCollection::getElementType(  ) throw(RuntimeException)
{
	return::getCppuType(static_cast< Reference< XPropertySet>*>(NULL));
}
// -----------------------------------------------------------------------------
sal_Bool SAL_CALL OCollection::hasElements(  ) throw(RuntimeException)
{
	::osl::MutexGuard aGuard(m_rMutex);
	return !m_pElements->empty();
}
// -----------------------------------------------------------------------------
sal_Int32 SAL_CALL OCollection::getCount(  ) throw(RuntimeException)
{
	::osl::MutexGuard aGuard(m_rMutex);
	return m_pElements->size();
}
// -----------------------------------------------------------------------------
sal_Bool SAL_CALL OCollection::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException)
{
	::osl::MutexGuard aGuard(m_rMutex);
	return m_pElements->exists(aName);
}
// -----------------------------------------------------------------------------
void SAL_CALL OCollection::addRefreshListener( const Reference< XRefreshListener >& l ) throw(RuntimeException)
{
	m_aRefreshListeners.addInterface(l);
}
// -----------------------------------------------------------------------------
void SAL_CALL OCollection::removeRefreshListener( const Reference< XRefreshListener >& l ) throw(RuntimeException)
{
	m_aRefreshListeners.removeInterface(l);
}
// -----------------------------------------------------------------------------
void OCollection::insertElement(const ::rtl::OUString& _sElementName,const ObjectType& _xElement)
{
	OSL_ENSURE(!m_pElements->exists(_sElementName),"Element already exists");
	if ( !m_pElements->exists(_sElementName) ) 
		m_pElements->insert(_sElementName,_xElement);
}
// -----------------------------------------------------------------------------
void OCollection::renameObject(const ::rtl::OUString _sOldName,const ::rtl::OUString _sNewName)
{
	OSL_ENSURE(m_pElements->exists(_sOldName),"Element doesn't exist");
	OSL_ENSURE(!m_pElements->exists(_sNewName),"Element already exists");
	OSL_ENSURE(_sNewName.getLength(),"New name must not be empty!");
	OSL_ENSURE(_sOldName.getLength(),"New name must not be empty!");

	if ( m_pElements->rename(_sOldName,_sNewName) )
	{
		ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(_sNewName), makeAny(m_pElements->getObject(_sNewName)),makeAny(_sOldName));
		// note that xExistent may be empty, in case somebody removed the data source while it is not alive at this moment
		OInterfaceIteratorHelper aListenerLoop(m_aContainerListeners);
		while (aListenerLoop.hasMoreElements())
			static_cast<XContainerListener*>(aListenerLoop.next())->elementReplaced(aEvent);
	}
}
// -----------------------------------------------------------------------------
ObjectType OCollection::getObject(sal_Int32 _nIndex)
{
	ObjectType xName = m_pElements->getObject(_nIndex);
	if ( !xName.is() )
	{
		try
		{
			xName = createObject(m_pElements->getName(_nIndex));
		}
		catch(const SQLException& e)
		{
			try
			{
				dropImpl(_nIndex,sal_False);
			}
			catch(const Exception& )
			{
			}
			throw WrappedTargetException(e.Message,static_cast<XTypeProvider*>(this),makeAny(e));
		}
		m_pElements->setObject(_nIndex,xName);
	}
	return xName;
}
// -----------------------------------------------------------------------------
void OCollection::disposeElements()
{
	m_pElements->disposeElements();
}
// -----------------------------------------------------------------------------
Reference< XPropertySet > OCollection::createDescriptor()
{
	OSL_ASSERT(!"Need to be overloaded when used!");
	throw SQLException();
}
// -----------------------------------------------------------------------------
ObjectType OCollection::cloneDescriptor( const ObjectType& _descriptor )
{
	ObjectType xNewDescriptor( createDescriptor() );
	::comphelper::copyProperties( _descriptor, xNewDescriptor );
	return xNewDescriptor;
}
// -----------------------------------------------------------------------------
ObjectType OCollection::appendObject( const ::rtl::OUString& /*_rForName*/, const Reference< XPropertySet >& descriptor )
{
    return cloneDescriptor( descriptor );
}
// -----------------------------------------------------------------------------
void OCollection::dropObject(sal_Int32 /*_nPos*/,const ::rtl::OUString /*_sElementName*/)
{
}
// -----------------------------------------------------------------------------
