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