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