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 UNOTOOLS_INC_SHAREDUNOCOMPONENT_HXX 25 #define UNOTOOLS_INC_SHAREDUNOCOMPONENT_HXX 26 27 #include "unotoolsdllapi.h" 28 29 #include <boost/shared_ptr.hpp> 30 #include <com/sun/star/uno/Reference.hxx> 31 #include <rtl/ref.hxx> 32 33 namespace com { namespace sun { namespace star { 34 namespace lang { 35 class XComponent; 36 } 37 } } } 38 //............................................................................ 39 namespace utl 40 { 41 //............................................................................ 42 43 //======================================================================== 44 //= DisposableComponent 45 //======================================================================== 46 /** is a class which controls lifetime of an UNO component via ->XComponent::dispose 47 48 You'll usually never use this class directly, but only as parameter for a 49 ->SharedUNOComponent class. 50 */ 51 class UNOTOOLS_DLLPUBLIC DisposableComponent 52 { 53 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > 54 m_xComponent; 55 56 public: 57 /** constructs a ->DisposableComponent instance 58 59 @param _rxComponent 60 the component whose life time should be controlled by the instance. Must not be <NULL/>. 61 */ 62 DisposableComponent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxComponent ); 63 64 /** disposes the component represented by the instance 65 66 The component is queried for ->XComponent(which <em>must</em> be supported), 67 and ->XComponent::dispose is invoked. A failure of this invocation (e.g. a thrown 68 exception) is silenced in release builds, and reported in debug builds. 69 */ 70 ~DisposableComponent(); 71 72 private: 73 DisposableComponent(); // never implemented 74 DisposableComponent( const DisposableComponent& ); // never implemented 75 DisposableComponent& operator=( const DisposableComponent& ); // never implemented 76 }; 77 78 //======================================================================== 79 //= CloseableComponent 80 //======================================================================== 81 class CloseableComponentImpl; 82 /** is a class which controls lifetime of an UNO component via ->XCloseable::close 83 84 You'll usually never use this class directly, but only as parameter for a 85 ->SharedUNOComponent class. 86 */ 87 class UNOTOOLS_DLLPUBLIC CloseableComponent 88 { 89 private: 90 /** Our IMPL class. 91 */ 92 ::rtl::Reference< CloseableComponentImpl > m_pImpl; 93 94 public: 95 /** constructs a ->CloseableComponent instance 96 97 @param _rxComponent 98 the component whose life time should be controlled by the instance. Must not be <NULL/>. 99 */ 100 CloseableComponent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxComponent ); 101 102 /** destroys resources associated with this instance, and disposes the component 103 104 The component is queried for ->XCloseable (which <em>must</em> be supported), 105 and ->XCloseable::close is invoked, with delivering the ownership. 106 If the invocation fails with a ->CloseVetoException, this is ignored, since in 107 this case the vetoing instance took the ownership. 108 109 Any other failure will be reported in a debug version via assertion mechanisms, 110 and silenced in release builds. 111 */ 112 ~CloseableComponent(); 113 114 private: 115 CloseableComponent(); // never implemented 116 CloseableComponent( const CloseableComponent& ); // never implemented 117 CloseableComponent& operator=( const CloseableComponent& ); // never implemented 118 }; 119 120 //======================================================================== 121 //= SharedUNOComponent 122 //======================================================================== 123 /** is a helper class for sharing ownership of a UNO component 124 125 If you need to share an UNO component, which normally needs a dedicated owner, 126 and is lifetime controlled by an explicit disposal action (not necessarily ->XComponent::dispose, 127 but <em>any</em> explicit method call, after which the object is considered 128 to be disposed), between different classes, ->SharedUNOComponent is what you need. 129 130 Instead of passing around a <code>Reference< XFoo ></code>, and bothering 131 with ownership and disposal, you just use a <code>SharedUNOComponent< XFoo ></code>. 132 This instance can be passed around, including copying, and in nearly all respects behaves 133 like the original <code>Reference< XFoo ></code>. However, when the last 134 ->SharedUNOComponent referencing a certain <code>Reference< XFoo ></code> dies, it 135 will automatically get rid of the object held by this reference. 136 137 @param INTERFACE 138 the UNO interface type as which the component should be held 139 140 @param COMPONENT_HOLDER 141 a class which can be used to represent and dispose a UNO component. 142 The class must support (maybe explicit only) construction from a 143 <code>Reference< INTERFACE ></code>, and destruction. Upon destruction, 144 the class must dispose (by any suitable means) the component instance it was 145 constructed with. 146 */ 147 template < class INTERFACE, class COMPONENT = DisposableComponent > 148 class SharedUNOComponent 149 { 150 private: 151 typedef COMPONENT Component; 152 typedef ::boost::shared_ptr< Component > ComponentPointer; 153 154 private: 155 ComponentPointer m_pComponent; 156 ::com::sun::star::uno::Reference< INTERFACE > m_xTypedComponent; 157 158 public: 159 enum AssignmentMode 160 { 161 TakeOwnership, 162 NoTakeOwnership 163 }; 164 165 public: SharedUNOComponent()166 inline SharedUNOComponent() 167 { 168 } 169 SharedUNOComponent(const::com::sun::star::uno::Reference<INTERFACE> & _rxComponent,AssignmentMode eMode=TakeOwnership)170 explicit inline SharedUNOComponent( const ::com::sun::star::uno::Reference< INTERFACE >& _rxComponent, AssignmentMode eMode = TakeOwnership ) 171 { 172 reset( _rxComponent, eMode ); 173 } 174 175 #ifndef EXCEPTIONS_OFF SharedUNOComponent(const::com::sun::star::uno::XInterface * _pInterface,::com::sun::star::uno::UnoReference_QueryThrow _queryThrow)176 inline SharedUNOComponent( const ::com::sun::star::uno::XInterface* _pInterface, ::com::sun::star::uno::UnoReference_QueryThrow _queryThrow ) 177 { 178 set( _pInterface, _queryThrow ); 179 } 180 SharedUNOComponent(const::com::sun::star::uno::BaseReference & _rRef,::com::sun::star::uno::UnoReference_QueryThrow _queryThrow)181 inline SharedUNOComponent( const ::com::sun::star::uno::BaseReference & _rRef, ::com::sun::star::uno::UnoReference_QueryThrow _queryThrow ) 182 { 183 set( _rRef, _queryThrow ); 184 } 185 SharedUNOComponent(const::com::sun::star::uno::Any & _rAny,::com::sun::star::uno::UnoReference_QueryThrow _queryThrow)186 inline SharedUNOComponent( const ::com::sun::star::uno::Any& _rAny, ::com::sun::star::uno::UnoReference_QueryThrow _queryThrow ) 187 { 188 set( _rAny, _queryThrow ); 189 } 190 SharedUNOComponent(const SharedUNOComponent & _rxComponent,::com::sun::star::uno::UnoReference_SetThrow _setThrow)191 inline SharedUNOComponent( const SharedUNOComponent& _rxComponent, ::com::sun::star::uno::UnoReference_SetThrow _setThrow ) 192 { 193 set( _rxComponent, _setThrow ); 194 } 195 #endif 196 197 // SharedUNOComponent& operator=( const ::com::sun::star::uno::Reference< INTERFACE >& _rxComponent ); 198 // this operator is not implemented by intention. There is no canonic ownership after this operatoer 199 // would have been applied: Should the SharedUNOComponent have the ownership of the component, 200 // or shouldn't it? Hard to guess, and probably wrong in 50 percent of all cases, anyway. So, 201 // instead of tempting clients of this class to use such a dangerous operator, we do 202 // not offer it at all. If you need to assign a Reference< INTERFACE > to your SharedUNOComponent, 203 // use the ->reset method. 204 205 /** assigns a new component, and releases the old one 206 */ 207 void reset( const ::com::sun::star::uno::Reference< INTERFACE >& _rxComponent, AssignmentMode _eMode = TakeOwnership ); 208 209 inline bool set( ::com::sun::star::uno::XInterface* _pInterface, ::com::sun::star::uno::UnoReference_Query _query ); 210 inline bool set( const ::com::sun::star::uno::BaseReference& _rRef, ::com::sun::star::uno::UnoReference_Query _query ); 211 inline bool set( const ::com::sun::star::uno::Any& _rAny, ::com::sun::star::uno::UnoReference_Query _query ); 212 213 #ifndef EXCEPTIONS_OFF 214 inline void set( const ::com::sun::star::uno::XInterface* _pInterface, ::com::sun::star::uno::UnoReference_QueryThrow _queryThrow ); 215 inline void set( const ::com::sun::star::uno::BaseReference & _rRef, ::com::sun::star::uno::UnoReference_QueryThrow _queryThrow ); 216 inline void set( const ::com::sun::star::uno::Any& _rAny, ::com::sun::star::uno::UnoReference_QueryThrow _queryThrow ); 217 218 inline void set( const INTERFACE* _pInterface, ::com::sun::star::uno::UnoReference_SetThrow _setThrow ); 219 inline void set( const ::com::sun::star::uno::Reference< INTERFACE >& _rRef, ::com::sun::star::uno::UnoReference_SetThrow _setThrow ); 220 inline void set( const SharedUNOComponent& _rComp, ::com::sun::star::uno::UnoReference_SetThrow _setThrow ); 221 #endif 222 223 INTERFACE* SAL_CALL operator->() const; 224 225 inline operator const ::com::sun::star::uno::Reference< INTERFACE >&() const 226 { 227 return m_xTypedComponent; 228 } 229 getTyped() const230 inline const ::com::sun::star::uno::Reference< INTERFACE >& getTyped() const 231 { 232 return m_xTypedComponent; 233 } 234 is() const235 inline bool is() const 236 { 237 return m_xTypedComponent.is(); 238 } 239 clear()240 inline void clear() 241 { 242 m_pComponent.reset(); 243 m_xTypedComponent.clear(); 244 } 245 }; 246 247 //------------------------------------------------------------------------- 248 template < class INTERFACE, class COMPONENT > operator ->() const249 INTERFACE* SAL_CALL SharedUNOComponent< INTERFACE, COMPONENT >::operator->() const 250 { 251 return m_xTypedComponent.operator->(); 252 } 253 254 //------------------------------------------------------------------------- 255 // assignments 256 template < class INTERFACE, class COMPONENT > reset(const::com::sun::star::uno::Reference<INTERFACE> & _rxComponent,AssignmentMode _eMode)257 void SharedUNOComponent< INTERFACE, COMPONENT >::reset( const ::com::sun::star::uno::Reference< INTERFACE >& _rxComponent, AssignmentMode _eMode ) 258 { 259 m_pComponent.reset( _eMode == TakeOwnership ? new COMPONENT( _rxComponent ) : NULL ); 260 m_xTypedComponent = _rxComponent; 261 } 262 263 //------------------------------------------------------------------------- 264 // comparison operators 265 template < class INTERFACE, class COMPONENT > operator ==(const::com::sun::star::uno::Reference<INTERFACE> & _rLHS,const SharedUNOComponent<INTERFACE,COMPONENT> & _rRHS)266 bool operator==( const ::com::sun::star::uno::Reference< INTERFACE >& _rLHS, const SharedUNOComponent< INTERFACE, COMPONENT >& _rRHS ) 267 { 268 return _rLHS == _rRHS.getTyped(); 269 } 270 271 template < class INTERFACE, class COMPONENT > operator ==(const SharedUNOComponent<INTERFACE,COMPONENT> & _rLHS,const::com::sun::star::uno::Reference<INTERFACE> & _rRHS)272 bool operator==( const SharedUNOComponent< INTERFACE, COMPONENT >& _rLHS, const ::com::sun::star::uno::Reference< INTERFACE >& _rRHS ) 273 { 274 return _rLHS.getTyped() == _rRHS; 275 } 276 277 //------------------------------------------------------------------------- 278 // conversion to Any 279 template < class INTERFACE, class COMPONENT > operator <<=(::com::sun::star::uno::Any & rAny,const SharedUNOComponent<INTERFACE,COMPONENT> & value)280 inline void SAL_CALL operator <<= ( ::com::sun::star::uno::Any & rAny, const SharedUNOComponent< INTERFACE, COMPONENT >& value ) SAL_THROW( () ) 281 { 282 rAny <<= value.getTyped(); 283 } 284 285 //------------------------------------------------------------------------- 286 template < class INTERFACE, class COMPONENT > makeAny(const SharedUNOComponent<INTERFACE,COMPONENT> & value)287 inline ::com::sun::star::uno::Any SAL_CALL makeAny( const SharedUNOComponent< INTERFACE, COMPONENT >& value ) SAL_THROW( () ) 288 { 289 return makeAny( value.getTyped() ); 290 } 291 292 #ifndef EXCEPTIONS_OFF 293 //------------------------------------------------------------------------- 294 template < class INTERFACE, class COMPONENT > set(const::com::sun::star::uno::XInterface * _pInterface,::com::sun::star::uno::UnoReference_QueryThrow _queryThrow)295 void SharedUNOComponent< INTERFACE, COMPONENT >::set( const ::com::sun::star::uno::XInterface* _pInterface, ::com::sun::star::uno::UnoReference_QueryThrow _queryThrow ) 296 { 297 reset( ::com::sun::star::uno::Reference< INTERFACE >( _pInterface, _queryThrow ), TakeOwnership ); 298 } 299 300 //------------------------------------------------------------------------- 301 template < class INTERFACE, class COMPONENT > set(const::com::sun::star::uno::BaseReference & _rRef,::com::sun::star::uno::UnoReference_QueryThrow _queryThrow)302 void SharedUNOComponent< INTERFACE, COMPONENT >::set( const ::com::sun::star::uno::BaseReference & _rRef, ::com::sun::star::uno::UnoReference_QueryThrow _queryThrow ) 303 { 304 reset( ::com::sun::star::uno::Reference< INTERFACE >( _rRef, _queryThrow ), TakeOwnership ); 305 } 306 307 //------------------------------------------------------------------------- 308 template < class INTERFACE, class COMPONENT > set(const::com::sun::star::uno::Any & _rAny,::com::sun::star::uno::UnoReference_QueryThrow _queryThrow)309 void SharedUNOComponent< INTERFACE, COMPONENT >::set( const ::com::sun::star::uno::Any& _rAny, ::com::sun::star::uno::UnoReference_QueryThrow _queryThrow ) 310 { 311 reset( ::com::sun::star::uno::Reference< INTERFACE >( _rAny, _queryThrow ), TakeOwnership ); 312 } 313 314 //------------------------------------------------------------------------- 315 template < class INTERFACE, class COMPONENT > set(const INTERFACE * _pInterface,::com::sun::star::uno::UnoReference_SetThrow _setThrow)316 void SharedUNOComponent< INTERFACE, COMPONENT >::set( const INTERFACE* _pInterface, ::com::sun::star::uno::UnoReference_SetThrow _setThrow ) 317 { 318 reset( ::com::sun::star::uno::Reference< INTERFACE >( _pInterface, _setThrow ), TakeOwnership ); 319 } 320 321 //------------------------------------------------------------------------- 322 template < class INTERFACE, class COMPONENT > set(const::com::sun::star::uno::Reference<INTERFACE> & _rRef,::com::sun::star::uno::UnoReference_SetThrow _setThrow)323 void SharedUNOComponent< INTERFACE, COMPONENT >::set( const ::com::sun::star::uno::Reference< INTERFACE >& _rRef, ::com::sun::star::uno::UnoReference_SetThrow _setThrow ) 324 { 325 reset( ::com::sun::star::uno::Reference< INTERFACE >( _rRef, _setThrow ), TakeOwnership ); 326 } 327 328 //------------------------------------------------------------------------- 329 template < class INTERFACE, class COMPONENT > set(const SharedUNOComponent & _rComp,::com::sun::star::uno::UnoReference_SetThrow _setThrow)330 void SharedUNOComponent< INTERFACE, COMPONENT >::set( const SharedUNOComponent& _rComp, ::com::sun::star::uno::UnoReference_SetThrow _setThrow ) 331 { 332 *this = _rComp; 333 // provoke an exception in case the component is NULL 334 m_xTypedComponent.set( m_xTypedComponent, _setThrow ); 335 } 336 #endif 337 338 //------------------------------------------------------------------------- 339 template < class INTERFACE, class COMPONENT > set(::com::sun::star::uno::XInterface * _pInterface,::com::sun::star::uno::UnoReference_Query _query)340 bool SharedUNOComponent< INTERFACE, COMPONENT >::set( ::com::sun::star::uno::XInterface* _pInterface, ::com::sun::star::uno::UnoReference_Query _query ) 341 { 342 reset( ::com::sun::star::uno::Reference< INTERFACE >( _pInterface, _query ) ); 343 return is(); 344 } 345 346 //------------------------------------------------------------------------- 347 template < class INTERFACE, class COMPONENT > set(const::com::sun::star::uno::BaseReference & _rRef,::com::sun::star::uno::UnoReference_Query _query)348 bool SharedUNOComponent< INTERFACE, COMPONENT >::set( const ::com::sun::star::uno::BaseReference& _rRef, ::com::sun::star::uno::UnoReference_Query _query ) 349 { 350 reset( ::com::sun::star::uno::Reference< INTERFACE >( _rRef, _query ) ); 351 return is(); 352 } 353 354 //------------------------------------------------------------------------- 355 template < class INTERFACE, class COMPONENT > set(const::com::sun::star::uno::Any & _rAny,::com::sun::star::uno::UnoReference_Query _query)356 bool SharedUNOComponent< INTERFACE, COMPONENT >::set( const ::com::sun::star::uno::Any& _rAny, ::com::sun::star::uno::UnoReference_Query _query ) 357 { 358 reset( ::com::sun::star::uno::Reference< INTERFACE >( _rAny, _query ) ); 359 return is(); 360 } 361 362 //............................................................................ 363 } // namespace utl 364 //............................................................................ 365 366 #endif // UNOTOOLS_INC_SHAREDUNOCOMPONENT_HXX 367