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

Generated by: LCOV version 1.10