30 #include <com/sun/star/uno/RuntimeException.hpp>
32 #include <rtl/ustrbuf.hxx>
43 void UNO_proxy_free( uno_ExtEnvironment * env,
void * proxy )
47 void UNO_proxy_acquire( uno_Interface * pUnoI )
51 void UNO_proxy_release( uno_Interface * pUnoI )
55 void UNO_proxy_dispatch(
57 void * uno_ret,
void * uno_args[],
uno_Any ** uno_exc )
74 "java exception occurred, but no java exception available!?" +
80 jni, jni->CallObjectMethodA(
86 ::com::sun::star::uno::TypeDescription td( exc_name.pData );
87 if (!td.is() || (td.get()->eTypeClass != typelib_TypeClass_EXCEPTION))
91 jni, jni->CallObjectMethodA(
95 "non-UNO exception occurred: "
102 val.l = jo_exc.
get();
104 jni, uno_data.get(), val, td.get()->pWeakRef,
nullptr,
107 #if OSL_DEBUG_LEVEL > 0
109 reinterpret_cast< ::com::sun::star::uno::Exception *
>(
114 uno_exc->pType = td.get()->pWeakRef;
115 uno_exc->pData = uno_data.release();
119 "exception occurred uno->java: [" << exc_name <<
"] "
120 << (static_cast<css::uno::Exception const *>(uno_exc->pData)
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 );
136 static_cast<JniUnoEnvironmentData *>(
m_java_env->pContext)->machine);
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) {
146 "cannot make type complete: "
147 + OUString::unacquired(&iface_holder.get()->pTypeName)
150 iface_td =
reinterpret_cast<typelib_InterfaceTypeDescription *
>(
151 iface_holder.get() );
152 assert( iface_td->aBase.eTypeClass == typelib_TypeClass_INTERFACE );
156 jvalue * java_args =
static_cast<jvalue *
>(alloca(
sizeof (jvalue) * nParams ));
159 for ( nPos = 0; nPos < nParams; ++nPos )
163 typelib_MethodParameter
const & param = params[ nPos ];
164 java_args[ nPos ].l =
nullptr;
166 jni, &java_args[ nPos ],
168 param.pTypeRef,
nullptr,
175 for ( sal_Int32
n = 0;
n < nPos; ++
n )
177 typelib_MethodParameter
const & param = params[
n ];
179 typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
181 jni->DeleteLocalRef( java_args[
n ].l );
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;
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;
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;
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 " );
214 jni, jni->ToReflectedMethod( info->
m_class, method_id, JNI_FALSE ) );
217 jni, jni->CallObjectMethodA(
221 trace_buf.append(
" on " );
223 jni->CallObjectMethodA(
224 javaI,
getJniInfo()->m_method_Object_toString,
nullptr ) );
227 trace_buf.append(
" (" );
230 jni->CallObjectMethodA(
234 trace_buf.append(
")" );
235 SAL_INFO(
"bridges", trace_buf.makeStringAndClear());
241 switch (return_type->eTypeClass)
243 case typelib_TypeClass_VOID:
244 jni->CallVoidMethodA( javaI, method_id, java_args );
246 case typelib_TypeClass_CHAR:
248 jni->CallCharMethodA( javaI, method_id, java_args );
250 case typelib_TypeClass_BOOLEAN:
252 jni->CallBooleanMethodA( javaI, method_id, java_args );
254 case typelib_TypeClass_BYTE:
256 jni->CallByteMethodA( javaI, method_id, java_args );
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 );
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 );
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 );
273 case typelib_TypeClass_FLOAT:
274 *
static_cast<float *
>(uno_ret) =
275 jni->CallFloatMethodA( javaI, method_id, java_args );
277 case typelib_TypeClass_DOUBLE:
278 *
static_cast<double *
>(uno_ret) =
279 jni->CallDoubleMethodA( javaI, method_id, java_args );
283 jni->CallObjectMethodA( javaI, method_id, java_args ) );
287 if (jni->ExceptionCheck())
290 jni->ExceptionClear();
293 for ( nPos = 0; nPos < nParams; ++nPos )
295 typelib_MethodParameter
const & param = params[ nPos ];
297 typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
299 jni->DeleteLocalRef( java_args[ nPos ].l );
307 for ( nPos = 0; nPos < nParams; ++nPos )
309 typelib_MethodParameter
const & param = params[ nPos ];
315 jni, uno_args[ nPos ],
316 java_args[ nPos ], param.pTypeRef,
nullptr,
323 for ( sal_Int32
n = 0;
n < nPos; ++
n )
325 typelib_MethodParameter
const &
p = params[
n ];
329 uno_args[
n ], p.pTypeRef,
nullptr );
333 for ( ; nPos < nParams; ++nPos )
335 typelib_MethodParameter
const &
p = params[ nPos ];
337 typelib_TypeClass_DOUBLE <
338 p.pTypeRef->eTypeClass)
340 jni->DeleteLocalRef( java_args[ nPos ].l );
345 jni->DeleteLocalRef( java_args[ nPos ].l );
349 if (typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
350 jni->DeleteLocalRef( java_args[ nPos ].l );
355 if (typelib_TypeClass_DOUBLE < return_type->eTypeClass)
360 val.l = java_ret.get();
362 jni, uno_ret, val, return_type,
nullptr,
368 for ( sal_Int32
i = 0;
i < nParams; ++
i )
370 typelib_MethodParameter
const & param = params[
i ];
374 uno_args[
i ], param.pTypeRef,
nullptr );
389 struct UNO_proxy :
public uno_Interface
391 mutable std::atomic<std::size_t>
m_ref;
400 inline void acquire()
const;
401 inline void release()
const;
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 )
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();
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 ));
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
450 void * that =
const_cast< UNO_proxy *
>( this );
452 (*
m_bridge->m_uno_env->registerProxyInterface)(
454 UNO_proxy_free,
m_oid.pData,
455 reinterpret_cast<typelib_InterfaceTypeDescription *>(
m_type_info->m_td.get()) );
461 inline void UNO_proxy::release()
const
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(
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)
487 pUnoI =
new UNO_proxy(
489 javaI, static_cast<jstring>(jo_oid.
get()), oid, info );
491 (*m_uno_env->registerProxyInterface)(
492 m_uno_env, reinterpret_cast<void **>(&pUnoI),
494 oid.pData,
reinterpret_cast<typelib_InterfaceTypeDescription *
>(info->
m_td.get()) );
509 void UNO_proxy_free( uno_ExtEnvironment * env,
void * proxy )
512 UNO_proxy * that =
static_cast< UNO_proxy *
>( proxy );
513 Bridge
const * bridge = that->m_bridge;
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)
525 jni->DeleteGlobalRef( that->m_javaI );
526 jni->DeleteGlobalRef( that->m_jo_oid );
532 "ignoring BridgeRuntimeError \"" << err.m_message <<
"\"");
536 SAL_WARN(
"bridges",
"attaching current thread to java failed");
540 #if OSL_DEBUG_LEVEL > 0
541 *
reinterpret_cast<int *
>(that) = 0xdeadcafe;
547 void UNO_proxy_acquire( uno_Interface * pUnoI )
550 UNO_proxy
const * that =
static_cast< UNO_proxy
const *
>( pUnoI );
555 void UNO_proxy_release( uno_Interface * pUnoI )
558 UNO_proxy
const * that =
static_cast< UNO_proxy
const *
>( pUnoI );
563 void UNO_proxy_dispatch(
565 void * uno_ret,
void * uno_args [],
uno_Any ** uno_exc )
568 UNO_proxy
const * that =
static_cast< UNO_proxy
const *
>( pUnoI );
569 Bridge
const * bridge = that->m_bridge;
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 =
584 typelib_InterfaceAttributeTypeDescription
const *
>(
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 );
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)
601 typelib_MethodParameter param;
602 param.pTypeRef = attrib_td->pAttributeTypeRef;
607 that->m_javaI, iface_td,
608 attrib_td->nIndex, 1,
609 bridge->getJniInfo()->m_void_type.getTypeLibType(),
611 nullptr, uno_args, uno_exc );
616 that->m_javaI, iface_td, attrib_td->nIndex, 0,
617 attrib_td->pAttributeTypeRef,
619 uno_ret,
nullptr, uno_exc );
623 case typelib_TypeClass_INTERFACE_METHOD:
625 typelib_InterfaceMethodTypeDescription
const * method_td =
627 typelib_InterfaceMethodTypeDescription
const *
>(
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 );
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 )
646 TypeDescr demanded_td(
647 *static_cast< typelib_TypeDescriptionReference ** >(
649 if (demanded_td.get()->eTypeClass !=
650 typelib_TypeClass_INTERFACE)
653 "queryInterface() call demands an INTERFACE type!" );
656 uno_Interface * pInterface =
nullptr;
657 (*bridge->m_uno_env->getRegisteredInterface)(
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(
667 (static_cast<JniUnoEnvironmentData *>(
668 bridge->m_java_env->pContext)
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() ) );
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,
685 if (jni->ExceptionCheck())
687 JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
688 jni->ExceptionClear();
689 bridge->handle_java_exc( jni, jo_exc, *uno_exc );
698 static_cast<jstring>(
703 "bridges",
"different oids");
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)(
711 reinterpret_cast<void **>(&pUnoI2),
712 UNO_proxy_free, that->m_oid.pData,
714 typelib_InterfaceTypeDescription *
>(
715 info->m_td.get() ) );
718 static_cast<uno_Any *>(uno_ret), &pUnoI2,
719 demanded_td.get(), nullptr );
720 (*pUnoI2->release)( pUnoI2 );
725 static_cast< uno_Any * >( uno_ret ),
726 nullptr,
nullptr,
nullptr );
735 static_cast< uno_Any * >( uno_ret ),
736 &pInterface, demanded_td.get(), nullptr );
737 (*pInterface->release)( pInterface );
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 );
763 "illegal member type description!" );
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(
776 typelib_InterfaceMemberTypeDescription
const *
>(
777 member_td )->pMemberName ) );
780 buf.append( err.m_message );
782 ::com::sun::star::uno::RuntimeException exc(
783 buf.makeStringAndClear(),
785 ::com::sun::star::uno::XInterface >() );
793 ::com::sun::star::uno::RuntimeException exc(
794 "[jni_uno bridge error] attaching current thread to java failed!",
796 ::com::sun::star::uno::XInterface >() );
jmethodID m_method_Object_toString
void SAL_CALL typelib_typedescriptionreference_acquire(typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
OUString jstring_to_oustring(JNI_context const &jni, jstring jstr)
jobject compute_oid(JNI_context const &jni, jobject jo)
void SAL_CALL uno_type_any_construct(uno_Any *pDest, void *pSource, typelib_TypeDescriptionReference *pType, uno_AcquireFunc acquire) SAL_THROW_EXTERN_C()
void SAL_CALL uno_any_construct(uno_Any *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_AcquireFunc acquire) SAL_THROW_EXTERN_C()
#define SAL_THROW_EXTERN_C()
std::atomic< std::size_t > m_ref
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
std::unique_ptr< jmethodID[]> m_methods
OUString get_stack_trace(jobject jo_exc=nullptr) const
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
void ensure_no_exception() const
JNI_interface_type_info const * m_type_info
uno_Environment * m_java_env
struct _typelib_TypeDescription typelib_TypeDescription
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()
::com::sun::star::uno::TypeDescription m_td
#define SAL_WARN_IF(condition, area, stream)
#define SAL_INFO(area, stream)
void handle_java_exc(JNI_context const &jni, JLocalAutoRef const &jo_exc, uno_Any *uno_exc) const
jmethodID m_method_Class_getName
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
#define SAL_WARN(area, stream)
static rtl_mem * allocate(std::size_t bytes)
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
JNI_info const * getJniInfo() const