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