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