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