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

Generated by: LCOV version 1.11