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 __FRAMEWORK_LOADENV_ACTIONLOCKGUARD_HXX_
25 #define __FRAMEWORK_LOADENV_ACTIONLOCKGUARD_HXX_
26 
27 //_______________________________________________
28 // includes of own project
29 
30 #include <threadhelp/threadhelpbase.hxx>
31 #include <threadhelp/resetableguard.hxx>
32 
33 //_______________________________________________
34 // includes of uno interface
35 #include <com/sun/star/document/XActionLockable.hpp>
36 
37 //_______________________________________________
38 // includes of an other project
39 
40 //_______________________________________________
41 // namespace
42 
43 namespace framework{
44 
45 #ifndef css
46 namespace css = ::com::sun::star;
47 #endif
48 
49 //_______________________________________________
50 // definitions
51 
52 /** @short  implements a guard, which can use the interface
53             <type scope="com::sun::star::document">XActionLockable</type>.
54 
55     @descr  This guard should be used to be shure, that any lock will be
56             released. Otherwhise the locaked document can hinder the office on shutdown!
57 */
58 class ActionLockGuard : private ThreadHelpBase
59 {
60     //-------------------------------------------
61     // member
62 
63     private:
64 
65         /** @short  points to the object, which can be locked from outside. */
66         css::uno::Reference< css::document::XActionLockable > m_xActionLock;
67 
68         /** @short  knows if a lock exists on the internal lock object
69                     forced by this guard instance. */
70         sal_Bool m_bActionLocked;
71 
72     //-------------------------------------------
73     // interface
74 
75     public:
76 
77         //---------------------------------------
78         /** @short  default ctor to initialize a "non working guard".
79 
80             @descr  That can be usefull in cases, where no resource still exists,
81                     but will be available next time. Then this guard can be used
82                     in a mode "use guard for more then one resources".
83          */
ActionLockGuard()84         ActionLockGuard()
85             : ThreadHelpBase (         )
86             , m_bActionLocked(sal_False)
87         {
88         }
89 
90         //---------------------------------------
91         /** @short  initialize new guard instance and lock the given resource immediatly.
92 
93             @param  xLock
94                     points to the outside resource, which should be locked.
95          */
ActionLockGuard(const css::uno::Reference<css::document::XActionLockable> & xLock)96         ActionLockGuard(const css::uno::Reference< css::document::XActionLockable >& xLock)
97             : ThreadHelpBase (         )
98             , m_bActionLocked(sal_False)
99         {
100             setResource(xLock);
101         }
102 
103         //---------------------------------------
104         /** @short  release this guard instance and make shure, that no lock
105                     will exist afterwards on the internal wrapped resource.
106          */
~ActionLockGuard()107         virtual ~ActionLockGuard()
108         {
109             unlock();
110         }
111 
112         //---------------------------------------
113         /** @short  set a new resource for locking at this guard.
114 
115             @descr  This call will fail, if an internal resource already exists
116                     and is currently locked.
117 
118             @param  xLock
119                     points to the outside resource, which should be locked.
120 
121             @return sal_True, if new resource could be set and locked.
122                     sal_False otherwhise.
123          */
setResource(const css::uno::Reference<css::document::XActionLockable> & xLock)124         virtual sal_Bool setResource(const css::uno::Reference< css::document::XActionLockable >& xLock)
125         {
126             // SAFE -> ..........................
127             ResetableGuard aMutexLock(m_aLock);
128 
129             if (m_bActionLocked || !xLock.is())
130                 return sal_False;
131 
132             m_xActionLock = xLock;
133             m_xActionLock->addActionLock();
134             m_bActionLocked = m_xActionLock->isActionLocked();
135             // <- SAFE ..........................
136 
137             return sal_True;
138         }
139 
140         //---------------------------------------
141         /** @short  set a new resource for locking at this guard.
142 
143             @descr  This call will fail, if an internal resource already exists
144                     and is currently locked.
145 
146             @param  xLock
147                     points to the outside resource, which should be locked.
148 
149             @return sal_True, if new resource could be set and locked.
150                     sal_False otherwhise.
151          */
freeResource()152         virtual void freeResource()
153         {
154             // SAFE -> ..........................
155             ResetableGuard aMutexLock(m_aLock);
156 
157             css::uno::Reference< css::document::XActionLockable > xLock   = m_xActionLock  ;
158             sal_Bool                                              bLocked = m_bActionLocked;
159 
160             m_xActionLock.clear();
161             m_bActionLocked = sal_False;
162 
163             aMutexLock.unlock();
164             // <- SAFE ..........................
165 
166             if (bLocked && xLock.is())
167                 xLock->removeActionLock();
168         }
169 
170         //---------------------------------------
171         /** @short  lock the internal wrapped resource, if its not already done. */
lock()172         virtual void lock()
173         {
174             // SAFE -> ..........................
175             ResetableGuard aMutexLock(m_aLock);
176 
177             if (!m_bActionLocked && m_xActionLock.is())
178             {
179                 m_xActionLock->addActionLock();
180                 m_bActionLocked = m_xActionLock->isActionLocked();
181             }
182             // <- SAFE ..........................
183         }
184 
185         //---------------------------------------
186         /** @short  unlock the internal wrapped resource, if its not already done. */
unlock()187         virtual void unlock()
188         {
189             // SAFE -> ..........................
190             ResetableGuard aMutexLock(m_aLock);
191 
192             if (m_bActionLocked && m_xActionLock.is())
193             {
194                 m_xActionLock->removeActionLock();
195                 // dont check for any locks here ...
196                 // May another guard use the same lock object :-(
197                 m_bActionLocked = sal_False;
198             }
199             // <- SAFE ..........................
200         }
201 };
202 
203 } // namespace framework
204 
205 #endif // __FRAMEWORK_LOADENV_ACTIONLOCKGUARD_HXX_
206