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