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 #include "componentmodule.hxx"
25 #include <tools/resmgr.hxx>
26 #ifndef _SOLAR_HRC
27 #include <svl/solar.hrc>
28 #endif
29 #include <comphelper/sequence.hxx>
30 #include <tools/debug.hxx>
31 
32 #define ENTER_MOD_METHOD()	\
33 	::osl::MutexGuard aGuard(s_aMutex);	\
34 	ensureImpl()
35 
36 //.........................................................................
37 namespace COMPMOD_NAMESPACE
38 {
39 //.........................................................................
40 
41 	using namespace ::com::sun::star::uno;
42 	using namespace ::com::sun::star::lang;
43 	using namespace ::com::sun::star::registry;
44 	using namespace ::comphelper;
45 	using namespace ::cppu;
46 
47 	//=========================================================================
48 	//= OModuleImpl
49 	//=========================================================================
50 	/** implementation for <type>OModule</type>. not threadsafe, has to be guarded by it's owner
51 	*/
52 	class OModuleImpl
53 	{
54 		ResMgr*		m_pRessources;
55 		sal_Bool	m_bInitialized;
56 		ByteString	m_sFilePrefix;
57 
58 	public:
59 		/// ctor
60 		OModuleImpl();
61 		~OModuleImpl();
62 
63 		/// get the manager for the ressources of the module
64 		ResMgr*	getResManager();
setResourceFilePrefix(const::rtl::OString & _rPrefix)65 		void	setResourceFilePrefix(const ::rtl::OString& _rPrefix) { m_sFilePrefix = _rPrefix; }
66 	};
67 
68 	//-------------------------------------------------------------------------
OModuleImpl()69 	OModuleImpl::OModuleImpl()
70 		:m_pRessources(NULL)
71 		,m_bInitialized(sal_False)
72 	{
73 	}
74 
75 	//-------------------------------------------------------------------------
~OModuleImpl()76 	OModuleImpl::~OModuleImpl()
77 	{
78 		if (m_pRessources)
79 			delete m_pRessources;
80 	}
81 
82 	//-------------------------------------------------------------------------
getResManager()83 	ResMgr*	OModuleImpl::getResManager()
84 	{
85 		// note that this method is not threadsafe, which counts for the whole class !
86 		if (!m_pRessources && !m_bInitialized)
87 		{
88 			DBG_ASSERT(m_sFilePrefix.Len(), "OModuleImpl::getResManager: no resource file prefix!");
89 			// create a manager with a fixed prefix
90 			ByteString aMgrName = m_sFilePrefix;
91 
92 			m_pRessources = ResMgr::CreateResMgr(aMgrName.GetBuffer());
93 			DBG_ASSERT(m_pRessources,
94 					(ByteString("OModuleImpl::getResManager: could not create the resource manager (file name: ")
95 				+=	aMgrName
96 				+=	ByteString(")!")).GetBuffer());
97 
98 			m_bInitialized = sal_True;
99 		}
100 		return m_pRessources;
101 	}
102 
103 	//=========================================================================
104 	//= OModule
105 	//=========================================================================
106 	::osl::Mutex	OModule::s_aMutex;
107 	sal_Int32		OModule::s_nClients = 0;
108 	OModuleImpl*	OModule::s_pImpl = NULL;
109 	::rtl::OString	OModule::s_sResPrefix;
110 	//-------------------------------------------------------------------------
getResManager()111 	ResMgr*	OModule::getResManager()
112 	{
113 		ENTER_MOD_METHOD();
114 		return s_pImpl->getResManager();
115 	}
116 
117 	//-------------------------------------------------------------------------
setResourceFilePrefix(const::rtl::OString & _rPrefix)118 	void OModule::setResourceFilePrefix(const ::rtl::OString& _rPrefix)
119 	{
120 		::osl::MutexGuard aGuard(s_aMutex);
121 		s_sResPrefix = _rPrefix;
122 		if (s_pImpl)
123 			s_pImpl->setResourceFilePrefix(_rPrefix);
124 	}
125 
126 	//-------------------------------------------------------------------------
registerClient()127 	void OModule::registerClient()
128 	{
129 		::osl::MutexGuard aGuard(s_aMutex);
130 		++s_nClients;
131 	}
132 
133 	//-------------------------------------------------------------------------
revokeClient()134 	void OModule::revokeClient()
135 	{
136 		::osl::MutexGuard aGuard(s_aMutex);
137 		if (!--s_nClients && s_pImpl)
138 		{
139 			delete s_pImpl;
140 			s_pImpl = NULL;
141 		}
142 	}
143 
144 	//-------------------------------------------------------------------------
ensureImpl()145 	void OModule::ensureImpl()
146 	{
147 		if (s_pImpl)
148 			return;
149 		s_pImpl = new OModuleImpl();
150 		s_pImpl->setResourceFilePrefix(s_sResPrefix);
151 	}
152 
153 	//--------------------------------------------------------------------------
154 	//- registration helper
155 	//--------------------------------------------------------------------------
156 
157 	Sequence< ::rtl::OUString >*				OModule::s_pImplementationNames = NULL;
158 	Sequence< Sequence< ::rtl::OUString > >*	OModule::s_pSupportedServices = NULL;
159 	Sequence< sal_Int64 >*						OModule::s_pCreationFunctionPointers = NULL;
160 	Sequence< sal_Int64 >*						OModule::s_pFactoryFunctionPointers = NULL;
161 
162 	//--------------------------------------------------------------------------
registerComponent(const::rtl::OUString & _rImplementationName,const Sequence<::rtl::OUString> & _rServiceNames,ComponentInstantiation _pCreateFunction,FactoryInstantiation _pFactoryFunction)163 	void OModule::registerComponent(
164 		const ::rtl::OUString& _rImplementationName,
165 		const Sequence< ::rtl::OUString >& _rServiceNames,
166 		ComponentInstantiation _pCreateFunction,
167 		FactoryInstantiation _pFactoryFunction)
168 	{
169 		if (!s_pImplementationNames)
170 		{
171 			OSL_ENSURE(!s_pSupportedServices && !s_pCreationFunctionPointers && !s_pFactoryFunctionPointers,
172 				"OModule::registerComponent : inconsistent state (the pointers (1)) !");
173 			s_pImplementationNames = new Sequence< ::rtl::OUString >;
174 			s_pSupportedServices = new Sequence< Sequence< ::rtl::OUString > >;
175 			s_pCreationFunctionPointers = new Sequence< sal_Int64 >;
176 			s_pFactoryFunctionPointers = new Sequence< sal_Int64 >;
177 		}
178 		OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
179 			"OModule::registerComponent : inconsistent state (the pointers (2)) !");
180 
181 		OSL_ENSURE(	(s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
182 					&&	(s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
183 					&&	(s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
184 			"OModule::registerComponent : inconsistent state !");
185 
186 		sal_Int32 nOldLen = s_pImplementationNames->getLength();
187 		s_pImplementationNames->realloc(nOldLen + 1);
188 		s_pSupportedServices->realloc(nOldLen + 1);
189 		s_pCreationFunctionPointers->realloc(nOldLen + 1);
190 		s_pFactoryFunctionPointers->realloc(nOldLen + 1);
191 
192 		s_pImplementationNames->getArray()[nOldLen] = _rImplementationName;
193 		s_pSupportedServices->getArray()[nOldLen] = _rServiceNames;
194 		s_pCreationFunctionPointers->getArray()[nOldLen] = reinterpret_cast<sal_Int64>(_pCreateFunction);
195 		s_pFactoryFunctionPointers->getArray()[nOldLen] = reinterpret_cast<sal_Int64>(_pFactoryFunction);
196 	}
197 
198 	//--------------------------------------------------------------------------
revokeComponent(const::rtl::OUString & _rImplementationName)199 	void OModule::revokeComponent(const ::rtl::OUString& _rImplementationName)
200 	{
201 		if (!s_pImplementationNames)
202 		{
203 			OSL_ASSERT("OModule::revokeComponent : have no class infos ! Are you sure called this method at the right time ?");
204 			return;
205 		}
206 		OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
207 			"OModule::revokeComponent : inconsistent state (the pointers) !");
208 		OSL_ENSURE(	(s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
209 					&&	(s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
210 					&&	(s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
211 			"OModule::revokeComponent : inconsistent state !");
212 
213 		sal_Int32 nLen = s_pImplementationNames->getLength();
214 		const ::rtl::OUString* pImplNames = s_pImplementationNames->getConstArray();
215 		for (sal_Int32 i=0; i<nLen; ++i, ++pImplNames)
216 		{
217 			if (pImplNames->equals(_rImplementationName))
218 			{
219 				removeElementAt(*s_pImplementationNames, i);
220 				removeElementAt(*s_pSupportedServices, i);
221 				removeElementAt(*s_pCreationFunctionPointers, i);
222 				removeElementAt(*s_pFactoryFunctionPointers, i);
223 				break;
224 			}
225 		}
226 
227 		if (s_pImplementationNames->getLength() == 0)
228 		{
229 			delete s_pImplementationNames; s_pImplementationNames = NULL;
230 			delete s_pSupportedServices; s_pSupportedServices = NULL;
231 			delete s_pCreationFunctionPointers; s_pCreationFunctionPointers = NULL;
232 			delete s_pFactoryFunctionPointers; s_pFactoryFunctionPointers = NULL;
233 		}
234 	}
235 
236 	//--------------------------------------------------------------------------
getComponentFactory(const::rtl::OUString & _rImplementationName,const Reference<XMultiServiceFactory> & _rxServiceManager)237 	Reference< XInterface > OModule::getComponentFactory(
238 		const ::rtl::OUString& _rImplementationName,
239 		const Reference< XMultiServiceFactory >& _rxServiceManager)
240 	{
241 		OSL_ENSURE(_rxServiceManager.is(), "OModule::getComponentFactory : invalid argument (service manager) !");
242 		OSL_ENSURE(_rImplementationName.getLength(), "OModule::getComponentFactory : invalid argument (implementation name) !");
243 
244 		if (!s_pImplementationNames)
245 		{
246 			OSL_ASSERT("OModule::getComponentFactory : have no class infos ! Are you sure called this method at the right time ?");
247 			return NULL;
248 		}
249 		OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
250 			"OModule::getComponentFactory : inconsistent state (the pointers) !");
251 		OSL_ENSURE(	(s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
252 					&&	(s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
253 					&&	(s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
254 			"OModule::getComponentFactory : inconsistent state !");
255 
256 
257 		Reference< XInterface > xReturn;
258 
259 
260 		sal_Int32 nLen = s_pImplementationNames->getLength();
261 		const ::rtl::OUString* pImplName = s_pImplementationNames->getConstArray();
262 		const Sequence< ::rtl::OUString >* pServices = s_pSupportedServices->getConstArray();
263 		const sal_Int64* pComponentFunction = s_pCreationFunctionPointers->getConstArray();
264 		const sal_Int64* pFactoryFunction = s_pFactoryFunctionPointers->getConstArray();
265 
266 		for (sal_Int32 i=0; i<nLen; ++i, ++pImplName, ++pServices, ++pComponentFunction, ++pFactoryFunction)
267 		{
268 			if (pImplName->equals(_rImplementationName))
269 			{
270 				const FactoryInstantiation FactoryInstantiationFunction = reinterpret_cast<const FactoryInstantiation>(*pFactoryFunction);
271 				const ComponentInstantiation ComponentInstantiationFunction = reinterpret_cast<const ComponentInstantiation>(*pComponentFunction);
272 
273 				xReturn = FactoryInstantiationFunction( _rxServiceManager, *pImplName, ComponentInstantiationFunction, *pServices, NULL);
274 				if (xReturn.is())
275 				{
276 					xReturn->acquire();
277 					return xReturn.get();
278 				}
279 			}
280 		}
281 
282 		return NULL;
283 	}
284 
285 
286 //.........................................................................
287 }	// namespace COMPMOD_NAMESPACE
288 //.........................................................................
289 
290