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