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