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_javaunohelper.hxx"
26
27 #include "osl/diagnose.h"
28
29 #include "rtl/alloc.h"
30 #include "rtl/bootstrap.hxx"
31 #include "rtl/string.hxx"
32
33 #include "uno/mapping.hxx"
34 #include "uno/environment.hxx"
35
36 #include "cppuhelper/bootstrap.hxx"
37
38 #include "com/sun/star/lang/XComponent.hpp"
39 #include "com/sun/star/lang/XSingleComponentFactory.hpp"
40
41 #include "jni.h"
42 #include "jvmaccess/virtualmachine.hxx"
43 #include "jvmaccess/unovirtualmachine.hxx"
44
45 #include "vm.hxx"
46
47 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
48
49
50 using namespace ::com::sun::star;
51 using namespace ::com::sun::star::uno;
52 using ::rtl::OString;
53 using ::rtl::OUString;
54
55 namespace javaunohelper
56 {
57
jstring_to_oustring(jstring jstr,JNIEnv * jni_env)58 inline ::rtl::OUString jstring_to_oustring( jstring jstr, JNIEnv * jni_env )
59 {
60 OSL_ASSERT( sizeof (sal_Unicode) == sizeof (jchar) );
61 jsize len = jni_env->GetStringLength( jstr );
62 rtl_uString * ustr =
63 (rtl_uString *)rtl_allocateMemory( sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) );
64 jni_env->GetStringRegion( jstr, 0, len, ustr->buffer );
65 OSL_ASSERT( JNI_FALSE == jni_env->ExceptionCheck() );
66 ustr->refCount = 1;
67 ustr->length = len;
68 ustr->buffer[ len ] = '\0';
69 return ::rtl::OUString( ustr, SAL_NO_ACQUIRE );
70 }
71
72 }
73
74 //==================================================================================================
Java_com_sun_star_comp_helper_Bootstrap_cppuhelper_1bootstrap(JNIEnv * jni_env,jclass,jstring juno_rc,jobjectArray jpairs,jobject loader)75 extern "C" JNIEXPORT jobject JNICALL Java_com_sun_star_comp_helper_Bootstrap_cppuhelper_1bootstrap(
76 JNIEnv * jni_env, jclass, jstring juno_rc, jobjectArray jpairs,
77 jobject loader )
78 {
79 try
80 {
81 if (0 != jpairs)
82 {
83 jsize nPos = 0, len = jni_env->GetArrayLength( jpairs );
84 while (nPos < len)
85 {
86 // name
87 jstring jstr = (jstring)jni_env->GetObjectArrayElement( jpairs, nPos );
88 if (JNI_FALSE != jni_env->ExceptionCheck())
89 {
90 jni_env->ExceptionClear();
91 throw RuntimeException(
92 OUSTR("index out of bounds?!"), Reference< XInterface >() );
93 }
94 if (0 != jstr)
95 {
96 OUString name( ::javaunohelper::jstring_to_oustring( jstr, jni_env ) );
97 // value
98 jstr = (jstring)jni_env->GetObjectArrayElement( jpairs, nPos +1 );
99 if (JNI_FALSE != jni_env->ExceptionCheck())
100 {
101 jni_env->ExceptionClear();
102 throw RuntimeException(
103 OUSTR("index out of bounds?!"), Reference< XInterface >() );
104 }
105 if (0 != jstr)
106 {
107 OUString value( ::javaunohelper::jstring_to_oustring( jstr, jni_env ) );
108
109 // set bootstrap parameter
110 ::rtl::Bootstrap::set( name, value );
111 }
112 }
113 nPos += 2;
114 }
115 }
116
117 // bootstrap uno
118 Reference< XComponentContext > xContext;
119 if (0 == juno_rc)
120 {
121 xContext = ::cppu::defaultBootstrap_InitialComponentContext();
122 }
123 else
124 {
125 OUString uno_rc( ::javaunohelper::jstring_to_oustring( juno_rc, jni_env ) );
126 xContext = ::cppu::defaultBootstrap_InitialComponentContext( uno_rc );
127 }
128
129 // create vm access
130 ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > vm_access(
131 ::javaunohelper::create_vm_access( jni_env, loader ) );
132 // wrap vm singleton entry
133 xContext = ::javaunohelper::install_vm_singleton( xContext, vm_access );
134
135 // get uno envs
136 OUString cpp_env_name = OUSTR(CPPU_CURRENT_LANGUAGE_BINDING_NAME);
137 OUString java_env_name = OUSTR(UNO_LB_JAVA);
138 Environment java_env, cpp_env;
139 uno_getEnvironment((uno_Environment **)&cpp_env, cpp_env_name.pData, NULL);
140 uno_getEnvironment( (uno_Environment **)&java_env, java_env_name.pData, vm_access.get() );
141
142 // map to java
143 Mapping mapping( cpp_env.get(), java_env.get() );
144 if (! mapping.is())
145 {
146 Reference< lang::XComponent > xComp( xContext, UNO_QUERY );
147 if (xComp.is())
148 xComp->dispose();
149 throw RuntimeException(
150 OUSTR("cannot get mapping C++ <-> Java!"),
151 Reference< XInterface >() );
152 }
153
154 jobject jret = (jobject)mapping.mapInterface( xContext.get(), ::getCppuType( &xContext ) );
155 jobject jlocal = jni_env->NewLocalRef( jret );
156 jni_env->DeleteGlobalRef( jret );
157
158 return jlocal;
159 }
160 catch (RuntimeException & exc)
161 {
162 jclass c = jni_env->FindClass( "com/sun/star/uno/RuntimeException" );
163 if (0 != c)
164 {
165 OString cstr( ::rtl::OUStringToOString(
166 exc.Message, RTL_TEXTENCODING_JAVA_UTF8 ) );
167 OSL_TRACE( __FILE__": forwarding RuntimeException: %s", cstr.getStr() );
168 jni_env->ThrowNew( c, cstr.getStr() );
169 }
170 }
171 catch (Exception & exc)
172 {
173 jclass c = jni_env->FindClass( "com/sun/star/uno/Exception" );
174 if (0 != c)
175 {
176 OString cstr( ::rtl::OUStringToOString(
177 exc.Message, RTL_TEXTENCODING_JAVA_UTF8 ) );
178 OSL_TRACE( __FILE__": forwarding Exception: %s", cstr.getStr() );
179 jni_env->ThrowNew( c, cstr.getStr() );
180 }
181 }
182
183 return 0;
184 }
185
186