summaryrefslogtreecommitdiff
path: root/bridges/source/jni_uno/jni_java2uno.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bridges/source/jni_uno/jni_java2uno.cxx')
-rw-r--r--bridges/source/jni_uno/jni_java2uno.cxx704
1 files changed, 704 insertions, 0 deletions
diff --git a/bridges/source/jni_uno/jni_java2uno.cxx b/bridges/source/jni_uno/jni_java2uno.cxx
new file mode 100644
index 000000000000..0ff4872804bb
--- /dev/null
+++ b/bridges/source/jni_uno/jni_java2uno.cxx
@@ -0,0 +1,704 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include "jni_bridge.h"
+//#include "jni_finalizer.h"
+
+#include <rtl/ustrbuf.hxx>
+
+#include <algorithm>
+
+
+using namespace ::rtl;
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+jobject Bridge::map_to_java(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, JNI_interface_type_info const * info ) const
+{
+ // get oid
+ rtl_uString * pOid = 0;
+ (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI );
+ OSL_ASSERT( 0 != pOid );
+ OUString oid( pOid, SAL_NO_ACQUIRE );
+
+ // opt getRegisteredInterface()
+ JLocalAutoRef jo_oid( jni, ustring_to_jstring( jni, oid.pData ) );
+ jvalue args[ 2 ];
+ args[ 0 ].l = jo_oid.get();
+ args[ 1 ].l = info->m_type;
+ jobject jo_iface = jni->CallObjectMethodA(
+ m_jni_info->m_object_java_env,
+ m_jni_info->m_method_IEnvironment_getRegisteredInterface, args );
+ jni.ensure_no_exception();
+
+ if (0 == jo_iface) // no registered iface
+ {
+ // register uno interface
+ (*m_uno_env->registerInterface)(
+ m_uno_env, reinterpret_cast< void ** >( &pUnoI ),
+ oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
+
+ // create java and register java proxy
+ jvalue args2[ 7 ];
+ acquire();
+ args2[ 0 ].j = reinterpret_cast< sal_Int64 >( this );
+ (*pUnoI->acquire)( pUnoI );
+ args2[ 1 ].l = m_jni_info->m_object_java_env;
+ args2[ 2 ].j = reinterpret_cast< sal_Int64 >( pUnoI );
+ typelib_typedescription_acquire( info->m_td.get() );
+ args2[ 3 ].j = reinterpret_cast< sal_Int64 >( info->m_td.get() );
+ args2[ 4 ].l = info->m_type;
+ args2[ 5 ].l = jo_oid.get();
+ args2[ 6 ].l = info->m_proxy_ctor;
+ jo_iface = jni->CallStaticObjectMethodA(
+ m_jni_info->m_class_JNI_proxy,
+ m_jni_info->m_method_JNI_proxy_create, args2 );
+ jni.ensure_no_exception();
+ }
+
+ OSL_ASSERT( 0 != jo_iface );
+ return jo_iface;
+}
+
+
+//______________________________________________________________________________
+void Bridge::handle_uno_exc( JNI_context const & jni, uno_Any * uno_exc ) const
+{
+ if (typelib_TypeClass_EXCEPTION == uno_exc->pType->eTypeClass)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // append java stack trace to Message member
+ reinterpret_cast< ::com::sun::star::uno::Exception * >(
+ uno_exc->pData )->Message += jni.get_stack_trace();
+#endif
+
+#if OSL_DEBUG_LEVEL > 1
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("exception occured java->uno: [") );
+ buf.append( OUString::unacquired( &uno_exc->pType->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
+ buf.append(
+ reinterpret_cast< ::com::sun::star::uno::Exception const * >(
+ uno_exc->pData )->Message );
+ OString cstr_msg(
+ OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+ }
+#endif
+ // signal exception
+ jvalue java_exc;
+ try
+ {
+ map_to_java(
+ jni, &java_exc, uno_exc->pData, uno_exc->pType, 0,
+ true /* in */, false /* no out */ );
+ }
+ catch (...)
+ {
+ uno_any_destruct( uno_exc, 0 );
+ throw;
+ }
+ uno_any_destruct( uno_exc, 0 );
+
+ JLocalAutoRef jo_exc( jni, java_exc.l );
+ jint res = jni->Throw( (jthrowable) jo_exc.get() );
+ if (0 != res)
+ {
+ // call toString()
+ JLocalAutoRef jo_descr(
+ jni, jni->CallObjectMethodA(
+ jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "throwing java exception failed: ") );
+ buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ OUString message(
+ OUSTR("thrown exception is no uno exception: ") +
+ OUString::unacquired( &uno_exc->pType->pTypeName ) +
+ jni.get_stack_trace() );
+ uno_any_destruct( uno_exc, 0 );
+ throw BridgeRuntimeError( message );
+ }
+}
+
+union largest
+{
+ sal_Int64 n;
+ double d;
+ void * p;
+ uno_Any a;
+};
+
+//______________________________________________________________________________
+jobject Bridge::call_uno(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, typelib_TypeDescription * member_td,
+ typelib_TypeDescriptionReference * return_type,
+ sal_Int32 nParams, typelib_MethodParameter const * pParams,
+ jobjectArray jo_args /* may be 0 */ ) const
+{
+ // return mem
+ sal_Int32 return_size;
+ switch (return_type->eTypeClass) {
+ case typelib_TypeClass_VOID:
+ return_size = 0;
+ break;
+
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ return_size = std::max(
+ TypeDescr(return_type).get()->nSize,
+ static_cast< sal_Int32 >(sizeof (largest)));
+ break;
+
+ default:
+ return_size = sizeof (largest);
+ break;
+ }
+
+#ifdef BROKEN_ALLOCA
+ char * mem = (char *) malloc(
+#else
+ char * mem = (char *) alloca(
+#endif
+ (nParams * sizeof (void *)) +
+ return_size + (nParams * sizeof (largest)) );
+ void ** uno_args = (void **) mem;
+ void * uno_ret = return_size == 0 ? 0 : (mem + (nParams * sizeof (void *)));
+ largest * uno_args_mem = (largest *)
+ (mem + (nParams * sizeof (void *)) + return_size);
+
+ OSL_ASSERT( (0 == nParams) || (nParams == jni->GetArrayLength( jo_args )) );
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = pParams[ nPos ];
+ typelib_TypeDescriptionReference * type = param.pTypeRef;
+
+ uno_args[ nPos ] = &uno_args_mem[ nPos ];
+ if (typelib_TypeClass_STRUCT == type->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == type->eTypeClass)
+ {
+ TypeDescr td( type );
+ if (sal::static_int_cast< sal_uInt32 >(td.get()->nSize)
+ > sizeof (largest))
+#ifdef BROKEN_ALLOCA
+ uno_args[ nPos ] = malloc( td.get()->nSize );
+#else
+ uno_args[ nPos ] = alloca( td.get()->nSize );
+#endif
+ }
+
+ if (param.bIn)
+ {
+ try
+ {
+ JLocalAutoRef jo_arg(
+ jni, jni->GetObjectArrayElement( jo_args, nPos ) );
+ jni.ensure_no_exception();
+ jvalue java_arg;
+ java_arg.l = jo_arg.get();
+ map_to_uno(
+ jni, uno_args[ nPos ], java_arg, type, 0,
+ false /* no assign */, sal_False != param.bOut,
+ true /* special wrapped integral types */ );
+ }
+ catch (...)
+ {
+ // cleanup uno in args
+ for ( sal_Int32 n = 0; n < nPos; ++n )
+ {
+ typelib_MethodParameter const & p = pParams[ n ];
+ if (p.bIn)
+ {
+ uno_type_destructData(
+ uno_args[ n ], p.pTypeRef, 0 );
+ }
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ throw;
+ }
+ }
+ }
+
+ uno_Any uno_exc_holder;
+ uno_Any * uno_exc = &uno_exc_holder;
+ // call binary uno
+ (*pUnoI->pDispatcher)( pUnoI, member_td, uno_ret, uno_args, &uno_exc );
+
+ if (0 == uno_exc)
+ {
+ // convert out args; destruct uno args
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = pParams[ nPos ];
+ typelib_TypeDescriptionReference * type = param.pTypeRef;
+ if (param.bOut)
+ {
+ try
+ {
+ // get out holder array[ 1 ]
+ JLocalAutoRef jo_out_holder(
+ jni, jni->GetObjectArrayElement( jo_args, nPos ) );
+ jni.ensure_no_exception();
+ jvalue java_arg;
+ java_arg.l = jo_out_holder.get();
+ map_to_java(
+ jni, &java_arg, uno_args[ nPos ], type, 0,
+ true /* in */, true /* out holder */ );
+ }
+ catch (...)
+ {
+ // cleanup further uno args
+ for ( sal_Int32 n = nPos; n < nParams; ++n )
+ {
+ uno_type_destructData(
+ uno_args[ n ], pParams[ n ].pTypeRef, 0 );
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+ // cleanup uno return value
+ uno_type_destructData( uno_ret, return_type, 0 );
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ throw;
+ }
+ }
+ if (typelib_TypeClass_DOUBLE < type->eTypeClass &&
+ typelib_TypeClass_ENUM != type->eTypeClass) // opt
+ {
+ uno_type_destructData( uno_args[ nPos ], type, 0 );
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+ }
+
+ if (typelib_TypeClass_VOID != return_type->eTypeClass)
+ {
+ // convert uno return value
+ jvalue java_ret;
+ try
+ {
+ map_to_java(
+ jni, &java_ret, uno_ret, return_type, 0,
+ true /* in */, false /* no out */,
+ true /* special_wrapped_integral_types */ );
+ }
+ catch (...)
+ {
+ uno_type_destructData( uno_ret, return_type, 0 );
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ throw;
+ }
+ if (typelib_TypeClass_DOUBLE < return_type->eTypeClass &&
+ typelib_TypeClass_ENUM != return_type->eTypeClass) // opt
+ {
+ uno_type_destructData( uno_ret, return_type, 0 );
+ }
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ return java_ret.l;
+ }
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ return 0; // void return
+ }
+ else // exception occured
+ {
+ // destruct uno in args
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = pParams[ nPos ];
+ if (param.bIn)
+ uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 );
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+
+ handle_uno_exc( jni, uno_exc );
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ return 0;
+ }
+}
+
+}
+
+using namespace ::jni_uno;
+
+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,
+ jstring jo_method, jobjectArray jo_args /* may be 0 */ )
+ SAL_THROW_EXTERN_C()
+{
+ Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JNI_context jni(
+ jni_info, jni_env,
+ static_cast< jobject >(
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext )->getClassLoader() ) );
+
+ OUString method_name;
+
+ try
+ {
+ method_name = jstring_to_oustring( jni, jo_method );
+#if OSL_DEBUG_LEVEL > 1
+ {
+ OUStringBuffer trace_buf( 64 );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("java->uno call: ") );
+ trace_buf.append( method_name );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") );
+ JLocalAutoRef jo_oid(
+ jni, jni->GetObjectField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
+ OString cstr_msg(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+ }
+#endif
+
+ // special IQueryInterface.queryInterface()
+ if (method_name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("queryInterface") ))
+ {
+ // oid
+ JLocalAutoRef jo_oid(
+ jni, jni->GetObjectField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
+ // type
+ JLocalAutoRef jo_type(
+ jni, jni->GetObjectArrayElement( jo_args, 0 ) );
+ jni.ensure_no_exception();
+
+ JLocalAutoRef jo_type_name(
+ jni, jni->GetObjectField(
+ jo_type.get(), jni_info->m_field_Type__typeName ) );
+ if (! jo_type_name.is())
+ {
+ throw BridgeRuntimeError(
+ OUSTR("incomplete type object: no type name!") +
+ jni.get_stack_trace() );
+ }
+ OUString type_name(
+ jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
+ JNI_type_info const * info =
+ jni_info->get_type_info( jni, type_name );
+ if (typelib_TypeClass_INTERFACE != info->m_td.get()->eTypeClass)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("queryInterface() call demands an INTERFACE type!") );
+ }
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >( info );
+
+ // getRegisteredInterface() already tested in JNI_proxy:
+ // perform queryInterface call on binary uno interface
+ uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
+
+ uno_Any uno_ret;
+ void * uno_args[] = { &iface_info->m_td.get()->pWeakRef };
+ uno_Any uno_exc_holder;
+ uno_Any * uno_exc = &uno_exc_holder;
+ // call binary uno
+ (*pUnoI->pDispatcher)(
+ pUnoI, jni_info->m_XInterface_queryInterface_td.get(),
+ &uno_ret, uno_args, &uno_exc );
+ if (0 == uno_exc)
+ {
+ 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_to_java( jni, pUnoRet, iface_info );
+ }
+ catch (...)
+ {
+ uno_any_destruct( &uno_ret, 0 );
+ throw;
+ }
+ }
+ }
+ uno_any_destruct( &uno_ret, 0 );
+ return jo_ret;
+ }
+ else
+ {
+ bridge->handle_uno_exc( jni, uno_exc );
+ return 0;
+ }
+ }
+
+ typelib_InterfaceTypeDescription * td =
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
+ uno_Interface * pUnoI =
+ reinterpret_cast< uno_Interface * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
+
+ typelib_TypeDescriptionReference ** ppAllMembers = td->ppAllMembers;
+ for ( sal_Int32 nPos = td->nAllMembers; 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 ];
+
+ // check method_name against fully qualified type_name
+ // of member_type; type_name is of the form
+ // <name> "::" <method_name> *(":@" <idx> "," <idx> ":" <name>)
+ OUString const & type_name =
+ OUString::unacquired( &member_type->pTypeName );
+ sal_Int32 offset = type_name.indexOf( ':' ) + 2;
+ OSL_ASSERT(
+ offset >= 2 && offset < type_name.getLength()
+ && type_name[offset - 1] == ':' );
+ sal_Int32 remainder = type_name.getLength() - offset;
+ if (typelib_TypeClass_INTERFACE_METHOD == member_type->eTypeClass)
+ {
+ if ((method_name.getLength() == remainder
+ || (method_name.getLength() < remainder
+ && type_name[offset + method_name.getLength()] == ':'))
+ && type_name.match(method_name, offset))
+ {
+ TypeDescr member_td( member_type );
+ typelib_InterfaceMethodTypeDescription * method_td =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member_td.get() );
+ return bridge->call_uno(
+ jni, pUnoI, member_td.get(),
+ method_td->pReturnTypeRef,
+ method_td->nParams, method_td->pParams,
+ jo_args );
+ }
+ }
+ else // attribute
+ {
+ OSL_ASSERT(
+ typelib_TypeClass_INTERFACE_ATTRIBUTE ==
+ member_type->eTypeClass );
+
+ if (method_name.getLength() >= 3
+ && (method_name.getLength() - 3 == remainder
+ || (method_name.getLength() - 3 < remainder
+ && type_name[
+ offset + (method_name.getLength() - 3)] == ':'))
+ && method_name[1] == 'e' && method_name[2] == 't'
+ && rtl_ustr_compare_WithLength(
+ type_name.getStr() + offset,
+ method_name.getLength() - 3,
+ method_name.getStr() + 3,
+ method_name.getLength() - 3) == 0)
+ {
+ if ('g' == method_name[ 0 ])
+ {
+ TypeDescr member_td( member_type );
+ typelib_InterfaceAttributeTypeDescription * attr_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member_td.get() );
+ return bridge->call_uno(
+ jni, pUnoI, member_td.get(),
+ attr_td->pAttributeTypeRef,
+ 0, 0,
+ jo_args );
+ }
+ else if ('s' == method_name[ 0 ])
+ {
+ TypeDescr member_td( member_type );
+ typelib_InterfaceAttributeTypeDescription * attr_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member_td.get() );
+ if (! attr_td->bReadOnly)
+ {
+ typelib_MethodParameter param;
+ param.pTypeRef = attr_td->pAttributeTypeRef;
+ param.bIn = sal_True;
+ param.bOut = sal_False;
+ return bridge->call_uno(
+ jni, pUnoI, member_td.get(),
+ jni_info->m_void_type.getTypeLibType(),
+ 1, &param,
+ jo_args );
+ }
+ }
+ }
+ }
+ }
+ // the thing that should not be... no method info found!
+ OUStringBuffer buf( 64 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "calling undeclared function on interface ") );
+ buf.append( OUString::unacquired(
+ &((typelib_TypeDescription *)td)->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ buf.append( method_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ catch (BridgeRuntimeError & err)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("[jni_uno bridge error] "
+ "Java calling UNO method ") );
+ buf.append( method_name );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ buf.append( err.m_message );
+ // notify RuntimeException
+ OString cstr_msg(
+ OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_JAVA_UTF8 ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+ if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
+ != 0)
+ {
+ OSL_ASSERT( false );
+ }
+ return 0;
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OString cstr_msg(
+ OString( RTL_CONSTASCII_STRINGPARAM(
+ "[jni_uno bridge error] "
+ "attaching current thread to java failed!") ) +
+ OUStringToOString(
+ jni.get_stack_trace(), RTL_TEXTENCODING_JAVA_UTF8 ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+ if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
+ != 0)
+ {
+ OSL_ASSERT( false );
+ }
+ return 0;
+ }
+}
+
+//------------------------------------------------------------------------------
+JNIEXPORT void
+JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J(
+ JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle )
+ SAL_THROW_EXTERN_C()
+{
+ Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JNI_context jni(
+ jni_info, jni_env,
+ static_cast< jobject >(
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext )->getClassLoader() ) );
+
+ uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
+ typelib_TypeDescription * td =
+ reinterpret_cast< typelib_TypeDescription * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
+
+#if OSL_DEBUG_LEVEL > 1
+ {
+ JLocalAutoRef jo_oid(
+ jni, jni->GetObjectField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
+ OUString oid( jstring_to_oustring( jni, (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 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();
+}
+
+}