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 DBACCESS_CONNECTION_DEPENDENT_HXX
29 #define DBACCESS_CONNECTION_DEPENDENT_HXX
30 
31 /** === begin UNO includes === **/
32 #include <com/sun/star/sdbc/XConnection.hpp>
33 #include <com/sun/star/lang/DisposedException.hpp>
34 /** === end UNO includes === **/
35 
36 #include <comphelper/componentcontext.hxx>
37 #include <cppuhelper/weakref.hxx>
38 #include <osl/mutex.hxx>
39 
40 //........................................................................
41 namespace sdbtools
42 {
43 //........................................................................
44 
45 	//====================================================================
46 	//= ConnectionDependentComponent
47 	//====================================================================
48     class ConnectionDependentComponent
49     {
50     private:
51         mutable ::osl::Mutex    m_aMutex;
52         ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XConnection >
53                                 m_aConnection;
54         ::comphelper::ComponentContext
55                                 m_aContext;
56 
57         /** a hard reference to the connection we're working for
58 
59             This member is only valid as long as a EntryGuard is on the stack.
60             The guard will, in its constructor, set the member, and reset it in its destructor.
61             This ensures that the connection is only held hard when it's needed, and weak otherwise.
62         */
63         ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >
64                                 m_xConnection;
65 
66     protected:
67         ::osl::Mutex&   getMutex() const { return m_aMutex; }
68 
69         const ::comphelper::ComponentContext&
70                         getContext() const { return m_aContext; }
71 
72     protected:
73         class EntryGuard;
74 
75     protected:
76         ConnectionDependentComponent( const ::comphelper::ComponentContext& _rContext )
77             :m_aContext( _rContext )
78         {
79         }
80 
81         /** sets the connection we depend on.
82 
83             To be called exactly once.
84 
85             @param  _rxConnection
86                 the connection to set
87         */
88         void    setWeakConnection( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection )
89         {
90             m_aConnection = _rxConnection;
91         }
92 
93         const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >&
94                 getConnection() const { return m_xConnection; }
95 
96     public:
97 	struct GuardAccess;
98 	friend struct GuardAccess;
99         /** helper for granting exclusive access to various other methods
100         */
101         struct GuardAccess { friend class EntryGuard; private: GuardAccess() { } };
102 
103         ::osl::Mutex&   getMutex( GuardAccess ) const { return m_aMutex; }
104 
105         inline bool acquireConnection( GuardAccess )
106         {
107             m_xConnection = (::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >)m_aConnection;
108             return m_xConnection.is();
109         }
110         inline void releaseConnection( GuardAccess )
111         {
112             m_xConnection.clear();
113         }
114     };
115 
116 	//====================================================================
117 	//= ConnectionDependentComponent::EntryGuard
118 	//====================================================================
119     /** a class for guarding methods of a connection-dependent component
120 
121         This class serves multiple purposes:
122         <ul><li>It ensures multi-threading safety by guarding the component's mutex
123                 as long as it lives.</li>
124             <li>It ensures that the component's connection is alive. The constructor
125                 throws a DisposedException if no hard reference to the connection can
126                 be obtained.</li>
127         </ul>
128     */
129     class ConnectionDependentComponent::EntryGuard
130     {
131     private:
132         ::osl::MutexGuard               m_aMutexGuard;
133         ConnectionDependentComponent&   m_rComponent;
134 
135     public:
136         EntryGuard( ConnectionDependentComponent& _rComponent )
137             :m_aMutexGuard( _rComponent.getMutex( ConnectionDependentComponent::GuardAccess() ) )
138             ,m_rComponent( _rComponent )
139         {
140             if ( !m_rComponent.acquireConnection( ConnectionDependentComponent::GuardAccess() ) )
141                 throw ::com::sun::star::lang::DisposedException();
142         }
143 
144         ~EntryGuard()
145         {
146             m_rComponent.releaseConnection( ConnectionDependentComponent::GuardAccess() );
147         }
148     };
149 
150 
151 //........................................................................
152 } // namespace sdbtools
153 //........................................................................
154 
155 #endif // DBACCESS_CONNECTION_DEPENDENT_HXX
156 
157