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 : using namespace ::rtl;
39 :
40 : namespace jni_uno
41 : {
42 :
43 :
44 40 : JNI_type_info::JNI_type_info(
45 : JNI_context const & jni, typelib_TypeDescription * td )
46 : : m_td( td ),
47 40 : m_class( 0 )
48 : {
49 40 : m_td.makeComplete();
50 40 : if (! m_td.get()->bComplete)
51 : {
52 : throw BridgeRuntimeError(
53 : "cannot make type complete: "
54 0 : + OUString::unacquired( &m_td.get()->pTypeName )
55 0 : + jni.get_stack_trace() );
56 : }
57 40 : }
58 :
59 :
60 :
61 0 : void JNI_interface_type_info::destroy( JNIEnv * jni_env )
62 : {
63 0 : JNI_type_info::destruct( jni_env );
64 0 : jni_env->DeleteGlobalRef( m_proxy_ctor );
65 0 : jni_env->DeleteGlobalRef( m_type );
66 0 : delete [] m_methods;
67 0 : delete this;
68 0 : }
69 :
70 :
71 38 : JNI_interface_type_info::JNI_interface_type_info(
72 : JNI_context const & jni, typelib_TypeDescription * td_ )
73 38 : : JNI_type_info( jni, td_ )
74 : {
75 : assert( typelib_TypeClass_INTERFACE == m_td.get()->eTypeClass );
76 :
77 38 : OUString const & uno_name = OUString::unacquired( &m_td.get()->pTypeName );
78 38 : JNI_info const * jni_info = jni.get_info();
79 :
80 : JLocalAutoRef jo_class(
81 : jni,
82 : find_class(
83 : jni,
84 : ( OUStringToOString( uno_name, RTL_TEXTENCODING_JAVA_UTF8 ).
85 38 : getStr() ) ) );
86 76 : JLocalAutoRef jo_type( jni, create_type( jni, (jclass) jo_class.get() ) );
87 :
88 : // get proxy ctor
89 : jvalue arg;
90 38 : arg.l = jo_class.get();
91 : JLocalAutoRef jo_proxy_ctor(
92 : jni, jni->CallStaticObjectMethodA(
93 : jni_info->m_class_JNI_proxy,
94 76 : jni_info->m_method_JNI_proxy_get_proxy_ctor, &arg ) );
95 :
96 38 : if (is_XInterface( m_td.get()->pWeakRef ))
97 : {
98 3 : m_methods = 0; // no methods
99 : }
100 : else
101 : {
102 : // retrieve method ids for all direct members
103 : try
104 : {
105 : typelib_InterfaceTypeDescription * td =
106 : reinterpret_cast< typelib_InterfaceTypeDescription * >(
107 35 : m_td.get() );
108 35 : m_methods = new jmethodID[ td->nMapFunctionIndexToMemberIndex ];
109 35 : sal_Int32 nMethodIndex = 0;
110 35 : typelib_TypeDescriptionReference ** ppMembers = td->ppMembers;
111 35 : sal_Int32 nMembers = td->nMembers;
112 :
113 150 : for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos )
114 : {
115 115 : TypeDescr member_td( ppMembers[ nPos ] );
116 :
117 230 : OStringBuffer sig_buf( 64 );
118 :
119 115 : if (typelib_TypeClass_INTERFACE_METHOD ==
120 115 : member_td.get()->eTypeClass) // method
121 : {
122 : typelib_InterfaceMethodTypeDescription * method_td =
123 : reinterpret_cast<
124 : typelib_InterfaceMethodTypeDescription * >(
125 114 : member_td.get() );
126 :
127 114 : sig_buf.append( '(' );
128 238 : for ( sal_Int32 i = 0; i < method_td->nParams; ++i )
129 : {
130 : typelib_MethodParameter const & param =
131 124 : method_td->pParams[ i ];
132 124 : if (param.bOut)
133 4 : sig_buf.append( '[' );
134 124 : JNI_info::append_sig( &sig_buf, param.pTypeRef );
135 : }
136 114 : sig_buf.append( ')' );
137 114 : JNI_info::append_sig( &sig_buf, method_td->pReturnTypeRef );
138 :
139 114 : OString method_signature( sig_buf.makeStringAndClear() );
140 : OString method_name(
141 : OUStringToOString( OUString::unacquired(
142 114 : &method_td->aBase.pMemberName ),
143 228 : RTL_TEXTENCODING_JAVA_UTF8 ) );
144 :
145 114 : m_methods[ nMethodIndex ] = jni->GetMethodID(
146 114 : (jclass) jo_class.get(), method_name.getStr(),
147 228 : method_signature.getStr() );
148 114 : jni.ensure_no_exception();
149 : assert( 0 != m_methods[ nMethodIndex ] );
150 228 : ++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 : (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 : (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 115 : }
212 : }
213 0 : catch (...)
214 : {
215 0 : delete [] m_methods;
216 0 : throw;
217 : }
218 : }
219 38 : m_class = (jclass) jni->NewGlobalRef( jo_class.get() );
220 38 : m_type = jni->NewGlobalRef( jo_type.get() );
221 76 : m_proxy_ctor = jni->NewGlobalRef( jo_proxy_ctor.get() );
222 38 : }
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( &((typelib_TypeDescription *)td)->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 : (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 : ((typelib_TypeDescription *)td)->pWeakRef,
288 3 : jni_info->m_Exception_type.getTypeLibType() ) ||
289 : type_equals(
290 : ((typelib_TypeDescription *)td)->pWeakRef,
291 1 : jni_info->m_RuntimeException_type.getTypeLibType() ))
292 : {
293 1 : m_fields = new jfieldID[ 2 ];
294 1 : m_fields[ 0 ] = 0; // special Throwable.getMessage()
295 : // field Context
296 1 : m_fields[ 1 ] = jni->GetFieldID(
297 1 : (jclass) jo_class.get(), "Context", "Ljava/lang/Object;" );
298 1 : jni.ensure_no_exception();
299 : assert( 0 != m_fields[ 1 ] );
300 : }
301 : else
302 : {
303 : // retrieve field ids for all direct members
304 1 : sal_Int32 nMembers = td->nMembers;
305 1 : m_fields = new jfieldID[ nMembers ];
306 :
307 2 : for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos )
308 : {
309 1 : OString sig;
310 1 : if (td->aBase.eTypeClass == typelib_TypeClass_STRUCT
311 0 : && reinterpret_cast< typelib_StructTypeDescription * >(
312 0 : td)->pParameterizedTypes != 0
313 0 : && reinterpret_cast< typelib_StructTypeDescription * >(
314 0 : td)->pParameterizedTypes[nPos])
315 : {
316 0 : sig = OString( "Ljava/lang/Object;" );
317 : } else {
318 1 : OStringBuffer sig_buf( 32 );
319 1 : JNI_info::append_sig( &sig_buf, td->ppTypeRefs[ nPos ] );
320 1 : sig = sig_buf.makeStringAndClear();
321 : }
322 :
323 : OString member_name(
324 : OUStringToOString(
325 1 : OUString::unacquired( &td->ppMemberNames[ nPos ] ),
326 2 : RTL_TEXTENCODING_JAVA_UTF8 ) );
327 :
328 1 : m_fields[ nPos ] = jni->GetFieldID(
329 1 : (jclass) jo_class.get(), member_name.getStr(),
330 2 : sig.getStr() );
331 1 : jni.ensure_no_exception();
332 : assert( 0 != m_fields[ nPos ] );
333 1 : }
334 : }
335 : }
336 0 : catch (...)
337 : {
338 0 : delete [] m_fields;
339 0 : throw;
340 : }
341 :
342 4 : m_class = (jclass) jni->NewGlobalRef( jo_class.get() );
343 2 : }
344 :
345 :
346 :
347 37 : JNI_type_info const * JNI_info::create_type_info(
348 : JNI_context const & jni, typelib_TypeDescription * td ) const
349 : {
350 37 : OUString const & uno_name = OUString::unacquired( &td->pTypeName );
351 :
352 : JNI_type_info * new_info;
353 37 : switch (td->eTypeClass)
354 : {
355 : case typelib_TypeClass_STRUCT:
356 : case typelib_TypeClass_EXCEPTION:
357 : {
358 2 : new_info = new JNI_compound_type_info( jni, td );
359 2 : break;
360 : }
361 : case typelib_TypeClass_INTERFACE:
362 : {
363 35 : new_info = new JNI_interface_type_info( jni, td );
364 35 : break;
365 : }
366 : default:
367 : {
368 : throw BridgeRuntimeError(
369 0 : "type info not supported for " + uno_name + jni.get_stack_trace() );
370 : }
371 : }
372 :
373 : // look up
374 : JNI_type_info * info;
375 37 : ClearableMutexGuard guard( m_mutex );
376 37 : JNI_type_info_holder & holder = m_type_map[ uno_name ];
377 37 : if (0 == holder.m_info) // new insertion
378 : {
379 37 : holder.m_info = new_info;
380 37 : guard.clear();
381 37 : 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 37 : return info;
390 : }
391 :
392 :
393 54 : JNI_type_info const * JNI_info::get_type_info(
394 : JNI_context const & jni, typelib_TypeDescription * td ) const
395 : {
396 54 : if (is_XInterface( td->pWeakRef ))
397 : {
398 0 : return m_XInterface_type_info;
399 : }
400 :
401 54 : OUString const & uno_name = OUString::unacquired( &td->pTypeName );
402 : JNI_type_info const * info;
403 54 : ClearableMutexGuard guard( m_mutex );
404 :
405 54 : t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
406 54 : if (iFind == m_type_map.end())
407 : {
408 18 : guard.clear();
409 18 : info = create_type_info( jni, td );
410 : }
411 : else
412 : {
413 36 : info = iFind->second.m_info;
414 : }
415 :
416 54 : return info;
417 : }
418 :
419 :
420 38 : JNI_type_info const * JNI_info::get_type_info(
421 : JNI_context const & jni, typelib_TypeDescriptionReference * type ) const
422 : {
423 38 : if (is_XInterface( type ))
424 : {
425 7 : return m_XInterface_type_info;
426 : }
427 :
428 31 : OUString const & uno_name = OUString::unacquired( &type->pTypeName );
429 : JNI_type_info const * info;
430 31 : ClearableMutexGuard guard( m_mutex );
431 31 : t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
432 31 : if (iFind == m_type_map.end())
433 : {
434 13 : guard.clear();
435 13 : TypeDescr td( type );
436 13 : info = create_type_info( jni, td.get() );
437 : }
438 : else
439 : {
440 18 : info = iFind->second.m_info;
441 : }
442 :
443 31 : return info;
444 : }
445 :
446 :
447 6 : JNI_type_info const * JNI_info::get_type_info(
448 : JNI_context const & jni, OUString const & uno_name ) const
449 : {
450 6 : 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 6 : ClearableMutexGuard guard( m_mutex );
457 6 : t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
458 6 : if (iFind == m_type_map.end())
459 : {
460 6 : guard.clear();
461 6 : css::uno::TypeDescription td( uno_name );
462 6 : if (! td.is())
463 : {
464 : throw BridgeRuntimeError(
465 0 : "UNO type not found: " + uno_name + jni.get_stack_trace() );
466 : }
467 6 : info = create_type_info( jni, td.get() );
468 : }
469 : else
470 : {
471 0 : info = iFind->second.m_info;
472 : }
473 :
474 6 : return info;
475 : }
476 :
477 :
478 3 : JNI_info::JNI_info(
479 : JNIEnv * jni_env, jobject class_loader, jclass classClass,
480 : jmethodID methodForName )
481 : : m_class_Class( classClass ),
482 : m_method_Class_forName( methodForName ),
483 : m_class_JNI_proxy( 0 ),
484 : m_XInterface_queryInterface_td(
485 : (reinterpret_cast< typelib_InterfaceTypeDescription * >(
486 : css::uno::TypeDescription(
487 : ::getCppuType(
488 3 : (css::uno::Reference< css::uno::XInterface > const *)0 ) )
489 6 : .get())->ppMembers[ 0 ] ) ),
490 3 : m_Exception_type( ::getCppuType( (css::uno::Exception const *)0 ) ),
491 : m_RuntimeException_type(
492 3 : ::getCppuType( (css::uno::RuntimeException const *)0 ) ),
493 3 : m_void_type( ::getCppuVoidType() ),
494 15 : m_XInterface_type_info( 0 )
495 : {
496 3 : JNI_context jni( this, jni_env, class_loader ); // !no proper jni_info!
497 :
498 : // class lookup
499 : JLocalAutoRef jo_Object(
500 3 : jni, find_class( jni, "java.lang.Object" ) );
501 : JLocalAutoRef jo_Class(
502 6 : jni, find_class( jni, "java.lang.Class" ) );
503 : JLocalAutoRef jo_Throwable(
504 6 : jni, find_class( jni, "java.lang.Throwable" ) );
505 : JLocalAutoRef jo_Character(
506 6 : jni, find_class( jni, "java.lang.Character" ) );
507 : JLocalAutoRef jo_Boolean(
508 6 : jni, find_class( jni, "java.lang.Boolean" ) );
509 : JLocalAutoRef jo_Byte(
510 6 : jni, find_class( jni, "java.lang.Byte" ) );
511 : JLocalAutoRef jo_Short(
512 6 : jni, find_class( jni, "java.lang.Short" ) );
513 : JLocalAutoRef jo_Integer(
514 6 : jni, find_class( jni, "java.lang.Integer" ) );
515 : JLocalAutoRef jo_Long(
516 6 : jni, find_class( jni, "java.lang.Long" ) );
517 : JLocalAutoRef jo_Float(
518 6 : jni, find_class( jni, "java.lang.Float" ) );
519 : JLocalAutoRef jo_Double(
520 6 : jni, find_class( jni, "java.lang.Double" ) );
521 : JLocalAutoRef jo_String(
522 6 : jni, find_class( jni, "java.lang.String" ) );
523 : JLocalAutoRef jo_RuntimeException(
524 6 : jni, find_class( jni, "com.sun.star.uno.RuntimeException" ) );
525 : JLocalAutoRef jo_UnoRuntime(
526 6 : jni, find_class( jni, "com.sun.star.uno.UnoRuntime" ) );
527 : JLocalAutoRef jo_Any(
528 6 : jni, find_class( jni, "com.sun.star.uno.Any" ) );
529 : JLocalAutoRef jo_Enum(
530 6 : jni, find_class( jni, "com.sun.star.uno.Enum" ) );
531 : JLocalAutoRef jo_Type(
532 6 : jni, find_class( jni, "com.sun.star.uno.Type" ) );
533 : JLocalAutoRef jo_TypeClass(
534 6 : jni, find_class( jni, "com.sun.star.uno.TypeClass" ) );
535 : JLocalAutoRef jo_IEnvironment(
536 6 : jni, find_class( jni, "com.sun.star.uno.IEnvironment" ) );
537 : JLocalAutoRef jo_JNI_proxy(
538 6 : jni, find_class( jni, "com.sun.star.bridges.jni_uno.JNI_proxy" ) );
539 :
540 : // method Object.toString()
541 : m_method_Object_toString = jni->GetMethodID(
542 3 : (jclass) jo_Object.get(), "toString", "()Ljava/lang/String;" );
543 3 : jni.ensure_no_exception();
544 : assert( 0 != m_method_Object_toString );
545 : // method Class.getName()
546 : m_method_Class_getName = jni->GetMethodID(
547 3 : (jclass) jo_Class.get(), "getName", "()Ljava/lang/String;" );
548 3 : jni.ensure_no_exception();
549 : assert( 0 != m_method_Class_getName );
550 :
551 : // method Throwable.getMessage()
552 : m_method_Throwable_getMessage = jni->GetMethodID(
553 3 : (jclass) jo_Throwable.get(), "getMessage", "()Ljava/lang/String;" );
554 3 : jni.ensure_no_exception();
555 : assert( 0 != m_method_Throwable_getMessage );
556 :
557 : // method Character.charValue()
558 : m_method_Character_charValue = jni->GetMethodID(
559 3 : (jclass) jo_Character.get(), "charValue", "()C" );
560 3 : jni.ensure_no_exception();
561 : assert( 0 != m_method_Character_charValue );
562 : // method Boolean.booleanValue()
563 : m_method_Boolean_booleanValue = jni->GetMethodID(
564 3 : (jclass) jo_Boolean.get(), "booleanValue", "()Z" );
565 3 : jni.ensure_no_exception();
566 : assert( 0 != m_method_Boolean_booleanValue );
567 : // method Byte.byteValue()
568 : m_method_Byte_byteValue = jni->GetMethodID(
569 3 : (jclass) jo_Byte.get(), "byteValue", "()B" );
570 3 : jni.ensure_no_exception();
571 : assert( 0 != m_method_Byte_byteValue );
572 : // method Short.shortValue()
573 : m_method_Short_shortValue = jni->GetMethodID(
574 3 : (jclass) jo_Short.get(), "shortValue", "()S" );
575 3 : jni.ensure_no_exception();
576 : assert( 0 != m_method_Short_shortValue );
577 : // method Integer.intValue()
578 : m_method_Integer_intValue = jni->GetMethodID(
579 3 : (jclass) jo_Integer.get(), "intValue", "()I" );
580 3 : jni.ensure_no_exception();
581 : assert( 0 != m_method_Integer_intValue );
582 : // method Long.longValue()
583 : m_method_Long_longValue = jni->GetMethodID(
584 3 : (jclass) jo_Long.get(), "longValue", "()J" );
585 3 : jni.ensure_no_exception();
586 : assert( 0 != m_method_Long_longValue );
587 : // method Float.floatValue()
588 : m_method_Float_floatValue = jni->GetMethodID(
589 3 : (jclass) jo_Float.get(), "floatValue", "()F" );
590 3 : jni.ensure_no_exception();
591 : assert( 0 != m_method_Float_floatValue );
592 : // method Double.doubleValue()
593 : m_method_Double_doubleValue = jni->GetMethodID(
594 3 : (jclass) jo_Double.get(), "doubleValue", "()D" );
595 3 : jni.ensure_no_exception();
596 : assert( 0 != m_method_Double_doubleValue );
597 :
598 : // ctor Character( char )
599 : m_ctor_Character_with_char = jni->GetMethodID(
600 3 : (jclass) jo_Character.get(), "<init>", "(C)V" );
601 3 : jni.ensure_no_exception();
602 : assert( 0 != m_ctor_Character_with_char );
603 : // ctor Boolean( boolean )
604 : m_ctor_Boolean_with_boolean = jni->GetMethodID(
605 3 : (jclass) jo_Boolean.get(), "<init>", "(Z)V" );
606 3 : jni.ensure_no_exception();
607 : assert( 0 != m_ctor_Boolean_with_boolean );
608 : // ctor Byte( byte )
609 : m_ctor_Byte_with_byte = jni->GetMethodID(
610 3 : (jclass) jo_Byte.get(), "<init>", "(B)V" );
611 3 : jni.ensure_no_exception();
612 : assert( 0 != m_ctor_Byte_with_byte );
613 : // ctor Short( short )
614 : m_ctor_Short_with_short = jni->GetMethodID(
615 3 : (jclass) jo_Short.get(), "<init>", "(S)V" );
616 3 : jni.ensure_no_exception();
617 : assert( 0 != m_ctor_Short_with_short );
618 : // ctor Integer( int )
619 : m_ctor_Integer_with_int = jni->GetMethodID(
620 3 : (jclass) jo_Integer.get(), "<init>", "(I)V" );
621 3 : jni.ensure_no_exception();
622 : assert( 0 != m_ctor_Integer_with_int );
623 : // ctor Long( long )
624 : m_ctor_Long_with_long = jni->GetMethodID(
625 3 : (jclass) jo_Long.get(), "<init>", "(J)V" );
626 3 : jni.ensure_no_exception();
627 : assert( 0 != m_ctor_Long_with_long );
628 : // ctor Float( float )
629 : m_ctor_Float_with_float = jni->GetMethodID(
630 3 : (jclass) jo_Float.get(), "<init>", "(F)V" );
631 3 : jni.ensure_no_exception();
632 : assert( 0 != m_ctor_Float_with_float );
633 : // ctor Double( double )
634 : m_ctor_Double_with_double = jni->GetMethodID(
635 3 : (jclass) jo_Double.get(), "<init>", "(D)V" );
636 3 : jni.ensure_no_exception();
637 : assert( 0 != m_ctor_Double_with_double );
638 :
639 : // static method UnoRuntime.generateOid()
640 : m_method_UnoRuntime_generateOid = jni->GetStaticMethodID(
641 3 : (jclass) jo_UnoRuntime.get(),
642 3 : "generateOid", "(Ljava/lang/Object;)Ljava/lang/String;" );
643 3 : jni.ensure_no_exception();
644 : assert( 0 != m_method_UnoRuntime_generateOid );
645 : // static method UnoRuntime.queryInterface()
646 : m_method_UnoRuntime_queryInterface = jni->GetStaticMethodID(
647 3 : (jclass) jo_UnoRuntime.get(),
648 : "queryInterface",
649 3 : "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)Ljava/lang/Object;" );
650 3 : jni.ensure_no_exception();
651 : assert( 0 != m_method_UnoRuntime_queryInterface );
652 :
653 : // field Enum.m_value
654 : m_field_Enum_m_value = jni->GetFieldID(
655 3 : (jclass) jo_Enum.get(), "m_value", "I" );
656 3 : jni.ensure_no_exception();
657 : assert( 0 != m_field_Enum_m_value );
658 :
659 : // static method TypeClass.fromInt()
660 : m_method_TypeClass_fromInt = jni->GetStaticMethodID(
661 3 : (jclass) jo_TypeClass.get(),
662 3 : "fromInt", "(I)Lcom/sun/star/uno/TypeClass;" );
663 3 : jni.ensure_no_exception();
664 : assert( 0 != m_method_TypeClass_fromInt );
665 :
666 : // ctor Type( Class )
667 : m_ctor_Type_with_Class = jni->GetMethodID(
668 3 : (jclass) jo_Type.get(), "<init>", "(Ljava/lang/Class;)V" );
669 3 : jni.ensure_no_exception();
670 : assert( 0 != m_ctor_Type_with_Class );
671 : // ctor Type( String, TypeClass )
672 : m_ctor_Type_with_Name_TypeClass = jni->GetMethodID(
673 3 : (jclass) jo_Type.get(),
674 3 : "<init>", "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V" );
675 3 : jni.ensure_no_exception();
676 : assert( 0 != m_ctor_Type_with_Name_TypeClass );
677 : // field Type._typeName
678 : m_field_Type__typeName = jni->GetFieldID(
679 3 : (jclass) jo_Type.get(), "_typeName", "Ljava/lang/String;" );
680 3 : jni.ensure_no_exception();
681 : assert( 0 != m_field_Type__typeName );
682 :
683 : // ctor Any( Type, Object )
684 : m_ctor_Any_with_Type_Object = jni->GetMethodID(
685 3 : (jclass) jo_Any.get(),
686 3 : "<init>", "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V" );
687 3 : jni.ensure_no_exception();
688 : assert( 0 != m_ctor_Any_with_Type_Object );
689 :
690 : // field Any._type
691 : m_field_Any__type = jni->GetFieldID(
692 3 : (jclass) jo_Any.get(), "_type", "Lcom/sun/star/uno/Type;" );
693 3 : jni.ensure_no_exception();
694 : assert( 0 != m_field_Any__type );
695 : // field Any._object
696 : m_field_Any__object = jni->GetFieldID(
697 3 : (jclass) jo_Any.get(), "_object", "Ljava/lang/Object;" );
698 3 : jni.ensure_no_exception();
699 : assert( 0 != m_field_Any__object );
700 :
701 : // method IEnvironment.getRegisteredInterface()
702 : m_method_IEnvironment_getRegisteredInterface = jni->GetMethodID(
703 3 : (jclass) jo_IEnvironment.get(),
704 : "getRegisteredInterface",
705 3 : "(Ljava/lang/String;Lcom/sun/star/uno/Type;)Ljava/lang/Object;" );
706 3 : jni.ensure_no_exception();
707 : assert( 0 != m_method_IEnvironment_getRegisteredInterface );
708 : // method IEnvironment.registerInterface()
709 : m_method_IEnvironment_registerInterface = jni->GetMethodID(
710 3 : (jclass) jo_IEnvironment.get(), "registerInterface",
711 : "(Ljava/lang/Object;[Ljava/lang/String;Lcom/sun/star/uno/Type;)"
712 3 : "Ljava/lang/Object;" );
713 3 : jni.ensure_no_exception();
714 : assert( 0 != m_method_IEnvironment_registerInterface );
715 :
716 : // static method JNI_proxy.get_proxy_ctor()
717 : m_method_JNI_proxy_get_proxy_ctor = jni->GetStaticMethodID(
718 3 : (jclass) jo_JNI_proxy.get(), "get_proxy_ctor",
719 3 : "(Ljava/lang/Class;)Ljava/lang/reflect/Constructor;" );
720 3 : jni.ensure_no_exception();
721 : assert( 0 != m_method_JNI_proxy_get_proxy_ctor );
722 : // static method JNI_proxy.create()
723 : m_method_JNI_proxy_create = jni->GetStaticMethodID(
724 3 : (jclass) jo_JNI_proxy.get(), "create",
725 : "(JLcom/sun/star/uno/IEnvironment;JJLcom/sun/star/uno/Type;Ljava/lang"
726 3 : "/String;Ljava/lang/reflect/Constructor;)Ljava/lang/Object;" );
727 3 : jni.ensure_no_exception();
728 : assert( 0 != m_method_JNI_proxy_create );
729 : // field JNI_proxy.m_receiver_handle
730 : m_field_JNI_proxy_m_receiver_handle = jni->GetFieldID(
731 3 : (jclass) jo_JNI_proxy.get(), "m_receiver_handle", "J" );
732 3 : jni.ensure_no_exception();
733 : assert( 0 != m_field_JNI_proxy_m_receiver_handle );
734 : // field JNI_proxy.m_td_handle
735 : m_field_JNI_proxy_m_td_handle = jni->GetFieldID(
736 3 : (jclass) jo_JNI_proxy.get(), "m_td_handle", "J" );
737 3 : jni.ensure_no_exception();
738 : assert( 0 != m_field_JNI_proxy_m_td_handle );
739 : // field JNI_proxy.m_type
740 : m_field_JNI_proxy_m_type = jni->GetFieldID(
741 3 : (jclass) jo_JNI_proxy.get(), "m_type", "Lcom/sun/star/uno/Type;" );
742 3 : jni.ensure_no_exception();
743 : assert( 0 != m_field_JNI_proxy_m_type );
744 : // field JNI_proxy.m_oid
745 : m_field_JNI_proxy_m_oid = jni->GetFieldID(
746 3 : (jclass) jo_JNI_proxy.get(), "m_oid", "Ljava/lang/String;" );
747 3 : jni.ensure_no_exception();
748 : assert( 0 != m_field_JNI_proxy_m_oid );
749 :
750 : // get java env
751 6 : OUString java_env_type_name( UNO_LB_JAVA );
752 : JLocalAutoRef jo_java(
753 6 : jni, ustring_to_jstring( jni, java_env_type_name.pData ) );
754 : jvalue args[ 2 ];
755 3 : args[ 0 ].l = jo_java.get();
756 3 : args[ 1 ].l = 0;
757 : jmethodID method_getEnvironment = jni->GetStaticMethodID(
758 3 : (jclass) jo_UnoRuntime.get(), "getEnvironment",
759 : "(Ljava/lang/String;Ljava/lang/Object;)"
760 3 : "Lcom/sun/star/uno/IEnvironment;" );
761 3 : jni.ensure_no_exception();
762 : assert( 0 != method_getEnvironment );
763 : JLocalAutoRef jo_java_env(
764 : jni, jni->CallStaticObjectMethodA(
765 6 : (jclass) jo_UnoRuntime.get(), method_getEnvironment, args ) );
766 :
767 : // get com.sun.star.uno.Any.VOID
768 : jfieldID field_Any_VOID = jni->GetStaticFieldID(
769 3 : (jclass) jo_Any.get(), "VOID", "Lcom/sun/star/uno/Any;" );
770 3 : jni.ensure_no_exception();
771 : assert( 0 != field_Any_VOID );
772 : JLocalAutoRef jo_Any_VOID(
773 : jni, jni->GetStaticObjectField(
774 6 : (jclass) jo_Any.get(), field_Any_VOID ) );
775 : // get com.sun.star.uno.Type.UNSIGNED_SHORT
776 : jfieldID field_Type_UNSIGNED_SHORT = jni->GetStaticFieldID(
777 3 : (jclass) jo_Type.get(), "UNSIGNED_SHORT", "Lcom/sun/star/uno/Type;" );
778 3 : jni.ensure_no_exception();
779 : assert( 0 != field_Type_UNSIGNED_SHORT );
780 : JLocalAutoRef jo_Type_UNSIGNED_SHORT(
781 : jni, jni->GetStaticObjectField(
782 6 : (jclass) jo_Type.get(), field_Type_UNSIGNED_SHORT ) );
783 : // get com.sun.star.uno.Type.UNSIGNED_LONG
784 : jfieldID field_Type_UNSIGNED_LONG = jni->GetStaticFieldID(
785 3 : (jclass) jo_Type.get(), "UNSIGNED_LONG", "Lcom/sun/star/uno/Type;" );
786 3 : jni.ensure_no_exception();
787 : assert( 0 != field_Type_UNSIGNED_LONG );
788 : JLocalAutoRef jo_Type_UNSIGNED_LONG(
789 : jni, jni->GetStaticObjectField(
790 6 : (jclass) jo_Type.get(), field_Type_UNSIGNED_LONG ) );
791 : // get com.sun.star.uno.Type.UNSIGNED_HYPER
792 : jfieldID field_Type_UNSIGNED_HYPER = jni->GetStaticFieldID(
793 3 : (jclass) jo_Type.get(), "UNSIGNED_HYPER", "Lcom/sun/star/uno/Type;" );
794 3 : jni.ensure_no_exception();
795 : assert( 0 != field_Type_UNSIGNED_HYPER );
796 : JLocalAutoRef jo_Type_UNSIGNED_HYPER(
797 : jni, jni->GetStaticObjectField(
798 6 : (jclass) jo_Type.get(), field_Type_UNSIGNED_HYPER ) );
799 :
800 : // make global refs
801 : m_class_UnoRuntime =
802 3 : (jclass) jni->NewGlobalRef( jo_UnoRuntime.get() );
803 : m_class_RuntimeException =
804 3 : (jclass) jni->NewGlobalRef( jo_RuntimeException.get() );
805 : m_class_Any =
806 3 : (jclass) jni->NewGlobalRef( jo_Any.get() );
807 : m_class_Type =
808 3 : (jclass) jni->NewGlobalRef( jo_Type.get() );
809 : m_class_TypeClass =
810 3 : (jclass) jni->NewGlobalRef( jo_TypeClass.get() );
811 : m_class_JNI_proxy =
812 3 : (jclass) jni->NewGlobalRef( jo_JNI_proxy.get() );
813 :
814 : m_class_Character =
815 3 : (jclass) jni->NewGlobalRef( jo_Character.get() );
816 : m_class_Boolean =
817 3 : (jclass) jni->NewGlobalRef( jo_Boolean.get() );
818 : m_class_Byte =
819 3 : (jclass) jni->NewGlobalRef( jo_Byte.get() );
820 : m_class_Short =
821 3 : (jclass) jni->NewGlobalRef( jo_Short.get() );
822 : m_class_Integer =
823 3 : (jclass) jni->NewGlobalRef( jo_Integer.get() );
824 : m_class_Long =
825 3 : (jclass) jni->NewGlobalRef( jo_Long.get() );
826 : m_class_Float =
827 3 : (jclass) jni->NewGlobalRef( jo_Float.get() );
828 : m_class_Double =
829 3 : (jclass) jni->NewGlobalRef( jo_Double.get() );
830 : m_class_String =
831 3 : (jclass) jni->NewGlobalRef( jo_String.get() );
832 : m_class_Object =
833 3 : (jclass) jni->NewGlobalRef( jo_Object.get() );
834 : m_class_Class =
835 3 : (jclass) jni->NewGlobalRef( m_class_Class );
836 :
837 : m_object_Any_VOID =
838 3 : jni->NewGlobalRef( jo_Any_VOID.get() );
839 : m_object_Type_UNSIGNED_SHORT =
840 3 : jni->NewGlobalRef( jo_Type_UNSIGNED_SHORT.get() );
841 : m_object_Type_UNSIGNED_LONG =
842 3 : jni->NewGlobalRef( jo_Type_UNSIGNED_LONG.get() );
843 : m_object_Type_UNSIGNED_HYPER =
844 3 : jni->NewGlobalRef( jo_Type_UNSIGNED_HYPER.get() );
845 3 : m_object_java_env = jni->NewGlobalRef( jo_java_env.get() );
846 :
847 : try
848 : {
849 : css::uno::TypeDescription XInterface_td(
850 : ::getCppuType(
851 3 : (css::uno::Reference< css::uno::XInterface > const *)0 ) );
852 : m_XInterface_type_info =
853 3 : new JNI_interface_type_info( jni, XInterface_td.get() );
854 : }
855 0 : catch (...)
856 : {
857 0 : destruct( jni_env );
858 0 : throw;
859 3 : }
860 3 : }
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 3 : 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 3 : uno_vm->getVirtualMachine() );
911 3 : JNIEnv * jni_env = guard.getEnvironment();
912 : JNI_context jni(
913 3 : 0, jni_env, static_cast< jobject >(uno_vm->getClassLoader()) );
914 :
915 : jclass jo_class;
916 : jmethodID jo_forName;
917 3 : jni.getClassForName( &jo_class, &jo_forName );
918 3 : 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 6 : jo_forName, false ) );
924 : // field JNI_info_holder.m_jni_info_handle
925 : jfieldID field_s_jni_info_handle =
926 : jni->GetStaticFieldID(
927 3 : (jclass) jo_JNI_info_holder.get(), "s_jni_info_handle", "J" );
928 3 : 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 3 : (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle ) );
935 3 : if (0 == jni_info) // un-initialized?
936 : {
937 : JNI_info * new_info = new JNI_info(
938 3 : jni_env, static_cast< jobject >(uno_vm->getClassLoader()), jo_class,
939 3 : jo_forName );
940 :
941 3 : ClearableMutexGuard g( Mutex::getGlobalMutex() );
942 : jni_info =
943 : reinterpret_cast< JNI_info const * >(
944 : jni->GetStaticLongField(
945 3 : (jclass) jo_JNI_info_holder.get(),
946 3 : field_s_jni_info_handle ) );
947 3 : if (0 == jni_info) // still un-initialized?
948 : {
949 : jni->SetStaticLongField(
950 3 : (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle,
951 6 : reinterpret_cast< jlong >( new_info ) );
952 3 : jni_info = new_info;
953 : }
954 : else
955 : {
956 0 : g.clear();
957 0 : new_info->destroy( jni_env );
958 3 : }
959 : }
960 :
961 6 : 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: */
|