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 COMPHELPER_COMPONENTBASE_HXX
25 #define COMPHELPER_COMPONENTBASE_HXX
26 
27 #include "comphelper/comphelperdllapi.h"
28 
29 /** === begin UNO includes === **/
30 /** === end UNO includes === **/
31 
32 #include <cppuhelper/interfacecontainer.hxx>
33 
34 //........................................................................
35 namespace comphelper
36 {
37 //........................................................................
38 
39 	//====================================================================
40 	//= ComponentBase
41 	//====================================================================
42 	class COMPHELPER_DLLPUBLIC ComponentBase
43 	{
44     protected:
45         /** creates a ComponentBase instance
46 
47             The instance is not initialized. As a consequence, every ComponentMethodGuard instantiated for
48             this component will throw a <type scope="com::sun::star::lang">NotInitializedException</type>,
49             until ->setInitialized() is called.
50         */
ComponentBase(::cppu::OBroadcastHelper & _rBHelper)51         ComponentBase( ::cppu::OBroadcastHelper& _rBHelper )
52             :m_rBHelper( _rBHelper )
53             ,m_bInitialized( false )
54         {
55         }
56 
57         struct NoInitializationNeeded { };
58 
59         /** creates a ComponentBase instance
60 
61             The instance is already initialized, so there's no need to call setInitialized later on. Use this
62             constructor for component implementations which do not require explicit initialization.
63         */
ComponentBase(::cppu::OBroadcastHelper & _rBHelper,NoInitializationNeeded)64         ComponentBase( ::cppu::OBroadcastHelper& _rBHelper, NoInitializationNeeded )
65             :m_rBHelper( _rBHelper )
66             ,m_bInitialized( true )
67         {
68         }
69 
70         /** marks the instance as initialized
71 
72             Subsequent instantiations of a ComponentMethodGuard won't throw the NotInitializedException now.
73         */
setInitialized()74         inline void setInitialized()    { m_bInitialized = true; }
75 
76     public:
77         /// helper struct to grant access to selected public methods to the ComponentMethodGuard class
GuardAccesscomphelper::ComponentBase::GuardAccess78         struct GuardAccess { friend class ComponentMethodGuard; private: GuardAccess() { } };
79 
80         /// retrieves the component's mutex
getMutex(GuardAccess)81         inline  ::osl::Mutex&   getMutex( GuardAccess )                 { return getMutex(); }
82         /// checks whether the component is already disposed, throws a DisposedException if so.
checkDisposed(GuardAccess) const83         inline  void            checkDisposed( GuardAccess ) const      { impl_checkDisposed_throw(); }
84         /// checks whether the component is already initialized, throws a NotInitializedException if not.
checkInitialized(GuardAccess) const85         inline  void            checkInitialized( GuardAccess ) const   { impl_checkInitialized_throw(); }
86 
87     protected:
88         /// retrieves the component's broadcast helper
getBroadcastHelper()89         inline  ::cppu::OBroadcastHelper&   getBroadcastHelper()    { return m_rBHelper; }
90         /// retrieves the component's mutex
getMutex()91         inline  ::osl::Mutex&               getMutex()              { return m_rBHelper.rMutex; }
92         /// determines whether the instance is already disposed
impl_isDisposed() const93         inline  bool                        impl_isDisposed() const { return m_rBHelper.bDisposed; }
94 
95         /// checks whether the component is already disposed. Throws a DisposedException if so.
96         void    impl_checkDisposed_throw() const;
97 
98         /// checks whether the component is already initialized. Throws a NotInitializedException if not.
99         void    impl_checkInitialized_throw() const;
100 
101         /// determines whether the component is already initialized
102         inline  bool
impl_isInitialized_nothrow() const103                 impl_isInitialized_nothrow() const { return m_bInitialized; }
104 
105         /** returns the context to be used when throwing exceptions
106 
107             The default implementation returns <NULL/>.
108         */
109         virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
110                 getComponent() const;
111 
112     private:
113         ::cppu::OBroadcastHelper&   m_rBHelper;
114         bool                        m_bInitialized;
115 	};
116 
117     class ComponentMethodGuard
118     {
119     public:
120         enum MethodType
121         {
122             /// allow the method to be called only when being initialized and not being disposed
123             Default,
124             /// allow the method to be called without being initialized
125             WithoutInit
126 
127         };
128 
ComponentMethodGuard(ComponentBase & _rComponent,const MethodType _eType=Default)129         ComponentMethodGuard( ComponentBase& _rComponent, const MethodType _eType = Default )
130             :m_aMutexGuard( _rComponent.getMutex( ComponentBase::GuardAccess() ) )
131         {
132             if ( _eType != WithoutInit )
133                 _rComponent.checkInitialized( ComponentBase::GuardAccess() );
134             _rComponent.checkDisposed( ComponentBase::GuardAccess() );
135         }
136 
~ComponentMethodGuard()137         ~ComponentMethodGuard()
138         {
139         }
140 
clear()141         inline void clear()
142         {
143             m_aMutexGuard.clear();
144         }
reset()145         inline void reset()
146         {
147             m_aMutexGuard.reset();
148         }
149 
150     private:
151         ::osl::ResettableMutexGuard   m_aMutexGuard;
152     };
153 
154 //........................................................................
155 } // namespace ComponentBase
156 //........................................................................
157 
158 #endif // COMPHELPER_COMPONENTBASE_HXX
159