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_dbaccess.hxx" 30 31 #ifndef _DBA_CORE_DEFINITIONCONTAINER_HXX_ 32 #include "definitioncontainer.hxx" 33 #endif 34 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC 35 #include "dbastrings.hrc" 36 #endif 37 #ifndef _DBASHARED_APITOOLS_HXX_ 38 #include "apitools.hxx" 39 #endif 40 #ifndef _DBA_CORE_RESOURCE_HXX_ 41 #include "core_resource.hxx" 42 #endif 43 #ifndef _DBA_CORE_RESOURCE_HRC_ 44 #include "core_resource.hrc" 45 #endif 46 47 #ifndef _TOOLS_DEBUG_HXX 48 #include <tools/debug.hxx> 49 #endif 50 #ifndef TOOLS_DIAGNOSE_EX_H 51 #include <tools/diagnose_ex.h> 52 #endif 53 #ifndef _COMPHELPER_SEQUENCE_HXX_ 54 #include <comphelper/sequence.hxx> 55 #endif 56 #ifndef _COMPHELPER_ENUMHELPER_HXX_ 57 #include <comphelper/enumhelper.hxx> 58 #endif 59 #ifndef _COMPHELPER_EXTRACT_HXX_ 60 #include <comphelper/extract.hxx> 61 #endif 62 #ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ 63 #include <com/sun/star/lang/XComponent.hpp> 64 #endif 65 #ifndef _COM_SUN_STAR_UCB_COMMANDINFO_HPP_ 66 #include <com/sun/star/ucb/CommandInfo.hpp> 67 #endif 68 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ 69 #include <com/sun/star/beans/XPropertySet.hpp> 70 #endif 71 #ifndef _COM_SUN_STAR_SDB_ERRORCONDITION_HPP_ 72 #include <com/sun/star/sdb/ErrorCondition.hpp> 73 #endif 74 #ifndef _COMPHELPER_TYPES_HXX_ 75 #include <comphelper/types.hxx> 76 #endif 77 #ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX 78 #include <ucbhelper/contentidentifier.hxx> 79 #endif 80 81 82 using namespace ::com::sun::star::uno; 83 using namespace ::com::sun::star::lang; 84 using namespace ::com::sun::star::util; 85 using namespace ::com::sun::star::beans; 86 using namespace ::com::sun::star::container; 87 using namespace ::com::sun::star::sdbcx; 88 using namespace ::com::sun::star::sdb; 89 using namespace ::osl; 90 using namespace ::comphelper; 91 using namespace ::cppu; 92 using namespace ::com::sun::star::ucb; 93 94 //........................................................................ 95 namespace dbaccess 96 { 97 //........................................................................ 98 99 //========================================================================== 100 //= ODefinitionContainer_Impl 101 //========================================================================== 102 //-------------------------------------------------------------------------- 103 void ODefinitionContainer_Impl::erase( TContentPtr _pDefinition ) 104 { 105 NamedDefinitions::iterator aPos = find( _pDefinition ); 106 if ( aPos != end() ) 107 m_aDefinitions.erase( aPos ); 108 } 109 110 //-------------------------------------------------------------------------- 111 ODefinitionContainer_Impl::const_iterator ODefinitionContainer_Impl::find( TContentPtr _pDefinition ) const 112 { 113 return ::std::find_if( 114 m_aDefinitions.begin(), 115 m_aDefinitions.end(), 116 ::std::compose1( 117 ::std::bind2nd( ::std::equal_to< TContentPtr >(), _pDefinition ), 118 ::std::select2nd< NamedDefinitions::value_type >() 119 ) 120 ); 121 } 122 123 //-------------------------------------------------------------------------- 124 ODefinitionContainer_Impl::iterator ODefinitionContainer_Impl::find( TContentPtr _pDefinition ) 125 { 126 return ::std::find_if( 127 m_aDefinitions.begin(), 128 m_aDefinitions.end(), 129 ::std::compose1( 130 ::std::bind2nd( ::std::equal_to< TContentPtr >(), _pDefinition ), 131 ::std::select2nd< NamedDefinitions::value_type >() 132 ) 133 ); 134 } 135 136 //========================================================================== 137 //= ODefinitionContainer 138 //========================================================================== 139 DBG_NAME(ODefinitionContainer) 140 //-------------------------------------------------------------------------- 141 ODefinitionContainer::ODefinitionContainer( const Reference< XMultiServiceFactory >& _xORB 142 , const Reference< XInterface >& _xParentContainer 143 , const TContentPtr& _pImpl 144 , bool _bCheckSlash 145 ) 146 :OContentHelper(_xORB,_xParentContainer,_pImpl) 147 ,m_aApproveListeners(m_aMutex) 148 ,m_aContainerListeners(m_aMutex) 149 ,m_bInPropertyChange(sal_False) 150 ,m_bCheckSlash(_bCheckSlash) 151 { 152 m_pImpl->m_aProps.bIsDocument = sal_False; 153 m_pImpl->m_aProps.bIsFolder = sal_True; 154 155 const ODefinitionContainer_Impl& rDefinitions( getDefinitions() ); 156 ODefinitionContainer_Impl::const_iterator aEnd = rDefinitions.end(); 157 for ( ODefinitionContainer_Impl::const_iterator aDefinition = rDefinitions.begin(); 158 aDefinition != aEnd; 159 ++aDefinition 160 ) 161 m_aDocuments.push_back( 162 m_aDocumentMap.insert( 163 Documents::value_type( aDefinition->first, Documents::mapped_type() ) ).first ); 164 165 DBG_CTOR(ODefinitionContainer, NULL); 166 } 167 168 //-------------------------------------------------------------------------- 169 void SAL_CALL ODefinitionContainer::disposing() 170 { 171 OContentHelper::disposing(); 172 173 MutexGuard aGuard(m_aMutex); 174 175 // say our listeners goobye 176 EventObject aEvt(*this); 177 m_aApproveListeners.disposeAndClear(aEvt); 178 m_aContainerListeners.disposeAndClear(aEvt); 179 180 // dispose our elements 181 Documents::iterator aIter = m_aDocumentMap.begin(); 182 Documents::iterator aEnd = m_aDocumentMap.end(); 183 184 for (; aIter != aEnd; ++aIter) 185 { 186 Reference<XContent> xProp = aIter->second; 187 if ( xProp.is() ) 188 { 189 removeObjectListener(xProp); 190 ::comphelper::disposeComponent(xProp); 191 } 192 } 193 194 // remove our elements 195 m_aDocuments.clear(); 196 // !!! do this before clearing the map which the vector elements refer to !!! 197 m_aDocumentMap.clear(); 198 } 199 200 //-------------------------------------------------------------------------- 201 ODefinitionContainer::~ODefinitionContainer() 202 { 203 DBG_DTOR(ODefinitionContainer, NULL); 204 } 205 206 IMPLEMENT_FORWARD_XINTERFACE2( ODefinitionContainer,OContentHelper,ODefinitionContainer_Base) 207 IMPLEMENT_TYPEPROVIDER2(ODefinitionContainer,OContentHelper,ODefinitionContainer_Base); 208 // XServiceInfo 209 //-------------------------------------------------------------------------- 210 ::rtl::OUString SAL_CALL ODefinitionContainer::getImplementationName( ) throw(RuntimeException) 211 { 212 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.ODefinitionContainer")); 213 } 214 //-------------------------------------------------------------------------- 215 Sequence< ::rtl::OUString > SAL_CALL ODefinitionContainer::getSupportedServiceNames( ) throw(RuntimeException) 216 { 217 Sequence< ::rtl::OUString > aReturn(2); 218 aReturn.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.DefinitionContainer")); 219 aReturn.getArray()[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.Content")); 220 return aReturn; 221 } 222 223 // XNameContainer 224 //-------------------------------------------------------------------------- 225 void SAL_CALL ODefinitionContainer::insertByName( const ::rtl::OUString& _rName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException) 226 { 227 ResettableMutexGuard aGuard(m_aMutex); 228 229 // approve the new object 230 Reference< XContent > xNewElement(aElement,UNO_QUERY); 231 approveNewObject( _rName, xNewElement ); // will throw if necessary 232 233 notifyByName( aGuard, _rName, xNewElement, NULL, E_INSERTED, ApproveListeners ); 234 implAppend( _rName, xNewElement ); 235 notifyByName( aGuard, _rName, xNewElement, NULL, E_INSERTED, ContainerListemers ); 236 } 237 238 //-------------------------------------------------------------------------- 239 void SAL_CALL ODefinitionContainer::removeByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) 240 { 241 ResettableMutexGuard aGuard(m_aMutex); 242 243 // check the arguments 244 if (!_rName.getLength()) 245 throw IllegalArgumentException(); 246 247 if (!checkExistence(_rName)) 248 throw NoSuchElementException(_rName,*this); 249 250 // the old element (for the notifications) 251 Reference< XContent > xOldElement = implGetByName( _rName, impl_haveAnyListeners_nothrow() ); 252 253 // do the removal 254 notifyByName( aGuard, _rName, NULL, xOldElement, E_REMOVED, ApproveListeners ); 255 implRemove( _rName ); 256 notifyByName( aGuard, _rName, NULL, xOldElement, E_REMOVED, ContainerListemers ); 257 258 removeObjectListener( xOldElement ); 259 disposeComponent(xOldElement); 260 } 261 262 // XNameReplace 263 //-------------------------------------------------------------------------- 264 void SAL_CALL ODefinitionContainer::replaceByName( const ::rtl::OUString& _rName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException) 265 { 266 ResettableMutexGuard aGuard(m_aMutex); 267 268 // let derived classes approve the new object 269 Reference< XContent > xNewElement(aElement,UNO_QUERY); 270 approveNewObject( _rName, xNewElement ); // will throw if necessary 271 272 // the old element (for the notifications) 273 Reference< XContent > xOldElement = implGetByName( _rName, impl_haveAnyListeners_nothrow() ); 274 275 notifyByName( aGuard, _rName, xNewElement, xOldElement, E_REPLACED, ApproveListeners ); 276 implReplace( _rName, xNewElement ); 277 notifyByName( aGuard, _rName, xNewElement, xOldElement, E_REPLACED, ContainerListemers ); 278 279 // and dispose it 280 disposeComponent(xOldElement); 281 } 282 283 // ----------------------------------------------------------------------------- 284 namespace 285 { 286 typedef Reference< XVeto > ( SAL_CALL XContainerApproveListener::*ContainerApprovalMethod )( const ContainerEvent& ); 287 288 struct RaiseExceptionFromVeto 289 { 290 private: 291 ContainerApprovalMethod m_pMethod; 292 const ContainerEvent& m_rEvent; 293 294 public: 295 RaiseExceptionFromVeto( ContainerApprovalMethod _pMethod, const ContainerEvent& _rEvent ) 296 :m_pMethod( _pMethod ) 297 ,m_rEvent( _rEvent ) 298 { 299 } 300 301 void operator()( const Reference< XContainerApproveListener >& _Listener ) const 302 { 303 Reference< XVeto > xVeto = (_Listener.get()->*m_pMethod)( m_rEvent ); 304 if ( !xVeto.is() ) 305 return; 306 307 Any eVetoDetails = xVeto->getDetails(); 308 309 IllegalArgumentException aIllegalArgumentError; 310 if ( eVetoDetails >>= aIllegalArgumentError ) 311 throw aIllegalArgumentError; 312 313 WrappedTargetException aWrappedError; 314 if ( eVetoDetails >>= aWrappedError ) 315 throw aWrappedError; 316 317 throw WrappedTargetException( xVeto->getReason(), _Listener.get(), eVetoDetails ); 318 } 319 }; 320 } 321 322 // ----------------------------------------------------------------------------- 323 void ODefinitionContainer::notifyByName( ResettableMutexGuard& _rGuard, const ::rtl::OUString& _rName, 324 const Reference< XContent >& _xNewElement, const Reference< XContent >& _xOldElement, 325 ContainerOperation _eOperation, ListenerType _eType ) 326 { 327 bool bApprove = ( _eType == ApproveListeners ); 328 329 ::cppu::OInterfaceContainerHelper& rContainer( bApprove ? m_aApproveListeners : m_aContainerListeners ); 330 if ( !rContainer.getLength() ) 331 return; 332 333 ContainerEvent aEvent( *this, makeAny( _rName ), makeAny( _xNewElement ), makeAny( _xOldElement ) ); 334 335 _rGuard.clear(); 336 switch ( _eOperation ) 337 { 338 case E_INSERTED: 339 if ( bApprove ) 340 rContainer.forEach< XContainerApproveListener, RaiseExceptionFromVeto >( 341 RaiseExceptionFromVeto( &XContainerApproveListener::approveInsertElement, aEvent ) ); 342 else 343 rContainer.notifyEach( &XContainerListener::elementInserted, aEvent ); 344 break; 345 case E_REPLACED: 346 if ( bApprove ) 347 rContainer.forEach< XContainerApproveListener, RaiseExceptionFromVeto >( 348 RaiseExceptionFromVeto( &XContainerApproveListener::approveReplaceElement, aEvent ) ); 349 else 350 rContainer.notifyEach( &XContainerListener::elementReplaced, aEvent ); 351 break; 352 case E_REMOVED: 353 if ( bApprove ) 354 rContainer.forEach< XContainerApproveListener, RaiseExceptionFromVeto >( 355 RaiseExceptionFromVeto( &XContainerApproveListener::approveRemoveElement, aEvent ) ); 356 else 357 rContainer.notifyEach( &XContainerListener::elementRemoved, aEvent ); 358 break; 359 } 360 361 if ( bApprove ) 362 _rGuard.reset(); 363 } 364 365 //-------------------------------------------------------------------------- 366 void SAL_CALL ODefinitionContainer::addContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException) 367 { 368 if (_rxListener.is()) 369 m_aContainerListeners.addInterface(_rxListener); 370 } 371 372 //-------------------------------------------------------------------------- 373 void SAL_CALL ODefinitionContainer::removeContainerListener( const Reference< XContainerListener >& _rxListener ) throw(RuntimeException) 374 { 375 if (_rxListener.is()) 376 m_aContainerListeners.removeInterface(_rxListener); 377 } 378 379 //-------------------------------------------------------------------------- 380 void SAL_CALL ODefinitionContainer::addContainerApproveListener( const Reference< XContainerApproveListener >& _Listener ) throw (RuntimeException) 381 { 382 if ( _Listener.is() ) 383 m_aApproveListeners.addInterface( _Listener ); 384 } 385 386 //-------------------------------------------------------------------------- 387 void SAL_CALL ODefinitionContainer::removeContainerApproveListener( const Reference< XContainerApproveListener >& _Listener ) throw (RuntimeException) 388 { 389 if ( _Listener.is() ) 390 m_aApproveListeners.removeInterface( _Listener ); 391 } 392 393 394 // XElementAccess 395 //-------------------------------------------------------------------------- 396 Type SAL_CALL ODefinitionContainer::getElementType( ) throw (RuntimeException) 397 { 398 return ::getCppuType( static_cast< Reference< XContent >* >(NULL) ); 399 } 400 401 //-------------------------------------------------------------------------- 402 sal_Bool SAL_CALL ODefinitionContainer::hasElements( ) throw (RuntimeException) 403 { 404 MutexGuard aGuard(m_aMutex); 405 return !m_aDocuments.empty(); 406 } 407 408 // XEnumerationAccess 409 //-------------------------------------------------------------------------- 410 Reference< XEnumeration > SAL_CALL ODefinitionContainer::createEnumeration( ) throw(RuntimeException) 411 { 412 MutexGuard aGuard(m_aMutex); 413 return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this)); 414 } 415 416 //-------------------------------------------------------------------------- 417 // XIndexAccess 418 sal_Int32 SAL_CALL ODefinitionContainer::getCount( ) throw(RuntimeException) 419 { 420 MutexGuard aGuard(m_aMutex); 421 return m_aDocuments.size(); 422 } 423 424 //-------------------------------------------------------------------------- 425 Any SAL_CALL ODefinitionContainer::getByIndex( sal_Int32 _nIndex ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException) 426 { 427 MutexGuard aGuard(m_aMutex); 428 429 if ((_nIndex < 0) || (_nIndex >= (sal_Int32)m_aDocuments.size())) 430 throw IndexOutOfBoundsException(); 431 432 Documents::iterator aPos = m_aDocuments[_nIndex]; 433 Reference<XContent> xProp = aPos->second; 434 if (!xProp.is()) 435 { // that's the first access to the object 436 // -> create it 437 xProp = createObject(aPos->first); 438 aPos->second = Documents::mapped_type(); 439 // and update the name-access map 440 } 441 442 return makeAny(xProp); 443 } 444 445 //-------------------------------------------------------------------------- 446 Any SAL_CALL ODefinitionContainer::getByName( const ::rtl::OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException) 447 { 448 MutexGuard aGuard(m_aMutex); 449 450 return makeAny( implGetByName( _rName, sal_True ) ); 451 } 452 453 //-------------------------------------------------------------------------- 454 Reference< XContent > ODefinitionContainer::implGetByName(const ::rtl::OUString& _rName, sal_Bool _bReadIfNeccessary) throw (NoSuchElementException) 455 { 456 Documents::iterator aMapPos = m_aDocumentMap.find(_rName); 457 if (aMapPos == m_aDocumentMap.end()) 458 throw NoSuchElementException(_rName,*this); 459 460 Reference< XContent > xProp = aMapPos->second; 461 462 if (_bReadIfNeccessary && !xProp.is()) 463 { // the object has never been accessed before, so we have to read it now 464 // (that's the expensive part) 465 466 // create the object and insert it into the map 467 xProp = createObject(_rName); 468 aMapPos->second = xProp; 469 addObjectListener(xProp); 470 } 471 472 return xProp; 473 } 474 475 //-------------------------------------------------------------------------- 476 Sequence< ::rtl::OUString > SAL_CALL ODefinitionContainer::getElementNames( ) throw(RuntimeException) 477 { 478 MutexGuard aGuard(m_aMutex); 479 480 Sequence< ::rtl::OUString > aNames(m_aDocumentMap.size()); 481 ::rtl::OUString* pNames = aNames.getArray(); 482 Documents::iterator aEnd = m_aDocumentMap.end(); 483 for ( Documents::iterator aNameIter = m_aDocumentMap.begin(); 484 aNameIter != aEnd; 485 ++pNames, ++aNameIter 486 ) 487 { 488 *pNames = aNameIter->first; 489 } 490 491 return aNames; 492 } 493 494 //-------------------------------------------------------------------------- 495 sal_Bool SAL_CALL ODefinitionContainer::hasByName( const ::rtl::OUString& _rName ) throw(RuntimeException) 496 { 497 MutexGuard aGuard(m_aMutex); 498 499 return checkExistence(_rName); 500 } 501 502 //-------------------------------------------------------------------------- 503 void SAL_CALL ODefinitionContainer::disposing( const EventObject& _rSource ) throw(RuntimeException) 504 { 505 MutexGuard aGuard(m_aMutex); 506 Reference< XContent > xSource(_rSource.Source, UNO_QUERY); 507 // it's one of our documents .... 508 Documents::iterator aIter = m_aDocumentMap.begin(); 509 Documents::iterator aEnd = m_aDocumentMap.end(); 510 for (;aIter != aEnd;++aIter ) 511 { 512 if ( xSource == aIter->second.get() ) 513 { 514 removeObjectListener(xSource); 515 // and clear our document map/vector, so the object will be recreated on next access 516 aIter->second = Documents::mapped_type(); 517 } 518 } 519 } 520 521 //-------------------------------------------------------------------------- 522 void ODefinitionContainer::implRemove(const ::rtl::OUString& _rName) 523 { 524 // from the object maps 525 Documents::iterator aFind = m_aDocumentMap.find(_rName); 526 if ( aFind != m_aDocumentMap.end() ) 527 { 528 m_aDocuments.erase( ::std::find(m_aDocuments.begin(),m_aDocuments.end(),aFind)); 529 m_aDocumentMap.erase(aFind); 530 531 getDefinitions().erase( _rName ); 532 533 notifyDataSourceModified(); 534 } 535 } 536 537 //-------------------------------------------------------------------------- 538 namespace 539 { 540 bool lcl_ensureName( const Reference< XContent >& _rxContent, const ::rtl::OUString& _rName ) 541 { 542 if ( !_rxContent.is() ) 543 return true; 544 545 // .......................................................... 546 // obtain the current name. If it's the same as the new one, 547 // don't do anything 548 try 549 { 550 Reference< XPropertySet > xProps( _rxContent, UNO_QUERY ); 551 if ( xProps.is() ) 552 { 553 ::rtl::OUString sCurrentName; 554 OSL_VERIFY( xProps->getPropertyValue( PROPERTY_NAME ) >>= sCurrentName ); 555 if ( sCurrentName.equals( _rName ) ) 556 return true; 557 } 558 } 559 catch( const Exception& ) 560 { 561 OSL_ENSURE( sal_False, "lcl_ensureName: caught an exception while obtaining the current name!" ); 562 } 563 564 // .......................................................... 565 // set the new name 566 Reference< XRename > xRename( _rxContent, UNO_QUERY ); 567 OSL_ENSURE( xRename.is(), "lcl_ensureName: invalid content (not renameable)!" ); 568 if ( !xRename.is() ) 569 return false; 570 try 571 { 572 xRename->rename( _rName ); 573 return true; 574 } 575 catch( const Exception& ) 576 { 577 OSL_ENSURE( sal_False, "lcl_ensureName: caught an exception!" ); 578 } 579 return false; 580 } 581 } 582 //-------------------------------------------------------------------------- 583 void ODefinitionContainer::implAppend(const ::rtl::OUString& _rName, const Reference< XContent >& _rxNewObject) 584 { 585 MutexGuard aGuard(m_aMutex); 586 try 587 { 588 Reference<XChild> xChild(_rxNewObject,UNO_QUERY); 589 if ( xChild.is() ) 590 xChild->setParent(static_cast<OWeakObject*>(this)); 591 592 ODefinitionContainer_Impl& rDefinitions( getDefinitions() ); 593 ODefinitionContainer_Impl::const_iterator aFind = rDefinitions.find( _rName ); 594 if ( aFind == rDefinitions.end() ) 595 { 596 // ensure that the new object thas the proper name. 597 // Somebody could create an object with name "foo", and insert it as "bar" 598 // into a container. In this case, we need to ensure that the object name 599 // is also "bar" 600 // #i44786# / 2005-03-11 / frank.schoenheit@sun.com 601 lcl_ensureName( _rxNewObject, _rName ); 602 603 ::rtl::Reference< OContentHelper > pContent = OContentHelper::getImplementation( _rxNewObject ); 604 if ( pContent.is() ) 605 { 606 TContentPtr pImpl = pContent->getImpl(); 607 rDefinitions.erase( pImpl ); 608 pImpl->m_aProps.aTitle = _rName; 609 rDefinitions.insert( _rName, pImpl ); 610 } 611 } 612 613 614 m_aDocuments.push_back(m_aDocumentMap.insert(Documents::value_type(_rName,_rxNewObject)).first); 615 notifyDataSourceModified(); 616 // now update our structures 617 if ( _rxNewObject.is() ) 618 addObjectListener(_rxNewObject); 619 } 620 catch(Exception&) 621 { 622 DBG_ERROR("ODefinitionContainer::implAppend: caught something !"); 623 } 624 } 625 626 //-------------------------------------------------------------------------- 627 void ODefinitionContainer::implReplace(const ::rtl::OUString& _rName, const Reference< XContent >& _rxNewObject) 628 { 629 DBG_ASSERT(checkExistence(_rName), "ODefinitionContainer::implReplace : invalid name !"); 630 631 Documents::iterator aFind = m_aDocumentMap.find(_rName); 632 removeObjectListener(aFind->second); 633 aFind->second = _rxNewObject; 634 addObjectListener(aFind->second); 635 } 636 637 // ----------------------------------------------------------------------------- 638 void ODefinitionContainer::approveNewObject(const ::rtl::OUString& _sName,const Reference< XContent >& _rxObject) const 639 { 640 // check the arguments 641 if ( !_sName.getLength() ) 642 throw IllegalArgumentException( 643 DBA_RES( RID_STR_NAME_MUST_NOT_BE_EMPTY ), 644 *this, 645 0 ); 646 647 if ( m_bCheckSlash && _sName.indexOf( '/' ) != -1 ) 648 throw IllegalArgumentException( 649 m_aErrorHelper.getErrorMessage( ErrorCondition::DB_OBJECT_NAME_WITH_SLASHES ), 650 *this, 651 0 ); 652 653 if ( !_rxObject.is() ) 654 throw IllegalArgumentException( 655 DBA_RES( RID_STR_NO_NULL_OBJECTS_IN_CONTAINER ), 656 *this, 657 0 ); 658 659 const ODefinitionContainer_Impl& rDefinitions( getDefinitions() ); 660 if ( rDefinitions.find( _sName ) != rDefinitions.end() ) 661 throw ElementExistException( 662 DBA_RES( RID_STR_NAME_ALREADY_USED ), 663 *this ); 664 665 ::rtl::Reference< OContentHelper > pContent( OContentHelper::getImplementation( _rxObject ) ); 666 if ( !pContent.is() ) 667 throw IllegalArgumentException( 668 DBA_RES( RID_STR_OBJECT_CONTAINER_MISMATCH ), 669 *this, 670 1 ); 671 672 if ( rDefinitions.find( pContent->getImpl() ) != rDefinitions.end() ) 673 throw ElementExistException( 674 DBA_RES( RID_STR_OBJECT_ALREADY_CONTAINED ), 675 *this ); 676 } 677 678 // ----------------------------------------------------------------------------- 679 // XPropertyChangeListener 680 void SAL_CALL ODefinitionContainer::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException) 681 { 682 ClearableMutexGuard aGuard(m_aMutex); 683 if(evt.PropertyName == (rtl::OUString) PROPERTY_NAME || evt.PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) )) 684 { 685 m_bInPropertyChange = sal_True; 686 try 687 { 688 ::rtl::OUString sNewName,sOldName; 689 evt.OldValue >>= sOldName; 690 evt.NewValue >>= sNewName; 691 Reference<XContent> xContent( evt.Source, UNO_QUERY ); 692 removeObjectListener( xContent ); 693 implRemove( sOldName ); 694 implAppend( sNewName, xContent ); 695 } 696 catch(const Exception&) 697 { 698 DBG_UNHANDLED_EXCEPTION(); 699 throw RuntimeException(); 700 } 701 m_bInPropertyChange = sal_False; 702 } 703 } 704 // ----------------------------------------------------------------------------- 705 // XVetoableChangeListener 706 void SAL_CALL ODefinitionContainer::vetoableChange( const PropertyChangeEvent& aEvent ) throw (PropertyVetoException, RuntimeException) 707 { 708 MutexGuard aGuard(m_aMutex); 709 710 if(aEvent.PropertyName == (rtl::OUString) PROPERTY_NAME || aEvent.PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) ) 711 { 712 ::rtl::OUString sNewName; 713 aEvent.NewValue >>= sNewName; 714 if(hasByName(sNewName)) 715 throw PropertyVetoException(); 716 } 717 } 718 // ----------------------------------------------------------------------------- 719 void ODefinitionContainer::addObjectListener(const Reference< XContent >& _xNewObject) 720 { 721 OSL_ENSURE(_xNewObject.is(),"ODefinitionContainer::addObjectListener: Object is null!"); 722 Reference<XPropertySet> xProp(_xNewObject,UNO_QUERY); 723 if ( xProp.is() ) 724 { 725 xProp->addPropertyChangeListener(PROPERTY_NAME, this); 726 xProp->addVetoableChangeListener(PROPERTY_NAME, this); 727 } 728 } 729 // ----------------------------------------------------------------------------- 730 void ODefinitionContainer::removeObjectListener(const Reference< XContent >& _xNewObject) 731 { 732 Reference<XPropertySet> xProp(_xNewObject,UNO_QUERY); 733 if ( xProp.is() ) 734 { 735 xProp->removePropertyChangeListener(PROPERTY_NAME, this); 736 xProp->removeVetoableChangeListener(PROPERTY_NAME, this); 737 } 738 } 739 // ----------------------------------------------------------------------------- 740 sal_Bool ODefinitionContainer::checkExistence(const ::rtl::OUString& _rName) 741 { 742 return m_aDocumentMap.find(_rName) != m_aDocumentMap.end(); 743 } 744 745 //........................................................................ 746 } 747 // namespace dbaccess 748 //........................................................................ 749