30#include <com/sun/star/uno/RuntimeException.hpp>
32#include <rtl/ustrbuf.hxx>
44void UNO_proxy_free( uno_ExtEnvironment * env,
void * proxy )
48void UNO_proxy_acquire( uno_Interface * pUnoI )
52void UNO_proxy_release( uno_Interface * pUnoI )
56void UNO_proxy_dispatch(
58 void * uno_ret,
void * uno_args[],
uno_Any ** uno_exc )
71 assert( jo_exc.
is() );
75 "java exception occurred, but no java exception available!?" +
81 jni, jni->CallObjectMethodA(
82 jo_class.
get(),
getJniInfo()->m_method_Class_getName,
nullptr ) );
87 css::uno::TypeDescription td( exc_name.pData );
88 if (!td.is() || (td.get()->eTypeClass != typelib_TypeClass_EXCEPTION))
92 jni, jni->CallObjectMethodA(
93 jo_exc.
get(),
getJniInfo()->m_method_Object_toString,
nullptr ) );
96 "non-UNO exception occurred: "
103 val.l = jo_exc.
get();
105 jni, uno_data.get(), val, td.get()->pWeakRef,
nullptr,
108#if OSL_DEBUG_LEVEL > 0
110 reinterpret_cast< css::uno::Exception *
>(
115 uno_exc->pType = td.get()->pWeakRef;
116 uno_exc->pData = uno_data.release();
120 "exception occurred uno->java: [" << exc_name <<
"] "
121 << (
static_cast<css::uno::Exception
const *
>(uno_exc->pData)
127 jobject javaI, typelib_InterfaceTypeDescription * iface_td,
128 sal_Int32 local_member_index, sal_Int32 function_pos_offset,
129 typelib_TypeDescriptionReference * return_type,
130 typelib_MethodParameter * params, sal_Int32 nParams,
131 void * uno_ret,
void * uno_args [],
uno_Any ** uno_exc )
const
133 assert( function_pos_offset == 0 || function_pos_offset == 1 );
140 css::uno::TypeDescription iface_holder;
141 if (! iface_td->aBase.bComplete) {
142 iface_holder = css::uno::TypeDescription(
144 iface_holder.makeComplete();
145 if (! iface_holder.get()->bComplete) {
147 "cannot make type complete: "
148 + OUString::unacquired(&iface_holder.get()->pTypeName)
151 iface_td =
reinterpret_cast<typelib_InterfaceTypeDescription *
>(
152 iface_holder.get() );
153 assert( iface_td->aBase.eTypeClass == typelib_TypeClass_INTERFACE );
157 jvalue * java_args =
static_cast<jvalue *
>(alloca(
sizeof (jvalue) * nParams ));
164 typelib_MethodParameter
const & param = params[
nPos ];
165 java_args[
nPos ].l =
nullptr;
167 jni, &java_args[
nPos ],
169 param.pTypeRef,
nullptr,
176 for ( sal_Int32
n = 0;
n <
nPos; ++
n )
178 typelib_MethodParameter
const & param = params[
n ];
180 typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
182 jni->DeleteLocalRef( java_args[
n ].l );
189 sal_Int32 base_members = iface_td->nAllMembers - iface_td->nMembers;
190 assert( base_members < iface_td->nAllMembers );
191 sal_Int32 base_members_function_pos =
192 iface_td->pMapMemberIndexToFunctionIndex[ base_members ];
193 sal_Int32 member_pos = base_members + local_member_index;
195 member_pos >= iface_td->nAllMembers,
"bridges",
196 "member pos out of range");
197 sal_Int32 function_pos =
198 iface_td->pMapMemberIndexToFunctionIndex[ member_pos ]
199 + function_pos_offset;
201 (function_pos < base_members_function_pos
202 || function_pos >= iface_td->nMapFunctionIndexToMemberIndex),
203 "bridges",
"illegal function index");
204 function_pos -= base_members_function_pos;
209 jmethodID method_id = info->
m_methods[ function_pos ];
211#if OSL_DEBUG_LEVEL > 0
213 jni, jni->ToReflectedMethod( info->
m_class, method_id, JNI_FALSE ) );
216 jni, jni->CallObjectMethodA(
217 jo_method.
get(),
getJniInfo()->m_method_Object_toString,
nullptr ) );
221 jni->CallObjectMethodA(
222 javaI,
getJniInfo()->m_method_Object_toString,
nullptr ) );
227 jni->CallObjectMethodA(
228 jo_class.
get(),
getJniInfo()->m_method_Object_toString,
nullptr ) );
240 switch (return_type->eTypeClass)
242 case typelib_TypeClass_VOID:
243 jni->CallVoidMethodA( javaI, method_id, java_args );
245 case typelib_TypeClass_CHAR:
247 jni->CallCharMethodA( javaI, method_id, java_args );
249 case typelib_TypeClass_BOOLEAN:
251 jni->CallBooleanMethodA( javaI, method_id, java_args );
253 case typelib_TypeClass_BYTE:
255 jni->CallByteMethodA( javaI, method_id, java_args );
257 case typelib_TypeClass_SHORT:
258 case typelib_TypeClass_UNSIGNED_SHORT:
259 *
static_cast<sal_Int16 *
>(uno_ret) =
260 jni->CallShortMethodA( javaI, method_id, java_args );
262 case typelib_TypeClass_LONG:
263 case typelib_TypeClass_UNSIGNED_LONG:
264 *
static_cast<sal_Int32 *
>(uno_ret) =
265 jni->CallIntMethodA( javaI, method_id, java_args );
267 case typelib_TypeClass_HYPER:
268 case typelib_TypeClass_UNSIGNED_HYPER:
269 *
static_cast<sal_Int64 *
>(uno_ret) =
270 jni->CallLongMethodA( javaI, method_id, java_args );
272 case typelib_TypeClass_FLOAT:
273 *
static_cast<float *
>(uno_ret) =
274 jni->CallFloatMethodA( javaI, method_id, java_args );
276 case typelib_TypeClass_DOUBLE:
277 *
static_cast<double *
>(uno_ret) =
278 jni->CallDoubleMethodA( javaI, method_id, java_args );
282 jni->CallObjectMethodA( javaI, method_id, java_args ) );
286 if (jni->ExceptionCheck())
289 jni->ExceptionClear();
294 typelib_MethodParameter
const & param = params[
nPos ];
296 typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
298 jni->DeleteLocalRef( java_args[
nPos ].l );
308 typelib_MethodParameter
const & param = params[
nPos ];
314 jni, uno_args[
nPos ],
315 java_args[
nPos ], param.pTypeRef,
nullptr,
322 for ( sal_Int32
n = 0;
n <
nPos; ++
n )
324 typelib_MethodParameter
const &
p = params[
n ];
328 uno_args[
n ],
p.pTypeRef,
nullptr );
334 typelib_MethodParameter
const &
p = params[
nPos ];
336 typelib_TypeClass_DOUBLE <
337 p.pTypeRef->eTypeClass)
339 jni->DeleteLocalRef( java_args[
nPos ].l );
344 jni->DeleteLocalRef( java_args[
nPos ].l );
348 if (typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
349 jni->DeleteLocalRef( java_args[
nPos ].l );
354 if (typelib_TypeClass_DOUBLE < return_type->eTypeClass)
359 val.l = java_ret.
get();
361 jni, uno_ret, val, return_type,
nullptr,
367 for ( sal_Int32
i = 0;
i < nParams; ++
i )
369 typelib_MethodParameter
const & param = params[
i ];
373 uno_args[
i ], param.pTypeRef,
nullptr );
388struct UNO_proxy :
public uno_Interface
390 mutable std::atomic<std::size_t>
m_ref;
399 inline void acquire()
const;
400 inline void release()
const;
404 JNI_context
const & jni, Bridge
const * bridge,
405 jobject javaI, jstring jo_oid, OUString oid,
406 JNI_interface_type_info
const * info );
411inline UNO_proxy::UNO_proxy(
412 JNI_context
const & jni, Bridge
const * bridge,
413 jobject javaI, jstring jo_oid, OUString oid,
414 JNI_interface_type_info
const * info )
419 JNI_info
const * jni_info = bridge->getJniInfo();
420 JLocalAutoRef jo_string_array(
421 jni, jni->NewObjectArray( 1, jni_info->m_class_String, jo_oid ) );
422 jni.ensure_no_exception();
425 args[ 1 ].l = jo_string_array.get();
426 args[ 2 ].l = info->m_type;
427 jobject jo_iface = jni->CallObjectMethodA(
428 jni_info->m_object_java_env,
429 jni_info->m_method_IEnvironment_registerInterface, args );
430 jni.ensure_no_exception();
432 m_javaI = jni->NewGlobalRef( jo_iface );
433 m_jo_oid =
static_cast<jstring
>(jni->NewGlobalRef( jo_oid ));
438 uno_Interface::acquire = UNO_proxy_acquire;
439 uno_Interface::release = UNO_proxy_release;
440 uno_Interface::pDispatcher = UNO_proxy_dispatch;
444inline void UNO_proxy::acquire()
const
449 void * that =
const_cast< UNO_proxy *
>( this );
451 (*
m_bridge->m_uno_env->registerProxyInterface)(
453 UNO_proxy_free,
m_oid.pData,
454 reinterpret_cast<typelib_InterfaceTypeDescription *
>(
m_type_info->m_td.get()) );
455 assert(
this == that );
460inline void UNO_proxy::release()
const
465 (*
m_bridge->m_uno_env->revokeInterface)(
466 m_bridge->m_uno_env,
const_cast< UNO_proxy *
>(
this ) );
471uno_Interface * Bridge::map_to_uno(
478 uno_Interface * pUnoI =
nullptr;
479 (*m_uno_env->getRegisteredInterface)(
480 m_uno_env,
reinterpret_cast<void **
>(&pUnoI),
481 oid.pData,
reinterpret_cast<typelib_InterfaceTypeDescription *
>(info->
m_td.get()) );
483 if (pUnoI ==
nullptr)
486 pUnoI =
new UNO_proxy(
488 javaI,
static_cast<jstring
>(jo_oid.
get()), oid, info );
490 (*m_uno_env->registerProxyInterface)(
491 m_uno_env,
reinterpret_cast<void **
>(&pUnoI),
493 oid.pData,
reinterpret_cast<typelib_InterfaceTypeDescription *
>(info->
m_td.get()) );
508void UNO_proxy_free( uno_ExtEnvironment * env,
void * proxy )
511 UNO_proxy * that =
static_cast< UNO_proxy *
>( proxy );
512 Bridge
const * bridge = that->m_bridge;
514 assert(env == bridge->m_uno_env); (void) env;
515 SAL_INFO(
"bridges",
"freeing binary uno proxy: " << that->m_oid);
519 JNI_guarded_context jni(
520 bridge->getJniInfo(),
521 (
static_cast<JniUnoEnvironmentData *
>(bridge->m_java_env->pContext)
524 jni->DeleteGlobalRef( that->m_javaI );
525 jni->DeleteGlobalRef( that->m_jo_oid );
531 "ignoring BridgeRuntimeError \"" <<
err.m_message <<
"\"");
535 SAL_WARN(
"bridges",
"attaching current thread to java failed");
539#if OSL_DEBUG_LEVEL > 0
540 *
reinterpret_cast<int *
>(that) = 0xdeadcafe;
546void UNO_proxy_acquire( uno_Interface * pUnoI )
549 UNO_proxy
const * that =
static_cast< UNO_proxy
const *
>( pUnoI );
554void UNO_proxy_release( uno_Interface * pUnoI )
557 UNO_proxy
const * that =
static_cast< UNO_proxy
const *
>( pUnoI );
562void UNO_proxy_dispatch(
564 void * uno_ret,
void * uno_args [],
uno_Any ** uno_exc )
567 UNO_proxy
const * that =
static_cast< UNO_proxy
const *
>( pUnoI );
568 Bridge
const * bridge = that->m_bridge;
572 "uno->java call: " << OUString::unacquired(&member_td->pTypeName)
573 <<
" on oid " << that->m_oid);
577 switch (member_td->eTypeClass)
579 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
581 typelib_InterfaceAttributeTypeDescription
const * attrib_td =
583 typelib_InterfaceAttributeTypeDescription
const *
>(
585 com::sun::star::uno::TypeDescription attrib_holder;
586 while ( attrib_td->pBaseRef !=
nullptr ) {
587 attrib_holder = com::sun::star::uno::TypeDescription(
588 attrib_td->pBaseRef );
590 attrib_holder.get()->eTypeClass
591 == typelib_TypeClass_INTERFACE_ATTRIBUTE );
592 attrib_td =
reinterpret_cast<
593 typelib_InterfaceAttributeTypeDescription *
>(
594 attrib_holder.get() );
596 typelib_InterfaceTypeDescription * iface_td = attrib_td->pInterface;
598 if (uno_ret ==
nullptr)
600 typelib_MethodParameter param;
601 param.pTypeRef = attrib_td->pAttributeTypeRef;
606 that->m_javaI, iface_td,
607 attrib_td->nIndex, 1,
608 bridge->getJniInfo()->m_void_type.getTypeLibType(),
610 nullptr, uno_args, uno_exc );
615 that->m_javaI, iface_td, attrib_td->nIndex, 0,
616 attrib_td->pAttributeTypeRef,
618 uno_ret,
nullptr, uno_exc );
622 case typelib_TypeClass_INTERFACE_METHOD:
624 typelib_InterfaceMethodTypeDescription
const * method_td =
626 typelib_InterfaceMethodTypeDescription
const *
>(
628 com::sun::star::uno::TypeDescription method_holder;
629 while ( method_td->pBaseRef !=
nullptr ) {
630 method_holder = com::sun::star::uno::TypeDescription(
631 method_td->pBaseRef );
633 method_holder.get()->eTypeClass
634 == typelib_TypeClass_INTERFACE_METHOD );
635 method_td =
reinterpret_cast<
636 typelib_InterfaceMethodTypeDescription *
>(
637 method_holder.get() );
639 typelib_InterfaceTypeDescription * iface_td = method_td->pInterface;
641 switch ( method_td->aBase.nPosition )
645 TypeDescr demanded_td(
646 *
static_cast< typelib_TypeDescriptionReference **
>(
648 if (demanded_td.get()->eTypeClass !=
649 typelib_TypeClass_INTERFACE)
652 "queryInterface() call demands an INTERFACE type!" );
655 uno_Interface * pInterface =
nullptr;
656 (*bridge->m_uno_env->getRegisteredInterface)(
658 reinterpret_cast<void **
>(&pInterface), that->m_oid.pData,
659 reinterpret_cast<typelib_InterfaceTypeDescription *
>(demanded_td.get()) );
661 if (pInterface ==
nullptr)
663 JNI_info
const * jni_info = bridge->getJniInfo();
664 JNI_guarded_context jni(
666 (
static_cast<JniUnoEnvironmentData *
>(
667 bridge->m_java_env->pContext)
670 JNI_interface_type_info
const * info =
671 static_cast< JNI_interface_type_info
const *
>(
672 jni_info->get_type_info( jni, demanded_td.get() ) );
675 args[ 0 ].l = info->m_type;
676 args[ 1 ].l = that->m_javaI;
678 JLocalAutoRef jo_ret(
679 jni, jni->CallStaticObjectMethodA(
680 jni_info->m_class_UnoRuntime,
681 jni_info->m_method_UnoRuntime_queryInterface,
684 if (jni->ExceptionCheck())
686 JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
687 jni->ExceptionClear();
688 bridge->handle_java_exc( jni, jo_exc, *uno_exc );
697 static_cast<jstring
>(
702 "bridges",
"different oids");
704 uno_Interface * pUnoI2 =
new UNO_proxy(
705 jni, bridge, jo_ret.get(),
706 that->m_jo_oid, that->m_oid, info );
708 (*bridge->m_uno_env->registerProxyInterface)(
710 reinterpret_cast<void **
>(&pUnoI2),
711 UNO_proxy_free, that->m_oid.pData,
713 typelib_InterfaceTypeDescription *
>(
714 info->m_td.get() ) );
717 static_cast<uno_Any *
>(uno_ret), &pUnoI2,
718 demanded_td.get(),
nullptr );
719 (*pUnoI2->release)( pUnoI2 );
724 static_cast< uno_Any *
>( uno_ret ),
725 nullptr,
nullptr,
nullptr );
734 static_cast< uno_Any *
>( uno_ret ),
735 &pInterface, demanded_td.get(),
nullptr );
736 (*pInterface->release)( pInterface );
751 that->m_javaI, iface_td, method_td->nIndex, 0,
752 method_td->pReturnTypeRef,
753 method_td->pParams, method_td->nParams,
754 uno_ret, uno_args, uno_exc );
762 "illegal member type description!" );
768 OUStringBuffer buf( 128 );
769 buf.append(
"[jni_uno bridge error] UNO calling Java method " );
770 if (member_td->eTypeClass == typelib_TypeClass_INTERFACE_METHOD ||
771 member_td->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE)
773 buf.append( OUString::unacquired(
775 typelib_InterfaceMemberTypeDescription
const *
>(
776 member_td )->pMemberName ) );
778 buf.append(
": " +
err.m_message );
780 css::uno::RuntimeException exc(
781 buf.makeStringAndClear(),
783 css::uno::XInterface >() );
784 css::uno::Type
const & exc_type =
cppu::UnoType<
decltype(exc)>::get();
791 css::uno::RuntimeException exc(
792 "[jni_uno bridge error] attaching current thread to java failed!",
794 css::uno::XInterface >() );
795 css::uno::Type
const & exc_type =
cppu::UnoType<
decltype(exc)>::get();
void SAL_CALL uno_any_construct(uno_Any *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_AcquireFunc acquire) SAL_THROW_EXTERN_C()
void SAL_CALL uno_type_any_construct(uno_Any *pDest, void *pSource, typelib_TypeDescriptionReference *pType, uno_AcquireFunc acquire) SAL_THROW_EXTERN_C()
OUString get_stack_trace(jobject jo_exc=nullptr) const
void ensure_no_exception() const
JNI_type_info const * get_type_info(JNI_context const &jni, typelib_TypeDescription *type) const
void SAL_CALL uno_type_destructData(void *pValue, typelib_TypeDescriptionReference *pType, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
JNI_interface_type_info const * m_type_info
std::atomic< std::size_t > m_ref
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
struct _typelib_TypeDescription typelib_TypeDescription
OUString jstring_to_oustring(JNI_context const &jni, jstring jstr)
jobject compute_oid(JNI_context const &jni, jobject jo)
void map_to_java(JNI_context const &jni, jvalue *java_data, void const *uno_data, typelib_TypeDescriptionReference *type, JNI_type_info const *info, bool in_param, bool out_param, bool special_wrapped_integral_types=false) const
void map_to_uno(JNI_context const &jni, void *uno_data, jvalue java_data, typelib_TypeDescriptionReference *type, JNI_type_info const *info, bool assign, bool out_param, bool special_wrapped_integral_types=false) const
void call_java(jobject javaI, typelib_InterfaceTypeDescription *iface_td, sal_Int32 local_member_index, sal_Int32 function_pos_offset, typelib_TypeDescriptionReference *return_type, typelib_MethodParameter *params, sal_Int32 nParams, void *uno_ret, void *uno_args[], uno_Any **uno_exc) const
JNI_info const * getJniInfo() const
void handle_java_exc(JNI_context const &jni, JLocalAutoRef const &jo_exc, uno_Any *uno_exc) const
uno_Environment * m_java_env
std::unique_ptr< jmethodID[]> m_methods
::com::sun::star::uno::TypeDescription m_td
rtl::Reference< jvmaccess::UnoVirtualMachine > const machine
static rtl_mem * allocate(std::size_t bytes)
void SAL_CALL typelib_typedescriptionreference_acquire(typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
#define SAL_THROW_EXTERN_C()