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 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 //================================================================================================== 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