nss: upgrade to release 3.73
[LibreOffice.git] / bridges / source / jni_uno / jni_uno2java.cxx
blobeb152c110ec75389bda782ed770f6b3057eb12b5
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>
21 #include <sal/log.hxx>
23 #include <atomic>
24 #include <cassert>
25 #include <cstddef>
26 #include <memory>
28 #include <sal/alloca.h>
30 #include <com/sun/star/uno/RuntimeException.hpp>
32 #include <rtl/ustrbuf.hxx>
34 #include "jni_bridge.h"
35 #include "jniunoenvironmentdata.hxx"
37 namespace
39 extern "C"
43 void UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
44 SAL_THROW_EXTERN_C();
47 void UNO_proxy_acquire( uno_Interface * pUnoI )
48 SAL_THROW_EXTERN_C();
51 void UNO_proxy_release( uno_Interface * pUnoI )
52 SAL_THROW_EXTERN_C();
55 void UNO_proxy_dispatch(
56 uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
57 void * uno_ret, void * uno_args[], uno_Any ** uno_exc )
58 SAL_THROW_EXTERN_C();
62 namespace jni_uno
66 void Bridge::handle_java_exc(
67 JNI_context const & jni,
68 JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) const
70 assert( jo_exc.is() );
71 if (! jo_exc.is())
73 throw BridgeRuntimeError(
74 "java exception occurred, but no java exception available!?" +
75 jni.get_stack_trace() );
78 JLocalAutoRef jo_class( jni, jni->GetObjectClass( jo_exc.get() ) );
79 JLocalAutoRef jo_class_name(
80 jni, jni->CallObjectMethodA(
81 jo_class.get(), getJniInfo()->m_method_Class_getName, nullptr ) );
82 jni.ensure_no_exception();
83 OUString exc_name(
84 jstring_to_oustring( jni, static_cast<jstring>(jo_class_name.get()) ) );
86 ::com::sun::star::uno::TypeDescription td( exc_name.pData );
87 if (!td.is() || (td.get()->eTypeClass != typelib_TypeClass_EXCEPTION))
89 // call toString()
90 JLocalAutoRef jo_descr(
91 jni, jni->CallObjectMethodA(
92 jo_exc.get(), getJniInfo()->m_method_Object_toString, nullptr ) );
93 jni.ensure_no_exception();
94 throw BridgeRuntimeError(
95 "non-UNO exception occurred: "
96 + jstring_to_oustring( jni, static_cast<jstring>(jo_descr.get()) )
97 + jni.get_stack_trace( jo_exc.get() ) );
100 std::unique_ptr< rtl_mem > uno_data( rtl_mem::allocate( td.get()->nSize ) );
101 jvalue val;
102 val.l = jo_exc.get();
103 map_to_uno(
104 jni, uno_data.get(), val, td.get()->pWeakRef, nullptr,
105 false /* no assign */, false /* no out param */ );
107 #if OSL_DEBUG_LEVEL > 0
108 // patch Message, append stack trace
109 reinterpret_cast< ::com::sun::star::uno::Exception * >(
110 uno_data.get() )->Message += jni.get_stack_trace( jo_exc.get() );
111 #endif
113 typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
114 uno_exc->pType = td.get()->pWeakRef;
115 uno_exc->pData = uno_data.release();
117 SAL_INFO(
118 "bridges",
119 "exception occurred uno->java: [" << exc_name << "] "
120 << (static_cast<css::uno::Exception const *>(uno_exc->pData)
121 ->Message));
125 void Bridge::call_java(
126 jobject javaI, typelib_InterfaceTypeDescription * iface_td,
127 sal_Int32 local_member_index, sal_Int32 function_pos_offset,
128 typelib_TypeDescriptionReference * return_type,
129 typelib_MethodParameter * params, sal_Int32 nParams,
130 void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const
132 assert( function_pos_offset == 0 || function_pos_offset == 1 );
134 JNI_guarded_context jni(
135 getJniInfo(),
136 static_cast<JniUnoEnvironmentData *>(m_java_env->pContext)->machine);
138 // assure fully initialized iface_td:
139 ::com::sun::star::uno::TypeDescription iface_holder;
140 if (! iface_td->aBase.bComplete) {
141 iface_holder = ::com::sun::star::uno::TypeDescription(
142 reinterpret_cast<typelib_TypeDescription *>(iface_td) );
143 iface_holder.makeComplete();
144 if (! iface_holder.get()->bComplete) {
145 throw BridgeRuntimeError(
146 "cannot make type complete: "
147 + OUString::unacquired(&iface_holder.get()->pTypeName)
148 + jni.get_stack_trace() );
150 iface_td = reinterpret_cast<typelib_InterfaceTypeDescription *>(
151 iface_holder.get() );
152 assert( iface_td->aBase.eTypeClass == typelib_TypeClass_INTERFACE );
155 // prepare java args, save param td
156 jvalue * java_args = static_cast<jvalue *>(alloca( sizeof (jvalue) * nParams ));
158 sal_Int32 nPos;
159 for ( nPos = 0; nPos < nParams; ++nPos )
163 typelib_MethodParameter const & param = params[ nPos ];
164 java_args[ nPos ].l = nullptr; // if out: build up array[ 1 ]
165 map_to_java(
166 jni, &java_args[ nPos ],
167 uno_args[ nPos ],
168 param.pTypeRef, nullptr,
169 param.bIn /* convert uno value */,
170 param.bOut /* build up array[ 1 ] */ );
172 catch (...)
174 // cleanup
175 for ( sal_Int32 n = 0; n < nPos; ++n )
177 typelib_MethodParameter const & param = params[ n ];
178 if (param.bOut ||
179 typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
181 jni->DeleteLocalRef( java_args[ n ].l );
184 throw;
188 sal_Int32 base_members = iface_td->nAllMembers - iface_td->nMembers;
189 assert( base_members < iface_td->nAllMembers );
190 sal_Int32 base_members_function_pos =
191 iface_td->pMapMemberIndexToFunctionIndex[ base_members ];
192 sal_Int32 member_pos = base_members + local_member_index;
193 SAL_WARN_IF(
194 member_pos >= iface_td->nAllMembers, "bridges",
195 "member pos out of range");
196 sal_Int32 function_pos =
197 iface_td->pMapMemberIndexToFunctionIndex[ member_pos ]
198 + function_pos_offset;
199 SAL_WARN_IF(
200 (function_pos < base_members_function_pos
201 || function_pos >= iface_td->nMapFunctionIndexToMemberIndex),
202 "bridges", "illegal function index");
203 function_pos -= base_members_function_pos;
205 JNI_interface_type_info const * info =
206 static_cast< JNI_interface_type_info const * >(
207 getJniInfo()->get_type_info( jni, &iface_td->aBase ) );
208 jmethodID method_id = info->m_methods[ function_pos ];
210 #if OSL_DEBUG_LEVEL > 0
211 OUStringBuffer trace_buf( 128 );
212 trace_buf.append( "calling " );
213 JLocalAutoRef jo_method(
214 jni, jni->ToReflectedMethod( info->m_class, method_id, JNI_FALSE ) );
215 jni.ensure_no_exception();
216 JLocalAutoRef jo_descr(
217 jni, jni->CallObjectMethodA(
218 jo_method.get(), getJniInfo()->m_method_Object_toString, nullptr ) );
219 jni.ensure_no_exception();
220 trace_buf.append( jstring_to_oustring( jni, static_cast<jstring>(jo_descr.get()) ) );
221 trace_buf.append( " on " );
222 jo_descr.reset(
223 jni->CallObjectMethodA(
224 javaI, getJniInfo()->m_method_Object_toString, nullptr ) );
225 jni.ensure_no_exception();
226 trace_buf.append( jstring_to_oustring( jni, static_cast<jstring>(jo_descr.get()) ) );
227 trace_buf.append( " (" );
228 JLocalAutoRef jo_class( jni, jni->GetObjectClass( javaI ) );
229 jo_descr.reset(
230 jni->CallObjectMethodA(
231 jo_class.get(), getJniInfo()->m_method_Object_toString, nullptr ) );
232 jni.ensure_no_exception();
233 trace_buf.append( jstring_to_oustring( jni, static_cast<jstring>(jo_descr.get()) ) );
234 trace_buf.append( ")" );
235 SAL_INFO("bridges", trace_buf.makeStringAndClear());
236 #endif
238 // complex return value
239 JLocalAutoRef java_ret( jni );
241 switch (return_type->eTypeClass)
243 case typelib_TypeClass_VOID:
244 jni->CallVoidMethodA( javaI, method_id, java_args );
245 break;
246 case typelib_TypeClass_CHAR:
247 *static_cast<sal_Unicode *>(uno_ret) =
248 jni->CallCharMethodA( javaI, method_id, java_args );
249 break;
250 case typelib_TypeClass_BOOLEAN:
251 *static_cast<sal_Bool *>(uno_ret) =
252 jni->CallBooleanMethodA( javaI, method_id, java_args );
253 break;
254 case typelib_TypeClass_BYTE:
255 *static_cast<sal_Int8 *>(uno_ret) =
256 jni->CallByteMethodA( javaI, method_id, java_args );
257 break;
258 case typelib_TypeClass_SHORT:
259 case typelib_TypeClass_UNSIGNED_SHORT:
260 *static_cast<sal_Int16 *>(uno_ret) =
261 jni->CallShortMethodA( javaI, method_id, java_args );
262 break;
263 case typelib_TypeClass_LONG:
264 case typelib_TypeClass_UNSIGNED_LONG:
265 *static_cast<sal_Int32 *>(uno_ret) =
266 jni->CallIntMethodA( javaI, method_id, java_args );
267 break;
268 case typelib_TypeClass_HYPER:
269 case typelib_TypeClass_UNSIGNED_HYPER:
270 *static_cast<sal_Int64 *>(uno_ret) =
271 jni->CallLongMethodA( javaI, method_id, java_args );
272 break;
273 case typelib_TypeClass_FLOAT:
274 *static_cast<float *>(uno_ret) =
275 jni->CallFloatMethodA( javaI, method_id, java_args );
276 break;
277 case typelib_TypeClass_DOUBLE:
278 *static_cast<double *>(uno_ret) =
279 jni->CallDoubleMethodA( javaI, method_id, java_args );
280 break;
281 default:
282 java_ret.reset(
283 jni->CallObjectMethodA( javaI, method_id, java_args ) );
284 break;
287 if (jni->ExceptionCheck())
289 JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
290 jni->ExceptionClear();
292 // release temp java local refs
293 for ( nPos = 0; nPos < nParams; ++nPos )
295 typelib_MethodParameter const & param = params[ nPos ];
296 if (param.bOut ||
297 typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
299 jni->DeleteLocalRef( java_args[ nPos ].l );
303 handle_java_exc( jni, jo_exc, *uno_exc );
305 else // no exception
307 for ( nPos = 0; nPos < nParams; ++nPos )
309 typelib_MethodParameter const & param = params[ nPos ];
310 if (param.bOut)
314 map_to_uno(
315 jni, uno_args[ nPos ],
316 java_args[ nPos ], param.pTypeRef, nullptr,
317 param.bIn /* assign if inout */,
318 true /* out param */ );
320 catch (...)
322 // cleanup uno pure out
323 for ( sal_Int32 n = 0; n < nPos; ++n )
325 typelib_MethodParameter const & p = params[ n ];
326 if (! p.bIn)
328 uno_type_destructData(
329 uno_args[ n ], p.pTypeRef, nullptr );
332 // cleanup java temp local refs
333 for ( ; nPos < nParams; ++nPos )
335 typelib_MethodParameter const & p = params[ nPos ];
336 if (p.bOut ||
337 typelib_TypeClass_DOUBLE <
338 p.pTypeRef->eTypeClass)
340 jni->DeleteLocalRef( java_args[ nPos ].l );
343 throw;
345 jni->DeleteLocalRef( java_args[ nPos ].l );
347 else // pure temp in param
349 if (typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
350 jni->DeleteLocalRef( java_args[ nPos ].l );
354 // return value
355 if (typelib_TypeClass_DOUBLE < return_type->eTypeClass)
359 jvalue val;
360 val.l = java_ret.get();
361 map_to_uno(
362 jni, uno_ret, val, return_type, nullptr,
363 false /* no assign */, false /* no out param */ );
365 catch (...)
367 // cleanup uno pure out
368 for ( sal_Int32 i = 0; i < nParams; ++i )
370 typelib_MethodParameter const & param = params[ i ];
371 if (! param.bIn)
373 uno_type_destructData(
374 uno_args[ i ], param.pTypeRef, nullptr );
377 throw;
379 } // else: already set integral uno return value
381 // no exception occurred
382 *uno_exc = nullptr;
386 namespace {
388 // a UNO proxy wrapping a Java interface
389 struct UNO_proxy : public uno_Interface
391 mutable std::atomic<std::size_t> m_ref;
392 Bridge const * m_bridge;
394 // mapping information
395 jobject m_javaI;
396 jstring m_jo_oid;
397 OUString m_oid;
398 JNI_interface_type_info const * m_type_info;
400 inline void acquire() const;
401 inline void release() const;
403 // ctor
404 inline UNO_proxy(
405 JNI_context const & jni, Bridge const * bridge,
406 jobject javaI, jstring jo_oid, OUString const & oid,
407 JNI_interface_type_info const * info );
412 inline UNO_proxy::UNO_proxy(
413 JNI_context const & jni, Bridge const * bridge,
414 jobject javaI, jstring jo_oid, OUString const & oid,
415 JNI_interface_type_info const * info )
416 : m_ref( 1 ),
417 m_oid( oid ),
418 m_type_info( info )
420 JNI_info const * jni_info = bridge->getJniInfo();
421 JLocalAutoRef jo_string_array(
422 jni, jni->NewObjectArray( 1, jni_info->m_class_String, jo_oid ) );
423 jni.ensure_no_exception();
424 jvalue args[ 3 ];
425 args[ 0 ].l = javaI;
426 args[ 1 ].l = jo_string_array.get();
427 args[ 2 ].l = info->m_type;
428 jobject jo_iface = jni->CallObjectMethodA(
429 jni_info->m_object_java_env,
430 jni_info->m_method_IEnvironment_registerInterface, args );
431 jni.ensure_no_exception();
433 m_javaI = jni->NewGlobalRef( jo_iface );
434 m_jo_oid = static_cast<jstring>(jni->NewGlobalRef( jo_oid ));
435 bridge->acquire();
436 m_bridge = bridge;
438 // uno_Interface
439 uno_Interface::acquire = UNO_proxy_acquire;
440 uno_Interface::release = UNO_proxy_release;
441 uno_Interface::pDispatcher = UNO_proxy_dispatch;
445 inline void UNO_proxy::acquire() const
447 if (++m_ref == 1)
449 // rebirth of proxy zombie
450 void * that = const_cast< UNO_proxy * >( this );
451 // register at uno env
452 (*m_bridge->m_uno_env->registerProxyInterface)(
453 m_bridge->m_uno_env, &that,
454 UNO_proxy_free, m_oid.pData,
455 reinterpret_cast<typelib_InterfaceTypeDescription *>(m_type_info->m_td.get()) );
456 assert( this == that );
461 inline void UNO_proxy::release() const
463 if (--m_ref == 0)
465 // revoke from uno env on last release
466 (*m_bridge->m_uno_env->revokeInterface)(
467 m_bridge->m_uno_env, const_cast< UNO_proxy * >( this ) );
472 uno_Interface * Bridge::map_to_uno(
473 JNI_context const & jni,
474 jobject javaI, JNI_interface_type_info const * info ) const
476 JLocalAutoRef jo_oid( jni, compute_oid( jni, javaI ) );
477 OUString oid( jstring_to_oustring( jni, static_cast<jstring>(jo_oid.get()) ) );
479 uno_Interface * pUnoI = nullptr;
480 (*m_uno_env->getRegisteredInterface)(
481 m_uno_env, reinterpret_cast<void **>(&pUnoI),
482 oid.pData, reinterpret_cast<typelib_InterfaceTypeDescription *>(info->m_td.get()) );
484 if (pUnoI == nullptr) // no existing interface, register new proxy
486 // refcount initially 1
487 pUnoI = new UNO_proxy(
488 jni, this,
489 javaI, static_cast<jstring>(jo_oid.get()), oid, info );
491 (*m_uno_env->registerProxyInterface)(
492 m_uno_env, reinterpret_cast<void **>(&pUnoI),
493 UNO_proxy_free,
494 oid.pData, reinterpret_cast<typelib_InterfaceTypeDescription *>(info->m_td.get()) );
496 return pUnoI;
501 using namespace ::jni_uno;
503 namespace
505 extern "C"
509 void UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
510 SAL_THROW_EXTERN_C()
512 UNO_proxy * that = static_cast< UNO_proxy * >( proxy );
513 Bridge const * bridge = that->m_bridge;
515 assert(env == bridge->m_uno_env); (void) env;
516 SAL_INFO("bridges", "freeing binary uno proxy: " << that->m_oid);
520 JNI_guarded_context jni(
521 bridge->getJniInfo(),
522 (static_cast<JniUnoEnvironmentData *>(bridge->m_java_env->pContext)
523 ->machine));
525 jni->DeleteGlobalRef( that->m_javaI );
526 jni->DeleteGlobalRef( that->m_jo_oid );
528 catch (BridgeRuntimeError & err)
530 SAL_WARN(
531 "bridges",
532 "ignoring BridgeRuntimeError \"" << err.m_message << "\"");
534 catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
536 SAL_WARN("bridges", "attaching current thread to java failed");
539 bridge->release();
540 #if OSL_DEBUG_LEVEL > 0
541 *reinterpret_cast<int *>(that) = 0xdeadcafe;
542 #endif
543 delete that;
547 void UNO_proxy_acquire( uno_Interface * pUnoI )
548 SAL_THROW_EXTERN_C()
550 UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
551 that->acquire();
555 void UNO_proxy_release( uno_Interface * pUnoI )
556 SAL_THROW_EXTERN_C()
558 UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
559 that->release();
563 void UNO_proxy_dispatch(
564 uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
565 void * uno_ret, void * uno_args [], uno_Any ** uno_exc )
566 SAL_THROW_EXTERN_C()
568 UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
569 Bridge const * bridge = that->m_bridge;
571 SAL_INFO(
572 "bridges",
573 "uno->java call: " << OUString::unacquired(&member_td->pTypeName)
574 << " on oid " << that->m_oid);
578 switch (member_td->eTypeClass)
580 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
582 typelib_InterfaceAttributeTypeDescription const * attrib_td =
583 reinterpret_cast<
584 typelib_InterfaceAttributeTypeDescription const * >(
585 member_td );
586 com::sun::star::uno::TypeDescription attrib_holder;
587 while ( attrib_td->pBaseRef != nullptr ) {
588 attrib_holder = com::sun::star::uno::TypeDescription(
589 attrib_td->pBaseRef );
590 assert(
591 attrib_holder.get()->eTypeClass
592 == typelib_TypeClass_INTERFACE_ATTRIBUTE );
593 attrib_td = reinterpret_cast<
594 typelib_InterfaceAttributeTypeDescription * >(
595 attrib_holder.get() );
597 typelib_InterfaceTypeDescription * iface_td = attrib_td->pInterface;
599 if (uno_ret == nullptr) // is setter method
601 typelib_MethodParameter param;
602 param.pTypeRef = attrib_td->pAttributeTypeRef;
603 param.bIn = true;
604 param.bOut = false;
606 bridge->call_java(
607 that->m_javaI, iface_td,
608 attrib_td->nIndex, 1, // get, then set method
609 bridge->getJniInfo()->m_void_type.getTypeLibType(),
610 &param, 1,
611 nullptr, uno_args, uno_exc );
613 else // is getter method
615 bridge->call_java(
616 that->m_javaI, iface_td, attrib_td->nIndex, 0,
617 attrib_td->pAttributeTypeRef,
618 nullptr, 0, // no params
619 uno_ret, nullptr, uno_exc );
621 break;
623 case typelib_TypeClass_INTERFACE_METHOD:
625 typelib_InterfaceMethodTypeDescription const * method_td =
626 reinterpret_cast<
627 typelib_InterfaceMethodTypeDescription const * >(
628 member_td );
629 com::sun::star::uno::TypeDescription method_holder;
630 while ( method_td->pBaseRef != nullptr ) {
631 method_holder = com::sun::star::uno::TypeDescription(
632 method_td->pBaseRef );
633 assert(
634 method_holder.get()->eTypeClass
635 == typelib_TypeClass_INTERFACE_METHOD );
636 method_td = reinterpret_cast<
637 typelib_InterfaceMethodTypeDescription * >(
638 method_holder.get() );
640 typelib_InterfaceTypeDescription * iface_td = method_td->pInterface;
642 switch ( method_td->aBase.nPosition )
644 case 0: // queryInterface()
646 TypeDescr demanded_td(
647 *static_cast< typelib_TypeDescriptionReference ** >(
648 uno_args[ 0 ] ) );
649 if (demanded_td.get()->eTypeClass !=
650 typelib_TypeClass_INTERFACE)
652 throw BridgeRuntimeError(
653 "queryInterface() call demands an INTERFACE type!" );
656 uno_Interface * pInterface = nullptr;
657 (*bridge->m_uno_env->getRegisteredInterface)(
658 bridge->m_uno_env,
659 reinterpret_cast<void **>(&pInterface), that->m_oid.pData,
660 reinterpret_cast<typelib_InterfaceTypeDescription *>(demanded_td.get()) );
662 if (pInterface == nullptr)
664 JNI_info const * jni_info = bridge->getJniInfo();
665 JNI_guarded_context jni(
666 jni_info,
667 (static_cast<JniUnoEnvironmentData *>(
668 bridge->m_java_env->pContext)
669 ->machine));
671 JNI_interface_type_info const * info =
672 static_cast< JNI_interface_type_info const * >(
673 jni_info->get_type_info( jni, demanded_td.get() ) );
675 jvalue args[ 2 ];
676 args[ 0 ].l = info->m_type;
677 args[ 1 ].l = that->m_javaI;
679 JLocalAutoRef jo_ret(
680 jni, jni->CallStaticObjectMethodA(
681 jni_info->m_class_UnoRuntime,
682 jni_info->m_method_UnoRuntime_queryInterface,
683 args ) );
685 if (jni->ExceptionCheck())
687 JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
688 jni->ExceptionClear();
689 bridge->handle_java_exc( jni, jo_exc, *uno_exc );
691 else
693 if (jo_ret.is())
695 SAL_WARN_IF(
696 (jstring_to_oustring(
697 jni,
698 static_cast<jstring>(
699 JLocalAutoRef(
700 jni, compute_oid(jni, jo_ret.get()))
701 .get()))
702 != that->m_oid),
703 "bridges", "different oids");
704 // refcount initially 1
705 uno_Interface * pUnoI2 = new UNO_proxy(
706 jni, bridge, jo_ret.get(),
707 that->m_jo_oid, that->m_oid, info );
709 (*bridge->m_uno_env->registerProxyInterface)(
710 bridge->m_uno_env,
711 reinterpret_cast<void **>(&pUnoI2),
712 UNO_proxy_free, that->m_oid.pData,
713 reinterpret_cast<
714 typelib_InterfaceTypeDescription * >(
715 info->m_td.get() ) );
717 uno_any_construct(
718 static_cast<uno_Any *>(uno_ret), &pUnoI2,
719 demanded_td.get(), nullptr );
720 (*pUnoI2->release)( pUnoI2 );
722 else // object does not support demanded interface
724 uno_any_construct(
725 static_cast< uno_Any * >( uno_ret ),
726 nullptr, nullptr, nullptr );
728 // no exception occurred
729 *uno_exc = nullptr;
732 else
734 uno_any_construct(
735 static_cast< uno_Any * >( uno_ret ),
736 &pInterface, demanded_td.get(), nullptr );
737 (*pInterface->release)( pInterface );
738 *uno_exc = nullptr;
740 break;
742 case 1: // acquire this proxy
743 that->acquire();
744 *uno_exc = nullptr;
745 break;
746 case 2: // release this proxy
747 that->release();
748 *uno_exc = nullptr;
749 break;
750 default: // arbitrary method call
751 bridge->call_java(
752 that->m_javaI, iface_td, method_td->nIndex, 0,
753 method_td->pReturnTypeRef,
754 method_td->pParams, method_td->nParams,
755 uno_ret, uno_args, uno_exc );
756 break;
758 break;
760 default:
762 throw BridgeRuntimeError(
763 "illegal member type description!" );
767 catch (BridgeRuntimeError & err)
769 OUStringBuffer buf( 128 );
770 buf.append( "[jni_uno bridge error] UNO calling Java method " );
771 if (member_td->eTypeClass == typelib_TypeClass_INTERFACE_METHOD ||
772 member_td->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE)
774 buf.append( OUString::unacquired(
775 &reinterpret_cast<
776 typelib_InterfaceMemberTypeDescription const * >(
777 member_td )->pMemberName ) );
779 buf.append( ": " );
780 buf.append( err.m_message );
781 // binary identical struct
782 ::com::sun::star::uno::RuntimeException exc(
783 buf.makeStringAndClear(),
784 ::com::sun::star::uno::Reference<
785 ::com::sun::star::uno::XInterface >() );
786 ::com::sun::star::uno::Type const & exc_type = cppu::UnoType<decltype(exc)>::get();
787 uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), nullptr );
788 SAL_INFO("bridges", exc.Message);
790 catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
792 // binary identical struct
793 ::com::sun::star::uno::RuntimeException exc(
794 "[jni_uno bridge error] attaching current thread to java failed!",
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(), nullptr );
799 SAL_WARN("bridges", exc.Message);
806 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */