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