diff options
author | Daniel Boelzle <dbo@openoffice.org> | 2002-11-01 13:24:58 +0000 |
---|---|---|
committer | Daniel Boelzle <dbo@openoffice.org> | 2002-11-01 13:24:58 +0000 |
commit | bfbba70a4514b747617d4d37cc093ed00e48c0a4 (patch) | |
tree | b76971029268ef2ad51268180b725abe05ed4879 | |
parent | 153e383a7ecc911623f253e611469e437ab6b20e (diff) |
#104312# preparing using java.lang.reflect.Proxy; bugs
-rw-r--r-- | bridges/source/jni_uno/jni_bridge.h | 46 | ||||
-rw-r--r-- | bridges/source/jni_uno/jni_data.cxx | 90 | ||||
-rw-r--r-- | bridges/source/jni_uno/jni_helper.h | 12 | ||||
-rw-r--r-- | bridges/source/jni_uno/jni_info.cxx | 87 | ||||
-rw-r--r-- | bridges/source/jni_uno/jni_info.h | 21 | ||||
-rw-r--r-- | bridges/source/jni_uno/jni_java2uno.cxx | 277 | ||||
-rw-r--r-- | bridges/source/jni_uno/jni_uno2java.cxx | 113 |
7 files changed, 366 insertions, 280 deletions
diff --git a/bridges/source/jni_uno/jni_bridge.h b/bridges/source/jni_uno/jni_bridge.h index 23006ea36664..e3ad9d2b4a7a 100644 --- a/bridges/source/jni_uno/jni_bridge.h +++ b/bridges/source/jni_uno/jni_bridge.h @@ -2,9 +2,9 @@ * * $RCSfile: jni_bridge.h,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: dbo $ $Date: 2002-10-29 10:55:07 $ + * last change: $Author: dbo $ $Date: 2002-11-01 14:24:56 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -107,42 +107,44 @@ struct jni_Bridge void acquire() const SAL_THROW( () ); void release() const SAL_THROW( () ); + // jni_data.cxx + void map_to_uno( + JNI_attach const & attach, + void * uno_data, jvalue java_data, + typelib_TypeDescriptionReference * type, JNI_type_info const * info /* maybe 0 */, + bool assign, bool out_param, + bool special_wrapped_integral_types = false ) const; + void map_to_java( + JNI_attach const & attach, + jvalue * java_data, void const * uno_data, + typelib_TypeDescriptionReference * type, JNI_type_info const * info /* maybe 0 */, + bool in_param, bool out_param, + bool special_wrapped_integral_types = false ) const; + // jni_uno2java.cxx + void handle_uno_exc( + JNI_attach const & attach, uno_Any * uno_exc ) const; void call_java( jobject javaI, JNI_type_info const * info, sal_Int32 function_pos, typelib_TypeDescriptionReference * return_type, typelib_MethodParameter * params, sal_Int32 nParams, void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const; + jobject map_uno2java( + JNI_attach const & attach, + uno_Interface * pUnoI, JNI_type_info const * info ) const; + // jni_java2uno.cxx + void handle_java_exc( + JNI_attach const & attach, JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) const; jobject call_uno( JNI_attach const & attach, uno_Interface * pUnoI, typelib_TypeDescription * member_td, typelib_TypeDescriptionReference * return_tdref, sal_Int32 nParams, typelib_MethodParameter const * pParams, jobjectArray jo_args ) const; - - // jni_java2uno.cxx uno_Interface * map_java2uno( JNI_attach const & attach, jobject javaI, JNI_type_info const * info ) const; - // jni_uno2java.cxx - jobject map_uno2java( - JNI_attach const & attach, - uno_Interface * pUnoI, JNI_type_info const * info ) const; - - // jni_data.cxx - void map_to_uno( - JNI_attach const & attach, - void * uno_data, jvalue java_data, - typelib_TypeDescriptionReference * type, JNI_type_info const * info /* maybe 0 */, - bool assign, bool out_param, - bool special_wrapped_integral_types = false ) const; - void map_to_java( - JNI_attach const & attach, - jvalue * java_data, void * uno_data, - typelib_TypeDescriptionReference * type, JNI_type_info const * info /* maybe 0 */, - bool in_param, bool out_param, - bool special_wrapped_integral_types = false ) const; }; } diff --git a/bridges/source/jni_uno/jni_data.cxx b/bridges/source/jni_uno/jni_data.cxx index c1b339fc3a29..b352ed6a51f4 100644 --- a/bridges/source/jni_uno/jni_data.cxx +++ b/bridges/source/jni_uno/jni_data.cxx @@ -2,9 +2,9 @@ * * $RCSfile: jni_data.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: dbo $ $Date: 2002-10-29 12:20:27 $ + * last change: $Author: dbo $ $Date: 2002-11-01 14:24:56 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -276,7 +276,7 @@ void jni_Bridge::map_to_uno( OUString type_name( jstring_to_oustring( attach, (jstring)jo_type_name.get() ) ); ::com::sun::star::uno::TypeDescription td( type_name ); if (! td.is()) - throw BridgeRuntimeError( OUSTR("type not found: ") + type_name ); + throw BridgeRuntimeError( OUSTR("UNO type not found: ") + type_name ); typelib_typedescriptionreference_acquire( td.get()->pWeakRef ); if (assign) { @@ -300,7 +300,7 @@ void jni_Bridge::map_to_uno( // (typelib_TypeDescriptionReference **)uno_data, type_class, type_name.pData ); break; } - case typelib_TypeClass_ANY: + case typelib_TypeClass_ANY: // xxx todo: possible opt on anys { JLocalAutoRef jo_out_holder; if (out_param) @@ -327,15 +327,15 @@ void jni_Bridge::map_to_uno( attach.ensure_no_exception(); jvalue arg; arg.l = jo_class.get(); - bool equals = + bool is_any = (JNI_FALSE != attach->CallBooleanMethodA( m_jni_info->m_class_Any, m_jni_info->m_method_Object_equals, &arg )); attach.ensure_no_exception(); JLocalAutoRef jo_type; - JLocalAutoRef jo_wrapped; + JLocalAutoRef jo_wrapped_holder; - if (equals) // is com.sun.star.uno.Any + if (is_any) { // wrapped value type jo_type.reset( @@ -343,13 +343,27 @@ void jni_Bridge::map_to_uno( if (! jo_type.is()) throw BridgeRuntimeError( OUSTR("no type set at com.sun.star.uno.Any!") ); // wrapped value - jo_wrapped.reset( + jo_wrapped_holder.reset( attach, attach->GetObjectField( java_data.l, m_jni_info->m_field_Any__object ) ); - java_data.l = jo_wrapped.get(); + java_data.l = jo_wrapped_holder.get(); } else { - jo_type.reset( attach, create_type( attach, (jclass)jo_class.get() ) ); + // check whether this is a proxy + if (JNI_FALSE != attach->IsAssignableFrom( + (jclass)jo_class.get(), m_jni_info->m_class_TypedProxy )) + { + // is proxy => determine exact type + jo_type.reset( + attach, attach->CallObjectMethodA( + java_data.l, m_jni_info->m_method_TypedProxy_getType, 0 ) ); + attach.ensure_no_exception(); + } + else + { + jo_type.reset( + attach, create_type( attach, (jclass)jo_class.get() ) ); + } } // get type name @@ -360,7 +374,7 @@ void jni_Bridge::map_to_uno( ::com::sun::star::uno::TypeDescription value_td( type_name ); if (! value_td.is()) - throw BridgeRuntimeError( OUSTR("type not found: ") + type_name ); + throw BridgeRuntimeError( OUSTR("UNO type not found: ") + type_name ); typelib_TypeClass type_class = value_td.get()->eTypeClass; // just as fallback: should never happen @@ -595,9 +609,9 @@ void jni_Bridge::map_to_uno( { OSL_ASSERT( typelib_typedescriptionreference_equals( - type, m_jni_info->m_Exception.getTypeLibType() ) || + type, m_jni_info->m_Exception_type.getTypeLibType() ) || typelib_typedescriptionreference_equals( - type, m_jni_info->m_RuntimeException.getTypeLibType() ) ); + type, m_jni_info->m_RuntimeException_type.getTypeLibType() ) ); OSL_ASSERT( 0 == nPos ); // first member // call getMessage() jo_field.reset( @@ -833,7 +847,7 @@ void jni_Bridge::map_to_uno( //__________________________________________________________________________________________________ void jni_Bridge::map_to_java( JNI_attach const & attach, - jvalue * java_data, void * uno_data, + jvalue * java_data, void const * uno_data, typelib_TypeDescriptionReference * type, JNI_type_info const * info /* maybe 0 */, bool in_param, bool out_param, bool special_wrapped_integral_types ) const { @@ -1102,15 +1116,27 @@ void jni_Bridge::map_to_java( map_to_java( attach, args, pAny->pData, pAny->pType, 0, true /* in */, false /* no out */, true /* create integral wrappers */ ); - JLocalAutoRef jo_val( attach, args[ 0 ].l ); - JLocalAutoRef jo_type( attach, create_type( attach, pAny->pType ) ); - args[ 0 ].l = jo_type.get(); - args[ 1 ].l = jo_val.get(); - // build up any - jo_any.reset( - attach, attach->NewObjectA( - m_jni_info->m_class_Any, m_jni_info->m_ctor_Any_with_Type_Object, args ) ); - attach.ensure_no_exception(); + switch (pAny->pType->eTypeClass) + { + case typelib_TypeClass_UNSIGNED_SHORT: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_UNSIGNED_HYPER: + { + // build up com.sun.star.uno.Any + JLocalAutoRef jo_val( attach, args[ 0 ].l ); + JLocalAutoRef jo_type( attach, create_type( attach, pAny->pType ) ); + args[ 0 ].l = jo_type.get(); + args[ 1 ].l = jo_val.get(); + jo_any.reset( + attach, attach->NewObjectA( + m_jni_info->m_class_Any, m_jni_info->m_ctor_Any_with_Type_Object, args ) ); + attach.ensure_no_exception(); + break; + } + default: + jo_any.reset( attach, args[ 0 ].l ); + break; + } } if (out_param) { @@ -1202,7 +1228,7 @@ void jni_Bridge::map_to_java( jfieldID field_id = linfo->m_fields[ nPos ]; if (0 != field_id) { - void * p = (char *)uno_data + pMemberOffsets[ nPos ]; + void const * p = (char const *)uno_data + pMemberOffsets[ nPos ]; typelib_TypeDescriptionReference * member_type = ppMemberTypeRefs[ nPos ]; switch (member_type->eTypeClass) { @@ -1285,10 +1311,10 @@ void jni_Bridge::map_to_java( JLocalAutoRef jo_ar; sal_Int32 nElements; - uno_Sequence * seq = 0; + uno_Sequence const * seq = 0; if (in_param) { - seq = *(uno_Sequence **)uno_data; + seq = *(uno_Sequence * const *)uno_data; nElements = seq->nElements; } else @@ -1391,7 +1417,7 @@ void jni_Bridge::map_to_java( attach.ensure_no_exception(); if (in_param) { - rtl_uString ** pp = (rtl_uString **)seq->elements; + rtl_uString * const * pp = (rtl_uString * const *)seq->elements; for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos ) { JLocalAutoRef jo_string( attach, ustring_to_jstring( attach, pp[ nPos ] ) ); @@ -1407,8 +1433,8 @@ void jni_Bridge::map_to_java( attach.ensure_no_exception(); if (in_param) { - typelib_TypeDescriptionReference ** pp = - (typelib_TypeDescriptionReference **)seq->elements; + typelib_TypeDescriptionReference * const * pp = + (typelib_TypeDescriptionReference * const *)seq->elements; for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos ) { jvalue val; @@ -1428,7 +1454,7 @@ void jni_Bridge::map_to_java( attach.ensure_no_exception(); if (in_param) { - uno_Any * p = (uno_Any *)seq->elements; + uno_Any const * p = (uno_Any const *)seq->elements; for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos ) { jvalue val; @@ -1515,7 +1541,7 @@ void jni_Bridge::map_to_java( case typelib_TypeClass_SEQUENCE: { OStringBuffer buf( 64 ); - m_jni_info->append_sig( &buf, element_type ); // xxx todo opt + m_jni_info->append_sig( &buf, element_type ); OString class_name( buf.makeStringAndClear() ); JLocalAutoRef jo_seq_class( attach, find_class( attach, class_name.getStr() ) ); @@ -1614,7 +1640,7 @@ void jni_Bridge::map_to_java( if (out_param) { if (typelib_typedescriptionreference_equals( - type, m_jni_info->m_XInterface.get()->pWeakRef )) + type, m_jni_info->m_XInterface_td.get()->pWeakRef )) { java_data->l = attach->NewObjectArray( 1, m_jni_info->m_class_Object, jo_iface.get() ); diff --git a/bridges/source/jni_uno/jni_helper.h b/bridges/source/jni_uno/jni_helper.h index 1cbe256b8b7a..d00779aca97d 100644 --- a/bridges/source/jni_uno/jni_helper.h +++ b/bridges/source/jni_uno/jni_helper.h @@ -2,9 +2,9 @@ * * $RCSfile: jni_helper.h,v $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * - * last change: $Author: dbo $ $Date: 2002-10-29 10:55:38 $ + * last change: $Author: dbo $ $Date: 2002-11-01 14:24:57 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -77,12 +77,11 @@ inline void jstring_to_ustring( JNI_attach const & attach, rtl_uString ** out_us } else { - OSL_ASSERT( sizeof (sal_Unicode) == sizeof (jchar) ); jsize len = attach->GetStringLength( jstr ); ::std::auto_ptr< rtl_mem > mem( rtl_mem::allocate( sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) ); rtl_uString * ustr = (rtl_uString *)mem.get(); - attach->GetStringRegion( jstr, 0, len, ustr->buffer ); + attach->GetStringRegion( jstr, 0, len, (jchar *)ustr->buffer ); attach.ensure_no_exception(); ustr->refCount = 1; ustr->length = len; @@ -101,10 +100,9 @@ inline ::rtl::OUString jstring_to_oustring( JNI_attach const & attach, jstring j return ::rtl::OUString( ustr, SAL_NO_ACQUIRE ); } //-------------------------------------------------------------------------------------------------- -inline jstring ustring_to_jstring( JNI_attach const & attach, rtl_uString * ustr ) +inline jstring ustring_to_jstring( JNI_attach const & attach, rtl_uString const * ustr ) { - OSL_ASSERT( sizeof (sal_Unicode) == sizeof (jchar) ); - jstring jstr = attach->NewString( ustr->buffer, ustr->length ); + jstring jstr = attach->NewString( (jchar const *)ustr->buffer, ustr->length ); attach.ensure_no_exception(); return jstr; } diff --git a/bridges/source/jni_uno/jni_info.cxx b/bridges/source/jni_uno/jni_info.cxx index cc4be7d5b018..7eba5f2425c8 100644 --- a/bridges/source/jni_uno/jni_info.cxx +++ b/bridges/source/jni_uno/jni_info.cxx @@ -2,9 +2,9 @@ * * $RCSfile: jni_info.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: dbo $ $Date: 2002-10-29 10:55:07 $ + * last change: $Author: dbo $ $Date: 2002-11-01 14:24:57 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -104,7 +104,7 @@ JNI_type_info::JNI_type_info( // if ! XInterface if (! typelib_typedescriptionreference_equals( - ((typelib_TypeDescription *)td)->pWeakRef, jni_info->m_XInterface.get()->pWeakRef )) + ((typelib_TypeDescription *)td)->pWeakRef, jni_info->m_XInterface_td.get()->pWeakRef )) { try { @@ -253,10 +253,10 @@ JNI_type_info::JNI_type_info( { if (typelib_typedescriptionreference_equals( ((typelib_TypeDescription *)td)->pWeakRef, - jni_info->m_Exception.getTypeLibType() ) || + jni_info->m_Exception_type.getTypeLibType() ) || typelib_typedescriptionreference_equals( ((typelib_TypeDescription *)td)->pWeakRef, - jni_info->m_RuntimeException.getTypeLibType() )) + jni_info->m_RuntimeException_type.getTypeLibType() )) { m_fields = new jfieldID[ 2 ]; m_fields[ 0 ] = 0; // special Throwable.getMessage() @@ -364,15 +364,70 @@ JNI_type_info const * JNI_info::get_type_info( return info; } //__________________________________________________________________________________________________ +JNI_type_info const * JNI_info::get_type_info( + JNI_attach const & attach, OUString const & uno_name ) const +{ + JNI_type_info * info; + + ClearableMutexGuard guard( m_mutex ); + t_str2type::const_iterator iFind( m_type_map.find( uno_name ) ); + if (m_type_map.end() == iFind) + { + guard.clear(); + + ::com::sun::star::uno::TypeDescription td( uno_name ); + if (! td.is()) + throw BridgeRuntimeError( OUSTR("UNO type not found: ") + uno_name ); + + JNI_type_info * new_info; + switch (td.get()->eTypeClass) + { + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + new_info = new JNI_type_info( attach, (typelib_CompoundTypeDescription *)td.get() ); + break; + case typelib_TypeClass_INTERFACE: + new_info = new JNI_type_info( attach, (typelib_InterfaceTypeDescription *)td.get() ); + break; + default: + throw BridgeRuntimeError( OUSTR("unsupported: type info for ") + uno_name ); + } + + // look again + ClearableMutexGuard guard( m_mutex ); + JNI_type_info_holder & holder = m_type_map[ uno_name ]; + if (0 == holder.m_info) // new insertion + { + holder.m_info = new_info; + guard.clear(); + info = new_info; + } + else // inserted in the meantime + { + info = holder.m_info; + guard.clear(); + JNI_type_info::_delete( attach, new_info ); + } + } + else + { + info = iFind->second.m_info; + } + + return info; +} +//__________________________________________________________________________________________________ JNI_info::JNI_info( uno_Environment * java_env ) : m_java_env( java_env ), // unacquired pointer to owner - m_XInterface( + m_XInterface_td( ::getCppuType( (::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > const *)0 ) ), - m_Exception( + m_XInterface_queryInterface_td( + ((typelib_InterfaceTypeDescription *)m_XInterface_td.get())->ppMembers[ 0 ] ), + m_Exception_type( ::getCppuType( (::com::sun::star::uno::Exception const *)0 ) ), - m_RuntimeException( + m_RuntimeException_type( ::getCppuType( (::com::sun::star::uno::RuntimeException const *)0 ) ), m_class_JNI_proxy( 0 ) @@ -418,6 +473,8 @@ JNI_info::JNI_info( uno_Environment * java_env ) attach, find_class( attach, "com/sun/star/uno/TypeClass" ) ); JLocalAutoRef jo_IEnvironment( attach, find_class( attach, "com/sun/star/uno/IEnvironment" ) ); + JLocalAutoRef jo_TypedProxy( + attach, find_class( attach, "com/sun/star/lib/uno/TypedProxy" ) ); JLocalAutoRef jo_JNI_proxy( attach, find_class( attach, "com/sun/star/bridges/jni_uno/JNI_proxy" ) ); @@ -607,10 +664,17 @@ JNI_info::JNI_info( uno_Environment * java_env ) attach.ensure_no_exception(); OSL_ASSERT( 0 != m_method_IEnvironment_revokeInterface ); + // method TypedProxy.getType() + m_method_TypedProxy_getType = attach->GetMethodID( + (jclass)jo_TypedProxy.get(), "getType", + "()Lcom/sun/star/uno/Type;" ); + attach.ensure_no_exception(); + OSL_ASSERT( 0 != m_method_TypedProxy_getType ); + // static method JNI_proxy.create() m_method_JNI_proxy_create = attach->GetStaticMethodID( (jclass)jo_JNI_proxy.get(), "create", - "(JJJLcom/sun/star/uno/Type;Ljava/lang/String;)Ljava/lang/Object;" ); + "(JLcom/sun/star/uno/IEnvironment;JJLcom/sun/star/uno/Type;Ljava/lang/String;)Ljava/lang/Object;" ); attach.ensure_no_exception(); OSL_ASSERT( 0 != m_method_JNI_proxy_create ); // field JNI_proxy.m_receiver_handle @@ -649,11 +713,12 @@ JNI_info::JNI_info( uno_Environment * java_env ) (jclass)jo_UnoRuntime.get(), method_getEnvironment, args ) ); // make global refs + m_class_UnoRuntime = (jclass)attach->NewGlobalRef( jo_UnoRuntime.get() ); + m_class_RuntimeException = (jclass)attach->NewGlobalRef( jo_RuntimeException.get() ); m_class_Any = (jclass)attach->NewGlobalRef( jo_Any.get() ); m_class_Type = (jclass)attach->NewGlobalRef( jo_Type.get() ); m_class_TypeClass = (jclass)attach->NewGlobalRef( jo_TypeClass.get() ); - m_class_UnoRuntime = (jclass)attach->NewGlobalRef( jo_UnoRuntime.get() ); - m_class_RuntimeException = (jclass)attach->NewGlobalRef( jo_RuntimeException.get() ); + m_class_TypedProxy = (jclass)attach->NewGlobalRef( jo_TypedProxy.get() ); m_class_JNI_proxy = (jclass)attach->NewGlobalRef( jo_JNI_proxy.get() ); m_class_Character = (jclass)attach->NewGlobalRef( jo_Character.get() ); diff --git a/bridges/source/jni_uno/jni_info.h b/bridges/source/jni_uno/jni_info.h index 80eebc703aca..b4334fc5e0cd 100644 --- a/bridges/source/jni_uno/jni_info.h +++ b/bridges/source/jni_uno/jni_info.h @@ -2,9 +2,9 @@ * * $RCSfile: jni_info.h,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: dbo $ $Date: 2002-10-29 10:55:07 $ + * last change: $Author: dbo $ $Date: 2002-11-01 14:24:58 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -120,14 +120,16 @@ class JNI_info jmethodID m_method_IEnvironment_getRegisteredInterface; jmethodID m_method_IEnvironment_registerInterface; jmethodID m_method_IEnvironment_revokeInterface; + +public: // jobject m_object_java_env; -public: // - ::com::sun::star::uno::TypeDescription m_XInterface; - ::com::sun::star::uno::Type const & m_Exception; - ::com::sun::star::uno::Type const & m_RuntimeException; + ::com::sun::star::uno::TypeDescription m_XInterface_td; + ::com::sun::star::uno::TypeDescription m_XInterface_queryInterface_td; + ::com::sun::star::uno::Type const & m_Exception_type; + ::com::sun::star::uno::Type const & m_RuntimeException_type; // jclass m_class_Object; @@ -146,6 +148,7 @@ public: jclass m_class_Any; jclass m_class_Type; jclass m_class_TypeClass; + jclass m_class_TypedProxy; jclass m_class_JNI_proxy; // @@ -181,6 +184,7 @@ public: jfieldID m_field_Type__typeName; jmethodID m_method_TypeClass_fromInt; jfieldID m_field_Enum_m_value; + jmethodID m_method_TypedProxy_getType; jmethodID m_method_JNI_proxy_create; jfieldID m_field_JNI_proxy_m_receiver_handle; @@ -195,6 +199,8 @@ public: // JNI_type_info const * get_type_info( JNI_attach const & attach, typelib_TypeDescription * td ) const; + JNI_type_info const * get_type_info( + JNI_attach const & attach, ::rtl::OUString const & uno_name ) const; // inline void append_sig( ::rtl::OStringBuffer * buf, typelib_TypeDescriptionReference * type ) const; @@ -205,7 +211,6 @@ public: JNI_attach const & attach, jobject javaI, jstring oid, jobject type ) const; inline void java_env_revokeInterface( JNI_attach const & attach, jstring oid, jobject type ) const; - }; //__________________________________________________________________________________________________ inline void JNI_info::append_sig( @@ -273,7 +278,7 @@ inline void JNI_info::append_sig( break; } case typelib_TypeClass_INTERFACE: - if (typelib_typedescriptionreference_equals( type, m_XInterface.get()->pWeakRef )) + if (typelib_typedescriptionreference_equals( type, m_XInterface_td.get()->pWeakRef )) { buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;") ); } diff --git a/bridges/source/jni_uno/jni_java2uno.cxx b/bridges/source/jni_uno/jni_java2uno.cxx index 3294a0ef5c46..998b378a7d5e 100644 --- a/bridges/source/jni_uno/jni_java2uno.cxx +++ b/bridges/source/jni_uno/jni_java2uno.cxx @@ -2,9 +2,9 @@ * * $RCSfile: jni_java2uno.cxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: dbo $ $Date: 2002-10-29 10:55:08 $ + * last change: $Author: dbo $ $Date: 2002-11-01 14:24:58 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -87,6 +87,7 @@ jobject jni_Bridge::map_uno2java( JLocalAutoRef jo_iface( attach, m_jni_info->java_env_getRegisteredInterface( attach, (jstring)jo_oid.get(), info->m_jo_type ) ); + if (! jo_iface.is()) // no registered iface { // register uno interface @@ -94,37 +95,71 @@ jobject jni_Bridge::map_uno2java( m_uno_env, reinterpret_cast< void ** >( &pUnoI ), oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() ); + // create java and register java proxy + jvalue args[ 5 ]; + acquire(); + args[ 0 ].j = reinterpret_cast< sal_Int64 >( this ); + (*pUnoI->acquire)( pUnoI ); + args[ 1 ].l = m_jni_info->m_object_java_env; + args[ 2 ].j = reinterpret_cast< sal_Int64 >( pUnoI ); + typelib_typedescription_acquire( info->m_td.get() ); + args[ 3 ].j = reinterpret_cast< sal_Int64 >( info->m_td.get() ); + args[ 4 ].l = info->m_jo_type; + args[ 5 ].l = jo_oid.get(); + jo_iface.reset( + attach, attach->CallStaticObjectMethodA( + m_jni_info->m_class_JNI_proxy, + m_jni_info->m_method_JNI_proxy_create, args ) ); + attach.ensure_no_exception(); + } + + return jo_iface.release(); +} + +//################################################################################################## + +//__________________________________________________________________________________________________ +void jni_Bridge::handle_uno_exc( JNI_attach const & attach, uno_Any * uno_exc ) const +{ + if (typelib_TypeClass_EXCEPTION == uno_exc->pType->eTypeClass) + { +#ifdef DEBUG + OString cstr_msg( + OUStringToOString( + OUString(uno_exc->pType->pTypeName) + OUSTR(": ") + + *(OUString const *)uno_exc->pData, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( cstr_msg.getStr() ); +#endif + // signal exception + jvalue java_exc; try { - // create java proxy - jvalue args[ 5 ]; - acquire(); - args[ 0 ].j = reinterpret_cast< sal_Int64 >( this ); - (*pUnoI->acquire)( pUnoI ); - args[ 1 ].j = reinterpret_cast< sal_Int64 >( pUnoI ); - typelib_typedescription_acquire( info->m_td.get() ); - args[ 2 ].j = reinterpret_cast< sal_Int64 >( info->m_td.get() ); - args[ 3 ].l = info->m_jo_type; - args[ 4 ].l = jo_oid.get(); - jo_iface.reset( - attach, attach->CallStaticObjectMethodA( - m_jni_info->m_class_JNI_proxy, - m_jni_info->m_method_JNI_proxy_create, args ) ); - attach.ensure_no_exception(); - - // register at java env - jo_iface.reset( - attach, m_jni_info->java_env_registerInterface( - attach, jo_iface.get(), (jstring)jo_oid.get(), info->m_jo_type ) ); + map_to_java( attach, &java_exc, uno_exc->pData, uno_exc->pType, 0, true, false ); } catch (...) { - (*m_uno_env->revokeInterface)( m_uno_env, pUnoI ); + uno_any_destruct( uno_exc, 0 ); throw; } + uno_any_destruct( uno_exc, 0 ); + JLocalAutoRef jo_exc( attach, java_exc.l ); + jint res = attach->Throw( (jthrowable)jo_exc.get() ); + if (0 != res) + { + OUStringBuffer buf( 64 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("throwing java exception failed: [") ); + buf.append( *reinterpret_cast< OUString const * >( &uno_exc->pType->pTypeName ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); + buf.append( ((::com::sun::star::uno::Exception const *)uno_exc->pData)->Message ); + throw BridgeRuntimeError( buf.makeStringAndClear() ); + } + } + else + { + throw BridgeRuntimeError( + OUSTR("thrown exception is no uno exception: ") + + *reinterpret_cast< OUString const * >( &uno_exc->pType->pTypeName ) ); } - - return jo_iface.release(); } union largest @@ -134,17 +169,14 @@ union largest void * p; uno_Any a; }; - //__________________________________________________________________________________________________ jobject jni_Bridge::call_uno( JNI_attach const & attach, uno_Interface * pUnoI, typelib_TypeDescription * member_td, typelib_TypeDescriptionReference * return_type /* 0 indicates void return */, sal_Int32 nParams, typelib_MethodParameter const * pParams, - jobjectArray jo_args ) const + jobjectArray jo_args /* may be 0 */ ) const { - OSL_ASSERT( nParams == attach->GetArrayLength( jo_args ) ); - // return mem sal_Int32 return_size = sizeof (largest); if ((0 != return_type) && @@ -162,6 +194,7 @@ jobject jni_Bridge::call_uno( void * uno_ret = (mem + (nParams * sizeof (void *))); largest * uno_args_mem = (largest *)(mem + (nParams * sizeof (void *)) + return_size); + OSL_ASSERT( (0 == nParams) || (nParams == attach->GetArrayLength( jo_args )) ); for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) { typelib_MethodParameter const & param = pParams[ nPos ]; @@ -277,38 +310,8 @@ jobject jni_Bridge::call_uno( } } - if (typelib_TypeClass_EXCEPTION == uno_exc->pType->eTypeClass) - { -#ifdef DEBUG - OString cstr_msg( - OUStringToOString( - OUString(uno_exc->pType->pTypeName) + OUSTR(": ") + - *(OUString const *)uno_exc->pData, RTL_TEXTENCODING_ASCII_US ) ); - OSL_TRACE( cstr_msg.getStr() ); -#endif - // signal exception - jvalue java_exc; - map_to_java( attach, &java_exc, uno_exc->pData, uno_exc->pType, 0, true, false ); - JLocalAutoRef jo_exc( attach, java_exc.l ); - uno_any_destruct( uno_exc, 0 ); - jint res = attach->Throw( (jthrowable)jo_exc.get() ); - if (0 != res) - { - OUStringBuffer buf( 64 ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("throwing java exception failed: [") ); - buf.append( *reinterpret_cast< OUString const * >( &uno_exc->pType->pTypeName ) ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); - buf.append( ((::com::sun::star::uno::Exception const *)uno_exc->pData)->Message ); - throw BridgeRuntimeError( buf.makeStringAndClear() ); - } - return 0; - } - else - { - throw BridgeRuntimeError( - OUSTR("thrown exception is no uno exception: ") + - *reinterpret_cast< OUString const * >( &uno_exc->pType->pTypeName ) ); - } + handle_uno_exc( attach, uno_exc ); + return 0; } } @@ -320,8 +323,8 @@ extern "C" { //################################################################################################## JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call( - JNIEnv * jni_env, - jobject jo_proxy, jlong bridge_handle, jstring jo_method, jobjectArray jo_args ) + JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle, + jstring jo_decl_class, jstring jo_method, jobjectArray jo_args /* may be 0 */ ) { jni_Bridge const * bridge = reinterpret_cast< jni_Bridge const * >( bridge_handle ); JNI_info const * jni_info = bridge->m_jni_info; @@ -336,7 +339,8 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch OUSTR("java dispatch call occurs: ") + method_name, RTL_TEXTENCODING_ASCII_US ) ); OSL_TRACE( cstr_msg.getStr() ); #endif - // queryInterface opt + + // special IQueryInterface.queryInterface() if (method_name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("queryInterface") )) { // oid @@ -345,48 +349,78 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch // type JLocalAutoRef jo_type( attach, attach->GetObjectArrayElement( jo_args, 0 ) ); attach.ensure_no_exception(); - // getRegisteredInterface() - JLocalAutoRef jo_iface( - attach, jni_info->java_env_getRegisteredInterface( - attach, (jstring)jo_oid.get(), jo_type.get() ) ); - if (jo_iface.is()) + + JLocalAutoRef jo_type_name( + attach, attach->GetObjectField( + jo_type.get(), jni_info->m_field_Type__typeName ) ); + if (! jo_type_name.is()) + throw BridgeRuntimeError( OUSTR("incomplete type object: no type name!") ); + OUString type_name( jstring_to_oustring( attach, (jstring)jo_type_name.get() ) ); + JNI_type_info const * info = jni_info->get_type_info( attach, type_name ); + + // getRegisteredInterface() already tested in JNI_proxy + // perform queryInterface call on binary uno interface + uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >( + attach->GetLongField( + jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) ); + + uno_Any uno_ret; + void * uno_args[] = { &info->m_td.get()->pWeakRef }; + uno_Any * uno_exc; + // call binary uno + (*pUnoI->pDispatcher)( + pUnoI, jni_info->m_XInterface_queryInterface_td.get(), + &uno_ret, uno_args, &uno_exc ); + if (0 == uno_exc) { - return jo_iface.release(); + jobject jo_ret = 0; + if (typelib_TypeClass_INTERFACE == uno_ret.pType->eTypeClass) + { + uno_Interface * pUnoRet = (uno_Interface *)uno_ret.pReserved; + if (0 != pUnoRet) + { + try + { + jo_ret = bridge->map_uno2java( attach, pUnoRet, info ); + } + catch (...) + { + uno_any_destruct( &uno_ret, 0 ); + throw; + } + } + } + uno_any_destruct( &uno_ret, 0 ); + return jo_ret; } - else // call queryInterface + else { - uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >( - attach->GetLongField( - jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) ); - typelib_InterfaceTypeDescription * td = - (typelib_InterfaceTypeDescription *)jni_info->m_XInterface.get(); - TypeDescr member_td( td->ppMembers[ 0 ] ); // queryInterface - typelib_InterfaceMethodTypeDescription * method_td = - (typelib_InterfaceMethodTypeDescription *)member_td.get(); - // idl returns an any - JLocalAutoRef jo_any( - attach, bridge->call_uno( - attach, pUnoI, member_td.get(), - method_td->pReturnTypeRef, method_td->nParams, method_td->pParams, - jo_args ) ); - return attach->GetObjectField( - jo_any.get(), bridge->m_jni_info->m_field_Any__object ); + bridge->handle_uno_exc( attach, uno_exc ); + return 0; } } + // determine exact interface td typelib_InterfaceTypeDescription * td = reinterpret_cast< typelib_InterfaceTypeDescription * >( attach->GetLongField( jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) ); + OUString iface_name( jstring_to_oustring( attach, jo_decl_class ) ); + while (! reinterpret_cast< OUString const * >( + &((typelib_TypeDescription *)td)->pTypeName )->equals( iface_name )) + { + td = td->pBaseTypeDescription; + } + uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >( attach->GetLongField( jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) ); - typelib_TypeDescriptionReference ** ppAllMembers = td->ppAllMembers; - for ( sal_Int32 nPos = td->nAllMembers; nPos--; ) + typelib_TypeDescriptionReference ** ppMembers = td->ppMembers; + for ( sal_Int32 nPos = td->nMembers; nPos--; ) { // try to avoid getting typedescription as long as possible, // because of a Mutex.acquire() in typelib_typedescriptionreference_getDescription() - typelib_TypeDescriptionReference * member_type = ppAllMembers[ nPos ]; + typelib_TypeDescriptionReference * member_type = ppMembers[ nPos ]; // check method_name against fully qualified type_name of member_type OUString const & type_name = @@ -400,7 +434,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch type_name.getStr() + type_name.getLength() - method_name.getLength() ) /* ends with method_name: */)) { - TypeDescr member_td( ppAllMembers[ nPos ] ); + TypeDescr member_td( ppMembers[ nPos ] ); typelib_InterfaceMethodTypeDescription * method_td = (typelib_InterfaceMethodTypeDescription *)member_td.get(); return bridge->call_uno( @@ -424,7 +458,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch { if ('g' == method_name[ 0 ]) { - TypeDescr member_td( ppAllMembers[ nPos ] ); + TypeDescr member_td( ppMembers[ nPos ] ); typelib_InterfaceAttributeTypeDescription * attribute_td = (typelib_InterfaceAttributeTypeDescription *)member_td.get(); return bridge->call_uno( @@ -434,7 +468,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch } else if ('s' == method_name[ 0 ]) { - TypeDescr member_td( ppAllMembers[ nPos ] ); + TypeDescr member_td( ppMembers[ nPos ] ); typelib_InterfaceAttributeTypeDescription * attribute_td = (typelib_InterfaceAttributeTypeDescription *)member_td.get(); if (! attribute_td->bReadOnly) @@ -480,49 +514,22 @@ JNIEXPORT void JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J typelib_TypeDescription * td = reinterpret_cast< typelib_TypeDescription * >( attach->GetLongField( jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) ); - try - { - // revoke from java env - JLocalAutoRef jo_oid( - attach, attach->GetObjectField( jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) ); - JLocalAutoRef jo_type( - attach, attach->GetObjectField( jo_proxy, jni_info->m_field_JNI_proxy_m_type ) ); #ifdef DEBUG - OUString oid( jstring_to_oustring( attach, (jstring)jo_oid.get() ) ); - OString cstr_msg( - OUStringToOString( - OUSTR("freeing java uno proxy: ") + oid, RTL_TEXTENCODING_ASCII_US ) ); - OSL_TRACE( cstr_msg.getStr() ); + JLocalAutoRef jo_oid( + attach, attach->GetObjectField( jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) ); + OUString oid( jstring_to_oustring( attach, (jstring)jo_oid.get() ) ); + OString cstr_msg( + OUStringToOString( + OUSTR("freeing java uno proxy: ") + oid, RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( cstr_msg.getStr() ); #endif - // revoke from java env - jni_info->java_env_revokeInterface( attach, (jstring)jo_oid.get(), jo_type.get() ); - - // revoke from uno env - (*bridge->m_uno_env->revokeInterface)( bridge->m_uno_env, pUnoI ); - - // release receiver - (*pUnoI->release)( pUnoI ); - // release typedescription handle - typelib_typedescription_release( td ); - // release bridge handle - bridge->release(); - } - catch (BridgeRuntimeError & err) - { - // revoke from uno env - (*bridge->m_uno_env->revokeInterface)( bridge->m_uno_env, pUnoI ); - // release receiver - (*pUnoI->release)( pUnoI ); - // release typedescription handle - typelib_typedescription_release( td ); - // release bridge handle - bridge->release(); - // notify RuntimeException - OString cstr_msg( - OUStringToOString( - OUSTR("[jni_uno bridge error] ") + err.m_message, RTL_TEXTENCODING_ASCII_US ) ); - jint res = attach->ThrowNew( jni_info->m_class_RuntimeException, cstr_msg.getStr() ); - OSL_ASSERT( 0 == res ); - } + // revoke from uno env; has already been revoked from java env + (*bridge->m_uno_env->revokeInterface)( bridge->m_uno_env, pUnoI ); + // release receiver + (*pUnoI->release)( pUnoI ); + // release typedescription handle + typelib_typedescription_release( td ); + // release bridge handle + bridge->release(); } } diff --git a/bridges/source/jni_uno/jni_uno2java.cxx b/bridges/source/jni_uno/jni_uno2java.cxx index ae0c33623d22..b66527544b26 100644 --- a/bridges/source/jni_uno/jni_uno2java.cxx +++ b/bridges/source/jni_uno/jni_uno2java.cxx @@ -2,9 +2,9 @@ * * $RCSfile: jni_uno2java.cxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: dbo $ $Date: 2002-10-29 10:55:08 $ + * last change: $Author: dbo $ $Date: 2002-11-01 14:24:58 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -70,10 +70,9 @@ using namespace ::rtl; namespace jni_bridge { -//-------------------------------------------------------------------------------------------------- -static void handle_java_exc( - JNI_attach const & attach, jni_Bridge const * bridge, - JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) +//__________________________________________________________________________________________________ +void jni_Bridge::handle_java_exc( + JNI_attach const & attach, JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) const { OSL_ASSERT( jo_exc.is() ); if (! jo_exc.is()) @@ -89,7 +88,7 @@ static void handle_java_exc( // call toString() JLocalAutoRef jo_descr( attach, attach->CallObjectMethodA( - jo_exc.get(), bridge->m_jni_info->m_method_Object_toString, 0 ) ); + jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) ); attach.ensure_no_exception(); OUString descr( jstring_to_oustring( attach, (jstring)jo_descr.get() ) ); throw BridgeRuntimeError( OUSTR("non-UNO exception occurred: ") + descr ); @@ -98,7 +97,7 @@ static void handle_java_exc( auto_ptr< rtl_mem > uno_data( rtl_mem::allocate( td.get()->nSize ) ); jvalue val; val.l = jo_exc.get(); - bridge->map_to_uno( + map_to_uno( attach, uno_data.get(), val, td.get()->pWeakRef, 0, false /* no assign */, false /* no out param */ ); @@ -113,7 +112,6 @@ static void handle_java_exc( OSL_TRACE( cstr_msg.getStr() ); #endif } - //__________________________________________________________________________________________________ void jni_Bridge::call_java( jobject javaI, JNI_type_info const * info, sal_Int32 function_pos, @@ -226,7 +224,7 @@ void jni_Bridge::call_java( attach->DeleteLocalRef( java_args[ nPos ].l ); } - handle_java_exc( attach, this, jo_exc, *uno_exc ); + handle_java_exc( attach, jo_exc, *uno_exc ); } else // no exception { @@ -301,7 +299,8 @@ struct jni_unoInterfaceProxy : public uno_Interface // ctor inline jni_unoInterfaceProxy( JNI_attach const & attach, jni_Bridge const * bridge, - jobject javaI, jstring jo_oid, OUString const & oid, JNI_type_info const * info ); + jobject javaI, jstring jo_oid, OUString const & oid, JNI_type_info const * info ) + SAL_THROW( () ); }; //-------------------------------------------------------------------------------------------------- @@ -375,7 +374,7 @@ static void SAL_CALL jni_unoInterfaceProxy_acquire( jni_unoInterfaceProxy * that //-------------------------------------------------------------------------------------------------- static void SAL_CALL jni_unoInterfaceProxy_release( jni_unoInterfaceProxy * that ) SAL_THROW( () ) { - if (! osl_decrementInterlockedCount( &that->m_ref )) + if (0 == osl_decrementInterlockedCount( &that->m_ref )) { // revoke from uno env on last release (*that->m_bridge->m_uno_env->revokeInterface)( that->m_bridge->m_uno_env, that ); @@ -385,6 +384,7 @@ static void SAL_CALL jni_unoInterfaceProxy_release( jni_unoInterfaceProxy * that inline jni_unoInterfaceProxy::jni_unoInterfaceProxy( JNI_attach const & attach, jni_Bridge const * bridge, jobject javaI, jstring jo_oid, OUString const & oid, JNI_type_info const * info ) + SAL_THROW( () ) : m_ref( 1 ), m_oid( oid ), m_type_info( info ) @@ -488,15 +488,7 @@ static void SAL_CALL jni_unoInterfaceProxy_dispatch( (void **)&pInterface, that->m_oid.pData, (typelib_InterfaceTypeDescription *)demanded_td.get() ); - if (pInterface) - { - uno_any_construct( - reinterpret_cast< uno_Any * >( uno_ret ), - &pInterface, demanded_td.get(), 0 ); - (*pInterface->release)( pInterface ); - *uno_exc = 0; - } - else + if (0 == pInterface) { JNI_info const * jni_info = bridge->m_jni_info; JNI_attach attach( bridge->m_java_env ); @@ -517,7 +509,7 @@ static void SAL_CALL jni_unoInterfaceProxy_dispatch( { JLocalAutoRef jo_exc( attach, attach->ExceptionOccurred() ); attach->ExceptionClear(); - handle_java_exc( attach, bridge, jo_exc, *uno_exc ); + bridge->handle_java_exc( attach, jo_exc, *uno_exc ); } else { @@ -531,30 +523,21 @@ static void SAL_CALL jni_unoInterfaceProxy_dispatch( JLocalAutoRef jo_iface( attach, jni_info->java_env_registerInterface( attach, jo_ret.get(), that->m_jo_oid, info->m_jo_type ) ); - try - { - // refcount initially 1 - uno_Interface * pUnoI = new jni_unoInterfaceProxy( - attach, bridge, jo_iface.get(), - (jstring)jo_oid.get(), oid, info ); - - (*bridge->m_uno_env->registerProxyInterface)( - bridge->m_uno_env, reinterpret_cast< void ** >( &pUnoI ), - (uno_freeProxyFunc)jni_unoInterfaceProxy_free, - that->m_oid.pData, - (typelib_InterfaceTypeDescription *)info->m_td.get() ); - - uno_any_construct( - (uno_Any *)uno_ret, &pUnoI, demanded_td.get(), 0 ); - (*pUnoI->release)( pUnoI ); - } - catch (...) - { - // cleanup - jni_info->java_env_revokeInterface( - attach, that->m_jo_oid, info->m_jo_type ); - throw; - } + + // refcount initially 1 + uno_Interface * pUnoI = new jni_unoInterfaceProxy( + attach, bridge, jo_iface.get(), + that->m_jo_oid, that->m_oid, info ); + + (*bridge->m_uno_env->registerProxyInterface)( + bridge->m_uno_env, reinterpret_cast< void ** >( &pUnoI ), + (uno_freeProxyFunc)jni_unoInterfaceProxy_free, + that->m_oid.pData, + (typelib_InterfaceTypeDescription *)info->m_td.get() ); + + uno_any_construct( + (uno_Any *)uno_ret, &pUnoI, demanded_td.get(), 0 ); + (*pUnoI->release)( pUnoI ); } else // object does not support demanded interface { @@ -564,6 +547,14 @@ static void SAL_CALL jni_unoInterfaceProxy_dispatch( *uno_exc = 0; } } + else + { + uno_any_construct( + reinterpret_cast< uno_Any * >( uno_ret ), + &pInterface, demanded_td.get(), 0 ); + (*pInterface->release)( pInterface ); + *uno_exc = 0; + } break; } case 1: // acquire uno interface @@ -622,30 +613,22 @@ uno_Interface * jni_Bridge::map_java2uno( (*m_uno_env->getRegisteredInterface)( m_uno_env, (void **)&pUnoI, oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() ); + if (0 == pUnoI) // no existing interface, register new proxy { JLocalAutoRef jo_iface( attach, m_jni_info->java_env_registerInterface( attach, javaI, (jstring)jo_oid.get(), info->m_jo_type ) ); - try - { - // refcount initially 1 - pUnoI = new jni_unoInterfaceProxy( - attach, const_cast< jni_Bridge * >( this ), - jo_iface.get(), (jstring)jo_oid.get(), oid, info ); - - (*m_uno_env->registerProxyInterface)( - m_uno_env, reinterpret_cast< void ** >( &pUnoI ), - (uno_freeProxyFunc)jni_unoInterfaceProxy_free, - oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() ); - } - catch (...) - { - // cleanup - m_jni_info->java_env_revokeInterface( - attach, (jstring)jo_oid.get(), info->m_jo_type ); - throw; - } + + // refcount initially 1 + pUnoI = new jni_unoInterfaceProxy( + attach, const_cast< jni_Bridge * >( this ), + jo_iface.get(), (jstring)jo_oid.get(), oid, info ); + + (*m_uno_env->registerProxyInterface)( + m_uno_env, reinterpret_cast< void ** >( &pUnoI ), + (uno_freeProxyFunc)jni_unoInterfaceProxy_free, + oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() ); } return pUnoI; } |