1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_stoc.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir #include <cstdarg>
33*cdf0e10cSrcweir #include <osl/diagnose.h>
34*cdf0e10cSrcweir #include <osl/process.h>
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include <rtl/process.h>
37*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include <uno/environment.h>
40*cdf0e10cSrcweir #include <uno/mapping.hxx>
41*cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir #include <cppuhelper/servicefactory.hxx>
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir #ifdef LINUX
46*cdf0e10cSrcweir #undef minor
47*cdf0e10cSrcweir #undef major
48*cdf0e10cSrcweir #endif
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir #include <com/sun/star/java/XJavaVM.hpp>
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiComponentFactory.hpp>
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir #include "jni.h"
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir #include <cppuhelper/factory.hxx>
57*cdf0e10cSrcweir #include <cppuhelper/implementationentry.hxx>
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir #include <cppuhelper/implbase2.hxx>
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir #include <com/sun/star/loader/XImplementationLoader.hpp>
62*cdf0e10cSrcweir #include <com/sun/star/lang/IllegalArgumentException.hpp>
63*cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
64*cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
65*cdf0e10cSrcweir #include <com/sun/star/registry/XRegistryKey.hpp>
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir #include "jvmaccess/unovirtualmachine.hxx"
68*cdf0e10cSrcweir #include "jvmaccess/virtualmachine.hxx"
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir namespace css = com::sun::star;
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir using namespace ::com::sun::star::java;
73*cdf0e10cSrcweir using namespace ::com::sun::star::lang;
74*cdf0e10cSrcweir using namespace ::com::sun::star::loader;
75*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
76*cdf0e10cSrcweir using namespace ::com::sun::star::registry;
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir using namespace ::cppu;
79*cdf0e10cSrcweir using namespace ::rtl;
80*cdf0e10cSrcweir using namespace ::osl;
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir namespace stoc_javaloader {
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir static Mutex & getInitMutex();
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir static Sequence< OUString > loader_getSupportedServiceNames()
87*cdf0e10cSrcweir {
88*cdf0e10cSrcweir     static Sequence < OUString > *pNames = 0;
89*cdf0e10cSrcweir     if( ! pNames )
90*cdf0e10cSrcweir     {
91*cdf0e10cSrcweir         MutexGuard guard( Mutex::getGlobalMutex() );
92*cdf0e10cSrcweir         if( !pNames )
93*cdf0e10cSrcweir         {
94*cdf0e10cSrcweir             static Sequence< OUString > seqNames(2);
95*cdf0e10cSrcweir             seqNames.getArray()[0] = OUString(
96*cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.loader.Java") );
97*cdf0e10cSrcweir             seqNames.getArray()[1] = OUString(
98*cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.loader.Java2") );
99*cdf0e10cSrcweir             pNames = &seqNames;
100*cdf0e10cSrcweir         }
101*cdf0e10cSrcweir     }
102*cdf0e10cSrcweir     return *pNames;
103*cdf0e10cSrcweir }
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir static OUString loader_getImplementationName()
106*cdf0e10cSrcweir {
107*cdf0e10cSrcweir     static OUString *pImplName = 0;
108*cdf0e10cSrcweir     if( ! pImplName )
109*cdf0e10cSrcweir     {
110*cdf0e10cSrcweir         MutexGuard guard( Mutex::getGlobalMutex() );
111*cdf0e10cSrcweir         if( ! pImplName )
112*cdf0e10cSrcweir         {
113*cdf0e10cSrcweir             static OUString implName(
114*cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.JavaComponentLoader" ) );
115*cdf0e10cSrcweir             pImplName = &implName;
116*cdf0e10cSrcweir         }
117*cdf0e10cSrcweir     }
118*cdf0e10cSrcweir     return *pImplName;
119*cdf0e10cSrcweir }
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir class JavaComponentLoader : public WeakImplHelper2<XImplementationLoader, XServiceInfo>
122*cdf0e10cSrcweir {
123*cdf0e10cSrcweir     css::uno::Reference<XComponentContext> m_xComponentContext;
124*cdf0e10cSrcweir     /** Do not use m_javaLoader directly. Instead use getJavaLoader.
125*cdf0e10cSrcweir      */
126*cdf0e10cSrcweir     css::uno::Reference<XImplementationLoader> m_javaLoader;
127*cdf0e10cSrcweir     /** The retured Reference contains a null pointer if the office is not configured
128*cdf0e10cSrcweir         to run java.
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir         @exception com::sun::star::uno::RuntimeException
131*cdf0e10cSrcweir         If the Java implementation of the loader could not be obtained, for reasons other
132*cdf0e10cSrcweir         then that java was not configured the RuntimeException is thrown.
133*cdf0e10cSrcweir      */
134*cdf0e10cSrcweir     const css::uno::Reference<XImplementationLoader> & getJavaLoader();
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir public:
138*cdf0e10cSrcweir 	JavaComponentLoader(const css::uno::Reference<XComponentContext> & xCtx)
139*cdf0e10cSrcweir         throw(RuntimeException);
140*cdf0e10cSrcweir 	virtual ~JavaComponentLoader() throw();
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir public:
143*cdf0e10cSrcweir 	// XServiceInfo
144*cdf0e10cSrcweir 	virtual OUString SAL_CALL getImplementationName() throw(RuntimeException);
145*cdf0e10cSrcweir 	virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
146*cdf0e10cSrcweir         throw(RuntimeException);
147*cdf0e10cSrcweir 	virtual Sequence<OUString> SAL_CALL getSupportedServiceNames()
148*cdf0e10cSrcweir         throw(RuntimeException);
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir 	// XImplementationLoader
151*cdf0e10cSrcweir 	virtual css::uno::Reference<XInterface> SAL_CALL activate(
152*cdf0e10cSrcweir         const OUString& implementationName, const OUString& implementationLoaderUrl,
153*cdf0e10cSrcweir         const OUString& locationUrl, const css::uno::Reference<XRegistryKey>& xKey)
154*cdf0e10cSrcweir         throw(CannotActivateFactoryException, RuntimeException);
155*cdf0e10cSrcweir 	virtual sal_Bool SAL_CALL writeRegistryInfo(
156*cdf0e10cSrcweir         const css::uno::Reference<XRegistryKey>& xKey,
157*cdf0e10cSrcweir         const OUString& implementationLoaderUrl, const OUString& locationUrl)
158*cdf0e10cSrcweir         throw(CannotRegisterImplementationException, RuntimeException);
159*cdf0e10cSrcweir };
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir const css::uno::Reference<XImplementationLoader> & JavaComponentLoader::getJavaLoader()
162*cdf0e10cSrcweir {
163*cdf0e10cSrcweir     MutexGuard aGuard(getInitMutex());
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir     if (m_javaLoader.is())
166*cdf0e10cSrcweir         return m_javaLoader;
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir 	uno_Environment * pJava_environment = NULL;
169*cdf0e10cSrcweir 	uno_Environment * pUno_environment = NULL;
170*cdf0e10cSrcweir 	typelib_InterfaceTypeDescription * pType_XImplementationLoader = 0;
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir 	try {
173*cdf0e10cSrcweir 		// get a java vm, where we can create a loader
174*cdf0e10cSrcweir 		css::uno::Reference<XJavaVM> javaVM_xJavaVM(
175*cdf0e10cSrcweir             m_xComponentContext->getValueByName(
176*cdf0e10cSrcweir                 OUString(RTL_CONSTASCII_USTRINGPARAM(
177*cdf0e10cSrcweir                              "/singletons/"
178*cdf0e10cSrcweir                              "com.sun.star.java.theJavaVirtualMachine"))),
179*cdf0e10cSrcweir             UNO_QUERY_THROW);
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir         // Use the special protocol of XJavaVM.getJavaVM:  If the passed in
182*cdf0e10cSrcweir         // process ID has an extra 17th byte of value one, the returned any
183*cdf0e10cSrcweir         // contains a pointer to a jvmaccess::UnoVirtualMachine, instead of the
184*cdf0e10cSrcweir         // underlying JavaVM pointer:
185*cdf0e10cSrcweir 		Sequence<sal_Int8> processID(17);
186*cdf0e10cSrcweir 		rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8 *>(processID.getArray()));
187*cdf0e10cSrcweir         processID[16] = 1;
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir         // We get a non-refcounted pointer to a jvmaccess::UnoVirtualMachine
190*cdf0e10cSrcweir         // from the XJavaVM service (the pointer is guaranteed to be valid
191*cdf0e10cSrcweir         // as long as our reference to the XJavaVM service lasts), and
192*cdf0e10cSrcweir         // convert the non-refcounted pointer into a refcounted one
193*cdf0e10cSrcweir         // immediately:
194*cdf0e10cSrcweir         OSL_ENSURE(sizeof (sal_Int64)
195*cdf0e10cSrcweir                         >= sizeof (jvmaccess::UnoVirtualMachine *),
196*cdf0e10cSrcweir                     "Pointer cannot be represented as sal_Int64");
197*cdf0e10cSrcweir         sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
198*cdf0e10cSrcweir             static_cast< jvmaccess::UnoVirtualMachine * >(0));
199*cdf0e10cSrcweir         javaVM_xJavaVM->getJavaVM(processID) >>= nPointer;
200*cdf0e10cSrcweir         rtl::Reference< jvmaccess::UnoVirtualMachine > xVirtualMachine(
201*cdf0e10cSrcweir             reinterpret_cast< jvmaccess::UnoVirtualMachine * >(nPointer));
202*cdf0e10cSrcweir         if (!xVirtualMachine.is())
203*cdf0e10cSrcweir             //throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
204*cdf0e10cSrcweir             //   "javaloader error - JavaVirtualMachine service could not provide a VM")),
205*cdf0e10cSrcweir             //   css::uno::Reference<XInterface>());
206*cdf0e10cSrcweir             // We must not throw a RuntimeException, because this might end the applications.
207*cdf0e10cSrcweir             // It is ok if java components
208*cdf0e10cSrcweir             // are not working because the office can be installed without Java support.
209*cdf0e10cSrcweir             return m_javaLoader; // null-ref
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir         try
212*cdf0e10cSrcweir         {
213*cdf0e10cSrcweir             jvmaccess::VirtualMachine::AttachGuard aGuard2(
214*cdf0e10cSrcweir                 xVirtualMachine->getVirtualMachine());
215*cdf0e10cSrcweir             JNIEnv * pJNIEnv = aGuard2.getEnvironment();
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir             // instantiate the java JavaLoader
218*cdf0e10cSrcweir             jclass jcClassLoader = pJNIEnv->FindClass("java/lang/ClassLoader");
219*cdf0e10cSrcweir             if(pJNIEnv->ExceptionOccurred())
220*cdf0e10cSrcweir                 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
221*cdf0e10cSrcweir                     "javaloader error - could not find class java/lang/ClassLoader")),
222*cdf0e10cSrcweir                     css::uno::Reference<XInterface>());
223*cdf0e10cSrcweir             jmethodID jmLoadClass = pJNIEnv->GetMethodID(
224*cdf0e10cSrcweir                 jcClassLoader, "loadClass",
225*cdf0e10cSrcweir                 "(Ljava/lang/String;)Ljava/lang/Class;");
226*cdf0e10cSrcweir             if(pJNIEnv->ExceptionOccurred())
227*cdf0e10cSrcweir                 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
228*cdf0e10cSrcweir                     "javaloader error - could not find method java/lang/ClassLoader.loadClass")),
229*cdf0e10cSrcweir                     css::uno::Reference<XInterface>());
230*cdf0e10cSrcweir             jvalue arg;
231*cdf0e10cSrcweir             arg.l = pJNIEnv->NewStringUTF(
232*cdf0e10cSrcweir                 "com.sun.star.comp.loader.JavaLoader");
233*cdf0e10cSrcweir             if(pJNIEnv->ExceptionOccurred())
234*cdf0e10cSrcweir                 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
235*cdf0e10cSrcweir                     "javaloader error - could not create string")),
236*cdf0e10cSrcweir                     css::uno::Reference<XInterface>());
237*cdf0e10cSrcweir             jclass jcJavaLoader = static_cast< jclass >(
238*cdf0e10cSrcweir                 pJNIEnv->CallObjectMethodA(
239*cdf0e10cSrcweir                     static_cast< jobject >(xVirtualMachine->getClassLoader()),
240*cdf0e10cSrcweir                     jmLoadClass, &arg));
241*cdf0e10cSrcweir             if(pJNIEnv->ExceptionOccurred())
242*cdf0e10cSrcweir                 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
243*cdf0e10cSrcweir                     "javaloader error - could not find class com/sun/star/comp/loader/JavaLoader")),
244*cdf0e10cSrcweir                     css::uno::Reference<XInterface>());
245*cdf0e10cSrcweir             jmethodID jmJavaLoader_init = pJNIEnv->GetMethodID(jcJavaLoader, "<init>", "()V");
246*cdf0e10cSrcweir             if(pJNIEnv->ExceptionOccurred())
247*cdf0e10cSrcweir                 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
248*cdf0e10cSrcweir                     "javaloader error - instantiation of com.sun.star.comp.loader.JavaLoader failed")),
249*cdf0e10cSrcweir                     css::uno::Reference<XInterface>());
250*cdf0e10cSrcweir             jobject joJavaLoader = pJNIEnv->NewObject(jcJavaLoader, jmJavaLoader_init);
251*cdf0e10cSrcweir             if(pJNIEnv->ExceptionOccurred())
252*cdf0e10cSrcweir                 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
253*cdf0e10cSrcweir                     "javaloader error - instantiation of com.sun.star.comp.loader.JavaLoader failed")),
254*cdf0e10cSrcweir                     css::uno::Reference<XInterface>());
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir             // map the java JavaLoader to this environment
257*cdf0e10cSrcweir             OUString sJava(RTL_CONSTASCII_USTRINGPARAM("java"));
258*cdf0e10cSrcweir             uno_getEnvironment(&pJava_environment, sJava.pData,
259*cdf0e10cSrcweir                                 xVirtualMachine.get());
260*cdf0e10cSrcweir             if(!pJava_environment)
261*cdf0e10cSrcweir                 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
262*cdf0e10cSrcweir                     "javaloader error - no Java environment available")), css::uno::Reference<XInterface>());
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir             // why is there no convinient contructor?
265*cdf0e10cSrcweir             OUString sCppu_current_lb_name(RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME));
266*cdf0e10cSrcweir             uno_getEnvironment(&pUno_environment, sCppu_current_lb_name.pData, NULL);
267*cdf0e10cSrcweir             if(!pUno_environment)
268*cdf0e10cSrcweir                 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
269*cdf0e10cSrcweir                     "javaloader error - no C++ environment available")), css::uno::Reference<XInterface>());
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir             Mapping java_curr(pJava_environment, pUno_environment);
272*cdf0e10cSrcweir             if(!java_curr.is())
273*cdf0e10cSrcweir                 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
274*cdf0e10cSrcweir                     "javaloader error - no mapping from java to C++ ")), css::uno::Reference<XInterface>());
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir             // release java environment
277*cdf0e10cSrcweir             pJava_environment->release(pJava_environment);
278*cdf0e10cSrcweir             pJava_environment = NULL;
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir             // release uno environment
281*cdf0e10cSrcweir             pUno_environment->release(pUno_environment);
282*cdf0e10cSrcweir             pUno_environment = NULL;
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir             getCppuType((css::uno::Reference<XImplementationLoader> *) 0).
285*cdf0e10cSrcweir                 getDescription((typelib_TypeDescription **) & pType_XImplementationLoader);
286*cdf0e10cSrcweir             if(!pType_XImplementationLoader)
287*cdf0e10cSrcweir                 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
288*cdf0e10cSrcweir                     "javaloader error - no type information for XImplementationLoader")),
289*cdf0e10cSrcweir                     css::uno::Reference<XInterface>());
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir             m_javaLoader = css::uno::Reference<XImplementationLoader>(reinterpret_cast<XImplementationLoader *>(
292*cdf0e10cSrcweir                             java_curr.mapInterface(joJavaLoader, pType_XImplementationLoader)));
293*cdf0e10cSrcweir             pJNIEnv->DeleteLocalRef( joJavaLoader );
294*cdf0e10cSrcweir             if(!m_javaLoader.is())
295*cdf0e10cSrcweir                 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
296*cdf0e10cSrcweir                     "javaloader error - mapping of java XImplementationLoader to c++ failed")),
297*cdf0e10cSrcweir                     css::uno::Reference<XInterface>());
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir             typelib_typedescription_release(reinterpret_cast<typelib_TypeDescription *>(pType_XImplementationLoader));
300*cdf0e10cSrcweir             pType_XImplementationLoader = NULL;
301*cdf0e10cSrcweir         }
302*cdf0e10cSrcweir         catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
303*cdf0e10cSrcweir         {
304*cdf0e10cSrcweir             throw RuntimeException(
305*cdf0e10cSrcweir                 OUString(RTL_CONSTASCII_USTRINGPARAM(
306*cdf0e10cSrcweir                                 "jvmaccess::VirtualMachine::AttachGuard"
307*cdf0e10cSrcweir                                 "::CreationException")),0);
308*cdf0e10cSrcweir         }
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir 		// set the service manager at the javaloader
311*cdf0e10cSrcweir 		css::uno::Reference<XInitialization> javaLoader_XInitialization(m_javaLoader, UNO_QUERY);
312*cdf0e10cSrcweir 		if(!javaLoader_XInitialization.is())
313*cdf0e10cSrcweir             throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
314*cdf0e10cSrcweir                 "javaloader error - initialization of java javaloader failed, no XInitialization")),
315*cdf0e10cSrcweir                 css::uno::Reference<XInterface>());
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir 		Any any;
318*cdf0e10cSrcweir 		any <<= css::uno::Reference<XMultiComponentFactory>(
319*cdf0e10cSrcweir             m_xComponentContext->getServiceManager());
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir 		javaLoader_XInitialization->initialize(Sequence<Any>(&any, 1));
322*cdf0e10cSrcweir 	}
323*cdf0e10cSrcweir 	catch(RuntimeException &) {
324*cdf0e10cSrcweir 		if(pJava_environment)
325*cdf0e10cSrcweir 			pJava_environment->release(pJava_environment);
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir 		if(pUno_environment)
328*cdf0e10cSrcweir 			pUno_environment->release(pUno_environment);
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir 		if(pType_XImplementationLoader)
331*cdf0e10cSrcweir 			typelib_typedescription_release(
332*cdf0e10cSrcweir                 reinterpret_cast<typelib_TypeDescription *>(pType_XImplementationLoader));
333*cdf0e10cSrcweir 		throw;
334*cdf0e10cSrcweir 	}
335*cdf0e10cSrcweir 	OSL_TRACE("javaloader.cxx: mapped javaloader - 0x%x", m_javaLoader.get());
336*cdf0e10cSrcweir     return m_javaLoader;
337*cdf0e10cSrcweir }
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir JavaComponentLoader::JavaComponentLoader(const css::uno::Reference<XComponentContext> & xCtx) throw(RuntimeException) :
340*cdf0e10cSrcweir     m_xComponentContext(xCtx)
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir {
343*cdf0e10cSrcweir 
344*cdf0e10cSrcweir }
345*cdf0e10cSrcweir 
346*cdf0e10cSrcweir JavaComponentLoader::~JavaComponentLoader() throw()
347*cdf0e10cSrcweir {
348*cdf0e10cSrcweir }
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir // XServiceInfo
351*cdf0e10cSrcweir OUString SAL_CALL JavaComponentLoader::getImplementationName()
352*cdf0e10cSrcweir     throw(::com::sun::star::uno::RuntimeException)
353*cdf0e10cSrcweir {
354*cdf0e10cSrcweir 	return loader_getImplementationName();
355*cdf0e10cSrcweir }
356*cdf0e10cSrcweir 
357*cdf0e10cSrcweir sal_Bool SAL_CALL JavaComponentLoader::supportsService(const OUString & ServiceName)
358*cdf0e10cSrcweir     throw(::com::sun::star::uno::RuntimeException)
359*cdf0e10cSrcweir {
360*cdf0e10cSrcweir 	sal_Bool bSupport = sal_False;
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir 	Sequence<OUString> aSNL = getSupportedServiceNames();
363*cdf0e10cSrcweir 	const OUString * pArray = aSNL.getArray();
364*cdf0e10cSrcweir 	for(sal_Int32 i = 0; i < aSNL.getLength() && !bSupport; ++ i)
365*cdf0e10cSrcweir 		bSupport = pArray[i] == ServiceName;
366*cdf0e10cSrcweir 
367*cdf0e10cSrcweir 	return bSupport;
368*cdf0e10cSrcweir }
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir Sequence<OUString> SAL_CALL JavaComponentLoader::getSupportedServiceNames()
371*cdf0e10cSrcweir     throw(::com::sun::star::uno::RuntimeException)
372*cdf0e10cSrcweir {
373*cdf0e10cSrcweir 	return loader_getSupportedServiceNames();
374*cdf0e10cSrcweir }
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir 
378*cdf0e10cSrcweir // XImplementationLoader
379*cdf0e10cSrcweir sal_Bool SAL_CALL JavaComponentLoader::writeRegistryInfo(
380*cdf0e10cSrcweir     const css::uno::Reference<XRegistryKey> & xKey, const OUString & blabla,
381*cdf0e10cSrcweir     const OUString & rLibName)
382*cdf0e10cSrcweir 	throw(CannotRegisterImplementationException, RuntimeException)
383*cdf0e10cSrcweir {
384*cdf0e10cSrcweir     const css::uno::Reference<XImplementationLoader> & loader = getJavaLoader();
385*cdf0e10cSrcweir     if (loader.is())
386*cdf0e10cSrcweir         return loader->writeRegistryInfo(xKey, blabla, rLibName);
387*cdf0e10cSrcweir     else
388*cdf0e10cSrcweir         throw CannotRegisterImplementationException(
389*cdf0e10cSrcweir             OUString(RTL_CONSTASCII_USTRINGPARAM("Could not create Java implementation loader")), NULL);
390*cdf0e10cSrcweir }
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir css::uno::Reference<XInterface> SAL_CALL JavaComponentLoader::activate(
394*cdf0e10cSrcweir     const OUString & rImplName, const OUString & blabla, const OUString & rLibName,
395*cdf0e10cSrcweir     const css::uno::Reference<XRegistryKey> & xKey)
396*cdf0e10cSrcweir     throw(CannotActivateFactoryException, RuntimeException)
397*cdf0e10cSrcweir {
398*cdf0e10cSrcweir     const css::uno::Reference<XImplementationLoader> & loader = getJavaLoader();
399*cdf0e10cSrcweir     if (loader.is())
400*cdf0e10cSrcweir         return loader->activate(rImplName, blabla, rLibName, xKey);
401*cdf0e10cSrcweir     else
402*cdf0e10cSrcweir         throw CannotActivateFactoryException(
403*cdf0e10cSrcweir             OUString(RTL_CONSTASCII_USTRINGPARAM("Could not create Java implementation loader")), NULL);
404*cdf0e10cSrcweir }
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir static Mutex & getInitMutex()
407*cdf0e10cSrcweir {
408*cdf0e10cSrcweir     static Mutex * pMutex = 0;
409*cdf0e10cSrcweir     if( ! pMutex )
410*cdf0e10cSrcweir     {
411*cdf0e10cSrcweir         MutexGuard guard( Mutex::getGlobalMutex() );
412*cdf0e10cSrcweir         if( ! pMutex )
413*cdf0e10cSrcweir         {
414*cdf0e10cSrcweir             static Mutex mutex;
415*cdf0e10cSrcweir             pMutex = &mutex;
416*cdf0e10cSrcweir         }
417*cdf0e10cSrcweir     }
418*cdf0e10cSrcweir     return *pMutex;
419*cdf0e10cSrcweir }
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir css::uno::Reference<XInterface> SAL_CALL JavaComponentLoader_CreateInstance(const css::uno::Reference<XComponentContext> & xCtx) throw(Exception)
422*cdf0e10cSrcweir {
423*cdf0e10cSrcweir     css::uno::Reference<XInterface> xRet;
424*cdf0e10cSrcweir 
425*cdf0e10cSrcweir     try {
426*cdf0e10cSrcweir         MutexGuard guard( getInitMutex() );
427*cdf0e10cSrcweir         // The javaloader is never destroyed and there can be only one!
428*cdf0e10cSrcweir         // Note that the first context wins ....
429*cdf0e10cSrcweir         static css::uno::Reference< XInterface > *pStaticRef = 0;
430*cdf0e10cSrcweir         if( pStaticRef )
431*cdf0e10cSrcweir         {
432*cdf0e10cSrcweir             xRet = *pStaticRef;
433*cdf0e10cSrcweir         }
434*cdf0e10cSrcweir         else
435*cdf0e10cSrcweir         {
436*cdf0e10cSrcweir             xRet = *new JavaComponentLoader(xCtx);
437*cdf0e10cSrcweir             pStaticRef = new css::uno::Reference< XInterface > ( xRet );
438*cdf0e10cSrcweir         }
439*cdf0e10cSrcweir     }
440*cdf0e10cSrcweir     catch(RuntimeException & runtimeException) {
441*cdf0e10cSrcweir         OString message = OUStringToOString(runtimeException.Message, RTL_TEXTENCODING_ASCII_US);
442*cdf0e10cSrcweir         osl_trace("javaloader - could not init javaloader cause of %s", message.getStr());
443*cdf0e10cSrcweir         throw;
444*cdf0e10cSrcweir     }
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir     return xRet;
447*cdf0e10cSrcweir }
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir } //end namespace
450*cdf0e10cSrcweir 
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir using namespace stoc_javaloader;
453*cdf0e10cSrcweir 
454*cdf0e10cSrcweir static struct ImplementationEntry g_entries[] =
455*cdf0e10cSrcweir {
456*cdf0e10cSrcweir 	{
457*cdf0e10cSrcweir 		JavaComponentLoader_CreateInstance, loader_getImplementationName,
458*cdf0e10cSrcweir 		loader_getSupportedServiceNames, createSingleComponentFactory,
459*cdf0e10cSrcweir 		0 , 0
460*cdf0e10cSrcweir 	},
461*cdf0e10cSrcweir 	{ 0, 0, 0, 0, 0, 0 }
462*cdf0e10cSrcweir };
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir extern "C"
465*cdf0e10cSrcweir {
466*cdf0e10cSrcweir // NOTE: component_canUnload is not exported, as the library cannot be unloaded.
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir //==================================================================================================
469*cdf0e10cSrcweir void SAL_CALL component_getImplementationEnvironment(
470*cdf0e10cSrcweir 	const sal_Char ** ppEnvTypeName, uno_Environment ** )
471*cdf0e10cSrcweir {
472*cdf0e10cSrcweir 	*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
473*cdf0e10cSrcweir }
474*cdf0e10cSrcweir //==================================================================================================
475*cdf0e10cSrcweir void * SAL_CALL component_getFactory(
476*cdf0e10cSrcweir 	const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
477*cdf0e10cSrcweir {
478*cdf0e10cSrcweir 	return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
479*cdf0e10cSrcweir }
480*cdf0e10cSrcweir }
481