bump product version to 6.3.0.0.beta1
[LibreOffice.git] / bridges / source / jni_uno / jni_uno2java.cxx
blob9b7c45c6185b7b860f7af4557ec282dc186d86f3
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 // a UNO proxy wrapping a Java interface
387 struct UNO_proxy : public uno_Interface
389 mutable std::atomic<std::size_t> m_ref;
390 Bridge const * m_bridge;
392 // mapping information
393 jobject m_javaI;
394 jstring m_jo_oid;
395 OUString m_oid;
396 JNI_interface_type_info const * m_type_info;
398 inline void acquire() const;
399 inline void release() const;
401 // ctor
402 inline UNO_proxy(
403 JNI_context const & jni, Bridge const * bridge,
404 jobject javaI, jstring jo_oid, OUString const & oid,
405 JNI_interface_type_info const * info );
409 inline UNO_proxy::UNO_proxy(
410 JNI_context const & jni, Bridge const * bridge,
411 jobject javaI, jstring jo_oid, OUString const & oid,
412 JNI_interface_type_info const * info )
413 : m_ref( 1 ),
414 m_oid( oid ),
415 m_type_info( info )
417 JNI_info const * jni_info = bridge->getJniInfo();
418 JLocalAutoRef jo_string_array(
419 jni, jni->NewObjectArray( 1, jni_info->m_class_String, jo_oid ) );
420 jni.ensure_no_exception();
421 jvalue args[ 3 ];
422 args[ 0 ].l = javaI;
423 args[ 1 ].l = jo_string_array.get();
424 args[ 2 ].l = info->m_type;
425 jobject jo_iface = jni->CallObjectMethodA(
426 jni_info->m_object_java_env,
427 jni_info->m_method_IEnvironment_registerInterface, args );
428 jni.ensure_no_exception();
430 m_javaI = jni->NewGlobalRef( jo_iface );
431 m_jo_oid = static_cast<jstring>(jni->NewGlobalRef( jo_oid ));
432 bridge->acquire();
433 m_bridge = bridge;
435 // uno_Interface
436 uno_Interface::acquire = UNO_proxy_acquire;
437 uno_Interface::release = UNO_proxy_release;
438 uno_Interface::pDispatcher = UNO_proxy_dispatch;
442 inline void UNO_proxy::acquire() const
444 if (++m_ref == 1)
446 // rebirth of proxy zombie
447 void * that = const_cast< UNO_proxy * >( this );
448 // register at uno env
449 (*m_bridge->m_uno_env->registerProxyInterface)(
450 m_bridge->m_uno_env, &that,
451 UNO_proxy_free, m_oid.pData,
452 reinterpret_cast<typelib_InterfaceTypeDescription *>(m_type_info->m_td.get()) );
453 assert( this == that );
458 inline void UNO_proxy::release() const
460 if (--m_ref == 0)
462 // revoke from uno env on last release
463 (*m_bridge->m_uno_env->revokeInterface)(
464 m_bridge->m_uno_env, const_cast< UNO_proxy * >( this ) );
469 uno_Interface * Bridge::map_to_uno(
470 JNI_context const & jni,
471 jobject javaI, JNI_interface_type_info const * info ) const
473 JLocalAutoRef jo_oid( jni, compute_oid( jni, javaI ) );
474 OUString oid( jstring_to_oustring( jni, static_cast<jstring>(jo_oid.get()) ) );
476 uno_Interface * pUnoI = nullptr;
477 (*m_uno_env->getRegisteredInterface)(
478 m_uno_env, reinterpret_cast<void **>(&pUnoI),
479 oid.pData, reinterpret_cast<typelib_InterfaceTypeDescription *>(info->m_td.get()) );
481 if (pUnoI == nullptr) // no existing interface, register new proxy
483 // refcount initially 1
484 pUnoI = new UNO_proxy(
485 jni, this,
486 javaI, static_cast<jstring>(jo_oid.get()), oid, info );
488 (*m_uno_env->registerProxyInterface)(
489 m_uno_env, reinterpret_cast<void **>(&pUnoI),
490 UNO_proxy_free,
491 oid.pData, reinterpret_cast<typelib_InterfaceTypeDescription *>(info->m_td.get()) );
493 return pUnoI;
498 using namespace ::jni_uno;
500 namespace
502 extern "C"
506 void UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
507 SAL_THROW_EXTERN_C()
509 UNO_proxy * that = static_cast< UNO_proxy * >( proxy );
510 Bridge const * bridge = that->m_bridge;
512 assert(env == bridge->m_uno_env); (void) env;
513 SAL_INFO("bridges", "freeing binary uno proxy: " << that->m_oid);
517 JNI_guarded_context jni(
518 bridge->getJniInfo(),
519 (static_cast<JniUnoEnvironmentData *>(bridge->m_java_env->pContext)
520 ->machine));
522 jni->DeleteGlobalRef( that->m_javaI );
523 jni->DeleteGlobalRef( that->m_jo_oid );
525 catch (BridgeRuntimeError & err)
527 SAL_WARN(
528 "bridges",
529 "ignoring BridgeRuntimeError \"" << err.m_message << "\"");
531 catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
533 SAL_WARN("bridges", "attaching current thread to java failed");
536 bridge->release();
537 #if OSL_DEBUG_LEVEL > 0
538 *reinterpret_cast<int *>(that) = 0xdeadcafe;
539 #endif
540 delete that;
544 void UNO_proxy_acquire( uno_Interface * pUnoI )
545 SAL_THROW_EXTERN_C()
547 UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
548 that->acquire();
552 void UNO_proxy_release( uno_Interface * pUnoI )
553 SAL_THROW_EXTERN_C()
555 UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
556 that->release();
560 void UNO_proxy_dispatch(
561 uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
562 void * uno_ret, void * uno_args [], uno_Any ** uno_exc )
563 SAL_THROW_EXTERN_C()
565 UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
566 Bridge const * bridge = that->m_bridge;
568 SAL_INFO(
569 "bridges",
570 "uno->java call: " << OUString::unacquired(&member_td->pTypeName)
571 << " on oid " << that->m_oid);
575 switch (member_td->eTypeClass)
577 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
579 typelib_InterfaceAttributeTypeDescription const * attrib_td =
580 reinterpret_cast<
581 typelib_InterfaceAttributeTypeDescription const * >(
582 member_td );
583 com::sun::star::uno::TypeDescription attrib_holder;
584 while ( attrib_td->pBaseRef != nullptr ) {
585 attrib_holder = com::sun::star::uno::TypeDescription(
586 attrib_td->pBaseRef );
587 assert(
588 attrib_holder.get()->eTypeClass
589 == typelib_TypeClass_INTERFACE_ATTRIBUTE );
590 attrib_td = reinterpret_cast<
591 typelib_InterfaceAttributeTypeDescription * >(
592 attrib_holder.get() );
594 typelib_InterfaceTypeDescription * iface_td = attrib_td->pInterface;
596 if (uno_ret == nullptr) // is setter method
598 typelib_MethodParameter param;
599 param.pTypeRef = attrib_td->pAttributeTypeRef;
600 param.bIn = true;
601 param.bOut = false;
603 bridge->call_java(
604 that->m_javaI, iface_td,
605 attrib_td->nIndex, 1, // get, then set method
606 bridge->getJniInfo()->m_void_type.getTypeLibType(),
607 &param, 1,
608 nullptr, uno_args, uno_exc );
610 else // is getter method
612 bridge->call_java(
613 that->m_javaI, iface_td, attrib_td->nIndex, 0,
614 attrib_td->pAttributeTypeRef,
615 nullptr, 0, // no params
616 uno_ret, nullptr, uno_exc );
618 break;
620 case typelib_TypeClass_INTERFACE_METHOD:
622 typelib_InterfaceMethodTypeDescription const * method_td =
623 reinterpret_cast<
624 typelib_InterfaceMethodTypeDescription const * >(
625 member_td );
626 com::sun::star::uno::TypeDescription method_holder;
627 while ( method_td->pBaseRef != nullptr ) {
628 method_holder = com::sun::star::uno::TypeDescription(
629 method_td->pBaseRef );
630 assert(
631 method_holder.get()->eTypeClass
632 == typelib_TypeClass_INTERFACE_METHOD );
633 method_td = reinterpret_cast<
634 typelib_InterfaceMethodTypeDescription * >(
635 method_holder.get() );
637 typelib_InterfaceTypeDescription * iface_td = method_td->pInterface;
639 switch ( method_td->aBase.nPosition )
641 case 0: // queryInterface()
643 TypeDescr demanded_td(
644 *static_cast< typelib_TypeDescriptionReference ** >(
645 uno_args[ 0 ] ) );
646 if (demanded_td.get()->eTypeClass !=
647 typelib_TypeClass_INTERFACE)
649 throw BridgeRuntimeError(
650 "queryInterface() call demands an INTERFACE type!" );
653 uno_Interface * pInterface = nullptr;
654 (*bridge->m_uno_env->getRegisteredInterface)(
655 bridge->m_uno_env,
656 reinterpret_cast<void **>(&pInterface), that->m_oid.pData,
657 reinterpret_cast<typelib_InterfaceTypeDescription *>(demanded_td.get()) );
659 if (pInterface == nullptr)
661 JNI_info const * jni_info = bridge->getJniInfo();
662 JNI_guarded_context jni(
663 jni_info,
664 (static_cast<JniUnoEnvironmentData *>(
665 bridge->m_java_env->pContext)
666 ->machine));
668 JNI_interface_type_info const * info =
669 static_cast< JNI_interface_type_info const * >(
670 jni_info->get_type_info( jni, demanded_td.get() ) );
672 jvalue args[ 2 ];
673 args[ 0 ].l = info->m_type;
674 args[ 1 ].l = that->m_javaI;
676 JLocalAutoRef jo_ret(
677 jni, jni->CallStaticObjectMethodA(
678 jni_info->m_class_UnoRuntime,
679 jni_info->m_method_UnoRuntime_queryInterface,
680 args ) );
682 if (jni->ExceptionCheck())
684 JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
685 jni->ExceptionClear();
686 bridge->handle_java_exc( jni, jo_exc, *uno_exc );
688 else
690 if (jo_ret.is())
692 SAL_WARN_IF(
693 (jstring_to_oustring(
694 jni,
695 static_cast<jstring>(
696 JLocalAutoRef(
697 jni, compute_oid(jni, jo_ret.get()))
698 .get()))
699 != that->m_oid),
700 "bridges", "different oids");
701 // refcount initially 1
702 uno_Interface * pUnoI2 = new UNO_proxy(
703 jni, bridge, jo_ret.get(),
704 that->m_jo_oid, that->m_oid, info );
706 (*bridge->m_uno_env->registerProxyInterface)(
707 bridge->m_uno_env,
708 reinterpret_cast<void **>(&pUnoI2),
709 UNO_proxy_free, that->m_oid.pData,
710 reinterpret_cast<
711 typelib_InterfaceTypeDescription * >(
712 info->m_td.get() ) );
714 uno_any_construct(
715 static_cast<uno_Any *>(uno_ret), &pUnoI2,
716 demanded_td.get(), nullptr );
717 (*pUnoI2->release)( pUnoI2 );
719 else // object does not support demanded interface
721 uno_any_construct(
722 static_cast< uno_Any * >( uno_ret ),
723 nullptr, nullptr, nullptr );
725 // no exception occurred
726 *uno_exc = nullptr;
729 else
731 uno_any_construct(
732 static_cast< uno_Any * >( uno_ret ),
733 &pInterface, demanded_td.get(), nullptr );
734 (*pInterface->release)( pInterface );
735 *uno_exc = nullptr;
737 break;
739 case 1: // acquire this proxy
740 that->acquire();
741 *uno_exc = nullptr;
742 break;
743 case 2: // release this proxy
744 that->release();
745 *uno_exc = nullptr;
746 break;
747 default: // arbitrary method call
748 bridge->call_java(
749 that->m_javaI, iface_td, method_td->nIndex, 0,
750 method_td->pReturnTypeRef,
751 method_td->pParams, method_td->nParams,
752 uno_ret, uno_args, uno_exc );
753 break;
755 break;
757 default:
759 throw BridgeRuntimeError(
760 "illegal member type description!" );
764 catch (BridgeRuntimeError & err)
766 OUStringBuffer buf( 128 );
767 buf.append( "[jni_uno bridge error] UNO calling Java method " );
768 if (member_td->eTypeClass == typelib_TypeClass_INTERFACE_METHOD ||
769 member_td->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE)
771 buf.append( OUString::unacquired(
772 &reinterpret_cast<
773 typelib_InterfaceMemberTypeDescription const * >(
774 member_td )->pMemberName ) );
776 buf.append( ": " );
777 buf.append( err.m_message );
778 // binary identical struct
779 ::com::sun::star::uno::RuntimeException exc(
780 buf.makeStringAndClear(),
781 ::com::sun::star::uno::Reference<
782 ::com::sun::star::uno::XInterface >() );
783 ::com::sun::star::uno::Type const & exc_type = cppu::UnoType<decltype(exc)>::get();
784 uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), nullptr );
785 SAL_INFO("bridges", exc.Message);
787 catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
789 // binary identical struct
790 ::com::sun::star::uno::RuntimeException exc(
791 "[jni_uno bridge error] attaching current thread to java failed!",
792 ::com::sun::star::uno::Reference<
793 ::com::sun::star::uno::XInterface >() );
794 ::com::sun::star::uno::Type const & exc_type = cppu::UnoType<decltype(exc)>::get();
795 uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), nullptr );
796 SAL_WARN("bridges", exc.Message);
803 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */