xref: /trunk/main/javaunohelper/source/javaunohelper.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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_javaunohelper.hxx"
30 
31 #include <osl/diagnose.h>
32 #include <osl/module.h>
33 
34 #include <uno/environment.hxx>
35 #include <uno/mapping.hxx>
36 
37 #include <cppuhelper/factory.hxx>
38 #include <cppuhelper/servicefactory.hxx>
39 #include <cppuhelper/component_context.hxx>
40 
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
43 #include <com/sun/star/lang/XServiceInfo.hpp>
44 #include <com/sun/star/registry/XRegistryKey.hpp>
45 
46 #include "jni.h"
47 #include "jvmaccess/virtualmachine.hxx"
48 #include "jvmaccess/unovirtualmachine.hxx"
49 
50 #include "vm.hxx"
51 
52 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
53 
54 
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::uno;
57 using ::rtl::OString;
58 using ::rtl::OUString;
59 
60 /*
61  * Class:     com_sun_star_comp_helper_SharedLibraryLoader
62  * Method:    component_writeInfo
63  * Signature: (Ljava/lang/String;Lcom/sun/star/lang/XMultiServiceFactory;Lcom/sun/star/registry/XRegistryKey;)Z
64  */
65 extern "C" JNIEXPORT jboolean JNICALL
66 Java_com_sun_star_comp_helper_SharedLibraryLoader_component_1writeInfo(
67     JNIEnv * pJEnv, jclass, jstring jLibName, jobject jSMgr,
68     jobject jRegKey, jobject loader )
69 {
70     sal_Bool bRet = sal_False;
71 
72     const jchar* pJLibName = pJEnv->GetStringChars( jLibName, NULL );
73     OUString aLibName( pJLibName );
74     pJEnv->ReleaseStringChars( jLibName, pJLibName);
75 
76     oslModule lib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
77     if (lib)
78     {
79         // ========================= LATEST VERSION =========================
80         OUString aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV) );
81         oslGenericFunction pSym =
82             osl_getFunctionSymbol( lib, aGetEnvName.pData );
83         if (pSym)
84         {
85             Environment java_env, loader_env;
86 
87             const sal_Char * pEnvTypeName = 0;
88             (*((component_getImplementationEnvironmentFunc)pSym))(
89                 &pEnvTypeName, (uno_Environment **)&loader_env );
90             if (! loader_env.is())
91             {
92                 OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) );
93                 uno_getEnvironment( (uno_Environment **)&loader_env, aEnvTypeName.pData, 0 );
94             }
95 
96             // create vm access
97             ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > vm_access(
98                 ::javaunohelper::create_vm_access( pJEnv, loader ) );
99             OUString java_env_name = OUSTR(UNO_LB_JAVA);
100             uno_getEnvironment(
101                 (uno_Environment **)&java_env, java_env_name.pData, vm_access.get() );
102 
103             OUString aWriteInfoName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_WRITEINFO) );
104             pSym = osl_getFunctionSymbol( lib, aWriteInfoName.pData );
105             if (pSym)
106             {
107                 if (loader_env.is() && java_env.is())
108                 {
109                     Mapping java2dest(java_env.get(), loader_env.get());
110 
111                     if ( java2dest.is() )
112                     {
113                         void * pSMgr =
114                             java2dest.mapInterface(
115                                 jSMgr, getCppuType((Reference< lang::XMultiServiceFactory > *) 0) );
116                         void * pKey =
117                             java2dest.mapInterface(
118                                 jRegKey, getCppuType((Reference< registry::XRegistryKey > *) 0) );
119 
120                         uno_ExtEnvironment * env = loader_env.get()->pExtEnv;
121                         if (pKey)
122                         {
123                             bRet = (*((component_writeInfoFunc)pSym))( pSMgr, pKey );
124 
125                             if (env)
126                                 (*env->releaseInterface)( env, pKey );
127                         }
128 
129                         if (pSMgr && env)
130                             (*env->releaseInterface)( env, pSMgr );
131                     }
132                 }
133             }
134         }
135     }
136 
137     return bRet == sal_False? JNI_FALSE : JNI_TRUE;
138 }
139 
140 /*
141  * Class:     com_sun_star_comp_helper_SharedLibraryLoader
142  * Method:    component_getFactory
143  * Signature: (Ljava/lang/String;Ljava/lang/String;Lcom/sun/star/lang/XMultiServiceFactory;Lcom/sun/star/registry/XRegistryKey;)Ljava/lang/Object;
144  */
145 extern "C" JNIEXPORT jobject JNICALL
146 Java_com_sun_star_comp_helper_SharedLibraryLoader_component_1getFactory(
147     JNIEnv * pJEnv, jclass, jstring jLibName, jstring jImplName,
148     jobject jSMgr, jobject jRegKey, jobject loader )
149 {
150     const jchar* pJLibName = pJEnv->GetStringChars(jLibName, NULL);
151     OUString aLibName( pJLibName );
152     pJEnv->ReleaseStringChars( jLibName, pJLibName);
153 
154     aLibName += OUString( RTL_CONSTASCII_USTRINGPARAM(SAL_DLLEXTENSION) );
155 
156     jobject joSLL_cpp = 0;
157 
158     oslModule lib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
159     if (lib)
160     {
161         // ========================= LATEST VERSION =========================
162         OUString aGetEnvName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETENV) );
163         oslGenericFunction pSym =
164             osl_getFunctionSymbol( lib, aGetEnvName.pData );
165         if (pSym)
166         {
167             Environment java_env, loader_env;
168 
169             const sal_Char * pEnvTypeName = 0;
170             (*((component_getImplementationEnvironmentFunc)pSym))(
171                 &pEnvTypeName, (uno_Environment **)&loader_env );
172 
173             if (! loader_env.is())
174             {
175                 OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) );
176                 uno_getEnvironment( (uno_Environment **)&loader_env, aEnvTypeName.pData, 0 );
177             }
178 
179             // create vm access
180             ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > vm_access(
181                 ::javaunohelper::create_vm_access( pJEnv, loader ) );
182             OUString java_env_name = OUSTR(UNO_LB_JAVA);
183             uno_getEnvironment(
184                 (uno_Environment **)&java_env, java_env_name.pData, vm_access.get() );
185 
186             OUString aGetFactoryName( RTL_CONSTASCII_USTRINGPARAM(COMPONENT_GETFACTORY) );
187             pSym = osl_getFunctionSymbol( lib, aGetFactoryName.pData );
188             if (pSym)
189             {
190                 if (loader_env.is() && java_env.is())
191                 {
192                     Mapping java2dest( java_env.get(), loader_env.get() );
193                     Mapping dest2java( loader_env.get(), java_env.get() );
194 
195                     if (dest2java.is() && java2dest.is())
196                     {
197                         void * pSMgr =
198                             java2dest.mapInterface(
199                                 jSMgr, ::getCppuType((Reference< lang::XMultiServiceFactory > *) 0) );
200                         void * pKey =
201                             java2dest.mapInterface(
202                                 jRegKey, ::getCppuType((Reference< registry::XRegistryKey > *) 0) );
203 
204                         const char* pImplName = pJEnv->GetStringUTFChars( jImplName, NULL );
205 
206                         void * pSSF = (*((component_getFactoryFunc)pSym))(
207                             pImplName, pSMgr, pKey );
208 
209                         pJEnv->ReleaseStringUTFChars( jImplName, pImplName );
210 
211                         uno_ExtEnvironment * env = loader_env.get()->pExtEnv;
212 
213                         if (pKey && env)
214                             (*env->releaseInterface)( env, pKey );
215                         if (pSMgr && env)
216                             (*env->releaseInterface)( env, pSMgr );
217 
218                         if (pSSF)
219                         {
220                             jobject jglobal = (jobject) dest2java.mapInterface(
221                                 pSSF, getCppuType((Reference< XInterface > *) 0) );
222                             joSLL_cpp = pJEnv->NewLocalRef( jglobal );
223                             pJEnv->DeleteGlobalRef( jglobal );
224                             if (env)
225                                 (*env->releaseInterface)( env, pSSF );
226                         }
227                     }
228                 }
229             }
230         }
231     }
232 
233     return joSLL_cpp;
234 }
235 
236 /*
237  * Class:     com_sun_star_comp_helper_RegistryServiceFactory
238  * Method:    createRegistryServiceFactory
239  * Signature: (Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/Object;
240  */
241 extern "C" JNIEXPORT jobject JNICALL
242 Java_com_sun_star_comp_helper_RegistryServiceFactory_createRegistryServiceFactory(
243     JNIEnv * pJEnv, jclass, jstring jWriteRegFile,
244     jstring jReadRegFile, jboolean jbReadOnly, jobject loader )
245 {
246     jobject joRegServiceFac = 0;
247 
248     try
249     {
250         OUString aWriteRegFile;
251         OUString aReadRegFile;
252 
253         sal_Bool bReadOnly = jbReadOnly == JNI_FALSE ? sal_False : sal_True;
254 
255         if (jReadRegFile) {
256             const jchar* pjReadRegFile = pJEnv->GetStringChars(jReadRegFile, NULL);
257             aReadRegFile = OUString(pjReadRegFile);
258             pJEnv->ReleaseStringChars(jReadRegFile, pjReadRegFile);
259         }
260 
261         if (jWriteRegFile) {
262             const jchar * pjWriteRegFile = pJEnv->GetStringChars(jWriteRegFile, NULL);
263             aWriteRegFile = OUString(pjWriteRegFile);
264             pJEnv->ReleaseStringChars(jWriteRegFile, pjWriteRegFile);
265         }
266 
267         // bootstrap
268         Reference< lang::XMultiServiceFactory > rMSFac;
269         if (aReadRegFile.getLength() == 0)
270             rMSFac = ::cppu::createRegistryServiceFactory( aWriteRegFile, bReadOnly);
271         else
272             rMSFac = ::cppu::createRegistryServiceFactory(aWriteRegFile, aReadRegFile, bReadOnly);
273 
274         Reference< beans::XPropertySet > xProps(
275             rMSFac, UNO_QUERY_THROW );
276         Reference< XComponentContext > xContext(
277             xProps->getPropertyValue( OUSTR("DefaultContext") ), UNO_QUERY_THROW );
278 
279         // create vm access
280         ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > vm_access(
281             ::javaunohelper::create_vm_access( pJEnv, loader ) );
282         // wrap vm singleton entry
283         xContext = ::javaunohelper::install_vm_singleton( xContext, vm_access );
284         rMSFac.set( xContext->getServiceManager(), UNO_QUERY_THROW );
285 
286         // get uno envs
287         OUString aCurrentEnv(RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME));
288         OUString java_env_name = OUSTR(UNO_LB_JAVA);
289         Environment java_env, curr_env;
290         uno_getEnvironment((uno_Environment **)&curr_env, aCurrentEnv.pData, NULL);
291         uno_getEnvironment( (uno_Environment **)&java_env, java_env_name.pData, vm_access.get() );
292 
293         Mapping curr_java(curr_env.get(), java_env.get());
294         if (! curr_java.is())
295         {
296             throw RuntimeException(
297                 OUSTR("no C++ <-> Java mapping available!"), Reference< XInterface >() );
298         }
299 
300         jobject joGlobalRegServiceFac =
301             (jobject)curr_java.mapInterface(
302                 rMSFac.get(),
303                 getCppuType((Reference< lang::XMultiServiceFactory > *)0) );
304         joRegServiceFac = pJEnv->NewLocalRef( joGlobalRegServiceFac );
305         pJEnv->DeleteGlobalRef(joGlobalRegServiceFac);
306     }
307     catch (Exception & exc)
308     {
309         jclass c = pJEnv->FindClass( "com/sun/star/uno/RuntimeException" );
310         if (0 != c)
311         {
312             OString cstr( ::rtl::OUStringToOString(
313                               exc.Message, RTL_TEXTENCODING_JAVA_UTF8 ) );
314             OSL_TRACE( __FILE__": forwarding Exception: %s", cstr.getStr() );
315             pJEnv->ThrowNew( c, cstr.getStr() );
316         }
317         return 0;
318     }
319 
320     OSL_TRACE("javaunohelper.cxx: object %i", joRegServiceFac);
321 
322     return joRegServiceFac;
323 }
324