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