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