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 #ifndef _DBA_COREDATAACCESS_MODELIMPL_HXX_
25 #define _DBA_COREDATAACCESS_MODELIMPL_HXX_
26 
27 #include "apitools.hxx"
28 #include "bookmarkcontainer.hxx"
29 #include "ContentHelper.hxx"
30 #include "core_resource.hxx"
31 #include "documentevents.hxx"
32 
33 /** === begin UNO includes === **/
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <com/sun/star/beans/PropertyValue.hpp>
36 #include <com/sun/star/beans/XPropertyAccess.hpp>
37 #include <com/sun/star/container/XContainerListener.hpp>
38 #include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
39 #include <com/sun/star/document/XEventListener.hpp>
40 #include <com/sun/star/document/XStorageBasedDocument.hpp>
41 #include <com/sun/star/embed/ElementModes.hpp>
42 #include <com/sun/star/embed/XStorage.hpp>
43 #include <com/sun/star/embed/XTransactionListener.hpp>
44 #include <com/sun/star/frame/XModel.hpp>
45 #include <com/sun/star/frame/XStorable.hpp>
46 #include <com/sun/star/lang/NotInitializedException.hpp>
47 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
48 #include <com/sun/star/lang/XServiceInfo.hpp>
49 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
50 #include <com/sun/star/sdb/XBookmarksSupplier.hpp>
51 #include <com/sun/star/sdb/XCompletedConnection.hpp>
52 #include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
53 #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
54 #include <com/sun/star/sdb/XReportDocumentsSupplier.hpp>
55 #include <com/sun/star/sdbc/XDataSource.hpp>
56 #include <com/sun/star/sdbc/XIsolatedConnection.hpp>
57 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
58 #include <com/sun/star/util/XCloseable.hpp>
59 #include <com/sun/star/util/XFlushable.hpp>
60 #include <com/sun/star/util/XModifiable.hpp>
61 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
62 #include <com/sun/star/util/XNumberFormatter.hpp>
63 #include <com/sun/star/util/XRefreshable.hpp>
64 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
65 #include <com/sun/star/frame/DoubleInitializationException.hpp>
66 /** === end UNO includes === **/
67 
68 #include <comphelper/broadcasthelper.hxx>
69 #include <comphelper/namedvaluecollection.hxx>
70 #include <comphelper/proparrhlp.hxx>
71 #include <comphelper/sharedmutex.hxx>
72 #include <connectivity/CommonTools.hxx>
73 #include <cppuhelper/propshlp.hxx>
74 #include <cppuhelper/weakref.hxx>
75 #include <sfx2/docmacromode.hxx>
76 #include <sfx2/docstoragemodifylistener.hxx>
77 #include <tools/string.hxx>
78 #include <unotools/sharedunocomponent.hxx>
79 #include <vos/mutex.hxx>
80 
81 #include <memory>
82 
83 namespace comphelper
84 {
85     class NamedValueCollection;
86 }
87 
88 //........................................................................
89 namespace dbaccess
90 {
91 //........................................................................
92 
93 typedef ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XConnection > OWeakConnection;
94 typedef std::vector< OWeakConnection > OWeakConnectionArray;
95 
96 struct AsciiPropertyValue
97 {
98     // note: the canonic member order would be AsciiName / DefaultValue, but
99     // this crashes on unxlngi6.pro, since there's a bug which somehow results in
100     // getDefaultDataSourceSettings returning corrupted Any instances then.
101     ::com::sun::star::uno::Any          DefaultValue;
102     const sal_Char*                     AsciiName;
103     const ::com::sun::star::uno::Type&  ValueType;
104 
AsciiPropertyValuedbaccess::AsciiPropertyValue105     AsciiPropertyValue()
106         :DefaultValue( )
107         ,AsciiName( NULL )
108         ,ValueType( ::cppu::UnoType< ::cppu::UnoVoidType >::get() )
109     {
110     }
111 
AsciiPropertyValuedbaccess::AsciiPropertyValue112     AsciiPropertyValue( const sal_Char* _pAsciiName, const ::com::sun::star::uno::Any& _rDefaultValue )
113         :DefaultValue( _rDefaultValue )
114         ,AsciiName( _pAsciiName )
115         ,ValueType( _rDefaultValue.getValueType() )
116     {
117         OSL_ENSURE( ValueType.getTypeClass() != ::com::sun::star::uno::TypeClass_VOID,
118             "AsciiPropertyValue::AsciiPropertyValue: NULL values not allowed here, use the other CTOR for this!" );
119     }
AsciiPropertyValuedbaccess::AsciiPropertyValue120     AsciiPropertyValue( const sal_Char* _pAsciiName, const ::com::sun::star::uno::Type& _rValeType )
121         :DefaultValue()
122         ,AsciiName( _pAsciiName )
123         ,ValueType( _rValeType )
124     {
125         OSL_ENSURE( ValueType.getTypeClass() != ::com::sun::star::uno::TypeClass_VOID,
126             "AsciiPropertyValue::AsciiPropertyValue: VOID property values not supported!" );
127     }
128 };
129 
130 class ODatabaseContext;
131 class OSharedConnectionManager;
132 
133 //============================================================
134 //= VosMutexFacade
135 //============================================================
136 /** a class which provides an IMutex interface to an OSL-based mutex
137 */
138 class VosMutexFacade : public ::vos::IMutex
139 {
140 public:
141     /** beware of life time: the mutex you pass here must live as least as long
142         as the VosMutexFacade instance lives.
143     */
144     VosMutexFacade( ::osl::Mutex& _rMutex );
145 
146     // IMutex
147     virtual void SAL_CALL acquire();
148     virtual sal_Bool SAL_CALL tryToAcquire();
149     virtual void SAL_CALL release();
150 
151 private:
152     ::osl::Mutex&   m_rMutex;
153 };
154 
155 
156 //============================================================
157 //= ODatabaseModelImpl
158 //============================================================
159 typedef ::utl::SharedUNOComponent< ::com::sun::star::embed::XStorage >  SharedStorage;
160 
161 class ODatabaseContext;
162 class DocumentStorageAccess;
163 class OSharedConnectionManager;
164 class ODatabaseModelImpl    :public ::rtl::IReference
165                             ,public ::sfx2::IMacroDocumentAccess
166                             ,public ::sfx2::IModifiableDocument
167 {
168 public:
169 	enum ObjectType
170 	{
171 		E_FORM   = 0,
172 		E_REPORT = 1,
173 		E_QUERY  = 2,
174 		E_TABLE  = 3
175 	};
176 
177     enum EmbeddedMacros
178     {
179         // the database document (storage) itself contains macros
180         eDocumentWideMacros,
181         // there are sub document( storage)s containing macros
182         eSubDocumentMacros,
183         // there are no known macro( storage)s
184         eNoMacros
185     };
186 
187 private:
188     OModuleClient                                                               m_aModuleClient;
189     ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XModel >	    m_xModel;
190     ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XDataSource >	m_xDataSource;
191 
192     DocumentStorageAccess*                                                      m_pStorageAccess;
193     ::comphelper::SharedMutex                                                   m_aMutex;
194     VosMutexFacade                                                              m_aMutexFacade;
195 	::std::vector< TContentPtr >                                                m_aContainer;   // one for each ObjectType
196     ::sfx2::DocumentMacroMode                                                   m_aMacroMode;
197     sal_Int16                                                                   m_nImposedMacroExecMode;
198 
199     ::com::sun::star::uno::Reference< ::com::sun::star::script::XStorageBasedLibraryContainer > m_xBasicLibraries;
200     ::com::sun::star::uno::Reference< ::com::sun::star::script::XStorageBasedLibraryContainer > m_xDialogLibraries;
201 
202     SharedStorage                                                               m_xDocumentStorage;
203     ::rtl::Reference< ::sfx2::DocumentStorageModifyListener >                   m_pStorageModifyListener;
204 	ODatabaseContext*									                        m_pDBContext;
205     DocumentEventsData                                                          m_aDocumentEvents;
206 
207     ::comphelper::NamedValueCollection                                          m_aMediaDescriptor;
208     /// the URL the document was loaded from
209 	::rtl::OUString										                        m_sDocFileLocation;
210 
211 	oslInterlockedCount									m_refCount;
212 
213     /// do we have any object (forms/reports) which contains macros?
214     ::boost::optional< EmbeddedMacros >                 m_aEmbeddedMacros;
215 
216     /// true if setting the Modified flag of the document is currently locked
217     bool                                                m_bModificationLock;
218 
219     /// true if and only if a database document existed previously (though meanwhile disposed), and was already initialized
220     bool                                                m_bDocumentInitialized;
221 
222     /** the URL which the document should report as it's URL
223 
224         This might differ from ->m_sDocFileLocation in case the document was loaded
225         as part of a crash recovery process. In this case, ->m_sDocFileLocation points to
226         the temporary file where the DB had been saved to, after a crash.
227         ->m_sDocumentURL then is the URL of the document which actually had
228         been recovered.
229     */
230     ::rtl::OUString                                     m_sDocumentURL;
231 
232 public:
233     OWeakConnectionArray                                                        m_aConnections;
234     const ::comphelper::ComponentContext                                        m_aContext;
235 
236 public:
237 	::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess >	m_xCommandDefinitions;
238 	::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess >	m_xTableDefinitions;
239 
240 	::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >
241 														m_xNumberFormatsSupplier;
242 	::rtl::OUString										m_sConnectURL;
243 	::rtl::OUString										m_sName;		// transient, our creator has to tell us the title
244 	::rtl::OUString										m_sUser;
245 	::rtl::OUString										m_aPassword;	// transient !
246     ::rtl::OUString                                     m_sFailedPassword;
247 	::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>
248 														m_aLayoutInformation;
249     sal_Int32                                           m_nLoginTimeout;
250 	sal_Bool											m_bReadOnly : 1;
251 	sal_Bool											m_bPasswordRequired : 1;
252 	sal_Bool											m_bSuppressVersionColumns : 1;
253 	sal_Bool											m_bModified : 1;
254 	sal_Bool											m_bDocumentReadOnly : 1;
255     ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyAccess >
256                                                         m_xSettings;
257 	::com::sun::star::uno::Sequence< ::rtl::OUString >	m_aTableFilter;
258 	::com::sun::star::uno::Sequence< ::rtl::OUString >	m_aTableTypeFilter;
259 	OSharedConnectionManager*							m_pSharedConnectionManager;
260     ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >
261                                                         m_xSharedConnectionManager;
262 	sal_uInt16											m_nControllerLockCount;
263 
264     void reset();
265 
266     /** determines whether the database document has an embedded data storage
267     */
isEmbeddedDatabase() const268     inline bool isEmbeddedDatabase() const { return ( m_sConnectURL.compareToAscii( "sdbc:embedded:", 14 ) == 0 ); }
269 
270     /** stores the embedded storage ("database")
271 
272         @param _bPreventRootCommits
273             Normally, committing the embedded storage results in also commiting the root storage
274             - this is an automatism for data safety reasons.
275             If you pass <TRUE/> here, committing the root storage is prevented for this particular
276             call.
277 		@return <TRUE/> if the storage could be commited, otherwise <FALSE/>
278 	*/
279 	bool        commitEmbeddedStorage( bool _bPreventRootCommits = false );
280 
281     /// commits all sub storages
282     void commitStorages()
283             SAL_THROW(( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException ));
284 
285 	ODatabaseModelImpl(
286 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory,
287 		ODatabaseContext& _pDBContext
288 	);
289 	virtual ~ODatabaseModelImpl();
290 
291 	ODatabaseModelImpl(
292 		const ::rtl::OUString& _rRegistrationName,
293 		const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory,
294 		ODatabaseContext& _rDBContext
295 		);
296 
297 	// XEventListener
298 	void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
299 
300     void setModified( sal_Bool bModified );
301 
302 	void dispose();
303 
getURL() const304     inline ::rtl::OUString getURL() const               { return m_sDocumentURL;     }
getDocFileLocation() const305     inline ::rtl::OUString getDocFileLocation() const   { return m_sDocFileLocation; }
306 
307 	::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
308             getStorage(
309                 const ObjectType _eType, const sal_Int32 _nDesiredMode = ::com::sun::star::embed::ElementModes::READWRITE );
310 
311 // helper
312 	const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >&
313 			getNumberFormatsSupplier();
314 
315     DocumentEventsData&
getDocumentEvents()316             getDocumentEvents() { return m_aDocumentEvents; }
317 
318     const ::comphelper::NamedValueCollection&
getMediaDescriptor() const319             getMediaDescriptor() const { return m_aMediaDescriptor; }
320 
321     void    setResource(
322                 const ::rtl::OUString& _rURL,
323                 const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArgs
324             );
325     void    setDocFileLocation(
326                 const ::rtl::OUString& i_rLoadedFrom
327             );
328 
329     static ::comphelper::NamedValueCollection
330             stripLoadArguments( const ::comphelper::NamedValueCollection& _rArguments );
331 
332 // other stuff
333 	void	flushTables();
334 
335     // disposes all elements in m_aStorages, and clears it
336     void    disposeStorages() SAL_THROW(());
337 
338     /// creates a ->com::sun::star::embed::StorageFactory
339     ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory >
340             createStorageFactory() const;
341 
342     /// commits our storage
343     void    commitRootStorage();
344 
345     /// commits a given storage if it's not readonly, ignoring (but asserting) all errors
346     static  bool    commitStorageIfWriteable_ignoreErrors(
347                 const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxStorage
348             )
349             SAL_THROW(());
350 
351 	void clearConnections();
352 
353 	        ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > getOrCreateRootStorage();
getRootStorage() const354     inline  ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > getRootStorage() const { return m_xDocumentStorage.getTyped(); }
resetRootStroage()355     inline  void resetRootStroage() { impl_switchToStorage_throw( NULL ); }
356 
357 	/** returns the data source. If it doesn't exist it will be created
358 	*/
359 	::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource> getOrCreateDataSource();
360 
361     /** returns the model, if there already exists one
362     */
363 	::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > getModel_noCreate() const;
364 
365     /** returns a new ->ODatabaseDocument
366 
367         @param _bInitializeIfNecessary
368             calls XLoadable::initNew on the newly created model, if necessary
369 
370         @precond
371             No ->ODatabaseDocument exists so far
372 
373         @seealso
374             getModel_noCreate
375     */
376 	::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > createNewModel_deliverOwnership( bool _bInitialize );
377 
ResetModelAccessdbaccess::ODatabaseModelImpl::ResetModelAccess378     struct ResetModelAccess { friend class ODatabaseDocument; private: ResetModelAccess() { } };
379 
380     /** resets the model to NULL
381 
382         Only to be called when the model is being disposed
383     */
384     void    modelIsDisposing( const bool _wasInitialized, ResetModelAccess );
385 
hadInitializedDocument() const386     bool    hadInitializedDocument() const { return m_bDocumentInitialized; }
387 
388     DocumentStorageAccess*
389             getDocumentStorageAccess();
390 
391     ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentSubStorageSupplier >
392             getDocumentSubStorageSupplier();
393 
getSharedMutex() const394     inline const ::comphelper::SharedMutex& getSharedMutex() const { return m_aMutex; }
395 
396 	/** @see osl_incrementInterlockedCount.
397 	 */
398 	virtual oslInterlockedCount SAL_CALL acquire();
399 
400 	/** @see osl_decrementInterlockedCount.
401 	 */
402 	virtual oslInterlockedCount SAL_CALL release();
403 
404     /// returns a all known data source settings, including their default values
405     static const AsciiPropertyValue* getDefaultDataSourceSettings();
406 
407     /** retrieves the requested container of objects (forms/reports/tables/queries)
408     */
409     TContentPtr&    getObjectContainer( const ObjectType _eType );
410 
411     /** returns the name of the storage which is used to stored objects of the given type, if applicable
412     */
413     static ::rtl::OUString
414                     getObjectContainerStorageName( const ObjectType _eType );
415 
416     /** revokes the data source registration at the database context
417     */
418     void            revokeDataSource() const;
419 
420     /** determines whether a given object storage contains macros
421     */
422     static bool     objectHasMacros(
423                         const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxContainerStorage,
424                         const ::rtl::OUString& _rPersistentName
425                     );
426 
427     /** determines which kind of embedded macros are present in the document
428     */
429     EmbeddedMacros  determineEmbeddedMacros();
430 
431     /** checks our document's macro execution mode, using the interaction handler as supplied with our
432         load arguments
433     */
434     bool            checkMacrosOnLoading();
435 
436     /** adjusts our document's macro execution mode, without using any UI, assuming the user
437         would reject execution of macros, if she would have been asked.
438 
439         If checkMacrosOnLoading has been called before (and thus the macro execution mode
440         is already adjusted), then the current execution mode is simply returned.
441 
442         @return
443             whether or not macro execution is allowed
444     */
445     bool            adjustMacroMode_AutoReject();
446 
447     /** resets our macro execute mode, so next time  the checkMacrosOnLoading is called, it will
448         behave as if it has never been called before
449     */
450     void            resetMacroExecutionMode();
451 
452     /** ensures that ->m_xBasicLibraries resp. m_xDialogLibraries exists
453 
454         @return
455             the requested library container. Is never <NULL/>.
456 
457         @throws RuntimeException
458             if something does wrong, which indicates a server error in the installation
459     */
460     ::com::sun::star::uno::Reference< ::com::sun::star::script::XStorageBasedLibraryContainer >
461             getLibraryContainer( bool _bScript );
462 
463     /** lets our library containers store themself into the given root storage
464     */
465     void    storeLibraryContainersTo( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxToRootStorage );
466 
467     /** rebases the document to the given storage
468 
469         No actual committing, copying, saving, whatsoever happens. The storage is just remembered as the documents
470         new storage, nothing more.
471 
472         @throws ::com::sun::star::lang::IllegalArgumentException
473             if the given storage is <NULL/>
474         @throws ::com::sun::star::lang::RuntimeException
475             if any of the invoked operations does so
476     */
477     ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
478             switchToStorage(
479                 const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxNewRootStorage
480             );
481 
482     /** returns the macro mode imposed by an external instance, which passed it to attachResource
483     */
getImposedMacroExecMode() const484     sal_Int16       getImposedMacroExecMode() const
485     {
486         return m_nImposedMacroExecMode;
487     }
setImposedMacroExecMode(const sal_Int16 _nMacroMode)488     void            setImposedMacroExecMode( const sal_Int16 _nMacroMode )
489     {
490         m_nImposedMacroExecMode = _nMacroMode;
491     }
492 
493 public:
494     // IMacroDocumentAccess overridables
495     virtual sal_Int16 getCurrentMacroExecMode() const;
496     virtual sal_Bool setCurrentMacroExecMode( sal_uInt16 );
497     virtual ::rtl::OUString getDocumentLocation() const;
498     virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > getZipStorageToSign();
499     virtual sal_Bool documentStorageHasMacros() const;
500     virtual ::com::sun::star::uno::Reference< ::com::sun::star::document::XEmbeddedScripts > getEmbeddedDocumentScripts() const;
501     virtual sal_Int16 getScriptingSignatureState();
502     virtual sal_Bool hasTrustedScriptingSignature( sal_Bool bAllowUIToAddAuthor );
503     virtual void showBrokenSignatureWarning( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxInteraction ) const;
504 
505     // IModifiableDocument
506     virtual void storageIsModified();
507 
508     // don't use directly, use the ModifyLock class instead
lockModify()509     void    lockModify()              { m_bModificationLock = true; }
unlockModify()510     void    unlockModify()            { m_bModificationLock = false; }
isModifyLocked() const511     bool    isModifyLocked() const    { return m_bModificationLock; }
512 
513 private:
514     void    impl_construct_nothrow();
515     ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
516             impl_switchToStorage_throw( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& _rxNewRootStorage );
517 
518     /** switches to the given document URL, which denotes the logical URL of the document, not necessariy the
519         URL where the doc was loaded/recovered from
520     */
521     void    impl_switchToLogicalURL(
522                 const ::rtl::OUString& i_rDocumentURL
523             );
524 
525 };
526 
527 /** a small base class for UNO components whose functionality depends on a ODatabaseModelImpl
528 */
529 class ModelDependentComponent
530 {
531 protected:
532     ::rtl::Reference< ODatabaseModelImpl >  m_pImpl;
533     mutable ::comphelper::SharedMutex       m_aMutex;
534 
535 protected:
536     ModelDependentComponent( const ::rtl::Reference< ODatabaseModelImpl >& _model );
537     virtual ~ModelDependentComponent();
538 
539     /** returns the component itself
540     */
541     virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getThis() const = 0;
542 
getMutex() const543     inline ::osl::Mutex& getMutex() const
544     {
545         return m_aMutex;
546     }
547 
548 public:
GuardAccessdbaccess::ModelDependentComponent::GuardAccess549     struct GuardAccess { friend class ModelMethodGuard; private: GuardAccess() { } };
550 
551     /** returns the mutex used for thread safety
552 
553         @throws ::com::sun::star::lang::DisposedException
554             if m_pImpl is <NULL/>. Usually, you will set this member in your derived
555             component's <code>dispose</code> method to <NULL/>.
556     */
getMutex(GuardAccess) const557     inline ::osl::Mutex& getMutex( GuardAccess ) const
558     {
559         return getMutex();
560     }
getImpl(GuardAccess)561     inline ::rtl::Reference< ODatabaseModelImpl > getImpl( GuardAccess )
562     {
563         return m_pImpl;
564     }
565 
566     /// checks whether the component is already disposed, throws a DisposedException if so
checkDisposed() const567     inline void checkDisposed() const
568     {
569         if ( !m_pImpl.is() )
570             throw ::com::sun::star::lang::DisposedException( ::rtl::OUString::createFromAscii( "Component is already disposed." ), getThis() );
571     }
572 
lockModify()573     inline void lockModify()
574     {
575         m_pImpl->lockModify();
576     }
577 
unlockModify()578     inline void unlockModify()
579     {
580         m_pImpl->unlockModify();
581     }
582 };
583 
584 class ModifyLock
585 {
586 public:
ModifyLock(ModelDependentComponent & _component)587     ModifyLock( ModelDependentComponent& _component )
588         :m_rComponent( _component )
589     {
590         m_rComponent.lockModify();
591     }
592 
~ModifyLock()593     ~ModifyLock()
594     {
595         m_rComponent.unlockModify();
596     }
597 
598 private:
599     ModelDependentComponent&    m_rComponent;
600 };
601 
602 /** a guard for public methods of objects dependent on a ODatabaseModelImpl instance
603 
604     Just put this guard onto the stack at the beginning of your method. Don't bother yourself
605     with a MutexGuard, checks for being disposed, and the like.
606 */
607 class ModelMethodGuard : public ::osl::ResettableMutexGuard
608 {
609 private:
610     typedef ::osl::ResettableMutexGuard             BaseMutexGuard;
611 
612 public:
613     /** constructs the guard
614 
615         @param _component
616             the component whose functionality depends on a ODatabaseModelImpl instance
617 
618         @throws ::com::sun::star::lang::DisposedException
619             If the given component is already disposed
620     */
ModelMethodGuard(const ModelDependentComponent & _component)621     ModelMethodGuard( const ModelDependentComponent& _component )
622         :BaseMutexGuard( _component.getMutex( ModelDependentComponent::GuardAccess() ) )
623     {
624         _component.checkDisposed();
625     }
626 
~ModelMethodGuard()627     ~ModelMethodGuard()
628     {
629     }
630 };
631 
632 //........................................................................
633 }	// namespace dbaccess
634 //........................................................................
635 
636 #endif // _DBA_COREDATAACCESS_DATALINK_HXX_
637 
638