163a165407
2006/11/07 16:36:20 vg 1.24.12.2: RESYNC: (1.24-1.25); FILE MERGED 2006/09/07 09:21:09 vg 1.24.12.1: #i53572# MinGW port
716 lines
26 KiB
C++
716 lines
26 KiB
C++
/*************************************************************************
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* $RCSfile: jni_java2uno.cxx,v $
|
|
*
|
|
* $Revision: 1.26 $
|
|
*
|
|
* last change: $Author: vg $ $Date: 2007-03-26 13:15:43 $
|
|
*
|
|
* The Contents of this file are made available subject to
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
|
*
|
|
*
|
|
* GNU Lesser General Public License Version 2.1
|
|
* =============================================
|
|
* Copyright 2005 by Sun Microsystems, Inc.
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
*
|
|
* This library 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 for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*
|
|
************************************************************************/
|
|
|
|
// 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>
|
|
|
|
|
|
#ifdef __MINGW32__
|
|
#define BROKEN_ALLOCA
|
|
#endif
|
|
|
|
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, ¶m,
|
|
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();
|
|
}
|
|
|
|
}
|