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