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