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 0 : JNI_type_info::JNI_type_info(
45 : JNI_context const & jni, typelib_TypeDescription * td )
46 : : m_td( td ),
47 0 : m_class( 0 )
48 : {
49 0 : m_td.makeComplete();
50 0 : 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 0 : }
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 0 : JNI_interface_type_info::JNI_interface_type_info(
72 : JNI_context const & jni, typelib_TypeDescription * td_ )
73 0 : : JNI_type_info( jni, td_ )
74 : {
75 : assert( typelib_TypeClass_INTERFACE == m_td.get()->eTypeClass );
76 :
77 0 : OUString const & uno_name = OUString::unacquired( &m_td.get()->pTypeName );
78 0 : 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 0 : getStr() ) ) );
86 0 : JLocalAutoRef jo_type( jni, create_type( jni, (jclass) jo_class.get() ) );
87 :
88 : // get proxy ctor
89 : jvalue arg;
90 0 : arg.l = jo_class.get();
91 : JLocalAutoRef jo_proxy_ctor(
92 : jni, jni->CallStaticObjectMethodA(
93 : jni_info->m_class_JNI_proxy,
94 0 : jni_info->m_method_JNI_proxy_get_proxy_ctor, &arg ) );
95 :
96 0 : if (is_XInterface( m_td.get()->pWeakRef ))
97 : {
98 0 : 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 0 : m_td.get() );
108 0 : m_methods = new jmethodID[ td->nMapFunctionIndexToMemberIndex ];
109 0 : sal_Int32 nMethodIndex = 0;
110 0 : typelib_TypeDescriptionReference ** ppMembers = td->ppMembers;
111 0 : sal_Int32 nMembers = td->nMembers;
112 :
113 0 : for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos )
114 : {
115 0 : TypeDescr member_td( ppMembers[ nPos ] );
116 :
117 0 : OStringBuffer sig_buf( 64 );
118 :
119 0 : if (typelib_TypeClass_INTERFACE_METHOD ==
120 0 : member_td.get()->eTypeClass) // method
121 : {
122 : typelib_InterfaceMethodTypeDescription * method_td =
123 : reinterpret_cast<
124 : typelib_InterfaceMethodTypeDescription * >(
125 0 : member_td.get() );
126 :
127 0 : sig_buf.append( '(' );
128 0 : for ( sal_Int32 i = 0; i < method_td->nParams; ++i )
129 : {
130 : typelib_MethodParameter const & param =
131 0 : method_td->pParams[ i ];
132 0 : if (param.bOut)
133 0 : sig_buf.append( '[' );
134 0 : JNI_info::append_sig( &sig_buf, param.pTypeRef );
135 : }
136 0 : sig_buf.append( ')' );
137 0 : JNI_info::append_sig( &sig_buf, method_td->pReturnTypeRef );
138 :
139 0 : OString method_signature( sig_buf.makeStringAndClear() );
140 : OString method_name(
141 : OUStringToOString( OUString::unacquired(
142 0 : &method_td->aBase.pMemberName ),
143 0 : RTL_TEXTENCODING_JAVA_UTF8 ) );
144 :
145 0 : m_methods[ nMethodIndex ] = jni->GetMethodID(
146 0 : (jclass) jo_class.get(), method_name.getStr(),
147 0 : method_signature.getStr() );
148 0 : jni.ensure_no_exception();
149 : assert( 0 != m_methods[ nMethodIndex ] );
150 0 : ++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 0 : member_td.get() );
161 :
162 : // type sig
163 : JNI_info::append_sig(
164 0 : &sig_buf, attribute_td->pAttributeTypeRef );
165 0 : OString type_sig( sig_buf.makeStringAndClear() );
166 0 : sig_buf.ensureCapacity( 64 );
167 : // member name
168 : OUString const & member_name =
169 : OUString::unacquired(
170 0 : &attribute_td->aBase.pMemberName );
171 :
172 : // getter
173 0 : sig_buf.append( "()" );
174 0 : sig_buf.append( type_sig );
175 0 : OString method_signature( sig_buf.makeStringAndClear() );
176 0 : OUStringBuffer name_buf( 3 + member_name.getLength() );
177 0 : name_buf.append( "get" );
178 0 : name_buf.append( member_name );
179 : OString method_name(
180 : OUStringToOString(
181 : name_buf.makeStringAndClear(),
182 0 : RTL_TEXTENCODING_JAVA_UTF8 ) );
183 0 : m_methods[ nMethodIndex ] = jni->GetMethodID(
184 0 : (jclass) jo_class.get(), method_name.getStr(),
185 0 : method_signature.getStr() );
186 0 : jni.ensure_no_exception();
187 : assert( 0 != m_methods[ nMethodIndex ] );
188 0 : ++nMethodIndex;
189 0 : 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 0 : }
210 : }
211 0 : }
212 : }
213 0 : catch (...)
214 : {
215 0 : delete [] m_methods;
216 0 : throw;
217 : }
218 : }
219 0 : m_class = (jclass) jni->NewGlobalRef( jo_class.get() );
220 0 : m_type = jni->NewGlobalRef( jo_type.get() );
221 0 : m_proxy_ctor = jni->NewGlobalRef( jo_proxy_ctor.get() );
222 0 : }
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 0 : 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 0 : 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 0 : reinterpret_cast< typelib_CompoundTypeDescription * >( m_td.get() );
244 :
245 : OUString const & uno_name =
246 0 : OUString::unacquired( &((typelib_TypeDescription *)td)->pTypeName );
247 :
248 : // Erase type arguments of instantiated polymorphic struct types:
249 0 : OUString nucleus;
250 0 : sal_Int32 i = uno_name.indexOf( '<' );
251 0 : if ( i < 0 ) {
252 0 : 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 0 : nucleus, RTL_TEXTENCODING_JAVA_UTF8 ).getStr() ) );
262 :
263 0 : JNI_info const * jni_info = jni.get_info();
264 :
265 0 : if (typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass)
266 : {
267 : // retrieve exc ctor( msg )
268 : m_exc_ctor = jni->GetMethodID(
269 0 : (jclass) jo_class.get(), "<init>", "(Ljava/lang/String;)V" );
270 0 : 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 0 : jni_info->m_RuntimeException_type.getTypeLibType())
279 : ? 0
280 : : reinterpret_cast< typelib_TypeDescription * >(
281 0 : td->pBaseTypeDescription );
282 0 : m_base = (0 == base_td ? 0 : jni_info->get_type_info( jni, base_td ));
283 :
284 : try
285 : {
286 0 : if (type_equals(
287 : ((typelib_TypeDescription *)td)->pWeakRef,
288 0 : jni_info->m_Exception_type.getTypeLibType() ) ||
289 : type_equals(
290 : ((typelib_TypeDescription *)td)->pWeakRef,
291 0 : jni_info->m_RuntimeException_type.getTypeLibType() ))
292 : {
293 0 : m_fields = new jfieldID[ 2 ];
294 0 : m_fields[ 0 ] = 0; // special Throwable.getMessage()
295 : // field Context
296 0 : m_fields[ 1 ] = jni->GetFieldID(
297 0 : (jclass) jo_class.get(), "Context", "Ljava/lang/Object;" );
298 0 : jni.ensure_no_exception();
299 : assert( 0 != m_fields[ 1 ] );
300 : }
301 : else
302 : {
303 : // retrieve field ids for all direct members
304 0 : sal_Int32 nMembers = td->nMembers;
305 0 : m_fields = new jfieldID[ nMembers ];
306 :
307 0 : for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos )
308 : {
309 0 : OString sig;
310 0 : 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 0 : OStringBuffer sig_buf( 32 );
319 0 : JNI_info::append_sig( &sig_buf, td->ppTypeRefs[ nPos ] );
320 0 : sig = sig_buf.makeStringAndClear();
321 : }
322 :
323 : OString member_name(
324 : OUStringToOString(
325 0 : OUString::unacquired( &td->ppMemberNames[ nPos ] ),
326 0 : RTL_TEXTENCODING_JAVA_UTF8 ) );
327 :
328 0 : m_fields[ nPos ] = jni->GetFieldID(
329 0 : (jclass) jo_class.get(), member_name.getStr(),
330 0 : sig.getStr() );
331 0 : jni.ensure_no_exception();
332 : assert( 0 != m_fields[ nPos ] );
333 0 : }
334 : }
335 : }
336 0 : catch (...)
337 : {
338 0 : delete [] m_fields;
339 0 : throw;
340 : }
341 :
342 0 : m_class = (jclass) jni->NewGlobalRef( jo_class.get() );
343 0 : }
344 :
345 :
346 :
347 0 : JNI_type_info const * JNI_info::create_type_info(
348 : JNI_context const & jni, typelib_TypeDescription * td ) const
349 : {
350 0 : OUString const & uno_name = OUString::unacquired( &td->pTypeName );
351 :
352 : JNI_type_info * new_info;
353 0 : switch (td->eTypeClass)
354 : {
355 : case typelib_TypeClass_STRUCT:
356 : case typelib_TypeClass_EXCEPTION:
357 : {
358 0 : new_info = new JNI_compound_type_info( jni, td );
359 0 : break;
360 : }
361 : case typelib_TypeClass_INTERFACE:
362 : {
363 0 : new_info = new JNI_interface_type_info( jni, td );
364 0 : 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 0 : ClearableMutexGuard guard( m_mutex );
376 0 : JNI_type_info_holder & holder = m_type_map[ uno_name ];
377 0 : if (0 == holder.m_info) // new insertion
378 : {
379 0 : holder.m_info = new_info;
380 0 : guard.clear();
381 0 : 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 0 : return info;
390 : }
391 :
392 :
393 0 : JNI_type_info const * JNI_info::get_type_info(
394 : JNI_context const & jni, typelib_TypeDescription * td ) const
395 : {
396 0 : if (is_XInterface( td->pWeakRef ))
397 : {
398 0 : return m_XInterface_type_info;
399 : }
400 :
401 0 : OUString const & uno_name = OUString::unacquired( &td->pTypeName );
402 : JNI_type_info const * info;
403 0 : ClearableMutexGuard guard( m_mutex );
404 :
405 0 : t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
406 0 : if (iFind == m_type_map.end())
407 : {
408 0 : guard.clear();
409 0 : info = create_type_info( jni, td );
410 : }
411 : else
412 : {
413 0 : info = iFind->second.m_info;
414 : }
415 :
416 0 : return info;
417 : }
418 :
419 :
420 0 : JNI_type_info const * JNI_info::get_type_info(
421 : JNI_context const & jni, typelib_TypeDescriptionReference * type ) const
422 : {
423 0 : if (is_XInterface( type ))
424 : {
425 0 : return m_XInterface_type_info;
426 : }
427 :
428 0 : OUString const & uno_name = OUString::unacquired( &type->pTypeName );
429 : JNI_type_info const * info;
430 0 : ClearableMutexGuard guard( m_mutex );
431 0 : t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
432 0 : if (iFind == m_type_map.end())
433 : {
434 0 : guard.clear();
435 0 : TypeDescr td( type );
436 0 : info = create_type_info( jni, td.get() );
437 : }
438 : else
439 : {
440 0 : info = iFind->second.m_info;
441 : }
442 :
443 0 : return info;
444 : }
445 :
446 :
447 0 : JNI_type_info const * JNI_info::get_type_info(
448 : JNI_context const & jni, OUString const & uno_name ) const
449 : {
450 0 : 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 0 : ClearableMutexGuard guard( m_mutex );
457 0 : t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
458 0 : if (iFind == m_type_map.end())
459 : {
460 0 : guard.clear();
461 0 : css::uno::TypeDescription td( uno_name );
462 0 : if (! td.is())
463 : {
464 : throw BridgeRuntimeError(
465 0 : "UNO type not found: " + uno_name + jni.get_stack_trace() );
466 : }
467 0 : info = create_type_info( jni, td.get() );
468 : }
469 : else
470 : {
471 0 : info = iFind->second.m_info;
472 : }
473 :
474 0 : return info;
475 : }
476 :
477 :
478 0 : 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 0 : (css::uno::Reference< css::uno::XInterface > const *)0 ) )
489 0 : .get())->ppMembers[ 0 ] ) ),
490 0 : m_Exception_type( ::getCppuType( (css::uno::Exception const *)0 ) ),
491 : m_RuntimeException_type(
492 0 : ::getCppuType( (css::uno::RuntimeException const *)0 ) ),
493 0 : m_void_type( ::getCppuVoidType() ),
494 0 : m_XInterface_type_info( 0 )
495 : {
496 0 : JNI_context jni( this, jni_env, class_loader ); // !no proper jni_info!
497 :
498 : // class lookup
499 : JLocalAutoRef jo_Object(
500 0 : jni, find_class( jni, "java.lang.Object" ) );
501 : JLocalAutoRef jo_Class(
502 0 : jni, find_class( jni, "java.lang.Class" ) );
503 : JLocalAutoRef jo_Throwable(
504 0 : jni, find_class( jni, "java.lang.Throwable" ) );
505 : JLocalAutoRef jo_Character(
506 0 : jni, find_class( jni, "java.lang.Character" ) );
507 : JLocalAutoRef jo_Boolean(
508 0 : jni, find_class( jni, "java.lang.Boolean" ) );
509 : JLocalAutoRef jo_Byte(
510 0 : jni, find_class( jni, "java.lang.Byte" ) );
511 : JLocalAutoRef jo_Short(
512 0 : jni, find_class( jni, "java.lang.Short" ) );
513 : JLocalAutoRef jo_Integer(
514 0 : jni, find_class( jni, "java.lang.Integer" ) );
515 : JLocalAutoRef jo_Long(
516 0 : jni, find_class( jni, "java.lang.Long" ) );
517 : JLocalAutoRef jo_Float(
518 0 : jni, find_class( jni, "java.lang.Float" ) );
519 : JLocalAutoRef jo_Double(
520 0 : jni, find_class( jni, "java.lang.Double" ) );
521 : JLocalAutoRef jo_String(
522 0 : jni, find_class( jni, "java.lang.String" ) );
523 : JLocalAutoRef jo_RuntimeException(
524 0 : jni, find_class( jni, "com.sun.star.uno.RuntimeException" ) );
525 : JLocalAutoRef jo_UnoRuntime(
526 0 : jni, find_class( jni, "com.sun.star.uno.UnoRuntime" ) );
527 : JLocalAutoRef jo_Any(
528 0 : jni, find_class( jni, "com.sun.star.uno.Any" ) );
529 : JLocalAutoRef jo_Enum(
530 0 : jni, find_class( jni, "com.sun.star.uno.Enum" ) );
531 : JLocalAutoRef jo_Type(
532 0 : jni, find_class( jni, "com.sun.star.uno.Type" ) );
533 : JLocalAutoRef jo_TypeClass(
534 0 : jni, find_class( jni, "com.sun.star.uno.TypeClass" ) );
535 : JLocalAutoRef jo_IEnvironment(
536 0 : jni, find_class( jni, "com.sun.star.uno.IEnvironment" ) );
537 : JLocalAutoRef jo_JNI_proxy(
538 0 : 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 0 : (jclass) jo_Object.get(), "toString", "()Ljava/lang/String;" );
543 0 : jni.ensure_no_exception();
544 : assert( 0 != m_method_Object_toString );
545 : // method Class.getName()
546 : m_method_Class_getName = jni->GetMethodID(
547 0 : (jclass) jo_Class.get(), "getName", "()Ljava/lang/String;" );
548 0 : jni.ensure_no_exception();
549 : assert( 0 != m_method_Class_getName );
550 :
551 : // method Throwable.getMessage()
552 : m_method_Throwable_getMessage = jni->GetMethodID(
553 0 : (jclass) jo_Throwable.get(), "getMessage", "()Ljava/lang/String;" );
554 0 : jni.ensure_no_exception();
555 : assert( 0 != m_method_Throwable_getMessage );
556 :
557 : // method Character.charValue()
558 : m_method_Character_charValue = jni->GetMethodID(
559 0 : (jclass) jo_Character.get(), "charValue", "()C" );
560 0 : jni.ensure_no_exception();
561 : assert( 0 != m_method_Character_charValue );
562 : // method Boolean.booleanValue()
563 : m_method_Boolean_booleanValue = jni->GetMethodID(
564 0 : (jclass) jo_Boolean.get(), "booleanValue", "()Z" );
565 0 : jni.ensure_no_exception();
566 : assert( 0 != m_method_Boolean_booleanValue );
567 : // method Byte.byteValue()
568 : m_method_Byte_byteValue = jni->GetMethodID(
569 0 : (jclass) jo_Byte.get(), "byteValue", "()B" );
570 0 : jni.ensure_no_exception();
571 : assert( 0 != m_method_Byte_byteValue );
572 : // method Short.shortValue()
573 : m_method_Short_shortValue = jni->GetMethodID(
574 0 : (jclass) jo_Short.get(), "shortValue", "()S" );
575 0 : jni.ensure_no_exception();
576 : assert( 0 != m_method_Short_shortValue );
577 : // method Integer.intValue()
578 : m_method_Integer_intValue = jni->GetMethodID(
579 0 : (jclass) jo_Integer.get(), "intValue", "()I" );
580 0 : jni.ensure_no_exception();
581 : assert( 0 != m_method_Integer_intValue );
582 : // method Long.longValue()
583 : m_method_Long_longValue = jni->GetMethodID(
584 0 : (jclass) jo_Long.get(), "longValue", "()J" );
585 0 : jni.ensure_no_exception();
586 : assert( 0 != m_method_Long_longValue );
587 : // method Float.floatValue()
588 : m_method_Float_floatValue = jni->GetMethodID(
589 0 : (jclass) jo_Float.get(), "floatValue", "()F" );
590 0 : jni.ensure_no_exception();
591 : assert( 0 != m_method_Float_floatValue );
592 : // method Double.doubleValue()
593 : m_method_Double_doubleValue = jni->GetMethodID(
594 0 : (jclass) jo_Double.get(), "doubleValue", "()D" );
595 0 : 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 0 : (jclass) jo_Character.get(), "<init>", "(C)V" );
601 0 : 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 0 : (jclass) jo_Boolean.get(), "<init>", "(Z)V" );
606 0 : 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 0 : (jclass) jo_Byte.get(), "<init>", "(B)V" );
611 0 : 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 0 : (jclass) jo_Short.get(), "<init>", "(S)V" );
616 0 : 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 0 : (jclass) jo_Integer.get(), "<init>", "(I)V" );
621 0 : 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 0 : (jclass) jo_Long.get(), "<init>", "(J)V" );
626 0 : 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 0 : (jclass) jo_Float.get(), "<init>", "(F)V" );
631 0 : 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 0 : (jclass) jo_Double.get(), "<init>", "(D)V" );
636 0 : 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 0 : (jclass) jo_UnoRuntime.get(),
642 0 : "generateOid", "(Ljava/lang/Object;)Ljava/lang/String;" );
643 0 : jni.ensure_no_exception();
644 : assert( 0 != m_method_UnoRuntime_generateOid );
645 : // static method UnoRuntime.queryInterface()
646 : m_method_UnoRuntime_queryInterface = jni->GetStaticMethodID(
647 0 : (jclass) jo_UnoRuntime.get(),
648 : "queryInterface",
649 0 : "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)Ljava/lang/Object;" );
650 0 : 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 0 : (jclass) jo_Enum.get(), "m_value", "I" );
656 0 : 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 0 : (jclass) jo_TypeClass.get(),
662 0 : "fromInt", "(I)Lcom/sun/star/uno/TypeClass;" );
663 0 : 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 0 : (jclass) jo_Type.get(), "<init>", "(Ljava/lang/Class;)V" );
669 0 : 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 0 : (jclass) jo_Type.get(),
674 0 : "<init>", "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V" );
675 0 : 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 0 : (jclass) jo_Type.get(), "_typeName", "Ljava/lang/String;" );
680 0 : 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 0 : (jclass) jo_Any.get(),
686 0 : "<init>", "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V" );
687 0 : 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 0 : (jclass) jo_Any.get(), "_type", "Lcom/sun/star/uno/Type;" );
693 0 : jni.ensure_no_exception();
694 : assert( 0 != m_field_Any__type );
695 : // field Any._object
696 : m_field_Any__object = jni->GetFieldID(
697 0 : (jclass) jo_Any.get(), "_object", "Ljava/lang/Object;" );
698 0 : jni.ensure_no_exception();
699 : assert( 0 != m_field_Any__object );
700 :
701 : // method IEnvironment.getRegisteredInterface()
702 : m_method_IEnvironment_getRegisteredInterface = jni->GetMethodID(
703 0 : (jclass) jo_IEnvironment.get(),
704 : "getRegisteredInterface",
705 0 : "(Ljava/lang/String;Lcom/sun/star/uno/Type;)Ljava/lang/Object;" );
706 0 : jni.ensure_no_exception();
707 : assert( 0 != m_method_IEnvironment_getRegisteredInterface );
708 : // method IEnvironment.registerInterface()
709 : m_method_IEnvironment_registerInterface = jni->GetMethodID(
710 0 : (jclass) jo_IEnvironment.get(), "registerInterface",
711 : "(Ljava/lang/Object;[Ljava/lang/String;Lcom/sun/star/uno/Type;)"
712 0 : "Ljava/lang/Object;" );
713 0 : 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 0 : (jclass) jo_JNI_proxy.get(), "get_proxy_ctor",
719 0 : "(Ljava/lang/Class;)Ljava/lang/reflect/Constructor;" );
720 0 : 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 0 : (jclass) jo_JNI_proxy.get(), "create",
725 : "(JLcom/sun/star/uno/IEnvironment;JJLcom/sun/star/uno/Type;Ljava/lang"
726 0 : "/String;Ljava/lang/reflect/Constructor;)Ljava/lang/Object;" );
727 0 : 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 0 : (jclass) jo_JNI_proxy.get(), "m_receiver_handle", "J" );
732 0 : 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 0 : (jclass) jo_JNI_proxy.get(), "m_td_handle", "J" );
737 0 : 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 0 : (jclass) jo_JNI_proxy.get(), "m_type", "Lcom/sun/star/uno/Type;" );
742 0 : 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 0 : (jclass) jo_JNI_proxy.get(), "m_oid", "Ljava/lang/String;" );
747 0 : jni.ensure_no_exception();
748 : assert( 0 != m_field_JNI_proxy_m_oid );
749 :
750 : // get java env
751 0 : OUString java_env_type_name( UNO_LB_JAVA );
752 : JLocalAutoRef jo_java(
753 0 : jni, ustring_to_jstring( jni, java_env_type_name.pData ) );
754 : jvalue args[ 2 ];
755 0 : args[ 0 ].l = jo_java.get();
756 0 : args[ 1 ].l = 0;
757 : jmethodID method_getEnvironment = jni->GetStaticMethodID(
758 0 : (jclass) jo_UnoRuntime.get(), "getEnvironment",
759 : "(Ljava/lang/String;Ljava/lang/Object;)"
760 0 : "Lcom/sun/star/uno/IEnvironment;" );
761 0 : jni.ensure_no_exception();
762 : assert( 0 != method_getEnvironment );
763 : JLocalAutoRef jo_java_env(
764 : jni, jni->CallStaticObjectMethodA(
765 0 : (jclass) jo_UnoRuntime.get(), method_getEnvironment, args ) );
766 :
767 : // get com.sun.star.uno.Any.VOID
768 : jfieldID field_Any_VOID = jni->GetStaticFieldID(
769 0 : (jclass) jo_Any.get(), "VOID", "Lcom/sun/star/uno/Any;" );
770 0 : jni.ensure_no_exception();
771 : assert( 0 != field_Any_VOID );
772 : JLocalAutoRef jo_Any_VOID(
773 : jni, jni->GetStaticObjectField(
774 0 : (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 0 : (jclass) jo_Type.get(), "UNSIGNED_SHORT", "Lcom/sun/star/uno/Type;" );
778 0 : jni.ensure_no_exception();
779 : assert( 0 != field_Type_UNSIGNED_SHORT );
780 : JLocalAutoRef jo_Type_UNSIGNED_SHORT(
781 : jni, jni->GetStaticObjectField(
782 0 : (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 0 : (jclass) jo_Type.get(), "UNSIGNED_LONG", "Lcom/sun/star/uno/Type;" );
786 0 : jni.ensure_no_exception();
787 : assert( 0 != field_Type_UNSIGNED_LONG );
788 : JLocalAutoRef jo_Type_UNSIGNED_LONG(
789 : jni, jni->GetStaticObjectField(
790 0 : (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 0 : (jclass) jo_Type.get(), "UNSIGNED_HYPER", "Lcom/sun/star/uno/Type;" );
794 0 : jni.ensure_no_exception();
795 : assert( 0 != field_Type_UNSIGNED_HYPER );
796 : JLocalAutoRef jo_Type_UNSIGNED_HYPER(
797 : jni, jni->GetStaticObjectField(
798 0 : (jclass) jo_Type.get(), field_Type_UNSIGNED_HYPER ) );
799 :
800 : // make global refs
801 : m_class_UnoRuntime =
802 0 : (jclass) jni->NewGlobalRef( jo_UnoRuntime.get() );
803 : m_class_RuntimeException =
804 0 : (jclass) jni->NewGlobalRef( jo_RuntimeException.get() );
805 : m_class_Any =
806 0 : (jclass) jni->NewGlobalRef( jo_Any.get() );
807 : m_class_Type =
808 0 : (jclass) jni->NewGlobalRef( jo_Type.get() );
809 : m_class_TypeClass =
810 0 : (jclass) jni->NewGlobalRef( jo_TypeClass.get() );
811 : m_class_JNI_proxy =
812 0 : (jclass) jni->NewGlobalRef( jo_JNI_proxy.get() );
813 :
814 : m_class_Character =
815 0 : (jclass) jni->NewGlobalRef( jo_Character.get() );
816 : m_class_Boolean =
817 0 : (jclass) jni->NewGlobalRef( jo_Boolean.get() );
818 : m_class_Byte =
819 0 : (jclass) jni->NewGlobalRef( jo_Byte.get() );
820 : m_class_Short =
821 0 : (jclass) jni->NewGlobalRef( jo_Short.get() );
822 : m_class_Integer =
823 0 : (jclass) jni->NewGlobalRef( jo_Integer.get() );
824 : m_class_Long =
825 0 : (jclass) jni->NewGlobalRef( jo_Long.get() );
826 : m_class_Float =
827 0 : (jclass) jni->NewGlobalRef( jo_Float.get() );
828 : m_class_Double =
829 0 : (jclass) jni->NewGlobalRef( jo_Double.get() );
830 : m_class_String =
831 0 : (jclass) jni->NewGlobalRef( jo_String.get() );
832 : m_class_Object =
833 0 : (jclass) jni->NewGlobalRef( jo_Object.get() );
834 : m_class_Class =
835 0 : (jclass) jni->NewGlobalRef( m_class_Class );
836 :
837 : m_object_Any_VOID =
838 0 : jni->NewGlobalRef( jo_Any_VOID.get() );
839 : m_object_Type_UNSIGNED_SHORT =
840 0 : jni->NewGlobalRef( jo_Type_UNSIGNED_SHORT.get() );
841 : m_object_Type_UNSIGNED_LONG =
842 0 : jni->NewGlobalRef( jo_Type_UNSIGNED_LONG.get() );
843 : m_object_Type_UNSIGNED_HYPER =
844 0 : jni->NewGlobalRef( jo_Type_UNSIGNED_HYPER.get() );
845 0 : m_object_java_env = jni->NewGlobalRef( jo_java_env.get() );
846 :
847 : try
848 : {
849 : css::uno::TypeDescription XInterface_td(
850 : ::getCppuType(
851 0 : (css::uno::Reference< css::uno::XInterface > const *)0 ) );
852 : m_XInterface_type_info =
853 0 : new JNI_interface_type_info( jni, XInterface_td.get() );
854 : }
855 0 : catch (...)
856 : {
857 0 : destruct( jni_env );
858 0 : throw;
859 0 : }
860 0 : }
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 0 : 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 0 : uno_vm->getVirtualMachine() );
911 0 : JNIEnv * jni_env = guard.getEnvironment();
912 : JNI_context jni(
913 0 : 0, jni_env, static_cast< jobject >(uno_vm->getClassLoader()) );
914 :
915 : jclass jo_class;
916 : jmethodID jo_forName;
917 0 : jni.getClassForName( &jo_class, &jo_forName );
918 0 : 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 0 : jo_forName, false ) );
924 : // field JNI_info_holder.m_jni_info_handle
925 : jfieldID field_s_jni_info_handle =
926 : jni->GetStaticFieldID(
927 0 : (jclass) jo_JNI_info_holder.get(), "s_jni_info_handle", "J" );
928 0 : 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 0 : (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle ) );
935 0 : if (0 == jni_info) // un-initialized?
936 : {
937 : JNI_info * new_info = new JNI_info(
938 0 : jni_env, static_cast< jobject >(uno_vm->getClassLoader()), jo_class,
939 0 : jo_forName );
940 :
941 0 : ClearableMutexGuard g( Mutex::getGlobalMutex() );
942 : jni_info =
943 : reinterpret_cast< JNI_info const * >(
944 : jni->GetStaticLongField(
945 0 : (jclass) jo_JNI_info_holder.get(),
946 0 : field_s_jni_info_handle ) );
947 0 : if (0 == jni_info) // still un-initialized?
948 : {
949 : jni->SetStaticLongField(
950 0 : (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle,
951 0 : reinterpret_cast< jlong >( new_info ) );
952 0 : jni_info = new_info;
953 : }
954 : else
955 : {
956 0 : g.clear();
957 0 : new_info->destroy( jni_env );
958 0 : }
959 : }
960 :
961 0 : 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: */
|