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