LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/bridges/source/jni_uno - jni_java2uno.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 121 229 52.8 %
Date: 2013-07-09 Functions: 4 5 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <sal/alloca.h>
      22             : 
      23             : #include "jni_bridge.h"
      24             : 
      25             : #include <rtl/ustrbuf.hxx>
      26             : 
      27             : #include <algorithm>
      28             : 
      29             : 
      30             : using namespace ::rtl;
      31             : 
      32             : namespace jni_uno
      33             : {
      34             : 
      35             : //______________________________________________________________________________
      36          25 : jobject Bridge::map_to_java(
      37             :     JNI_context const & jni,
      38             :     uno_Interface * pUnoI, JNI_interface_type_info const * info ) const
      39             : {
      40             :     // get oid
      41          25 :     rtl_uString * pOid = 0;
      42          25 :     (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI );
      43             :     OSL_ASSERT( 0 != pOid );
      44          25 :     OUString oid( pOid, SAL_NO_ACQUIRE );
      45             : 
      46             :     // opt getRegisteredInterface()
      47          50 :     JLocalAutoRef jo_oid( jni, ustring_to_jstring( jni, oid.pData ) );
      48             :     jvalue args[ 2 ];
      49          25 :     args[ 0 ].l = jo_oid.get();
      50          25 :     args[ 1 ].l = info->m_type;
      51             :     jobject jo_iface = jni->CallObjectMethodA(
      52             :         m_jni_info->m_object_java_env,
      53          25 :         m_jni_info->m_method_IEnvironment_getRegisteredInterface, args );
      54          25 :     jni.ensure_no_exception();
      55             : 
      56          25 :     if (0 == jo_iface) // no registered iface
      57             :     {
      58             :         // register uno interface
      59             :         (*m_uno_env->registerInterface)(
      60             :             m_uno_env, reinterpret_cast< void ** >( &pUnoI ),
      61          24 :             oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
      62             : 
      63             :         // create java and register java proxy
      64             :         jvalue args2[ 7 ];
      65          24 :         acquire();
      66          24 :         args2[ 0 ].j = reinterpret_cast< sal_Int64 >( this );
      67          24 :         (*pUnoI->acquire)( pUnoI );
      68          24 :         args2[ 1 ].l = m_jni_info->m_object_java_env;
      69          24 :         args2[ 2 ].j = reinterpret_cast< sal_Int64 >( pUnoI );
      70          24 :         typelib_typedescription_acquire( info->m_td.get() );
      71          24 :         args2[ 3 ].j = reinterpret_cast< sal_Int64 >( info->m_td.get() );
      72          24 :         args2[ 4 ].l = info->m_type;
      73          24 :         args2[ 5 ].l = jo_oid.get();
      74          24 :         args2[ 6 ].l = info->m_proxy_ctor;
      75             :         jo_iface = jni->CallStaticObjectMethodA(
      76             :             m_jni_info->m_class_JNI_proxy,
      77          24 :             m_jni_info->m_method_JNI_proxy_create, args2 );
      78          24 :         jni.ensure_no_exception();
      79             :     }
      80             : 
      81             :     OSL_ASSERT( 0 != jo_iface );
      82          50 :     return jo_iface;
      83             : }
      84             : 
      85             : 
      86             : //______________________________________________________________________________
      87           0 : void Bridge::handle_uno_exc( JNI_context const & jni, uno_Any * uno_exc ) const
      88             : {
      89           0 :     if (typelib_TypeClass_EXCEPTION == uno_exc->pType->eTypeClass)
      90             :     {
      91             : #if OSL_DEBUG_LEVEL > 0
      92             :         // append java stack trace to Message member
      93             :         reinterpret_cast< ::com::sun::star::uno::Exception * >(
      94             :             uno_exc->pData )->Message += jni.get_stack_trace();
      95             : #endif
      96             : 
      97             : #if OSL_DEBUG_LEVEL > 1
      98             :         {
      99             :         OUStringBuffer buf( 128 );
     100             :         buf.append( "exception occurred java->uno: [" );
     101             :         buf.append( OUString::unacquired( &uno_exc->pType->pTypeName ) );
     102             :         buf.append( "] " );
     103             :         buf.append(
     104             :             reinterpret_cast< ::com::sun::star::uno::Exception const * >(
     105             :                 uno_exc->pData )->Message );
     106             :         OString cstr_msg(
     107             :             OUStringToOString(
     108             :                 buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
     109             :         OSL_TRACE( "%s", cstr_msg.getStr() );
     110             :         }
     111             : #endif
     112             :         // signal exception
     113             :         jvalue java_exc;
     114             :         try
     115             :         {
     116             :             map_to_java(
     117             :                 jni, &java_exc, uno_exc->pData, uno_exc->pType, 0,
     118           0 :                 true /* in */, false /* no out */ );
     119             :         }
     120           0 :         catch (...)
     121             :         {
     122           0 :             uno_any_destruct( uno_exc, 0 );
     123           0 :             throw;
     124             :         }
     125           0 :         uno_any_destruct( uno_exc, 0 );
     126             : 
     127           0 :         JLocalAutoRef jo_exc( jni, java_exc.l );
     128           0 :         jint res = jni->Throw( (jthrowable) jo_exc.get() );
     129           0 :         if (0 != res)
     130             :         {
     131             :             // call toString()
     132             :             JLocalAutoRef jo_descr(
     133             :                 jni, jni->CallObjectMethodA(
     134           0 :                     jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) );
     135           0 :             jni.ensure_no_exception();
     136           0 :             OUStringBuffer buf( 128 );
     137           0 :             buf.append( "throwing java exception failed: " );
     138           0 :             buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
     139           0 :             buf.append( jni.get_stack_trace() );
     140           0 :             throw BridgeRuntimeError( buf.makeStringAndClear() );
     141           0 :         }
     142             :     }
     143             :     else
     144             :     {
     145             :         OUString message(
     146           0 :             "thrown exception is no uno exception: " +
     147           0 :             OUString::unacquired( &uno_exc->pType->pTypeName ) +
     148           0 :             jni.get_stack_trace() );
     149           0 :         uno_any_destruct( uno_exc, 0 );
     150           0 :         throw BridgeRuntimeError( message );
     151             :     }
     152           0 : }
     153             : 
     154             : union largest
     155             : {
     156             :     sal_Int64 n;
     157             :     double d;
     158             :     void * p;
     159             :     uno_Any a;
     160             : };
     161             : 
     162             : //______________________________________________________________________________
     163          14 : jobject Bridge::call_uno(
     164             :     JNI_context const & jni,
     165             :     uno_Interface * pUnoI, typelib_TypeDescription * member_td,
     166             :     typelib_TypeDescriptionReference * return_type,
     167             :     sal_Int32 nParams, typelib_MethodParameter const * pParams,
     168             :     jobjectArray jo_args /* may be 0 */ ) const
     169             : {
     170             :     // return mem
     171             :     sal_Int32 return_size;
     172          14 :     switch (return_type->eTypeClass) {
     173             :     case typelib_TypeClass_VOID:
     174           1 :         return_size = 0;
     175           1 :         break;
     176             : 
     177             :     case typelib_TypeClass_STRUCT:
     178             :     case typelib_TypeClass_EXCEPTION:
     179             :         return_size = std::max(
     180           0 :             TypeDescr(return_type).get()->nSize,
     181           0 :             static_cast< sal_Int32 >(sizeof (largest)));
     182           0 :         break;
     183             : 
     184             :     default:
     185          13 :         return_size = sizeof (largest);
     186          13 :         break;
     187             :     }
     188             : 
     189             : #ifdef BROKEN_ALLOCA
     190             :     char * mem = (char *) malloc(
     191             : #else
     192          14 :     char * mem = (char *) alloca(
     193             : #endif
     194             :         (nParams * sizeof (void *)) +
     195             :         return_size + (nParams * sizeof (largest)) );
     196          14 :     void ** uno_args = (void **) mem;
     197          14 :     void * uno_ret = return_size == 0 ? 0 : (mem + (nParams * sizeof (void *)));
     198             :     largest * uno_args_mem = (largest *)
     199          14 :         (mem + (nParams * sizeof (void *)) + return_size);
     200             : 
     201             :     OSL_ASSERT( (0 == nParams) || (nParams == jni->GetArrayLength( jo_args )) );
     202          23 :     for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
     203             :     {
     204           9 :         typelib_MethodParameter const & param = pParams[ nPos ];
     205           9 :         typelib_TypeDescriptionReference * type = param.pTypeRef;
     206             : 
     207           9 :         uno_args[ nPos ] = &uno_args_mem[ nPos ];
     208          18 :         if (typelib_TypeClass_STRUCT == type->eTypeClass ||
     209           9 :             typelib_TypeClass_EXCEPTION == type->eTypeClass)
     210             :         {
     211           0 :             TypeDescr td( type );
     212           0 :             if (sal::static_int_cast< sal_uInt32 >(td.get()->nSize)
     213             :                 > sizeof (largest))
     214             : #ifdef BROKEN_ALLOCA
     215             :                 uno_args[ nPos ] = malloc( td.get()->nSize );
     216             : #else
     217           0 :                 uno_args[ nPos ] = alloca( td.get()->nSize );
     218             : #endif
     219             :         }
     220             : 
     221           9 :         if (param.bIn)
     222             :         {
     223             :             try
     224             :             {
     225             :                 JLocalAutoRef jo_arg(
     226           9 :                     jni, jni->GetObjectArrayElement( jo_args, nPos ) );
     227           9 :                 jni.ensure_no_exception();
     228             :                 jvalue java_arg;
     229           9 :                 java_arg.l = jo_arg.get();
     230             :                 map_to_uno(
     231           9 :                     jni, uno_args[ nPos ], java_arg, type, 0,
     232             :                     false /* no assign */, sal_False != param.bOut,
     233          18 :                     true /* special wrapped integral types */ );
     234             :             }
     235           0 :             catch (...)
     236             :             {
     237             :                 // cleanup uno in args
     238           0 :                 for ( sal_Int32 n = 0; n < nPos; ++n )
     239             :                 {
     240           0 :                     typelib_MethodParameter const & p = pParams[ n ];
     241           0 :                     if (p.bIn)
     242             :                     {
     243             :                         uno_type_destructData(
     244           0 :                             uno_args[ n ], p.pTypeRef, 0 );
     245             :                     }
     246             : #ifdef BROKEN_ALLOCA
     247             :             if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
     248             :             free( uno_args[ nPos ] );
     249             : #endif
     250             :                 }
     251             : #ifdef BROKEN_ALLOCA
     252             :         free( mem );
     253             : #endif
     254           0 :                 throw;
     255             :             }
     256             :         }
     257             :     }
     258             : 
     259             :     uno_Any uno_exc_holder;
     260          14 :     uno_Any * uno_exc = &uno_exc_holder;
     261             :     // call binary uno
     262          14 :     (*pUnoI->pDispatcher)( pUnoI, member_td, uno_ret, uno_args, &uno_exc );
     263             : 
     264          14 :     if (0 == uno_exc)
     265             :     {
     266             :         // convert out args; destruct uno args
     267          23 :         for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
     268             :         {
     269           9 :             typelib_MethodParameter const & param = pParams[ nPos ];
     270           9 :             typelib_TypeDescriptionReference * type = param.pTypeRef;
     271           9 :             if (param.bOut)
     272             :             {
     273             :                 try
     274             :                 {
     275             :                     // get out holder array[ 1 ]
     276             :                     JLocalAutoRef jo_out_holder(
     277           0 :                         jni, jni->GetObjectArrayElement( jo_args, nPos ) );
     278           0 :                     jni.ensure_no_exception();
     279             :                     jvalue java_arg;
     280           0 :                     java_arg.l = jo_out_holder.get();
     281             :                     map_to_java(
     282           0 :                         jni, &java_arg, uno_args[ nPos ], type, 0,
     283           0 :                         true /* in */, true /* out holder */ );
     284             :                 }
     285           0 :                 catch (...)
     286             :                 {
     287             :                     // cleanup further uno args
     288           0 :                     for ( sal_Int32 n = nPos; n < nParams; ++n )
     289             :                     {
     290             :                         uno_type_destructData(
     291           0 :                             uno_args[ n ], pParams[ n ].pTypeRef, 0 );
     292             : #ifdef BROKEN_ALLOCA
     293             :             if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
     294             :                 free( uno_args[ nPos ] );
     295             : #endif
     296             :                     }
     297             :                     // cleanup uno return value
     298           0 :                     uno_type_destructData( uno_ret, return_type, 0 );
     299             : #ifdef BROKEN_ALLOCA
     300             :             free( mem );
     301             : #endif
     302           0 :                     throw;
     303             :                 }
     304             :             }
     305          18 :             if (typelib_TypeClass_DOUBLE < type->eTypeClass &&
     306           9 :                 typelib_TypeClass_ENUM != type->eTypeClass) // opt
     307             :             {
     308           9 :                 uno_type_destructData( uno_args[ nPos ], type, 0 );
     309             : #ifdef BROKEN_ALLOCA
     310             :         if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
     311             :             free( uno_args[ nPos ] );
     312             : #endif
     313             :             }
     314             :         }
     315             : 
     316          14 :         if (typelib_TypeClass_VOID != return_type->eTypeClass)
     317             :         {
     318             :             // convert uno return value
     319             :             jvalue java_ret;
     320             :             try
     321             :             {
     322             :                 map_to_java(
     323             :                     jni, &java_ret, uno_ret, return_type, 0,
     324             :                     true /* in */, false /* no out */,
     325          13 :                     true /* special_wrapped_integral_types */ );
     326             :             }
     327           0 :             catch (...)
     328             :             {
     329           0 :                 uno_type_destructData( uno_ret, return_type, 0 );
     330             : #ifdef BROKEN_ALLOCA
     331             :         free( mem );
     332             : #endif
     333           0 :                 throw;
     334             :             }
     335          26 :             if (typelib_TypeClass_DOUBLE < return_type->eTypeClass &&
     336          13 :                 typelib_TypeClass_ENUM != return_type->eTypeClass) // opt
     337             :             {
     338          13 :                 uno_type_destructData( uno_ret, return_type, 0 );
     339             :             }
     340             : #ifdef BROKEN_ALLOCA
     341             :         free( mem );
     342             : #endif
     343          13 :             return java_ret.l;
     344             :         }
     345             : #ifdef BROKEN_ALLOCA
     346             :     free( mem );
     347             : #endif
     348           1 :         return 0; // void return
     349             :     }
     350             :     else // exception occurred
     351             :     {
     352             :         // destruct uno in args
     353           0 :         for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
     354             :         {
     355           0 :             typelib_MethodParameter const & param = pParams[ nPos ];
     356           0 :             if (param.bIn)
     357           0 :                 uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 );
     358             : #ifdef BROKEN_ALLOCA
     359             :         if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
     360             :             free( uno_args[ nPos ] );
     361             : #endif
     362             :         }
     363             : 
     364           0 :         handle_uno_exc( jni, uno_exc );
     365             : #ifdef BROKEN_ALLOCA
     366             :     free( mem );
     367             : #endif
     368           0 :         return 0;
     369             :     }
     370             : }
     371             : 
     372             : }
     373             : 
     374             : using namespace ::jni_uno;
     375             : 
     376             : extern "C"
     377             : {
     378             : 
     379             : //------------------------------------------------------------------------------
     380             : SAL_JNI_EXPORT jobject
     381          19 : JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call(
     382             :     JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle, jstring jo_method,
     383             :     jobjectArray jo_args /* may be 0 */ )
     384             :     SAL_THROW_EXTERN_C()
     385             : {
     386          19 :     Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
     387          19 :     JNI_info const * jni_info = bridge->m_jni_info;
     388             :     JNI_context jni(
     389             :         jni_info, jni_env,
     390             :         static_cast< jobject >(
     391             :             reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
     392          19 :                 bridge->m_java_env->pContext )->getClassLoader() ) );
     393             : 
     394          19 :     OUString method_name;
     395             : 
     396             :     try
     397             :     {
     398          19 :         method_name = jstring_to_oustring( jni, jo_method );
     399             : #if OSL_DEBUG_LEVEL > 1
     400             :         {
     401             :         OUStringBuffer trace_buf( 64 );
     402             :         trace_buf.append( "java->uno call: " );
     403             :         trace_buf.append( method_name );
     404             :         trace_buf.append( " on oid " );
     405             :         JLocalAutoRef jo_oid(
     406             :             jni, jni->GetObjectField(
     407             :                 jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
     408             :         trace_buf.append( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
     409             :         OString cstr_msg(
     410             :             OUStringToOString(
     411             :                 trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
     412             :         OSL_TRACE( "%s", cstr_msg.getStr() );
     413             :         }
     414             : #endif
     415             : 
     416             :         // special IQueryInterface.queryInterface()
     417          19 :         if ( method_name == "queryInterface" )
     418             :         {
     419             :             // oid
     420             :             JLocalAutoRef jo_oid(
     421             :                 jni, jni->GetObjectField(
     422           5 :                     jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
     423             :             // type
     424             :             JLocalAutoRef jo_type(
     425          10 :                 jni, jni->GetObjectArrayElement( jo_args, 0 ) );
     426           5 :             jni.ensure_no_exception();
     427             : 
     428             :             JLocalAutoRef jo_type_name(
     429             :                 jni, jni->GetObjectField(
     430          10 :                     jo_type.get(), jni_info->m_field_Type__typeName ) );
     431           5 :             if (! jo_type_name.is())
     432             :             {
     433             :                 throw BridgeRuntimeError(
     434           0 :                     "incomplete type object: no type name!" +
     435           0 :                     jni.get_stack_trace() );
     436             :             }
     437             :             OUString type_name(
     438          10 :                 jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
     439             :             JNI_type_info const * info =
     440           5 :                 jni_info->get_type_info( jni, type_name );
     441           5 :             if (typelib_TypeClass_INTERFACE != info->m_td.get()->eTypeClass)
     442             :             {
     443             :                 throw BridgeRuntimeError(
     444           0 :                     "queryInterface() call demands an INTERFACE type!" );
     445             :             }
     446             :             JNI_interface_type_info const * iface_info =
     447           5 :                 static_cast< JNI_interface_type_info const * >( info );
     448             : 
     449             :             // getRegisteredInterface() already tested in JNI_proxy:
     450             :             // perform queryInterface call on binary uno interface
     451             :             uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
     452             :                 jni->GetLongField(
     453           5 :                     jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
     454             : 
     455             :             uno_Any uno_ret;
     456           5 :             void * uno_args[] = { &iface_info->m_td.get()->pWeakRef };
     457             :             uno_Any uno_exc_holder;
     458           5 :             uno_Any * uno_exc = &uno_exc_holder;
     459             :             // call binary uno
     460             :             (*pUnoI->pDispatcher)(
     461           5 :                 pUnoI, jni_info->m_XInterface_queryInterface_td.get(),
     462          10 :                 &uno_ret, uno_args, &uno_exc );
     463           5 :             if (0 == uno_exc)
     464             :             {
     465           5 :                 jobject jo_ret = 0;
     466           5 :                 if (typelib_TypeClass_INTERFACE == uno_ret.pType->eTypeClass)
     467             :                 {
     468             :                     uno_Interface * pUnoRet =
     469           5 :                         (uno_Interface *) uno_ret.pReserved;
     470           5 :                     if (0 != pUnoRet)
     471             :                     {
     472             :                         try
     473             :                         {
     474             :                             jo_ret =
     475           5 :                                 bridge->map_to_java( jni, pUnoRet, iface_info );
     476             :                         }
     477           0 :                         catch (...)
     478             :                         {
     479           0 :                             uno_any_destruct( &uno_ret, 0 );
     480           0 :                             throw;
     481             :                         }
     482             :                     }
     483             :                 }
     484           5 :                 uno_any_destruct( &uno_ret, 0 );
     485           5 :                 return jo_ret;
     486             :             }
     487             :             else
     488             :             {
     489           0 :                 bridge->handle_uno_exc( jni, uno_exc );
     490           0 :                 return 0;
     491           5 :             }
     492             :         }
     493             : 
     494             :         typelib_InterfaceTypeDescription * td =
     495             :             reinterpret_cast< typelib_InterfaceTypeDescription * >(
     496             :                 jni->GetLongField(
     497          14 :                     jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
     498             :         uno_Interface * pUnoI =
     499             :             reinterpret_cast< uno_Interface * >(
     500             :                 jni->GetLongField(
     501          14 :                     jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
     502             : 
     503          14 :         typelib_TypeDescriptionReference ** ppAllMembers = td->ppAllMembers;
     504          66 :         for ( sal_Int32 nPos = td->nAllMembers; nPos--; )
     505             :         {
     506             :             // try to avoid getting typedescription as long as possible,
     507             :             // because of a Mutex.acquire() in
     508             :             // typelib_typedescriptionreference_getDescription()
     509             :             typelib_TypeDescriptionReference * member_type =
     510          52 :                 ppAllMembers[ nPos ];
     511             : 
     512             :             // check method_name against fully qualified type_name
     513             :             // of member_type; type_name is of the form
     514             :             //  <name> "::" <method_name> *(":@" <idx> "," <idx> ":" <name>)
     515             :             OUString const & type_name =
     516          52 :                 OUString::unacquired( &member_type->pTypeName );
     517          52 :             sal_Int32 offset = type_name.indexOf( ':' ) + 2;
     518             :             OSL_ASSERT(
     519             :                 offset >= 2 && offset < type_name.getLength()
     520             :                 && type_name[offset - 1] == ':' );
     521          52 :             sal_Int32 remainder = type_name.getLength() - offset;
     522          52 :             if (typelib_TypeClass_INTERFACE_METHOD == member_type->eTypeClass)
     523             :             {
     524         104 :                 if ((method_name.getLength() == remainder
     525          35 :                      || (method_name.getLength() < remainder
     526          27 :                          && type_name[offset + method_name.getLength()] == ':'))
     527          70 :                     && type_name.match(method_name, offset))
     528             :                 {
     529          14 :                     TypeDescr member_td( member_type );
     530             :                     typelib_InterfaceMethodTypeDescription * method_td =
     531             :                         reinterpret_cast<
     532             :                           typelib_InterfaceMethodTypeDescription * >(
     533          14 :                               member_td.get() );
     534             :                     return bridge->call_uno(
     535             :                         jni, pUnoI, member_td.get(),
     536             :                         method_td->pReturnTypeRef,
     537             :                         method_td->nParams, method_td->pParams,
     538          14 :                         jo_args );
     539             :                 }
     540             :             }
     541             :             else // attribute
     542             :             {
     543             :                 OSL_ASSERT(
     544             :                     typelib_TypeClass_INTERFACE_ATTRIBUTE ==
     545             :                       member_type->eTypeClass );
     546             : 
     547           0 :                 if (method_name.getLength() >= 3
     548           0 :                     && (method_name.getLength() - 3 == remainder
     549           0 :                         || (method_name.getLength() - 3 < remainder
     550           0 :                             && type_name[
     551           0 :                                 offset + (method_name.getLength() - 3)] == ':'))
     552           0 :                     && method_name[1] == 'e' && method_name[2] == 't'
     553           0 :                     && rtl_ustr_compare_WithLength(
     554           0 :                         type_name.getStr() + offset,
     555           0 :                         method_name.getLength() - 3,
     556           0 :                         method_name.getStr() + 3,
     557           0 :                         method_name.getLength() - 3) == 0)
     558             :                 {
     559           0 :                     if ('g' == method_name[ 0 ])
     560             :                     {
     561           0 :                         TypeDescr member_td( member_type );
     562             :                         typelib_InterfaceAttributeTypeDescription * attr_td =
     563             :                             reinterpret_cast<
     564             :                               typelib_InterfaceAttributeTypeDescription * >(
     565           0 :                                   member_td.get() );
     566             :                         return bridge->call_uno(
     567             :                             jni, pUnoI, member_td.get(),
     568             :                             attr_td->pAttributeTypeRef,
     569             :                             0, 0,
     570           0 :                             jo_args );
     571             :                     }
     572           0 :                     else if ('s' == method_name[ 0 ])
     573             :                     {
     574           0 :                         TypeDescr member_td( member_type );
     575             :                         typelib_InterfaceAttributeTypeDescription * attr_td =
     576             :                             reinterpret_cast<
     577             :                               typelib_InterfaceAttributeTypeDescription * >(
     578           0 :                                   member_td.get() );
     579           0 :                         if (! attr_td->bReadOnly)
     580             :                         {
     581             :                             typelib_MethodParameter param;
     582           0 :                             param.pTypeRef = attr_td->pAttributeTypeRef;
     583           0 :                             param.bIn = sal_True;
     584           0 :                             param.bOut = sal_False;
     585             :                             return bridge->call_uno(
     586             :                                 jni, pUnoI, member_td.get(),
     587             :                                 jni_info->m_void_type.getTypeLibType(),
     588             :                                 1, &param,
     589           0 :                                 jo_args );
     590           0 :                         }
     591             :                     }
     592             :                 }
     593             :             }
     594             :         }
     595             :         // the thing that should not be... no method info found!
     596           0 :         OUStringBuffer buf( 64 );
     597           0 :         buf.append( "calling undeclared function on interface " );
     598             :         buf.append( OUString::unacquired(
     599           0 :                         &((typelib_TypeDescription *)td)->pTypeName ) );
     600           0 :         buf.append( ": " );
     601           0 :         buf.append( method_name );
     602           0 :         buf.append( jni.get_stack_trace() );
     603           0 :         throw BridgeRuntimeError( buf.makeStringAndClear() );
     604             :     }
     605           0 :     catch (const BridgeRuntimeError & err)
     606             :     {
     607           0 :         OUStringBuffer buf( 128 );
     608           0 :         buf.append( "[jni_uno bridge error] " "Java calling UNO method " );
     609           0 :         buf.append( method_name );
     610           0 :         buf.append( ": " );
     611           0 :         buf.append( err.m_message );
     612             :         // notify RuntimeException
     613             :         OString cstr_msg(
     614             :             OUStringToOString(
     615           0 :                 buf.makeStringAndClear(), RTL_TEXTENCODING_JAVA_UTF8 ) );
     616             :         OSL_FAIL( cstr_msg.getStr() );
     617           0 :         if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
     618             :             != 0)
     619             :         {
     620             :             OSL_ASSERT( false );
     621             :         }
     622           0 :         return 0;
     623             :     }
     624           0 :     catch (const ::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
     625             :     {
     626             :         OString cstr_msg(
     627             :             OString( "[jni_uno bridge error] "
     628           0 :                 "attaching current thread to java failed!" ) +
     629             :             OUStringToOString(
     630           0 :                 jni.get_stack_trace(), RTL_TEXTENCODING_JAVA_UTF8 ) );
     631             :         OSL_FAIL( cstr_msg.getStr() );
     632           0 :         if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
     633             :             != 0)
     634             :         {
     635             :             OSL_ASSERT( false );
     636             :         }
     637           0 :         return 0;
     638          19 :     }
     639             : }
     640             : 
     641             : //------------------------------------------------------------------------------
     642             : SAL_JNI_EXPORT void
     643          16 : JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J(
     644             :     JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle )
     645             :     SAL_THROW_EXTERN_C()
     646             : {
     647          16 :     Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
     648          16 :     JNI_info const * jni_info = bridge->m_jni_info;
     649             :     JNI_context jni(
     650             :         jni_info, jni_env,
     651             :         static_cast< jobject >(
     652             :             reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
     653          16 :                 bridge->m_java_env->pContext )->getClassLoader() ) );
     654             : 
     655             :     uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
     656             :         jni->GetLongField(
     657          16 :             jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
     658             :     typelib_TypeDescription * td =
     659             :         reinterpret_cast< typelib_TypeDescription * >(
     660             :             jni->GetLongField(
     661          16 :                 jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
     662             : 
     663             : #if OSL_DEBUG_LEVEL > 1
     664             :     {
     665             :     JLocalAutoRef jo_oid(
     666             :         jni, jni->GetObjectField(
     667             :             jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
     668             :     OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
     669             :     OString cstr_msg(
     670             :         OUStringToOString(
     671             :             "freeing java uno proxy: " + oid,
     672             :             RTL_TEXTENCODING_ASCII_US ) );
     673             :     OSL_TRACE( "%s", cstr_msg.getStr() );
     674             :     }
     675             : #endif
     676             :     // revoke from uno env; has already been revoked from java env
     677          16 :     (*bridge->m_uno_env->revokeInterface)( bridge->m_uno_env, pUnoI );
     678             :     // release receiver
     679          16 :     (*pUnoI->release)( pUnoI );
     680             :     // release typedescription handle
     681          16 :     typelib_typedescription_release( td );
     682             :     // release bridge handle
     683          16 :     bridge->release();
     684          16 : }
     685             : 
     686             : }
     687             : 
     688             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10