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