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 #ifndef COMPHELPER_INC_COMPHELPER_COMPONENTMODULE_HXX 24 #define COMPHELPER_INC_COMPHELPER_COMPONENTMODULE_HXX 25 26 #include <comphelper/comphelperdllapi.h> 27 #include <comphelper/legacysingletonfactory.hxx> 28 29 /** === begin UNO includes === **/ 30 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 31 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 32 #include <com/sun/star/uno/Sequence.hxx> 33 /** === end UNO includes === **/ 34 35 #include <cppuhelper/factory.hxx> 36 37 #include <osl/mutex.hxx> 38 39 #include <rtl/string.hxx> 40 #include <rtl/instance.hxx> 41 42 //........................................................................ 43 namespace comphelper 44 { 45 //........................................................................ 46 47 /** factory factory declaration 48 */ 49 typedef ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleComponentFactory > (SAL_CALL *FactoryInstantiation) 50 ( 51 ::cppu::ComponentFactoryFunc _pFactoryFunc, 52 ::rtl::OUString const& _rComponentName, 53 ::com::sun::star::uno::Sequence< ::rtl::OUString > const & _rServiceNames, 54 rtl_ModuleCount* _pModuleCounter 55 ) SAL_THROW(()); 56 57 //========================================================================= 58 //= ComponentDescription 59 //========================================================================= 60 struct COMPHELPER_DLLPUBLIC ComponentDescription 61 { 62 /// the implementation name of the component 63 ::rtl::OUString sImplementationName; 64 /// the services supported by the component implementation 65 ::com::sun::star::uno::Sequence< ::rtl::OUString > aSupportedServices; 66 /** the name under which the component implementation should be registered as singleton, 67 or empty if the component does not implement a singleton. 68 */ 69 ::rtl::OUString sSingletonName; 70 /// the function to create an instance of the component 71 ::cppu::ComponentFactoryFunc pComponentCreationFunc; 72 /// the function to create a factory for the component (usually <code>::cppu::createSingleComponentFactory</code>) 73 FactoryInstantiation pFactoryCreationFunc; 74 ComponentDescriptioncomphelper::ComponentDescription75 ComponentDescription() 76 :sImplementationName() 77 ,aSupportedServices() 78 ,sSingletonName() 79 ,pComponentCreationFunc( NULL ) 80 ,pFactoryCreationFunc( NULL ) 81 { 82 } 83 ComponentDescriptioncomphelper::ComponentDescription84 ComponentDescription( 85 const ::rtl::OUString& _rImplementationName, 86 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rSupportedServices, 87 const ::rtl::OUString& _rSingletonName, 88 ::cppu::ComponentFactoryFunc _pComponentCreationFunc, 89 FactoryInstantiation _pFactoryCreationFunc 90 ) 91 :sImplementationName( _rImplementationName ) 92 ,aSupportedServices( _rSupportedServices ) 93 ,sSingletonName( _rSingletonName ) 94 ,pComponentCreationFunc( _pComponentCreationFunc ) 95 ,pFactoryCreationFunc( _pFactoryCreationFunc ) 96 { 97 } 98 }; 99 100 //========================================================================= 101 //= OModule 102 //========================================================================= 103 class OModuleImpl; 104 class COMPHELPER_DLLPUBLIC OModule 105 { 106 private: 107 oslInterlockedCount m_nClients; /// number of registered clients 108 OModuleImpl* m_pImpl; /// impl class. lives as long as at least one client for the module is registered 109 110 protected: 111 mutable ::osl::Mutex m_aMutex; /// access safety 112 113 public: 114 OModule(); 115 116 virtual ~OModule(); 117 118 /** register a component implementing a service with the given data. 119 @param _rImplementationName 120 the implementation name of the component 121 @param _rServiceNames 122 the services the component supports 123 @param _pCreateFunction 124 a function for creating an instance of the component 125 @param _pFactoryFunction 126 a function for creating a factory for that component 127 */ 128 void registerImplementation( 129 const ::rtl::OUString& _rImplementationName, 130 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rServiceNames, 131 ::cppu::ComponentFactoryFunc _pCreateFunction, 132 FactoryInstantiation _pFactoryFunction = ::cppu::createSingleComponentFactory ); 133 134 /** registers a component given by <type>ComponentDescription</type> 135 */ 136 void registerImplementation( const ComponentDescription& _rComp ); 137 138 /** creates a Factory for the component with the given implementation name. 139 <p>Usually used from within component_getFactory.<p/> 140 @param _rxServiceManager 141 a pointer to an XMultiServiceFactory interface as got in component_getFactory 142 @param _pImplementationName 143 the implementation name of the component 144 @return 145 the XInterface access to a factory for the component 146 */ 147 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getComponentFactory( 148 const ::rtl::OUString& _rImplementationName, 149 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxServiceManager 150 ); 151 152 /** version of getComponentFactory which directly takes the arguments you got in your component_getFactory call 153 */ 154 void* getComponentFactory( 155 const sal_Char* _pImplementationName, void* _pServiceManager, void* _pRegistryKey 156 ); 157 158 public: ClientAccess()159 class ClientAccess { friend class OModuleClient; private: ClientAccess() { } }; 160 /// register a client for the module 161 void registerClient( ClientAccess ); 162 /// revoke a client for the module 163 void revokeClient( ClientAccess ); 164 165 protected: 166 /** called when the first client has been registered 167 @precond 168 <member>m_aMutex</member> is locked 169 */ 170 virtual void onFirstClient(); 171 172 /** called when the last client has been revoked 173 @precond 174 <member>m_aMutex</member> is locked 175 */ 176 virtual void onLastClient(); 177 178 private: 179 OModule( const OModule& ); // never implemented 180 OModule& operator=( const OModule& ); // never implemented 181 }; 182 183 //========================================================================= 184 //= OModuleClient 185 //========================================================================= 186 /** base class for objects which uses any global module-specific ressources 187 */ 188 class COMPHELPER_DLLPUBLIC OModuleClient 189 { 190 protected: 191 OModule& m_rModule; 192 193 public: OModuleClient(OModule & _rModule)194 OModuleClient( OModule& _rModule ) :m_rModule( _rModule ) { m_rModule.registerClient( OModule::ClientAccess() ); } ~OModuleClient()195 ~OModuleClient() { m_rModule.revokeClient( OModule::ClientAccess() ); } 196 }; 197 198 //========================================================================== 199 //= OAutoRegistration 200 //========================================================================== 201 template <class TYPE> 202 class OAutoRegistration 203 { 204 public: 205 /** automatically provides all component information to an OModule instance 206 <p>Assumed that the template argument has the three methods 207 <ul> 208 <li><code>static ::rtl::OUString getImplementationName_static()</code><li/> 209 <li><code>static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static()</code><li/> 210 <li><code>static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > 211 Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&)</code> 212 </li> 213 <ul/> 214 the instantiation of this object will automatically register the class via <member>OModule::registerImplementation</member>. 215 <p/> 216 The factory creation function used is <code>::cppu::createSingleComponentFactory</code>. 217 */ 218 OAutoRegistration( OModule& _rModule ); 219 }; 220 221 template <class TYPE> OAutoRegistration(OModule & _rModule)222 OAutoRegistration<TYPE>::OAutoRegistration( OModule& _rModule ) 223 { 224 _rModule.registerImplementation( 225 TYPE::getImplementationName_static(), 226 TYPE::getSupportedServiceNames_static(), 227 TYPE::Create 228 ); 229 } 230 231 //========================================================================== 232 //= OSingletonRegistration 233 //========================================================================== 234 template <class TYPE> 235 class OSingletonRegistration 236 { 237 public: 238 /** automatically provides all component information to an OModule instance, 239 for a singleton component 240 241 <p>Assumed that the template argument has the three methods 242 <ul> 243 <li><code>static ::rtl::OUString getImplementationName_static()</code><li/> 244 <li><code>static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static()</code><li/> 245 <li><code>static ::rtl::OUString getSingletonName_static()</code></li> 246 <li><code>static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > 247 Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&)</code> 248 </li> 249 <ul/> 250 the instantiation of this object will automatically register the class via <member>OModule::registerImplementation</member>. 251 </p> 252 */ 253 OSingletonRegistration( OModule& _rModule ); 254 }; 255 256 template <class TYPE> 257 //-------------------------------------------------------------------------- OSingletonRegistration(OModule & _rModule)258 OSingletonRegistration<TYPE>::OSingletonRegistration( OModule& _rModule ) 259 { 260 _rModule.registerImplementation( ComponentDescription( 261 TYPE::getImplementationName_static(), 262 TYPE::getSupportedServiceNames_static(), 263 TYPE::getSingletonName_static(), 264 &TYPE::Create, 265 &::cppu::createSingleComponentFactory 266 ) ); 267 } 268 269 //========================================================================== 270 //= OLegacySingletonRegistration 271 //========================================================================== 272 template <class TYPE> 273 class OLegacySingletonRegistration 274 { 275 public: 276 OLegacySingletonRegistration( OModule& _rModule ); 277 }; 278 279 //-------------------------------------------------------------------------- 280 template <class TYPE> OLegacySingletonRegistration(OModule & _rModule)281 OLegacySingletonRegistration<TYPE>::OLegacySingletonRegistration( OModule& _rModule ) 282 { 283 _rModule.registerImplementation( ComponentDescription( 284 TYPE::getImplementationName_static(), 285 TYPE::getSupportedServiceNames_static(), 286 ::rtl::OUString(), 287 &TYPE::Create, 288 &::comphelper::createLegacySingletonFactory 289 ) ); 290 } 291 292 //========================================================================== 293 //= helpers 294 //========================================================================== 295 296 //========================================================================== 297 // declaring a OModule for a component library 298 299 #define DECLARE_COMPONENT_MODULE( ModuleClass, ClientClass ) \ 300 /* -------------------------------------------------------------------- */ \ 301 class ModuleClass : public ::comphelper::OModule \ 302 { \ 303 friend struct CreateModuleClass; \ 304 typedef ::comphelper::OModule BaseClass; \ 305 \ 306 public: \ 307 static ModuleClass& getInstance(); \ 308 \ 309 private: \ 310 ModuleClass(); \ 311 }; \ 312 \ 313 /* -------------------------------------------------------------------- */ \ 314 class ClientClass : public ::comphelper::OModuleClient \ 315 { \ 316 private: \ 317 typedef ::comphelper::OModuleClient BaseClass; \ 318 \ 319 public: \ 320 ClientClass() : BaseClass( ModuleClass::getInstance() ) \ 321 { \ 322 } \ 323 }; \ 324 \ 325 /* -------------------------------------------------------------------- */ \ 326 template < class TYPE > \ 327 class OAutoRegistration : public ::comphelper::OAutoRegistration< TYPE > \ 328 { \ 329 private: \ 330 typedef ::comphelper::OAutoRegistration< TYPE > BaseClass; \ 331 \ 332 public: \ 333 OAutoRegistration() : BaseClass( ModuleClass::getInstance() ) \ 334 { \ 335 } \ 336 }; \ 337 /* -------------------------------------------------------------------- */ \ 338 template < class TYPE > \ 339 class OSingletonRegistration : public ::comphelper::OSingletonRegistration< TYPE > \ 340 { \ 341 private: \ 342 typedef ::comphelper::OSingletonRegistration< TYPE > BaseClass; \ 343 \ 344 public: \ 345 OSingletonRegistration() : BaseClass( ModuleClass::getInstance() ) \ 346 { \ 347 } \ 348 }; \ 349 /* -------------------------------------------------------------------- */ \ 350 template < class TYPE > \ 351 class OLegacySingletonRegistration : public ::comphelper::OLegacySingletonRegistration< TYPE > \ 352 { \ 353 private: \ 354 typedef ::comphelper::OLegacySingletonRegistration< TYPE > BaseClass; \ 355 \ 356 public: \ 357 OLegacySingletonRegistration() : BaseClass( ModuleClass::getInstance() ) \ 358 { \ 359 } \ 360 }; \ 361 362 //========================================================================== 363 //= implementing a OModule for a component library 364 365 #define IMPLEMENT_COMPONENT_MODULE( ModuleClass ) \ 366 struct CreateModuleClass \ 367 { \ 368 ModuleClass* operator()() \ 369 { \ 370 static ModuleClass* pModule = new ModuleClass; \ 371 return pModule; \ 372 } \ 373 }; \ 374 \ 375 ModuleClass::ModuleClass() \ 376 :BaseClass() \ 377 { \ 378 } \ 379 \ 380 ModuleClass& ModuleClass::getInstance() \ 381 { \ 382 return *rtl_Instance< ModuleClass, CreateModuleClass, ::osl::MutexGuard, ::osl::GetGlobalMutex >:: \ 383 create( CreateModuleClass(), ::osl::GetGlobalMutex() ); \ 384 } \ 385 386 //========================================================================== 387 //= implementing the API of a component library (component_*) 388 389 #define IMPLEMENT_COMPONENT_LIBRARY_API( module_class, initializer_function ) \ 390 extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL \ 391 component_getImplementationEnvironment( \ 392 const sal_Char **ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) \ 393 { \ 394 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; \ 395 } \ 396 extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( \ 397 const sal_Char* pImplementationName, void* pServiceManager, void* pRegistryKey ) \ 398 { \ 399 initializer_function(); \ 400 return module_class::getInstance().getComponentFactory( pImplementationName, pServiceManager, pRegistryKey ); \ 401 } 402 403 //........................................................................ 404 } // namespace comphelper 405 //........................................................................ 406 407 #endif // COMPHELPER_INC_COMPHELPER_COMPONENTMODULE_HXX 408 409