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 _EXTENSIONS_COMPONENT_MODULE_HXX_
29 #define _EXTENSIONS_COMPONENT_MODULE_HXX_
30 
31 /** you may find this file helpfull if you implement a component (in it's own library) which can't use
32 	the usual infrastructure.<br/>
33 	More precise, you find helper classes to ease the use of resources and the registration of services.
34 	<p>
35 	You need to define a preprocessor variable COMPMOD_NAMESPACE in order to use this file. Set it to a string
36 	which should be used as namespace for the classes defined herein.</p>
37 */
38 
39 #ifndef _OSL_MUTEX_HXX_
40 #include <osl/mutex.hxx>
41 #endif
42 #ifndef _TOOLS_RESID_HXX
43 #include <tools/resid.hxx>
44 #endif
45 #ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #endif
48 #ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
49 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
50 #endif
51 #ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
52 #include <com/sun/star/uno/Sequence.hxx>
53 #endif
54 #ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HPP_
55 #include <com/sun/star/registry/XRegistryKey.hpp>
56 #endif
57 #ifndef _CPPUHELPER_FACTORY_HXX_
58 #include <cppuhelper/factory.hxx>
59 #endif
60 #ifndef _RTL_STRING_HXX_
61 #include <rtl/string.hxx>
62 #endif
63 
64 class ResMgr;
65 
66 //.........................................................................
67 namespace COMPMOD_NAMESPACE
68 {
69 //.........................................................................
70 
71 typedef ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > (SAL_CALL *FactoryInstantiation)
72 		(
73 			const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rServiceManager,
74 			const ::rtl::OUString & _rComponentName,
75 			::cppu::ComponentInstantiation _pCreateFunction,
76 			const ::com::sun::star::uno::Sequence< ::rtl::OUString > & _rServiceNames,
77 			rtl_ModuleCount* _pModuleCounter
78 		);
79 
80 	//=========================================================================
81 	//= OModule
82 	//=========================================================================
83 	class OModuleImpl;
84 	class OModule
85 	{
86 		friend class OModuleResourceClient;
87 
88 	private:
89 		OModule();
90 			// not implemented. OModule is a static class
91 
92 	protected:
93 		// resource administration
94 		static ::osl::Mutex		s_aMutex;		/// access safety
95 		static sal_Int32		s_nClients;		/// number of registered clients
96 		static OModuleImpl*		s_pImpl;		/// impl class. lives as long as at least one client for the module is registered
97 		static ::rtl::OString	s_sResPrefix;
98 
99 		// auto registration administration
100 		static	::com::sun::star::uno::Sequence< ::rtl::OUString >*
101 			s_pImplementationNames;
102 		static	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > >*
103 			s_pSupportedServices;
104 		static	::com::sun::star::uno::Sequence< sal_Int64 >*
105 			s_pCreationFunctionPointers;
106 		static	::com::sun::star::uno::Sequence< sal_Int64 >*
107 			s_pFactoryFunctionPointers;
108 
109 	public:
110 		// cna be set as long as no resource has been accessed ...
111 		static void		setResourceFilePrefix(const ::rtl::OString& _rPrefix);
112 
113 		/// get the vcl res manager of the module
114 		static ResMgr*	getResManager();
115 
116 		/** register a component implementing a service with the given data.
117 			@param	_rImplementationName
118 						the implementation name of the component
119 			@param	_rServiceNames
120 						the services the component supports
121 			@param	_pCreateFunction
122 						a function for creating an instance of the component
123 			@param	_pFactoryFunction
124 						a function for creating a factory for that component
125 			@see revokeComponent
126 		*/
127 		static void registerComponent(
128 			const ::rtl::OUString& _rImplementationName,
129 			const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rServiceNames,
130 			::cppu::ComponentInstantiation _pCreateFunction,
131 			FactoryInstantiation _pFactoryFunction);
132 
133 		/** revoke the registration for the specified component
134 			@param	_rImplementationName
135 				the implementation name of the component
136 		*/
137 		static void revokeComponent(
138 			const ::rtl::OUString& _rImplementationName);
139 
140 		/** creates a Factory for the component with the given implementation name.
141 			<p>Usually used from within component_getFactory.<p/>
142 			@param	_rxServiceManager
143 						a pointer to an XMultiServiceFactory interface as got in component_getFactory
144 			@param	_pImplementationName
145 						the implementation name of the component
146 			@return
147 						the XInterface access to a factory for the component
148 		*/
149 		static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getComponentFactory(
150 			const ::rtl::OUString& _rImplementationName,
151 			const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxServiceManager
152 			);
153 
154 	protected:
155 		/// register a client for the module
156 		static void	registerClient();
157 		/// revoke a client for the module
158 		static void	revokeClient();
159 
160 	private:
161 		/** ensure that the impl class exists
162 			@precond m_aMutex is guarded when this method gets called
163 		*/
164 		static void ensureImpl();
165 	};
166 
167 	//=========================================================================
168 	//= OModuleResourceClient
169 	//=========================================================================
170 	/** base class for objects which uses any global module-specific ressources
171 	*/
172 	class OModuleResourceClient
173 	{
174 	public:
175 		OModuleResourceClient()		{ OModule::registerClient(); }
176 		~OModuleResourceClient()	{ OModule::revokeClient(); }
177 	};
178 
179 	//=========================================================================
180 	//= ModuleRes
181 	//=========================================================================
182 	/** specialized ResId, using the ressource manager provided by the global module
183 	*/
184 	class ModuleRes : public ::ResId
185 	{
186 	public:
187 		ModuleRes(sal_uInt16 _nId) : ResId(_nId, *OModule::getResManager()) { }
188 	};
189 
190 	//==========================================================================
191 	//= OMultiInstanceAutoRegistration
192 	//==========================================================================
193 	template <class TYPE>
194 	class OMultiInstanceAutoRegistration
195 	{
196 	public:
197 		/** automatically registeres a multi instance component
198 			<p>Assumed that the template argument has the three methods
199 				<ul>
200 					<li><code>static ::rtl::OUString getImplementationName_Static()</code><li/>
201 					<li><code>static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static()</code><li/>
202 					<li><code>static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
203 						Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&)</code>
204 						</li>
205 				<ul/>
206 			the instantiation of this object will automatically register the class via <method>OModule::registerComponent</method>.
207 			<p/>
208 			The factory creation function used is <code>::cppu::createSingleFactory</code>.
209 			@see OOneInstanceAutoRegistration
210 		*/
211 		OMultiInstanceAutoRegistration();
212 		~OMultiInstanceAutoRegistration();
213 	};
214 
215 	template <class TYPE>
216 	OMultiInstanceAutoRegistration<TYPE>::OMultiInstanceAutoRegistration()
217 	{
218 		OModule::registerComponent(
219 			TYPE::getImplementationName_Static(),
220 			TYPE::getSupportedServiceNames_Static(),
221 			TYPE::Create,
222 			::cppu::createSingleFactory
223 			);
224 	}
225 
226 	template <class TYPE>
227 	OMultiInstanceAutoRegistration<TYPE>::~OMultiInstanceAutoRegistration()
228 	{
229 		OModule::revokeComponent(TYPE::getImplementationName_Static());
230 	}
231 
232 	//==========================================================================
233 	//= OOneInstanceAutoRegistration
234 	//==========================================================================
235 	template <class TYPE>
236 	class OOneInstanceAutoRegistration
237 	{
238 	public:
239 		/** automatically registeres a single instance component
240 			<p>Assumed that the template argument has the three methods
241 				<ul>
242 					<li><code>static ::rtl::OUString getImplementationName_Static()</code><li/>
243 					<li><code>static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static()</code><li/>
244 					<li><code>static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
245 						Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&)</code>
246 						</li>
247 				<ul/>
248 			the instantiation of this object will automatically register the class via <method>OModule::registerComponent</method>.
249 			<p/>
250 			The factory creation function used is <code>::cppu::createOneInstanceFactory</code>.
251 			@see OOneInstanceAutoRegistration
252 		*/
253 		OOneInstanceAutoRegistration();
254 		~OOneInstanceAutoRegistration();
255 	};
256 
257 	template <class TYPE>
258 	OOneInstanceAutoRegistration<TYPE>::OOneInstanceAutoRegistration()
259 	{
260 		OModule::registerComponent(
261 			TYPE::getImplementationName_Static(),
262 			TYPE::getSupportedServiceNames_Static(),
263 			TYPE::Create,
264 			::cppu::createOneInstanceFactory
265 			);
266 	}
267 
268 	template <class TYPE>
269 	OOneInstanceAutoRegistration<TYPE>::~OOneInstanceAutoRegistration()
270 	{
271 		OModule::revokeComponent(TYPE::getImplementationName_Static());
272 	}
273 
274 //.........................................................................
275 }	// namespace COMPMOD_NAMESPACE
276 //.........................................................................
277 
278 #endif // _EXTENSIONS_COMPONENT_MODULE_HXX_
279 
280