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 //______________________________________________________________________________
JNI_type_info(JNI_context const & jni,typelib_TypeDescription * td)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 //______________________________________________________________________________
destroy(JNIEnv * jni_env)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 //______________________________________________________________________________
JNI_interface_type_info(JNI_context const & jni,typelib_TypeDescription * td_)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 //______________________________________________________________________________
destroy(JNIEnv * jni_env)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 //______________________________________________________________________________
JNI_compound_type_info(JNI_context const & jni,typelib_TypeDescription * td_)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 //______________________________________________________________________________
create_type_info(JNI_context const & jni,typelib_TypeDescription * td) const350 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 //______________________________________________________________________________
get_type_info(JNI_context const & jni,typelib_TypeDescription * td) const400 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 //______________________________________________________________________________
get_type_info(JNI_context const & jni,typelib_TypeDescriptionReference * type) const427 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 //______________________________________________________________________________
get_type_info(JNI_context const & jni,OUString const & uno_name) const454 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 //______________________________________________________________________________
JNI_info(JNIEnv * jni_env,jobject class_loader,jclass classClass,jmethodID methodForName)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 //______________________________________________________________________________
destruct(JNIEnv * jni_env)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 //______________________________________________________________________________
get_jni_info(rtl::Reference<jvmaccess::UnoVirtualMachine> const & uno_vm)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
Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J(JNIEnv * jni_env,jobject,jlong jni_info_handle)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