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