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