1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_connectivity.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <algorithm>
32*cdf0e10cSrcweir #include <stdio.h>
33*cdf0e10cSrcweir #include "connectivity/sdbcx/VCollection.hxx"
34*cdf0e10cSrcweir #include "connectivity/sdbcx/VDescriptor.hxx"
35*cdf0e10cSrcweir #include "connectivity/dbexception.hxx"
36*cdf0e10cSrcweir #include <comphelper/enumhelper.hxx>
37*cdf0e10cSrcweir #include <comphelper/container.hxx>
38*cdf0e10cSrcweir #include <comphelper/types.hxx>
39*cdf0e10cSrcweir #include <comphelper/property.hxx>
40*cdf0e10cSrcweir #include "TConnection.hxx"
41*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
42*cdf0e10cSrcweir #include "resource/common_res.hrc"
43*cdf0e10cSrcweir #include "resource/sharedresources.hxx"
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir using namespace connectivity::sdbcx;
46*cdf0e10cSrcweir using namespace connectivity;
47*cdf0e10cSrcweir using namespace comphelper;
48*cdf0e10cSrcweir using namespace ::cppu;
49*cdf0e10cSrcweir using namespace ::com::sun::star::beans;
50*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
51*cdf0e10cSrcweir using namespace ::com::sun::star::lang;
52*cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
53*cdf0e10cSrcweir using namespace ::com::sun::star::container;
54*cdf0e10cSrcweir using namespace ::com::sun::star::util;
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir namespace
57*cdf0e10cSrcweir {
58*cdf0e10cSrcweir 	template < typename T> class OHardRefMap : public connectivity::sdbcx::IObjectCollection
59*cdf0e10cSrcweir 	{
60*cdf0e10cSrcweir 		typedef ::std::multimap< ::rtl::OUString, T , ::comphelper::UStringMixLess> ObjectMap;
61*cdf0e10cSrcweir 		typedef typename ObjectMap::iterator   ObjectIter;
62*cdf0e10cSrcweir 		typedef typename ObjectMap::value_type ObjectEntry;
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir 	//	private:
65*cdf0e10cSrcweir 		// this combination of map and vector is used to have a fast name and index access
66*cdf0e10cSrcweir 		::std::vector< ObjectIter >				m_aElements;		// hold the iterators which point to map
67*cdf0e10cSrcweir 		ObjectMap								m_aNameMap;			// hold the elements and a name
68*cdf0e10cSrcweir 	public:
69*cdf0e10cSrcweir 		OHardRefMap(sal_Bool _bCase)
70*cdf0e10cSrcweir 			: m_aNameMap(_bCase ? true : false)
71*cdf0e10cSrcweir 		{
72*cdf0e10cSrcweir 		}
73*cdf0e10cSrcweir         virtual ~OHardRefMap()
74*cdf0e10cSrcweir         {
75*cdf0e10cSrcweir         }
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir 		virtual void reserve(size_t nLength)
78*cdf0e10cSrcweir 		{
79*cdf0e10cSrcweir 			m_aElements.reserve(nLength);
80*cdf0e10cSrcweir 		}
81*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
82*cdf0e10cSrcweir 		virtual bool exists(const ::rtl::OUString& _sName )
83*cdf0e10cSrcweir 		{
84*cdf0e10cSrcweir 			return m_aNameMap.find(_sName) != m_aNameMap.end();
85*cdf0e10cSrcweir 		}
86*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
87*cdf0e10cSrcweir 		virtual bool empty()
88*cdf0e10cSrcweir 		{
89*cdf0e10cSrcweir 			return m_aNameMap.empty();
90*cdf0e10cSrcweir 		}
91*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
92*cdf0e10cSrcweir 		virtual void swapAll()
93*cdf0e10cSrcweir 		{
94*cdf0e10cSrcweir 			::std::vector< ObjectIter >(m_aElements).swap(m_aElements);
95*cdf0e10cSrcweir 			ObjectMap(m_aNameMap).swap(m_aNameMap);
96*cdf0e10cSrcweir 		}
97*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
98*cdf0e10cSrcweir 		virtual void swap()
99*cdf0e10cSrcweir 		{
100*cdf0e10cSrcweir 			::std::vector< ObjectIter >().swap(m_aElements);
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir 			OSL_ENSURE( m_aNameMap.empty(), "swap: what did disposeElements do?" );
103*cdf0e10cSrcweir 			ObjectMap( m_aNameMap ).swap( m_aNameMap );
104*cdf0e10cSrcweir 				// Note that it's /important/ to construct the new ObjectMap from m_aNameMap before
105*cdf0e10cSrcweir 				// swapping. This way, it's ensured that the compare object held by these maps is preserved
106*cdf0e10cSrcweir 				// during the swap. If we would not do this, the UStringMixLess instance which is used would be
107*cdf0e10cSrcweir 				// default constructed (instead of being constructed from the same instance in m_aNameMap), and
108*cdf0e10cSrcweir 				// it's case-sensitive flag would have an unpredictable value.
109*cdf0e10cSrcweir 				// 2002-01-09 - #106589# - fs@openoffice.org
110*cdf0e10cSrcweir 		}
111*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
112*cdf0e10cSrcweir 		virtual void clear()
113*cdf0e10cSrcweir 		{
114*cdf0e10cSrcweir 			m_aElements.clear();
115*cdf0e10cSrcweir 			m_aNameMap.clear();
116*cdf0e10cSrcweir 		}
117*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
118*cdf0e10cSrcweir 		virtual void insert(const ::rtl::OUString& _sName,const ObjectType& _xObject)
119*cdf0e10cSrcweir 		{
120*cdf0e10cSrcweir 			m_aElements.push_back(m_aNameMap.insert(m_aNameMap.begin(), ObjectEntry(_sName,_xObject)));
121*cdf0e10cSrcweir 		}
122*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
123*cdf0e10cSrcweir 		virtual void reFill(const TStringVector &_rVector)
124*cdf0e10cSrcweir 		{
125*cdf0e10cSrcweir 			OSL_ENSURE(!m_aNameMap.size(),"OCollection::reFill: collection isn't empty");
126*cdf0e10cSrcweir 			m_aElements.reserve(_rVector.size());
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir 			for(TStringVector::const_iterator i=_rVector.begin(); i != _rVector.end();++i)
129*cdf0e10cSrcweir 				m_aElements.push_back(m_aNameMap.insert(m_aNameMap.begin(), ObjectEntry(*i,ObjectType())));
130*cdf0e10cSrcweir 		}
131*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
132*cdf0e10cSrcweir 		virtual bool rename(const ::rtl::OUString _sOldName,const ::rtl::OUString _sNewName)
133*cdf0e10cSrcweir 		{
134*cdf0e10cSrcweir 			bool bRet = false;
135*cdf0e10cSrcweir 			ObjectIter aIter = m_aNameMap.find(_sOldName);
136*cdf0e10cSrcweir 			if ( aIter != m_aNameMap.end() )
137*cdf0e10cSrcweir 			{
138*cdf0e10cSrcweir 				typename ::std::vector< ObjectIter >::iterator aFind = ::std::find(m_aElements.begin(),m_aElements.end(),aIter);
139*cdf0e10cSrcweir 				if(m_aElements.end() != aFind)
140*cdf0e10cSrcweir 				{
141*cdf0e10cSrcweir 					(*aFind) = m_aNameMap.insert(m_aNameMap.begin(), ObjectEntry(_sNewName,(*aFind)->second));
142*cdf0e10cSrcweir 					m_aNameMap.erase(aIter);
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir 					bRet = true;
145*cdf0e10cSrcweir 				}
146*cdf0e10cSrcweir 			}
147*cdf0e10cSrcweir 			return bRet;
148*cdf0e10cSrcweir 		}
149*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
150*cdf0e10cSrcweir 		virtual sal_Int32 size()
151*cdf0e10cSrcweir 		{
152*cdf0e10cSrcweir 			return static_cast<sal_Int32>(m_aNameMap.size());
153*cdf0e10cSrcweir 		}
154*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
155*cdf0e10cSrcweir 		virtual Sequence< ::rtl::OUString > getElementNames()
156*cdf0e10cSrcweir 		{
157*cdf0e10cSrcweir 			Sequence< ::rtl::OUString > aNameList(m_aElements.size());
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir 			::rtl::OUString* pStringArray = aNameList.getArray();
160*cdf0e10cSrcweir             typename ::std::vector< ObjectIter >::const_iterator aEnd = m_aElements.end();
161*cdf0e10cSrcweir 			for(typename ::std::vector< ObjectIter >::const_iterator aIter = m_aElements.begin(); aIter != aEnd;++aIter,++pStringArray)
162*cdf0e10cSrcweir 				*pStringArray = (*aIter)->first;
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir 			return aNameList;
165*cdf0e10cSrcweir 		}
166*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
167*cdf0e10cSrcweir 		virtual ::rtl::OUString getName(sal_Int32 _nIndex)
168*cdf0e10cSrcweir 		{
169*cdf0e10cSrcweir 			return m_aElements[_nIndex]->first;
170*cdf0e10cSrcweir 		}
171*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
172*cdf0e10cSrcweir 		virtual void disposeAndErase(sal_Int32 _nIndex)
173*cdf0e10cSrcweir 		{
174*cdf0e10cSrcweir 			OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
175*cdf0e10cSrcweir 			Reference<XComponent> xComp(m_aElements[_nIndex]->second.get(),UNO_QUERY);
176*cdf0e10cSrcweir 			::comphelper::disposeComponent(xComp);
177*cdf0e10cSrcweir 			m_aElements[_nIndex]->second = T();
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir 			::rtl::OUString sName = m_aElements[_nIndex]->first;
180*cdf0e10cSrcweir 			m_aElements.erase(m_aElements.begin()+_nIndex);
181*cdf0e10cSrcweir 			m_aNameMap.erase(sName);
182*cdf0e10cSrcweir 		}
183*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
184*cdf0e10cSrcweir 		virtual void disposeElements()
185*cdf0e10cSrcweir 		{
186*cdf0e10cSrcweir 			for( ObjectIter aIter = m_aNameMap.begin(); aIter != m_aNameMap.end(); ++aIter)
187*cdf0e10cSrcweir 			{
188*cdf0e10cSrcweir 				Reference<XComponent> xComp(aIter->second.get(),UNO_QUERY);
189*cdf0e10cSrcweir 				if ( xComp.is() )
190*cdf0e10cSrcweir 				{
191*cdf0e10cSrcweir 					::comphelper::disposeComponent(xComp);
192*cdf0e10cSrcweir 					(*aIter).second = T();
193*cdf0e10cSrcweir 				}
194*cdf0e10cSrcweir 			}
195*cdf0e10cSrcweir 			m_aElements.clear();
196*cdf0e10cSrcweir 			m_aNameMap.clear();
197*cdf0e10cSrcweir 		}
198*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
199*cdf0e10cSrcweir 		virtual sal_Int32 findColumn( const ::rtl::OUString& columnName )
200*cdf0e10cSrcweir 		{
201*cdf0e10cSrcweir 			ObjectIter aIter = m_aNameMap.find(columnName);
202*cdf0e10cSrcweir 			OSL_ENSURE(aIter != m_aNameMap.end(),"findColumn:: Illegal name!");
203*cdf0e10cSrcweir 			return m_aElements.size() - (m_aElements.end() - ::std::find(m_aElements.begin(),m_aElements.end(),aIter));
204*cdf0e10cSrcweir 		}
205*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
206*cdf0e10cSrcweir 		virtual ::rtl::OUString findColumnAtIndex(  sal_Int32 _nIndex)
207*cdf0e10cSrcweir 		{
208*cdf0e10cSrcweir 			OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
209*cdf0e10cSrcweir 			return m_aElements[_nIndex]->first;
210*cdf0e10cSrcweir 		}
211*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
212*cdf0e10cSrcweir 		virtual ObjectType getObject(sal_Int32 _nIndex)
213*cdf0e10cSrcweir 		{
214*cdf0e10cSrcweir 			OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
215*cdf0e10cSrcweir 			return m_aElements[_nIndex]->second;
216*cdf0e10cSrcweir 		}
217*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
218*cdf0e10cSrcweir 		virtual ObjectType getObject(const ::rtl::OUString& columnName)
219*cdf0e10cSrcweir 		{
220*cdf0e10cSrcweir 			return m_aNameMap.find(columnName)->second;
221*cdf0e10cSrcweir 		}
222*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
223*cdf0e10cSrcweir 		virtual void setObject(sal_Int32 _nIndex,const ObjectType& _xObject)
224*cdf0e10cSrcweir 		{
225*cdf0e10cSrcweir 			OSL_ENSURE(_nIndex >= 0 && _nIndex < static_cast<sal_Int32>(m_aElements.size()),"Illegal argument!");
226*cdf0e10cSrcweir 			m_aElements[_nIndex]->second = _xObject;
227*cdf0e10cSrcweir 		}
228*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
229*cdf0e10cSrcweir 		sal_Bool isCaseSensitive() const
230*cdf0e10cSrcweir 		{
231*cdf0e10cSrcweir 			return m_aNameMap.key_comp().isCaseSensitive();
232*cdf0e10cSrcweir 		}
233*cdf0e10cSrcweir 		// -----------------------------------------------------------------------------
234*cdf0e10cSrcweir 	};
235*cdf0e10cSrcweir }
236*cdf0e10cSrcweir // -----------------------------------------------------------------------------
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir IMPLEMENT_SERVICE_INFO(OCollection,"com.sun.star.sdbcx.VContainer" , "com.sun.star.sdbcx.Container")
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir OCollection::OCollection(::cppu::OWeakObject& _rParent
241*cdf0e10cSrcweir 						 , sal_Bool _bCase
242*cdf0e10cSrcweir 						 , ::osl::Mutex& _rMutex
243*cdf0e10cSrcweir 						 , const TStringVector &_rVector
244*cdf0e10cSrcweir 						 , sal_Bool _bUseIndexOnly
245*cdf0e10cSrcweir 						 , sal_Bool _bUseHardRef)
246*cdf0e10cSrcweir                      :m_aContainerListeners(_rMutex)
247*cdf0e10cSrcweir 					 ,m_aRefreshListeners(_rMutex)
248*cdf0e10cSrcweir 					 ,m_rParent(_rParent)
249*cdf0e10cSrcweir 					 ,m_rMutex(_rMutex)
250*cdf0e10cSrcweir 					 ,m_bUseIndexOnly(_bUseIndexOnly)
251*cdf0e10cSrcweir {
252*cdf0e10cSrcweir 	if ( _bUseHardRef )
253*cdf0e10cSrcweir 	{
254*cdf0e10cSrcweir 		m_pElements.reset(new OHardRefMap< ObjectType >(_bCase));
255*cdf0e10cSrcweir 	}
256*cdf0e10cSrcweir 	else
257*cdf0e10cSrcweir 	{
258*cdf0e10cSrcweir 		m_pElements.reset(new OHardRefMap< WeakReference< XPropertySet> >(_bCase));
259*cdf0e10cSrcweir 	}
260*cdf0e10cSrcweir 	m_pElements->reFill(_rVector);
261*cdf0e10cSrcweir }
262*cdf0e10cSrcweir // -------------------------------------------------------------------------
263*cdf0e10cSrcweir OCollection::~OCollection()
264*cdf0e10cSrcweir {
265*cdf0e10cSrcweir }
266*cdf0e10cSrcweir // -----------------------------------------------------------------------------
267*cdf0e10cSrcweir Any SAL_CALL OCollection::queryInterface( const Type & rType ) throw (RuntimeException)
268*cdf0e10cSrcweir {
269*cdf0e10cSrcweir 	if ( m_bUseIndexOnly && rType == ::getCppuType(static_cast< Reference< XNameAccess > *> (NULL)) )
270*cdf0e10cSrcweir 	{
271*cdf0e10cSrcweir 		return Any();
272*cdf0e10cSrcweir 	}
273*cdf0e10cSrcweir 	return OCollectionBase::queryInterface( rType );
274*cdf0e10cSrcweir }
275*cdf0e10cSrcweir // -----------------------------------------------------------------------------
276*cdf0e10cSrcweir Sequence< Type > SAL_CALL OCollection::getTypes() throw (RuntimeException)
277*cdf0e10cSrcweir {
278*cdf0e10cSrcweir 	if ( m_bUseIndexOnly )
279*cdf0e10cSrcweir 	{
280*cdf0e10cSrcweir 		Sequence< Type > aTypes(OCollectionBase::getTypes());
281*cdf0e10cSrcweir 		Type* pBegin	= aTypes.getArray();
282*cdf0e10cSrcweir 		Type* pEnd		= pBegin + aTypes.getLength();
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir 		::std::vector<Type> aOwnTypes;
285*cdf0e10cSrcweir 		aOwnTypes.reserve(aTypes.getLength());
286*cdf0e10cSrcweir 		Type aType = ::getCppuType(static_cast< Reference<XNameAccess> *>(NULL));
287*cdf0e10cSrcweir 		for(;pBegin != pEnd; ++pBegin)
288*cdf0e10cSrcweir 		{
289*cdf0e10cSrcweir 			if ( *pBegin != aType )
290*cdf0e10cSrcweir 				aOwnTypes.push_back(*pBegin);
291*cdf0e10cSrcweir 		}
292*cdf0e10cSrcweir 		Type* pTypes = aOwnTypes.empty() ? 0 : &aOwnTypes[0];
293*cdf0e10cSrcweir 		return Sequence< Type >(pTypes,aOwnTypes.size());
294*cdf0e10cSrcweir 	}
295*cdf0e10cSrcweir 	return OCollectionBase::getTypes( );
296*cdf0e10cSrcweir }
297*cdf0e10cSrcweir // -------------------------------------------------------------------------
298*cdf0e10cSrcweir void OCollection::clear_NoDispose()
299*cdf0e10cSrcweir {
300*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir 	m_pElements->clear();
303*cdf0e10cSrcweir 	m_pElements->swapAll();
304*cdf0e10cSrcweir }
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir // -------------------------------------------------------------------------
307*cdf0e10cSrcweir void OCollection::disposing(void)
308*cdf0e10cSrcweir {
309*cdf0e10cSrcweir 	m_aContainerListeners.disposeAndClear(EventObject(static_cast<XTypeProvider*>(this)));
310*cdf0e10cSrcweir 	m_aRefreshListeners.disposeAndClear(EventObject(static_cast<XTypeProvider*>(this)));
311*cdf0e10cSrcweir 
312*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir 	disposeElements();
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir 	m_pElements->swap();
317*cdf0e10cSrcweir }
318*cdf0e10cSrcweir // -------------------------------------------------------------------------
319*cdf0e10cSrcweir Any SAL_CALL OCollection::getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
320*cdf0e10cSrcweir {
321*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
322*cdf0e10cSrcweir 	if (Index < 0 || Index >= m_pElements->size() )
323*cdf0e10cSrcweir 		throw IndexOutOfBoundsException(::rtl::OUString::valueOf(Index),static_cast<XTypeProvider*>(this));
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir 	return makeAny(getObject(Index));
326*cdf0e10cSrcweir }
327*cdf0e10cSrcweir // -------------------------------------------------------------------------
328*cdf0e10cSrcweir Any SAL_CALL OCollection::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
329*cdf0e10cSrcweir {
330*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir 	if ( !m_pElements->exists(aName) )
333*cdf0e10cSrcweir     {
334*cdf0e10cSrcweir         ::connectivity::SharedResources aResources;
335*cdf0e10cSrcweir         const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(
336*cdf0e10cSrcweir                 STR_NO_ELEMENT_NAME,
337*cdf0e10cSrcweir                 "$name$", aName
338*cdf0e10cSrcweir              ) );
339*cdf0e10cSrcweir 		throw NoSuchElementException( sError, static_cast< XTypeProvider* >( this ) );
340*cdf0e10cSrcweir     }
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir 	return makeAny(getObject(m_pElements->findColumn(aName)));
343*cdf0e10cSrcweir }
344*cdf0e10cSrcweir // -------------------------------------------------------------------------
345*cdf0e10cSrcweir Sequence< ::rtl::OUString > SAL_CALL OCollection::getElementNames(  ) throw(RuntimeException)
346*cdf0e10cSrcweir {
347*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
348*cdf0e10cSrcweir 	return m_pElements->getElementNames();
349*cdf0e10cSrcweir }
350*cdf0e10cSrcweir // -------------------------------------------------------------------------
351*cdf0e10cSrcweir void SAL_CALL OCollection::refresh(  ) throw(RuntimeException)
352*cdf0e10cSrcweir {
353*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir 	disposeElements();
356*cdf0e10cSrcweir 
357*cdf0e10cSrcweir 	impl_refresh();
358*cdf0e10cSrcweir 	EventObject aEvt(static_cast<XTypeProvider*>(this));
359*cdf0e10cSrcweir     m_aRefreshListeners.notifyEach( &XRefreshListener::refreshed, aEvt );
360*cdf0e10cSrcweir }
361*cdf0e10cSrcweir // -----------------------------------------------------------------------------
362*cdf0e10cSrcweir void OCollection::reFill(const TStringVector &_rVector)
363*cdf0e10cSrcweir {
364*cdf0e10cSrcweir 	m_pElements->reFill(_rVector);
365*cdf0e10cSrcweir }
366*cdf0e10cSrcweir // -------------------------------------------------------------------------
367*cdf0e10cSrcweir // XDataDescriptorFactory
368*cdf0e10cSrcweir Reference< XPropertySet > SAL_CALL OCollection::createDataDescriptor(  ) throw(RuntimeException)
369*cdf0e10cSrcweir {
370*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir 	return createDescriptor();
373*cdf0e10cSrcweir }
374*cdf0e10cSrcweir // -----------------------------------------------------------------------------
375*cdf0e10cSrcweir ::rtl::OUString OCollection::getNameForObject(const ObjectType& _xObject)
376*cdf0e10cSrcweir {
377*cdf0e10cSrcweir     OSL_ENSURE(_xObject.is(),"OCollection::getNameForObject: Object is NULL!");
378*cdf0e10cSrcweir     ::rtl::OUString sName;
379*cdf0e10cSrcweir     _xObject->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= sName;
380*cdf0e10cSrcweir     return sName;
381*cdf0e10cSrcweir }
382*cdf0e10cSrcweir // -------------------------------------------------------------------------
383*cdf0e10cSrcweir // XAppend
384*cdf0e10cSrcweir void SAL_CALL OCollection::appendByDescriptor( const Reference< XPropertySet >& descriptor ) throw(SQLException, ElementExistException, RuntimeException)
385*cdf0e10cSrcweir {
386*cdf0e10cSrcweir 	::osl::ClearableMutexGuard aGuard(m_rMutex);
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir     ::rtl::OUString sName = getNameForObject( descriptor );
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir 	if ( m_pElements->exists(sName) )
391*cdf0e10cSrcweir 		throw ElementExistException(sName,static_cast<XTypeProvider*>(this));
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir     ObjectType xNewlyCreated = appendObject( sName, descriptor );
394*cdf0e10cSrcweir 	if ( !xNewlyCreated.is() )
395*cdf0e10cSrcweir         throw RuntimeException();
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir     ODescriptor* pDescriptor = ODescriptor::getImplementation( xNewlyCreated );
398*cdf0e10cSrcweir 	if ( pDescriptor )
399*cdf0e10cSrcweir 		pDescriptor->setNew( sal_False );
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir     sName = getNameForObject( xNewlyCreated );
402*cdf0e10cSrcweir 	if ( !m_pElements->exists( sName ) ) // this may happen when the drived class included it itself
403*cdf0e10cSrcweir 		m_pElements->insert( sName, xNewlyCreated );
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir     // notify our container listeners
406*cdf0e10cSrcweir 	ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(sName), makeAny(xNewlyCreated), Any());
407*cdf0e10cSrcweir     aGuard.clear();
408*cdf0e10cSrcweir     m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
409*cdf0e10cSrcweir }
410*cdf0e10cSrcweir // -------------------------------------------------------------------------
411*cdf0e10cSrcweir // XDrop
412*cdf0e10cSrcweir void SAL_CALL OCollection::dropByName( const ::rtl::OUString& elementName ) throw(SQLException, NoSuchElementException, RuntimeException)
413*cdf0e10cSrcweir {
414*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir 	if ( !m_pElements->exists(elementName) )
417*cdf0e10cSrcweir 		throw NoSuchElementException(elementName,static_cast<XTypeProvider*>(this));
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir 	dropImpl(m_pElements->findColumn(elementName));
420*cdf0e10cSrcweir }
421*cdf0e10cSrcweir // -------------------------------------------------------------------------
422*cdf0e10cSrcweir void SAL_CALL OCollection::dropByIndex( sal_Int32 index ) throw(SQLException, IndexOutOfBoundsException, RuntimeException)
423*cdf0e10cSrcweir {
424*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
425*cdf0e10cSrcweir 	if(index <0 || index >= getCount())
426*cdf0e10cSrcweir 		throw IndexOutOfBoundsException(::rtl::OUString::valueOf(index),static_cast<XTypeProvider*>(this));
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir 	dropImpl(index);
429*cdf0e10cSrcweir }
430*cdf0e10cSrcweir // -----------------------------------------------------------------------------
431*cdf0e10cSrcweir void OCollection::dropImpl(sal_Int32 _nIndex,sal_Bool _bReallyDrop)
432*cdf0e10cSrcweir {
433*cdf0e10cSrcweir 	::rtl::OUString elementName = m_pElements->getName(_nIndex);
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir 	if ( _bReallyDrop )
436*cdf0e10cSrcweir 		dropObject(_nIndex,elementName);
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir 	m_pElements->disposeAndErase(_nIndex);
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir 	// notify our container listeners
441*cdf0e10cSrcweir 	notifyElementRemoved(elementName);
442*cdf0e10cSrcweir }
443*cdf0e10cSrcweir // -----------------------------------------------------------------------------
444*cdf0e10cSrcweir void OCollection::notifyElementRemoved(const ::rtl::OUString& _sName)
445*cdf0e10cSrcweir {
446*cdf0e10cSrcweir 	ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(_sName), Any(), Any());
447*cdf0e10cSrcweir 	// note that xExistent may be empty, in case somebody removed the data source while it is not alive at this moment
448*cdf0e10cSrcweir 	OInterfaceIteratorHelper aListenerLoop(m_aContainerListeners);
449*cdf0e10cSrcweir 	while (aListenerLoop.hasMoreElements())
450*cdf0e10cSrcweir 		static_cast<XContainerListener*>(aListenerLoop.next())->elementRemoved(aEvent);
451*cdf0e10cSrcweir }
452*cdf0e10cSrcweir // -------------------------------------------------------------------------
453*cdf0e10cSrcweir sal_Int32 SAL_CALL OCollection::findColumn( const ::rtl::OUString& columnName ) throw(SQLException, RuntimeException)
454*cdf0e10cSrcweir {
455*cdf0e10cSrcweir 	if ( !m_pElements->exists(columnName) )
456*cdf0e10cSrcweir     {
457*cdf0e10cSrcweir         ::connectivity::SharedResources aResources;
458*cdf0e10cSrcweir         const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(
459*cdf0e10cSrcweir                             STR_UNKNOWN_COLUMN_NAME,
460*cdf0e10cSrcweir                             "$columnname$", columnName
461*cdf0e10cSrcweir                          ) );
462*cdf0e10cSrcweir 		::dbtools::throwGenericSQLException(sError,static_cast< XIndexAccess*>(this));
463*cdf0e10cSrcweir     }
464*cdf0e10cSrcweir 
465*cdf0e10cSrcweir 	return m_pElements->findColumn(columnName) + 1; // because columns start at one
466*cdf0e10cSrcweir }
467*cdf0e10cSrcweir // -------------------------------------------------------------------------
468*cdf0e10cSrcweir Reference< XEnumeration > SAL_CALL OCollection::createEnumeration(  ) throw(RuntimeException)
469*cdf0e10cSrcweir {
470*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
471*cdf0e10cSrcweir     return new OEnumerationByIndex( static_cast< XIndexAccess*>(this));
472*cdf0e10cSrcweir }
473*cdf0e10cSrcweir // -----------------------------------------------------------------------------
474*cdf0e10cSrcweir void SAL_CALL OCollection::addContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
475*cdf0e10cSrcweir {
476*cdf0e10cSrcweir 	m_aContainerListeners.addInterface(_rxListener);
477*cdf0e10cSrcweir }
478*cdf0e10cSrcweir 
479*cdf0e10cSrcweir //------------------------------------------------------------------------------
480*cdf0e10cSrcweir void SAL_CALL OCollection::removeContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException)
481*cdf0e10cSrcweir {
482*cdf0e10cSrcweir 	m_aContainerListeners.removeInterface(_rxListener);
483*cdf0e10cSrcweir }
484*cdf0e10cSrcweir // -----------------------------------------------------------------------------
485*cdf0e10cSrcweir void SAL_CALL OCollection::acquire() throw()
486*cdf0e10cSrcweir {
487*cdf0e10cSrcweir 	m_rParent.acquire();
488*cdf0e10cSrcweir }
489*cdf0e10cSrcweir // -----------------------------------------------------------------------------
490*cdf0e10cSrcweir void SAL_CALL OCollection::release() throw()
491*cdf0e10cSrcweir {
492*cdf0e10cSrcweir 	m_rParent.release();
493*cdf0e10cSrcweir }
494*cdf0e10cSrcweir // -----------------------------------------------------------------------------
495*cdf0e10cSrcweir Type SAL_CALL OCollection::getElementType(  ) throw(RuntimeException)
496*cdf0e10cSrcweir {
497*cdf0e10cSrcweir 	return::getCppuType(static_cast< Reference< XPropertySet>*>(NULL));
498*cdf0e10cSrcweir }
499*cdf0e10cSrcweir // -----------------------------------------------------------------------------
500*cdf0e10cSrcweir sal_Bool SAL_CALL OCollection::hasElements(  ) throw(RuntimeException)
501*cdf0e10cSrcweir {
502*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
503*cdf0e10cSrcweir 	return !m_pElements->empty();
504*cdf0e10cSrcweir }
505*cdf0e10cSrcweir // -----------------------------------------------------------------------------
506*cdf0e10cSrcweir sal_Int32 SAL_CALL OCollection::getCount(  ) throw(RuntimeException)
507*cdf0e10cSrcweir {
508*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
509*cdf0e10cSrcweir 	return m_pElements->size();
510*cdf0e10cSrcweir }
511*cdf0e10cSrcweir // -----------------------------------------------------------------------------
512*cdf0e10cSrcweir sal_Bool SAL_CALL OCollection::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException)
513*cdf0e10cSrcweir {
514*cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_rMutex);
515*cdf0e10cSrcweir 	return m_pElements->exists(aName);
516*cdf0e10cSrcweir }
517*cdf0e10cSrcweir // -----------------------------------------------------------------------------
518*cdf0e10cSrcweir void SAL_CALL OCollection::addRefreshListener( const Reference< XRefreshListener >& l ) throw(RuntimeException)
519*cdf0e10cSrcweir {
520*cdf0e10cSrcweir 	m_aRefreshListeners.addInterface(l);
521*cdf0e10cSrcweir }
522*cdf0e10cSrcweir // -----------------------------------------------------------------------------
523*cdf0e10cSrcweir void SAL_CALL OCollection::removeRefreshListener( const Reference< XRefreshListener >& l ) throw(RuntimeException)
524*cdf0e10cSrcweir {
525*cdf0e10cSrcweir 	m_aRefreshListeners.removeInterface(l);
526*cdf0e10cSrcweir }
527*cdf0e10cSrcweir // -----------------------------------------------------------------------------
528*cdf0e10cSrcweir void OCollection::insertElement(const ::rtl::OUString& _sElementName,const ObjectType& _xElement)
529*cdf0e10cSrcweir {
530*cdf0e10cSrcweir 	OSL_ENSURE(!m_pElements->exists(_sElementName),"Element already exists");
531*cdf0e10cSrcweir 	if ( !m_pElements->exists(_sElementName) )
532*cdf0e10cSrcweir 		m_pElements->insert(_sElementName,_xElement);
533*cdf0e10cSrcweir }
534*cdf0e10cSrcweir // -----------------------------------------------------------------------------
535*cdf0e10cSrcweir void OCollection::renameObject(const ::rtl::OUString _sOldName,const ::rtl::OUString _sNewName)
536*cdf0e10cSrcweir {
537*cdf0e10cSrcweir 	OSL_ENSURE(m_pElements->exists(_sOldName),"Element doesn't exist");
538*cdf0e10cSrcweir 	OSL_ENSURE(!m_pElements->exists(_sNewName),"Element already exists");
539*cdf0e10cSrcweir 	OSL_ENSURE(_sNewName.getLength(),"New name must not be empty!");
540*cdf0e10cSrcweir 	OSL_ENSURE(_sOldName.getLength(),"New name must not be empty!");
541*cdf0e10cSrcweir 
542*cdf0e10cSrcweir 	if ( m_pElements->rename(_sOldName,_sNewName) )
543*cdf0e10cSrcweir 	{
544*cdf0e10cSrcweir 		ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(_sNewName), makeAny(m_pElements->getObject(_sNewName)),makeAny(_sOldName));
545*cdf0e10cSrcweir 		// note that xExistent may be empty, in case somebody removed the data source while it is not alive at this moment
546*cdf0e10cSrcweir 		OInterfaceIteratorHelper aListenerLoop(m_aContainerListeners);
547*cdf0e10cSrcweir 		while (aListenerLoop.hasMoreElements())
548*cdf0e10cSrcweir 			static_cast<XContainerListener*>(aListenerLoop.next())->elementReplaced(aEvent);
549*cdf0e10cSrcweir 	}
550*cdf0e10cSrcweir }
551*cdf0e10cSrcweir // -----------------------------------------------------------------------------
552*cdf0e10cSrcweir ObjectType OCollection::getObject(sal_Int32 _nIndex)
553*cdf0e10cSrcweir {
554*cdf0e10cSrcweir 	ObjectType xName = m_pElements->getObject(_nIndex);
555*cdf0e10cSrcweir 	if ( !xName.is() )
556*cdf0e10cSrcweir 	{
557*cdf0e10cSrcweir 		try
558*cdf0e10cSrcweir 		{
559*cdf0e10cSrcweir 			xName = createObject(m_pElements->getName(_nIndex));
560*cdf0e10cSrcweir 		}
561*cdf0e10cSrcweir 		catch(const SQLException& e)
562*cdf0e10cSrcweir 		{
563*cdf0e10cSrcweir 			try
564*cdf0e10cSrcweir 			{
565*cdf0e10cSrcweir 				dropImpl(_nIndex,sal_False);
566*cdf0e10cSrcweir 			}
567*cdf0e10cSrcweir 			catch(const Exception& )
568*cdf0e10cSrcweir 			{
569*cdf0e10cSrcweir 			}
570*cdf0e10cSrcweir 			throw WrappedTargetException(e.Message,static_cast<XTypeProvider*>(this),makeAny(e));
571*cdf0e10cSrcweir 		}
572*cdf0e10cSrcweir 		m_pElements->setObject(_nIndex,xName);
573*cdf0e10cSrcweir 	}
574*cdf0e10cSrcweir 	return xName;
575*cdf0e10cSrcweir }
576*cdf0e10cSrcweir // -----------------------------------------------------------------------------
577*cdf0e10cSrcweir void OCollection::disposeElements()
578*cdf0e10cSrcweir {
579*cdf0e10cSrcweir 	m_pElements->disposeElements();
580*cdf0e10cSrcweir }
581*cdf0e10cSrcweir // -----------------------------------------------------------------------------
582*cdf0e10cSrcweir Reference< XPropertySet > OCollection::createDescriptor()
583*cdf0e10cSrcweir {
584*cdf0e10cSrcweir 	OSL_ASSERT(!"Need to be overloaded when used!");
585*cdf0e10cSrcweir 	throw SQLException();
586*cdf0e10cSrcweir }
587*cdf0e10cSrcweir // -----------------------------------------------------------------------------
588*cdf0e10cSrcweir ObjectType OCollection::cloneDescriptor( const ObjectType& _descriptor )
589*cdf0e10cSrcweir {
590*cdf0e10cSrcweir 	ObjectType xNewDescriptor( createDescriptor() );
591*cdf0e10cSrcweir 	::comphelper::copyProperties( _descriptor, xNewDescriptor );
592*cdf0e10cSrcweir 	return xNewDescriptor;
593*cdf0e10cSrcweir }
594*cdf0e10cSrcweir // -----------------------------------------------------------------------------
595*cdf0e10cSrcweir ObjectType OCollection::appendObject( const ::rtl::OUString& /*_rForName*/, const Reference< XPropertySet >& descriptor )
596*cdf0e10cSrcweir {
597*cdf0e10cSrcweir     return cloneDescriptor( descriptor );
598*cdf0e10cSrcweir }
599*cdf0e10cSrcweir // -----------------------------------------------------------------------------
600*cdf0e10cSrcweir void OCollection::dropObject(sal_Int32 /*_nPos*/,const ::rtl::OUString /*_sElementName*/)
601*cdf0e10cSrcweir {
602*cdf0e10cSrcweir }
603*cdf0e10cSrcweir // -----------------------------------------------------------------------------
604