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