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