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 #include "commandcontainer.hxx" 32 #include "connection.hxx" 33 #include "core_resource.hrc" 34 #include "core_resource.hxx" 35 #include "databasecontext.hxx" 36 #include "databasedocument.hxx" 37 #include "datasource.hxx" 38 #include "dbastrings.hrc" 39 #include "ModelImpl.hxx" 40 #include "userinformation.hxx" 41 #include "sdbcoretools.hxx" 42 43 /** === begin UNO includes === **/ 44 #include <com/sun/star/container/XSet.hpp> 45 #include <com/sun/star/document/MacroExecMode.hpp> 46 #include <com/sun/star/embed/XTransactedObject.hpp> 47 #include <com/sun/star/embed/XTransactionBroadcaster.hpp> 48 #include <com/sun/star/sdb/BooleanComparisonMode.hpp> 49 #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp> 50 #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp> 51 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> 52 #include <com/sun/star/form/XLoadable.hpp> 53 /** === end UNO includes === **/ 54 55 #include <comphelper/interaction.hxx> 56 #include <comphelper/mediadescriptor.hxx> 57 #include <comphelper/seqstream.hxx> 58 #include <comphelper/sequence.hxx> 59 #include <connectivity/dbexception.hxx> 60 #include <cppuhelper/exc_hlp.hxx> 61 #include <cppuhelper/typeprovider.hxx> 62 #include <rtl/digest.h> 63 #include <sfx2/signaturestate.hxx> 64 #include <tools/debug.hxx> 65 #include <tools/diagnose_ex.h> 66 #include <tools/errcode.hxx> 67 #include <tools/urlobj.hxx> 68 #include <unotools/sharedunocomponent.hxx> 69 70 #include <algorithm> 71 72 using namespace ::com::sun::star::document; 73 using namespace ::com::sun::star::sdbc; 74 using namespace ::com::sun::star::sdbcx; 75 using namespace ::com::sun::star::sdb; 76 using namespace ::com::sun::star::beans; 77 using namespace ::com::sun::star::uno; 78 using namespace ::com::sun::star::lang; 79 using namespace ::com::sun::star::embed; 80 using namespace ::com::sun::star::container; 81 using namespace ::com::sun::star::util; 82 using namespace ::com::sun::star::io; 83 using namespace ::com::sun::star::task; 84 using namespace ::com::sun::star::ucb; 85 using namespace ::com::sun::star::frame; 86 using namespace ::com::sun::star::view; 87 using namespace ::com::sun::star::task; 88 using namespace ::com::sun::star::reflection; 89 using namespace ::com::sun::star::script; 90 using namespace ::cppu; 91 using namespace ::osl; 92 using namespace ::vos; 93 using namespace ::dbtools; 94 using namespace ::comphelper; 95 namespace css = ::com::sun::star; 96 97 //........................................................................ 98 namespace dbaccess 99 { 100 //........................................................................ 101 102 //============================================================ 103 //= VosMutexFacade 104 //============================================================ 105 //------------------------------------------------------------------------ 106 VosMutexFacade::VosMutexFacade( ::osl::Mutex& _rMutex ) 107 :m_rMutex( _rMutex ) 108 { 109 } 110 111 //------------------------------------------------------------------------ 112 void SAL_CALL VosMutexFacade::acquire() 113 { 114 m_rMutex.acquire(); 115 } 116 117 //------------------------------------------------------------------------ 118 sal_Bool SAL_CALL VosMutexFacade::tryToAcquire() 119 { 120 return m_rMutex.tryToAcquire(); 121 } 122 123 //------------------------------------------------------------------------ 124 void SAL_CALL VosMutexFacade::release() 125 { 126 m_rMutex.release(); 127 } 128 129 //============================================================ 130 //= DocumentStorageAccess 131 //============================================================ 132 DBG_NAME( DocumentStorageAccess ) 133 class DocumentStorageAccess : public ::cppu::WeakImplHelper2< XDocumentSubStorageSupplier 134 , XTransactionListener > 135 { 136 typedef ::std::map< ::rtl::OUString, Reference< XStorage > > NamedStorages; 137 138 ::osl::Mutex m_aMutex; 139 /// all sub storages which we ever gave to the outer world 140 NamedStorages m_aExposedStorages; 141 ODatabaseModelImpl* m_pModelImplementation; 142 bool m_bPropagateCommitToRoot; 143 bool m_bDisposingSubStorages; 144 145 public: 146 DocumentStorageAccess( ODatabaseModelImpl& _rModelImplementation ) 147 :m_pModelImplementation( &_rModelImplementation ) 148 ,m_bPropagateCommitToRoot( true ) 149 ,m_bDisposingSubStorages( false ) 150 { 151 DBG_CTOR( DocumentStorageAccess, NULL ); 152 } 153 154 protected: 155 ~DocumentStorageAccess() 156 { 157 DBG_DTOR( DocumentStorageAccess, NULL ); 158 } 159 160 public: 161 void dispose(); 162 163 // XDocumentSubStorageSupplier 164 virtual Reference< XStorage > SAL_CALL getDocumentSubStorage( const ::rtl::OUString& aStorageName, ::sal_Int32 _nMode ) throw (RuntimeException); 165 virtual Sequence< ::rtl::OUString > SAL_CALL getDocumentSubStoragesNames( ) throw (IOException, RuntimeException); 166 167 // XTransactionListener 168 virtual void SAL_CALL preCommit( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 169 virtual void SAL_CALL commited( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException); 170 virtual void SAL_CALL preRevert( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); 171 virtual void SAL_CALL reverted( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException); 172 173 // XEventListener 174 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); 175 176 /// disposes all storages managed by this instance 177 void disposeStorages(); 178 179 /// disposes all known sub storages 180 void commitStorages() SAL_THROW(( IOException, RuntimeException )); 181 182 /// commits the dedicated "database" storage 183 bool commitEmbeddedStorage( bool _bPreventRootCommits ); 184 185 private: 186 /** opens the sub storage with the given name, in the given mode 187 */ 188 Reference< XStorage > impl_openSubStorage_nothrow( const ::rtl::OUString& _rStorageName, sal_Int32 _nMode ); 189 190 void impl_suspendCommitPropagation() 191 { 192 OSL_ENSURE( m_bPropagateCommitToRoot, "DocumentStorageAccess::impl_suspendCommitPropagation: already suspended" ); 193 m_bPropagateCommitToRoot = false; 194 } 195 void impl_resumeCommitPropagation() 196 { 197 OSL_ENSURE( !m_bPropagateCommitToRoot, "DocumentStorageAccess::impl_resumeCommitPropagation: not suspended" ); 198 m_bPropagateCommitToRoot = true; 199 } 200 201 }; 202 203 //-------------------------------------------------------------------------- 204 void DocumentStorageAccess::dispose() 205 { 206 ::osl::MutexGuard aGuard( m_aMutex ); 207 208 for ( NamedStorages::iterator loop = m_aExposedStorages.begin(); 209 loop != m_aExposedStorages.end(); 210 ++loop 211 ) 212 { 213 try 214 { 215 Reference< XTransactionBroadcaster > xBroadcaster( loop->second, UNO_QUERY ); 216 if ( xBroadcaster.is() ) 217 xBroadcaster->removeTransactionListener( this ); 218 } 219 catch( const Exception& ) 220 { 221 DBG_UNHANDLED_EXCEPTION(); 222 } 223 } 224 225 m_aExposedStorages.clear(); 226 227 m_pModelImplementation = NULL; 228 } 229 230 //-------------------------------------------------------------------------- 231 Reference< XStorage > DocumentStorageAccess::impl_openSubStorage_nothrow( const ::rtl::OUString& _rStorageName, sal_Int32 _nDesiredMode ) 232 { 233 OSL_ENSURE( _rStorageName.getLength(),"ODatabaseModelImpl::impl_openSubStorage_nothrow: Invalid storage name!" ); 234 235 Reference< XStorage > xStorage; 236 try 237 { 238 Reference< XStorage > xRootStorage( m_pModelImplementation->getOrCreateRootStorage() ); 239 if ( xRootStorage.is() ) 240 { 241 sal_Int32 nRealMode = m_pModelImplementation->m_bDocumentReadOnly ? ElementModes::READ : _nDesiredMode; 242 if ( nRealMode == ElementModes::READ ) 243 { 244 Reference< XNameAccess > xSubStorageNames( xRootStorage, UNO_QUERY ); 245 if ( xSubStorageNames.is() && !xSubStorageNames->hasByName( _rStorageName ) ) 246 return xStorage; 247 } 248 249 xStorage = xRootStorage->openStorageElement( _rStorageName, nRealMode ); 250 251 Reference< XTransactionBroadcaster > xBroad( xStorage, UNO_QUERY ); 252 if ( xBroad.is() ) 253 xBroad->addTransactionListener( this ); 254 } 255 } 256 catch( const Exception& ) 257 { 258 DBG_UNHANDLED_EXCEPTION(); 259 } 260 261 return xStorage; 262 } 263 264 //-------------------------------------------------------------------------- 265 void DocumentStorageAccess::disposeStorages() 266 { 267 m_bDisposingSubStorages = true; 268 269 NamedStorages::iterator aEnd = m_aExposedStorages.end(); 270 for ( NamedStorages::iterator aIter = m_aExposedStorages.begin(); 271 aIter != aEnd ; 272 ++aIter 273 ) 274 { 275 try 276 { 277 ::comphelper::disposeComponent( aIter->second ); 278 } 279 catch( const Exception& ) 280 { 281 DBG_UNHANDLED_EXCEPTION(); 282 } 283 } 284 m_aExposedStorages.clear(); 285 286 m_bDisposingSubStorages = false; 287 } 288 289 //-------------------------------------------------------------------------- 290 void DocumentStorageAccess::commitStorages() SAL_THROW(( IOException, RuntimeException )) 291 { 292 try 293 { 294 for ( NamedStorages::const_iterator aIter = m_aExposedStorages.begin(); 295 aIter != m_aExposedStorages.end(); 296 ++aIter 297 ) 298 { 299 tools::stor::commitStorageIfWriteable( aIter->second ); 300 } 301 } 302 catch(const WrappedTargetException&) 303 { 304 // WrappedTargetException not allowed to leave 305 throw IOException(); 306 } 307 } 308 309 //-------------------------------------------------------------------------- 310 bool DocumentStorageAccess::commitEmbeddedStorage( bool _bPreventRootCommits ) 311 { 312 if ( _bPreventRootCommits ) 313 impl_suspendCommitPropagation(); 314 315 bool bSuccess = false; 316 try 317 { 318 NamedStorages::const_iterator pos = m_aExposedStorages.find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "database" ) ) ); 319 if ( pos != m_aExposedStorages.end() ) 320 bSuccess = tools::stor::commitStorageIfWriteable( pos->second ); 321 } 322 catch( Exception& ) 323 { 324 DBG_UNHANDLED_EXCEPTION(); 325 } 326 327 if ( _bPreventRootCommits ) 328 impl_resumeCommitPropagation(); 329 330 return bSuccess; 331 332 } 333 334 //-------------------------------------------------------------------------- 335 Reference< XStorage > SAL_CALL DocumentStorageAccess::getDocumentSubStorage( const ::rtl::OUString& aStorageName, ::sal_Int32 _nDesiredMode ) throw (RuntimeException) 336 { 337 ::osl::MutexGuard aGuard( m_aMutex ); 338 NamedStorages::iterator pos = m_aExposedStorages.find( aStorageName ); 339 if ( pos == m_aExposedStorages.end() ) 340 { 341 Reference< XStorage > xResult = impl_openSubStorage_nothrow( aStorageName, _nDesiredMode ); 342 pos = m_aExposedStorages.insert( NamedStorages::value_type( aStorageName, xResult ) ).first; 343 } 344 345 return pos->second; 346 } 347 348 //-------------------------------------------------------------------------- 349 Sequence< ::rtl::OUString > SAL_CALL DocumentStorageAccess::getDocumentSubStoragesNames( ) throw (IOException, RuntimeException) 350 { 351 Reference< XStorage > xRootStor( m_pModelImplementation->getRootStorage() ); 352 if ( !xRootStor.is() ) 353 return Sequence< ::rtl::OUString >(); 354 355 ::std::vector< ::rtl::OUString > aNames; 356 357 Reference< XNameAccess > xNames( xRootStor, UNO_QUERY_THROW ); 358 Sequence< ::rtl::OUString > aElementNames( xNames->getElementNames() ); 359 for ( sal_Int32 i=0; i<aElementNames.getLength(); ++i ) 360 { 361 if ( xRootStor->isStorageElement( aElementNames[i] ) ) 362 aNames.push_back( aElementNames[i] ); 363 } 364 return aNames.empty() 365 ? Sequence< ::rtl::OUString >() 366 : Sequence< ::rtl::OUString >( &aNames[0], aNames.size() ); 367 } 368 369 //-------------------------------------------------------------------------- 370 void SAL_CALL DocumentStorageAccess::preCommit( const css::lang::EventObject& /*aEvent*/ ) throw (Exception, RuntimeException) 371 { 372 // not interested in 373 } 374 375 //-------------------------------------------------------------------------- 376 void SAL_CALL DocumentStorageAccess::commited( const css::lang::EventObject& aEvent ) throw (RuntimeException) 377 { 378 ::osl::MutexGuard aGuard( m_aMutex ); 379 380 if ( m_pModelImplementation ) 381 m_pModelImplementation->setModified( sal_True ); 382 383 if ( m_pModelImplementation && m_bPropagateCommitToRoot ) 384 { 385 Reference< XStorage > xStorage( aEvent.Source, UNO_QUERY ); 386 387 // check if this is the dedicated "database" sub storage 388 NamedStorages::const_iterator pos = m_aExposedStorages.find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "database" ) ) ); 389 if ( ( pos != m_aExposedStorages.end() ) 390 && ( pos->second == xStorage ) 391 ) 392 { 393 // if so, also commit the root storage 394 m_pModelImplementation->commitRootStorage(); 395 } 396 } 397 } 398 399 //-------------------------------------------------------------------------- 400 void SAL_CALL DocumentStorageAccess::preRevert( const css::lang::EventObject& /*aEvent*/ ) throw (Exception, RuntimeException) 401 { 402 // not interested in 403 } 404 405 //-------------------------------------------------------------------------- 406 void SAL_CALL DocumentStorageAccess::reverted( const css::lang::EventObject& /*aEvent*/ ) throw (RuntimeException) 407 { 408 // not interested in 409 } 410 411 //-------------------------------------------------------------------------- 412 void SAL_CALL DocumentStorageAccess::disposing( const css::lang::EventObject& Source ) throw ( RuntimeException ) 413 { 414 OSL_ENSURE( Reference< XStorage >( Source.Source, UNO_QUERY ).is(), "DocumentStorageAccess::disposing: No storage? What's this?" ); 415 416 if ( m_bDisposingSubStorages ) 417 return; 418 419 for ( NamedStorages::iterator find = m_aExposedStorages.begin(); 420 find != m_aExposedStorages.end(); 421 ++find 422 ) 423 if ( find->second == Source.Source ) 424 { 425 m_aExposedStorages.erase( find ); 426 break; 427 } 428 } 429 430 //============================================================ 431 //= ODatabaseModelImpl 432 //============================================================ 433 DBG_NAME(ODatabaseModelImpl) 434 //-------------------------------------------------------------------------- 435 ODatabaseModelImpl::ODatabaseModelImpl( const Reference< XMultiServiceFactory >& _rxFactory, ODatabaseContext& _rDBContext ) 436 :m_xModel() 437 ,m_xDataSource() 438 ,m_pStorageAccess( NULL ) 439 ,m_aMutex() 440 ,m_aMutexFacade( m_aMutex ) 441 ,m_aContainer(4) 442 ,m_aMacroMode( *this ) 443 ,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE ) 444 ,m_pDBContext( &_rDBContext ) 445 ,m_refCount(0) 446 ,m_aEmbeddedMacros() 447 ,m_bModificationLock( false ) 448 ,m_bDocumentInitialized( false ) 449 ,m_aContext( _rxFactory ) 450 ,m_nLoginTimeout(0) 451 ,m_bReadOnly(sal_False) 452 ,m_bPasswordRequired(sal_False) 453 ,m_bSuppressVersionColumns(sal_True) 454 ,m_bModified(sal_False) 455 ,m_bDocumentReadOnly(sal_False) 456 ,m_pSharedConnectionManager(NULL) 457 ,m_nControllerLockCount(0) 458 { 459 // some kind of default 460 DBG_CTOR(ODatabaseModelImpl,NULL); 461 m_sConnectURL = ::rtl::OUString::createFromAscii("jdbc:"); 462 m_aTableFilter.realloc(1); 463 m_aTableFilter[0] = ::rtl::OUString::createFromAscii("%"); 464 impl_construct_nothrow(); 465 } 466 467 //-------------------------------------------------------------------------- 468 ODatabaseModelImpl::ODatabaseModelImpl( 469 const ::rtl::OUString& _rRegistrationName, 470 const Reference< XMultiServiceFactory >& _rxFactory, 471 ODatabaseContext& _rDBContext 472 ) 473 :m_xModel() 474 ,m_xDataSource() 475 ,m_pStorageAccess( NULL ) 476 ,m_aMutex() 477 ,m_aMutexFacade( m_aMutex ) 478 ,m_aContainer(4) 479 ,m_aMacroMode( *this ) 480 ,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE ) 481 ,m_pDBContext( &_rDBContext ) 482 ,m_refCount(0) 483 ,m_aEmbeddedMacros() 484 ,m_bModificationLock( false ) 485 ,m_bDocumentInitialized( false ) 486 ,m_aContext( _rxFactory ) 487 ,m_sName(_rRegistrationName) 488 ,m_nLoginTimeout(0) 489 ,m_bReadOnly(sal_False) 490 ,m_bPasswordRequired(sal_False) 491 ,m_bSuppressVersionColumns(sal_True) 492 ,m_bModified(sal_False) 493 ,m_bDocumentReadOnly(sal_False) 494 ,m_pSharedConnectionManager(NULL) 495 ,m_nControllerLockCount(0) 496 { 497 DBG_CTOR(ODatabaseModelImpl,NULL); 498 impl_construct_nothrow(); 499 } 500 501 //-------------------------------------------------------------------------- 502 ODatabaseModelImpl::~ODatabaseModelImpl() 503 { 504 DBG_DTOR(ODatabaseModelImpl,NULL); 505 } 506 507 // ----------------------------------------------------------------------------- 508 void ODatabaseModelImpl::impl_construct_nothrow() 509 { 510 // create the property bag to hold the settings (also known as "Info" property) 511 try 512 { 513 // the set of property value types in the bag is limited: 514 Sequence< Type > aAllowedTypes(6); 515 Type* pAllowedType = aAllowedTypes.getArray(); 516 *pAllowedType++ = ::getCppuType( static_cast< sal_Bool* >( NULL ) ); 517 *pAllowedType++ = ::getCppuType( static_cast< double* >( NULL ) ); 518 *pAllowedType++ = ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ); 519 *pAllowedType++ = ::getCppuType( static_cast< sal_Int32* >( NULL ) ); 520 *pAllowedType++ = ::getCppuType( static_cast< sal_Int16* >( NULL ) ); 521 *pAllowedType++ = ::getCppuType( static_cast< Sequence< Any >* >( NULL ) ); 522 523 Sequence< Any > aInitArgs( 2 ); 524 aInitArgs[0] <<= NamedValue( 525 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutomaticAddition" ) ), 526 makeAny( (sal_Bool)sal_True ) 527 ); 528 aInitArgs[1] <<= NamedValue( 529 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowedTypes" ) ), 530 makeAny( aAllowedTypes ) 531 ); 532 533 m_xSettings.set( m_aContext.createComponentWithArguments( "com.sun.star.beans.PropertyBag", aInitArgs ), UNO_QUERY_THROW ); 534 535 // insert the default settings 536 Reference< XPropertyContainer > xContainer( m_xSettings, UNO_QUERY_THROW ); 537 Reference< XSet > xSettingsSet( m_xSettings, UNO_QUERY_THROW ); 538 const AsciiPropertyValue* pSettings = getDefaultDataSourceSettings(); 539 for ( ; pSettings->AsciiName; ++pSettings ) 540 { 541 if ( !pSettings->DefaultValue.hasValue() ) 542 { 543 Property aProperty( 544 ::rtl::OUString::createFromAscii( pSettings->AsciiName ), 545 -1, 546 pSettings->ValueType, 547 PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT | PropertyAttribute::MAYBEVOID 548 ); 549 xSettingsSet->insert( makeAny( aProperty ) ); 550 } 551 else 552 { 553 xContainer->addProperty( 554 ::rtl::OUString::createFromAscii( pSettings->AsciiName ), 555 PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT, 556 pSettings->DefaultValue 557 ); 558 } 559 } 560 } 561 catch( const Exception& ) 562 { 563 DBG_UNHANDLED_EXCEPTION(); 564 } 565 m_pDBContext->appendAtTerminateListener(*this); 566 } 567 568 // ----------------------------------------------------------------------------- 569 namespace 570 { 571 // ......................................................................... 572 ::rtl::OUString lcl_getContainerStorageName_throw( ODatabaseModelImpl::ObjectType _eType ) 573 { 574 const sal_Char* pAsciiName( NULL ); 575 switch ( _eType ) 576 { 577 case ODatabaseModelImpl::E_FORM: pAsciiName = "forms"; break; 578 case ODatabaseModelImpl::E_REPORT: pAsciiName = "reports"; break; 579 case ODatabaseModelImpl::E_QUERY: pAsciiName = "queries"; break; 580 case ODatabaseModelImpl::E_TABLE: pAsciiName = "tables"; break; 581 default: 582 throw RuntimeException(); 583 } 584 return ::rtl::OUString::createFromAscii( pAsciiName ); 585 } 586 587 // ......................................................................... 588 bool lcl_hasObjectWithMacros_throw( const ODefinitionContainer_Impl& _rObjectDefinitions, const Reference< XStorage >& _rxContainerStorage ) 589 { 590 bool bSomeDocHasMacros = false; 591 592 for ( ODefinitionContainer_Impl::const_iterator object = _rObjectDefinitions.begin(); 593 ( object != _rObjectDefinitions.end() ) && !bSomeDocHasMacros; 594 ++object 595 ) 596 { 597 #if OSL_DEBUG_LEVEL > 0 598 const ::rtl::OUString& rName( object->first ); (void)rName; 599 #endif 600 601 const TContentPtr& rDefinition( object->second ); 602 const ::rtl::OUString& rPersistentName( rDefinition->m_aProps.sPersistentName ); 603 604 if ( !rPersistentName.getLength() ) 605 { // it's a logical sub folder used to organize the real objects 606 const ODefinitionContainer_Impl& rSubFoldersObjectDefinitions( dynamic_cast< const ODefinitionContainer_Impl& >( *rDefinition.get() ) ); 607 bSomeDocHasMacros = lcl_hasObjectWithMacros_throw( rSubFoldersObjectDefinitions, _rxContainerStorage ); 608 continue; 609 } 610 611 bSomeDocHasMacros = ODatabaseModelImpl::objectHasMacros( _rxContainerStorage, rPersistentName ); 612 } 613 return bSomeDocHasMacros; 614 } 615 616 // ......................................................................... 617 bool lcl_hasObjectsWithMacros_nothrow( ODatabaseModelImpl& _rModel, const ODatabaseModelImpl::ObjectType _eType ) 618 { 619 bool bSomeDocHasMacros = false; 620 621 const OContentHelper_Impl& rContainerData( *_rModel.getObjectContainer( _eType ).get() ); 622 const ODefinitionContainer_Impl& rObjectDefinitions = dynamic_cast< const ODefinitionContainer_Impl& >( rContainerData ); 623 624 try 625 { 626 Reference< XStorage > xContainerStorage( _rModel.getStorage( _eType, ElementModes::READWRITE ) ); 627 // note the READWRITE here: If the storage already existed before, then the OpenMode will 628 // be ignored, anyway. 629 // If the storage did not yet exist, then it will be created. If the database document 630 // is read-only, the OpenMode will be automatically downgraded to READ. Otherwise, 631 // the storage will in fact be created as READWRITE. While this is not strictly necessary 632 // for this particular use case here, it is required since the storage is *cached*, and 633 // later use cases will need the READWRITE mode. 634 635 if ( xContainerStorage.is() ) 636 bSomeDocHasMacros = lcl_hasObjectWithMacros_throw( rObjectDefinitions, xContainerStorage ); 637 } 638 catch( const Exception& ) 639 { 640 DBG_UNHANDLED_EXCEPTION(); 641 // be on the safe side: If we can't reliably determine whether there are macros, 642 // assume there actually are. Better this way, than the other way round. 643 bSomeDocHasMacros = true; 644 } 645 646 return bSomeDocHasMacros; 647 } 648 } 649 650 // ----------------------------------------------------------------------------- 651 bool ODatabaseModelImpl::objectHasMacros( const Reference< XStorage >& _rxContainerStorage, const ::rtl::OUString& _rPersistentName ) 652 { 653 OSL_PRECOND( _rxContainerStorage.is(), "ODatabaseModelImpl::objectHasMacros: this will crash!" ); 654 655 bool bHasMacros = true; 656 try 657 { 658 if ( !_rxContainerStorage->hasByName( _rPersistentName ) ) 659 return false; 660 661 Reference< XStorage > xObjectStor( _rxContainerStorage->openStorageElement( 662 _rPersistentName, ElementModes::READ ) ); 663 664 bHasMacros = ::sfx2::DocumentMacroMode::storageHasMacros( xObjectStor ); 665 } 666 catch( const Exception& ) 667 { 668 DBG_UNHANDLED_EXCEPTION(); 669 } 670 return bHasMacros; 671 } 672 673 // ----------------------------------------------------------------------------- 674 void ODatabaseModelImpl::reset() 675 { 676 m_bReadOnly = sal_False; 677 ::std::vector< TContentPtr > aEmptyContainers( 4 ); 678 m_aContainer.swap( aEmptyContainers ); 679 680 if ( m_pStorageAccess ) 681 { 682 m_pStorageAccess->dispose(); 683 m_pStorageAccess->release(); 684 m_pStorageAccess = NULL; 685 } 686 } 687 // ----------------------------------------------------------------------------- 688 void SAL_CALL ODatabaseModelImpl::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException) 689 { 690 Reference<XConnection> xCon(Source.Source,UNO_QUERY); 691 if ( xCon.is() ) 692 { 693 bool bStore = false; 694 OWeakConnectionArray::iterator aEnd = m_aConnections.end(); 695 for (OWeakConnectionArray::iterator i = m_aConnections.begin(); aEnd != i; ++i) 696 { 697 if ( xCon == i->get() ) 698 { 699 *i = OWeakConnection(); 700 bStore = true; 701 break; 702 } 703 } 704 705 if ( bStore ) 706 commitRootStorage(); 707 } 708 else 709 { 710 OSL_ENSURE( false, "ODatabaseModelImpl::disposing: where does this come from?" ); 711 } 712 } 713 //------------------------------------------------------------------------------ 714 void ODatabaseModelImpl::clearConnections() 715 { 716 OWeakConnectionArray aConnections; 717 aConnections.swap( m_aConnections ); 718 719 Reference< XConnection > xConn; 720 OWeakConnectionArray::iterator aEnd = aConnections.end(); 721 for ( OWeakConnectionArray::iterator i = aConnections.begin(); aEnd != i; ++i ) 722 { 723 xConn = *i; 724 if ( xConn.is() ) 725 { 726 try 727 { 728 xConn->close(); 729 } 730 catch(const Exception&) 731 { 732 DBG_UNHANDLED_EXCEPTION(); 733 } 734 } 735 } 736 737 m_pSharedConnectionManager = NULL; 738 m_xSharedConnectionManager = NULL; 739 } 740 //------------------------------------------------------------------------------ 741 void ODatabaseModelImpl::dispose() 742 { 743 // dispose the data source and the model 744 try 745 { 746 Reference< XDataSource > xDS( m_xDataSource ); 747 ::comphelper::disposeComponent( xDS ); 748 749 Reference< XModel > xModel( m_xModel ); 750 ::comphelper::disposeComponent( xModel ); 751 } 752 catch( const Exception& ) 753 { 754 DBG_UNHANDLED_EXCEPTION(); 755 } 756 m_xDataSource = WeakReference<XDataSource>(); 757 m_xModel = WeakReference< XModel >(); 758 759 ::std::vector<TContentPtr>::iterator aIter = m_aContainer.begin(); 760 ::std::vector<TContentPtr>::iterator aEnd = m_aContainer.end(); 761 for (;aIter != aEnd ; ++aIter) 762 { 763 if ( aIter->get() ) 764 (*aIter)->m_pDataSource = NULL; 765 } 766 m_aContainer.clear(); 767 768 clearConnections(); 769 770 m_xNumberFormatsSupplier = NULL; 771 772 try 773 { 774 sal_Bool bCouldStore = commitEmbeddedStorage( true ); 775 // "true" means that committing the embedded storage should not trigger committing the root 776 // storage. This is because we are going to commit the root storage ourself, anyway 777 disposeStorages(); 778 if ( bCouldStore ) 779 commitRootStorage(); 780 781 impl_switchToStorage_throw( NULL ); 782 } 783 catch( const Exception& ) 784 { 785 DBG_UNHANDLED_EXCEPTION(); 786 } 787 788 if ( m_pStorageAccess ) 789 { 790 m_pStorageAccess->dispose(); 791 m_pStorageAccess->release(); 792 m_pStorageAccess = NULL; 793 } 794 } 795 // ----------------------------------------------------------------------------- 796 const Reference< XNumberFormatsSupplier > & ODatabaseModelImpl::getNumberFormatsSupplier() 797 { 798 if (!m_xNumberFormatsSupplier.is()) 799 { 800 // the arguments : the locale of the current user 801 UserInformation aUserInfo; 802 Sequence< Any > aArguments(1); 803 aArguments.getArray()[0] <<= aUserInfo.getUserLanguage(); 804 805 m_xNumberFormatsSupplier.set( 806 m_aContext.createComponentWithArguments( "com.sun.star.util.NumberFormatsSupplier", aArguments ), UNO_QUERY_THROW ); 807 DBG_ASSERT(m_xNumberFormatsSupplier.is(), "ODatabaseModelImpl::getNumberFormatsSupplier : could not instantiate the formats supplier !"); 808 } 809 return m_xNumberFormatsSupplier; 810 } 811 812 // ----------------------------------------------------------------------------- 813 void ODatabaseModelImpl::setDocFileLocation( const ::rtl::OUString& i_rLoadedFrom ) 814 { 815 ENSURE_OR_THROW( i_rLoadedFrom.getLength(), "invalid URL" ); 816 m_sDocFileLocation = i_rLoadedFrom; 817 } 818 819 // ----------------------------------------------------------------------------- 820 void ODatabaseModelImpl::setResource( const ::rtl::OUString& i_rDocumentURL, const Sequence< PropertyValue >& _rArgs ) 821 { 822 ENSURE_OR_THROW( i_rDocumentURL.getLength(), "invalid URL" ); 823 824 ::comphelper::NamedValueCollection aMediaDescriptor( _rArgs ); 825 #if OSL_DEBUG_LEVEL > 0 826 if ( aMediaDescriptor.has( "SalvagedFile" ) ) 827 { 828 ::rtl::OUString sSalvagedFile( aMediaDescriptor.getOrDefault( "SalvagedFile", ::rtl::OUString() ) ); 829 // If SalvagedFile is an empty string, this indicates "the document is being recovered, but i_rDocumentURL already 830 // is the real document URL, not the temporary document location" 831 if ( !sSalvagedFile.getLength() ) 832 sSalvagedFile = i_rDocumentURL; 833 834 OSL_ENSURE( sSalvagedFile == i_rDocumentURL, "ODatabaseModelImpl::setResource: inconsistency!" ); 835 // nowadays, setResource should only be called with the logical URL of the document 836 } 837 #endif 838 839 m_aMediaDescriptor = stripLoadArguments( aMediaDescriptor ); 840 841 impl_switchToLogicalURL( i_rDocumentURL ); 842 } 843 844 // ----------------------------------------------------------------------------- 845 ::comphelper::NamedValueCollection ODatabaseModelImpl::stripLoadArguments( const ::comphelper::NamedValueCollection& _rArguments ) 846 { 847 OSL_ENSURE( !_rArguments.has( "Model" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (1)!" ); 848 OSL_ENSURE( !_rArguments.has( "ViewName" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (2)!" ); 849 850 ::comphelper::NamedValueCollection aMutableArgs( _rArguments ); 851 aMutableArgs.remove( "Model" ); 852 aMutableArgs.remove( "ViewName" ); 853 return aMutableArgs; 854 } 855 856 // ----------------------------------------------------------------------------- 857 void ODatabaseModelImpl::disposeStorages() SAL_THROW(()) 858 { 859 getDocumentStorageAccess()->disposeStorages(); 860 } 861 862 // ----------------------------------------------------------------------------- 863 Reference< XSingleServiceFactory > ODatabaseModelImpl::createStorageFactory() const 864 { 865 return Reference< XSingleServiceFactory >( m_aContext.createComponent( "com.sun.star.embed.StorageFactory" ), UNO_QUERY_THROW ); 866 } 867 // ----------------------------------------------------------------------------- 868 void ODatabaseModelImpl::commitRootStorage() 869 { 870 Reference< XStorage > xStorage( getOrCreateRootStorage() ); 871 #if OSL_DEBUG_LEVEL > 0 872 bool bSuccess = 873 #endif 874 commitStorageIfWriteable_ignoreErrors( xStorage ); 875 OSL_ENSURE( bSuccess || !xStorage.is(), 876 "ODatabaseModelImpl::commitRootStorage: could commit the storage!" ); 877 } 878 // ----------------------------------------------------------------------------- 879 Reference< XStorage > ODatabaseModelImpl::getOrCreateRootStorage() 880 { 881 if ( !m_xDocumentStorage.is() ) 882 { 883 Reference< XSingleServiceFactory> xStorageFactory = createStorageFactory(); 884 if ( xStorageFactory.is() ) 885 { 886 Any aSource; 887 aSource = m_aMediaDescriptor.get( "Stream" ); 888 if ( !aSource.hasValue() ) 889 aSource = m_aMediaDescriptor.get( "InputStream" ); 890 if ( !aSource.hasValue() && m_sDocFileLocation.getLength() ) 891 aSource <<= m_sDocFileLocation; 892 // TODO: shouldn't we also check URL? 893 894 OSL_ENSURE( aSource.hasValue(), "ODatabaseModelImpl::getOrCreateRootStorage: no source to create the storage from!" ); 895 896 if ( aSource.hasValue() ) 897 { 898 Sequence< Any > aStorageCreationArgs(2); 899 aStorageCreationArgs[0] = aSource; 900 aStorageCreationArgs[1] <<= ElementModes::READWRITE; 901 902 Reference< XStorage > xDocumentStorage; 903 try 904 { 905 xDocumentStorage.set( xStorageFactory->createInstanceWithArguments( aStorageCreationArgs ), UNO_QUERY_THROW ); 906 } 907 catch( const Exception& ) 908 { 909 m_bDocumentReadOnly = sal_True; 910 aStorageCreationArgs[1] <<= ElementModes::READ; 911 try 912 { 913 xDocumentStorage.set( xStorageFactory->createInstanceWithArguments( aStorageCreationArgs ), UNO_QUERY_THROW ); 914 } 915 catch( const Exception& ) 916 { 917 DBG_UNHANDLED_EXCEPTION(); 918 } 919 } 920 921 impl_switchToStorage_throw( xDocumentStorage ); 922 } 923 } 924 } 925 return m_xDocumentStorage.getTyped(); 926 } 927 // ----------------------------------------------------------------------------- 928 DocumentStorageAccess* ODatabaseModelImpl::getDocumentStorageAccess() 929 { 930 if ( !m_pStorageAccess ) 931 { 932 m_pStorageAccess = new DocumentStorageAccess( *this ); 933 m_pStorageAccess->acquire(); 934 } 935 return m_pStorageAccess; 936 } 937 938 // ----------------------------------------------------------------------------- 939 void ODatabaseModelImpl::modelIsDisposing( const bool _wasInitialized, ResetModelAccess ) 940 { 941 m_xModel = Reference< XModel >(); 942 943 // Basic libraries and Dialog libraries are a model facet, though held at this impl class. 944 // They automatically dispose themself when the model they belong to is being disposed. 945 // So, to not be tempted to do anything with them, again, we reset them. 946 m_xBasicLibraries.clear(); 947 m_xDialogLibraries.clear(); 948 949 m_bDocumentInitialized = _wasInitialized; 950 } 951 952 // ----------------------------------------------------------------------------- 953 Reference< XDocumentSubStorageSupplier > ODatabaseModelImpl::getDocumentSubStorageSupplier() 954 { 955 return getDocumentStorageAccess(); 956 } 957 958 // ----------------------------------------------------------------------------- 959 bool ODatabaseModelImpl::commitEmbeddedStorage( bool _bPreventRootCommits ) 960 { 961 return getDocumentStorageAccess()->commitEmbeddedStorage( _bPreventRootCommits ); 962 } 963 964 // ----------------------------------------------------------------------------- 965 bool ODatabaseModelImpl::commitStorageIfWriteable_ignoreErrors( const Reference< XStorage >& _rxStorage ) SAL_THROW(()) 966 { 967 bool bSuccess = false; 968 try 969 { 970 bSuccess = tools::stor::commitStorageIfWriteable( _rxStorage ); 971 } 972 catch( const Exception& ) 973 { 974 DBG_UNHANDLED_EXCEPTION(); 975 } 976 return bSuccess; 977 } 978 // ----------------------------------------------------------------------------- 979 void ODatabaseModelImpl::setModified( sal_Bool _bModified ) 980 { 981 if ( isModifyLocked() ) 982 return; 983 984 try 985 { 986 Reference< XModifiable > xModi( m_xModel.get(), UNO_QUERY ); 987 if ( xModi.is() ) 988 xModi->setModified( _bModified ); 989 else 990 m_bModified = _bModified; 991 } 992 catch( const Exception& ) 993 { 994 DBG_UNHANDLED_EXCEPTION(); 995 } 996 } 997 998 // ----------------------------------------------------------------------------- 999 Reference<XDataSource> ODatabaseModelImpl::getOrCreateDataSource() 1000 { 1001 Reference<XDataSource> xDs = m_xDataSource; 1002 if ( !xDs.is() ) 1003 { 1004 xDs = new ODatabaseSource(this); 1005 m_xDataSource = xDs; 1006 } 1007 return xDs; 1008 } 1009 // ----------------------------------------------------------------------------- 1010 Reference< XModel> ODatabaseModelImpl::getModel_noCreate() const 1011 { 1012 return m_xModel; 1013 } 1014 // ----------------------------------------------------------------------------- 1015 Reference< XModel > ODatabaseModelImpl::createNewModel_deliverOwnership( bool _bInitialize ) 1016 { 1017 Reference< XModel > xModel( m_xModel ); 1018 OSL_PRECOND( !xModel.is(), "ODatabaseModelImpl::createNewModel_deliverOwnership: not to be called if there already is a model!" ); 1019 if ( !xModel.is() ) 1020 { 1021 bool bHadModelBefore = m_bDocumentInitialized; 1022 1023 xModel = ODatabaseDocument::createDatabaseDocument( this, ODatabaseDocument::FactoryAccess() ); 1024 m_xModel = xModel; 1025 1026 try 1027 { 1028 Reference< XSet > xModelCollection; 1029 if ( m_aContext.createComponent( "com.sun.star.frame.GlobalEventBroadcaster", xModelCollection ) ) 1030 xModelCollection->insert( makeAny( xModel ) ); 1031 } 1032 catch( const Exception& ) 1033 { 1034 DBG_UNHANDLED_EXCEPTION(); 1035 } 1036 1037 if ( bHadModelBefore ) 1038 { 1039 // do an attachResources 1040 // In case the document is loaded regularly, this is not necessary, as our loader will do it. 1041 // However, in case that the document is implicitly created by asking the data source for the document, 1042 // then nobody would call the doc's attachResource. So, we do it here, to ensure it's in a proper 1043 // state, fires all events, and so on. 1044 // #i105505# / 2009-10-02 / frank.schoenheit@sun.com 1045 xModel->attachResource( xModel->getURL(), m_aMediaDescriptor.getPropertyValues() ); 1046 } 1047 1048 if ( _bInitialize ) 1049 { 1050 try 1051 { 1052 Reference< XLoadable > xLoad( xModel, UNO_QUERY_THROW ); 1053 xLoad->initNew(); 1054 } 1055 catch( RuntimeException& ) { throw; } 1056 catch( const Exception& ) 1057 { 1058 DBG_UNHANDLED_EXCEPTION(); 1059 } 1060 } 1061 } 1062 return xModel; 1063 } 1064 // ----------------------------------------------------------------------------- 1065 oslInterlockedCount SAL_CALL ODatabaseModelImpl::acquire() 1066 { 1067 return osl_incrementInterlockedCount(&m_refCount); 1068 } 1069 // ----------------------------------------------------------------------------- 1070 oslInterlockedCount SAL_CALL ODatabaseModelImpl::release() 1071 { 1072 if ( osl_decrementInterlockedCount(&m_refCount) == 0 ) 1073 { 1074 acquire(); // prevent multiple releases 1075 m_pDBContext->removeFromTerminateListener(*this); 1076 dispose(); 1077 m_pDBContext->storeTransientProperties(*this); 1078 revokeDataSource(); 1079 delete this; 1080 return 0; 1081 } 1082 return m_refCount; 1083 } 1084 // ----------------------------------------------------------------------------- 1085 void ODatabaseModelImpl::commitStorages() SAL_THROW(( IOException, RuntimeException )) 1086 { 1087 getDocumentStorageAccess()->commitStorages(); 1088 } 1089 1090 // ----------------------------------------------------------------------------- 1091 Reference< XStorage > ODatabaseModelImpl::getStorage( const ObjectType _eType, const sal_Int32 _nDesiredMode ) 1092 { 1093 return getDocumentStorageAccess()->getDocumentSubStorage( getObjectContainerStorageName( _eType ), _nDesiredMode ); 1094 } 1095 1096 // ----------------------------------------------------------------------------- 1097 const AsciiPropertyValue* ODatabaseModelImpl::getDefaultDataSourceSettings() 1098 { 1099 static const AsciiPropertyValue aKnownSettings[] = 1100 { 1101 // known JDBC settings 1102 AsciiPropertyValue( "JavaDriverClass", makeAny( ::rtl::OUString() ) ), 1103 AsciiPropertyValue( "JavaDriverClassPath", makeAny( ::rtl::OUString() ) ), 1104 AsciiPropertyValue( "IgnoreCurrency", makeAny( (sal_Bool)sal_False ) ), 1105 // known settings for file-based drivers 1106 AsciiPropertyValue( "Extension", makeAny( ::rtl::OUString() ) ), 1107 AsciiPropertyValue( "CharSet", makeAny( ::rtl::OUString() ) ), 1108 AsciiPropertyValue( "HeaderLine", makeAny( (sal_Bool)sal_True ) ), 1109 AsciiPropertyValue( "FieldDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "," ) ) ) ), 1110 AsciiPropertyValue( "StringDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\"" ) ) ) ), 1111 AsciiPropertyValue( "DecimalDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) ) ) ), 1112 AsciiPropertyValue( "ThousandDelimiter", makeAny( ::rtl::OUString() ) ), 1113 AsciiPropertyValue( "ShowDeleted", makeAny( (sal_Bool)sal_False ) ), 1114 // known ODBC settings 1115 AsciiPropertyValue( "SystemDriverSettings", makeAny( ::rtl::OUString() ) ), 1116 AsciiPropertyValue( "UseCatalog", makeAny( (sal_Bool)sal_False ) ), 1117 AsciiPropertyValue( "TypeInfoSettings", makeAny( Sequence< Any >()) ), 1118 // settings related to auto increment handling 1119 AsciiPropertyValue( "AutoIncrementCreation", makeAny( ::rtl::OUString() ) ), 1120 AsciiPropertyValue( "AutoRetrievingStatement", makeAny( ::rtl::OUString() ) ), 1121 AsciiPropertyValue( "IsAutoRetrievingEnabled", makeAny( (sal_Bool)sal_False ) ), 1122 // known Adabas D driver setting 1123 AsciiPropertyValue( "ShutdownDatabase", makeAny( (sal_Bool)sal_False ) ), 1124 AsciiPropertyValue( "DataCacheSizeIncrement", makeAny( (sal_Int32)20 ) ), 1125 AsciiPropertyValue( "DataCacheSize", makeAny( (sal_Int32)20 ) ), 1126 AsciiPropertyValue( "ControlUser", makeAny( ::rtl::OUString() ) ), 1127 AsciiPropertyValue( "ControlPassword", makeAny( ::rtl::OUString() ) ), 1128 // known LDAP driver settings 1129 AsciiPropertyValue( "HostName", makeAny( ::rtl::OUString() ) ), 1130 AsciiPropertyValue( "PortNumber", makeAny( (sal_Int32)389 ) ), 1131 AsciiPropertyValue( "BaseDN", makeAny( ::rtl::OUString() ) ), 1132 AsciiPropertyValue( "MaxRowCount", makeAny( (sal_Int32)100 ) ), 1133 // known MySQLNative driver settings 1134 AsciiPropertyValue( "LocalSocket", makeAny( ::rtl::OUString() ) ), 1135 AsciiPropertyValue( "NamedPipe", makeAny( ::rtl::OUString() ) ), 1136 // misc known driver settings 1137 AsciiPropertyValue( "ParameterNameSubstitution", makeAny( (sal_Bool)sal_False ) ), 1138 AsciiPropertyValue( "AddIndexAppendix", makeAny( (sal_Bool)sal_True ) ), 1139 AsciiPropertyValue( "IgnoreDriverPrivileges", makeAny( (sal_Bool)sal_True ) ), 1140 AsciiPropertyValue( "ImplicitCatalogRestriction", ::cppu::UnoType< ::rtl::OUString >::get() ), 1141 AsciiPropertyValue( "ImplicitSchemaRestriction", ::cppu::UnoType< ::rtl::OUString >::get() ), 1142 AsciiPropertyValue( "PrimaryKeySupport", ::cppu::UnoType< sal_Bool >::get() ), 1143 AsciiPropertyValue( "ShowColumnDescription", makeAny( (sal_Bool)sal_False ) ), 1144 // known SDB level settings 1145 AsciiPropertyValue( "NoNameLengthLimit", makeAny( (sal_Bool)sal_False ) ), 1146 AsciiPropertyValue( "AppendTableAliasName", makeAny( (sal_Bool)sal_False ) ), 1147 AsciiPropertyValue( "GenerateASBeforeCorrelationName", makeAny( (sal_Bool)sal_True ) ), 1148 AsciiPropertyValue( "ColumnAliasInOrderBy", makeAny( (sal_Bool)sal_True ) ), 1149 AsciiPropertyValue( "EnableSQL92Check", makeAny( (sal_Bool)sal_False ) ), 1150 AsciiPropertyValue( "BooleanComparisonMode", makeAny( BooleanComparisonMode::EQUAL_INTEGER ) ), 1151 AsciiPropertyValue( "TableTypeFilterMode", makeAny( (sal_Int32)3 ) ), 1152 AsciiPropertyValue( "RespectDriverResultSetType", makeAny( (sal_Bool)sal_False ) ), 1153 AsciiPropertyValue( "UseSchemaInSelect", makeAny( (sal_Bool)sal_True ) ), 1154 AsciiPropertyValue( "UseCatalogInSelect", makeAny( (sal_Bool)sal_True ) ), 1155 AsciiPropertyValue( "EnableOuterJoinEscape", makeAny( (sal_Bool)sal_True ) ), 1156 AsciiPropertyValue( "PreferDosLikeLineEnds", makeAny( (sal_Bool)sal_False ) ), 1157 AsciiPropertyValue( "FormsCheckRequiredFields", makeAny( (sal_Bool)sal_True ) ), 1158 AsciiPropertyValue( "EscapeDateTime", makeAny( (sal_Bool)sal_True ) ), 1159 1160 // known services to handle database tasks 1161 AsciiPropertyValue( "TableAlterationServiceName", makeAny( ::rtl::OUString() ) ), 1162 AsciiPropertyValue( "TableRenameServiceName", makeAny( ::rtl::OUString() ) ), 1163 AsciiPropertyValue( "ViewAlterationServiceName", makeAny( ::rtl::OUString() ) ), 1164 AsciiPropertyValue( "ViewAccessServiceName", makeAny( ::rtl::OUString() ) ), 1165 AsciiPropertyValue( "CommandDefinitions", makeAny( ::rtl::OUString() ) ), 1166 AsciiPropertyValue( "Forms", makeAny( ::rtl::OUString() ) ), 1167 AsciiPropertyValue( "Reports", makeAny( ::rtl::OUString() ) ), 1168 AsciiPropertyValue( "KeyAlterationServiceName", makeAny( ::rtl::OUString() ) ), 1169 AsciiPropertyValue( "IndexAlterationServiceName", makeAny( ::rtl::OUString() ) ), 1170 1171 AsciiPropertyValue() 1172 }; 1173 return aKnownSettings; 1174 } 1175 1176 // ----------------------------------------------------------------------------- 1177 TContentPtr& ODatabaseModelImpl::getObjectContainer( ObjectType _eType ) 1178 { 1179 OSL_PRECOND( _eType >= E_FORM && _eType <= E_TABLE, "ODatabaseModelImpl::getObjectContainer: illegal index!" ); 1180 TContentPtr& rContentPtr = m_aContainer[ _eType ]; 1181 1182 if ( !rContentPtr.get() ) 1183 { 1184 rContentPtr = TContentPtr( new ODefinitionContainer_Impl ); 1185 rContentPtr->m_pDataSource = this; 1186 rContentPtr->m_aProps.aTitle = lcl_getContainerStorageName_throw( _eType ); 1187 } 1188 return rContentPtr; 1189 } 1190 1191 // ----------------------------------------------------------------------------- 1192 void ODatabaseModelImpl::revokeDataSource() const 1193 { 1194 if ( m_pDBContext && m_sDocumentURL.getLength() ) 1195 m_pDBContext->revokeDatabaseDocument( *this ); 1196 } 1197 1198 // ----------------------------------------------------------------------------- 1199 bool ODatabaseModelImpl::adjustMacroMode_AutoReject() 1200 { 1201 return m_aMacroMode.adjustMacroMode( NULL ); 1202 } 1203 1204 // ----------------------------------------------------------------------------- 1205 bool ODatabaseModelImpl::checkMacrosOnLoading() 1206 { 1207 Reference< XInteractionHandler > xInteraction; 1208 xInteraction = m_aMediaDescriptor.getOrDefault( "InteractionHandler", xInteraction ); 1209 return m_aMacroMode.checkMacrosOnLoading( xInteraction ); 1210 } 1211 1212 // ----------------------------------------------------------------------------- 1213 void ODatabaseModelImpl::resetMacroExecutionMode() 1214 { 1215 m_aMacroMode = ::sfx2::DocumentMacroMode( *this ); 1216 } 1217 1218 // ----------------------------------------------------------------------------- 1219 Reference< XStorageBasedLibraryContainer > ODatabaseModelImpl::getLibraryContainer( bool _bScript ) 1220 { 1221 Reference< XStorageBasedLibraryContainer >& rxContainer( _bScript ? m_xBasicLibraries : m_xDialogLibraries ); 1222 if ( rxContainer.is() ) 1223 return rxContainer; 1224 1225 Reference< XStorageBasedDocument > xDocument( getModel_noCreate(), UNO_QUERY_THROW ); 1226 // this is only to be called if there already exists a document model - in fact, it is 1227 // to be called by the document model only 1228 1229 try 1230 { 1231 Reference< XStorageBasedLibraryContainer > (*Factory)( const Reference< XComponentContext >&, const Reference< XStorageBasedDocument >&) 1232 = _bScript ? &DocumentScriptLibraryContainer::create : &DocumentDialogLibraryContainer::create; 1233 1234 rxContainer.set( 1235 (*Factory)( m_aContext.getUNOContext(), xDocument ), 1236 UNO_QUERY_THROW 1237 ); 1238 } 1239 catch( const RuntimeException& ) 1240 { 1241 throw; 1242 } 1243 catch( const Exception& ) 1244 { 1245 throw WrappedTargetRuntimeException( 1246 ::rtl::OUString(), 1247 xDocument, 1248 ::cppu::getCaughtException() 1249 ); 1250 } 1251 return rxContainer; 1252 } 1253 1254 // ----------------------------------------------------------------------------- 1255 void ODatabaseModelImpl::storeLibraryContainersTo( const Reference< XStorage >& _rxToRootStorage ) 1256 { 1257 if ( m_xBasicLibraries.is() ) 1258 m_xBasicLibraries->storeLibrariesToStorage( _rxToRootStorage ); 1259 1260 if ( m_xDialogLibraries.is() ) 1261 m_xDialogLibraries->storeLibrariesToStorage( _rxToRootStorage ); 1262 } 1263 1264 // ----------------------------------------------------------------------------- 1265 Reference< XStorage > ODatabaseModelImpl::switchToStorage( const Reference< XStorage >& _rxNewRootStorage ) 1266 { 1267 if ( !_rxNewRootStorage.is() ) 1268 throw IllegalArgumentException(); 1269 1270 return impl_switchToStorage_throw( _rxNewRootStorage ); 1271 } 1272 1273 // ----------------------------------------------------------------------------- 1274 namespace 1275 { 1276 void lcl_modifyListening( ::sfx2::IModifiableDocument& _rDocument, 1277 const Reference< XStorage >& _rxStorage, ::rtl::Reference< ::sfx2::DocumentStorageModifyListener >& _inout_rListener, 1278 ::vos::IMutex& _rMutex, bool _bListen ) 1279 { 1280 Reference< XModifiable > xModify( _rxStorage, UNO_QUERY ); 1281 OSL_ENSURE( xModify.is() || !_rxStorage.is(), "lcl_modifyListening: storage can't notify us!" ); 1282 1283 if ( xModify.is() && !_bListen && _inout_rListener.is() ) 1284 { 1285 xModify->removeModifyListener( _inout_rListener.get() ); 1286 } 1287 1288 if ( _inout_rListener.is() ) 1289 { 1290 _inout_rListener->dispose(); 1291 _inout_rListener = NULL; 1292 } 1293 1294 if ( xModify.is() && _bListen ) 1295 { 1296 _inout_rListener = new ::sfx2::DocumentStorageModifyListener( _rDocument, _rMutex ); 1297 xModify->addModifyListener( _inout_rListener.get() ); 1298 } 1299 } 1300 } 1301 1302 // ----------------------------------------------------------------------------- 1303 namespace 1304 { 1305 static void lcl_rebaseScriptStorage_throw( const Reference< XStorageBasedLibraryContainer >& _rxContainer, 1306 const Reference< XStorage >& _rxNewRootStorage ) 1307 { 1308 if ( _rxContainer.is() ) 1309 { 1310 if ( _rxNewRootStorage.is() ) 1311 _rxContainer->setRootStorage( _rxNewRootStorage ); 1312 // else 1313 // TODO: what to do here? dispose the container? 1314 } 1315 } 1316 } 1317 1318 // ----------------------------------------------------------------------------- 1319 Reference< XStorage > ODatabaseModelImpl::impl_switchToStorage_throw( const Reference< XStorage >& _rxNewRootStorage ) 1320 { 1321 // stop listening for modifications at the old storage 1322 lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, m_aMutexFacade, false ); 1323 1324 // set new storage 1325 m_xDocumentStorage.reset( _rxNewRootStorage, SharedStorage::TakeOwnership ); 1326 1327 // start listening for modifications 1328 lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, m_aMutexFacade, true ); 1329 1330 // forward new storage to Basic and Dialog library containers 1331 lcl_rebaseScriptStorage_throw( m_xBasicLibraries, m_xDocumentStorage.getTyped() ); 1332 lcl_rebaseScriptStorage_throw( m_xDialogLibraries, m_xDocumentStorage.getTyped() ); 1333 1334 m_bReadOnly = !tools::stor::storageIsWritable_nothrow( m_xDocumentStorage.getTyped() ); 1335 // TODO: our data source, if it exists, must broadcast the change of its ReadOnly property 1336 1337 return m_xDocumentStorage.getTyped(); 1338 } 1339 1340 // ----------------------------------------------------------------------------- 1341 void ODatabaseModelImpl::impl_switchToLogicalURL( const ::rtl::OUString& i_rDocumentURL ) 1342 { 1343 if ( i_rDocumentURL == m_sDocumentURL ) 1344 return; 1345 1346 const ::rtl::OUString sOldURL( m_sDocumentURL ); 1347 // update our name, if necessary 1348 if ( ( m_sName == m_sDocumentURL ) // our name is our old URL 1349 || ( !m_sName.getLength() ) // we do not have a name, yet (i.e. are not registered at the database context) 1350 ) 1351 { 1352 INetURLObject aURL( i_rDocumentURL ); 1353 if ( aURL.GetProtocol() != INET_PROT_NOT_VALID ) 1354 { 1355 m_sName = i_rDocumentURL; 1356 // TODO: our data source must broadcast the change of the Name property 1357 } 1358 } 1359 1360 // remember URL 1361 m_sDocumentURL = i_rDocumentURL; 1362 1363 // update our location, if necessary 1364 if ( m_sDocFileLocation.getLength() == 0 ) 1365 m_sDocFileLocation = m_sDocumentURL; 1366 1367 // register at the database context, or change registration 1368 if ( m_pDBContext ) 1369 { 1370 if ( sOldURL.getLength() ) 1371 m_pDBContext->databaseDocumentURLChange( sOldURL, m_sDocumentURL ); 1372 else 1373 m_pDBContext->registerDatabaseDocument( *this ); 1374 } 1375 } 1376 1377 // ----------------------------------------------------------------------------- 1378 ::rtl::OUString ODatabaseModelImpl::getObjectContainerStorageName( const ObjectType _eType ) 1379 { 1380 return lcl_getContainerStorageName_throw( _eType ); 1381 } 1382 1383 // ----------------------------------------------------------------------------- 1384 sal_Int16 ODatabaseModelImpl::getCurrentMacroExecMode() const 1385 { 1386 sal_Int16 nCurrentMode = MacroExecMode::NEVER_EXECUTE; 1387 try 1388 { 1389 nCurrentMode = m_aMediaDescriptor.getOrDefault( "MacroExecutionMode", nCurrentMode ); 1390 } 1391 catch( const Exception& ) 1392 { 1393 DBG_UNHANDLED_EXCEPTION(); 1394 } 1395 return nCurrentMode; 1396 } 1397 1398 // ----------------------------------------------------------------------------- 1399 sal_Bool ODatabaseModelImpl::setCurrentMacroExecMode( sal_uInt16 nMacroMode ) 1400 { 1401 m_aMediaDescriptor.put( "MacroExecutionMode", nMacroMode ); 1402 return sal_True; 1403 } 1404 1405 // ----------------------------------------------------------------------------- 1406 ::rtl::OUString ODatabaseModelImpl::getDocumentLocation() const 1407 { 1408 return getURL(); 1409 // formerly, we returned getDocFileLocation here, which is the location of the file from which we 1410 // recovered the "real" document. 1411 // However, during CWS autorecovery evolving, we clarified (with MAV/MT) the role of XModel::getURL and 1412 // XStorable::getLocation. In this course, we agreed that for a macro security check, the *document URL* 1413 // (not the recovery file URL) is to be used: The recovery file lies in the backup folder, and by definition, 1414 // this folder is considered to be secure. So, the document URL needs to be used to decide about the security. 1415 } 1416 1417 // ----------------------------------------------------------------------------- 1418 Reference< XStorage > ODatabaseModelImpl::getZipStorageToSign() 1419 { 1420 // we do not support signing the scripting storages, so we're allowed to 1421 // return <NULL/> here. 1422 return Reference< XStorage >(); 1423 } 1424 1425 // ----------------------------------------------------------------------------- 1426 ODatabaseModelImpl::EmbeddedMacros ODatabaseModelImpl::determineEmbeddedMacros() 1427 { 1428 if ( !m_aEmbeddedMacros ) 1429 { 1430 if ( ::sfx2::DocumentMacroMode::storageHasMacros( const_cast< ODatabaseModelImpl* >( this )->getOrCreateRootStorage() ) ) 1431 { 1432 m_aEmbeddedMacros.reset( eDocumentWideMacros ); 1433 } 1434 else if ( lcl_hasObjectsWithMacros_nothrow( const_cast< ODatabaseModelImpl& >( *this ), E_FORM ) 1435 || lcl_hasObjectsWithMacros_nothrow( const_cast< ODatabaseModelImpl& >( *this ), E_REPORT ) 1436 ) 1437 { 1438 m_aEmbeddedMacros.reset( eSubDocumentMacros ); 1439 } 1440 else 1441 { 1442 m_aEmbeddedMacros.reset( eNoMacros ); 1443 } 1444 } 1445 return *m_aEmbeddedMacros; 1446 } 1447 1448 // ----------------------------------------------------------------------------- 1449 sal_Bool ODatabaseModelImpl::documentStorageHasMacros() const 1450 { 1451 const_cast< ODatabaseModelImpl* >( this )->determineEmbeddedMacros(); 1452 return ( *m_aEmbeddedMacros != eNoMacros ); 1453 } 1454 1455 // ----------------------------------------------------------------------------- 1456 Reference< XEmbeddedScripts > ODatabaseModelImpl::getEmbeddedDocumentScripts() const 1457 { 1458 return Reference< XEmbeddedScripts >( getModel_noCreate(), UNO_QUERY ); 1459 } 1460 1461 // ----------------------------------------------------------------------------- 1462 sal_Int16 ODatabaseModelImpl::getScriptingSignatureState() 1463 { 1464 // no support for signatures at the moment 1465 return SIGNATURESTATE_NOSIGNATURES; 1466 } 1467 1468 // ----------------------------------------------------------------------------- 1469 sal_Bool ODatabaseModelImpl::hasTrustedScriptingSignature( sal_Bool /*bAllowUIToAddAuthor*/ ) 1470 { 1471 // no support for signatures at the moment 1472 return sal_False; 1473 } 1474 1475 // ----------------------------------------------------------------------------- 1476 void ODatabaseModelImpl::showBrokenSignatureWarning( const Reference< XInteractionHandler >& /*_rxInteraction*/ ) const 1477 { 1478 OSL_ENSURE( false, "ODatabaseModelImpl::showBrokenSignatureWarning: signatures can't be broken - we do not support them!" ); 1479 } 1480 1481 // ----------------------------------------------------------------------------- 1482 void ODatabaseModelImpl::storageIsModified() 1483 { 1484 setModified( sal_True ); 1485 } 1486 1487 // ----------------------------------------------------------------------------- 1488 ModelDependentComponent::ModelDependentComponent( const ::rtl::Reference< ODatabaseModelImpl >& _model ) 1489 :m_pImpl( _model ) 1490 ,m_aMutex( _model->getSharedMutex() ) 1491 { 1492 } 1493 1494 // ----------------------------------------------------------------------------- 1495 ModelDependentComponent::~ModelDependentComponent() 1496 { 1497 } 1498 1499 //........................................................................ 1500 } // namespace dbaccess 1501 //........................................................................ 1502 1503