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