Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "componentmodule.hxx"
30 : : #include <tools/resmgr.hxx>
31 : : #include <svl/solar.hrc>
32 : : #include <comphelper/sequence.hxx>
33 : : #include <tools/debug.hxx>
34 : : #include <rtl/strbuf.hxx>
35 : :
36 : : #define ENTER_MOD_METHOD() \
37 : : ::osl::MutexGuard aGuard(s_aMutex); \
38 : : ensureImpl()
39 : :
40 : : //.........................................................................
41 : : namespace COMPMOD_NAMESPACE
42 : : {
43 : : //.........................................................................
44 : :
45 : : using namespace ::com::sun::star::uno;
46 : : using namespace ::com::sun::star::lang;
47 : : using namespace ::com::sun::star::registry;
48 : : using namespace ::comphelper;
49 : : using namespace ::cppu;
50 : :
51 : : //=========================================================================
52 : : //= OModuleImpl
53 : : //=========================================================================
54 : : /** implementation for <type>OModule</type>. not threadsafe, has to be guarded by it's owner
55 : : */
56 : : class OModuleImpl
57 : : {
58 : : ResMgr* m_pResources;
59 : : sal_Bool m_bInitialized;
60 : : rtl::OString m_sFilePrefix;
61 : :
62 : : public:
63 : : /// ctor
64 : : OModuleImpl();
65 : : ~OModuleImpl();
66 : :
67 : : /// get the manager for the resources of the module
68 : : ResMgr* getResManager();
69 : 0 : void setResourceFilePrefix(const ::rtl::OString& _rPrefix) { m_sFilePrefix = _rPrefix; }
70 : : };
71 : :
72 : : //-------------------------------------------------------------------------
73 : 0 : OModuleImpl::OModuleImpl()
74 : : :m_pResources(NULL)
75 : 0 : ,m_bInitialized(sal_False)
76 : : {
77 : 0 : }
78 : :
79 : : //-------------------------------------------------------------------------
80 : 0 : OModuleImpl::~OModuleImpl()
81 : : {
82 : 0 : if (m_pResources)
83 : 0 : delete m_pResources;
84 : 0 : }
85 : :
86 : : //-------------------------------------------------------------------------
87 : 0 : ResMgr* OModuleImpl::getResManager()
88 : : {
89 : : // note that this method is not threadsafe, which counts for the whole class !
90 : 0 : if (!m_pResources && !m_bInitialized)
91 : : {
92 : : DBG_ASSERT(!m_sFilePrefix.isEmpty(), "OModuleImpl::getResManager: no resource file prefix!");
93 : : // create a manager with a fixed prefix
94 : 0 : m_pResources = ResMgr::CreateResMgr(m_sFilePrefix.getStr());
95 : : DBG_ASSERT(m_pResources,
96 : : rtl::OStringBuffer("OModuleImpl::getResManager: could not create the resource manager (file name: ")
97 : : .append(m_sFilePrefix)
98 : : .append(")!").getStr());
99 : :
100 : 0 : m_bInitialized = sal_True;
101 : : }
102 : 0 : return m_pResources;
103 : : }
104 : :
105 : : //=========================================================================
106 : : //= OModule
107 : : //=========================================================================
108 : 0 : ::osl::Mutex OModule::s_aMutex;
109 : : sal_Int32 OModule::s_nClients = 0;
110 : : OModuleImpl* OModule::s_pImpl = NULL;
111 : 0 : ::rtl::OString OModule::s_sResPrefix;
112 : : //-------------------------------------------------------------------------
113 : 0 : ResMgr* OModule::getResManager()
114 : : {
115 : 0 : ENTER_MOD_METHOD();
116 : 0 : return s_pImpl->getResManager();
117 : : }
118 : :
119 : : //-------------------------------------------------------------------------
120 : 0 : void OModule::setResourceFilePrefix(const ::rtl::OString& _rPrefix)
121 : : {
122 : 0 : ::osl::MutexGuard aGuard(s_aMutex);
123 : 0 : s_sResPrefix = _rPrefix;
124 : 0 : if (s_pImpl)
125 : 0 : s_pImpl->setResourceFilePrefix(_rPrefix);
126 : 0 : }
127 : :
128 : : //-------------------------------------------------------------------------
129 : 0 : void OModule::registerClient()
130 : : {
131 : 0 : ::osl::MutexGuard aGuard(s_aMutex);
132 : 0 : ++s_nClients;
133 : 0 : }
134 : :
135 : : //-------------------------------------------------------------------------
136 : 0 : void OModule::revokeClient()
137 : : {
138 : 0 : ::osl::MutexGuard aGuard(s_aMutex);
139 : 0 : if (!--s_nClients && s_pImpl)
140 : : {
141 : 0 : delete s_pImpl;
142 : 0 : s_pImpl = NULL;
143 : 0 : }
144 : 0 : }
145 : :
146 : : //-------------------------------------------------------------------------
147 : 0 : void OModule::ensureImpl()
148 : : {
149 : 0 : if (s_pImpl)
150 : 0 : return;
151 : 0 : s_pImpl = new OModuleImpl();
152 : 0 : s_pImpl->setResourceFilePrefix(s_sResPrefix);
153 : : }
154 : :
155 : : //--------------------------------------------------------------------------
156 : : //- registration helper
157 : : //--------------------------------------------------------------------------
158 : :
159 : : Sequence< ::rtl::OUString >* OModule::s_pImplementationNames = NULL;
160 : : Sequence< Sequence< ::rtl::OUString > >* OModule::s_pSupportedServices = NULL;
161 : : Sequence< sal_Int64 >* OModule::s_pCreationFunctionPointers = NULL;
162 : : Sequence< sal_Int64 >* OModule::s_pFactoryFunctionPointers = NULL;
163 : :
164 : : //--------------------------------------------------------------------------
165 : 0 : void OModule::registerComponent(
166 : : const ::rtl::OUString& _rImplementationName,
167 : : const Sequence< ::rtl::OUString >& _rServiceNames,
168 : : ComponentInstantiation _pCreateFunction,
169 : : FactoryInstantiation _pFactoryFunction)
170 : : {
171 : 0 : if (!s_pImplementationNames)
172 : : {
173 : : OSL_ENSURE(!s_pSupportedServices && !s_pCreationFunctionPointers && !s_pFactoryFunctionPointers,
174 : : "OModule::registerComponent : inconsistent state (the pointers (1)) !");
175 : 0 : s_pImplementationNames = new Sequence< ::rtl::OUString >;
176 : 0 : s_pSupportedServices = new Sequence< Sequence< ::rtl::OUString > >;
177 : 0 : s_pCreationFunctionPointers = new Sequence< sal_Int64 >;
178 : 0 : s_pFactoryFunctionPointers = new Sequence< sal_Int64 >;
179 : : }
180 : : OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
181 : : "OModule::registerComponent : inconsistent state (the pointers (2)) !");
182 : :
183 : : OSL_ENSURE( (s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
184 : : && (s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
185 : : && (s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
186 : : "OModule::registerComponent : inconsistent state !");
187 : :
188 : 0 : sal_Int32 nOldLen = s_pImplementationNames->getLength();
189 : 0 : s_pImplementationNames->realloc(nOldLen + 1);
190 : 0 : s_pSupportedServices->realloc(nOldLen + 1);
191 : 0 : s_pCreationFunctionPointers->realloc(nOldLen + 1);
192 : 0 : s_pFactoryFunctionPointers->realloc(nOldLen + 1);
193 : :
194 : 0 : s_pImplementationNames->getArray()[nOldLen] = _rImplementationName;
195 : 0 : s_pSupportedServices->getArray()[nOldLen] = _rServiceNames;
196 : 0 : s_pCreationFunctionPointers->getArray()[nOldLen] = reinterpret_cast<sal_Int64>(_pCreateFunction);
197 : 0 : s_pFactoryFunctionPointers->getArray()[nOldLen] = reinterpret_cast<sal_Int64>(_pFactoryFunction);
198 : 0 : }
199 : :
200 : : //--------------------------------------------------------------------------
201 : 0 : void OModule::revokeComponent(const ::rtl::OUString& _rImplementationName)
202 : : {
203 : 0 : if (!s_pImplementationNames)
204 : : {
205 : : OSL_FAIL("OModule::revokeComponent : have no class infos ! Are you sure called this method at the right time ?");
206 : 0 : return;
207 : : }
208 : : OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
209 : : "OModule::revokeComponent : inconsistent state (the pointers) !");
210 : : OSL_ENSURE( (s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
211 : : && (s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
212 : : && (s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
213 : : "OModule::revokeComponent : inconsistent state !");
214 : :
215 : 0 : sal_Int32 nLen = s_pImplementationNames->getLength();
216 : 0 : const ::rtl::OUString* pImplNames = s_pImplementationNames->getConstArray();
217 : 0 : for (sal_Int32 i=0; i<nLen; ++i, ++pImplNames)
218 : : {
219 : 0 : if (pImplNames->equals(_rImplementationName))
220 : : {
221 : 0 : removeElementAt(*s_pImplementationNames, i);
222 : 0 : removeElementAt(*s_pSupportedServices, i);
223 : 0 : removeElementAt(*s_pCreationFunctionPointers, i);
224 : 0 : removeElementAt(*s_pFactoryFunctionPointers, i);
225 : 0 : break;
226 : : }
227 : : }
228 : :
229 : 0 : if (s_pImplementationNames->getLength() == 0)
230 : : {
231 : 0 : delete s_pImplementationNames; s_pImplementationNames = NULL;
232 : 0 : delete s_pSupportedServices; s_pSupportedServices = NULL;
233 : 0 : delete s_pCreationFunctionPointers; s_pCreationFunctionPointers = NULL;
234 : 0 : delete s_pFactoryFunctionPointers; s_pFactoryFunctionPointers = NULL;
235 : : }
236 : : }
237 : :
238 : : //--------------------------------------------------------------------------
239 : 0 : Reference< XInterface > OModule::getComponentFactory(
240 : : const ::rtl::OUString& _rImplementationName,
241 : : const Reference< XMultiServiceFactory >& _rxServiceManager)
242 : : {
243 : : OSL_ENSURE(_rxServiceManager.is(), "OModule::getComponentFactory : invalid argument (service manager) !");
244 : : OSL_ENSURE(!_rImplementationName.isEmpty(), "OModule::getComponentFactory : invalid argument (implementation name) !");
245 : :
246 : 0 : if (!s_pImplementationNames)
247 : : {
248 : : OSL_FAIL("OModule::getComponentFactory : have no class infos ! Are you sure called this method at the right time ?");
249 : 0 : return NULL;
250 : : }
251 : : OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
252 : : "OModule::getComponentFactory : inconsistent state (the pointers) !");
253 : : OSL_ENSURE( (s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
254 : : && (s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
255 : : && (s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
256 : : "OModule::getComponentFactory : inconsistent state !");
257 : :
258 : :
259 : 0 : Reference< XInterface > xReturn;
260 : :
261 : :
262 : 0 : sal_Int32 nLen = s_pImplementationNames->getLength();
263 : 0 : const ::rtl::OUString* pImplName = s_pImplementationNames->getConstArray();
264 : 0 : const Sequence< ::rtl::OUString >* pServices = s_pSupportedServices->getConstArray();
265 : 0 : const sal_Int64* pComponentFunction = s_pCreationFunctionPointers->getConstArray();
266 : 0 : const sal_Int64* pFactoryFunction = s_pFactoryFunctionPointers->getConstArray();
267 : :
268 : 0 : for (sal_Int32 i=0; i<nLen; ++i, ++pImplName, ++pServices, ++pComponentFunction, ++pFactoryFunction)
269 : : {
270 : 0 : if (pImplName->equals(_rImplementationName))
271 : : {
272 : 0 : const FactoryInstantiation FactoryInstantiationFunction = reinterpret_cast<const FactoryInstantiation>(*pFactoryFunction);
273 : 0 : const ComponentInstantiation ComponentInstantiationFunction = reinterpret_cast<const ComponentInstantiation>(*pComponentFunction);
274 : :
275 : 0 : xReturn = FactoryInstantiationFunction( _rxServiceManager, *pImplName, ComponentInstantiationFunction, *pServices, NULL);
276 : 0 : if (xReturn.is())
277 : : {
278 : 0 : xReturn->acquire();
279 : 0 : return xReturn.get();
280 : : }
281 : : }
282 : : }
283 : :
284 : 0 : return NULL;
285 : : }
286 : :
287 : :
288 : : //.........................................................................
289 : 0 : } // namespace COMPMOD_NAMESPACE
290 : : //.........................................................................
291 : :
292 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|