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