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