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