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 :
21 : #include <sal/alloca.h>
22 :
23 : #include "jni_bridge.h"
24 :
25 : #include <rtl/ustrbuf.hxx>
26 :
27 : #include <algorithm>
28 :
29 :
30 : using namespace ::rtl;
31 :
32 : namespace jni_uno
33 : {
34 :
35 : //______________________________________________________________________________
36 0 : jobject Bridge::map_to_java(
37 : JNI_context const & jni,
38 : uno_Interface * pUnoI, JNI_interface_type_info const * info ) const
39 : {
40 : // get oid
41 0 : rtl_uString * pOid = 0;
42 0 : (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI );
43 : OSL_ASSERT( 0 != pOid );
44 0 : OUString oid( pOid, SAL_NO_ACQUIRE );
45 :
46 : // opt getRegisteredInterface()
47 0 : JLocalAutoRef jo_oid( jni, ustring_to_jstring( jni, oid.pData ) );
48 : jvalue args[ 2 ];
49 0 : args[ 0 ].l = jo_oid.get();
50 0 : args[ 1 ].l = info->m_type;
51 : jobject jo_iface = jni->CallObjectMethodA(
52 : m_jni_info->m_object_java_env,
53 0 : m_jni_info->m_method_IEnvironment_getRegisteredInterface, args );
54 0 : jni.ensure_no_exception();
55 :
56 0 : if (0 == jo_iface) // no registered iface
57 : {
58 : // register uno interface
59 : (*m_uno_env->registerInterface)(
60 : m_uno_env, reinterpret_cast< void ** >( &pUnoI ),
61 0 : oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
62 :
63 : // create java and register java proxy
64 : jvalue args2[ 7 ];
65 0 : acquire();
66 0 : args2[ 0 ].j = reinterpret_cast< sal_Int64 >( this );
67 0 : (*pUnoI->acquire)( pUnoI );
68 0 : args2[ 1 ].l = m_jni_info->m_object_java_env;
69 0 : args2[ 2 ].j = reinterpret_cast< sal_Int64 >( pUnoI );
70 0 : typelib_typedescription_acquire( info->m_td.get() );
71 0 : args2[ 3 ].j = reinterpret_cast< sal_Int64 >( info->m_td.get() );
72 0 : args2[ 4 ].l = info->m_type;
73 0 : args2[ 5 ].l = jo_oid.get();
74 0 : args2[ 6 ].l = info->m_proxy_ctor;
75 : jo_iface = jni->CallStaticObjectMethodA(
76 : m_jni_info->m_class_JNI_proxy,
77 0 : m_jni_info->m_method_JNI_proxy_create, args2 );
78 0 : jni.ensure_no_exception();
79 : }
80 :
81 : OSL_ASSERT( 0 != jo_iface );
82 0 : return jo_iface;
83 : }
84 :
85 :
86 : //______________________________________________________________________________
87 0 : void Bridge::handle_uno_exc( JNI_context const & jni, uno_Any * uno_exc ) const
88 : {
89 0 : if (typelib_TypeClass_EXCEPTION == uno_exc->pType->eTypeClass)
90 : {
91 : #if OSL_DEBUG_LEVEL > 0
92 : // append java stack trace to Message member
93 : reinterpret_cast< ::com::sun::star::uno::Exception * >(
94 : uno_exc->pData )->Message += jni.get_stack_trace();
95 : #endif
96 :
97 : #if OSL_DEBUG_LEVEL > 1
98 : {
99 : OUStringBuffer buf( 128 );
100 : buf.appendAscii(
101 : RTL_CONSTASCII_STRINGPARAM("exception occurred java->uno: [") );
102 : buf.append( OUString::unacquired( &uno_exc->pType->pTypeName ) );
103 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
104 : buf.append(
105 : reinterpret_cast< ::com::sun::star::uno::Exception const * >(
106 : uno_exc->pData )->Message );
107 : OString cstr_msg(
108 : OUStringToOString(
109 : buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
110 : OSL_TRACE( "%s", cstr_msg.getStr() );
111 : }
112 : #endif
113 : // signal exception
114 : jvalue java_exc;
115 : try
116 : {
117 : map_to_java(
118 : jni, &java_exc, uno_exc->pData, uno_exc->pType, 0,
119 0 : true /* in */, false /* no out */ );
120 : }
121 0 : catch (...)
122 : {
123 0 : uno_any_destruct( uno_exc, 0 );
124 0 : throw;
125 : }
126 0 : uno_any_destruct( uno_exc, 0 );
127 :
128 0 : JLocalAutoRef jo_exc( jni, java_exc.l );
129 0 : jint res = jni->Throw( (jthrowable) jo_exc.get() );
130 0 : if (0 != res)
131 : {
132 : // call toString()
133 : JLocalAutoRef jo_descr(
134 : jni, jni->CallObjectMethodA(
135 0 : jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) );
136 0 : jni.ensure_no_exception();
137 0 : OUStringBuffer buf( 128 );
138 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
139 0 : "throwing java exception failed: ") );
140 0 : buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
141 0 : buf.append( jni.get_stack_trace() );
142 0 : throw BridgeRuntimeError( buf.makeStringAndClear() );
143 0 : }
144 : }
145 : else
146 : {
147 : OUString message(
148 : OUSTR("thrown exception is no uno exception: ") +
149 0 : OUString::unacquired( &uno_exc->pType->pTypeName ) +
150 0 : jni.get_stack_trace() );
151 0 : uno_any_destruct( uno_exc, 0 );
152 0 : throw BridgeRuntimeError( message );
153 : }
154 0 : }
155 :
156 : union largest
157 : {
158 : sal_Int64 n;
159 : double d;
160 : void * p;
161 : uno_Any a;
162 : };
163 :
164 : //______________________________________________________________________________
165 0 : jobject Bridge::call_uno(
166 : JNI_context const & jni,
167 : uno_Interface * pUnoI, typelib_TypeDescription * member_td,
168 : typelib_TypeDescriptionReference * return_type,
169 : sal_Int32 nParams, typelib_MethodParameter const * pParams,
170 : jobjectArray jo_args /* may be 0 */ ) const
171 : {
172 : // return mem
173 : sal_Int32 return_size;
174 0 : switch (return_type->eTypeClass) {
175 : case typelib_TypeClass_VOID:
176 0 : return_size = 0;
177 0 : break;
178 :
179 : case typelib_TypeClass_STRUCT:
180 : case typelib_TypeClass_EXCEPTION:
181 : return_size = std::max(
182 0 : TypeDescr(return_type).get()->nSize,
183 0 : static_cast< sal_Int32 >(sizeof (largest)));
184 0 : break;
185 :
186 : default:
187 0 : return_size = sizeof (largest);
188 0 : break;
189 : }
190 :
191 : #ifdef BROKEN_ALLOCA
192 : char * mem = (char *) malloc(
193 : #else
194 0 : char * mem = (char *) alloca(
195 : #endif
196 : (nParams * sizeof (void *)) +
197 : return_size + (nParams * sizeof (largest)) );
198 0 : void ** uno_args = (void **) mem;
199 0 : void * uno_ret = return_size == 0 ? 0 : (mem + (nParams * sizeof (void *)));
200 : largest * uno_args_mem = (largest *)
201 0 : (mem + (nParams * sizeof (void *)) + return_size);
202 :
203 : OSL_ASSERT( (0 == nParams) || (nParams == jni->GetArrayLength( jo_args )) );
204 0 : for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
205 : {
206 0 : typelib_MethodParameter const & param = pParams[ nPos ];
207 0 : typelib_TypeDescriptionReference * type = param.pTypeRef;
208 :
209 0 : uno_args[ nPos ] = &uno_args_mem[ nPos ];
210 0 : if (typelib_TypeClass_STRUCT == type->eTypeClass ||
211 : typelib_TypeClass_EXCEPTION == type->eTypeClass)
212 : {
213 0 : TypeDescr td( type );
214 0 : if (sal::static_int_cast< sal_uInt32 >(td.get()->nSize)
215 : > sizeof (largest))
216 : #ifdef BROKEN_ALLOCA
217 : uno_args[ nPos ] = malloc( td.get()->nSize );
218 : #else
219 0 : uno_args[ nPos ] = alloca( td.get()->nSize );
220 : #endif
221 : }
222 :
223 0 : if (param.bIn)
224 : {
225 : try
226 : {
227 : JLocalAutoRef jo_arg(
228 0 : jni, jni->GetObjectArrayElement( jo_args, nPos ) );
229 0 : jni.ensure_no_exception();
230 : jvalue java_arg;
231 0 : java_arg.l = jo_arg.get();
232 : map_to_uno(
233 0 : jni, uno_args[ nPos ], java_arg, type, 0,
234 : false /* no assign */, sal_False != param.bOut,
235 0 : true /* special wrapped integral types */ );
236 : }
237 0 : catch (...)
238 : {
239 : // cleanup uno in args
240 0 : for ( sal_Int32 n = 0; n < nPos; ++n )
241 : {
242 0 : typelib_MethodParameter const & p = pParams[ n ];
243 0 : if (p.bIn)
244 : {
245 : uno_type_destructData(
246 0 : uno_args[ n ], p.pTypeRef, 0 );
247 : }
248 : #ifdef BROKEN_ALLOCA
249 : if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
250 : free( uno_args[ nPos ] );
251 : #endif
252 : }
253 : #ifdef BROKEN_ALLOCA
254 : free( mem );
255 : #endif
256 0 : throw;
257 : }
258 : }
259 : }
260 :
261 : uno_Any uno_exc_holder;
262 0 : uno_Any * uno_exc = &uno_exc_holder;
263 : // call binary uno
264 0 : (*pUnoI->pDispatcher)( pUnoI, member_td, uno_ret, uno_args, &uno_exc );
265 :
266 0 : if (0 == uno_exc)
267 : {
268 : // convert out args; destruct uno args
269 0 : for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
270 : {
271 0 : typelib_MethodParameter const & param = pParams[ nPos ];
272 0 : typelib_TypeDescriptionReference * type = param.pTypeRef;
273 0 : if (param.bOut)
274 : {
275 : try
276 : {
277 : // get out holder array[ 1 ]
278 : JLocalAutoRef jo_out_holder(
279 0 : jni, jni->GetObjectArrayElement( jo_args, nPos ) );
280 0 : jni.ensure_no_exception();
281 : jvalue java_arg;
282 0 : java_arg.l = jo_out_holder.get();
283 : map_to_java(
284 0 : jni, &java_arg, uno_args[ nPos ], type, 0,
285 0 : true /* in */, true /* out holder */ );
286 : }
287 0 : catch (...)
288 : {
289 : // cleanup further uno args
290 0 : for ( sal_Int32 n = nPos; n < nParams; ++n )
291 : {
292 : uno_type_destructData(
293 0 : uno_args[ n ], pParams[ n ].pTypeRef, 0 );
294 : #ifdef BROKEN_ALLOCA
295 : if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
296 : free( uno_args[ nPos ] );
297 : #endif
298 : }
299 : // cleanup uno return value
300 0 : uno_type_destructData( uno_ret, return_type, 0 );
301 : #ifdef BROKEN_ALLOCA
302 : free( mem );
303 : #endif
304 0 : throw;
305 : }
306 : }
307 0 : if (typelib_TypeClass_DOUBLE < type->eTypeClass &&
308 : typelib_TypeClass_ENUM != type->eTypeClass) // opt
309 : {
310 0 : uno_type_destructData( uno_args[ nPos ], type, 0 );
311 : #ifdef BROKEN_ALLOCA
312 : if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
313 : free( uno_args[ nPos ] );
314 : #endif
315 : }
316 : }
317 :
318 0 : if (typelib_TypeClass_VOID != return_type->eTypeClass)
319 : {
320 : // convert uno return value
321 : jvalue java_ret;
322 : try
323 : {
324 : map_to_java(
325 : jni, &java_ret, uno_ret, return_type, 0,
326 : true /* in */, false /* no out */,
327 0 : true /* special_wrapped_integral_types */ );
328 : }
329 0 : catch (...)
330 : {
331 0 : uno_type_destructData( uno_ret, return_type, 0 );
332 : #ifdef BROKEN_ALLOCA
333 : free( mem );
334 : #endif
335 0 : throw;
336 : }
337 0 : if (typelib_TypeClass_DOUBLE < return_type->eTypeClass &&
338 : typelib_TypeClass_ENUM != return_type->eTypeClass) // opt
339 : {
340 0 : uno_type_destructData( uno_ret, return_type, 0 );
341 : }
342 : #ifdef BROKEN_ALLOCA
343 : free( mem );
344 : #endif
345 0 : return java_ret.l;
346 : }
347 : #ifdef BROKEN_ALLOCA
348 : free( mem );
349 : #endif
350 0 : return 0; // void return
351 : }
352 : else // exception occurred
353 : {
354 : // destruct uno in args
355 0 : for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
356 : {
357 0 : typelib_MethodParameter const & param = pParams[ nPos ];
358 0 : if (param.bIn)
359 0 : uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 );
360 : #ifdef BROKEN_ALLOCA
361 : if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
362 : free( uno_args[ nPos ] );
363 : #endif
364 : }
365 :
366 0 : handle_uno_exc( jni, uno_exc );
367 : #ifdef BROKEN_ALLOCA
368 : free( mem );
369 : #endif
370 0 : return 0;
371 : }
372 : }
373 :
374 : }
375 :
376 : using namespace ::jni_uno;
377 :
378 : extern "C"
379 : {
380 :
381 : //------------------------------------------------------------------------------
382 : SAL_JNI_EXPORT jobject
383 0 : JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call(
384 : JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle, jstring jo_method,
385 : jobjectArray jo_args /* may be 0 */ )
386 : SAL_THROW_EXTERN_C()
387 : {
388 0 : Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
389 0 : JNI_info const * jni_info = bridge->m_jni_info;
390 : JNI_context jni(
391 : jni_info, jni_env,
392 : static_cast< jobject >(
393 : reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
394 0 : bridge->m_java_env->pContext )->getClassLoader() ) );
395 :
396 0 : OUString method_name;
397 :
398 : try
399 : {
400 0 : method_name = jstring_to_oustring( jni, jo_method );
401 : #if OSL_DEBUG_LEVEL > 1
402 : {
403 : OUStringBuffer trace_buf( 64 );
404 : trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("java->uno call: ") );
405 : trace_buf.append( method_name );
406 : trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") );
407 : JLocalAutoRef jo_oid(
408 : jni, jni->GetObjectField(
409 : jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
410 : trace_buf.append( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
411 : OString cstr_msg(
412 : OUStringToOString(
413 : trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
414 : OSL_TRACE( "%s", cstr_msg.getStr() );
415 : }
416 : #endif
417 :
418 : // special IQueryInterface.queryInterface()
419 0 : if ( method_name == "queryInterface" )
420 : {
421 : // oid
422 : JLocalAutoRef jo_oid(
423 : jni, jni->GetObjectField(
424 0 : jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
425 : // type
426 : JLocalAutoRef jo_type(
427 0 : jni, jni->GetObjectArrayElement( jo_args, 0 ) );
428 0 : jni.ensure_no_exception();
429 :
430 : JLocalAutoRef jo_type_name(
431 : jni, jni->GetObjectField(
432 0 : jo_type.get(), jni_info->m_field_Type__typeName ) );
433 0 : if (! jo_type_name.is())
434 : {
435 : throw BridgeRuntimeError(
436 : OUSTR("incomplete type object: no type name!") +
437 0 : jni.get_stack_trace() );
438 : }
439 : OUString type_name(
440 0 : jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
441 : JNI_type_info const * info =
442 0 : jni_info->get_type_info( jni, type_name );
443 0 : if (typelib_TypeClass_INTERFACE != info->m_td.get()->eTypeClass)
444 : {
445 : throw BridgeRuntimeError(
446 0 : OUSTR("queryInterface() call demands an INTERFACE type!") );
447 : }
448 : JNI_interface_type_info const * iface_info =
449 0 : static_cast< JNI_interface_type_info const * >( info );
450 :
451 : // getRegisteredInterface() already tested in JNI_proxy:
452 : // perform queryInterface call on binary uno interface
453 : uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
454 : jni->GetLongField(
455 0 : jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
456 :
457 : uno_Any uno_ret;
458 0 : void * uno_args[] = { &iface_info->m_td.get()->pWeakRef };
459 : uno_Any uno_exc_holder;
460 0 : uno_Any * uno_exc = &uno_exc_holder;
461 : // call binary uno
462 : (*pUnoI->pDispatcher)(
463 0 : pUnoI, jni_info->m_XInterface_queryInterface_td.get(),
464 0 : &uno_ret, uno_args, &uno_exc );
465 0 : if (0 == uno_exc)
466 : {
467 0 : jobject jo_ret = 0;
468 0 : if (typelib_TypeClass_INTERFACE == uno_ret.pType->eTypeClass)
469 : {
470 : uno_Interface * pUnoRet =
471 0 : (uno_Interface *) uno_ret.pReserved;
472 0 : if (0 != pUnoRet)
473 : {
474 : try
475 : {
476 : jo_ret =
477 0 : bridge->map_to_java( jni, pUnoRet, iface_info );
478 : }
479 0 : catch (...)
480 : {
481 0 : uno_any_destruct( &uno_ret, 0 );
482 0 : throw;
483 : }
484 : }
485 : }
486 0 : uno_any_destruct( &uno_ret, 0 );
487 0 : return jo_ret;
488 : }
489 : else
490 : {
491 0 : bridge->handle_uno_exc( jni, uno_exc );
492 0 : return 0;
493 0 : }
494 : }
495 :
496 : typelib_InterfaceTypeDescription * td =
497 : reinterpret_cast< typelib_InterfaceTypeDescription * >(
498 : jni->GetLongField(
499 0 : jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
500 : uno_Interface * pUnoI =
501 : reinterpret_cast< uno_Interface * >(
502 : jni->GetLongField(
503 0 : jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
504 :
505 0 : typelib_TypeDescriptionReference ** ppAllMembers = td->ppAllMembers;
506 0 : for ( sal_Int32 nPos = td->nAllMembers; nPos--; )
507 : {
508 : // try to avoid getting typedescription as long as possible,
509 : // because of a Mutex.acquire() in
510 : // typelib_typedescriptionreference_getDescription()
511 : typelib_TypeDescriptionReference * member_type =
512 0 : ppAllMembers[ nPos ];
513 :
514 : // check method_name against fully qualified type_name
515 : // of member_type; type_name is of the form
516 : // <name> "::" <method_name> *(":@" <idx> "," <idx> ":" <name>)
517 : OUString const & type_name =
518 0 : OUString::unacquired( &member_type->pTypeName );
519 0 : sal_Int32 offset = type_name.indexOf( ':' ) + 2;
520 : OSL_ASSERT(
521 : offset >= 2 && offset < type_name.getLength()
522 : && type_name[offset - 1] == ':' );
523 0 : sal_Int32 remainder = type_name.getLength() - offset;
524 0 : if (typelib_TypeClass_INTERFACE_METHOD == member_type->eTypeClass)
525 : {
526 0 : if ((method_name.getLength() == remainder
527 0 : || (method_name.getLength() < remainder
528 0 : && type_name[offset + method_name.getLength()] == ':'))
529 0 : && type_name.match(method_name, offset))
530 : {
531 0 : TypeDescr member_td( member_type );
532 : typelib_InterfaceMethodTypeDescription * method_td =
533 : reinterpret_cast<
534 : typelib_InterfaceMethodTypeDescription * >(
535 0 : member_td.get() );
536 : return bridge->call_uno(
537 : jni, pUnoI, member_td.get(),
538 : method_td->pReturnTypeRef,
539 : method_td->nParams, method_td->pParams,
540 0 : jo_args );
541 : }
542 : }
543 : else // attribute
544 : {
545 : OSL_ASSERT(
546 : typelib_TypeClass_INTERFACE_ATTRIBUTE ==
547 : member_type->eTypeClass );
548 :
549 0 : if (method_name.getLength() >= 3
550 0 : && (method_name.getLength() - 3 == remainder
551 0 : || (method_name.getLength() - 3 < remainder
552 : && type_name[
553 0 : offset + (method_name.getLength() - 3)] == ':'))
554 0 : && method_name[1] == 'e' && method_name[2] == 't'
555 : && rtl_ustr_compare_WithLength(
556 0 : type_name.getStr() + offset,
557 0 : method_name.getLength() - 3,
558 0 : method_name.getStr() + 3,
559 0 : method_name.getLength() - 3) == 0)
560 : {
561 0 : if ('g' == method_name[ 0 ])
562 : {
563 0 : TypeDescr member_td( member_type );
564 : typelib_InterfaceAttributeTypeDescription * attr_td =
565 : reinterpret_cast<
566 : typelib_InterfaceAttributeTypeDescription * >(
567 0 : member_td.get() );
568 : return bridge->call_uno(
569 : jni, pUnoI, member_td.get(),
570 : attr_td->pAttributeTypeRef,
571 : 0, 0,
572 0 : jo_args );
573 : }
574 0 : else if ('s' == method_name[ 0 ])
575 : {
576 0 : TypeDescr member_td( member_type );
577 : typelib_InterfaceAttributeTypeDescription * attr_td =
578 : reinterpret_cast<
579 : typelib_InterfaceAttributeTypeDescription * >(
580 0 : member_td.get() );
581 0 : if (! attr_td->bReadOnly)
582 : {
583 : typelib_MethodParameter param;
584 0 : param.pTypeRef = attr_td->pAttributeTypeRef;
585 0 : param.bIn = sal_True;
586 0 : param.bOut = sal_False;
587 : return bridge->call_uno(
588 : jni, pUnoI, member_td.get(),
589 : jni_info->m_void_type.getTypeLibType(),
590 : 1, ¶m,
591 0 : jo_args );
592 0 : }
593 : }
594 : }
595 : }
596 : }
597 : // the thing that should not be... no method info found!
598 0 : OUStringBuffer buf( 64 );
599 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
600 0 : "calling undeclared function on interface ") );
601 : buf.append( OUString::unacquired(
602 0 : &((typelib_TypeDescription *)td)->pTypeName ) );
603 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
604 0 : buf.append( method_name );
605 0 : buf.append( jni.get_stack_trace() );
606 0 : throw BridgeRuntimeError( buf.makeStringAndClear() );
607 : }
608 0 : catch (const BridgeRuntimeError & err)
609 : {
610 0 : OUStringBuffer buf( 128 );
611 : buf.appendAscii(
612 : RTL_CONSTASCII_STRINGPARAM("[jni_uno bridge error] "
613 0 : "Java calling UNO method ") );
614 0 : buf.append( method_name );
615 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
616 0 : buf.append( err.m_message );
617 : // notify RuntimeException
618 : OString cstr_msg(
619 : OUStringToOString(
620 0 : buf.makeStringAndClear(), RTL_TEXTENCODING_JAVA_UTF8 ) );
621 : OSL_FAIL( cstr_msg.getStr() );
622 0 : if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
623 : != 0)
624 : {
625 : OSL_ASSERT( false );
626 : }
627 0 : return 0;
628 : }
629 0 : catch (const ::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
630 : {
631 : OString cstr_msg(
632 : OString( RTL_CONSTASCII_STRINGPARAM(
633 : "[jni_uno bridge error] "
634 : "attaching current thread to java failed!") ) +
635 : OUStringToOString(
636 0 : jni.get_stack_trace(), RTL_TEXTENCODING_JAVA_UTF8 ) );
637 : OSL_FAIL( cstr_msg.getStr() );
638 0 : if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
639 : != 0)
640 : {
641 : OSL_ASSERT( false );
642 : }
643 0 : return 0;
644 0 : }
645 : }
646 :
647 : //------------------------------------------------------------------------------
648 : SAL_JNI_EXPORT void
649 0 : JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J(
650 : JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle )
651 : SAL_THROW_EXTERN_C()
652 : {
653 0 : Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
654 0 : JNI_info const * jni_info = bridge->m_jni_info;
655 : JNI_context jni(
656 : jni_info, jni_env,
657 : static_cast< jobject >(
658 : reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
659 0 : bridge->m_java_env->pContext )->getClassLoader() ) );
660 :
661 : uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
662 : jni->GetLongField(
663 0 : jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
664 : typelib_TypeDescription * td =
665 : reinterpret_cast< typelib_TypeDescription * >(
666 : jni->GetLongField(
667 0 : jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
668 :
669 : #if OSL_DEBUG_LEVEL > 1
670 : {
671 : JLocalAutoRef jo_oid(
672 : jni, jni->GetObjectField(
673 : jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
674 : OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
675 : OString cstr_msg(
676 : OUStringToOString(
677 : OUSTR("freeing java uno proxy: ") + oid,
678 : RTL_TEXTENCODING_ASCII_US ) );
679 : OSL_TRACE( "%s", cstr_msg.getStr() );
680 : }
681 : #endif
682 : // revoke from uno env; has already been revoked from java env
683 0 : (*bridge->m_uno_env->revokeInterface)( bridge->m_uno_env, pUnoI );
684 : // release receiver
685 0 : (*pUnoI->release)( pUnoI );
686 : // release typedescription handle
687 0 : typelib_typedescription_release( td );
688 : // release bridge handle
689 0 : bridge->release();
690 0 : }
691 :
692 : }
693 :
694 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|