Bump version to 4.1-6
[LibreOffice.git] / bridges / source / jni_uno / jni_info.cxx
blobad0b52b463685c8b9d9128741e141d3816a0ef49
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "jni_bridge.h"
22 #include "com/sun/star/uno/RuntimeException.hpp"
24 #include "jvmaccess/unovirtualmachine.hxx"
25 #include "rtl/string.hxx"
26 #include "rtl/strbuf.hxx"
27 #include "rtl/ustrbuf.hxx"
29 #include "uno/lbnames.h"
32 using namespace ::std;
33 using namespace ::osl;
34 using namespace ::rtl;
36 namespace jni_uno
39 //______________________________________________________________________________
40 JNI_type_info::JNI_type_info(
41 JNI_context const & jni, typelib_TypeDescription * td )
42 : m_td( td ),
43 m_class( 0 )
45 m_td.makeComplete();
46 if (! m_td.get()->bComplete)
48 OUStringBuffer buf( 128 );
49 buf.append( "cannot make type complete: " );
50 buf.append( OUString::unacquired( &m_td.get()->pTypeName ) );
51 buf.append( jni.get_stack_trace() );
52 throw BridgeRuntimeError( buf.makeStringAndClear() );
57 //______________________________________________________________________________
58 void JNI_interface_type_info::destroy( JNIEnv * jni_env )
60 JNI_type_info::destruct( jni_env );
61 jni_env->DeleteGlobalRef( m_proxy_ctor );
62 jni_env->DeleteGlobalRef( m_type );
63 delete [] m_methods;
64 delete this;
67 //______________________________________________________________________________
68 JNI_interface_type_info::JNI_interface_type_info(
69 JNI_context const & jni, typelib_TypeDescription * td_ )
70 : JNI_type_info( jni, td_ )
72 OSL_ASSERT( typelib_TypeClass_INTERFACE == m_td.get()->eTypeClass );
74 OUString const & uno_name = OUString::unacquired( &m_td.get()->pTypeName );
75 JNI_info const * jni_info = jni.get_info();
77 JLocalAutoRef jo_class(
78 jni,
79 find_class(
80 jni,
81 ( OUStringToOString( uno_name, RTL_TEXTENCODING_JAVA_UTF8 ).
82 getStr() ) ) );
83 JLocalAutoRef jo_type( jni, create_type( jni, (jclass) jo_class.get() ) );
85 // get proxy ctor
86 jvalue arg;
87 arg.l = jo_class.get();
88 JLocalAutoRef jo_proxy_ctor(
89 jni, jni->CallStaticObjectMethodA(
90 jni_info->m_class_JNI_proxy,
91 jni_info->m_method_JNI_proxy_get_proxy_ctor, &arg ) );
93 if (is_XInterface( m_td.get()->pWeakRef ))
95 m_methods = 0; // no methods
97 else
99 // retrieve method ids for all direct members
102 typelib_InterfaceTypeDescription * td =
103 reinterpret_cast< typelib_InterfaceTypeDescription * >(
104 m_td.get() );
105 m_methods = new jmethodID[ td->nMapFunctionIndexToMemberIndex ];
106 sal_Int32 nMethodIndex = 0;
107 typelib_TypeDescriptionReference ** ppMembers = td->ppMembers;
108 sal_Int32 nMembers = td->nMembers;
110 for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos )
112 TypeDescr member_td( ppMembers[ nPos ] );
114 OStringBuffer sig_buf( 64 );
116 if (typelib_TypeClass_INTERFACE_METHOD ==
117 member_td.get()->eTypeClass) // method
119 typelib_InterfaceMethodTypeDescription * method_td =
120 reinterpret_cast<
121 typelib_InterfaceMethodTypeDescription * >(
122 member_td.get() );
124 sig_buf.append( '(' );
125 for ( sal_Int32 i = 0; i < method_td->nParams; ++i )
127 typelib_MethodParameter const & param =
128 method_td->pParams[ i ];
129 if (param.bOut)
130 sig_buf.append( '[' );
131 JNI_info::append_sig( &sig_buf, param.pTypeRef );
133 sig_buf.append( ')' );
134 JNI_info::append_sig( &sig_buf, method_td->pReturnTypeRef );
136 OString method_signature( sig_buf.makeStringAndClear() );
137 OString method_name(
138 OUStringToOString( OUString::unacquired(
139 &method_td->aBase.pMemberName ),
140 RTL_TEXTENCODING_JAVA_UTF8 ) );
142 m_methods[ nMethodIndex ] = jni->GetMethodID(
143 (jclass) jo_class.get(), method_name.getStr(),
144 method_signature.getStr() );
145 jni.ensure_no_exception();
146 OSL_ASSERT( 0 != m_methods[ nMethodIndex ] );
147 ++nMethodIndex;
149 else // attribute
151 OSL_ASSERT(
152 typelib_TypeClass_INTERFACE_ATTRIBUTE ==
153 member_td.get()->eTypeClass );
154 typelib_InterfaceAttributeTypeDescription * attribute_td =
155 reinterpret_cast<
156 typelib_InterfaceAttributeTypeDescription * >(
157 member_td.get() );
159 // type sig
160 JNI_info::append_sig(
161 &sig_buf, attribute_td->pAttributeTypeRef );
162 OString type_sig( sig_buf.makeStringAndClear() );
163 sig_buf.ensureCapacity( 64 );
164 // member name
165 OUString const & member_name =
166 OUString::unacquired(
167 &attribute_td->aBase.pMemberName );
169 // getter
170 sig_buf.append( "()" );
171 sig_buf.append( type_sig );
172 OString method_signature( sig_buf.makeStringAndClear() );
173 OUStringBuffer name_buf( 3 + member_name.getLength() );
174 name_buf.append( "get" );
175 name_buf.append( member_name );
176 OString method_name(
177 OUStringToOString(
178 name_buf.makeStringAndClear(),
179 RTL_TEXTENCODING_JAVA_UTF8 ) );
180 m_methods[ nMethodIndex ] = jni->GetMethodID(
181 (jclass) jo_class.get(), method_name.getStr(),
182 method_signature.getStr() );
183 jni.ensure_no_exception();
184 OSL_ASSERT( 0 != m_methods[ nMethodIndex ] );
185 ++nMethodIndex;
186 if (! attribute_td->bReadOnly)
188 // setter
189 sig_buf.ensureCapacity( 64 );
190 sig_buf.append( '(' );
191 sig_buf.append( type_sig );
192 sig_buf.append( ")V" );
193 method_signature = sig_buf.makeStringAndClear();
194 name_buf.ensureCapacity( 3 + member_name.getLength() );
195 name_buf.append( "set" );
196 name_buf.append( member_name );
197 method_name = OUStringToOString(
198 name_buf.makeStringAndClear(),
199 RTL_TEXTENCODING_JAVA_UTF8 );
200 m_methods[ nMethodIndex ] = jni->GetMethodID(
201 (jclass) jo_class.get(), method_name.getStr(),
202 method_signature.getStr() );
203 jni.ensure_no_exception();
204 OSL_ASSERT( 0 != m_methods[ nMethodIndex ] );
205 ++nMethodIndex;
210 catch (...)
212 delete [] m_methods;
213 throw;
216 m_class = (jclass) jni->NewGlobalRef( jo_class.get() );
217 m_type = jni->NewGlobalRef( jo_type.get() );
218 m_proxy_ctor = jni->NewGlobalRef( jo_proxy_ctor.get() );
222 //______________________________________________________________________________
223 void JNI_compound_type_info::destroy( JNIEnv * jni_env )
225 JNI_type_info::destruct( jni_env );
226 delete [] m_fields;
227 delete this;
230 //______________________________________________________________________________
231 JNI_compound_type_info::JNI_compound_type_info(
232 JNI_context const & jni, typelib_TypeDescription * td_ )
233 : JNI_type_info( jni, td_ ),
234 m_exc_ctor( 0 ),
235 m_fields( 0 )
237 OSL_ASSERT( typelib_TypeClass_STRUCT == m_td.get()->eTypeClass ||
238 typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass );
239 typelib_CompoundTypeDescription * td =
240 reinterpret_cast< typelib_CompoundTypeDescription * >( m_td.get() );
242 OUString const & uno_name =
243 OUString::unacquired( &((typelib_TypeDescription *)td)->pTypeName );
245 // Erase type arguments of instantiated polymorphic struct types:
246 OUString nucleus;
247 sal_Int32 i = uno_name.indexOf( '<' );
248 if ( i < 0 ) {
249 nucleus = uno_name;
250 } else {
251 nucleus = uno_name.copy( 0, i );
253 JLocalAutoRef jo_class(
254 jni,
255 find_class(
256 jni,
257 OUStringToOString(
258 nucleus, RTL_TEXTENCODING_JAVA_UTF8 ).getStr() ) );
260 JNI_info const * jni_info = jni.get_info();
262 if (typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass)
264 // retrieve exc ctor( msg )
265 m_exc_ctor = jni->GetMethodID(
266 (jclass) jo_class.get(), "<init>", "(Ljava/lang/String;)V" );
267 jni.ensure_no_exception();
268 OSL_ASSERT( 0 != m_exc_ctor );
271 // retrieve info for base type
272 typelib_TypeDescription * base_td =
273 type_equals(
274 td->aBase.pWeakRef,
275 jni_info->m_RuntimeException_type.getTypeLibType())
277 : reinterpret_cast< typelib_TypeDescription * >(
278 td->pBaseTypeDescription );
279 m_base = (0 == base_td ? 0 : jni_info->get_type_info( jni, base_td ));
283 if (type_equals(
284 ((typelib_TypeDescription *)td)->pWeakRef,
285 jni_info->m_Exception_type.getTypeLibType() ) ||
286 type_equals(
287 ((typelib_TypeDescription *)td)->pWeakRef,
288 jni_info->m_RuntimeException_type.getTypeLibType() ))
290 m_fields = new jfieldID[ 2 ];
291 m_fields[ 0 ] = 0; // special Throwable.getMessage()
292 // field Context
293 m_fields[ 1 ] = jni->GetFieldID(
294 (jclass) jo_class.get(), "Context", "Ljava/lang/Object;" );
295 jni.ensure_no_exception();
296 OSL_ASSERT( 0 != m_fields[ 1 ] );
298 else
300 // retrieve field ids for all direct members
301 sal_Int32 nMembers = td->nMembers;
302 m_fields = new jfieldID[ nMembers ];
304 for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos )
306 OString sig;
307 if (td->aBase.eTypeClass == typelib_TypeClass_STRUCT
308 && reinterpret_cast< typelib_StructTypeDescription * >(
309 td)->pParameterizedTypes != 0
310 && reinterpret_cast< typelib_StructTypeDescription * >(
311 td)->pParameterizedTypes[nPos])
313 sig = OString( "Ljava/lang/Object;" );
314 } else {
315 OStringBuffer sig_buf( 32 );
316 JNI_info::append_sig( &sig_buf, td->ppTypeRefs[ nPos ] );
317 sig = sig_buf.makeStringAndClear();
320 OString member_name(
321 OUStringToOString(
322 OUString::unacquired( &td->ppMemberNames[ nPos ] ),
323 RTL_TEXTENCODING_JAVA_UTF8 ) );
325 m_fields[ nPos ] = jni->GetFieldID(
326 (jclass) jo_class.get(), member_name.getStr(),
327 sig.getStr() );
328 jni.ensure_no_exception();
329 OSL_ASSERT( 0 != m_fields[ nPos ] );
333 catch (...)
335 delete [] m_fields;
336 throw;
339 m_class = (jclass) jni->NewGlobalRef( jo_class.get() );
343 //______________________________________________________________________________
344 JNI_type_info const * JNI_info::create_type_info(
345 JNI_context const & jni, typelib_TypeDescription * td ) const
347 OUString const & uno_name = OUString::unacquired( &td->pTypeName );
349 JNI_type_info * new_info;
350 switch (td->eTypeClass)
352 case typelib_TypeClass_STRUCT:
353 case typelib_TypeClass_EXCEPTION:
355 new_info = new JNI_compound_type_info( jni, td );
356 break;
358 case typelib_TypeClass_INTERFACE:
360 new_info = new JNI_interface_type_info( jni, td );
361 break;
363 default:
365 OUStringBuffer buf( 128 );
366 buf.append( "type info not supported for " );
367 buf.append( uno_name );
368 buf.append( jni.get_stack_trace() );
369 throw BridgeRuntimeError( buf.makeStringAndClear() );
373 // look up
374 JNI_type_info * info;
375 ClearableMutexGuard guard( m_mutex );
376 JNI_type_info_holder & holder = m_type_map[ uno_name ];
377 if (0 == holder.m_info) // new insertion
379 holder.m_info = new_info;
380 guard.clear();
381 info = new_info;
383 else // inserted in the meantime
385 info = holder.m_info;
386 guard.clear();
387 new_info->destroy( jni.get_jni_env() );
389 return info;
392 //______________________________________________________________________________
393 JNI_type_info const * JNI_info::get_type_info(
394 JNI_context const & jni, typelib_TypeDescription * td ) const
396 if (is_XInterface( td->pWeakRef ))
398 return m_XInterface_type_info;
401 OUString const & uno_name = OUString::unacquired( &td->pTypeName );
402 JNI_type_info const * info;
403 ClearableMutexGuard guard( m_mutex );
405 t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
406 if (iFind == m_type_map.end())
408 guard.clear();
409 info = create_type_info( jni, td );
411 else
413 info = iFind->second.m_info;
416 return info;
419 //______________________________________________________________________________
420 JNI_type_info const * JNI_info::get_type_info(
421 JNI_context const & jni, typelib_TypeDescriptionReference * type ) const
423 if (is_XInterface( type ))
425 return m_XInterface_type_info;
428 OUString const & uno_name = OUString::unacquired( &type->pTypeName );
429 JNI_type_info const * info;
430 ClearableMutexGuard guard( m_mutex );
431 t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
432 if (iFind == m_type_map.end())
434 guard.clear();
435 TypeDescr td( type );
436 info = create_type_info( jni, td.get() );
438 else
440 info = iFind->second.m_info;
443 return info;
446 //______________________________________________________________________________
447 JNI_type_info const * JNI_info::get_type_info(
448 JNI_context const & jni, OUString const & uno_name ) const
450 if ( uno_name == "com.sun.star.uno.XInterface" )
452 return m_XInterface_type_info;
455 JNI_type_info const * info;
456 ClearableMutexGuard guard( m_mutex );
457 t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
458 if (iFind == m_type_map.end())
460 guard.clear();
461 css::uno::TypeDescription td( uno_name );
462 if (! td.is())
464 OUStringBuffer buf( 128 );
465 buf.append( "UNO type not found: " );
466 buf.append( uno_name );
467 buf.append( jni.get_stack_trace() );
468 throw BridgeRuntimeError( buf.makeStringAndClear() );
470 info = create_type_info( jni, td.get() );
472 else
474 info = iFind->second.m_info;
477 return info;
480 //______________________________________________________________________________
481 JNI_info::JNI_info(
482 JNIEnv * jni_env, jobject class_loader, jclass classClass,
483 jmethodID methodForName )
484 : m_class_Class( classClass ),
485 m_method_Class_forName( methodForName ),
486 m_class_JNI_proxy( 0 ),
487 m_XInterface_queryInterface_td(
488 (reinterpret_cast< typelib_InterfaceTypeDescription * >(
489 css::uno::TypeDescription(
490 ::getCppuType(
491 (css::uno::Reference< css::uno::XInterface > const *)0 ) )
492 .get())->ppMembers[ 0 ] ) ),
493 m_Exception_type( ::getCppuType( (css::uno::Exception const *)0 ) ),
494 m_RuntimeException_type(
495 ::getCppuType( (css::uno::RuntimeException const *)0 ) ),
496 m_void_type( ::getCppuVoidType() ),
497 m_XInterface_type_info( 0 )
499 JNI_context jni( this, jni_env, class_loader ); // !no proper jni_info!
501 // class lookup
502 JLocalAutoRef jo_Object(
503 jni, find_class( jni, "java.lang.Object" ) );
504 JLocalAutoRef jo_Class(
505 jni, find_class( jni, "java.lang.Class" ) );
506 JLocalAutoRef jo_Throwable(
507 jni, find_class( jni, "java.lang.Throwable" ) );
508 JLocalAutoRef jo_Character(
509 jni, find_class( jni, "java.lang.Character" ) );
510 JLocalAutoRef jo_Boolean(
511 jni, find_class( jni, "java.lang.Boolean" ) );
512 JLocalAutoRef jo_Byte(
513 jni, find_class( jni, "java.lang.Byte" ) );
514 JLocalAutoRef jo_Short(
515 jni, find_class( jni, "java.lang.Short" ) );
516 JLocalAutoRef jo_Integer(
517 jni, find_class( jni, "java.lang.Integer" ) );
518 JLocalAutoRef jo_Long(
519 jni, find_class( jni, "java.lang.Long" ) );
520 JLocalAutoRef jo_Float(
521 jni, find_class( jni, "java.lang.Float" ) );
522 JLocalAutoRef jo_Double(
523 jni, find_class( jni, "java.lang.Double" ) );
524 JLocalAutoRef jo_String(
525 jni, find_class( jni, "java.lang.String" ) );
526 JLocalAutoRef jo_RuntimeException(
527 jni, find_class( jni, "com.sun.star.uno.RuntimeException" ) );
528 JLocalAutoRef jo_UnoRuntime(
529 jni, find_class( jni, "com.sun.star.uno.UnoRuntime" ) );
530 JLocalAutoRef jo_Any(
531 jni, find_class( jni, "com.sun.star.uno.Any" ) );
532 JLocalAutoRef jo_Enum(
533 jni, find_class( jni, "com.sun.star.uno.Enum" ) );
534 JLocalAutoRef jo_Type(
535 jni, find_class( jni, "com.sun.star.uno.Type" ) );
536 JLocalAutoRef jo_TypeClass(
537 jni, find_class( jni, "com.sun.star.uno.TypeClass" ) );
538 JLocalAutoRef jo_IEnvironment(
539 jni, find_class( jni, "com.sun.star.uno.IEnvironment" ) );
540 JLocalAutoRef jo_JNI_proxy(
541 jni, find_class( jni, "com.sun.star.bridges.jni_uno.JNI_proxy" ) );
543 // method Object.toString()
544 m_method_Object_toString = jni->GetMethodID(
545 (jclass) jo_Object.get(), "toString", "()Ljava/lang/String;" );
546 jni.ensure_no_exception();
547 OSL_ASSERT( 0 != m_method_Object_toString );
548 // method Class.getName()
549 m_method_Class_getName = jni->GetMethodID(
550 (jclass) jo_Class.get(), "getName", "()Ljava/lang/String;" );
551 jni.ensure_no_exception();
552 OSL_ASSERT( 0 != m_method_Class_getName );
554 // method Throwable.getMessage()
555 m_method_Throwable_getMessage = jni->GetMethodID(
556 (jclass) jo_Throwable.get(), "getMessage", "()Ljava/lang/String;" );
557 jni.ensure_no_exception();
558 OSL_ASSERT( 0 != m_method_Throwable_getMessage );
560 // method Character.charValue()
561 m_method_Character_charValue = jni->GetMethodID(
562 (jclass) jo_Character.get(), "charValue", "()C" );
563 jni.ensure_no_exception();
564 OSL_ASSERT( 0 != m_method_Character_charValue );
565 // method Boolean.booleanValue()
566 m_method_Boolean_booleanValue = jni->GetMethodID(
567 (jclass) jo_Boolean.get(), "booleanValue", "()Z" );
568 jni.ensure_no_exception();
569 OSL_ASSERT( 0 != m_method_Boolean_booleanValue );
570 // method Byte.byteValue()
571 m_method_Byte_byteValue = jni->GetMethodID(
572 (jclass) jo_Byte.get(), "byteValue", "()B" );
573 jni.ensure_no_exception();
574 OSL_ASSERT( 0 != m_method_Byte_byteValue );
575 // method Short.shortValue()
576 m_method_Short_shortValue = jni->GetMethodID(
577 (jclass) jo_Short.get(), "shortValue", "()S" );
578 jni.ensure_no_exception();
579 OSL_ASSERT( 0 != m_method_Short_shortValue );
580 // method Integer.intValue()
581 m_method_Integer_intValue = jni->GetMethodID(
582 (jclass) jo_Integer.get(), "intValue", "()I" );
583 jni.ensure_no_exception();
584 OSL_ASSERT( 0 != m_method_Integer_intValue );
585 // method Long.longValue()
586 m_method_Long_longValue = jni->GetMethodID(
587 (jclass) jo_Long.get(), "longValue", "()J" );
588 jni.ensure_no_exception();
589 OSL_ASSERT( 0 != m_method_Long_longValue );
590 // method Float.floatValue()
591 m_method_Float_floatValue = jni->GetMethodID(
592 (jclass) jo_Float.get(), "floatValue", "()F" );
593 jni.ensure_no_exception();
594 OSL_ASSERT( 0 != m_method_Float_floatValue );
595 // method Double.doubleValue()
596 m_method_Double_doubleValue = jni->GetMethodID(
597 (jclass) jo_Double.get(), "doubleValue", "()D" );
598 jni.ensure_no_exception();
599 OSL_ASSERT( 0 != m_method_Double_doubleValue );
601 // ctor Character( char )
602 m_ctor_Character_with_char = jni->GetMethodID(
603 (jclass) jo_Character.get(), "<init>", "(C)V" );
604 jni.ensure_no_exception();
605 OSL_ASSERT( 0 != m_ctor_Character_with_char );
606 // ctor Boolean( boolean )
607 m_ctor_Boolean_with_boolean = jni->GetMethodID(
608 (jclass) jo_Boolean.get(), "<init>", "(Z)V" );
609 jni.ensure_no_exception();
610 OSL_ASSERT( 0 != m_ctor_Boolean_with_boolean );
611 // ctor Byte( byte )
612 m_ctor_Byte_with_byte = jni->GetMethodID(
613 (jclass) jo_Byte.get(), "<init>", "(B)V" );
614 jni.ensure_no_exception();
615 OSL_ASSERT( 0 != m_ctor_Byte_with_byte );
616 // ctor Short( short )
617 m_ctor_Short_with_short = jni->GetMethodID(
618 (jclass) jo_Short.get(), "<init>", "(S)V" );
619 jni.ensure_no_exception();
620 OSL_ASSERT( 0 != m_ctor_Short_with_short );
621 // ctor Integer( int )
622 m_ctor_Integer_with_int = jni->GetMethodID(
623 (jclass) jo_Integer.get(), "<init>", "(I)V" );
624 jni.ensure_no_exception();
625 OSL_ASSERT( 0 != m_ctor_Integer_with_int );
626 // ctor Long( long )
627 m_ctor_Long_with_long = jni->GetMethodID(
628 (jclass) jo_Long.get(), "<init>", "(J)V" );
629 jni.ensure_no_exception();
630 OSL_ASSERT( 0 != m_ctor_Long_with_long );
631 // ctor Float( float )
632 m_ctor_Float_with_float = jni->GetMethodID(
633 (jclass) jo_Float.get(), "<init>", "(F)V" );
634 jni.ensure_no_exception();
635 OSL_ASSERT( 0 != m_ctor_Float_with_float );
636 // ctor Double( double )
637 m_ctor_Double_with_double = jni->GetMethodID(
638 (jclass) jo_Double.get(), "<init>", "(D)V" );
639 jni.ensure_no_exception();
640 OSL_ASSERT( 0 != m_ctor_Double_with_double );
642 // static method UnoRuntime.generateOid()
643 m_method_UnoRuntime_generateOid = jni->GetStaticMethodID(
644 (jclass) jo_UnoRuntime.get(),
645 "generateOid", "(Ljava/lang/Object;)Ljava/lang/String;" );
646 jni.ensure_no_exception();
647 OSL_ASSERT( 0 != m_method_UnoRuntime_generateOid );
648 // static method UnoRuntime.queryInterface()
649 m_method_UnoRuntime_queryInterface = jni->GetStaticMethodID(
650 (jclass) jo_UnoRuntime.get(),
651 "queryInterface",
652 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)Ljava/lang/Object;" );
653 jni.ensure_no_exception();
654 OSL_ASSERT( 0 != m_method_UnoRuntime_queryInterface );
656 // field Enum.m_value
657 m_field_Enum_m_value = jni->GetFieldID(
658 (jclass) jo_Enum.get(), "m_value", "I" );
659 jni.ensure_no_exception();
660 OSL_ASSERT( 0 != m_field_Enum_m_value );
662 // static method TypeClass.fromInt()
663 m_method_TypeClass_fromInt = jni->GetStaticMethodID(
664 (jclass) jo_TypeClass.get(),
665 "fromInt", "(I)Lcom/sun/star/uno/TypeClass;" );
666 jni.ensure_no_exception();
667 OSL_ASSERT( 0 != m_method_TypeClass_fromInt );
669 // ctor Type( Class )
670 m_ctor_Type_with_Class = jni->GetMethodID(
671 (jclass) jo_Type.get(), "<init>", "(Ljava/lang/Class;)V" );
672 jni.ensure_no_exception();
673 OSL_ASSERT( 0 != m_ctor_Type_with_Class );
674 // ctor Type( String, TypeClass )
675 m_ctor_Type_with_Name_TypeClass = jni->GetMethodID(
676 (jclass) jo_Type.get(),
677 "<init>", "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V" );
678 jni.ensure_no_exception();
679 OSL_ASSERT( 0 != m_ctor_Type_with_Name_TypeClass );
680 // field Type._typeName
681 m_field_Type__typeName = jni->GetFieldID(
682 (jclass) jo_Type.get(), "_typeName", "Ljava/lang/String;" );
683 jni.ensure_no_exception();
684 OSL_ASSERT( 0 != m_field_Type__typeName );
686 // ctor Any( Type, Object )
687 m_ctor_Any_with_Type_Object = jni->GetMethodID(
688 (jclass) jo_Any.get(),
689 "<init>", "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V" );
690 jni.ensure_no_exception();
691 OSL_ASSERT( 0 != m_ctor_Any_with_Type_Object );
693 // field Any._type
694 m_field_Any__type = jni->GetFieldID(
695 (jclass) jo_Any.get(), "_type", "Lcom/sun/star/uno/Type;" );
696 jni.ensure_no_exception();
697 OSL_ASSERT( 0 != m_field_Any__type );
698 // field Any._object
699 m_field_Any__object = jni->GetFieldID(
700 (jclass) jo_Any.get(), "_object", "Ljava/lang/Object;" );
701 jni.ensure_no_exception();
702 OSL_ASSERT( 0 != m_field_Any__object );
704 // method IEnvironment.getRegisteredInterface()
705 m_method_IEnvironment_getRegisteredInterface = jni->GetMethodID(
706 (jclass) jo_IEnvironment.get(),
707 "getRegisteredInterface",
708 "(Ljava/lang/String;Lcom/sun/star/uno/Type;)Ljava/lang/Object;" );
709 jni.ensure_no_exception();
710 OSL_ASSERT( 0 != m_method_IEnvironment_getRegisteredInterface );
711 // method IEnvironment.registerInterface()
712 m_method_IEnvironment_registerInterface = jni->GetMethodID(
713 (jclass) jo_IEnvironment.get(), "registerInterface",
714 "(Ljava/lang/Object;[Ljava/lang/String;Lcom/sun/star/uno/Type;)"
715 "Ljava/lang/Object;" );
716 jni.ensure_no_exception();
717 OSL_ASSERT( 0 != m_method_IEnvironment_registerInterface );
719 // static method JNI_proxy.get_proxy_ctor()
720 m_method_JNI_proxy_get_proxy_ctor = jni->GetStaticMethodID(
721 (jclass) jo_JNI_proxy.get(), "get_proxy_ctor",
722 "(Ljava/lang/Class;)Ljava/lang/reflect/Constructor;" );
723 jni.ensure_no_exception();
724 OSL_ASSERT( 0 != m_method_JNI_proxy_get_proxy_ctor );
725 // static method JNI_proxy.create()
726 m_method_JNI_proxy_create = jni->GetStaticMethodID(
727 (jclass) jo_JNI_proxy.get(), "create",
728 "(JLcom/sun/star/uno/IEnvironment;JJLcom/sun/star/uno/Type;Ljava/lang"
729 "/String;Ljava/lang/reflect/Constructor;)Ljava/lang/Object;" );
730 jni.ensure_no_exception();
731 OSL_ASSERT( 0 != m_method_JNI_proxy_create );
732 // field JNI_proxy.m_receiver_handle
733 m_field_JNI_proxy_m_receiver_handle = jni->GetFieldID(
734 (jclass) jo_JNI_proxy.get(), "m_receiver_handle", "J" );
735 jni.ensure_no_exception();
736 OSL_ASSERT( 0 != m_field_JNI_proxy_m_receiver_handle );
737 // field JNI_proxy.m_td_handle
738 m_field_JNI_proxy_m_td_handle = jni->GetFieldID(
739 (jclass) jo_JNI_proxy.get(), "m_td_handle", "J" );
740 jni.ensure_no_exception();
741 OSL_ASSERT( 0 != m_field_JNI_proxy_m_td_handle );
742 // field JNI_proxy.m_type
743 m_field_JNI_proxy_m_type = jni->GetFieldID(
744 (jclass) jo_JNI_proxy.get(), "m_type", "Lcom/sun/star/uno/Type;" );
745 jni.ensure_no_exception();
746 OSL_ASSERT( 0 != m_field_JNI_proxy_m_type );
747 // field JNI_proxy.m_oid
748 m_field_JNI_proxy_m_oid = jni->GetFieldID(
749 (jclass) jo_JNI_proxy.get(), "m_oid", "Ljava/lang/String;" );
750 jni.ensure_no_exception();
751 OSL_ASSERT( 0 != m_field_JNI_proxy_m_oid );
753 // get java env
754 OUString java_env_type_name( UNO_LB_JAVA );
755 JLocalAutoRef jo_java(
756 jni, ustring_to_jstring( jni, java_env_type_name.pData ) );
757 jvalue args[ 2 ];
758 args[ 0 ].l = jo_java.get();
759 args[ 1 ].l = 0;
760 jmethodID method_getEnvironment = jni->GetStaticMethodID(
761 (jclass) jo_UnoRuntime.get(), "getEnvironment",
762 "(Ljava/lang/String;Ljava/lang/Object;)"
763 "Lcom/sun/star/uno/IEnvironment;" );
764 jni.ensure_no_exception();
765 OSL_ASSERT( 0 != method_getEnvironment );
766 JLocalAutoRef jo_java_env(
767 jni, jni->CallStaticObjectMethodA(
768 (jclass) jo_UnoRuntime.get(), method_getEnvironment, args ) );
770 // get com.sun.star.uno.Any.VOID
771 jfieldID field_Any_VOID = jni->GetStaticFieldID(
772 (jclass) jo_Any.get(), "VOID", "Lcom/sun/star/uno/Any;" );
773 jni.ensure_no_exception();
774 OSL_ASSERT( 0 != field_Any_VOID );
775 JLocalAutoRef jo_Any_VOID(
776 jni, jni->GetStaticObjectField(
777 (jclass) jo_Any.get(), field_Any_VOID ) );
778 // get com.sun.star.uno.Type.UNSIGNED_SHORT
779 jfieldID field_Type_UNSIGNED_SHORT = jni->GetStaticFieldID(
780 (jclass) jo_Type.get(), "UNSIGNED_SHORT", "Lcom/sun/star/uno/Type;" );
781 jni.ensure_no_exception();
782 OSL_ASSERT( 0 != field_Type_UNSIGNED_SHORT );
783 JLocalAutoRef jo_Type_UNSIGNED_SHORT(
784 jni, jni->GetStaticObjectField(
785 (jclass) jo_Type.get(), field_Type_UNSIGNED_SHORT ) );
786 // get com.sun.star.uno.Type.UNSIGNED_LONG
787 jfieldID field_Type_UNSIGNED_LONG = jni->GetStaticFieldID(
788 (jclass) jo_Type.get(), "UNSIGNED_LONG", "Lcom/sun/star/uno/Type;" );
789 jni.ensure_no_exception();
790 OSL_ASSERT( 0 != field_Type_UNSIGNED_LONG );
791 JLocalAutoRef jo_Type_UNSIGNED_LONG(
792 jni, jni->GetStaticObjectField(
793 (jclass) jo_Type.get(), field_Type_UNSIGNED_LONG ) );
794 // get com.sun.star.uno.Type.UNSIGNED_HYPER
795 jfieldID field_Type_UNSIGNED_HYPER = jni->GetStaticFieldID(
796 (jclass) jo_Type.get(), "UNSIGNED_HYPER", "Lcom/sun/star/uno/Type;" );
797 jni.ensure_no_exception();
798 OSL_ASSERT( 0 != field_Type_UNSIGNED_HYPER );
799 JLocalAutoRef jo_Type_UNSIGNED_HYPER(
800 jni, jni->GetStaticObjectField(
801 (jclass) jo_Type.get(), field_Type_UNSIGNED_HYPER ) );
803 // make global refs
804 m_class_UnoRuntime =
805 (jclass) jni->NewGlobalRef( jo_UnoRuntime.get() );
806 m_class_RuntimeException =
807 (jclass) jni->NewGlobalRef( jo_RuntimeException.get() );
808 m_class_Any =
809 (jclass) jni->NewGlobalRef( jo_Any.get() );
810 m_class_Type =
811 (jclass) jni->NewGlobalRef( jo_Type.get() );
812 m_class_TypeClass =
813 (jclass) jni->NewGlobalRef( jo_TypeClass.get() );
814 m_class_JNI_proxy =
815 (jclass) jni->NewGlobalRef( jo_JNI_proxy.get() );
817 m_class_Character =
818 (jclass) jni->NewGlobalRef( jo_Character.get() );
819 m_class_Boolean =
820 (jclass) jni->NewGlobalRef( jo_Boolean.get() );
821 m_class_Byte =
822 (jclass) jni->NewGlobalRef( jo_Byte.get() );
823 m_class_Short =
824 (jclass) jni->NewGlobalRef( jo_Short.get() );
825 m_class_Integer =
826 (jclass) jni->NewGlobalRef( jo_Integer.get() );
827 m_class_Long =
828 (jclass) jni->NewGlobalRef( jo_Long.get() );
829 m_class_Float =
830 (jclass) jni->NewGlobalRef( jo_Float.get() );
831 m_class_Double =
832 (jclass) jni->NewGlobalRef( jo_Double.get() );
833 m_class_String =
834 (jclass) jni->NewGlobalRef( jo_String.get() );
835 m_class_Object =
836 (jclass) jni->NewGlobalRef( jo_Object.get() );
837 m_class_Class =
838 (jclass) jni->NewGlobalRef( m_class_Class );
840 m_object_Any_VOID =
841 jni->NewGlobalRef( jo_Any_VOID.get() );
842 m_object_Type_UNSIGNED_SHORT =
843 jni->NewGlobalRef( jo_Type_UNSIGNED_SHORT.get() );
844 m_object_Type_UNSIGNED_LONG =
845 jni->NewGlobalRef( jo_Type_UNSIGNED_LONG.get() );
846 m_object_Type_UNSIGNED_HYPER =
847 jni->NewGlobalRef( jo_Type_UNSIGNED_HYPER.get() );
848 m_object_java_env = jni->NewGlobalRef( jo_java_env.get() );
852 css::uno::TypeDescription XInterface_td(
853 ::getCppuType(
854 (css::uno::Reference< css::uno::XInterface > const *)0 ) );
855 m_XInterface_type_info =
856 new JNI_interface_type_info( jni, XInterface_td.get() );
858 catch (...)
860 destruct( jni_env );
861 throw;
865 //______________________________________________________________________________
866 void JNI_info::destruct( JNIEnv * jni_env )
868 t_str2type::const_iterator iPos( m_type_map.begin() );
869 t_str2type::const_iterator const iEnd( m_type_map.begin() );
870 for ( ; iPos != iEnd; ++iPos )
872 iPos->second.m_info->destroy( jni_env );
874 if (0 != m_XInterface_type_info)
876 const_cast< JNI_interface_type_info * >(
877 m_XInterface_type_info )->destroy( jni_env );
880 // free global refs
881 jni_env->DeleteGlobalRef( m_object_java_env );
882 jni_env->DeleteGlobalRef( m_object_Any_VOID );
883 jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_SHORT );
884 jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_LONG );
885 jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_HYPER );
887 jni_env->DeleteGlobalRef( m_class_Class );
888 jni_env->DeleteGlobalRef( m_class_Object );
889 jni_env->DeleteGlobalRef( m_class_String );
890 jni_env->DeleteGlobalRef( m_class_Double );
891 jni_env->DeleteGlobalRef( m_class_Float );
892 jni_env->DeleteGlobalRef( m_class_Long );
893 jni_env->DeleteGlobalRef( m_class_Integer );
894 jni_env->DeleteGlobalRef( m_class_Short );
895 jni_env->DeleteGlobalRef( m_class_Byte );
896 jni_env->DeleteGlobalRef( m_class_Boolean );
897 jni_env->DeleteGlobalRef( m_class_Character );
899 jni_env->DeleteGlobalRef( m_class_JNI_proxy );
900 jni_env->DeleteGlobalRef( m_class_RuntimeException );
901 jni_env->DeleteGlobalRef( m_class_UnoRuntime );
902 jni_env->DeleteGlobalRef( m_class_TypeClass );
903 jni_env->DeleteGlobalRef( m_class_Type );
904 jni_env->DeleteGlobalRef( m_class_Any );
907 //______________________________________________________________________________
908 JNI_info const * JNI_info::get_jni_info(
909 rtl::Reference< jvmaccess::UnoVirtualMachine > const & uno_vm )
911 // !!!no JNI_info available at JNI_context!!!
912 ::jvmaccess::VirtualMachine::AttachGuard guard(
913 uno_vm->getVirtualMachine() );
914 JNIEnv * jni_env = guard.getEnvironment();
915 JNI_context jni(
916 0, jni_env, static_cast< jobject >(uno_vm->getClassLoader()) );
918 jclass jo_class;
919 jmethodID jo_forName;
920 jni.getClassForName( &jo_class, &jo_forName );
921 jni.ensure_no_exception();
922 JLocalAutoRef jo_JNI_info_holder(
923 jni,
924 jni.findClass(
925 "com.sun.star.bridges.jni_uno.JNI_info_holder", jo_class,
926 jo_forName, false ) );
927 // field JNI_info_holder.m_jni_info_handle
928 jfieldID field_s_jni_info_handle =
929 jni->GetStaticFieldID(
930 (jclass) jo_JNI_info_holder.get(), "s_jni_info_handle", "J" );
931 jni.ensure_no_exception();
932 OSL_ASSERT( 0 != field_s_jni_info_handle );
934 JNI_info const * jni_info =
935 reinterpret_cast< JNI_info const * >(
936 jni->GetStaticLongField(
937 (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle ) );
938 if (0 == jni_info) // un-initialized?
940 JNI_info * new_info = new JNI_info(
941 jni_env, static_cast< jobject >(uno_vm->getClassLoader()), jo_class,
942 jo_forName );
944 ClearableMutexGuard g( Mutex::getGlobalMutex() );
945 jni_info =
946 reinterpret_cast< JNI_info const * >(
947 jni->GetStaticLongField(
948 (jclass) jo_JNI_info_holder.get(),
949 field_s_jni_info_handle ) );
950 if (0 == jni_info) // still un-initialized?
952 jni->SetStaticLongField(
953 (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle,
954 reinterpret_cast< jlong >( new_info ) );
955 jni_info = new_info;
957 else
959 g.clear();
960 new_info->destroy( jni_env );
964 return jni_info;
969 extern "C"
972 //------------------------------------------------------------------------------
973 SAL_JNI_EXPORT void
974 JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J(
975 JNIEnv * jni_env, SAL_UNUSED_PARAMETER jobject, jlong jni_info_handle )
976 SAL_THROW_EXTERN_C()
978 ::jni_uno::JNI_info * jni_info =
979 reinterpret_cast< ::jni_uno::JNI_info * >( jni_info_handle );
980 jni_info->destroy( jni_env );
985 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */