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