bump product version to 5.0.4.1
[LibreOffice.git] / bridges / source / jni_uno / jni_uno2java.cxx
blob749db52ad2d086297b393351df31b3adb4be025c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <cassert>
23 #include <memory>
25 #include <sal/alloca.h>
27 #include "com/sun/star/uno/RuntimeException.hpp"
29 #include "rtl/ustrbuf.hxx"
31 #include "jni_bridge.h"
32 #include "jniunoenvironmentdata.hxx"
34 namespace
36 extern "C"
40 void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
41 SAL_THROW_EXTERN_C();
44 void SAL_CALL UNO_proxy_acquire( uno_Interface * pUnoI )
45 SAL_THROW_EXTERN_C();
48 void SAL_CALL UNO_proxy_release( uno_Interface * pUnoI )
49 SAL_THROW_EXTERN_C();
52 void SAL_CALL UNO_proxy_dispatch(
53 uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
54 void * uno_ret, void * uno_args[], uno_Any ** uno_exc )
55 SAL_THROW_EXTERN_C();
59 namespace jni_uno
63 void Bridge::handle_java_exc(
64 JNI_context const & jni,
65 JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) const
67 assert( jo_exc.is() );
68 if (! jo_exc.is())
70 throw BridgeRuntimeError(
71 "java exception occurred, but no java exception available!?" +
72 jni.get_stack_trace() );
75 JLocalAutoRef jo_class( jni, jni->GetObjectClass( jo_exc.get() ) );
76 JLocalAutoRef jo_class_name(
77 jni, jni->CallObjectMethodA(
78 jo_class.get(), getJniInfo()->m_method_Class_getName, 0 ) );
79 jni.ensure_no_exception();
80 OUString exc_name(
81 jstring_to_oustring( jni, static_cast<jstring>(jo_class_name.get()) ) );
83 ::com::sun::star::uno::TypeDescription td( exc_name.pData );
84 if (!td.is() || (typelib_TypeClass_EXCEPTION != td.get()->eTypeClass))
86 // call toString()
87 JLocalAutoRef jo_descr(
88 jni, jni->CallObjectMethodA(
89 jo_exc.get(), getJniInfo()->m_method_Object_toString, 0 ) );
90 jni.ensure_no_exception();
91 throw BridgeRuntimeError(
92 "non-UNO exception occurred: "
93 + jstring_to_oustring( jni, static_cast<jstring>(jo_descr.get()) )
94 + jni.get_stack_trace( jo_exc.get() ) );
97 std::unique_ptr< rtl_mem > uno_data( rtl_mem::allocate( td.get()->nSize ) );
98 jvalue val;
99 val.l = jo_exc.get();
100 map_to_uno(
101 jni, uno_data.get(), val, td.get()->pWeakRef, 0,
102 false /* no assign */, false /* no out param */ );
104 #if OSL_DEBUG_LEVEL > 0
105 // patch Message, append stack trace
106 reinterpret_cast< ::com::sun::star::uno::Exception * >(
107 uno_data.get() )->Message += jni.get_stack_trace( jo_exc.get() );
108 #endif
110 typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
111 uno_exc->pType = td.get()->pWeakRef;
112 uno_exc->pData = uno_data.release();
114 SAL_INFO(
115 "bridges",
116 "exception occurred uno->java: [" << exc_name << "] "
117 << (static_cast<css::uno::Exception const *>(uno_exc->pData)
118 ->Message));
122 void Bridge::call_java(
123 jobject javaI, typelib_InterfaceTypeDescription * iface_td,
124 sal_Int32 local_member_index, sal_Int32 function_pos_offset,
125 typelib_TypeDescriptionReference * return_type,
126 typelib_MethodParameter * params, sal_Int32 nParams,
127 void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const
129 assert( function_pos_offset == 0 || function_pos_offset == 1 );
131 JNI_guarded_context jni(
132 getJniInfo(),
133 static_cast<JniUnoEnvironmentData *>(m_java_env->pContext)->machine);
135 // assure fully initialized iface_td:
136 ::com::sun::star::uno::TypeDescription iface_holder;
137 if (! iface_td->aBase.bComplete) {
138 iface_holder = ::com::sun::star::uno::TypeDescription(
139 reinterpret_cast<typelib_TypeDescription *>(iface_td) );
140 iface_holder.makeComplete();
141 if (! iface_holder.get()->bComplete) {
142 throw BridgeRuntimeError(
143 "cannot make type complete: "
144 + OUString::unacquired(&iface_holder.get()->pTypeName)
145 + jni.get_stack_trace() );
147 iface_td = reinterpret_cast<typelib_InterfaceTypeDescription *>(
148 iface_holder.get() );
149 assert( iface_td->aBase.eTypeClass == typelib_TypeClass_INTERFACE );
152 // prepare java args, save param td
153 #ifdef BROKEN_ALLOCA
154 jvalue * java_args = (jvalue *) malloc( sizeof (jvalue) * nParams );
155 #else
156 jvalue * java_args = static_cast<jvalue *>(alloca( sizeof (jvalue) * nParams ));
157 #endif
159 sal_Int32 nPos;
160 for ( nPos = 0; nPos < nParams; ++nPos )
164 typelib_MethodParameter const & param = params[ nPos ];
165 java_args[ nPos ].l = 0; // if out: build up array[ 1 ]
166 map_to_java(
167 jni, &java_args[ nPos ],
168 uno_args[ nPos ],
169 param.pTypeRef, 0,
170 sal_False != param.bIn /* convert uno value */,
171 sal_False != param.bOut /* build up array[ 1 ] */ );
173 catch (...)
175 // cleanup
176 for ( sal_Int32 n = 0; n < nPos; ++n )
178 typelib_MethodParameter const & param = params[ n ];
179 if (param.bOut ||
180 typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
182 jni->DeleteLocalRef( java_args[ n ].l );
185 #ifdef BROKEN_ALLOCA
186 free( java_args );
187 #endif
188 throw;
192 sal_Int32 base_members = iface_td->nAllMembers - iface_td->nMembers;
193 assert( base_members < iface_td->nAllMembers );
194 sal_Int32 base_members_function_pos =
195 iface_td->pMapMemberIndexToFunctionIndex[ base_members ];
196 sal_Int32 member_pos = base_members + local_member_index;
197 SAL_WARN_IF(
198 member_pos >= iface_td->nAllMembers, "bridges",
199 "member pos out of range");
200 sal_Int32 function_pos =
201 iface_td->pMapMemberIndexToFunctionIndex[ member_pos ]
202 + function_pos_offset;
203 SAL_WARN_IF(
204 (function_pos < base_members_function_pos
205 || function_pos >= iface_td->nMapFunctionIndexToMemberIndex),
206 "bridges", "illegal function index");
207 function_pos -= base_members_function_pos;
209 JNI_interface_type_info const * info =
210 static_cast< JNI_interface_type_info const * >(
211 getJniInfo()->get_type_info( jni, &iface_td->aBase ) );
212 jmethodID method_id = info->m_methods[ function_pos ];
214 #if OSL_DEBUG_LEVEL > 0
215 OUStringBuffer trace_buf( 128 );
216 trace_buf.append( "calling " );
217 JLocalAutoRef jo_method(
218 jni, jni->ToReflectedMethod( info->m_class, method_id, JNI_FALSE ) );
219 jni.ensure_no_exception();
220 JLocalAutoRef jo_descr(
221 jni, jni->CallObjectMethodA(
222 jo_method.get(), getJniInfo()->m_method_Object_toString, 0 ) );
223 jni.ensure_no_exception();
224 trace_buf.append( jstring_to_oustring( jni, static_cast<jstring>(jo_descr.get()) ) );
225 trace_buf.append( " on " );
226 jo_descr.reset(
227 jni->CallObjectMethodA(
228 javaI, getJniInfo()->m_method_Object_toString, 0 ) );
229 jni.ensure_no_exception();
230 trace_buf.append( jstring_to_oustring( jni, static_cast<jstring>(jo_descr.get()) ) );
231 trace_buf.append( " (" );
232 JLocalAutoRef jo_class( jni, jni->GetObjectClass( javaI ) );
233 jo_descr.reset(
234 jni->CallObjectMethodA(
235 jo_class.get(), getJniInfo()->m_method_Object_toString, 0 ) );
236 jni.ensure_no_exception();
237 trace_buf.append( jstring_to_oustring( jni, static_cast<jstring>(jo_descr.get()) ) );
238 trace_buf.append( ")" );
239 SAL_INFO("bridges", trace_buf.makeStringAndClear());
240 #endif
242 // complex return value
243 JLocalAutoRef java_ret( jni );
245 switch (return_type->eTypeClass)
247 case typelib_TypeClass_VOID:
248 jni->CallVoidMethodA( javaI, method_id, java_args );
249 break;
250 case typelib_TypeClass_CHAR:
251 *static_cast<sal_Unicode *>(uno_ret) =
252 jni->CallCharMethodA( javaI, method_id, java_args );
253 break;
254 case typelib_TypeClass_BOOLEAN:
255 *static_cast<sal_Bool *>(uno_ret) =
256 jni->CallBooleanMethodA( javaI, method_id, java_args );
257 break;
258 case typelib_TypeClass_BYTE:
259 *static_cast<sal_Int8 *>(uno_ret) =
260 jni->CallByteMethodA( javaI, method_id, java_args );
261 break;
262 case typelib_TypeClass_SHORT:
263 case typelib_TypeClass_UNSIGNED_SHORT:
264 *static_cast<sal_Int16 *>(uno_ret) =
265 jni->CallShortMethodA( javaI, method_id, java_args );
266 break;
267 case typelib_TypeClass_LONG:
268 case typelib_TypeClass_UNSIGNED_LONG:
269 *static_cast<sal_Int32 *>(uno_ret) =
270 jni->CallIntMethodA( javaI, method_id, java_args );
271 break;
272 case typelib_TypeClass_HYPER:
273 case typelib_TypeClass_UNSIGNED_HYPER:
274 *static_cast<sal_Int64 *>(uno_ret) =
275 jni->CallLongMethodA( javaI, method_id, java_args );
276 break;
277 case typelib_TypeClass_FLOAT:
278 *static_cast<float *>(uno_ret) =
279 jni->CallFloatMethodA( javaI, method_id, java_args );
280 break;
281 case typelib_TypeClass_DOUBLE:
282 *static_cast<double *>(uno_ret) =
283 jni->CallDoubleMethodA( javaI, method_id, java_args );
284 break;
285 default:
286 java_ret.reset(
287 jni->CallObjectMethodA( javaI, method_id, java_args ) );
288 break;
291 if (jni->ExceptionCheck())
293 JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
294 jni->ExceptionClear();
296 // release temp java local refs
297 for ( nPos = 0; nPos < nParams; ++nPos )
299 typelib_MethodParameter const & param = params[ nPos ];
300 if (param.bOut ||
301 typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
303 jni->DeleteLocalRef( java_args[ nPos ].l );
307 handle_java_exc( jni, jo_exc, *uno_exc );
309 else // no exception
311 for ( nPos = 0; nPos < nParams; ++nPos )
313 typelib_MethodParameter const & param = params[ nPos ];
314 if (param.bOut)
318 map_to_uno(
319 jni, uno_args[ nPos ],
320 java_args[ nPos ], param.pTypeRef, 0,
321 sal_False != param.bIn /* assign if inout */,
322 true /* out param */ );
324 catch (...)
326 // cleanup uno pure out
327 for ( sal_Int32 n = 0; n < nPos; ++n )
329 typelib_MethodParameter const & p = params[ n ];
330 if (! p.bIn)
332 uno_type_destructData(
333 uno_args[ n ], p.pTypeRef, 0 );
336 // cleanup java temp local refs
337 for ( ; nPos < nParams; ++nPos )
339 typelib_MethodParameter const & p = params[ nPos ];
340 if (p.bOut ||
341 typelib_TypeClass_DOUBLE <
342 p.pTypeRef->eTypeClass)
344 jni->DeleteLocalRef( java_args[ nPos ].l );
347 #ifdef BROKEN_ALLOCA
348 free( java_args );
349 #endif
350 throw;
352 jni->DeleteLocalRef( java_args[ nPos ].l );
354 else // pure temp in param
356 if (typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
357 jni->DeleteLocalRef( java_args[ nPos ].l );
361 // return value
362 if (typelib_TypeClass_DOUBLE < return_type->eTypeClass)
366 jvalue val;
367 val.l = java_ret.get();
368 map_to_uno(
369 jni, uno_ret, val, return_type, 0,
370 false /* no assign */, false /* no out param */ );
372 catch (...)
374 // cleanup uno pure out
375 for ( sal_Int32 i = 0; i < nParams; ++i )
377 typelib_MethodParameter const & param = params[ i ];
378 if (! param.bIn)
380 uno_type_destructData(
381 uno_args[ i ], param.pTypeRef, 0 );
384 #ifdef BROKEN_ALLOCA
385 free( java_args );
386 #endif
387 throw;
389 } // else: already set integral uno return value
391 // no exception occurred
392 *uno_exc = 0;
394 #ifdef BROKEN_ALLOCA
395 free( java_args );
396 #endif
399 // an UNO proxy wrapping a Java interface
400 struct UNO_proxy : public uno_Interface
402 mutable oslInterlockedCount m_ref;
403 Bridge const * m_bridge;
405 // mapping information
406 jobject m_javaI;
407 jstring m_jo_oid;
408 OUString m_oid;
409 JNI_interface_type_info const * m_type_info;
411 inline void acquire() const;
412 inline void release() const;
414 // ctor
415 inline UNO_proxy(
416 JNI_context const & jni, Bridge const * bridge,
417 jobject javaI, jstring jo_oid, OUString const & oid,
418 JNI_interface_type_info const * info );
422 inline UNO_proxy::UNO_proxy(
423 JNI_context const & jni, Bridge const * bridge,
424 jobject javaI, jstring jo_oid, OUString const & oid,
425 JNI_interface_type_info const * info )
426 : m_ref( 1 ),
427 m_oid( oid ),
428 m_type_info( info )
430 JNI_info const * jni_info = bridge->getJniInfo();
431 JLocalAutoRef jo_string_array(
432 jni, jni->NewObjectArray( 1, jni_info->m_class_String, jo_oid ) );
433 jni.ensure_no_exception();
434 jvalue args[ 3 ];
435 args[ 0 ].l = javaI;
436 args[ 1 ].l = jo_string_array.get();
437 args[ 2 ].l = info->m_type;
438 jobject jo_iface = jni->CallObjectMethodA(
439 jni_info->m_object_java_env,
440 jni_info->m_method_IEnvironment_registerInterface, args );
441 jni.ensure_no_exception();
443 m_javaI = jni->NewGlobalRef( jo_iface );
444 m_jo_oid = static_cast<jstring>(jni->NewGlobalRef( jo_oid ));
445 bridge->acquire();
446 m_bridge = bridge;
448 // uno_Interface
449 uno_Interface::acquire = UNO_proxy_acquire;
450 uno_Interface::release = UNO_proxy_release;
451 uno_Interface::pDispatcher = UNO_proxy_dispatch;
455 inline void UNO_proxy::acquire() const
457 if (1 == osl_atomic_increment( &m_ref ))
459 // rebirth of proxy zombie
460 void * that = const_cast< UNO_proxy * >( this );
461 // register at uno env
462 (*m_bridge->m_uno_env->registerProxyInterface)(
463 m_bridge->m_uno_env, &that,
464 UNO_proxy_free, m_oid.pData,
465 reinterpret_cast<typelib_InterfaceTypeDescription *>(m_type_info->m_td.get()) );
466 assert( this == that );
471 inline void UNO_proxy::release() const
473 if (0 == osl_atomic_decrement( &m_ref ))
475 // revoke from uno env on last release
476 (*m_bridge->m_uno_env->revokeInterface)(
477 m_bridge->m_uno_env, const_cast< UNO_proxy * >( this ) );
483 uno_Interface * Bridge::map_to_uno(
484 JNI_context const & jni,
485 jobject javaI, JNI_interface_type_info const * info ) const
487 JLocalAutoRef jo_oid( jni, compute_oid( jni, javaI ) );
488 OUString oid( jstring_to_oustring( jni, static_cast<jstring>(jo_oid.get()) ) );
490 uno_Interface * pUnoI = 0;
491 (*m_uno_env->getRegisteredInterface)(
492 m_uno_env, reinterpret_cast<void **>(&pUnoI),
493 oid.pData, reinterpret_cast<typelib_InterfaceTypeDescription *>(info->m_td.get()) );
495 if (0 == pUnoI) // no existing interface, register new proxy
497 // refcount initially 1
498 pUnoI = new UNO_proxy(
499 jni, this,
500 javaI, static_cast<jstring>(jo_oid.get()), oid, info );
502 (*m_uno_env->registerProxyInterface)(
503 m_uno_env, reinterpret_cast<void **>(&pUnoI),
504 UNO_proxy_free,
505 oid.pData, reinterpret_cast<typelib_InterfaceTypeDescription *>(info->m_td.get()) );
507 return pUnoI;
512 using namespace ::jni_uno;
514 namespace
516 extern "C"
520 void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
521 SAL_THROW_EXTERN_C()
523 UNO_proxy * that = static_cast< UNO_proxy * >( proxy );
524 Bridge const * bridge = that->m_bridge;
526 assert(env == bridge->m_uno_env); (void) env;
527 SAL_INFO("bridges", "freeing binary uno proxy: " << that->m_oid);
531 JNI_guarded_context jni(
532 bridge->getJniInfo(),
533 (static_cast<JniUnoEnvironmentData *>(bridge->m_java_env->pContext)
534 ->machine));
536 jni->DeleteGlobalRef( that->m_javaI );
537 jni->DeleteGlobalRef( that->m_jo_oid );
539 catch (BridgeRuntimeError & err)
541 SAL_WARN(
542 "bridges",
543 "ignoring BridgeRuntimeError \"" << err.m_message << "\"");
545 catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
547 SAL_WARN("bridges", "attaching current thread to java failed");
550 bridge->release();
551 #if OSL_DEBUG_LEVEL > 0
552 *reinterpret_cast<int *>(that) = 0xdeadcafe;
553 #endif
554 delete that;
558 void SAL_CALL UNO_proxy_acquire( uno_Interface * pUnoI )
559 SAL_THROW_EXTERN_C()
561 UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
562 that->acquire();
566 void SAL_CALL UNO_proxy_release( uno_Interface * pUnoI )
567 SAL_THROW_EXTERN_C()
569 UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
570 that->release();
574 void SAL_CALL UNO_proxy_dispatch(
575 uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
576 void * uno_ret, void * uno_args [], uno_Any ** uno_exc )
577 SAL_THROW_EXTERN_C()
579 UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
580 Bridge const * bridge = that->m_bridge;
582 SAL_INFO(
583 "bridges",
584 "uno->java call: " << OUString::unacquired(&member_td->pTypeName)
585 << " on oid " << that->m_oid);
589 switch (member_td->eTypeClass)
591 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
593 typelib_InterfaceAttributeTypeDescription const * attrib_td =
594 reinterpret_cast<
595 typelib_InterfaceAttributeTypeDescription const * >(
596 member_td );
597 com::sun::star::uno::TypeDescription attrib_holder;
598 while ( attrib_td->pBaseRef != 0 ) {
599 attrib_holder = com::sun::star::uno::TypeDescription(
600 attrib_td->pBaseRef );
601 assert(
602 attrib_holder.get()->eTypeClass
603 == typelib_TypeClass_INTERFACE_ATTRIBUTE );
604 attrib_td = reinterpret_cast<
605 typelib_InterfaceAttributeTypeDescription * >(
606 attrib_holder.get() );
608 typelib_InterfaceTypeDescription * iface_td = attrib_td->pInterface;
610 if (0 == uno_ret) // is setter method
612 typelib_MethodParameter param;
613 param.pTypeRef = attrib_td->pAttributeTypeRef;
614 param.bIn = sal_True;
615 param.bOut = sal_False;
617 bridge->call_java(
618 that->m_javaI, iface_td,
619 attrib_td->nIndex, 1, // get, then set method
620 bridge->getJniInfo()->m_void_type.getTypeLibType(),
621 &param, 1,
622 0, uno_args, uno_exc );
624 else // is getter method
626 bridge->call_java(
627 that->m_javaI, iface_td, attrib_td->nIndex, 0,
628 attrib_td->pAttributeTypeRef,
629 0, 0, // no params
630 uno_ret, 0, uno_exc );
632 break;
634 case typelib_TypeClass_INTERFACE_METHOD:
636 typelib_InterfaceMethodTypeDescription const * method_td =
637 reinterpret_cast<
638 typelib_InterfaceMethodTypeDescription const * >(
639 member_td );
640 com::sun::star::uno::TypeDescription method_holder;
641 while ( method_td->pBaseRef != 0 ) {
642 method_holder = com::sun::star::uno::TypeDescription(
643 method_td->pBaseRef );
644 assert(
645 method_holder.get()->eTypeClass
646 == typelib_TypeClass_INTERFACE_METHOD );
647 method_td = reinterpret_cast<
648 typelib_InterfaceMethodTypeDescription * >(
649 method_holder.get() );
651 typelib_InterfaceTypeDescription * iface_td = method_td->pInterface;
653 switch ( method_td->aBase.nPosition )
655 case 0: // queryInterface()
657 TypeDescr demanded_td(
658 *static_cast< typelib_TypeDescriptionReference ** >(
659 uno_args[ 0 ] ) );
660 if (typelib_TypeClass_INTERFACE !=
661 demanded_td.get()->eTypeClass)
663 throw BridgeRuntimeError(
664 "queryInterface() call demands an INTERFACE type!" );
667 uno_Interface * pInterface = 0;
668 (*bridge->m_uno_env->getRegisteredInterface)(
669 bridge->m_uno_env,
670 reinterpret_cast<void **>(&pInterface), that->m_oid.pData,
671 reinterpret_cast<typelib_InterfaceTypeDescription *>(demanded_td.get()) );
673 if (0 == pInterface)
675 JNI_info const * jni_info = bridge->getJniInfo();
676 JNI_guarded_context jni(
677 jni_info,
678 (static_cast<JniUnoEnvironmentData *>(
679 bridge->m_java_env->pContext)
680 ->machine));
682 JNI_interface_type_info const * info =
683 static_cast< JNI_interface_type_info const * >(
684 jni_info->get_type_info( jni, demanded_td.get() ) );
686 jvalue args[ 2 ];
687 args[ 0 ].l = info->m_type;
688 args[ 1 ].l = that->m_javaI;
690 JLocalAutoRef jo_ret(
691 jni, jni->CallStaticObjectMethodA(
692 jni_info->m_class_UnoRuntime,
693 jni_info->m_method_UnoRuntime_queryInterface,
694 args ) );
696 if (jni->ExceptionCheck())
698 JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
699 jni->ExceptionClear();
700 bridge->handle_java_exc( jni, jo_exc, *uno_exc );
702 else
704 if (jo_ret.is())
706 SAL_WARN_IF(
707 (jstring_to_oustring(
708 jni,
709 static_cast<jstring>(
710 JLocalAutoRef(
711 jni, compute_oid(jni, jo_ret.get()))
712 .get()))
713 != that->m_oid),
714 "bridges", "different oids");
715 // refcount initially 1
716 uno_Interface * pUnoI2 = new UNO_proxy(
717 jni, bridge, jo_ret.get(),
718 that->m_jo_oid, that->m_oid, info );
720 (*bridge->m_uno_env->registerProxyInterface)(
721 bridge->m_uno_env,
722 reinterpret_cast<void **>(&pUnoI2),
723 UNO_proxy_free, that->m_oid.pData,
724 reinterpret_cast<
725 typelib_InterfaceTypeDescription * >(
726 info->m_td.get() ) );
728 uno_any_construct(
729 static_cast<uno_Any *>(uno_ret), &pUnoI2,
730 demanded_td.get(), 0 );
731 (*pUnoI2->release)( pUnoI2 );
733 else // object does not support demanded interface
735 uno_any_construct(
736 static_cast< uno_Any * >( uno_ret ),
737 0, 0, 0 );
739 // no exception occurred
740 *uno_exc = 0;
743 else
745 uno_any_construct(
746 static_cast< uno_Any * >( uno_ret ),
747 &pInterface, demanded_td.get(), 0 );
748 (*pInterface->release)( pInterface );
749 *uno_exc = 0;
751 break;
753 case 1: // acquire this proxy
754 that->acquire();
755 *uno_exc = 0;
756 break;
757 case 2: // release this proxy
758 that->release();
759 *uno_exc = 0;
760 break;
761 default: // arbitrary method call
762 bridge->call_java(
763 that->m_javaI, iface_td, method_td->nIndex, 0,
764 method_td->pReturnTypeRef,
765 method_td->pParams, method_td->nParams,
766 uno_ret, uno_args, uno_exc );
767 break;
769 break;
771 default:
773 throw BridgeRuntimeError(
774 "illegal member type description!" );
778 catch (BridgeRuntimeError & err)
780 OUStringBuffer buf( 128 );
781 buf.append( "[jni_uno bridge error] UNO calling Java method " );
782 if (typelib_TypeClass_INTERFACE_METHOD == member_td->eTypeClass ||
783 typelib_TypeClass_INTERFACE_ATTRIBUTE == member_td->eTypeClass)
785 buf.append( OUString::unacquired(
786 &reinterpret_cast<
787 typelib_InterfaceMemberTypeDescription const * >(
788 member_td )->pMemberName ) );
790 buf.append( ": " );
791 buf.append( err.m_message );
792 // binary identical struct
793 ::com::sun::star::uno::RuntimeException exc(
794 buf.makeStringAndClear(),
795 ::com::sun::star::uno::Reference<
796 ::com::sun::star::uno::XInterface >() );
797 ::com::sun::star::uno::Type const & exc_type = cppu::UnoType<decltype(exc)>::get();
798 uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 );
799 SAL_INFO("bridges", exc.Message);
801 catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
803 // binary identical struct
804 ::com::sun::star::uno::RuntimeException exc(
805 "[jni_uno bridge error] attaching current thread to java failed!",
806 ::com::sun::star::uno::Reference<
807 ::com::sun::star::uno::XInterface >() );
808 ::com::sun::star::uno::Type const & exc_type = cppu::UnoType<decltype(exc)>::get();
809 uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 );
810 SAL_WARN("bridges", exc.Message);
817 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */