1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ModelImpl.cxx,v $
10 * $Revision: 1.25.6.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
34 #include "commandcontainer.hxx"
35 #include "connection.hxx"
36 #include "core_resource.hrc"
37 #include "core_resource.hxx"
38 #include "databasecontext.hxx"
39 #include "databasedocument.hxx"
40 #include "datasource.hxx"
41 #include "dbastrings.hrc"
42 #include "ModelImpl.hxx"
43 #include "userinformation.hxx"
45 /** === begin UNO includes === **/
46 #include <com/sun/star/container/XSet.hpp>
47 #include <com/sun/star/document/MacroExecMode.hpp>
48 #include <com/sun/star/embed/XTransactedObject.hpp>
49 #include <com/sun/star/embed/XTransactionBroadcaster.hpp>
50 #include <com/sun/star/sdb/BooleanComparisonMode.hpp>
51 #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
52 #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
53 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
54 #include <com/sun/star/form/XLoadable.hpp>
55 /** === end UNO includes === **/
57 #include <comphelper/interaction.hxx>
58 #include <comphelper/mediadescriptor.hxx>
59 #include <comphelper/namedvaluecollection.hxx>
60 #include <comphelper/seqstream.hxx>
61 #include <comphelper/sequence.hxx>
62 #include <connectivity/dbexception.hxx>
63 #include <cppuhelper/exc_hlp.hxx>
64 #include <cppuhelper/typeprovider.hxx>
65 #include <rtl/digest.h>
66 #include <sfx2/signaturestate.hxx>
67 #include <tools/debug.hxx>
68 #include <tools/diagnose_ex.h>
69 #include <tools/errcode.hxx>
70 #include <tools/urlobj.hxx>
71 #include <unotools/sharedunocomponent.hxx>
75 using namespace ::com::sun::star::document
;
76 using namespace ::com::sun::star::sdbc
;
77 using namespace ::com::sun::star::sdbcx
;
78 using namespace ::com::sun::star::sdb
;
79 using namespace ::com::sun::star::beans
;
80 using namespace ::com::sun::star::uno
;
81 using namespace ::com::sun::star::lang
;
82 using namespace ::com::sun::star::embed
;
83 using namespace ::com::sun::star::container
;
84 using namespace ::com::sun::star::util
;
85 using namespace ::com::sun::star::io
;
86 using namespace ::com::sun::star::task
;
87 using namespace ::com::sun::star::ucb
;
88 using namespace ::com::sun::star::frame
;
89 using namespace ::com::sun::star::view
;
90 using namespace ::com::sun::star::task
;
91 using namespace ::com::sun::star::reflection
;
92 using namespace ::com::sun::star::script
;
93 using namespace ::cppu
;
94 using namespace ::osl
;
95 using namespace ::vos
;
96 using namespace ::dbtools
;
97 using namespace ::comphelper
;
98 namespace css
= ::com::sun::star
;
100 //........................................................................
103 //........................................................................
105 //============================================================
107 //============================================================
108 //------------------------------------------------------------------------
109 VosMutexFacade::VosMutexFacade( ::osl::Mutex
& _rMutex
)
114 //------------------------------------------------------------------------
115 void SAL_CALL
VosMutexFacade::acquire()
120 //------------------------------------------------------------------------
121 sal_Bool SAL_CALL
VosMutexFacade::tryToAcquire()
123 return m_rMutex
.tryToAcquire();
126 //------------------------------------------------------------------------
127 void SAL_CALL
VosMutexFacade::release()
132 //============================================================
133 //= DocumentStorageAccess
134 //============================================================
135 DBG_NAME( DocumentStorageAccess
)
136 class DocumentStorageAccess
: public ::cppu::WeakImplHelper2
< XDocumentSubStorageSupplier
137 , XTransactionListener
>
139 typedef ::std::map
< ::rtl::OUString
, Reference
< XStorage
> > NamedStorages
;
141 ::osl::Mutex m_aMutex
;
142 /// all sub storages which we ever gave to the outer world
143 NamedStorages m_aExposedStorages
;
144 ODatabaseModelImpl
* m_pModelImplementation
;
145 bool m_bPropagateCommitToRoot
;
148 DocumentStorageAccess( ODatabaseModelImpl
& _rModelImplementation
)
149 :m_pModelImplementation( &_rModelImplementation
)
150 ,m_bPropagateCommitToRoot( true )
152 DBG_CTOR( DocumentStorageAccess
, NULL
);
156 ~DocumentStorageAccess()
158 DBG_DTOR( DocumentStorageAccess
, NULL
);
164 void suspendCommitPropagation()
166 DBG_ASSERT( m_bPropagateCommitToRoot
, "DocumentStorageAccess:: suspendCommitPropagation: already suspended" );
167 m_bPropagateCommitToRoot
= false;
169 void resumeCommitPropagation()
171 DBG_ASSERT( !m_bPropagateCommitToRoot
, "DocumentStorageAccess:: suspendCommitPropagation: already suspended" );
172 m_bPropagateCommitToRoot
= true;
175 // XDocumentSubStorageSupplier
176 virtual Reference
< XStorage
> SAL_CALL
getDocumentSubStorage( const ::rtl::OUString
& aStorageName
, ::sal_Int32 nMode
) throw (RuntimeException
);
177 virtual Sequence
< ::rtl::OUString
> SAL_CALL
getDocumentSubStoragesNames( ) throw (IOException
, RuntimeException
);
179 // XTransactionListener
180 virtual void SAL_CALL
preCommit( const ::com::sun::star::lang::EventObject
& aEvent
) throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
);
181 virtual void SAL_CALL
commited( const ::com::sun::star::lang::EventObject
& aEvent
) throw (::com::sun::star::uno::RuntimeException
);
182 virtual void SAL_CALL
preRevert( const ::com::sun::star::lang::EventObject
& aEvent
) throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
);
183 virtual void SAL_CALL
reverted( const ::com::sun::star::lang::EventObject
& aEvent
) throw (::com::sun::star::uno::RuntimeException
);
186 virtual void SAL_CALL
disposing( const ::com::sun::star::lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
);
189 //--------------------------------------------------------------------------
190 void DocumentStorageAccess::dispose()
192 ::osl::MutexGuard
aGuard( m_aMutex
);
194 for ( NamedStorages::iterator loop
= m_aExposedStorages
.begin();
195 loop
!= m_aExposedStorages
.end();
201 Reference
< XTransactionBroadcaster
> xBroadcaster( loop
->second
, UNO_QUERY
);
202 if ( xBroadcaster
.is() )
203 xBroadcaster
->removeTransactionListener( this );
205 catch( const Exception
& )
207 DBG_UNHANDLED_EXCEPTION();
211 m_aExposedStorages
.clear();
213 m_pModelImplementation
= NULL
;
216 //--------------------------------------------------------------------------
217 Reference
< XStorage
> SAL_CALL
DocumentStorageAccess::getDocumentSubStorage( const ::rtl::OUString
& aStorageName
, ::sal_Int32 nMode
) throw (RuntimeException
)
219 ::osl::MutexGuard
aGuard( m_aMutex
);
220 NamedStorages::iterator pos
= m_aExposedStorages
.find( aStorageName
);
221 if ( pos
== m_aExposedStorages
.end() )
223 Reference
< XStorage
> xResult
= m_pModelImplementation
->getStorage( aStorageName
, nMode
);
224 Reference
< XTransactionBroadcaster
> xBroadcaster( xResult
, UNO_QUERY
);
225 if ( xBroadcaster
.is() )
226 xBroadcaster
->addTransactionListener( this );
228 pos
= m_aExposedStorages
.insert( NamedStorages::value_type( aStorageName
, xResult
) ).first
;
234 //--------------------------------------------------------------------------
235 Sequence
< ::rtl::OUString
> SAL_CALL
DocumentStorageAccess::getDocumentSubStoragesNames( ) throw (IOException
, RuntimeException
)
237 Reference
< XStorage
> xRootStor( m_pModelImplementation
->getRootStorage() );
238 if ( !xRootStor
.is() )
239 return Sequence
< ::rtl::OUString
>();
241 ::std::vector
< ::rtl::OUString
> aNames
;
243 Reference
< XNameAccess
> xNames( xRootStor
, UNO_QUERY_THROW
);
244 Sequence
< ::rtl::OUString
> aElementNames( xNames
->getElementNames() );
245 for ( sal_Int32 i
=0; i
<aElementNames
.getLength(); ++i
)
247 if ( xRootStor
->isStorageElement( aElementNames
[i
] ) )
248 aNames
.push_back( aElementNames
[i
] );
250 return aNames
.empty()
251 ? Sequence
< ::rtl::OUString
>()
252 : Sequence
< ::rtl::OUString
>( &aNames
[0], aNames
.size() );
255 //--------------------------------------------------------------------------
256 void SAL_CALL
DocumentStorageAccess::preCommit( const css::lang::EventObject
& /*aEvent*/ ) throw (Exception
, RuntimeException
)
261 //--------------------------------------------------------------------------
262 void SAL_CALL
DocumentStorageAccess::commited( const css::lang::EventObject
& aEvent
) throw (RuntimeException
)
264 ::osl::MutexGuard
aGuard( m_aMutex
);
266 if ( m_pModelImplementation
)
267 m_pModelImplementation
->setModified( sal_True
);
269 if ( m_pModelImplementation
&& m_bPropagateCommitToRoot
)
271 Reference
< XStorage
> xStorage( aEvent
.Source
, UNO_QUERY
);
272 if ( m_pModelImplementation
->isDatabaseStorage( xStorage
) )
274 m_pModelImplementation
->commitRootStorage();
279 //--------------------------------------------------------------------------
280 void SAL_CALL
DocumentStorageAccess::preRevert( const css::lang::EventObject
& /*aEvent*/ ) throw (Exception
, RuntimeException
)
285 //--------------------------------------------------------------------------
286 void SAL_CALL
DocumentStorageAccess::reverted( const css::lang::EventObject
& /*aEvent*/ ) throw (RuntimeException
)
291 //--------------------------------------------------------------------------
292 void SAL_CALL
DocumentStorageAccess::disposing( const css::lang::EventObject
& Source
) throw ( RuntimeException
)
294 ODatabaseModelImpl
* pImpl
= m_pModelImplementation
;
296 pImpl
->disposing( Source
);
298 for ( NamedStorages::iterator find
= m_aExposedStorages
.begin();
299 find
!= m_aExposedStorages
.end();
302 if ( find
->second
== Source
.Source
)
304 m_aExposedStorages
.erase( find
);
309 //============================================================
310 //= ODatabaseModelImpl
311 //============================================================
312 DBG_NAME(ODatabaseModelImpl
)
313 //--------------------------------------------------------------------------
314 ODatabaseModelImpl::ODatabaseModelImpl( const Reference
< XMultiServiceFactory
>& _rxFactory
, ODatabaseContext
& _rDBContext
)
317 ,m_pStorageAccess( NULL
)
319 ,m_aMutexFacade( m_aMutex
)
322 ,m_aMacroMode( *this )
323 ,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE
)
324 ,m_pDBContext( &_rDBContext
)
327 ,m_bModificationLock( false )
328 ,m_bDocumentInitialized( false )
329 ,m_aContext( _rxFactory
)
331 ,m_bReadOnly(sal_False
)
332 ,m_bPasswordRequired(sal_False
)
333 ,m_bSuppressVersionColumns(sal_True
)
334 ,m_bModified(sal_False
)
335 ,m_bDocumentReadOnly(sal_False
)
336 ,m_bDisposingSubStorages( sal_False
)
337 ,m_pSharedConnectionManager(NULL
)
338 ,m_nControllerLockCount(0)
340 // some kind of default
341 DBG_CTOR(ODatabaseModelImpl
,NULL
);
342 m_sConnectURL
= ::rtl::OUString::createFromAscii("jdbc:");
343 m_aTableFilter
.realloc(1);
344 m_aTableFilter
[0] = ::rtl::OUString::createFromAscii("%");
345 impl_construct_nothrow();
348 //--------------------------------------------------------------------------
349 ODatabaseModelImpl::ODatabaseModelImpl(
350 const ::rtl::OUString
& _rRegistrationName
,
351 const Reference
< XMultiServiceFactory
>& _rxFactory
,
352 ODatabaseContext
& _rDBContext
356 ,m_pStorageAccess( NULL
)
358 ,m_aMutexFacade( m_aMutex
)
361 ,m_aMacroMode( *this )
362 ,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE
)
363 ,m_pDBContext( &_rDBContext
)
366 ,m_bModificationLock( false )
367 ,m_bDocumentInitialized( false )
368 ,m_aContext( _rxFactory
)
369 ,m_sName(_rRegistrationName
)
371 ,m_bReadOnly(sal_False
)
372 ,m_bPasswordRequired(sal_False
)
373 ,m_bSuppressVersionColumns(sal_True
)
374 ,m_bModified(sal_False
)
375 ,m_bDocumentReadOnly(sal_False
)
376 ,m_bDisposingSubStorages( sal_False
)
377 ,m_pSharedConnectionManager(NULL
)
378 ,m_nControllerLockCount(0)
380 DBG_CTOR(ODatabaseModelImpl
,NULL
);
381 impl_construct_nothrow();
384 //--------------------------------------------------------------------------
385 ODatabaseModelImpl::~ODatabaseModelImpl()
387 DBG_DTOR(ODatabaseModelImpl
,NULL
);
390 // -----------------------------------------------------------------------------
391 void ODatabaseModelImpl::impl_construct_nothrow()
393 // create the property bag to hold the settings (also known as "Info" property)
396 // the set of property value types in the bag is limited:
397 Sequence
< Type
> aAllowedTypes(6);
398 Type
* pAllowedType
= aAllowedTypes
.getArray();
399 *pAllowedType
++ = ::getCppuType( static_cast< sal_Bool
* >( NULL
) );
400 *pAllowedType
++ = ::getCppuType( static_cast< double* >( NULL
) );
401 *pAllowedType
++ = ::getCppuType( static_cast< ::rtl::OUString
* >( NULL
) );
402 *pAllowedType
++ = ::getCppuType( static_cast< sal_Int32
* >( NULL
) );
403 *pAllowedType
++ = ::getCppuType( static_cast< sal_Int16
* >( NULL
) );
404 *pAllowedType
++ = ::getCppuType( static_cast< Sequence
< Any
>* >( NULL
) );
406 Sequence
< Any
> aInitArgs( 2 );
407 aInitArgs
[0] <<= NamedValue(
408 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AutomaticAddition" ) ),
409 makeAny( (sal_Bool
)sal_True
)
411 aInitArgs
[1] <<= NamedValue(
412 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowedTypes" ) ),
413 makeAny( aAllowedTypes
)
416 m_xSettings
.set( m_aContext
.createComponentWithArguments( "com.sun.star.beans.PropertyBag", aInitArgs
), UNO_QUERY_THROW
);
418 // insert the default settings
419 Reference
< XPropertyContainer
> xContainer( m_xSettings
, UNO_QUERY_THROW
);
420 Reference
< XSet
> xSettingsSet( m_xSettings
, UNO_QUERY_THROW
);
421 const AsciiPropertyValue
* pSettings
= getDefaultDataSourceSettings();
422 for ( ; pSettings
->AsciiName
; ++pSettings
)
424 if ( !pSettings
->DefaultValue
.hasValue() )
427 ::rtl::OUString::createFromAscii( pSettings
->AsciiName
),
429 ::getCppuType( static_cast< ::rtl::OUString
* >( NULL
) ),
430 PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
| PropertyAttribute::MAYBEVOID
432 xSettingsSet
->insert( makeAny( aProperty
) );
436 xContainer
->addProperty(
437 ::rtl::OUString::createFromAscii( pSettings
->AsciiName
),
438 PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
,
439 pSettings
->DefaultValue
444 catch( const Exception
& )
446 DBG_UNHANDLED_EXCEPTION();
448 m_pDBContext
->appendAtTerminateListener(*this);
451 // -----------------------------------------------------------------------------
454 // .........................................................................
455 ::rtl::OUString
lcl_getContainerStorageName_throw( ODatabaseModelImpl::ObjectType _eType
)
457 const sal_Char
* pAsciiName( NULL
);
460 case ODatabaseModelImpl::E_FORM
: pAsciiName
= "forms"; break;
461 case ODatabaseModelImpl::E_REPORT
: pAsciiName
= "reports"; break;
462 case ODatabaseModelImpl::E_QUERY
: pAsciiName
= "queries"; break;
463 case ODatabaseModelImpl::E_TABLE
: pAsciiName
= "tables"; break;
465 throw RuntimeException();
467 return ::rtl::OUString::createFromAscii( pAsciiName
);
470 // .........................................................................
471 bool lcl_hasObjectWithMacros_throw( const ODefinitionContainer_Impl
& _rObjectDefinitions
, const Reference
< XStorage
>& _rxContainerStorage
)
473 bool bSomeDocHasMacros
= false;
475 for ( ODefinitionContainer_Impl::const_iterator object
= _rObjectDefinitions
.begin();
476 ( object
!= _rObjectDefinitions
.end() ) && !bSomeDocHasMacros
;
480 #if OSL_DEBUG_LEVEL > 0
481 const ::rtl::OUString
& rName( object
->first
); (void)rName
;
484 const TContentPtr
& rDefinition( object
->second
);
485 const ::rtl::OUString
& rPersistentName( rDefinition
->m_aProps
.sPersistentName
);
487 if ( !rPersistentName
.getLength() )
488 { // it's a logical sub folder used to organize the real objects
489 const ODefinitionContainer_Impl
& rSubFoldersObjectDefinitions( dynamic_cast< const ODefinitionContainer_Impl
& >( *rDefinition
.get() ) );
490 bSomeDocHasMacros
= lcl_hasObjectWithMacros_throw( rSubFoldersObjectDefinitions
, _rxContainerStorage
);
494 bSomeDocHasMacros
= ODatabaseModelImpl::objectHasMacros( _rxContainerStorage
, rPersistentName
);
496 return bSomeDocHasMacros
;
499 // .........................................................................
500 bool lcl_hasObjectsWithMacros_nothrow( ODatabaseModelImpl
& _rModel
, const ODatabaseModelImpl::ObjectType _eType
)
502 bool bSomeDocHasMacros
= false;
504 const OContentHelper_Impl
& rContainerData( *_rModel
.getObjectContainer( _eType
).get() );
505 const ODefinitionContainer_Impl
& rObjectDefinitions
= dynamic_cast< const ODefinitionContainer_Impl
& >( rContainerData
);
509 Reference
< XStorage
> xContainerStorage( _rModel
.getStorage(
510 _rModel
.getObjectContainerStorageName( _eType
), ElementModes::READWRITE
) );
511 // note the READWRITE here: If the storage already existed before, then the OpenMode will
512 // be ignored, anyway.
513 // If the storage did not yet exist, then it will be created. If the database document
514 // is read-only, the OpenMode will be automatically downgraded to READ. Otherwise,
515 // the storage will in fact be created as READWRITE. While this is not strictly necessary
516 // for this particular use case here, it is required since the storage is *cached*, and
517 // later use cases will need the READWRITE mode.
519 if ( xContainerStorage
.is() )
520 bSomeDocHasMacros
= lcl_hasObjectWithMacros_throw( rObjectDefinitions
, xContainerStorage
);
522 catch( const Exception
& )
524 DBG_UNHANDLED_EXCEPTION();
525 // be on the safe side: If we can't reliably determine whether there are macros,
526 // assume there actually are. Better this way, than the other way round.
527 bSomeDocHasMacros
= true;
530 return bSomeDocHasMacros
;
534 // -----------------------------------------------------------------------------
535 bool ODatabaseModelImpl::objectHasMacros( const Reference
< XStorage
>& _rxContainerStorage
, const ::rtl::OUString
& _rPersistentName
)
537 OSL_PRECOND( _rxContainerStorage
.is(), "ODatabaseModelImpl::objectHasMacros: this will crash!" );
539 bool bHasMacros
= true;
542 if ( !_rxContainerStorage
->hasByName( _rPersistentName
) )
545 Reference
< XStorage
> xObjectStor( _rxContainerStorage
->openStorageElement(
546 _rPersistentName
, ElementModes::READ
) );
548 bHasMacros
= ::sfx2::DocumentMacroMode::storageHasMacros( xObjectStor
);
550 catch( const Exception
& )
552 DBG_UNHANDLED_EXCEPTION();
557 // -----------------------------------------------------------------------------
558 void ODatabaseModelImpl::reset()
560 m_bReadOnly
= sal_False
;
561 ::std::vector
< TContentPtr
> aEmptyContainers( 4 );
562 m_aContainer
.swap( aEmptyContainers
);
564 if ( m_pStorageAccess
)
566 m_pStorageAccess
->dispose();
567 m_pStorageAccess
->release();
568 m_pStorageAccess
= NULL
;
571 // -----------------------------------------------------------------------------
572 void SAL_CALL
ODatabaseModelImpl::disposing( const ::com::sun::star::lang::EventObject
& Source
) throw(RuntimeException
)
574 Reference
<XConnection
> xCon(Source
.Source
,UNO_QUERY
);
578 OWeakConnectionArray::iterator aEnd
= m_aConnections
.end();
579 for (OWeakConnectionArray::iterator i
= m_aConnections
.begin(); aEnd
!= i
; ++i
)
581 if ( xCon
== i
->get() )
583 *i
= OWeakConnection();
594 if ( !m_bDisposingSubStorages
)
596 Reference
<XStorage
> xStorage(Source
.Source
,UNO_QUERY
);
597 TStorages::iterator aFind
= ::std::find_if(m_aStorages
.begin(),m_aStorages
.end(),
598 ::std::compose1(::std::bind2nd(::std::equal_to
<Reference
<XStorage
> >(),xStorage
),::std::select2nd
<TStorages::value_type
>()));
599 if ( aFind
!= m_aStorages
.end() )
600 m_aStorages
.erase(aFind
);
604 //------------------------------------------------------------------------------
605 void ODatabaseModelImpl::clearConnections()
607 OWeakConnectionArray aConnections
;
608 aConnections
.swap( m_aConnections
);
610 Reference
< XConnection
> xConn
;
611 OWeakConnectionArray::iterator aEnd
= aConnections
.end();
612 for ( OWeakConnectionArray::iterator i
= aConnections
.begin(); aEnd
!= i
; ++i
)
621 catch(const Exception
&)
623 DBG_UNHANDLED_EXCEPTION();
628 m_pSharedConnectionManager
= NULL
;
629 m_xSharedConnectionManager
= NULL
;
631 //------------------------------------------------------------------------------
632 void ODatabaseModelImpl::dispose()
634 // dispose the data source and the model
637 Reference
< XDataSource
> xDS( m_xDataSource
);
638 ::comphelper::disposeComponent( xDS
);
640 Reference
< XModel
> xModel( m_xModel
);
641 ::comphelper::disposeComponent( xModel
);
643 catch( const Exception
& )
645 DBG_UNHANDLED_EXCEPTION();
647 m_xDataSource
= WeakReference
<XDataSource
>();
648 m_xModel
= WeakReference
< XModel
>();
650 ::std::vector
<TContentPtr
>::iterator aIter
= m_aContainer
.begin();
651 ::std::vector
<TContentPtr
>::iterator aEnd
= m_aContainer
.end();
652 for (;aIter
!= aEnd
; ++aIter
)
655 (*aIter
)->m_pDataSource
= NULL
;
657 m_aContainer
.clear();
661 m_xNumberFormatsSupplier
= NULL
;
665 sal_Bool bStore
= commitEmbeddedStorage();
670 impl_switchToStorage_throw( NULL
);
672 catch( const Exception
& )
674 DBG_UNHANDLED_EXCEPTION();
677 if ( m_pStorageAccess
)
679 m_pStorageAccess
->dispose();
680 m_pStorageAccess
->release();
681 m_pStorageAccess
= NULL
;
684 // -----------------------------------------------------------------------------
685 const Reference
< XNumberFormatsSupplier
> & ODatabaseModelImpl::getNumberFormatsSupplier()
687 if (!m_xNumberFormatsSupplier
.is())
689 // the arguments : the locale of the current user
690 UserInformation aUserInfo
;
691 Sequence
< Any
> aArguments(1);
692 aArguments
.getArray()[0] <<= aUserInfo
.getUserLanguage();
694 m_xNumberFormatsSupplier
.set(
695 m_aContext
.createComponentWithArguments( "com.sun.star.util.NumberFormatsSupplier", aArguments
), UNO_QUERY_THROW
);
696 DBG_ASSERT(m_xNumberFormatsSupplier
.is(), "ODatabaseModelImpl::getNumberFormatsSupplier : could not instantiate the formats supplier !");
698 return m_xNumberFormatsSupplier
;
700 // -----------------------------------------------------------------------------
701 void ODatabaseModelImpl::attachResource( const ::rtl::OUString
& _rURL
, const Sequence
< PropertyValue
>& _rArgs
)
703 ::comphelper::NamedValueCollection
aMediaDescriptor( _rArgs
);
705 ::rtl::OUString
sDocumentLocation( aMediaDescriptor
.getOrDefault( "SalvagedFile", _rURL
) );
706 if ( !sDocumentLocation
.getLength() )
707 // this indicates "the document is being recovered, but _rURL already is the real document URL,
708 // not the temporary document location"
709 sDocumentLocation
= _rURL
;
711 if ( aMediaDescriptor
.has( "SalvagedFile" ) )
712 aMediaDescriptor
.remove( "SalvagedFile" );
714 m_aArgs
= stripLoadArguments( aMediaDescriptor
);
716 switchToURL( sDocumentLocation
, _rURL
);
719 // -----------------------------------------------------------------------------
720 Sequence
< PropertyValue
> ODatabaseModelImpl::stripLoadArguments( const ::comphelper::NamedValueCollection
& _rArguments
)
722 OSL_ENSURE( !_rArguments
.has( "Model" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (1)!" );
723 OSL_ENSURE( !_rArguments
.has( "ViewName" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (2)!" );
725 ::comphelper::NamedValueCollection
aMutableArgs( _rArguments
);
726 aMutableArgs
.remove( "Model" );
727 aMutableArgs
.remove( "ViewName" );
728 return aMutableArgs
.getPropertyValues();
731 // -----------------------------------------------------------------------------
732 void ODatabaseModelImpl::disposeStorages() SAL_THROW(())
734 m_bDisposingSubStorages
= sal_True
;
736 TStorages::iterator aEnd
= m_aStorages
.end();
737 for ( TStorages::iterator aIter
= m_aStorages
.begin();
744 ::comphelper::disposeComponent( aIter
->second
);
746 catch( const Exception
& )
748 DBG_UNHANDLED_EXCEPTION();
753 m_bDisposingSubStorages
= sal_False
;
755 // -----------------------------------------------------------------------------
756 Reference
< XSingleServiceFactory
> ODatabaseModelImpl::createStorageFactory() const
758 return Reference
< XSingleServiceFactory
>( m_aContext
.createComponent( "com.sun.star.embed.StorageFactory" ), UNO_QUERY_THROW
);
760 // -----------------------------------------------------------------------------
761 void ODatabaseModelImpl::commitRootStorage()
763 Reference
< XStorage
> xStorage( getOrCreateRootStorage() );
764 #if OSL_DEBUG_LEVEL > 0
767 commitStorageIfWriteable_ignoreErrors( xStorage
);
768 OSL_ENSURE( bSuccess
|| !xStorage
.is(),
769 "ODatabaseModelImpl::commitRootStorage: could commit the storage!" );
771 // -----------------------------------------------------------------------------
772 Reference
< XStorage
> ODatabaseModelImpl::getOrCreateRootStorage()
774 if ( !m_xDocumentStorage
.is() )
776 Reference
< XSingleServiceFactory
> xStorageFactory
= createStorageFactory();
777 if ( xStorageFactory
.is() )
780 ::comphelper::NamedValueCollection
aArgs( m_aArgs
);
782 aSource
= aArgs
.get( "Stream" );
783 if ( !aSource
.hasValue() )
784 aSource
= aArgs
.get( "InputStream" );
785 if ( !aSource
.hasValue() && m_sDocFileLocation
.getLength() )
786 aSource
<<= m_sDocFileLocation
;
787 // TODO: shouldn't we also check URL?
789 OSL_ENSURE( aSource
.hasValue(), "ODatabaseModelImpl::getOrCreateRootStorage: no source to create the storage from!" );
791 if ( aSource
.hasValue() )
793 Sequence
< Any
> aStorageCreationArgs(2);
794 aStorageCreationArgs
[0] = aSource
;
795 aStorageCreationArgs
[1] <<= ElementModes::READWRITE
;
797 Reference
< XStorage
> xDocumentStorage
;
800 xDocumentStorage
.set( xStorageFactory
->createInstanceWithArguments( aStorageCreationArgs
), UNO_QUERY_THROW
);
802 catch( const Exception
& )
804 m_bDocumentReadOnly
= sal_True
;
805 aStorageCreationArgs
[1] <<= ElementModes::READ
;
808 xDocumentStorage
.set( xStorageFactory
->createInstanceWithArguments( aStorageCreationArgs
), UNO_QUERY_THROW
);
810 catch( const Exception
& )
812 DBG_UNHANDLED_EXCEPTION();
816 impl_switchToStorage_throw( xDocumentStorage
);
820 return m_xDocumentStorage
.getTyped();
822 // -----------------------------------------------------------------------------
823 DocumentStorageAccess
* ODatabaseModelImpl::getDocumentStorageAccess()
825 if ( !m_pStorageAccess
)
827 m_pStorageAccess
= new DocumentStorageAccess( *this );
828 m_pStorageAccess
->acquire();
830 return m_pStorageAccess
;
833 // -----------------------------------------------------------------------------
834 void ODatabaseModelImpl::modelIsDisposing( const bool _wasInitialized
, ResetModelAccess
)
836 m_xModel
= Reference
< XModel
>();
838 // Basic libraries and Dialog libraries are a model facet, though held at this impl class.
839 // They automatically dispose themself when the model they belong to is being disposed.
840 // So, to not be tempted to do anything with them, again, we reset them.
841 m_xBasicLibraries
.clear();
842 m_xDialogLibraries
.clear();
844 m_bDocumentInitialized
= _wasInitialized
;
847 // -----------------------------------------------------------------------------
848 Reference
< XDocumentSubStorageSupplier
> ODatabaseModelImpl::getDocumentSubStorageSupplier()
850 return getDocumentStorageAccess();
852 // -----------------------------------------------------------------------------
853 Reference
<XStorage
> ODatabaseModelImpl::getStorage( const ::rtl::OUString
& _sStorageName
, sal_Int32 _nMode
)
855 OSL_ENSURE(_sStorageName
.getLength(),"ODatabaseModelImpl::getStorage: Invalid storage name!");
856 Reference
<XStorage
> xStorage
;
857 TStorages::iterator aFind
= m_aStorages
.find(_sStorageName
);
858 if ( aFind
== m_aStorages
.end() )
862 Reference
< XStorage
> xMyStorage( getOrCreateRootStorage() );
863 if ( xMyStorage
.is() )
865 sal_Int32 nMode
= m_bDocumentReadOnly
? ElementModes::READ
: _nMode
;
866 if ( nMode
== ElementModes::READ
)
868 Reference
< XNameAccess
> xSubStorageNames( xMyStorage
, UNO_QUERY
);
869 if ( xSubStorageNames
.is() && !xSubStorageNames
->hasByName( _sStorageName
) )
873 xStorage
= xMyStorage
->openStorageElement( _sStorageName
, nMode
);
874 Reference
< XTransactionBroadcaster
> xBroad( xStorage
, UNO_QUERY
);
876 xBroad
->addTransactionListener( getDocumentStorageAccess() );
877 aFind
= m_aStorages
.insert( TStorages::value_type( _sStorageName
, xStorage
) ).first
;
880 catch( const Exception
& )
882 DBG_UNHANDLED_EXCEPTION();
886 if ( aFind
!= m_aStorages
.end() )
887 xStorage
= aFind
->second
;
891 // -----------------------------------------------------------------------------
892 sal_Bool
ODatabaseModelImpl::commitEmbeddedStorage( sal_Bool _bPreventRootCommits
)
894 if ( _bPreventRootCommits
&& m_pStorageAccess
)
895 m_pStorageAccess
->suspendCommitPropagation();
897 sal_Bool bStore
= sal_False
;
900 TStorages::iterator aFind
= m_aStorages
.find(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("database")));
901 if ( aFind
!= m_aStorages
.end() )
902 bStore
= commitStorageIfWriteable(aFind
->second
);
906 OSL_ENSURE(0,"Exception Caught: Could not store embedded database!");
909 if ( _bPreventRootCommits
&& m_pStorageAccess
)
910 m_pStorageAccess
->resumeCommitPropagation();
916 // -----------------------------------------------------------------------------
919 bool lcl_storageIsWritable_nothrow( const Reference
< XStorage
>& _rxStorage
)
921 if ( !_rxStorage
.is() )
924 sal_Int32 nMode
= ElementModes::READ
;
927 Reference
< XPropertySet
> xStorageProps( _rxStorage
, UNO_QUERY_THROW
);
928 xStorageProps
->getPropertyValue(
929 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ) ) ) >>= nMode
;
931 catch( const Exception
& )
933 DBG_UNHANDLED_EXCEPTION();
935 return ( nMode
& ElementModes::WRITE
) != 0;
939 // -----------------------------------------------------------------------------
940 bool ODatabaseModelImpl::commitStorageIfWriteable( const Reference
< XStorage
>& _rxStorage
) SAL_THROW(( IOException
, WrappedTargetException
, RuntimeException
))
942 bool bSuccess
= false;
943 Reference
<XTransactedObject
> xTrans( _rxStorage
, UNO_QUERY
);
946 if ( lcl_storageIsWritable_nothrow( _rxStorage
) )
952 // -----------------------------------------------------------------------------
953 bool ODatabaseModelImpl::commitStorageIfWriteable_ignoreErrors( const Reference
< XStorage
>& _rxStorage
) SAL_THROW(())
955 bool bSuccess
= false;
958 bSuccess
= commitStorageIfWriteable( _rxStorage
);
960 catch( const Exception
& )
962 DBG_UNHANDLED_EXCEPTION();
966 // -----------------------------------------------------------------------------
967 void ODatabaseModelImpl::setModified( sal_Bool _bModified
)
969 if ( isModifyLocked() )
974 Reference
< XModifiable
> xModi( m_xModel
.get(), UNO_QUERY
);
976 xModi
->setModified( _bModified
);
978 m_bModified
= _bModified
;
980 catch( const Exception
& )
982 DBG_UNHANDLED_EXCEPTION();
986 // -----------------------------------------------------------------------------
987 Reference
<XDataSource
> ODatabaseModelImpl::getOrCreateDataSource()
989 Reference
<XDataSource
> xDs
= m_xDataSource
;
992 xDs
= new ODatabaseSource(this);
997 // -----------------------------------------------------------------------------
998 Reference
< XModel
> ODatabaseModelImpl::getModel_noCreate() const
1002 // -----------------------------------------------------------------------------
1003 Reference
< XModel
> ODatabaseModelImpl::createNewModel_deliverOwnership( bool _bInitialize
)
1005 Reference
< XModel
> xModel( m_xModel
);
1006 OSL_PRECOND( !xModel
.is(), "ODatabaseModelImpl::createNewModel_deliverOwnership: not to be called if there already is a model!" );
1009 xModel
= ODatabaseDocument::createDatabaseDocument( this, ODatabaseDocument::FactoryAccess() );
1014 Reference
< XSet
> xModelCollection
;
1015 if ( m_aContext
.createComponent( "com.sun.star.frame.GlobalEventBroadcaster", xModelCollection
) )
1016 xModelCollection
->insert( makeAny( xModel
) );
1018 catch( const Exception
& )
1020 DBG_UNHANDLED_EXCEPTION();
1027 Reference
< XLoadable
> xLoad( xModel
, UNO_QUERY_THROW
);
1030 catch( RuntimeException
& ) { throw; }
1031 catch( const Exception
& )
1033 DBG_UNHANDLED_EXCEPTION();
1039 // -----------------------------------------------------------------------------
1040 oslInterlockedCount SAL_CALL
ODatabaseModelImpl::acquire()
1042 return osl_incrementInterlockedCount(&m_refCount
);
1044 // -----------------------------------------------------------------------------
1045 oslInterlockedCount SAL_CALL
ODatabaseModelImpl::release()
1047 if ( osl_decrementInterlockedCount(&m_refCount
) == 0 )
1049 acquire(); // prevent multiple releases
1050 m_pDBContext
->removeFromTerminateListener(*this);
1052 m_pDBContext
->storeTransientProperties(*this);
1059 // -----------------------------------------------------------------------------
1060 void ODatabaseModelImpl::commitStorages() SAL_THROW(( IOException
, RuntimeException
))
1064 TStorages::iterator aIter
= m_aStorages
.begin();
1065 TStorages::iterator aEnd
= m_aStorages
.end();
1066 for (; aIter
!= aEnd
; ++aIter
)
1067 commitStorageIfWriteable( aIter
->second
);
1069 catch(const WrappedTargetException
&)
1071 // WrappedTargetException not allowed to leave
1072 throw IOException();
1076 // -----------------------------------------------------------------------------
1077 const AsciiPropertyValue
* ODatabaseModelImpl::getDefaultDataSourceSettings()
1079 static const AsciiPropertyValue aKnownSettings
[] =
1081 // known JDBC settings
1082 AsciiPropertyValue( "JavaDriverClass", makeAny( ::rtl::OUString() ) ),
1083 AsciiPropertyValue( "IgnoreCurrency", makeAny( (sal_Bool
)sal_False
) ),
1084 // known settings for file-based drivers
1085 AsciiPropertyValue( "Extension", makeAny( ::rtl::OUString() ) ),
1086 AsciiPropertyValue( "CharSet", makeAny( ::rtl::OUString() ) ),
1087 AsciiPropertyValue( "HeaderLine", makeAny( (sal_Bool
)sal_True
) ),
1088 AsciiPropertyValue( "FieldDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "," ) ) ) ),
1089 AsciiPropertyValue( "StringDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\"" ) ) ) ),
1090 AsciiPropertyValue( "DecimalDelimiter", makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) ) ) ),
1091 AsciiPropertyValue( "ThousandDelimiter", makeAny( ::rtl::OUString() ) ),
1092 AsciiPropertyValue( "ShowDeleted", makeAny( (sal_Bool
)sal_False
) ),
1093 // known ODBC settings
1094 AsciiPropertyValue( "SystemDriverSettings", makeAny( ::rtl::OUString() ) ),
1095 AsciiPropertyValue( "UseCatalog", makeAny( (sal_Bool
)sal_False
) ),
1096 AsciiPropertyValue( "TypeInfoSettings", makeAny( Sequence
< Any
>()) ),
1097 // settings related to auto increment handling
1098 AsciiPropertyValue( "AutoIncrementCreation", makeAny( ::rtl::OUString() ) ),
1099 AsciiPropertyValue( "AutoRetrievingStatement", makeAny( ::rtl::OUString() ) ),
1100 AsciiPropertyValue( "IsAutoRetrievingEnabled", makeAny( (sal_Bool
)sal_False
) ),
1101 // known Adabas D driver setting
1102 AsciiPropertyValue( "ShutdownDatabase", makeAny( (sal_Bool
)sal_False
) ),
1103 AsciiPropertyValue( "DataCacheSizeIncrement", makeAny( (sal_Int32
)20 ) ),
1104 AsciiPropertyValue( "DataCacheSize", makeAny( (sal_Int32
)20 ) ),
1105 AsciiPropertyValue( "ControlUser", makeAny( ::rtl::OUString() ) ),
1106 AsciiPropertyValue( "ControlPassword", makeAny( ::rtl::OUString() ) ),
1107 // known LDAP driver settings
1108 AsciiPropertyValue( "HostName", makeAny( ::rtl::OUString() ) ),
1109 AsciiPropertyValue( "PortNumber", makeAny( (sal_Int32
)389 ) ),
1110 AsciiPropertyValue( "BaseDN", makeAny( ::rtl::OUString() ) ),
1111 AsciiPropertyValue( "MaxRowCount", makeAny( (sal_Int32
)100 ) ),
1112 // known MySQLNative driver settings
1113 AsciiPropertyValue( "LocalSocket", makeAny( ::rtl::OUString() ) ),
1114 // misc known driver settings
1115 AsciiPropertyValue( "ParameterNameSubstitution", makeAny( (sal_Bool
)sal_False
) ),
1116 AsciiPropertyValue( "AddIndexAppendix", makeAny( (sal_Bool
)sal_True
) ),
1117 AsciiPropertyValue( "IgnoreDriverPrivileges", makeAny( (sal_Bool
)sal_True
) ),
1118 AsciiPropertyValue( "ImplicitCatalogRestriction", Any( ) ),
1119 AsciiPropertyValue( "ImplicitSchemaRestriction", Any( ) ),
1120 // known SDB level settings
1121 AsciiPropertyValue( "NoNameLengthLimit", makeAny( (sal_Bool
)sal_False
) ),
1122 AsciiPropertyValue( "AppendTableAliasName", makeAny( (sal_Bool
)sal_False
) ),
1123 AsciiPropertyValue( "GenerateASBeforeCorrelationName", makeAny( (sal_Bool
)sal_True
) ),
1124 AsciiPropertyValue( "ColumnAliasInOrderBy", makeAny( (sal_Bool
)sal_True
) ),
1125 AsciiPropertyValue( "EnableSQL92Check", makeAny( (sal_Bool
)sal_False
) ),
1126 AsciiPropertyValue( "BooleanComparisonMode", makeAny( BooleanComparisonMode::EQUAL_INTEGER
) ),
1127 AsciiPropertyValue( "TableTypeFilterMode", makeAny( (sal_Int32
)3 ) ),
1128 AsciiPropertyValue( "RespectDriverResultSetType", makeAny( (sal_Bool
)sal_False
) ),
1129 AsciiPropertyValue( "UseSchemaInSelect", makeAny( (sal_Bool
)sal_True
) ),
1130 AsciiPropertyValue( "UseCatalogInSelect", makeAny( (sal_Bool
)sal_True
) ),
1131 AsciiPropertyValue( "EnableOuterJoinEscape", makeAny( (sal_Bool
)sal_True
) ),
1132 AsciiPropertyValue( "PreferDosLikeLineEnds", makeAny( (sal_Bool
)sal_False
) ),
1133 AsciiPropertyValue( "FormsCheckRequiredFields", makeAny( (sal_Bool
)sal_True
) ),
1134 AsciiPropertyValue( "EscapeDateTime", makeAny( (sal_Bool
)sal_True
) ),
1136 AsciiPropertyValue( NULL
, Any() )
1138 return aKnownSettings
;
1141 // -----------------------------------------------------------------------------
1142 TContentPtr
& ODatabaseModelImpl::getObjectContainer( ObjectType _eType
)
1144 OSL_PRECOND( _eType
>= E_FORM
&& _eType
<= E_TABLE
, "ODatabaseModelImpl::getObjectContainer: illegal index!" );
1145 TContentPtr
& rContentPtr
= m_aContainer
[ _eType
];
1147 if ( !rContentPtr
.get() )
1149 rContentPtr
= TContentPtr( new ODefinitionContainer_Impl
);
1150 rContentPtr
->m_pDataSource
= this;
1151 rContentPtr
->m_aProps
.aTitle
= lcl_getContainerStorageName_throw( _eType
);
1156 // -----------------------------------------------------------------------------
1157 void ODatabaseModelImpl::revokeDataSource() const
1159 if ( m_pDBContext
&& m_sDocumentURL
.getLength() )
1160 m_pDBContext
->deregisterPrivate( m_sDocumentURL
);
1163 // -----------------------------------------------------------------------------
1164 bool ODatabaseModelImpl::adjustMacroMode_AutoReject()
1166 return m_aMacroMode
.adjustMacroMode( NULL
);
1169 // -----------------------------------------------------------------------------
1170 bool ODatabaseModelImpl::checkMacrosOnLoading()
1172 ::comphelper::NamedValueCollection
aArgs( m_aArgs
);
1173 Reference
< XInteractionHandler
> xInteraction
;
1174 xInteraction
= aArgs
.getOrDefault( "InteractionHandler", xInteraction
);
1175 return m_aMacroMode
.checkMacrosOnLoading( xInteraction
);
1178 // -----------------------------------------------------------------------------
1179 void ODatabaseModelImpl::resetMacroExecutionMode()
1181 m_aMacroMode
= ::sfx2::DocumentMacroMode( *this );
1184 // -----------------------------------------------------------------------------
1185 Reference
< XStorageBasedLibraryContainer
> ODatabaseModelImpl::getLibraryContainer( bool _bScript
)
1187 Reference
< XStorageBasedLibraryContainer
>& rxContainer( _bScript
? m_xBasicLibraries
: m_xDialogLibraries
);
1188 if ( rxContainer
.is() )
1191 Reference
< XStorageBasedDocument
> xDocument( getModel_noCreate(), UNO_QUERY_THROW
);
1192 // this is only to be called if there already exists a document model - in fact, it is
1193 // to be called by the document model only
1197 Reference
< XStorageBasedLibraryContainer
> (*Factory
)( const Reference
< XComponentContext
>&, const Reference
< XStorageBasedDocument
>&)
1198 = _bScript
? &DocumentScriptLibraryContainer::create
: &DocumentDialogLibraryContainer::create
;
1201 (*Factory
)( m_aContext
.getUNOContext(), xDocument
),
1205 catch( const RuntimeException
& )
1209 catch( const Exception
& )
1211 throw WrappedTargetRuntimeException(
1214 ::cppu::getCaughtException()
1220 // -----------------------------------------------------------------------------
1221 void ODatabaseModelImpl::storeLibraryContainersTo( const Reference
< XStorage
>& _rxToRootStorage
)
1223 if ( m_xBasicLibraries
.is() )
1224 m_xBasicLibraries
->storeLibrariesToStorage( _rxToRootStorage
);
1226 if ( m_xDialogLibraries
.is() )
1227 m_xDialogLibraries
->storeLibrariesToStorage( _rxToRootStorage
);
1230 // -----------------------------------------------------------------------------
1231 Reference
< XStorage
> ODatabaseModelImpl::switchToStorage( const Reference
< XStorage
>& _rxNewRootStorage
)
1233 if ( !_rxNewRootStorage
.is() )
1234 throw IllegalArgumentException();
1236 return impl_switchToStorage_throw( _rxNewRootStorage
);
1239 // -----------------------------------------------------------------------------
1242 void lcl_modifyListening( ::sfx2::IModifiableDocument
& _rDocument
,
1243 const Reference
< XStorage
>& _rxStorage
, ::rtl::Reference
< ::sfx2::DocumentStorageModifyListener
>& _inout_rListener
,
1244 ::vos::IMutex
& _rMutex
, bool _bListen
)
1246 Reference
< XModifiable
> xModify( _rxStorage
, UNO_QUERY
);
1247 OSL_ENSURE( xModify
.is() || !_rxStorage
.is(), "lcl_modifyListening: storage can't notify us!" );
1249 if ( xModify
.is() && !_bListen
&& _inout_rListener
.is() )
1251 xModify
->removeModifyListener( _inout_rListener
.get() );
1254 if ( _inout_rListener
.is() )
1256 _inout_rListener
->dispose();
1257 _inout_rListener
= NULL
;
1260 if ( xModify
.is() && _bListen
)
1262 _inout_rListener
= new ::sfx2::DocumentStorageModifyListener( _rDocument
, _rMutex
);
1263 xModify
->addModifyListener( _inout_rListener
.get() );
1268 // -----------------------------------------------------------------------------
1271 static void lcl_rebaseScriptStorage_throw( const Reference
< XStorageBasedLibraryContainer
>& _rxContainer
,
1272 const Reference
< XStorage
>& _rxNewRootStorage
)
1274 if ( _rxContainer
.is() )
1276 if ( _rxNewRootStorage
.is() )
1277 _rxContainer
->setRootStorage( _rxNewRootStorage
);
1279 // TODO: what to do here? dispose the container?
1284 // -----------------------------------------------------------------------------
1285 Reference
< XStorage
> ODatabaseModelImpl::impl_switchToStorage_throw( const Reference
< XStorage
>& _rxNewRootStorage
)
1287 // stop listening for modifications at the old storage
1288 lcl_modifyListening( *this, m_xDocumentStorage
.getTyped(), m_pStorageModifyListener
, m_aMutexFacade
, false );
1291 m_xDocumentStorage
.reset( _rxNewRootStorage
, SharedStorage::TakeOwnership
);
1293 // start listening for modifications
1294 lcl_modifyListening( *this, m_xDocumentStorage
.getTyped(), m_pStorageModifyListener
, m_aMutexFacade
, true );
1296 // forward new storage to Basic and Dialog library containers
1297 lcl_rebaseScriptStorage_throw( m_xBasicLibraries
, m_xDocumentStorage
.getTyped() );
1298 lcl_rebaseScriptStorage_throw( m_xDialogLibraries
, m_xDocumentStorage
.getTyped() );
1300 m_bReadOnly
= !lcl_storageIsWritable_nothrow( m_xDocumentStorage
.getTyped() );
1301 // TODO: our data source, if it exists, must broadcast the change of its ReadOnly property
1303 return m_xDocumentStorage
.getTyped();
1306 // -----------------------------------------------------------------------------
1307 void ODatabaseModelImpl::switchToURL( const ::rtl::OUString
& _rDocumentLocation
, const ::rtl::OUString
& _rDocumentURL
)
1309 // register at the database context, or change registration
1310 if ( _rDocumentURL
!= m_sDocumentURL
)
1314 if ( m_sDocumentURL
.getLength() )
1315 m_pDBContext
->nameChangePrivate( m_sDocumentURL
, _rDocumentURL
);
1317 m_pDBContext
->registerPrivate( _rDocumentURL
, this );
1320 if ( ( m_sName
== m_sDocumentURL
) // our name is our old URL
1321 || ( !m_sName
.getLength() ) // we do not have a name, yet (i.e. are not registered at the database context)
1324 INetURLObject
aURL( _rDocumentURL
);
1325 if ( aURL
.GetProtocol() != INET_PROT_NOT_VALID
)
1327 m_sName
= _rDocumentURL
;
1328 // TODO: our data source must broadcast the change of the Name property
1334 m_sDocFileLocation
= _rDocumentLocation
.getLength() ? _rDocumentLocation
: _rDocumentURL
;
1335 m_sDocumentURL
= _rDocumentURL
;
1338 // -----------------------------------------------------------------------------
1339 bool ODatabaseModelImpl::isDatabaseStorage( const Reference
< XStorage
>& _rxStorage
) const
1341 TStorages::const_iterator pos
= m_aStorages
.find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "database" ) ) );
1342 if ( ( pos
!= m_aStorages
.end() )
1343 && ( pos
->second
== _rxStorage
)
1351 // -----------------------------------------------------------------------------
1352 ::rtl::OUString
ODatabaseModelImpl::getObjectContainerStorageName( const ObjectType _eType
)
1354 return lcl_getContainerStorageName_throw( _eType
);
1357 // -----------------------------------------------------------------------------
1358 sal_Int16
ODatabaseModelImpl::getCurrentMacroExecMode() const
1360 sal_Int16 nCurrentMode
= MacroExecMode::NEVER_EXECUTE
;
1363 ::comphelper::NamedValueCollection
aArgs( m_aArgs
);
1364 nCurrentMode
= aArgs
.getOrDefault( "MacroExecutionMode", nCurrentMode
);
1366 catch( const Exception
& )
1368 DBG_UNHANDLED_EXCEPTION();
1370 return nCurrentMode
;
1373 // -----------------------------------------------------------------------------
1374 sal_Bool
ODatabaseModelImpl::setCurrentMacroExecMode( sal_uInt16 nMacroMode
)
1378 ::comphelper::NamedValueCollection
aArgs( m_aArgs
);
1379 aArgs
.put( "MacroExecutionMode", nMacroMode
);
1383 catch( const Exception
& )
1385 DBG_UNHANDLED_EXCEPTION();
1391 // -----------------------------------------------------------------------------
1392 ::rtl::OUString
ODatabaseModelImpl::getDocumentLocation() const
1394 // don't return getURL() (or m_sDocumentURL, which is the same). In case we were recovered
1395 // after a previous crash of OOo, m_sDocFileLocation points to the file which were loaded from,
1396 // and this is the one we need for security checks.
1397 return getDocFileLocation();
1400 // -----------------------------------------------------------------------------
1401 Reference
< XStorage
> ODatabaseModelImpl::getLastCommitDocumentStorage()
1403 // we do not support signing the scripting storages, so we're allowed to
1404 // return <NULL/> here.
1405 return Reference
< XStorage
>();
1408 // -----------------------------------------------------------------------------
1409 ODatabaseModelImpl::EmbeddedMacros
ODatabaseModelImpl::determineEmbeddedMacros()
1411 if ( !m_aEmbeddedMacros
)
1413 if ( ::sfx2::DocumentMacroMode::storageHasMacros( const_cast< ODatabaseModelImpl
* >( this )->getOrCreateRootStorage() ) )
1415 m_aEmbeddedMacros
.reset( eDocumentWideMacros
);
1417 else if ( lcl_hasObjectsWithMacros_nothrow( const_cast< ODatabaseModelImpl
& >( *this ), E_FORM
)
1418 || lcl_hasObjectsWithMacros_nothrow( const_cast< ODatabaseModelImpl
& >( *this ), E_REPORT
)
1421 m_aEmbeddedMacros
.reset( eSubDocumentMacros
);
1425 m_aEmbeddedMacros
.reset( eNoMacros
);
1428 return *m_aEmbeddedMacros
;
1431 // -----------------------------------------------------------------------------
1432 sal_Bool
ODatabaseModelImpl::documentStorageHasMacros() const
1434 const_cast< ODatabaseModelImpl
* >( this )->determineEmbeddedMacros();
1435 return ( *m_aEmbeddedMacros
!= eNoMacros
);
1438 // -----------------------------------------------------------------------------
1439 Reference
< XEmbeddedScripts
> ODatabaseModelImpl::getEmbeddedDocumentScripts() const
1441 return Reference
< XEmbeddedScripts
>( getModel_noCreate(), UNO_QUERY
);
1444 // -----------------------------------------------------------------------------
1445 sal_Int16
ODatabaseModelImpl::getScriptingSignatureState() const
1447 // no support for signatures at the moment
1448 return SIGNATURESTATE_NOSIGNATURES
;
1451 // -----------------------------------------------------------------------------
1452 void ODatabaseModelImpl::showBrokenSignatureWarning( const Reference
< XInteractionHandler
>& /*_rxInteraction*/ ) const
1454 OSL_ENSURE( false, "ODatabaseModelImpl::showBrokenSignatureWarning: signatures can't be broken - we do not support them!" );
1457 // -----------------------------------------------------------------------------
1458 void ODatabaseModelImpl::storageIsModified()
1460 setModified( sal_True
);
1463 // -----------------------------------------------------------------------------
1464 ModelDependentComponent::ModelDependentComponent( const ::rtl::Reference
< ODatabaseModelImpl
>& _model
)
1466 ,m_aMutex( _model
->getSharedMutex() )
1470 // -----------------------------------------------------------------------------
1471 ModelDependentComponent::~ModelDependentComponent()
1475 //........................................................................
1476 } // namespace dbaccess
1477 //........................................................................