1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <sal/alloca.h>
32 #include "com/sun/star/uno/RuntimeException.hpp"
34 #include "rtl/ustrbuf.hxx"
36 #include "jni_bridge.h"
39 using namespace ::std
;
40 using namespace ::rtl
;
47 //------------------------------------------------------------------------------
48 void SAL_CALL
UNO_proxy_free( uno_ExtEnvironment
* env
, void * proxy
)
51 //------------------------------------------------------------------------------
52 void SAL_CALL
UNO_proxy_acquire( uno_Interface
* pUnoI
)
55 //------------------------------------------------------------------------------
56 void SAL_CALL
UNO_proxy_release( uno_Interface
* pUnoI
)
59 //------------------------------------------------------------------------------
60 void SAL_CALL
UNO_proxy_dispatch(
61 uno_Interface
* pUnoI
, typelib_TypeDescription
const * member_td
,
62 void * uno_ret
, void * uno_args
[], uno_Any
** uno_exc
)
70 //______________________________________________________________________________
71 void Bridge::handle_java_exc(
72 JNI_context
const & jni
,
73 JLocalAutoRef
const & jo_exc
, uno_Any
* uno_exc
) const
75 OSL_ASSERT( jo_exc
.is() );
78 throw BridgeRuntimeError(
79 OUSTR("java exception occurred, but no java exception available!?") +
80 jni
.get_stack_trace() );
83 JLocalAutoRef
jo_class( jni
, jni
->GetObjectClass( jo_exc
.get() ) );
84 JLocalAutoRef
jo_class_name(
85 jni
, jni
->CallObjectMethodA(
86 jo_class
.get(), m_jni_info
->m_method_Class_getName
, 0 ) );
87 jni
.ensure_no_exception();
89 jstring_to_oustring( jni
, (jstring
) jo_class_name
.get() ) );
91 ::com::sun::star::uno::TypeDescription
td( exc_name
.pData
);
92 if (!td
.is() || (typelib_TypeClass_EXCEPTION
!= td
.get()->eTypeClass
))
95 JLocalAutoRef
jo_descr(
96 jni
, jni
->CallObjectMethodA(
97 jo_exc
.get(), m_jni_info
->m_method_Object_toString
, 0 ) );
98 jni
.ensure_no_exception();
99 OUStringBuffer
buf( 128 );
101 RTL_CONSTASCII_STRINGPARAM("non-UNO exception occurred: ") );
102 buf
.append( jstring_to_oustring( jni
, (jstring
) jo_descr
.get() ) );
103 buf
.append( jni
.get_stack_trace( jo_exc
.get() ) );
104 throw BridgeRuntimeError( buf
.makeStringAndClear() );
107 SAL_WNODEPRECATED_DECLARATIONS_PUSH
108 auto_ptr
< rtl_mem
> uno_data( rtl_mem::allocate( td
.get()->nSize
) );
109 SAL_WNODEPRECATED_DECLARATIONS_POP
111 val
.l
= jo_exc
.get();
113 jni
, uno_data
.get(), val
, td
.get()->pWeakRef
, 0,
114 false /* no assign */, false /* no out param */ );
116 #if OSL_DEBUG_LEVEL > 0
117 // patch Message, append stack trace
118 reinterpret_cast< ::com::sun::star::uno::Exception
* >(
119 uno_data
.get() )->Message
+= jni
.get_stack_trace( jo_exc
.get() );
122 typelib_typedescriptionreference_acquire( td
.get()->pWeakRef
);
123 uno_exc
->pType
= td
.get()->pWeakRef
;
124 uno_exc
->pData
= uno_data
.release();
126 #if OSL_DEBUG_LEVEL > 1
127 OUStringBuffer
trace_buf( 128 );
128 trace_buf
.appendAscii(
129 RTL_CONSTASCII_STRINGPARAM("exception occurred uno->java: [") );
130 trace_buf
.append( exc_name
);
131 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
133 reinterpret_cast< ::com::sun::star::uno::Exception
const * >(
134 uno_exc
->pData
)->Message
);
137 trace_buf
.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US
) );
138 OSL_TRACE( "%s", cstr_trace
.getStr() );
142 //______________________________________________________________________________
143 void Bridge::call_java(
144 jobject javaI
, typelib_InterfaceTypeDescription
* iface_td
,
145 sal_Int32 local_member_index
, sal_Int32 function_pos_offset
,
146 typelib_TypeDescriptionReference
* return_type
,
147 typelib_MethodParameter
* params
, sal_Int32 nParams
,
148 void * uno_ret
, void * uno_args
[], uno_Any
** uno_exc
) const
150 OSL_ASSERT( function_pos_offset
== 0 || function_pos_offset
== 1 );
152 JNI_guarded_context
jni(
153 m_jni_info
, reinterpret_cast< ::jvmaccess::UnoVirtualMachine
* >(
154 m_java_env
->pContext
) );
156 // assure fully initialized iface_td:
157 ::com::sun::star::uno::TypeDescription iface_holder
;
158 if (! iface_td
->aBase
.bComplete
) {
159 iface_holder
= ::com::sun::star::uno::TypeDescription(
160 reinterpret_cast<typelib_TypeDescription
*>(iface_td
) );
161 iface_holder
.makeComplete();
162 if (! iface_holder
.get()->bComplete
) {
165 RTL_CONSTASCII_STRINGPARAM("cannot make type complete: ") );
166 buf
.append( OUString::unacquired(&iface_holder
.get()->pTypeName
) );
167 buf
.append( jni
.get_stack_trace() );
168 throw BridgeRuntimeError( buf
.makeStringAndClear() );
170 iface_td
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(
171 iface_holder
.get() );
172 OSL_ASSERT( iface_td
->aBase
.eTypeClass
== typelib_TypeClass_INTERFACE
);
175 // prepare java args, save param td
177 jvalue
* java_args
= (jvalue
*) malloc( sizeof (jvalue
) * nParams
);
179 jvalue
* java_args
= (jvalue
*) alloca( sizeof (jvalue
) * nParams
);
183 for ( nPos
= 0; nPos
< nParams
; ++nPos
)
187 typelib_MethodParameter
const & param
= params
[ nPos
];
188 java_args
[ nPos
].l
= 0; // if out: build up array[ 1 ]
190 jni
, &java_args
[ nPos
],
193 sal_False
!= param
.bIn
/* convert uno value */,
194 sal_False
!= param
.bOut
/* build up array[ 1 ] */ );
199 for ( sal_Int32 n
= 0; n
< nPos
; ++n
)
201 typelib_MethodParameter
const & param
= params
[ n
];
203 typelib_TypeClass_DOUBLE
< param
.pTypeRef
->eTypeClass
)
205 jni
->DeleteLocalRef( java_args
[ n
].l
);
215 sal_Int32 base_members
= iface_td
->nAllMembers
- iface_td
->nMembers
;
216 OSL_ASSERT( base_members
< iface_td
->nAllMembers
);
217 sal_Int32 base_members_function_pos
=
218 iface_td
->pMapMemberIndexToFunctionIndex
[ base_members
];
219 sal_Int32 member_pos
= base_members
+ local_member_index
;
221 member_pos
< iface_td
->nAllMembers
, "### member pos out of range!" );
222 sal_Int32 function_pos
=
223 iface_td
->pMapMemberIndexToFunctionIndex
[ member_pos
]
224 + function_pos_offset
;
226 function_pos
>= base_members_function_pos
227 && function_pos
< iface_td
->nMapFunctionIndexToMemberIndex
,
228 "### illegal function index!" );
229 function_pos
-= base_members_function_pos
;
231 JNI_interface_type_info
const * info
=
232 static_cast< JNI_interface_type_info
const * >(
233 m_jni_info
->get_type_info( jni
, &iface_td
->aBase
) );
234 jmethodID method_id
= info
->m_methods
[ function_pos
];
236 #if OSL_DEBUG_LEVEL > 1
237 OUStringBuffer
trace_buf( 128 );
238 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("calling ") );
239 JLocalAutoRef
jo_method(
240 jni
, jni
->ToReflectedMethod( info
->m_class
, method_id
, JNI_FALSE
) );
241 jni
.ensure_no_exception();
242 JLocalAutoRef
jo_descr(
243 jni
, jni
->CallObjectMethodA(
244 jo_method
.get(), m_jni_info
->m_method_Object_toString
, 0 ) );
245 jni
.ensure_no_exception();
246 trace_buf
.append( jstring_to_oustring( jni
, (jstring
) jo_descr
.get() ) );
247 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on ") );
249 jni
->CallObjectMethodA(
250 javaI
, m_jni_info
->m_method_Object_toString
, 0 ) );
251 jni
.ensure_no_exception();
252 trace_buf
.append( jstring_to_oustring( jni
, (jstring
) jo_descr
.get() ) );
253 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (") );
254 JLocalAutoRef
jo_class( jni
, jni
->GetObjectClass( javaI
) );
256 jni
->CallObjectMethodA(
257 jo_class
.get(), m_jni_info
->m_method_Object_toString
, 0 ) );
258 jni
.ensure_no_exception();
259 trace_buf
.append( jstring_to_oustring( jni
, (jstring
) jo_descr
.get() ) );
260 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(")") );
263 trace_buf
.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US
) );
264 OSL_TRACE( "%s", cstr_trace
.getStr() );
267 // complex return value
268 JLocalAutoRef
java_ret( jni
);
270 switch (return_type
->eTypeClass
)
272 case typelib_TypeClass_VOID
:
273 jni
->CallVoidMethodA( javaI
, method_id
, java_args
);
275 case typelib_TypeClass_CHAR
:
276 *(sal_Unicode
*)uno_ret
=
277 jni
->CallCharMethodA( javaI
, method_id
, java_args
);
279 case typelib_TypeClass_BOOLEAN
:
280 *(sal_Bool
*)uno_ret
=
281 jni
->CallBooleanMethodA( javaI
, method_id
, java_args
);
283 case typelib_TypeClass_BYTE
:
284 *(sal_Int8
*)uno_ret
=
285 jni
->CallByteMethodA( javaI
, method_id
, java_args
);
287 case typelib_TypeClass_SHORT
:
288 case typelib_TypeClass_UNSIGNED_SHORT
:
289 *(sal_Int16
*)uno_ret
=
290 jni
->CallShortMethodA( javaI
, method_id
, java_args
);
292 case typelib_TypeClass_LONG
:
293 case typelib_TypeClass_UNSIGNED_LONG
:
294 *(sal_Int32
*)uno_ret
=
295 jni
->CallIntMethodA( javaI
, method_id
, java_args
);
297 case typelib_TypeClass_HYPER
:
298 case typelib_TypeClass_UNSIGNED_HYPER
:
299 *(sal_Int64
*)uno_ret
=
300 jni
->CallLongMethodA( javaI
, method_id
, java_args
);
302 case typelib_TypeClass_FLOAT
:
304 jni
->CallFloatMethodA( javaI
, method_id
, java_args
);
306 case typelib_TypeClass_DOUBLE
:
308 jni
->CallDoubleMethodA( javaI
, method_id
, java_args
);
312 jni
->CallObjectMethodA( javaI
, method_id
, java_args
) );
316 if (jni
->ExceptionCheck())
318 JLocalAutoRef
jo_exc( jni
, jni
->ExceptionOccurred() );
319 jni
->ExceptionClear();
321 // release temp java local refs
322 for ( nPos
= 0; nPos
< nParams
; ++nPos
)
324 typelib_MethodParameter
const & param
= params
[ nPos
];
326 typelib_TypeClass_DOUBLE
< param
.pTypeRef
->eTypeClass
)
328 jni
->DeleteLocalRef( java_args
[ nPos
].l
);
332 handle_java_exc( jni
, jo_exc
, *uno_exc
);
336 for ( nPos
= 0; nPos
< nParams
; ++nPos
)
338 typelib_MethodParameter
const & param
= params
[ nPos
];
344 jni
, uno_args
[ nPos
],
345 java_args
[ nPos
], param
.pTypeRef
, 0,
346 sal_False
!= param
.bIn
/* assign if inout */,
347 true /* out param */ );
351 // cleanup uno pure out
352 for ( sal_Int32 n
= 0; n
< nPos
; ++n
)
354 typelib_MethodParameter
const & p
= params
[ n
];
357 uno_type_destructData(
358 uno_args
[ n
], p
.pTypeRef
, 0 );
361 // cleanup java temp local refs
362 for ( ; nPos
< nParams
; ++nPos
)
364 typelib_MethodParameter
const & p
= params
[ nPos
];
366 typelib_TypeClass_DOUBLE
<
367 p
.pTypeRef
->eTypeClass
)
369 jni
->DeleteLocalRef( java_args
[ nPos
].l
);
377 jni
->DeleteLocalRef( java_args
[ nPos
].l
);
379 else // pure temp in param
381 if (typelib_TypeClass_DOUBLE
< param
.pTypeRef
->eTypeClass
)
382 jni
->DeleteLocalRef( java_args
[ nPos
].l
);
387 if (typelib_TypeClass_DOUBLE
< return_type
->eTypeClass
)
392 val
.l
= java_ret
.get();
394 jni
, uno_ret
, val
, return_type
, 0,
395 false /* no assign */, false /* no out param */ );
399 // cleanup uno pure out
400 for ( sal_Int32 i
= 0; i
< nParams
; ++i
)
402 typelib_MethodParameter
const & param
= params
[ i
];
405 uno_type_destructData(
406 uno_args
[ i
], param
.pTypeRef
, 0 );
414 } // else: already set integral uno return value
416 // no exception occurred
424 //==== a uno proxy wrapping a java interface ===================================
425 struct UNO_proxy
: public uno_Interface
427 mutable oslInterlockedCount m_ref
;
428 Bridge
const * m_bridge
;
430 // mapping information
434 JNI_interface_type_info
const * m_type_info
;
436 inline void acquire() const;
437 inline void release() const;
441 JNI_context
const & jni
, Bridge
const * bridge
,
442 jobject javaI
, jstring jo_oid
, OUString
const & oid
,
443 JNI_interface_type_info
const * info
);
446 //______________________________________________________________________________
447 inline UNO_proxy::UNO_proxy(
448 JNI_context
const & jni
, Bridge
const * bridge
,
449 jobject javaI
, jstring jo_oid
, OUString
const & oid
,
450 JNI_interface_type_info
const * info
)
455 JNI_info
const * jni_info
= bridge
->m_jni_info
;
456 JLocalAutoRef
jo_string_array(
457 jni
, jni
->NewObjectArray( 1, jni_info
->m_class_String
, jo_oid
) );
458 jni
.ensure_no_exception();
461 args
[ 1 ].l
= jo_string_array
.get();
462 args
[ 2 ].l
= info
->m_type
;
463 jobject jo_iface
= jni
->CallObjectMethodA(
464 jni_info
->m_object_java_env
,
465 jni_info
->m_method_IEnvironment_registerInterface
, args
);
466 jni
.ensure_no_exception();
468 m_javaI
= jni
->NewGlobalRef( jo_iface
);
469 m_jo_oid
= (jstring
) jni
->NewGlobalRef( jo_oid
);
474 uno_Interface::acquire
= UNO_proxy_acquire
;
475 uno_Interface::release
= UNO_proxy_release
;
476 uno_Interface::pDispatcher
= UNO_proxy_dispatch
;
479 //______________________________________________________________________________
480 inline void UNO_proxy::acquire() const
482 if (1 == osl_incrementInterlockedCount( &m_ref
))
484 // rebirth of proxy zombie
485 void * that
= const_cast< UNO_proxy
* >( this );
486 // register at uno env
487 (*m_bridge
->m_uno_env
->registerProxyInterface
)(
488 m_bridge
->m_uno_env
, &that
,
489 UNO_proxy_free
, m_oid
.pData
,
490 (typelib_InterfaceTypeDescription
*)m_type_info
->m_td
.get() );
491 #if OSL_DEBUG_LEVEL > 1
492 OSL_ASSERT( this == (void const * const)that
);
497 //______________________________________________________________________________
498 inline void UNO_proxy::release() const
500 if (0 == osl_decrementInterlockedCount( &m_ref
))
502 // revoke from uno env on last release
503 (*m_bridge
->m_uno_env
->revokeInterface
)(
504 m_bridge
->m_uno_env
, const_cast< UNO_proxy
* >( this ) );
509 //______________________________________________________________________________
510 uno_Interface
* Bridge::map_to_uno(
511 JNI_context
const & jni
,
512 jobject javaI
, JNI_interface_type_info
const * info
) const
514 JLocalAutoRef
jo_oid( jni
, compute_oid( jni
, javaI
) );
515 OUString
oid( jstring_to_oustring( jni
, (jstring
) jo_oid
.get() ) );
517 uno_Interface
* pUnoI
= 0;
518 (*m_uno_env
->getRegisteredInterface
)(
519 m_uno_env
, (void **)&pUnoI
,
520 oid
.pData
, (typelib_InterfaceTypeDescription
*)info
->m_td
.get() );
522 if (0 == pUnoI
) // no existing interface, register new proxy
524 // refcount initially 1
525 pUnoI
= new UNO_proxy(
526 jni
, const_cast< Bridge
* >( this ),
527 javaI
, (jstring
) jo_oid
.get(), oid
, info
);
529 (*m_uno_env
->registerProxyInterface
)(
530 m_uno_env
, (void **)&pUnoI
,
532 oid
.pData
, (typelib_InterfaceTypeDescription
*)info
->m_td
.get() );
539 using namespace ::jni_uno
;
546 //------------------------------------------------------------------------------
547 void SAL_CALL
UNO_proxy_free( uno_ExtEnvironment
* env
, void * proxy
)
550 UNO_proxy
const * that
= reinterpret_cast< UNO_proxy
const * >( proxy
);
551 Bridge
const * bridge
= that
->m_bridge
;
553 if ( env
!= bridge
->m_uno_env
) {
556 #if OSL_DEBUG_LEVEL > 1
559 OUSTR("freeing binary uno proxy: ") + that
->m_oid
,
560 RTL_TEXTENCODING_ASCII_US
) );
561 OSL_TRACE( "%s", cstr_msg
.getStr() );
566 JNI_guarded_context
jni(
568 reinterpret_cast< ::jvmaccess::UnoVirtualMachine
* >(
569 bridge
->m_java_env
->pContext
) );
571 jni
->DeleteGlobalRef( that
->m_javaI
);
572 jni
->DeleteGlobalRef( that
->m_jo_oid
);
574 catch (BridgeRuntimeError
& err
)
576 #if OSL_DEBUG_LEVEL > 0
578 OUStringToOString( err
.m_message
, RTL_TEXTENCODING_ASCII_US
) );
579 OSL_FAIL( cstr_msg2
.getStr() );
581 (void) err
; // unused
584 catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException
&)
587 "[jni_uno bridge error] attaching current thread to java failed!" );
591 #if OSL_DEBUG_LEVEL > 1
592 *(int *)that
= 0xdeadcafe;
597 //------------------------------------------------------------------------------
598 void SAL_CALL
UNO_proxy_acquire( uno_Interface
* pUnoI
)
601 UNO_proxy
const * that
= static_cast< UNO_proxy
const * >( pUnoI
);
605 //------------------------------------------------------------------------------
606 void SAL_CALL
UNO_proxy_release( uno_Interface
* pUnoI
)
609 UNO_proxy
const * that
= static_cast< UNO_proxy
const * >( pUnoI
);
613 //------------------------------------------------------------------------------
614 void SAL_CALL
UNO_proxy_dispatch(
615 uno_Interface
* pUnoI
, typelib_TypeDescription
const * member_td
,
616 void * uno_ret
, void * uno_args
[], uno_Any
** uno_exc
)
619 UNO_proxy
const * that
= static_cast< UNO_proxy
const * >( pUnoI
);
620 Bridge
const * bridge
= that
->m_bridge
;
622 #if OSL_DEBUG_LEVEL > 1
623 OUStringBuffer
trace_buf( 64 );
624 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno->java call: ") );
625 trace_buf
.append( OUString::unacquired( &member_td
->pTypeName
) );
626 trace_buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") );
627 trace_buf
.append( that
->m_oid
);
630 trace_buf
.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US
) );
631 OSL_TRACE( "%s", cstr_msg
.getStr() );
636 switch (member_td
->eTypeClass
)
638 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
640 typelib_InterfaceAttributeTypeDescription
const * attrib_td
=
642 typelib_InterfaceAttributeTypeDescription
const * >(
644 com::sun::star::uno::TypeDescription attrib_holder
;
645 while ( attrib_td
->pBaseRef
!= 0 ) {
646 attrib_holder
= com::sun::star::uno::TypeDescription(
647 attrib_td
->pBaseRef
);
649 attrib_holder
.get()->eTypeClass
650 == typelib_TypeClass_INTERFACE_ATTRIBUTE
);
651 attrib_td
= reinterpret_cast<
652 typelib_InterfaceAttributeTypeDescription
* >(
653 attrib_holder
.get() );
655 typelib_InterfaceTypeDescription
* iface_td
= attrib_td
->pInterface
;
657 if (0 == uno_ret
) // is setter method
659 typelib_MethodParameter param
;
660 param
.pTypeRef
= attrib_td
->pAttributeTypeRef
;
661 param
.bIn
= sal_True
;
662 param
.bOut
= sal_False
;
665 that
->m_javaI
, iface_td
,
666 attrib_td
->nIndex
, 1, // get, then set method
667 bridge
->m_jni_info
->m_void_type
.getTypeLibType(),
669 0, uno_args
, uno_exc
);
671 else // is getter method
674 that
->m_javaI
, iface_td
, attrib_td
->nIndex
, 0,
675 attrib_td
->pAttributeTypeRef
,
677 uno_ret
, 0, uno_exc
);
681 case typelib_TypeClass_INTERFACE_METHOD
:
683 typelib_InterfaceMethodTypeDescription
const * method_td
=
685 typelib_InterfaceMethodTypeDescription
const * >(
687 com::sun::star::uno::TypeDescription method_holder
;
688 while ( method_td
->pBaseRef
!= 0 ) {
689 method_holder
= com::sun::star::uno::TypeDescription(
690 method_td
->pBaseRef
);
692 method_holder
.get()->eTypeClass
693 == typelib_TypeClass_INTERFACE_METHOD
);
694 method_td
= reinterpret_cast<
695 typelib_InterfaceMethodTypeDescription
* >(
696 method_holder
.get() );
698 typelib_InterfaceTypeDescription
* iface_td
= method_td
->pInterface
;
700 switch ( method_td
->aBase
.nPosition
)
702 case 0: // queryInterface()
704 TypeDescr
demanded_td(
705 *reinterpret_cast< typelib_TypeDescriptionReference
** >(
707 if (typelib_TypeClass_INTERFACE
!=
708 demanded_td
.get()->eTypeClass
)
710 throw BridgeRuntimeError(
711 OUSTR("queryInterface() call demands "
712 "an INTERFACE type!") );
715 uno_Interface
* pInterface
= 0;
716 (*bridge
->m_uno_env
->getRegisteredInterface
)(
718 (void **) &pInterface
, that
->m_oid
.pData
,
719 (typelib_InterfaceTypeDescription
*)demanded_td
.get() );
723 JNI_info
const * jni_info
= bridge
->m_jni_info
;
724 JNI_guarded_context
jni(
726 reinterpret_cast< ::jvmaccess::UnoVirtualMachine
* >(
727 bridge
->m_java_env
->pContext
) );
729 JNI_interface_type_info
const * info
=
730 static_cast< JNI_interface_type_info
const * >(
731 jni_info
->get_type_info( jni
, demanded_td
.get() ) );
734 args
[ 0 ].l
= info
->m_type
;
735 args
[ 1 ].l
= that
->m_javaI
;
737 JLocalAutoRef
jo_ret(
738 jni
, jni
->CallStaticObjectMethodA(
739 jni_info
->m_class_UnoRuntime
,
740 jni_info
->m_method_UnoRuntime_queryInterface
,
743 if (jni
->ExceptionCheck())
745 JLocalAutoRef
jo_exc( jni
, jni
->ExceptionOccurred() );
746 jni
->ExceptionClear();
747 bridge
->handle_java_exc( jni
, jo_exc
, *uno_exc
);
753 #if OSL_DEBUG_LEVEL > 0
754 JLocalAutoRef
jo_oid(
755 jni
, compute_oid( jni
, jo_ret
.get() ) );
756 OUString
oid( jstring_to_oustring(
757 jni
, (jstring
) jo_oid
.get() ) );
759 oid
.equals( that
->m_oid
),
760 "### different oids!" );
762 // refcount initially 1
763 uno_Interface
* pUnoI2
= new UNO_proxy(
764 jni
, bridge
, jo_ret
.get(),
765 that
->m_jo_oid
, that
->m_oid
, info
);
767 (*bridge
->m_uno_env
->registerProxyInterface
)(
770 UNO_proxy_free
, that
->m_oid
.pData
,
772 typelib_InterfaceTypeDescription
* >(
773 info
->m_td
.get() ) );
776 (uno_Any
*)uno_ret
, &pUnoI2
,
777 demanded_td
.get(), 0 );
778 (*pUnoI2
->release
)( pUnoI2
);
780 else // object does not support demanded interface
783 reinterpret_cast< uno_Any
* >( uno_ret
),
786 // no exception occurred
793 reinterpret_cast< uno_Any
* >( uno_ret
),
794 &pInterface
, demanded_td
.get(), 0 );
795 (*pInterface
->release
)( pInterface
);
800 case 1: // acquire this proxy
804 case 2: // release this proxy
808 default: // arbitrary method call
810 that
->m_javaI
, iface_td
, method_td
->nIndex
, 0,
811 method_td
->pReturnTypeRef
,
812 method_td
->pParams
, method_td
->nParams
,
813 uno_ret
, uno_args
, uno_exc
);
820 throw BridgeRuntimeError(
821 OUSTR("illegal member type description!") );
825 catch (BridgeRuntimeError
& err
)
827 OUStringBuffer
buf( 128 );
829 RTL_CONSTASCII_STRINGPARAM(
830 "[jni_uno bridge error] UNO calling Java method ") );
831 if (typelib_TypeClass_INTERFACE_METHOD
== member_td
->eTypeClass
||
832 typelib_TypeClass_INTERFACE_ATTRIBUTE
== member_td
->eTypeClass
)
834 buf
.append( OUString::unacquired(
836 typelib_InterfaceMemberTypeDescription
const * >(
837 member_td
)->pMemberName
) );
839 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
840 buf
.append( err
.m_message
);
841 // binary identical struct
842 ::com::sun::star::uno::RuntimeException
exc(
843 buf
.makeStringAndClear(),
844 ::com::sun::star::uno::Reference
<
845 ::com::sun::star::uno::XInterface
>() );
846 ::com::sun::star::uno::Type
const & exc_type
= ::getCppuType( &exc
);
847 uno_type_any_construct( *uno_exc
, &exc
, exc_type
.getTypeLibType(), 0 );
848 #if OSL_DEBUG_LEVEL > 0
850 OUStringToOString( exc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
851 OSL_TRACE( "%s", cstr_msg2
.getStr() );
854 catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException
&)
856 // binary identical struct
857 ::com::sun::star::uno::RuntimeException
exc(
858 OUSTR("[jni_uno bridge error] attaching current thread "
860 ::com::sun::star::uno::Reference
<
861 ::com::sun::star::uno::XInterface
>() );
862 ::com::sun::star::uno::Type
const & exc_type
= ::getCppuType( &exc
);
863 uno_type_any_construct( *uno_exc
, &exc
, exc_type
.getTypeLibType(), 0 );
864 #if OSL_DEBUG_LEVEL > 0
866 OUStringToOString( exc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
867 OSL_FAIL( cstr_msg2
.getStr() );
875 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */