1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: jni_uno2java.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_bridges.hxx"
34 #include <sal/alloca.h>
36 #include "com/sun/star/uno/RuntimeException.hpp"
38 #include "rtl/ustrbuf.hxx"
40 #include "jni_bridge.h"
43 using namespace ::std
;
44 using namespace ::rtl
;
51 //------------------------------------------------------------------------------
52 void SAL_CALL
UNO_proxy_free( uno_ExtEnvironment
* env
, void * proxy
)
55 //------------------------------------------------------------------------------
56 void SAL_CALL
UNO_proxy_acquire( uno_Interface
* pUnoI
)
59 //------------------------------------------------------------------------------
60 void SAL_CALL
UNO_proxy_release( uno_Interface
* pUnoI
)
63 //------------------------------------------------------------------------------
64 void SAL_CALL
UNO_proxy_dispatch(
65 uno_Interface
* pUnoI
, typelib_TypeDescription
const * member_td
,
66 void * uno_ret
, void * uno_args
[], uno_Any
** uno_exc
)
74 //______________________________________________________________________________
75 void Bridge::handle_java_exc(
76 JNI_context
const & jni
,
77 JLocalAutoRef
const & jo_exc
, uno_Any
* uno_exc
) const
79 OSL_ASSERT( jo_exc
.is() );
82 throw BridgeRuntimeError(
83 OUSTR("java exception occured, but no java exception available!?") +
84 jni
.get_stack_trace() );
87 JLocalAutoRef
jo_class( jni
, jni
->GetObjectClass( jo_exc
.get() ) );
88 JLocalAutoRef
jo_class_name(
89 jni
, jni
->CallObjectMethodA(
90 jo_class
.get(), m_jni_info
->m_method_Class_getName
, 0 ) );
91 jni
.ensure_no_exception();
93 jstring_to_oustring( jni
, (jstring
) jo_class_name
.get() ) );
95 ::com::sun::star::uno::TypeDescription
td( exc_name
.pData
);
96 if (!td
.is() || (typelib_TypeClass_EXCEPTION
!= td
.get()->eTypeClass
))
99 JLocalAutoRef
jo_descr(
100 jni
, jni
->CallObjectMethodA(
101 jo_exc
.get(), m_jni_info
->m_method_Object_toString
, 0 ) );
102 jni
.ensure_no_exception();
103 OUStringBuffer
buf( 128 );
105 RTL_CONSTASCII_STRINGPARAM("non-UNO exception occurred: ") );
106 buf
.append( jstring_to_oustring( jni
, (jstring
) jo_descr
.get() ) );
107 buf
.append( jni
.get_stack_trace( jo_exc
.get() ) );
108 throw BridgeRuntimeError( buf
.makeStringAndClear() );
111 auto_ptr
< rtl_mem
> uno_data( rtl_mem::allocate( td
.get()->nSize
) );
113 val
.l
= jo_exc
.get();
115 jni
, uno_data
.get(), val
, td
.get()->pWeakRef
, 0,
116 false /* no assign */, false /* no out param */ );
118 #if OSL_DEBUG_LEVEL > 0
119 // patch Message, append stack trace
120 reinterpret_cast< ::com::sun::star::uno::Exception
* >(
121 uno_data
.get() )->Message
+= jni
.get_stack_trace( jo_exc
.get() );
124 typelib_typedescriptionreference_acquire( td
.get()->pWeakRef
);
125 uno_exc
->pType
= td
.get()->pWeakRef
;
126 uno_exc
->pData
= uno_data
.release();
128 #if OSL_DEBUG_LEVEL > 1
129 OUStringBuffer
trace_buf( 128 );
130 trace_buf
.appendAscii(
131 RTL_CONSTASCII_STRINGPARAM("exception occured uno->java: [") );
132 trace_buf
.append( exc_name
);
133 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
135 reinterpret_cast< ::com::sun::star::uno::Exception
const * >(
136 uno_exc
->pData
)->Message
);
139 trace_buf
.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US
) );
140 OSL_TRACE( cstr_trace
.getStr() );
144 //______________________________________________________________________________
145 void Bridge::call_java(
146 jobject javaI
, typelib_InterfaceTypeDescription
* iface_td
,
147 sal_Int32 local_member_index
, sal_Int32 function_pos_offset
,
148 typelib_TypeDescriptionReference
* return_type
,
149 typelib_MethodParameter
* params
, sal_Int32 nParams
,
150 void * uno_ret
, void * uno_args
[], uno_Any
** uno_exc
) const
152 OSL_ASSERT( function_pos_offset
== 0 || function_pos_offset
== 1 );
154 JNI_guarded_context
jni(
155 m_jni_info
, reinterpret_cast< ::jvmaccess::UnoVirtualMachine
* >(
156 m_java_env
->pContext
) );
158 // assure fully initialized iface_td:
159 ::com::sun::star::uno::TypeDescription iface_holder
;
160 if (! iface_td
->aBase
.bComplete
) {
161 iface_holder
= ::com::sun::star::uno::TypeDescription(
162 reinterpret_cast<typelib_TypeDescription
*>(iface_td
) );
163 iface_holder
.makeComplete();
164 if (! iface_holder
.get()->bComplete
) {
167 RTL_CONSTASCII_STRINGPARAM("cannot make type complete: ") );
168 buf
.append( OUString::unacquired(&iface_holder
.get()->pTypeName
) );
169 buf
.append( jni
.get_stack_trace() );
170 throw BridgeRuntimeError( buf
.makeStringAndClear() );
172 iface_td
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(
173 iface_holder
.get() );
174 OSL_ASSERT( iface_td
->aBase
.eTypeClass
== typelib_TypeClass_INTERFACE
);
177 // prepare java args, save param td
179 jvalue
* java_args
= (jvalue
*) malloc( sizeof (jvalue
) * nParams
);
181 jvalue
* java_args
= (jvalue
*) alloca( sizeof (jvalue
) * nParams
);
185 for ( nPos
= 0; nPos
< nParams
; ++nPos
)
189 typelib_MethodParameter
const & param
= params
[ nPos
];
190 java_args
[ nPos
].l
= 0; // if out: build up array[ 1 ]
192 jni
, &java_args
[ nPos
],
195 sal_False
!= param
.bIn
/* convert uno value */,
196 sal_False
!= param
.bOut
/* build up array[ 1 ] */ );
201 for ( sal_Int32 n
= 0; n
< nPos
; ++n
)
203 typelib_MethodParameter
const & param
= params
[ n
];
205 typelib_TypeClass_DOUBLE
< param
.pTypeRef
->eTypeClass
)
207 jni
->DeleteLocalRef( java_args
[ n
].l
);
217 sal_Int32 base_members
= iface_td
->nAllMembers
- iface_td
->nMembers
;
218 OSL_ASSERT( base_members
< iface_td
->nAllMembers
);
219 sal_Int32 base_members_function_pos
=
220 iface_td
->pMapMemberIndexToFunctionIndex
[ base_members
];
221 sal_Int32 member_pos
= base_members
+ local_member_index
;
223 member_pos
< iface_td
->nAllMembers
, "### member pos out of range!" );
224 sal_Int32 function_pos
=
225 iface_td
->pMapMemberIndexToFunctionIndex
[ member_pos
]
226 + function_pos_offset
;
228 function_pos
>= base_members_function_pos
229 && function_pos
< iface_td
->nMapFunctionIndexToMemberIndex
,
230 "### illegal function index!" );
231 function_pos
-= base_members_function_pos
;
233 JNI_interface_type_info
const * info
=
234 static_cast< JNI_interface_type_info
const * >(
235 m_jni_info
->get_type_info( jni
, &iface_td
->aBase
) );
236 jmethodID method_id
= info
->m_methods
[ function_pos
];
238 #if OSL_DEBUG_LEVEL > 1
239 OUStringBuffer
trace_buf( 128 );
240 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("calling ") );
241 JLocalAutoRef
jo_method(
242 jni
, jni
->ToReflectedMethod( info
->m_class
, method_id
, JNI_FALSE
) );
243 jni
.ensure_no_exception();
244 JLocalAutoRef
jo_descr(
245 jni
, jni
->CallObjectMethodA(
246 jo_method
.get(), m_jni_info
->m_method_Object_toString
, 0 ) );
247 jni
.ensure_no_exception();
248 trace_buf
.append( jstring_to_oustring( jni
, (jstring
) jo_descr
.get() ) );
249 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on ") );
251 jni
->CallObjectMethodA(
252 javaI
, m_jni_info
->m_method_Object_toString
, 0 ) );
253 jni
.ensure_no_exception();
254 trace_buf
.append( jstring_to_oustring( jni
, (jstring
) jo_descr
.get() ) );
255 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (") );
256 JLocalAutoRef
jo_class( jni
, jni
->GetObjectClass( javaI
) );
258 jni
->CallObjectMethodA(
259 jo_class
.get(), m_jni_info
->m_method_Object_toString
, 0 ) );
260 jni
.ensure_no_exception();
261 trace_buf
.append( jstring_to_oustring( jni
, (jstring
) jo_descr
.get() ) );
262 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(")") );
265 trace_buf
.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US
) );
266 OSL_TRACE( cstr_trace
.getStr() );
269 // complex return value
270 JLocalAutoRef
java_ret( jni
);
272 switch (return_type
->eTypeClass
)
274 case typelib_TypeClass_VOID
:
275 jni
->CallVoidMethodA( javaI
, method_id
, java_args
);
277 case typelib_TypeClass_CHAR
:
278 *(sal_Unicode
*)uno_ret
=
279 jni
->CallCharMethodA( javaI
, method_id
, java_args
);
281 case typelib_TypeClass_BOOLEAN
:
282 *(sal_Bool
*)uno_ret
=
283 jni
->CallBooleanMethodA( javaI
, method_id
, java_args
);
285 case typelib_TypeClass_BYTE
:
286 *(sal_Int8
*)uno_ret
=
287 jni
->CallByteMethodA( javaI
, method_id
, java_args
);
289 case typelib_TypeClass_SHORT
:
290 case typelib_TypeClass_UNSIGNED_SHORT
:
291 *(sal_Int16
*)uno_ret
=
292 jni
->CallShortMethodA( javaI
, method_id
, java_args
);
294 case typelib_TypeClass_LONG
:
295 case typelib_TypeClass_UNSIGNED_LONG
:
296 *(sal_Int32
*)uno_ret
=
297 jni
->CallIntMethodA( javaI
, method_id
, java_args
);
299 case typelib_TypeClass_HYPER
:
300 case typelib_TypeClass_UNSIGNED_HYPER
:
301 *(sal_Int64
*)uno_ret
=
302 jni
->CallLongMethodA( javaI
, method_id
, java_args
);
304 case typelib_TypeClass_FLOAT
:
306 jni
->CallFloatMethodA( javaI
, method_id
, java_args
);
308 case typelib_TypeClass_DOUBLE
:
310 jni
->CallDoubleMethodA( javaI
, method_id
, java_args
);
314 jni
->CallObjectMethodA( javaI
, method_id
, java_args
) );
318 if (jni
->ExceptionCheck())
320 JLocalAutoRef
jo_exc( jni
, jni
->ExceptionOccurred() );
321 jni
->ExceptionClear();
323 // release temp java local refs
324 for ( nPos
= 0; nPos
< nParams
; ++nPos
)
326 typelib_MethodParameter
const & param
= params
[ nPos
];
328 typelib_TypeClass_DOUBLE
< param
.pTypeRef
->eTypeClass
)
330 jni
->DeleteLocalRef( java_args
[ nPos
].l
);
334 handle_java_exc( jni
, jo_exc
, *uno_exc
);
338 for ( nPos
= 0; nPos
< nParams
; ++nPos
)
340 typelib_MethodParameter
const & param
= params
[ nPos
];
346 jni
, uno_args
[ nPos
],
347 java_args
[ nPos
], param
.pTypeRef
, 0,
348 sal_False
!= param
.bIn
/* assign if inout */,
349 true /* out param */ );
353 // cleanup uno pure out
354 for ( sal_Int32 n
= 0; n
< nPos
; ++n
)
356 typelib_MethodParameter
const & p
= params
[ n
];
359 uno_type_destructData(
360 uno_args
[ n
], p
.pTypeRef
, 0 );
363 // cleanup java temp local refs
364 for ( ; nPos
< nParams
; ++nPos
)
366 typelib_MethodParameter
const & p
= params
[ nPos
];
368 typelib_TypeClass_DOUBLE
<
369 p
.pTypeRef
->eTypeClass
)
371 jni
->DeleteLocalRef( java_args
[ nPos
].l
);
379 jni
->DeleteLocalRef( java_args
[ nPos
].l
);
381 else // pure temp in param
383 if (typelib_TypeClass_DOUBLE
< param
.pTypeRef
->eTypeClass
)
384 jni
->DeleteLocalRef( java_args
[ nPos
].l
);
389 if (typelib_TypeClass_DOUBLE
< return_type
->eTypeClass
)
394 val
.l
= java_ret
.get();
396 jni
, uno_ret
, val
, return_type
, 0,
397 false /* no assign */, false /* no out param */ );
401 // cleanup uno pure out
402 for ( sal_Int32 i
= 0; i
< nParams
; ++i
)
404 typelib_MethodParameter
const & param
= params
[ i
];
407 uno_type_destructData(
408 uno_args
[ i
], param
.pTypeRef
, 0 );
416 } // else: already set integral uno return value
418 // no exception occured
426 //==== a uno proxy wrapping a java interface ===================================
427 struct UNO_proxy
: public uno_Interface
429 mutable oslInterlockedCount m_ref
;
430 Bridge
const * m_bridge
;
432 // mapping information
436 JNI_interface_type_info
const * m_type_info
;
438 inline void acquire() const;
439 inline void release() const;
443 JNI_context
const & jni
, Bridge
const * bridge
,
444 jobject javaI
, jstring jo_oid
, OUString
const & oid
,
445 JNI_interface_type_info
const * info
);
448 //______________________________________________________________________________
449 inline UNO_proxy::UNO_proxy(
450 JNI_context
const & jni
, Bridge
const * bridge
,
451 jobject javaI
, jstring jo_oid
, OUString
const & oid
,
452 JNI_interface_type_info
const * info
)
457 JNI_info
const * jni_info
= bridge
->m_jni_info
;
458 JLocalAutoRef
jo_string_array(
459 jni
, jni
->NewObjectArray( 1, jni_info
->m_class_String
, jo_oid
) );
460 jni
.ensure_no_exception();
463 args
[ 1 ].l
= jo_string_array
.get();
464 args
[ 2 ].l
= info
->m_type
;
465 jobject jo_iface
= jni
->CallObjectMethodA(
466 jni_info
->m_object_java_env
,
467 jni_info
->m_method_IEnvironment_registerInterface
, args
);
468 jni
.ensure_no_exception();
470 m_javaI
= jni
->NewGlobalRef( jo_iface
);
471 m_jo_oid
= (jstring
) jni
->NewGlobalRef( jo_oid
);
476 uno_Interface::acquire
= UNO_proxy_acquire
;
477 uno_Interface::release
= UNO_proxy_release
;
478 uno_Interface::pDispatcher
= UNO_proxy_dispatch
;
481 //______________________________________________________________________________
482 inline void UNO_proxy::acquire() const
484 if (1 == osl_incrementInterlockedCount( &m_ref
))
486 // rebirth of proxy zombie
487 void * that
= const_cast< UNO_proxy
* >( this );
488 // register at uno env
489 (*m_bridge
->m_uno_env
->registerProxyInterface
)(
490 m_bridge
->m_uno_env
, &that
,
491 UNO_proxy_free
, m_oid
.pData
,
492 (typelib_InterfaceTypeDescription
*)m_type_info
->m_td
.get() );
493 #if OSL_DEBUG_LEVEL > 1
494 OSL_ASSERT( this == (void const * const)that
);
499 //______________________________________________________________________________
500 inline void UNO_proxy::release() const
502 if (0 == osl_decrementInterlockedCount( &m_ref
))
504 // revoke from uno env on last release
505 (*m_bridge
->m_uno_env
->revokeInterface
)(
506 m_bridge
->m_uno_env
, const_cast< UNO_proxy
* >( this ) );
511 //______________________________________________________________________________
512 uno_Interface
* Bridge::map_to_uno(
513 JNI_context
const & jni
,
514 jobject javaI
, JNI_interface_type_info
const * info
) const
516 JLocalAutoRef
jo_oid( jni
, compute_oid( jni
, javaI
) );
517 OUString
oid( jstring_to_oustring( jni
, (jstring
) jo_oid
.get() ) );
519 uno_Interface
* pUnoI
= 0;
520 (*m_uno_env
->getRegisteredInterface
)(
521 m_uno_env
, (void **)&pUnoI
,
522 oid
.pData
, (typelib_InterfaceTypeDescription
*)info
->m_td
.get() );
524 if (0 == pUnoI
) // no existing interface, register new proxy
526 // refcount initially 1
527 pUnoI
= new UNO_proxy(
528 jni
, const_cast< Bridge
* >( this ),
529 javaI
, (jstring
) jo_oid
.get(), oid
, info
);
531 (*m_uno_env
->registerProxyInterface
)(
532 m_uno_env
, (void **)&pUnoI
,
534 oid
.pData
, (typelib_InterfaceTypeDescription
*)info
->m_td
.get() );
541 using namespace ::jni_uno
;
548 //------------------------------------------------------------------------------
549 void SAL_CALL
UNO_proxy_free( uno_ExtEnvironment
* env
, void * proxy
)
552 UNO_proxy
const * that
= reinterpret_cast< UNO_proxy
const * >( proxy
);
553 Bridge
const * bridge
= that
->m_bridge
;
555 if ( env
!= bridge
->m_uno_env
) {
558 #if OSL_DEBUG_LEVEL > 1
561 OUSTR("freeing binary uno proxy: ") + that
->m_oid
,
562 RTL_TEXTENCODING_ASCII_US
) );
563 OSL_TRACE( cstr_msg
.getStr() );
568 JNI_guarded_context
jni(
570 reinterpret_cast< ::jvmaccess::UnoVirtualMachine
* >(
571 bridge
->m_java_env
->pContext
) );
573 jni
->DeleteGlobalRef( that
->m_javaI
);
574 jni
->DeleteGlobalRef( that
->m_jo_oid
);
576 catch (BridgeRuntimeError
& err
)
578 #if OSL_DEBUG_LEVEL > 0
580 OUStringToOString( err
.m_message
, RTL_TEXTENCODING_ASCII_US
) );
581 OSL_ENSURE( 0, cstr_msg2
.getStr() );
583 (void) err
; // unused
586 catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException
&)
590 "[jni_uno bridge error] attaching current thread to java failed!" );
594 #if OSL_DEBUG_LEVEL > 1
595 *(int *)that
= 0xdeadcafe;
600 //------------------------------------------------------------------------------
601 void SAL_CALL
UNO_proxy_acquire( uno_Interface
* pUnoI
)
604 UNO_proxy
const * that
= static_cast< UNO_proxy
const * >( pUnoI
);
608 //------------------------------------------------------------------------------
609 void SAL_CALL
UNO_proxy_release( uno_Interface
* pUnoI
)
612 UNO_proxy
const * that
= static_cast< UNO_proxy
const * >( pUnoI
);
616 //------------------------------------------------------------------------------
617 void SAL_CALL
UNO_proxy_dispatch(
618 uno_Interface
* pUnoI
, typelib_TypeDescription
const * member_td
,
619 void * uno_ret
, void * uno_args
[], uno_Any
** uno_exc
)
622 UNO_proxy
const * that
= static_cast< UNO_proxy
const * >( pUnoI
);
623 Bridge
const * bridge
= that
->m_bridge
;
625 #if OSL_DEBUG_LEVEL > 1
626 OUStringBuffer
trace_buf( 64 );
627 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno->java call: ") );
628 trace_buf
.append( OUString::unacquired( &member_td
->pTypeName
) );
629 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") );
630 trace_buf
.append( that
->m_oid
);
633 trace_buf
.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US
) );
634 OSL_TRACE( cstr_msg
.getStr() );
639 switch (member_td
->eTypeClass
)
641 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
643 typelib_InterfaceAttributeTypeDescription
const * attrib_td
=
645 typelib_InterfaceAttributeTypeDescription
const * >(
647 com::sun::star::uno::TypeDescription attrib_holder
;
648 while ( attrib_td
->pBaseRef
!= 0 ) {
649 attrib_holder
= com::sun::star::uno::TypeDescription(
650 attrib_td
->pBaseRef
);
652 attrib_holder
.get()->eTypeClass
653 == typelib_TypeClass_INTERFACE_ATTRIBUTE
);
654 attrib_td
= reinterpret_cast<
655 typelib_InterfaceAttributeTypeDescription
* >(
656 attrib_holder
.get() );
658 typelib_InterfaceTypeDescription
* iface_td
= attrib_td
->pInterface
;
660 if (0 == uno_ret
) // is setter method
662 typelib_MethodParameter param
;
663 param
.pTypeRef
= attrib_td
->pAttributeTypeRef
;
664 param
.bIn
= sal_True
;
665 param
.bOut
= sal_False
;
668 that
->m_javaI
, iface_td
,
669 attrib_td
->nIndex
, 1, // get, then set method
670 bridge
->m_jni_info
->m_void_type
.getTypeLibType(),
672 0, uno_args
, uno_exc
);
674 else // is getter method
677 that
->m_javaI
, iface_td
, attrib_td
->nIndex
, 0,
678 attrib_td
->pAttributeTypeRef
,
680 uno_ret
, 0, uno_exc
);
684 case typelib_TypeClass_INTERFACE_METHOD
:
686 typelib_InterfaceMethodTypeDescription
const * method_td
=
688 typelib_InterfaceMethodTypeDescription
const * >(
690 com::sun::star::uno::TypeDescription method_holder
;
691 while ( method_td
->pBaseRef
!= 0 ) {
692 method_holder
= com::sun::star::uno::TypeDescription(
693 method_td
->pBaseRef
);
695 method_holder
.get()->eTypeClass
696 == typelib_TypeClass_INTERFACE_METHOD
);
697 method_td
= reinterpret_cast<
698 typelib_InterfaceMethodTypeDescription
* >(
699 method_holder
.get() );
701 typelib_InterfaceTypeDescription
* iface_td
= method_td
->pInterface
;
703 switch ( method_td
->aBase
.nPosition
)
705 case 0: // queryInterface()
707 TypeDescr
demanded_td(
708 *reinterpret_cast< typelib_TypeDescriptionReference
** >(
710 if (typelib_TypeClass_INTERFACE
!=
711 demanded_td
.get()->eTypeClass
)
713 throw BridgeRuntimeError(
714 OUSTR("queryInterface() call demands "
715 "an INTERFACE type!") );
718 uno_Interface
* pInterface
= 0;
719 (*bridge
->m_uno_env
->getRegisteredInterface
)(
721 (void **) &pInterface
, that
->m_oid
.pData
,
722 (typelib_InterfaceTypeDescription
*)demanded_td
.get() );
726 JNI_info
const * jni_info
= bridge
->m_jni_info
;
727 JNI_guarded_context
jni(
729 reinterpret_cast< ::jvmaccess::UnoVirtualMachine
* >(
730 bridge
->m_java_env
->pContext
) );
732 JNI_interface_type_info
const * info
=
733 static_cast< JNI_interface_type_info
const * >(
734 jni_info
->get_type_info( jni
, demanded_td
.get() ) );
737 args
[ 0 ].l
= info
->m_type
;
738 args
[ 1 ].l
= that
->m_javaI
;
740 JLocalAutoRef
jo_ret(
741 jni
, jni
->CallStaticObjectMethodA(
742 jni_info
->m_class_UnoRuntime
,
743 jni_info
->m_method_UnoRuntime_queryInterface
,
746 if (jni
->ExceptionCheck())
748 JLocalAutoRef
jo_exc( jni
, jni
->ExceptionOccurred() );
749 jni
->ExceptionClear();
750 bridge
->handle_java_exc( jni
, jo_exc
, *uno_exc
);
756 #if OSL_DEBUG_LEVEL > 0
757 JLocalAutoRef
jo_oid(
758 jni
, compute_oid( jni
, jo_ret
.get() ) );
759 OUString
oid( jstring_to_oustring(
760 jni
, (jstring
) jo_oid
.get() ) );
762 oid
.equals( that
->m_oid
),
763 "### different oids!" );
765 // refcount initially 1
766 uno_Interface
* pUnoI2
= new UNO_proxy(
767 jni
, bridge
, jo_ret
.get(),
768 that
->m_jo_oid
, that
->m_oid
, info
);
770 (*bridge
->m_uno_env
->registerProxyInterface
)(
773 UNO_proxy_free
, that
->m_oid
.pData
,
775 typelib_InterfaceTypeDescription
* >(
776 info
->m_td
.get() ) );
779 (uno_Any
*)uno_ret
, &pUnoI2
,
780 demanded_td
.get(), 0 );
781 (*pUnoI2
->release
)( pUnoI2
);
783 else // object does not support demanded interface
786 reinterpret_cast< uno_Any
* >( uno_ret
),
789 // no exception occured
796 reinterpret_cast< uno_Any
* >( uno_ret
),
797 &pInterface
, demanded_td
.get(), 0 );
798 (*pInterface
->release
)( pInterface
);
803 case 1: // acquire this proxy
807 case 2: // release this proxy
811 default: // arbitrary method call
813 that
->m_javaI
, iface_td
, method_td
->nIndex
, 0,
814 method_td
->pReturnTypeRef
,
815 method_td
->pParams
, method_td
->nParams
,
816 uno_ret
, uno_args
, uno_exc
);
823 throw BridgeRuntimeError(
824 OUSTR("illegal member type description!") );
828 catch (BridgeRuntimeError
& err
)
830 OUStringBuffer
buf( 128 );
832 RTL_CONSTASCII_STRINGPARAM(
833 "[jni_uno bridge error] UNO calling Java method ") );
834 if (typelib_TypeClass_INTERFACE_METHOD
== member_td
->eTypeClass
||
835 typelib_TypeClass_INTERFACE_ATTRIBUTE
== member_td
->eTypeClass
)
837 buf
.append( OUString::unacquired(
839 typelib_InterfaceMemberTypeDescription
const * >(
840 member_td
)->pMemberName
) );
842 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
843 buf
.append( err
.m_message
);
844 // binary identical struct
845 ::com::sun::star::uno::RuntimeException
exc(
846 buf
.makeStringAndClear(),
847 ::com::sun::star::uno::Reference
<
848 ::com::sun::star::uno::XInterface
>() );
849 ::com::sun::star::uno::Type
const & exc_type
= ::getCppuType( &exc
);
850 uno_type_any_construct( *uno_exc
, &exc
, exc_type
.getTypeLibType(), 0 );
851 #if OSL_DEBUG_LEVEL > 0
853 OUStringToOString( exc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
854 OSL_ENSURE( 0, cstr_msg2
.getStr() );
857 catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException
&)
859 // binary identical struct
860 ::com::sun::star::uno::RuntimeException
exc(
861 OUSTR("[jni_uno bridge error] attaching current thread "
863 ::com::sun::star::uno::Reference
<
864 ::com::sun::star::uno::XInterface
>() );
865 ::com::sun::star::uno::Type
const & exc_type
= ::getCppuType( &exc
);
866 uno_type_any_construct( *uno_exc
, &exc
, exc_type
.getTypeLibType(), 0 );
867 #if OSL_DEBUG_LEVEL > 0
869 OUStringToOString( exc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
870 OSL_ENSURE( 0, cstr_msg2
.getStr() );