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