xref: /AOO41X/main/extensions/source/inc/componentmodule.cxx (revision 2a97ec55f1442d65917e8c8b82a55ab76c9ff676)
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