1*61dff127SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*61dff127SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*61dff127SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*61dff127SAndrew Rist * distributed with this work for additional information 6*61dff127SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*61dff127SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*61dff127SAndrew Rist * "License"); you may not use this file except in compliance 9*61dff127SAndrew Rist * with the License. You may obtain a copy of the License at 10*61dff127SAndrew Rist * 11*61dff127SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*61dff127SAndrew Rist * 13*61dff127SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*61dff127SAndrew Rist * software distributed under the License is distributed on an 15*61dff127SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*61dff127SAndrew Rist * KIND, either express or implied. See the License for the 17*61dff127SAndrew Rist * specific language governing permissions and limitations 18*61dff127SAndrew Rist * under the License. 19*61dff127SAndrew Rist * 20*61dff127SAndrew Rist *************************************************************/ 21*61dff127SAndrew Rist 22*61dff127SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_bridges.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <sal/alloca.h> 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include "jni_bridge.h" 30cdf0e10cSrcweir //#include "jni_finalizer.h" 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 33cdf0e10cSrcweir 34cdf0e10cSrcweir #include <algorithm> 35cdf0e10cSrcweir 36cdf0e10cSrcweir 37cdf0e10cSrcweir using namespace ::rtl; 38cdf0e10cSrcweir 39cdf0e10cSrcweir namespace jni_uno 40cdf0e10cSrcweir { 41cdf0e10cSrcweir 42cdf0e10cSrcweir //______________________________________________________________________________ 43cdf0e10cSrcweir jobject Bridge::map_to_java( 44cdf0e10cSrcweir JNI_context const & jni, 45cdf0e10cSrcweir uno_Interface * pUnoI, JNI_interface_type_info const * info ) const 46cdf0e10cSrcweir { 47cdf0e10cSrcweir // get oid 48cdf0e10cSrcweir rtl_uString * pOid = 0; 49cdf0e10cSrcweir (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI ); 50cdf0e10cSrcweir OSL_ASSERT( 0 != pOid ); 51cdf0e10cSrcweir OUString oid( pOid, SAL_NO_ACQUIRE ); 52cdf0e10cSrcweir 53cdf0e10cSrcweir // opt getRegisteredInterface() 54cdf0e10cSrcweir JLocalAutoRef jo_oid( jni, ustring_to_jstring( jni, oid.pData ) ); 55cdf0e10cSrcweir jvalue args[ 2 ]; 56cdf0e10cSrcweir args[ 0 ].l = jo_oid.get(); 57cdf0e10cSrcweir args[ 1 ].l = info->m_type; 58cdf0e10cSrcweir jobject jo_iface = jni->CallObjectMethodA( 59cdf0e10cSrcweir m_jni_info->m_object_java_env, 60cdf0e10cSrcweir m_jni_info->m_method_IEnvironment_getRegisteredInterface, args ); 61cdf0e10cSrcweir jni.ensure_no_exception(); 62cdf0e10cSrcweir 63cdf0e10cSrcweir if (0 == jo_iface) // no registered iface 64cdf0e10cSrcweir { 65cdf0e10cSrcweir // register uno interface 66cdf0e10cSrcweir (*m_uno_env->registerInterface)( 67cdf0e10cSrcweir m_uno_env, reinterpret_cast< void ** >( &pUnoI ), 68cdf0e10cSrcweir oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() ); 69cdf0e10cSrcweir 70cdf0e10cSrcweir // create java and register java proxy 71cdf0e10cSrcweir jvalue args2[ 7 ]; 72cdf0e10cSrcweir acquire(); 73cdf0e10cSrcweir args2[ 0 ].j = reinterpret_cast< sal_Int64 >( this ); 74cdf0e10cSrcweir (*pUnoI->acquire)( pUnoI ); 75cdf0e10cSrcweir args2[ 1 ].l = m_jni_info->m_object_java_env; 76cdf0e10cSrcweir args2[ 2 ].j = reinterpret_cast< sal_Int64 >( pUnoI ); 77cdf0e10cSrcweir typelib_typedescription_acquire( info->m_td.get() ); 78cdf0e10cSrcweir args2[ 3 ].j = reinterpret_cast< sal_Int64 >( info->m_td.get() ); 79cdf0e10cSrcweir args2[ 4 ].l = info->m_type; 80cdf0e10cSrcweir args2[ 5 ].l = jo_oid.get(); 81cdf0e10cSrcweir args2[ 6 ].l = info->m_proxy_ctor; 82cdf0e10cSrcweir jo_iface = jni->CallStaticObjectMethodA( 83cdf0e10cSrcweir m_jni_info->m_class_JNI_proxy, 84cdf0e10cSrcweir m_jni_info->m_method_JNI_proxy_create, args2 ); 85cdf0e10cSrcweir jni.ensure_no_exception(); 86cdf0e10cSrcweir } 87cdf0e10cSrcweir 88cdf0e10cSrcweir OSL_ASSERT( 0 != jo_iface ); 89cdf0e10cSrcweir return jo_iface; 90cdf0e10cSrcweir } 91cdf0e10cSrcweir 92cdf0e10cSrcweir 93cdf0e10cSrcweir //______________________________________________________________________________ 94cdf0e10cSrcweir void Bridge::handle_uno_exc( JNI_context const & jni, uno_Any * uno_exc ) const 95cdf0e10cSrcweir { 96cdf0e10cSrcweir if (typelib_TypeClass_EXCEPTION == uno_exc->pType->eTypeClass) 97cdf0e10cSrcweir { 98cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 99cdf0e10cSrcweir // append java stack trace to Message member 100cdf0e10cSrcweir reinterpret_cast< ::com::sun::star::uno::Exception * >( 101cdf0e10cSrcweir uno_exc->pData )->Message += jni.get_stack_trace(); 102cdf0e10cSrcweir #endif 103cdf0e10cSrcweir 104cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 105cdf0e10cSrcweir { 106cdf0e10cSrcweir OUStringBuffer buf( 128 ); 107cdf0e10cSrcweir buf.appendAscii( 108cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("exception occured java->uno: [") ); 109cdf0e10cSrcweir buf.append( OUString::unacquired( &uno_exc->pType->pTypeName ) ); 110cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); 111cdf0e10cSrcweir buf.append( 112cdf0e10cSrcweir reinterpret_cast< ::com::sun::star::uno::Exception const * >( 113cdf0e10cSrcweir uno_exc->pData )->Message ); 114cdf0e10cSrcweir OString cstr_msg( 115cdf0e10cSrcweir OUStringToOString( 116cdf0e10cSrcweir buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); 117cdf0e10cSrcweir OSL_TRACE( cstr_msg.getStr() ); 118cdf0e10cSrcweir } 119cdf0e10cSrcweir #endif 120cdf0e10cSrcweir // signal exception 121cdf0e10cSrcweir jvalue java_exc; 122cdf0e10cSrcweir try 123cdf0e10cSrcweir { 124cdf0e10cSrcweir map_to_java( 125cdf0e10cSrcweir jni, &java_exc, uno_exc->pData, uno_exc->pType, 0, 126cdf0e10cSrcweir true /* in */, false /* no out */ ); 127cdf0e10cSrcweir } 128cdf0e10cSrcweir catch (...) 129cdf0e10cSrcweir { 130cdf0e10cSrcweir uno_any_destruct( uno_exc, 0 ); 131cdf0e10cSrcweir throw; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir uno_any_destruct( uno_exc, 0 ); 134cdf0e10cSrcweir 135cdf0e10cSrcweir JLocalAutoRef jo_exc( jni, java_exc.l ); 136cdf0e10cSrcweir jint res = jni->Throw( (jthrowable) jo_exc.get() ); 137cdf0e10cSrcweir if (0 != res) 138cdf0e10cSrcweir { 139cdf0e10cSrcweir // call toString() 140cdf0e10cSrcweir JLocalAutoRef jo_descr( 141cdf0e10cSrcweir jni, jni->CallObjectMethodA( 142cdf0e10cSrcweir jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) ); 143cdf0e10cSrcweir jni.ensure_no_exception(); 144cdf0e10cSrcweir OUStringBuffer buf( 128 ); 145cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( 146cdf0e10cSrcweir "throwing java exception failed: ") ); 147cdf0e10cSrcweir buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) ); 148cdf0e10cSrcweir buf.append( jni.get_stack_trace() ); 149cdf0e10cSrcweir throw BridgeRuntimeError( buf.makeStringAndClear() ); 150cdf0e10cSrcweir } 151cdf0e10cSrcweir } 152cdf0e10cSrcweir else 153cdf0e10cSrcweir { 154cdf0e10cSrcweir OUString message( 155cdf0e10cSrcweir OUSTR("thrown exception is no uno exception: ") + 156cdf0e10cSrcweir OUString::unacquired( &uno_exc->pType->pTypeName ) + 157cdf0e10cSrcweir jni.get_stack_trace() ); 158cdf0e10cSrcweir uno_any_destruct( uno_exc, 0 ); 159cdf0e10cSrcweir throw BridgeRuntimeError( message ); 160cdf0e10cSrcweir } 161cdf0e10cSrcweir } 162cdf0e10cSrcweir 163cdf0e10cSrcweir union largest 164cdf0e10cSrcweir { 165cdf0e10cSrcweir sal_Int64 n; 166cdf0e10cSrcweir double d; 167cdf0e10cSrcweir void * p; 168cdf0e10cSrcweir uno_Any a; 169cdf0e10cSrcweir }; 170cdf0e10cSrcweir 171cdf0e10cSrcweir //______________________________________________________________________________ 172cdf0e10cSrcweir jobject Bridge::call_uno( 173cdf0e10cSrcweir JNI_context const & jni, 174cdf0e10cSrcweir uno_Interface * pUnoI, typelib_TypeDescription * member_td, 175cdf0e10cSrcweir typelib_TypeDescriptionReference * return_type, 176cdf0e10cSrcweir sal_Int32 nParams, typelib_MethodParameter const * pParams, 177cdf0e10cSrcweir jobjectArray jo_args /* may be 0 */ ) const 178cdf0e10cSrcweir { 179cdf0e10cSrcweir // return mem 180cdf0e10cSrcweir sal_Int32 return_size; 181cdf0e10cSrcweir switch (return_type->eTypeClass) { 182cdf0e10cSrcweir case typelib_TypeClass_VOID: 183cdf0e10cSrcweir return_size = 0; 184cdf0e10cSrcweir break; 185cdf0e10cSrcweir 186cdf0e10cSrcweir case typelib_TypeClass_STRUCT: 187cdf0e10cSrcweir case typelib_TypeClass_EXCEPTION: 188cdf0e10cSrcweir return_size = std::max( 189cdf0e10cSrcweir TypeDescr(return_type).get()->nSize, 190cdf0e10cSrcweir static_cast< sal_Int32 >(sizeof (largest))); 191cdf0e10cSrcweir break; 192cdf0e10cSrcweir 193cdf0e10cSrcweir default: 194cdf0e10cSrcweir return_size = sizeof (largest); 195cdf0e10cSrcweir break; 196cdf0e10cSrcweir } 197cdf0e10cSrcweir 198cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 199cdf0e10cSrcweir char * mem = (char *) malloc( 200cdf0e10cSrcweir #else 201cdf0e10cSrcweir char * mem = (char *) alloca( 202cdf0e10cSrcweir #endif 203cdf0e10cSrcweir (nParams * sizeof (void *)) + 204cdf0e10cSrcweir return_size + (nParams * sizeof (largest)) ); 205cdf0e10cSrcweir void ** uno_args = (void **) mem; 206cdf0e10cSrcweir void * uno_ret = return_size == 0 ? 0 : (mem + (nParams * sizeof (void *))); 207cdf0e10cSrcweir largest * uno_args_mem = (largest *) 208cdf0e10cSrcweir (mem + (nParams * sizeof (void *)) + return_size); 209cdf0e10cSrcweir 210cdf0e10cSrcweir OSL_ASSERT( (0 == nParams) || (nParams == jni->GetArrayLength( jo_args )) ); 211cdf0e10cSrcweir for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 212cdf0e10cSrcweir { 213cdf0e10cSrcweir typelib_MethodParameter const & param = pParams[ nPos ]; 214cdf0e10cSrcweir typelib_TypeDescriptionReference * type = param.pTypeRef; 215cdf0e10cSrcweir 216cdf0e10cSrcweir uno_args[ nPos ] = &uno_args_mem[ nPos ]; 217cdf0e10cSrcweir if (typelib_TypeClass_STRUCT == type->eTypeClass || 218cdf0e10cSrcweir typelib_TypeClass_EXCEPTION == type->eTypeClass) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir TypeDescr td( type ); 221cdf0e10cSrcweir if (sal::static_int_cast< sal_uInt32 >(td.get()->nSize) 222cdf0e10cSrcweir > sizeof (largest)) 223cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 224cdf0e10cSrcweir uno_args[ nPos ] = malloc( td.get()->nSize ); 225cdf0e10cSrcweir #else 226cdf0e10cSrcweir uno_args[ nPos ] = alloca( td.get()->nSize ); 227cdf0e10cSrcweir #endif 228cdf0e10cSrcweir } 229cdf0e10cSrcweir 230cdf0e10cSrcweir if (param.bIn) 231cdf0e10cSrcweir { 232cdf0e10cSrcweir try 233cdf0e10cSrcweir { 234cdf0e10cSrcweir JLocalAutoRef jo_arg( 235cdf0e10cSrcweir jni, jni->GetObjectArrayElement( jo_args, nPos ) ); 236cdf0e10cSrcweir jni.ensure_no_exception(); 237cdf0e10cSrcweir jvalue java_arg; 238cdf0e10cSrcweir java_arg.l = jo_arg.get(); 239cdf0e10cSrcweir map_to_uno( 240cdf0e10cSrcweir jni, uno_args[ nPos ], java_arg, type, 0, 241cdf0e10cSrcweir false /* no assign */, sal_False != param.bOut, 242cdf0e10cSrcweir true /* special wrapped integral types */ ); 243cdf0e10cSrcweir } 244cdf0e10cSrcweir catch (...) 245cdf0e10cSrcweir { 246cdf0e10cSrcweir // cleanup uno in args 247cdf0e10cSrcweir for ( sal_Int32 n = 0; n < nPos; ++n ) 248cdf0e10cSrcweir { 249cdf0e10cSrcweir typelib_MethodParameter const & p = pParams[ n ]; 250cdf0e10cSrcweir if (p.bIn) 251cdf0e10cSrcweir { 252cdf0e10cSrcweir uno_type_destructData( 253cdf0e10cSrcweir uno_args[ n ], p.pTypeRef, 0 ); 254cdf0e10cSrcweir } 255cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 256cdf0e10cSrcweir if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ]) 257cdf0e10cSrcweir free( uno_args[ nPos ] ); 258cdf0e10cSrcweir #endif 259cdf0e10cSrcweir } 260cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 261cdf0e10cSrcweir free( mem ); 262cdf0e10cSrcweir #endif 263cdf0e10cSrcweir throw; 264cdf0e10cSrcweir } 265cdf0e10cSrcweir } 266cdf0e10cSrcweir } 267cdf0e10cSrcweir 268cdf0e10cSrcweir uno_Any uno_exc_holder; 269cdf0e10cSrcweir uno_Any * uno_exc = &uno_exc_holder; 270cdf0e10cSrcweir // call binary uno 271cdf0e10cSrcweir (*pUnoI->pDispatcher)( pUnoI, member_td, uno_ret, uno_args, &uno_exc ); 272cdf0e10cSrcweir 273cdf0e10cSrcweir if (0 == uno_exc) 274cdf0e10cSrcweir { 275cdf0e10cSrcweir // convert out args; destruct uno args 276cdf0e10cSrcweir for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 277cdf0e10cSrcweir { 278cdf0e10cSrcweir typelib_MethodParameter const & param = pParams[ nPos ]; 279cdf0e10cSrcweir typelib_TypeDescriptionReference * type = param.pTypeRef; 280cdf0e10cSrcweir if (param.bOut) 281cdf0e10cSrcweir { 282cdf0e10cSrcweir try 283cdf0e10cSrcweir { 284cdf0e10cSrcweir // get out holder array[ 1 ] 285cdf0e10cSrcweir JLocalAutoRef jo_out_holder( 286cdf0e10cSrcweir jni, jni->GetObjectArrayElement( jo_args, nPos ) ); 287cdf0e10cSrcweir jni.ensure_no_exception(); 288cdf0e10cSrcweir jvalue java_arg; 289cdf0e10cSrcweir java_arg.l = jo_out_holder.get(); 290cdf0e10cSrcweir map_to_java( 291cdf0e10cSrcweir jni, &java_arg, uno_args[ nPos ], type, 0, 292cdf0e10cSrcweir true /* in */, true /* out holder */ ); 293cdf0e10cSrcweir } 294cdf0e10cSrcweir catch (...) 295cdf0e10cSrcweir { 296cdf0e10cSrcweir // cleanup further uno args 297cdf0e10cSrcweir for ( sal_Int32 n = nPos; n < nParams; ++n ) 298cdf0e10cSrcweir { 299cdf0e10cSrcweir uno_type_destructData( 300cdf0e10cSrcweir uno_args[ n ], pParams[ n ].pTypeRef, 0 ); 301cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 302cdf0e10cSrcweir if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ]) 303cdf0e10cSrcweir free( uno_args[ nPos ] ); 304cdf0e10cSrcweir #endif 305cdf0e10cSrcweir } 306cdf0e10cSrcweir // cleanup uno return value 307cdf0e10cSrcweir uno_type_destructData( uno_ret, return_type, 0 ); 308cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 309cdf0e10cSrcweir free( mem ); 310cdf0e10cSrcweir #endif 311cdf0e10cSrcweir throw; 312cdf0e10cSrcweir } 313cdf0e10cSrcweir } 314cdf0e10cSrcweir if (typelib_TypeClass_DOUBLE < type->eTypeClass && 315cdf0e10cSrcweir typelib_TypeClass_ENUM != type->eTypeClass) // opt 316cdf0e10cSrcweir { 317cdf0e10cSrcweir uno_type_destructData( uno_args[ nPos ], type, 0 ); 318cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 319cdf0e10cSrcweir if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ]) 320cdf0e10cSrcweir free( uno_args[ nPos ] ); 321cdf0e10cSrcweir #endif 322cdf0e10cSrcweir } 323cdf0e10cSrcweir } 324cdf0e10cSrcweir 325cdf0e10cSrcweir if (typelib_TypeClass_VOID != return_type->eTypeClass) 326cdf0e10cSrcweir { 327cdf0e10cSrcweir // convert uno return value 328cdf0e10cSrcweir jvalue java_ret; 329cdf0e10cSrcweir try 330cdf0e10cSrcweir { 331cdf0e10cSrcweir map_to_java( 332cdf0e10cSrcweir jni, &java_ret, uno_ret, return_type, 0, 333cdf0e10cSrcweir true /* in */, false /* no out */, 334cdf0e10cSrcweir true /* special_wrapped_integral_types */ ); 335cdf0e10cSrcweir } 336cdf0e10cSrcweir catch (...) 337cdf0e10cSrcweir { 338cdf0e10cSrcweir uno_type_destructData( uno_ret, return_type, 0 ); 339cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 340cdf0e10cSrcweir free( mem ); 341cdf0e10cSrcweir #endif 342cdf0e10cSrcweir throw; 343cdf0e10cSrcweir } 344cdf0e10cSrcweir if (typelib_TypeClass_DOUBLE < return_type->eTypeClass && 345cdf0e10cSrcweir typelib_TypeClass_ENUM != return_type->eTypeClass) // opt 346cdf0e10cSrcweir { 347cdf0e10cSrcweir uno_type_destructData( uno_ret, return_type, 0 ); 348cdf0e10cSrcweir } 349cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 350cdf0e10cSrcweir free( mem ); 351cdf0e10cSrcweir #endif 352cdf0e10cSrcweir return java_ret.l; 353cdf0e10cSrcweir } 354cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 355cdf0e10cSrcweir free( mem ); 356cdf0e10cSrcweir #endif 357cdf0e10cSrcweir return 0; // void return 358cdf0e10cSrcweir } 359cdf0e10cSrcweir else // exception occured 360cdf0e10cSrcweir { 361cdf0e10cSrcweir // destruct uno in args 362cdf0e10cSrcweir for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 363cdf0e10cSrcweir { 364cdf0e10cSrcweir typelib_MethodParameter const & param = pParams[ nPos ]; 365cdf0e10cSrcweir if (param.bIn) 366cdf0e10cSrcweir uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 ); 367cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 368cdf0e10cSrcweir if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ]) 369cdf0e10cSrcweir free( uno_args[ nPos ] ); 370cdf0e10cSrcweir #endif 371cdf0e10cSrcweir } 372cdf0e10cSrcweir 373cdf0e10cSrcweir handle_uno_exc( jni, uno_exc ); 374cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 375cdf0e10cSrcweir free( mem ); 376cdf0e10cSrcweir #endif 377cdf0e10cSrcweir return 0; 378cdf0e10cSrcweir } 379cdf0e10cSrcweir } 380cdf0e10cSrcweir 381cdf0e10cSrcweir } 382cdf0e10cSrcweir 383cdf0e10cSrcweir using namespace ::jni_uno; 384cdf0e10cSrcweir 385cdf0e10cSrcweir extern "C" 386cdf0e10cSrcweir { 387cdf0e10cSrcweir 388cdf0e10cSrcweir //------------------------------------------------------------------------------ 389cdf0e10cSrcweir JNIEXPORT jobject 390cdf0e10cSrcweir JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call( 391cdf0e10cSrcweir JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle, jstring, 392cdf0e10cSrcweir jstring jo_method, jobjectArray jo_args /* may be 0 */ ) 393cdf0e10cSrcweir SAL_THROW_EXTERN_C() 394cdf0e10cSrcweir { 395cdf0e10cSrcweir Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle ); 396cdf0e10cSrcweir JNI_info const * jni_info = bridge->m_jni_info; 397cdf0e10cSrcweir JNI_context jni( 398cdf0e10cSrcweir jni_info, jni_env, 399cdf0e10cSrcweir static_cast< jobject >( 400cdf0e10cSrcweir reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >( 401cdf0e10cSrcweir bridge->m_java_env->pContext )->getClassLoader() ) ); 402cdf0e10cSrcweir 403cdf0e10cSrcweir OUString method_name; 404cdf0e10cSrcweir 405cdf0e10cSrcweir try 406cdf0e10cSrcweir { 407cdf0e10cSrcweir method_name = jstring_to_oustring( jni, jo_method ); 408cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 409cdf0e10cSrcweir { 410cdf0e10cSrcweir OUStringBuffer trace_buf( 64 ); 411cdf0e10cSrcweir trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("java->uno call: ") ); 412cdf0e10cSrcweir trace_buf.append( method_name ); 413cdf0e10cSrcweir trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") ); 414cdf0e10cSrcweir JLocalAutoRef jo_oid( 415cdf0e10cSrcweir jni, jni->GetObjectField( 416cdf0e10cSrcweir jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) ); 417cdf0e10cSrcweir trace_buf.append( jstring_to_oustring( jni, (jstring) jo_oid.get() ) ); 418cdf0e10cSrcweir OString cstr_msg( 419cdf0e10cSrcweir OUStringToOString( 420cdf0e10cSrcweir trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); 421cdf0e10cSrcweir OSL_TRACE( cstr_msg.getStr() ); 422cdf0e10cSrcweir } 423cdf0e10cSrcweir #endif 424cdf0e10cSrcweir 425cdf0e10cSrcweir // special IQueryInterface.queryInterface() 426cdf0e10cSrcweir if (method_name.equalsAsciiL( 427cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("queryInterface") )) 428cdf0e10cSrcweir { 429cdf0e10cSrcweir // oid 430cdf0e10cSrcweir JLocalAutoRef jo_oid( 431cdf0e10cSrcweir jni, jni->GetObjectField( 432cdf0e10cSrcweir jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) ); 433cdf0e10cSrcweir // type 434cdf0e10cSrcweir JLocalAutoRef jo_type( 435cdf0e10cSrcweir jni, jni->GetObjectArrayElement( jo_args, 0 ) ); 436cdf0e10cSrcweir jni.ensure_no_exception(); 437cdf0e10cSrcweir 438cdf0e10cSrcweir JLocalAutoRef jo_type_name( 439cdf0e10cSrcweir jni, jni->GetObjectField( 440cdf0e10cSrcweir jo_type.get(), jni_info->m_field_Type__typeName ) ); 441cdf0e10cSrcweir if (! jo_type_name.is()) 442cdf0e10cSrcweir { 443cdf0e10cSrcweir throw BridgeRuntimeError( 444cdf0e10cSrcweir OUSTR("incomplete type object: no type name!") + 445cdf0e10cSrcweir jni.get_stack_trace() ); 446cdf0e10cSrcweir } 447cdf0e10cSrcweir OUString type_name( 448cdf0e10cSrcweir jstring_to_oustring( jni, (jstring) jo_type_name.get() ) ); 449cdf0e10cSrcweir JNI_type_info const * info = 450cdf0e10cSrcweir jni_info->get_type_info( jni, type_name ); 451cdf0e10cSrcweir if (typelib_TypeClass_INTERFACE != info->m_td.get()->eTypeClass) 452cdf0e10cSrcweir { 453cdf0e10cSrcweir throw BridgeRuntimeError( 454cdf0e10cSrcweir OUSTR("queryInterface() call demands an INTERFACE type!") ); 455cdf0e10cSrcweir } 456cdf0e10cSrcweir JNI_interface_type_info const * iface_info = 457cdf0e10cSrcweir static_cast< JNI_interface_type_info const * >( info ); 458cdf0e10cSrcweir 459cdf0e10cSrcweir // getRegisteredInterface() already tested in JNI_proxy: 460cdf0e10cSrcweir // perform queryInterface call on binary uno interface 461cdf0e10cSrcweir uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >( 462cdf0e10cSrcweir jni->GetLongField( 463cdf0e10cSrcweir jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) ); 464cdf0e10cSrcweir 465cdf0e10cSrcweir uno_Any uno_ret; 466cdf0e10cSrcweir void * uno_args[] = { &iface_info->m_td.get()->pWeakRef }; 467cdf0e10cSrcweir uno_Any uno_exc_holder; 468cdf0e10cSrcweir uno_Any * uno_exc = &uno_exc_holder; 469cdf0e10cSrcweir // call binary uno 470cdf0e10cSrcweir (*pUnoI->pDispatcher)( 471cdf0e10cSrcweir pUnoI, jni_info->m_XInterface_queryInterface_td.get(), 472cdf0e10cSrcweir &uno_ret, uno_args, &uno_exc ); 473cdf0e10cSrcweir if (0 == uno_exc) 474cdf0e10cSrcweir { 475cdf0e10cSrcweir jobject jo_ret = 0; 476cdf0e10cSrcweir if (typelib_TypeClass_INTERFACE == uno_ret.pType->eTypeClass) 477cdf0e10cSrcweir { 478cdf0e10cSrcweir uno_Interface * pUnoRet = 479cdf0e10cSrcweir (uno_Interface *) uno_ret.pReserved; 480cdf0e10cSrcweir if (0 != pUnoRet) 481cdf0e10cSrcweir { 482cdf0e10cSrcweir try 483cdf0e10cSrcweir { 484cdf0e10cSrcweir jo_ret = 485cdf0e10cSrcweir bridge->map_to_java( jni, pUnoRet, iface_info ); 486cdf0e10cSrcweir } 487cdf0e10cSrcweir catch (...) 488cdf0e10cSrcweir { 489cdf0e10cSrcweir uno_any_destruct( &uno_ret, 0 ); 490cdf0e10cSrcweir throw; 491cdf0e10cSrcweir } 492cdf0e10cSrcweir } 493cdf0e10cSrcweir } 494cdf0e10cSrcweir uno_any_destruct( &uno_ret, 0 ); 495cdf0e10cSrcweir return jo_ret; 496cdf0e10cSrcweir } 497cdf0e10cSrcweir else 498cdf0e10cSrcweir { 499cdf0e10cSrcweir bridge->handle_uno_exc( jni, uno_exc ); 500cdf0e10cSrcweir return 0; 501cdf0e10cSrcweir } 502cdf0e10cSrcweir } 503cdf0e10cSrcweir 504cdf0e10cSrcweir typelib_InterfaceTypeDescription * td = 505cdf0e10cSrcweir reinterpret_cast< typelib_InterfaceTypeDescription * >( 506cdf0e10cSrcweir jni->GetLongField( 507cdf0e10cSrcweir jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) ); 508cdf0e10cSrcweir uno_Interface * pUnoI = 509cdf0e10cSrcweir reinterpret_cast< uno_Interface * >( 510cdf0e10cSrcweir jni->GetLongField( 511cdf0e10cSrcweir jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) ); 512cdf0e10cSrcweir 513cdf0e10cSrcweir typelib_TypeDescriptionReference ** ppAllMembers = td->ppAllMembers; 514cdf0e10cSrcweir for ( sal_Int32 nPos = td->nAllMembers; nPos--; ) 515cdf0e10cSrcweir { 516cdf0e10cSrcweir // try to avoid getting typedescription as long as possible, 517cdf0e10cSrcweir // because of a Mutex.acquire() in 518cdf0e10cSrcweir // typelib_typedescriptionreference_getDescription() 519cdf0e10cSrcweir typelib_TypeDescriptionReference * member_type = 520cdf0e10cSrcweir ppAllMembers[ nPos ]; 521cdf0e10cSrcweir 522cdf0e10cSrcweir // check method_name against fully qualified type_name 523cdf0e10cSrcweir // of member_type; type_name is of the form 524cdf0e10cSrcweir // <name> "::" <method_name> *(":@" <idx> "," <idx> ":" <name>) 525cdf0e10cSrcweir OUString const & type_name = 526cdf0e10cSrcweir OUString::unacquired( &member_type->pTypeName ); 527cdf0e10cSrcweir sal_Int32 offset = type_name.indexOf( ':' ) + 2; 528cdf0e10cSrcweir OSL_ASSERT( 529cdf0e10cSrcweir offset >= 2 && offset < type_name.getLength() 530cdf0e10cSrcweir && type_name[offset - 1] == ':' ); 531cdf0e10cSrcweir sal_Int32 remainder = type_name.getLength() - offset; 532cdf0e10cSrcweir if (typelib_TypeClass_INTERFACE_METHOD == member_type->eTypeClass) 533cdf0e10cSrcweir { 534cdf0e10cSrcweir if ((method_name.getLength() == remainder 535cdf0e10cSrcweir || (method_name.getLength() < remainder 536cdf0e10cSrcweir && type_name[offset + method_name.getLength()] == ':')) 537cdf0e10cSrcweir && type_name.match(method_name, offset)) 538cdf0e10cSrcweir { 539cdf0e10cSrcweir TypeDescr member_td( member_type ); 540cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription * method_td = 541cdf0e10cSrcweir reinterpret_cast< 542cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription * >( 543cdf0e10cSrcweir member_td.get() ); 544cdf0e10cSrcweir return bridge->call_uno( 545cdf0e10cSrcweir jni, pUnoI, member_td.get(), 546cdf0e10cSrcweir method_td->pReturnTypeRef, 547cdf0e10cSrcweir method_td->nParams, method_td->pParams, 548cdf0e10cSrcweir jo_args ); 549cdf0e10cSrcweir } 550cdf0e10cSrcweir } 551cdf0e10cSrcweir else // attribute 552cdf0e10cSrcweir { 553cdf0e10cSrcweir OSL_ASSERT( 554cdf0e10cSrcweir typelib_TypeClass_INTERFACE_ATTRIBUTE == 555cdf0e10cSrcweir member_type->eTypeClass ); 556cdf0e10cSrcweir 557cdf0e10cSrcweir if (method_name.getLength() >= 3 558cdf0e10cSrcweir && (method_name.getLength() - 3 == remainder 559cdf0e10cSrcweir || (method_name.getLength() - 3 < remainder 560cdf0e10cSrcweir && type_name[ 561cdf0e10cSrcweir offset + (method_name.getLength() - 3)] == ':')) 562cdf0e10cSrcweir && method_name[1] == 'e' && method_name[2] == 't' 563cdf0e10cSrcweir && rtl_ustr_compare_WithLength( 564cdf0e10cSrcweir type_name.getStr() + offset, 565cdf0e10cSrcweir method_name.getLength() - 3, 566cdf0e10cSrcweir method_name.getStr() + 3, 567cdf0e10cSrcweir method_name.getLength() - 3) == 0) 568cdf0e10cSrcweir { 569cdf0e10cSrcweir if ('g' == method_name[ 0 ]) 570cdf0e10cSrcweir { 571cdf0e10cSrcweir TypeDescr member_td( member_type ); 572cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription * attr_td = 573cdf0e10cSrcweir reinterpret_cast< 574cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription * >( 575cdf0e10cSrcweir member_td.get() ); 576cdf0e10cSrcweir return bridge->call_uno( 577cdf0e10cSrcweir jni, pUnoI, member_td.get(), 578cdf0e10cSrcweir attr_td->pAttributeTypeRef, 579cdf0e10cSrcweir 0, 0, 580cdf0e10cSrcweir jo_args ); 581cdf0e10cSrcweir } 582cdf0e10cSrcweir else if ('s' == method_name[ 0 ]) 583cdf0e10cSrcweir { 584cdf0e10cSrcweir TypeDescr member_td( member_type ); 585cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription * attr_td = 586cdf0e10cSrcweir reinterpret_cast< 587cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription * >( 588cdf0e10cSrcweir member_td.get() ); 589cdf0e10cSrcweir if (! attr_td->bReadOnly) 590cdf0e10cSrcweir { 591cdf0e10cSrcweir typelib_MethodParameter param; 592cdf0e10cSrcweir param.pTypeRef = attr_td->pAttributeTypeRef; 593cdf0e10cSrcweir param.bIn = sal_True; 594cdf0e10cSrcweir param.bOut = sal_False; 595cdf0e10cSrcweir return bridge->call_uno( 596cdf0e10cSrcweir jni, pUnoI, member_td.get(), 597cdf0e10cSrcweir jni_info->m_void_type.getTypeLibType(), 598cdf0e10cSrcweir 1, ¶m, 599cdf0e10cSrcweir jo_args ); 600cdf0e10cSrcweir } 601cdf0e10cSrcweir } 602cdf0e10cSrcweir } 603cdf0e10cSrcweir } 604cdf0e10cSrcweir } 605cdf0e10cSrcweir // the thing that should not be... no method info found! 606cdf0e10cSrcweir OUStringBuffer buf( 64 ); 607cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( 608cdf0e10cSrcweir "calling undeclared function on interface ") ); 609cdf0e10cSrcweir buf.append( OUString::unacquired( 610cdf0e10cSrcweir &((typelib_TypeDescription *)td)->pTypeName ) ); 611cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") ); 612cdf0e10cSrcweir buf.append( method_name ); 613cdf0e10cSrcweir buf.append( jni.get_stack_trace() ); 614cdf0e10cSrcweir throw BridgeRuntimeError( buf.makeStringAndClear() ); 615cdf0e10cSrcweir } 616cdf0e10cSrcweir catch (BridgeRuntimeError & err) 617cdf0e10cSrcweir { 618cdf0e10cSrcweir OUStringBuffer buf( 128 ); 619cdf0e10cSrcweir buf.appendAscii( 620cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("[jni_uno bridge error] " 621cdf0e10cSrcweir "Java calling UNO method ") ); 622cdf0e10cSrcweir buf.append( method_name ); 623cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") ); 624cdf0e10cSrcweir buf.append( err.m_message ); 625cdf0e10cSrcweir // notify RuntimeException 626cdf0e10cSrcweir OString cstr_msg( 627cdf0e10cSrcweir OUStringToOString( 628cdf0e10cSrcweir buf.makeStringAndClear(), RTL_TEXTENCODING_JAVA_UTF8 ) ); 629cdf0e10cSrcweir OSL_ENSURE( 0, cstr_msg.getStr() ); 630cdf0e10cSrcweir if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr()) 631cdf0e10cSrcweir != 0) 632cdf0e10cSrcweir { 633cdf0e10cSrcweir OSL_ASSERT( false ); 634cdf0e10cSrcweir } 635cdf0e10cSrcweir return 0; 636cdf0e10cSrcweir } 637cdf0e10cSrcweir catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &) 638cdf0e10cSrcweir { 639cdf0e10cSrcweir OString cstr_msg( 640cdf0e10cSrcweir OString( RTL_CONSTASCII_STRINGPARAM( 641cdf0e10cSrcweir "[jni_uno bridge error] " 642cdf0e10cSrcweir "attaching current thread to java failed!") ) + 643cdf0e10cSrcweir OUStringToOString( 644cdf0e10cSrcweir jni.get_stack_trace(), RTL_TEXTENCODING_JAVA_UTF8 ) ); 645cdf0e10cSrcweir OSL_ENSURE( 0, cstr_msg.getStr() ); 646cdf0e10cSrcweir if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr()) 647cdf0e10cSrcweir != 0) 648cdf0e10cSrcweir { 649cdf0e10cSrcweir OSL_ASSERT( false ); 650cdf0e10cSrcweir } 651cdf0e10cSrcweir return 0; 652cdf0e10cSrcweir } 653cdf0e10cSrcweir } 654cdf0e10cSrcweir 655cdf0e10cSrcweir //------------------------------------------------------------------------------ 656cdf0e10cSrcweir JNIEXPORT void 657cdf0e10cSrcweir JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J( 658cdf0e10cSrcweir JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle ) 659cdf0e10cSrcweir SAL_THROW_EXTERN_C() 660cdf0e10cSrcweir { 661cdf0e10cSrcweir Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle ); 662cdf0e10cSrcweir JNI_info const * jni_info = bridge->m_jni_info; 663cdf0e10cSrcweir JNI_context jni( 664cdf0e10cSrcweir jni_info, jni_env, 665cdf0e10cSrcweir static_cast< jobject >( 666cdf0e10cSrcweir reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >( 667cdf0e10cSrcweir bridge->m_java_env->pContext )->getClassLoader() ) ); 668cdf0e10cSrcweir 669cdf0e10cSrcweir uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >( 670cdf0e10cSrcweir jni->GetLongField( 671cdf0e10cSrcweir jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) ); 672cdf0e10cSrcweir typelib_TypeDescription * td = 673cdf0e10cSrcweir reinterpret_cast< typelib_TypeDescription * >( 674cdf0e10cSrcweir jni->GetLongField( 675cdf0e10cSrcweir jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) ); 676cdf0e10cSrcweir 677cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 678cdf0e10cSrcweir { 679cdf0e10cSrcweir JLocalAutoRef jo_oid( 680cdf0e10cSrcweir jni, jni->GetObjectField( 681cdf0e10cSrcweir jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) ); 682cdf0e10cSrcweir OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) ); 683cdf0e10cSrcweir OString cstr_msg( 684cdf0e10cSrcweir OUStringToOString( 685cdf0e10cSrcweir OUSTR("freeing java uno proxy: ") + oid, 686cdf0e10cSrcweir RTL_TEXTENCODING_ASCII_US ) ); 687cdf0e10cSrcweir OSL_TRACE( cstr_msg.getStr() ); 688cdf0e10cSrcweir } 689cdf0e10cSrcweir #endif 690cdf0e10cSrcweir // revoke from uno env; has already been revoked from java env 691cdf0e10cSrcweir (*bridge->m_uno_env->revokeInterface)( bridge->m_uno_env, pUnoI ); 692cdf0e10cSrcweir // release receiver 693cdf0e10cSrcweir (*pUnoI->release)( pUnoI ); 694cdf0e10cSrcweir // release typedescription handle 695cdf0e10cSrcweir typelib_typedescription_release( td ); 696cdf0e10cSrcweir // release bridge handle 697cdf0e10cSrcweir bridge->release(); 698cdf0e10cSrcweir } 699cdf0e10cSrcweir 700cdf0e10cSrcweir } 701