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_bridges.hxx" 26 #include "jni_bridge.h" 27 28 #include "com/sun/star/uno/RuntimeException.hpp" 29 30 #include "jvmaccess/unovirtualmachine.hxx" 31 #include "rtl/string.hxx" 32 #include "rtl/strbuf.hxx" 33 #include "rtl/ustrbuf.hxx" 34 35 #include "uno/lbnames.h" 36 37 38 namespace css = ::com::sun::star; 39 using namespace ::std; 40 using namespace ::osl; 41 using namespace ::rtl; 42 43 namespace jni_uno 44 { 45 46 //______________________________________________________________________________ 47 JNI_type_info::JNI_type_info( 48 JNI_context const & jni, typelib_TypeDescription * td ) 49 : m_td( td ), 50 m_class( 0 ) 51 { 52 m_td.makeComplete(); 53 if (! m_td.get()->bComplete) 54 { 55 OUStringBuffer buf( 128 ); 56 buf.appendAscii( 57 RTL_CONSTASCII_STRINGPARAM("cannot make type complete: ") ); 58 buf.append( OUString::unacquired( &m_td.get()->pTypeName ) ); 59 buf.append( jni.get_stack_trace() ); 60 throw BridgeRuntimeError( buf.makeStringAndClear() ); 61 } 62 } 63 64 65 //______________________________________________________________________________ 66 void JNI_interface_type_info::destroy( JNIEnv * jni_env ) 67 { 68 JNI_type_info::destruct( jni_env ); 69 jni_env->DeleteGlobalRef( m_proxy_ctor ); 70 jni_env->DeleteGlobalRef( m_type ); 71 delete [] m_methods; 72 delete this; 73 } 74 75 //______________________________________________________________________________ 76 JNI_interface_type_info::JNI_interface_type_info( 77 JNI_context const & jni, typelib_TypeDescription * td_ ) 78 : JNI_type_info( jni, td_ ) 79 { 80 OSL_ASSERT( typelib_TypeClass_INTERFACE == m_td.get()->eTypeClass ); 81 82 OUString const & uno_name = OUString::unacquired( &m_td.get()->pTypeName ); 83 JNI_info const * jni_info = jni.get_info(); 84 85 JLocalAutoRef jo_class( 86 jni, 87 find_class( 88 jni, 89 ( OUStringToOString( uno_name, RTL_TEXTENCODING_JAVA_UTF8 ). 90 getStr() ) ) ); 91 JLocalAutoRef jo_type( jni, create_type( jni, (jclass) jo_class.get() ) ); 92 93 // get proxy ctor 94 jvalue arg; 95 arg.l = jo_class.get(); 96 JLocalAutoRef jo_proxy_ctor( 97 jni, jni->CallStaticObjectMethodA( 98 jni_info->m_class_JNI_proxy, 99 jni_info->m_method_JNI_proxy_get_proxy_ctor, &arg ) ); 100 101 if (is_XInterface( m_td.get()->pWeakRef )) 102 { 103 m_methods = 0; // no methods 104 } 105 else 106 { 107 // retrieve method ids for all direct members 108 try 109 { 110 typelib_InterfaceTypeDescription * td = 111 reinterpret_cast< typelib_InterfaceTypeDescription * >( 112 m_td.get() ); 113 m_methods = new jmethodID[ td->nMapFunctionIndexToMemberIndex ]; 114 sal_Int32 nMethodIndex = 0; 115 typelib_TypeDescriptionReference ** ppMembers = td->ppMembers; 116 sal_Int32 nMembers = td->nMembers; 117 118 for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos ) 119 { 120 TypeDescr member_td( ppMembers[ nPos ] ); 121 122 OStringBuffer sig_buf( 64 ); 123 124 if (typelib_TypeClass_INTERFACE_METHOD == 125 member_td.get()->eTypeClass) // method 126 { 127 typelib_InterfaceMethodTypeDescription * method_td = 128 reinterpret_cast< 129 typelib_InterfaceMethodTypeDescription * >( 130 member_td.get() ); 131 132 sig_buf.append( '(' ); 133 for ( sal_Int32 i = 0; i < method_td->nParams; ++i ) 134 { 135 typelib_MethodParameter const & param = 136 method_td->pParams[ i ]; 137 if (param.bOut) 138 sig_buf.append( '[' ); 139 JNI_info::append_sig( &sig_buf, param.pTypeRef ); 140 } 141 sig_buf.append( ')' ); 142 JNI_info::append_sig( &sig_buf, method_td->pReturnTypeRef ); 143 144 OString method_signature( sig_buf.makeStringAndClear() ); 145 OString method_name( 146 OUStringToOString( OUString::unacquired( 147 &method_td->aBase.pMemberName ), 148 RTL_TEXTENCODING_JAVA_UTF8 ) ); 149 150 m_methods[ nMethodIndex ] = jni->GetMethodID( 151 (jclass) jo_class.get(), method_name.getStr(), 152 method_signature.getStr() ); 153 jni.ensure_no_exception(); 154 OSL_ASSERT( 0 != m_methods[ nMethodIndex ] ); 155 ++nMethodIndex; 156 } 157 else // attribute 158 { 159 OSL_ASSERT( 160 typelib_TypeClass_INTERFACE_ATTRIBUTE == 161 member_td.get()->eTypeClass ); 162 typelib_InterfaceAttributeTypeDescription * attribute_td = 163 reinterpret_cast< 164 typelib_InterfaceAttributeTypeDescription * >( 165 member_td.get() ); 166 167 // type sig 168 JNI_info::append_sig( 169 &sig_buf, attribute_td->pAttributeTypeRef ); 170 OString type_sig( sig_buf.makeStringAndClear() ); 171 sig_buf.ensureCapacity( 64 ); 172 // member name 173 OUString const & member_name = 174 OUString::unacquired( 175 &attribute_td->aBase.pMemberName ); 176 177 // getter 178 sig_buf.append( RTL_CONSTASCII_STRINGPARAM("()") ); 179 sig_buf.append( type_sig ); 180 OString method_signature( sig_buf.makeStringAndClear() ); 181 OUStringBuffer name_buf( 3 + member_name.getLength() ); 182 name_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("get") ); 183 name_buf.append( member_name ); 184 OString method_name( 185 OUStringToOString( 186 name_buf.makeStringAndClear(), 187 RTL_TEXTENCODING_JAVA_UTF8 ) ); 188 m_methods[ nMethodIndex ] = jni->GetMethodID( 189 (jclass) jo_class.get(), method_name.getStr(), 190 method_signature.getStr() ); 191 jni.ensure_no_exception(); 192 OSL_ASSERT( 0 != m_methods[ nMethodIndex ] ); 193 ++nMethodIndex; 194 if (! attribute_td->bReadOnly) 195 { 196 // setter 197 sig_buf.ensureCapacity( 64 ); 198 sig_buf.append( '(' ); 199 sig_buf.append( type_sig ); 200 sig_buf.append( RTL_CONSTASCII_STRINGPARAM(")V") ); 201 method_signature = sig_buf.makeStringAndClear(); 202 name_buf.ensureCapacity( 3 + member_name.getLength() ); 203 name_buf.appendAscii( 204 RTL_CONSTASCII_STRINGPARAM("set") ); 205 name_buf.append( member_name ); 206 method_name = OUStringToOString( 207 name_buf.makeStringAndClear(), 208 RTL_TEXTENCODING_JAVA_UTF8 ); 209 m_methods[ nMethodIndex ] = jni->GetMethodID( 210 (jclass) jo_class.get(), method_name.getStr(), 211 method_signature.getStr() ); 212 jni.ensure_no_exception(); 213 OSL_ASSERT( 0 != m_methods[ nMethodIndex ] ); 214 ++nMethodIndex; 215 } 216 } 217 } 218 } 219 catch (...) 220 { 221 delete [] m_methods; 222 throw; 223 } 224 } 225 m_class = (jclass) jni->NewGlobalRef( jo_class.get() ); 226 m_type = jni->NewGlobalRef( jo_type.get() ); 227 m_proxy_ctor = jni->NewGlobalRef( jo_proxy_ctor.get() ); 228 } 229 230 231 //______________________________________________________________________________ 232 void JNI_compound_type_info::destroy( JNIEnv * jni_env ) 233 { 234 JNI_type_info::destruct( jni_env ); 235 delete [] m_fields; 236 delete this; 237 } 238 239 //______________________________________________________________________________ 240 JNI_compound_type_info::JNI_compound_type_info( 241 JNI_context const & jni, typelib_TypeDescription * td_ ) 242 : JNI_type_info( jni, td_ ), 243 m_exc_ctor( 0 ), 244 m_fields( 0 ) 245 { 246 OSL_ASSERT( typelib_TypeClass_STRUCT == m_td.get()->eTypeClass || 247 typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass ); 248 typelib_CompoundTypeDescription * td = 249 reinterpret_cast< typelib_CompoundTypeDescription * >( m_td.get() ); 250 251 OUString const & uno_name = 252 OUString::unacquired( &((typelib_TypeDescription *)td)->pTypeName ); 253 254 // Erase type arguments of instantiated polymorphic struct types: 255 OUString nucleus; 256 sal_Int32 i = uno_name.indexOf( '<' ); 257 if ( i < 0 ) { 258 nucleus = uno_name; 259 } else { 260 nucleus = uno_name.copy( 0, i ); 261 } 262 JLocalAutoRef jo_class( 263 jni, 264 find_class( 265 jni, 266 OUStringToOString( 267 nucleus, RTL_TEXTENCODING_JAVA_UTF8 ).getStr() ) ); 268 269 JNI_info const * jni_info = jni.get_info(); 270 271 if (typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass) 272 { 273 // retrieve exc ctor( msg ) 274 m_exc_ctor = jni->GetMethodID( 275 (jclass) jo_class.get(), "<init>", "(Ljava/lang/String;)V" ); 276 jni.ensure_no_exception(); 277 OSL_ASSERT( 0 != m_exc_ctor ); 278 } 279 280 // retrieve info for base type 281 typelib_TypeDescription * base_td = 282 reinterpret_cast< typelib_TypeDescription * >( 283 td->pBaseTypeDescription ); 284 m_base = (0 == base_td ? 0 : jni_info->get_type_info( jni, base_td )); 285 286 try 287 { 288 if (type_equals( 289 ((typelib_TypeDescription *)td)->pWeakRef, 290 jni_info->m_Exception_type.getTypeLibType() ) || 291 type_equals( 292 ((typelib_TypeDescription *)td)->pWeakRef, 293 jni_info->m_RuntimeException_type.getTypeLibType() )) 294 { 295 m_fields = new jfieldID[ 2 ]; 296 m_fields[ 0 ] = 0; // special Throwable.getMessage() 297 // field Context 298 m_fields[ 1 ] = jni->GetFieldID( 299 (jclass) jo_class.get(), "Context", "Ljava/lang/Object;" ); 300 jni.ensure_no_exception(); 301 OSL_ASSERT( 0 != m_fields[ 1 ] ); 302 } 303 else 304 { 305 // retrieve field ids for all direct members 306 sal_Int32 nMembers = td->nMembers; 307 m_fields = new jfieldID[ nMembers ]; 308 309 for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos ) 310 { 311 OString sig; 312 if (td->aBase.eTypeClass == typelib_TypeClass_STRUCT 313 && reinterpret_cast< typelib_StructTypeDescription * >( 314 td)->pParameterizedTypes != 0 315 && reinterpret_cast< typelib_StructTypeDescription * >( 316 td)->pParameterizedTypes[nPos]) 317 { 318 sig = OString( 319 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;")); 320 } else { 321 OStringBuffer sig_buf( 32 ); 322 JNI_info::append_sig( &sig_buf, td->ppTypeRefs[ nPos ] ); 323 sig = sig_buf.makeStringAndClear(); 324 } 325 326 OString member_name( 327 OUStringToOString( 328 OUString::unacquired( &td->ppMemberNames[ nPos ] ), 329 RTL_TEXTENCODING_JAVA_UTF8 ) ); 330 331 m_fields[ nPos ] = jni->GetFieldID( 332 (jclass) jo_class.get(), member_name.getStr(), 333 sig.getStr() ); 334 jni.ensure_no_exception(); 335 OSL_ASSERT( 0 != m_fields[ nPos ] ); 336 } 337 } 338 } 339 catch (...) 340 { 341 delete [] m_fields; 342 throw; 343 } 344 345 m_class = (jclass) jni->NewGlobalRef( jo_class.get() ); 346 } 347 348 349 //______________________________________________________________________________ 350 JNI_type_info const * JNI_info::create_type_info( 351 JNI_context const & jni, typelib_TypeDescription * td ) const 352 { 353 OUString const & uno_name = OUString::unacquired( &td->pTypeName ); 354 355 JNI_type_info * new_info; 356 switch (td->eTypeClass) 357 { 358 case typelib_TypeClass_STRUCT: 359 case typelib_TypeClass_EXCEPTION: 360 { 361 new_info = new JNI_compound_type_info( jni, td ); 362 break; 363 } 364 case typelib_TypeClass_INTERFACE: 365 { 366 new_info = new JNI_interface_type_info( jni, td ); 367 break; 368 } 369 default: 370 { 371 OUStringBuffer buf( 128 ); 372 buf.appendAscii( 373 RTL_CONSTASCII_STRINGPARAM("type info not supported for ") ); 374 buf.append( uno_name ); 375 buf.append( jni.get_stack_trace() ); 376 throw BridgeRuntimeError( buf.makeStringAndClear() ); 377 } 378 } 379 380 // look up 381 JNI_type_info * info; 382 ClearableMutexGuard guard( m_mutex ); 383 JNI_type_info_holder & holder = m_type_map[ uno_name ]; 384 if (0 == holder.m_info) // new insertion 385 { 386 holder.m_info = new_info; 387 guard.clear(); 388 info = new_info; 389 } 390 else // inserted in the meantime 391 { 392 info = holder.m_info; 393 guard.clear(); 394 new_info->destroy( jni.get_jni_env() ); 395 } 396 return info; 397 } 398 399 //______________________________________________________________________________ 400 JNI_type_info const * JNI_info::get_type_info( 401 JNI_context const & jni, typelib_TypeDescription * td ) const 402 { 403 if (is_XInterface( td->pWeakRef )) 404 { 405 return m_XInterface_type_info; 406 } 407 408 OUString const & uno_name = OUString::unacquired( &td->pTypeName ); 409 JNI_type_info const * info; 410 ClearableMutexGuard guard( m_mutex ); 411 412 t_str2type::const_iterator iFind( m_type_map.find( uno_name ) ); 413 if (iFind == m_type_map.end()) 414 { 415 guard.clear(); 416 info = create_type_info( jni, td ); 417 } 418 else 419 { 420 info = iFind->second.m_info; 421 } 422 423 return info; 424 } 425 426 //______________________________________________________________________________ 427 JNI_type_info const * JNI_info::get_type_info( 428 JNI_context const & jni, typelib_TypeDescriptionReference * type ) const 429 { 430 if (is_XInterface( type )) 431 { 432 return m_XInterface_type_info; 433 } 434 435 OUString const & uno_name = OUString::unacquired( &type->pTypeName ); 436 JNI_type_info const * info; 437 ClearableMutexGuard guard( m_mutex ); 438 t_str2type::const_iterator iFind( m_type_map.find( uno_name ) ); 439 if (iFind == m_type_map.end()) 440 { 441 guard.clear(); 442 TypeDescr td( type ); 443 info = create_type_info( jni, td.get() ); 444 } 445 else 446 { 447 info = iFind->second.m_info; 448 } 449 450 return info; 451 } 452 453 //______________________________________________________________________________ 454 JNI_type_info const * JNI_info::get_type_info( 455 JNI_context const & jni, OUString const & uno_name ) const 456 { 457 if (uno_name.equalsAsciiL( 458 RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") )) 459 { 460 return m_XInterface_type_info; 461 } 462 463 JNI_type_info const * info; 464 ClearableMutexGuard guard( m_mutex ); 465 t_str2type::const_iterator iFind( m_type_map.find( uno_name ) ); 466 if (iFind == m_type_map.end()) 467 { 468 guard.clear(); 469 css::uno::TypeDescription td( uno_name ); 470 if (! td.is()) 471 { 472 OUStringBuffer buf( 128 ); 473 buf.appendAscii( 474 RTL_CONSTASCII_STRINGPARAM("UNO type not found: ") ); 475 buf.append( uno_name ); 476 buf.append( jni.get_stack_trace() ); 477 throw BridgeRuntimeError( buf.makeStringAndClear() ); 478 } 479 info = create_type_info( jni, td.get() ); 480 } 481 else 482 { 483 info = iFind->second.m_info; 484 } 485 486 return info; 487 } 488 489 //______________________________________________________________________________ 490 JNI_info::JNI_info( 491 JNIEnv * jni_env, jobject class_loader, jclass classClass, 492 jmethodID methodForName ) 493 : m_class_Class( classClass ), 494 m_method_Class_forName( methodForName ), 495 m_class_JNI_proxy( 0 ), 496 m_XInterface_queryInterface_td( 497 (reinterpret_cast< typelib_InterfaceTypeDescription * >( 498 css::uno::TypeDescription( 499 ::getCppuType( 500 (css::uno::Reference< css::uno::XInterface > const *)0 ) ) 501 .get())->ppMembers[ 0 ] ) ), 502 m_Exception_type( ::getCppuType( (css::uno::Exception const *)0 ) ), 503 m_RuntimeException_type( 504 ::getCppuType( (css::uno::RuntimeException const *)0 ) ), 505 m_void_type( ::getCppuVoidType() ), 506 m_XInterface_type_info( 0 ) 507 { 508 JNI_context jni( this, jni_env, class_loader ); // !no proper jni_info! 509 510 // class lookup 511 JLocalAutoRef jo_Object( 512 jni, find_class( jni, "java.lang.Object" ) ); 513 JLocalAutoRef jo_Class( 514 jni, find_class( jni, "java.lang.Class" ) ); 515 JLocalAutoRef jo_Throwable( 516 jni, find_class( jni, "java.lang.Throwable" ) ); 517 JLocalAutoRef jo_Character( 518 jni, find_class( jni, "java.lang.Character" ) ); 519 JLocalAutoRef jo_Boolean( 520 jni, find_class( jni, "java.lang.Boolean" ) ); 521 JLocalAutoRef jo_Byte( 522 jni, find_class( jni, "java.lang.Byte" ) ); 523 JLocalAutoRef jo_Short( 524 jni, find_class( jni, "java.lang.Short" ) ); 525 JLocalAutoRef jo_Integer( 526 jni, find_class( jni, "java.lang.Integer" ) ); 527 JLocalAutoRef jo_Long( 528 jni, find_class( jni, "java.lang.Long" ) ); 529 JLocalAutoRef jo_Float( 530 jni, find_class( jni, "java.lang.Float" ) ); 531 JLocalAutoRef jo_Double( 532 jni, find_class( jni, "java.lang.Double" ) ); 533 JLocalAutoRef jo_String( 534 jni, find_class( jni, "java.lang.String" ) ); 535 JLocalAutoRef jo_RuntimeException( 536 jni, find_class( jni, "com.sun.star.uno.RuntimeException" ) ); 537 JLocalAutoRef jo_UnoRuntime( 538 jni, find_class( jni, "com.sun.star.uno.UnoRuntime" ) ); 539 JLocalAutoRef jo_Any( 540 jni, find_class( jni, "com.sun.star.uno.Any" ) ); 541 JLocalAutoRef jo_Enum( 542 jni, find_class( jni, "com.sun.star.uno.Enum" ) ); 543 JLocalAutoRef jo_Type( 544 jni, find_class( jni, "com.sun.star.uno.Type" ) ); 545 JLocalAutoRef jo_TypeClass( 546 jni, find_class( jni, "com.sun.star.uno.TypeClass" ) ); 547 JLocalAutoRef jo_IEnvironment( 548 jni, find_class( jni, "com.sun.star.uno.IEnvironment" ) ); 549 JLocalAutoRef jo_JNI_proxy( 550 jni, find_class( jni, "com.sun.star.bridges.jni_uno.JNI_proxy" ) ); 551 552 // method Object.toString() 553 m_method_Object_toString = jni->GetMethodID( 554 (jclass) jo_Object.get(), "toString", "()Ljava/lang/String;" ); 555 jni.ensure_no_exception(); 556 OSL_ASSERT( 0 != m_method_Object_toString ); 557 // method Class.getName() 558 m_method_Class_getName = jni->GetMethodID( 559 (jclass) jo_Class.get(), "getName", "()Ljava/lang/String;" ); 560 jni.ensure_no_exception(); 561 OSL_ASSERT( 0 != m_method_Class_getName ); 562 563 // method Throwable.getMessage() 564 m_method_Throwable_getMessage = jni->GetMethodID( 565 (jclass) jo_Throwable.get(), "getMessage", "()Ljava/lang/String;" ); 566 jni.ensure_no_exception(); 567 OSL_ASSERT( 0 != m_method_Throwable_getMessage ); 568 569 // method Character.charValue() 570 m_method_Character_charValue = jni->GetMethodID( 571 (jclass) jo_Character.get(), "charValue", "()C" ); 572 jni.ensure_no_exception(); 573 OSL_ASSERT( 0 != m_method_Character_charValue ); 574 // method Boolean.booleanValue() 575 m_method_Boolean_booleanValue = jni->GetMethodID( 576 (jclass) jo_Boolean.get(), "booleanValue", "()Z" ); 577 jni.ensure_no_exception(); 578 OSL_ASSERT( 0 != m_method_Boolean_booleanValue ); 579 // method Byte.byteValue() 580 m_method_Byte_byteValue = jni->GetMethodID( 581 (jclass) jo_Byte.get(), "byteValue", "()B" ); 582 jni.ensure_no_exception(); 583 OSL_ASSERT( 0 != m_method_Byte_byteValue ); 584 // method Short.shortValue() 585 m_method_Short_shortValue = jni->GetMethodID( 586 (jclass) jo_Short.get(), "shortValue", "()S" ); 587 jni.ensure_no_exception(); 588 OSL_ASSERT( 0 != m_method_Short_shortValue ); 589 // method Integer.intValue() 590 m_method_Integer_intValue = jni->GetMethodID( 591 (jclass) jo_Integer.get(), "intValue", "()I" ); 592 jni.ensure_no_exception(); 593 OSL_ASSERT( 0 != m_method_Integer_intValue ); 594 // method Long.longValue() 595 m_method_Long_longValue = jni->GetMethodID( 596 (jclass) jo_Long.get(), "longValue", "()J" ); 597 jni.ensure_no_exception(); 598 OSL_ASSERT( 0 != m_method_Long_longValue ); 599 // method Float.floatValue() 600 m_method_Float_floatValue = jni->GetMethodID( 601 (jclass) jo_Float.get(), "floatValue", "()F" ); 602 jni.ensure_no_exception(); 603 OSL_ASSERT( 0 != m_method_Float_floatValue ); 604 // method Double.doubleValue() 605 m_method_Double_doubleValue = jni->GetMethodID( 606 (jclass) jo_Double.get(), "doubleValue", "()D" ); 607 jni.ensure_no_exception(); 608 OSL_ASSERT( 0 != m_method_Double_doubleValue ); 609 610 // ctor Character( char ) 611 m_ctor_Character_with_char = jni->GetMethodID( 612 (jclass) jo_Character.get(), "<init>", "(C)V" ); 613 jni.ensure_no_exception(); 614 OSL_ASSERT( 0 != m_ctor_Character_with_char ); 615 // ctor Boolean( boolean ) 616 m_ctor_Boolean_with_boolean = jni->GetMethodID( 617 (jclass) jo_Boolean.get(), "<init>", "(Z)V" ); 618 jni.ensure_no_exception(); 619 OSL_ASSERT( 0 != m_ctor_Boolean_with_boolean ); 620 // ctor Byte( byte ) 621 m_ctor_Byte_with_byte = jni->GetMethodID( 622 (jclass) jo_Byte.get(), "<init>", "(B)V" ); 623 jni.ensure_no_exception(); 624 OSL_ASSERT( 0 != m_ctor_Byte_with_byte ); 625 // ctor Short( short ) 626 m_ctor_Short_with_short = jni->GetMethodID( 627 (jclass) jo_Short.get(), "<init>", "(S)V" ); 628 jni.ensure_no_exception(); 629 OSL_ASSERT( 0 != m_ctor_Short_with_short ); 630 // ctor Integer( int ) 631 m_ctor_Integer_with_int = jni->GetMethodID( 632 (jclass) jo_Integer.get(), "<init>", "(I)V" ); 633 jni.ensure_no_exception(); 634 OSL_ASSERT( 0 != m_ctor_Integer_with_int ); 635 // ctor Long( long ) 636 m_ctor_Long_with_long = jni->GetMethodID( 637 (jclass) jo_Long.get(), "<init>", "(J)V" ); 638 jni.ensure_no_exception(); 639 OSL_ASSERT( 0 != m_ctor_Long_with_long ); 640 // ctor Float( float ) 641 m_ctor_Float_with_float = jni->GetMethodID( 642 (jclass) jo_Float.get(), "<init>", "(F)V" ); 643 jni.ensure_no_exception(); 644 OSL_ASSERT( 0 != m_ctor_Float_with_float ); 645 // ctor Double( double ) 646 m_ctor_Double_with_double = jni->GetMethodID( 647 (jclass) jo_Double.get(), "<init>", "(D)V" ); 648 jni.ensure_no_exception(); 649 OSL_ASSERT( 0 != m_ctor_Double_with_double ); 650 651 // static method UnoRuntime.generateOid() 652 m_method_UnoRuntime_generateOid = jni->GetStaticMethodID( 653 (jclass) jo_UnoRuntime.get(), 654 "generateOid", "(Ljava/lang/Object;)Ljava/lang/String;" ); 655 jni.ensure_no_exception(); 656 OSL_ASSERT( 0 != m_method_UnoRuntime_generateOid ); 657 // static method UnoRuntime.queryInterface() 658 m_method_UnoRuntime_queryInterface = jni->GetStaticMethodID( 659 (jclass) jo_UnoRuntime.get(), 660 "queryInterface", 661 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)Ljava/lang/Object;" ); 662 jni.ensure_no_exception(); 663 OSL_ASSERT( 0 != m_method_UnoRuntime_queryInterface ); 664 665 // field Enum.m_value 666 m_field_Enum_m_value = jni->GetFieldID( 667 (jclass) jo_Enum.get(), "m_value", "I" ); 668 jni.ensure_no_exception(); 669 OSL_ASSERT( 0 != m_field_Enum_m_value ); 670 671 // static method TypeClass.fromInt() 672 m_method_TypeClass_fromInt = jni->GetStaticMethodID( 673 (jclass) jo_TypeClass.get(), 674 "fromInt", "(I)Lcom/sun/star/uno/TypeClass;" ); 675 jni.ensure_no_exception(); 676 OSL_ASSERT( 0 != m_method_TypeClass_fromInt ); 677 678 // ctor Type( Class ) 679 m_ctor_Type_with_Class = jni->GetMethodID( 680 (jclass) jo_Type.get(), "<init>", "(Ljava/lang/Class;)V" ); 681 jni.ensure_no_exception(); 682 OSL_ASSERT( 0 != m_ctor_Type_with_Class ); 683 // ctor Type( String, TypeClass ) 684 m_ctor_Type_with_Name_TypeClass = jni->GetMethodID( 685 (jclass) jo_Type.get(), 686 "<init>", "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V" ); 687 jni.ensure_no_exception(); 688 OSL_ASSERT( 0 != m_ctor_Type_with_Name_TypeClass ); 689 // field Type._typeName 690 m_field_Type__typeName = jni->GetFieldID( 691 (jclass) jo_Type.get(), "_typeName", "Ljava/lang/String;" ); 692 jni.ensure_no_exception(); 693 OSL_ASSERT( 0 != m_field_Type__typeName ); 694 695 // ctor Any( Type, Object ) 696 m_ctor_Any_with_Type_Object = jni->GetMethodID( 697 (jclass) jo_Any.get(), 698 "<init>", "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V" ); 699 jni.ensure_no_exception(); 700 OSL_ASSERT( 0 != m_ctor_Any_with_Type_Object ); 701 702 // field Any._type 703 m_field_Any__type = jni->GetFieldID( 704 (jclass) jo_Any.get(), "_type", "Lcom/sun/star/uno/Type;" ); 705 jni.ensure_no_exception(); 706 OSL_ASSERT( 0 != m_field_Any__type ); 707 // field Any._object 708 m_field_Any__object = jni->GetFieldID( 709 (jclass) jo_Any.get(), "_object", "Ljava/lang/Object;" ); 710 jni.ensure_no_exception(); 711 OSL_ASSERT( 0 != m_field_Any__object ); 712 713 // method IEnvironment.getRegisteredInterface() 714 m_method_IEnvironment_getRegisteredInterface = jni->GetMethodID( 715 (jclass) jo_IEnvironment.get(), 716 "getRegisteredInterface", 717 "(Ljava/lang/String;Lcom/sun/star/uno/Type;)Ljava/lang/Object;" ); 718 jni.ensure_no_exception(); 719 OSL_ASSERT( 0 != m_method_IEnvironment_getRegisteredInterface ); 720 // method IEnvironment.registerInterface() 721 m_method_IEnvironment_registerInterface = jni->GetMethodID( 722 (jclass) jo_IEnvironment.get(), "registerInterface", 723 "(Ljava/lang/Object;[Ljava/lang/String;Lcom/sun/star/uno/Type;)" 724 "Ljava/lang/Object;" ); 725 jni.ensure_no_exception(); 726 OSL_ASSERT( 0 != m_method_IEnvironment_registerInterface ); 727 728 // static method JNI_proxy.get_proxy_ctor() 729 m_method_JNI_proxy_get_proxy_ctor = jni->GetStaticMethodID( 730 (jclass) jo_JNI_proxy.get(), "get_proxy_ctor", 731 "(Ljava/lang/Class;)Ljava/lang/reflect/Constructor;" ); 732 jni.ensure_no_exception(); 733 OSL_ASSERT( 0 != m_method_JNI_proxy_get_proxy_ctor ); 734 // static method JNI_proxy.create() 735 m_method_JNI_proxy_create = jni->GetStaticMethodID( 736 (jclass) jo_JNI_proxy.get(), "create", 737 "(JLcom/sun/star/uno/IEnvironment;JJLcom/sun/star/uno/Type;Ljava/lang" 738 "/String;Ljava/lang/reflect/Constructor;)Ljava/lang/Object;" ); 739 jni.ensure_no_exception(); 740 OSL_ASSERT( 0 != m_method_JNI_proxy_create ); 741 // field JNI_proxy.m_receiver_handle 742 m_field_JNI_proxy_m_receiver_handle = jni->GetFieldID( 743 (jclass) jo_JNI_proxy.get(), "m_receiver_handle", "J" ); 744 jni.ensure_no_exception(); 745 OSL_ASSERT( 0 != m_field_JNI_proxy_m_receiver_handle ); 746 // field JNI_proxy.m_td_handle 747 m_field_JNI_proxy_m_td_handle = jni->GetFieldID( 748 (jclass) jo_JNI_proxy.get(), "m_td_handle", "J" ); 749 jni.ensure_no_exception(); 750 OSL_ASSERT( 0 != m_field_JNI_proxy_m_td_handle ); 751 // field JNI_proxy.m_type 752 m_field_JNI_proxy_m_type = jni->GetFieldID( 753 (jclass) jo_JNI_proxy.get(), "m_type", "Lcom/sun/star/uno/Type;" ); 754 jni.ensure_no_exception(); 755 OSL_ASSERT( 0 != m_field_JNI_proxy_m_type ); 756 // field JNI_proxy.m_oid 757 m_field_JNI_proxy_m_oid = jni->GetFieldID( 758 (jclass) jo_JNI_proxy.get(), "m_oid", "Ljava/lang/String;" ); 759 jni.ensure_no_exception(); 760 OSL_ASSERT( 0 != m_field_JNI_proxy_m_oid ); 761 762 // get java env 763 OUString java_env_type_name( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_JAVA) ); 764 JLocalAutoRef jo_java( 765 jni, ustring_to_jstring( jni, java_env_type_name.pData ) ); 766 jvalue args[ 2 ]; 767 args[ 0 ].l = jo_java.get(); 768 args[ 1 ].l = 0; 769 jmethodID method_getEnvironment = jni->GetStaticMethodID( 770 (jclass) jo_UnoRuntime.get(), "getEnvironment", 771 "(Ljava/lang/String;Ljava/lang/Object;)" 772 "Lcom/sun/star/uno/IEnvironment;" ); 773 jni.ensure_no_exception(); 774 OSL_ASSERT( 0 != method_getEnvironment ); 775 JLocalAutoRef jo_java_env( 776 jni, jni->CallStaticObjectMethodA( 777 (jclass) jo_UnoRuntime.get(), method_getEnvironment, args ) ); 778 779 // get com.sun.star.uno.Any.VOID 780 jfieldID field_Any_VOID = jni->GetStaticFieldID( 781 (jclass) jo_Any.get(), "VOID", "Lcom/sun/star/uno/Any;" ); 782 jni.ensure_no_exception(); 783 OSL_ASSERT( 0 != field_Any_VOID ); 784 JLocalAutoRef jo_Any_VOID( 785 jni, jni->GetStaticObjectField( 786 (jclass) jo_Any.get(), field_Any_VOID ) ); 787 // get com.sun.star.uno.Type.UNSIGNED_SHORT 788 jfieldID field_Type_UNSIGNED_SHORT = jni->GetStaticFieldID( 789 (jclass) jo_Type.get(), "UNSIGNED_SHORT", "Lcom/sun/star/uno/Type;" ); 790 jni.ensure_no_exception(); 791 OSL_ASSERT( 0 != field_Type_UNSIGNED_SHORT ); 792 JLocalAutoRef jo_Type_UNSIGNED_SHORT( 793 jni, jni->GetStaticObjectField( 794 (jclass) jo_Type.get(), field_Type_UNSIGNED_SHORT ) ); 795 // get com.sun.star.uno.Type.UNSIGNED_LONG 796 jfieldID field_Type_UNSIGNED_LONG = jni->GetStaticFieldID( 797 (jclass) jo_Type.get(), "UNSIGNED_LONG", "Lcom/sun/star/uno/Type;" ); 798 jni.ensure_no_exception(); 799 OSL_ASSERT( 0 != field_Type_UNSIGNED_LONG ); 800 JLocalAutoRef jo_Type_UNSIGNED_LONG( 801 jni, jni->GetStaticObjectField( 802 (jclass) jo_Type.get(), field_Type_UNSIGNED_LONG ) ); 803 // get com.sun.star.uno.Type.UNSIGNED_HYPER 804 jfieldID field_Type_UNSIGNED_HYPER = jni->GetStaticFieldID( 805 (jclass) jo_Type.get(), "UNSIGNED_HYPER", "Lcom/sun/star/uno/Type;" ); 806 jni.ensure_no_exception(); 807 OSL_ASSERT( 0 != field_Type_UNSIGNED_HYPER ); 808 JLocalAutoRef jo_Type_UNSIGNED_HYPER( 809 jni, jni->GetStaticObjectField( 810 (jclass) jo_Type.get(), field_Type_UNSIGNED_HYPER ) ); 811 812 // make global refs 813 m_class_UnoRuntime = 814 (jclass) jni->NewGlobalRef( jo_UnoRuntime.get() ); 815 m_class_RuntimeException = 816 (jclass) jni->NewGlobalRef( jo_RuntimeException.get() ); 817 m_class_Any = 818 (jclass) jni->NewGlobalRef( jo_Any.get() ); 819 m_class_Type = 820 (jclass) jni->NewGlobalRef( jo_Type.get() ); 821 m_class_TypeClass = 822 (jclass) jni->NewGlobalRef( jo_TypeClass.get() ); 823 m_class_JNI_proxy = 824 (jclass) jni->NewGlobalRef( jo_JNI_proxy.get() ); 825 826 m_class_Character = 827 (jclass) jni->NewGlobalRef( jo_Character.get() ); 828 m_class_Boolean = 829 (jclass) jni->NewGlobalRef( jo_Boolean.get() ); 830 m_class_Byte = 831 (jclass) jni->NewGlobalRef( jo_Byte.get() ); 832 m_class_Short = 833 (jclass) jni->NewGlobalRef( jo_Short.get() ); 834 m_class_Integer = 835 (jclass) jni->NewGlobalRef( jo_Integer.get() ); 836 m_class_Long = 837 (jclass) jni->NewGlobalRef( jo_Long.get() ); 838 m_class_Float = 839 (jclass) jni->NewGlobalRef( jo_Float.get() ); 840 m_class_Double = 841 (jclass) jni->NewGlobalRef( jo_Double.get() ); 842 m_class_String = 843 (jclass) jni->NewGlobalRef( jo_String.get() ); 844 m_class_Object = 845 (jclass) jni->NewGlobalRef( jo_Object.get() ); 846 m_class_Class = 847 (jclass) jni->NewGlobalRef( m_class_Class ); 848 849 m_object_Any_VOID = 850 jni->NewGlobalRef( jo_Any_VOID.get() ); 851 m_object_Type_UNSIGNED_SHORT = 852 jni->NewGlobalRef( jo_Type_UNSIGNED_SHORT.get() ); 853 m_object_Type_UNSIGNED_LONG = 854 jni->NewGlobalRef( jo_Type_UNSIGNED_LONG.get() ); 855 m_object_Type_UNSIGNED_HYPER = 856 jni->NewGlobalRef( jo_Type_UNSIGNED_HYPER.get() ); 857 m_object_java_env = jni->NewGlobalRef( jo_java_env.get() ); 858 859 try 860 { 861 css::uno::TypeDescription XInterface_td( 862 ::getCppuType( 863 (css::uno::Reference< css::uno::XInterface > const *)0 ) ); 864 m_XInterface_type_info = 865 new JNI_interface_type_info( jni, XInterface_td.get() ); 866 } 867 catch (...) 868 { 869 destruct( jni_env ); 870 throw; 871 } 872 } 873 874 //______________________________________________________________________________ 875 void JNI_info::destruct( JNIEnv * jni_env ) 876 { 877 t_str2type::const_iterator iPos( m_type_map.begin() ); 878 t_str2type::const_iterator const iEnd( m_type_map.begin() ); 879 for ( ; iPos != iEnd; ++iPos ) 880 { 881 iPos->second.m_info->destroy( jni_env ); 882 } 883 if (0 != m_XInterface_type_info) 884 { 885 const_cast< JNI_interface_type_info * >( 886 m_XInterface_type_info )->destroy( jni_env ); 887 } 888 889 // free global refs 890 jni_env->DeleteGlobalRef( m_object_java_env ); 891 jni_env->DeleteGlobalRef( m_object_Any_VOID ); 892 jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_SHORT ); 893 jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_LONG ); 894 jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_HYPER ); 895 896 jni_env->DeleteGlobalRef( m_class_Class ); 897 jni_env->DeleteGlobalRef( m_class_Object ); 898 jni_env->DeleteGlobalRef( m_class_String ); 899 jni_env->DeleteGlobalRef( m_class_Double ); 900 jni_env->DeleteGlobalRef( m_class_Float ); 901 jni_env->DeleteGlobalRef( m_class_Long ); 902 jni_env->DeleteGlobalRef( m_class_Integer ); 903 jni_env->DeleteGlobalRef( m_class_Short ); 904 jni_env->DeleteGlobalRef( m_class_Byte ); 905 jni_env->DeleteGlobalRef( m_class_Boolean ); 906 jni_env->DeleteGlobalRef( m_class_Character ); 907 908 jni_env->DeleteGlobalRef( m_class_JNI_proxy ); 909 jni_env->DeleteGlobalRef( m_class_RuntimeException ); 910 jni_env->DeleteGlobalRef( m_class_UnoRuntime ); 911 jni_env->DeleteGlobalRef( m_class_TypeClass ); 912 jni_env->DeleteGlobalRef( m_class_Type ); 913 jni_env->DeleteGlobalRef( m_class_Any ); 914 } 915 916 //______________________________________________________________________________ 917 JNI_info const * JNI_info::get_jni_info( 918 rtl::Reference< jvmaccess::UnoVirtualMachine > const & uno_vm ) 919 { 920 // !!!no JNI_info available at JNI_context!!! 921 ::jvmaccess::VirtualMachine::AttachGuard guard( 922 uno_vm->getVirtualMachine() ); 923 JNIEnv * jni_env = guard.getEnvironment(); 924 JNI_context jni( 925 0, jni_env, static_cast< jobject >(uno_vm->getClassLoader()) ); 926 927 jclass jo_class; 928 jmethodID jo_forName; 929 jni.getClassForName( &jo_class, &jo_forName ); 930 jni.ensure_no_exception(); 931 JLocalAutoRef jo_JNI_info_holder( 932 jni, 933 jni.findClass( 934 "com.sun.star.bridges.jni_uno.JNI_info_holder", jo_class, 935 jo_forName, false ) ); 936 // field JNI_info_holder.m_jni_info_handle 937 jfieldID field_s_jni_info_handle = 938 jni->GetStaticFieldID( 939 (jclass) jo_JNI_info_holder.get(), "s_jni_info_handle", "J" ); 940 jni.ensure_no_exception(); 941 OSL_ASSERT( 0 != field_s_jni_info_handle ); 942 943 JNI_info const * jni_info = 944 reinterpret_cast< JNI_info const * >( 945 jni->GetStaticLongField( 946 (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle ) ); 947 if (0 == jni_info) // un-initialized? 948 { 949 JNI_info * new_info = new JNI_info( 950 jni_env, static_cast< jobject >(uno_vm->getClassLoader()), jo_class, 951 jo_forName ); 952 953 ClearableMutexGuard g( Mutex::getGlobalMutex() ); 954 jni_info = 955 reinterpret_cast< JNI_info const * >( 956 jni->GetStaticLongField( 957 (jclass) jo_JNI_info_holder.get(), 958 field_s_jni_info_handle ) ); 959 if (0 == jni_info) // still un-initialized? 960 { 961 jni->SetStaticLongField( 962 (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle, 963 reinterpret_cast< jlong >( new_info ) ); 964 jni_info = new_info; 965 } 966 else 967 { 968 g.clear(); 969 new_info->destroy( jni_env ); 970 } 971 } 972 973 return jni_info; 974 } 975 976 } 977 978 extern "C" 979 { 980 981 //------------------------------------------------------------------------------ 982 JNIEXPORT void 983 JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J( 984 JNIEnv * jni_env, jobject, jlong jni_info_handle ) 985 SAL_THROW_EXTERN_C() 986 { 987 ::jni_uno::JNI_info * jni_info = 988 reinterpret_cast< ::jni_uno::JNI_info * >( jni_info_handle ); 989 jni_info->destroy( jni_env ); 990 } 991 992 } 993