xref: /AOO41X/main/unotools/source/processfactory/componentfactory.cxx (revision b5088357f810cb81479bbbd0e021cd3c9835ca0d)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_unotools.hxx"
26 
27 #include <unotools/componentfactory.hxx>
28 #include <comphelper/processfactory.hxx>
29 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
30 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 
32 #ifndef _COM_SUN_STAR_REGISTRY_XREGISTRYKEY_HDL_
33 #include <com/sun/star/registry/XRegistryKey.hpp>
34 #endif
35 
36 #include <cppuhelper/factory.hxx>
37 
38 #include <uno/environment.h>
39 #include <uno/mapping.hxx>
40 
41 #include <rtl/ustring.hxx>
42 #include <osl/module.h>
43 
44 
45 
46 
47 using namespace ::com::sun::star;
48 using namespace ::com::sun::star::uno;
49 using namespace ::com::sun::star::lang;
50 using namespace ::com::sun::star::registry;
51 using namespace ::rtl;
52 
53 
54 namespace utl
55 {
56 
getComponentInstance(const OUString & rLibraryName,const OUString & rImplementationName)57 Reference< XInterface > getComponentInstance(
58             const OUString & rLibraryName,
59             const OUString & rImplementationName
60             )
61 {
62     Reference< XInterface > xI;
63     Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
64     if ( xMSF.is() )
65         xI = xMSF->createInstance( rImplementationName );
66     if( !xI.is() )
67     {
68         Reference< XSingleServiceFactory > xSSF =
69             loadLibComponentFactory( rLibraryName, rImplementationName,
70             Reference< XMultiServiceFactory >(), Reference< XRegistryKey >() );
71         xI = xSSF->createInstance();
72     }
73     return xI;
74 }
75 
76 
loadLibComponentFactory(const OUString & rLibName,const OUString & rImplName,const Reference<XMultiServiceFactory> & xSF,const Reference<XRegistryKey> & xKey)77 Reference< XSingleServiceFactory > loadLibComponentFactory(
78             const OUString & rLibName,
79             const OUString & rImplName,
80             const Reference< XMultiServiceFactory > & xSF,
81             const Reference< XRegistryKey > & xKey
82             )
83 {
84     Reference< XSingleServiceFactory > xRet;
85 
86     oslModule lib = osl_loadModule( rLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
87     if (lib)
88     {
89         void * pSym;
90 
91         // ========================= LATEST VERSION =========================
92         OUString aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV) );
93         if (pSym = osl_getSymbol( lib, aGetEnvName.pData ))
94         {
95             uno_Environment * pCurrentEnv = 0;
96             uno_Environment * pEnv = 0;
97             const sal_Char * pEnvTypeName = 0;
98             (*((component_getImplementationEnvironmentFunc)pSym))( &pEnvTypeName, &pEnv );
99 
100             sal_Bool bNeedsMapping =
101                 (pEnv || 0 != rtl_str_compare( pEnvTypeName, CPPU_CURRENT_LANGUAGE_BINDING_NAME ));
102 
103             OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) );
104 
105             if (bNeedsMapping)
106             {
107                 if (! pEnv)
108                     uno_getEnvironment( &pEnv, aEnvTypeName.pData, 0 );
109                 if (pEnv)
110                 {
111                     OUString aCppEnvTypeName( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
112                     uno_getEnvironment( &pCurrentEnv, aCppEnvTypeName.pData, 0 );
113                     if (pCurrentEnv)
114                         bNeedsMapping = (pEnv != pCurrentEnv);
115                 }
116             }
117 
118             OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETFACTORY) );
119             if (pSym = osl_getSymbol( lib, aGetFactoryName.pData ))
120             {
121                 OString aImplName( OUStringToOString( rImplName, RTL_TEXTENCODING_ASCII_US ) );
122 
123                 if (bNeedsMapping)
124                 {
125                     if (pEnv && pCurrentEnv)
126                     {
127                         Mapping aCurrent2Env( pCurrentEnv, pEnv );
128                         Mapping aEnv2Current( pEnv, pCurrentEnv );
129 
130                         if (aCurrent2Env.is() && aEnv2Current.is())
131                         {
132                             void * pSMgr = aCurrent2Env.mapInterface(
133                                 xSF.get(), ::getCppuType( (const Reference< XMultiServiceFactory > *)0 ) );
134                             void * pKey = aCurrent2Env.mapInterface(
135                                 xKey.get(), ::getCppuType( (const Reference< XRegistryKey > *)0 ) );
136 
137                             void * pSSF = (*((component_getFactoryFunc)pSym))(
138                                 aImplName.getStr(), pSMgr, pKey );
139 
140                             if (pKey)
141                                 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pKey );
142                             if (pSMgr)
143                                 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSMgr );
144 
145                             if (pSSF)
146                             {
147                                 aEnv2Current.mapInterface(
148                                     reinterpret_cast< void ** >( &xRet ),
149                                     pSSF, ::getCppuType( (const Reference< XSingleServiceFactory > *)0 ) );
150                                 (*pEnv->pExtEnv->releaseInterface)( pEnv->pExtEnv, pSSF );
151                             }
152                         }
153                     }
154                 }
155                 else
156                 {
157                     XSingleServiceFactory * pRet = (XSingleServiceFactory *)
158                         (*((component_getFactoryFunc)pSym))(
159                             aImplName.getStr(), xSF.get(), xKey.get() );
160                     if (pRet)
161                     {
162                         xRet = pRet;
163                         pRet->release();
164                     }
165                 }
166             }
167 
168             if (pEnv)
169                 (*pEnv->release)( pEnv );
170             if (pCurrentEnv)
171                 (*pCurrentEnv->release)( pCurrentEnv );
172         }
173 
174 
175         if (! xRet.is())
176             osl_unloadModule( lib );
177     }
178 
179     return xRet;
180 }
181 
182 }   // namespace utl
183