LCOV - code coverage report
Current view: top level - bridges/source/jni_uno - jni_uno2java.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 256 0.0 %
Date: 2014-04-14 Functions: 0 11 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             : #include <sal/config.h>
      21             : 
      22             : #include <cassert>
      23             : 
      24             : #include <o3tl/heap_ptr.hxx>
      25             : #include <sal/alloca.h>
      26             : 
      27             : #include "com/sun/star/uno/RuntimeException.hpp"
      28             : 
      29             : #include "rtl/ustrbuf.hxx"
      30             : 
      31             : #include "jni_bridge.h"
      32             : 
      33             : using namespace ::rtl;
      34             : 
      35             : namespace
      36             : {
      37             : extern "C"
      38             : {
      39             : 
      40             : 
      41             : void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
      42             :     SAL_THROW_EXTERN_C();
      43             : 
      44             : 
      45             : void SAL_CALL UNO_proxy_acquire( uno_Interface * pUnoI )
      46             :     SAL_THROW_EXTERN_C();
      47             : 
      48             : 
      49             : void SAL_CALL UNO_proxy_release( uno_Interface * pUnoI )
      50             :     SAL_THROW_EXTERN_C();
      51             : 
      52             : 
      53             : void SAL_CALL UNO_proxy_dispatch(
      54             :     uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
      55             :     void * uno_ret, void * uno_args[], uno_Any ** uno_exc )
      56             :     SAL_THROW_EXTERN_C();
      57             : }
      58             : }
      59             : 
      60             : namespace jni_uno
      61             : {
      62             : 
      63             : 
      64           0 : void Bridge::handle_java_exc(
      65             :     JNI_context const & jni,
      66             :     JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) const
      67             : {
      68             :     assert( jo_exc.is() );
      69           0 :     if (! jo_exc.is())
      70             :     {
      71             :         throw BridgeRuntimeError(
      72           0 :             "java exception occurred, but no java exception available!?" +
      73           0 :             jni.get_stack_trace() );
      74             :     }
      75             : 
      76           0 :     JLocalAutoRef jo_class( jni, jni->GetObjectClass( jo_exc.get() ) );
      77             :     JLocalAutoRef jo_class_name(
      78             :         jni, jni->CallObjectMethodA(
      79           0 :             jo_class.get(), m_jni_info->m_method_Class_getName, 0 ) );
      80           0 :     jni.ensure_no_exception();
      81             :     OUString exc_name(
      82           0 :         jstring_to_oustring( jni, (jstring) jo_class_name.get() ) );
      83             : 
      84           0 :     ::com::sun::star::uno::TypeDescription td( exc_name.pData );
      85           0 :     if (!td.is() || (typelib_TypeClass_EXCEPTION != td.get()->eTypeClass))
      86             :     {
      87             :         // call toString()
      88             :         JLocalAutoRef jo_descr(
      89             :             jni, jni->CallObjectMethodA(
      90           0 :                 jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) );
      91           0 :         jni.ensure_no_exception();
      92             :         throw BridgeRuntimeError(
      93             :             "non-UNO exception occurred: "
      94           0 :             + jstring_to_oustring( jni, (jstring) jo_descr.get() )
      95           0 :             + jni.get_stack_trace( jo_exc.get() ) );
      96             :     }
      97             : 
      98           0 :     o3tl::heap_ptr< rtl_mem > uno_data( rtl_mem::allocate( td.get()->nSize ) );
      99             :     jvalue val;
     100           0 :     val.l = jo_exc.get();
     101             :     map_to_uno(
     102           0 :         jni, uno_data.get(), val, td.get()->pWeakRef, 0,
     103           0 :         false /* no assign */, false /* no out param */ );
     104             : 
     105             : #if OSL_DEBUG_LEVEL > 0
     106             :     // patch Message, append stack trace
     107             :     reinterpret_cast< ::com::sun::star::uno::Exception * >(
     108             :         uno_data.get() )->Message += jni.get_stack_trace( jo_exc.get() );
     109             : #endif
     110             : 
     111           0 :     typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
     112           0 :     uno_exc->pType = td.get()->pWeakRef;
     113           0 :     uno_exc->pData = uno_data.release();
     114             : 
     115             :     SAL_INFO(
     116             :         "bridges",
     117             :         "exception occurred uno->java: [" << exc_name << "] "
     118             :         << (reinterpret_cast<css::uno::Exception const *>(uno_exc->pData)
     119           0 :             ->Message));
     120           0 : }
     121             : 
     122             : 
     123           0 : void Bridge::call_java(
     124             :     jobject javaI, typelib_InterfaceTypeDescription * iface_td,
     125             :     sal_Int32 local_member_index, sal_Int32 function_pos_offset,
     126             :     typelib_TypeDescriptionReference * return_type,
     127             :     typelib_MethodParameter * params, sal_Int32 nParams,
     128             :     void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const
     129             : {
     130             :     assert( function_pos_offset == 0 || function_pos_offset == 1 );
     131             : 
     132             :     JNI_guarded_context jni(
     133             :         m_jni_info, reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
     134           0 :             m_java_env->pContext ) );
     135             : 
     136             :     // assure fully initialized iface_td:
     137           0 :     ::com::sun::star::uno::TypeDescription iface_holder;
     138           0 :     if (! iface_td->aBase.bComplete) {
     139           0 :         iface_holder = ::com::sun::star::uno::TypeDescription(
     140           0 :             reinterpret_cast<typelib_TypeDescription *>(iface_td) );
     141           0 :         iface_holder.makeComplete();
     142           0 :         if (! iface_holder.get()->bComplete) {
     143             :             throw BridgeRuntimeError(
     144             :                 "cannot make type complete: "
     145           0 :                 + OUString::unacquired(&iface_holder.get()->pTypeName)
     146           0 :                 + jni.get_stack_trace() );
     147             :         }
     148             :         iface_td = reinterpret_cast<typelib_InterfaceTypeDescription *>(
     149           0 :             iface_holder.get() );
     150             :         assert( iface_td->aBase.eTypeClass == typelib_TypeClass_INTERFACE );
     151             :     }
     152             : 
     153             :     // prepare java args, save param td
     154             : #ifdef BROKEN_ALLOCA
     155             :     jvalue * java_args = (jvalue *) malloc( sizeof (jvalue) * nParams );
     156             : #else
     157           0 :     jvalue * java_args = (jvalue *) alloca( sizeof (jvalue) * nParams );
     158             : #endif
     159             : 
     160             :     sal_Int32 nPos;
     161           0 :     for ( nPos = 0; nPos < nParams; ++nPos )
     162             :     {
     163             :         try
     164             :         {
     165           0 :             typelib_MethodParameter const & param = params[ nPos ];
     166           0 :             java_args[ nPos ].l = 0; // if out: build up array[ 1 ]
     167             :             map_to_java(
     168             :                 jni, &java_args[ nPos ],
     169           0 :                 uno_args[ nPos ],
     170             :                 param.pTypeRef, 0,
     171             :                 sal_False != param.bIn /* convert uno value */,
     172           0 :                 sal_False != param.bOut /* build up array[ 1 ] */ );
     173             :         }
     174           0 :         catch (...)
     175             :         {
     176             :             // cleanup
     177           0 :             for ( sal_Int32 n = 0; n < nPos; ++n )
     178             :             {
     179           0 :                 typelib_MethodParameter const & param = params[ n ];
     180           0 :                 if (param.bOut ||
     181           0 :                     typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
     182             :                 {
     183           0 :                     jni->DeleteLocalRef( java_args[ n ].l );
     184             :                 }
     185             :             }
     186             : #ifdef BROKEN_ALLOCA
     187             :         free( java_args );
     188             : #endif
     189           0 :             throw;
     190             :         }
     191             :     }
     192             : 
     193           0 :     sal_Int32 base_members = iface_td->nAllMembers - iface_td->nMembers;
     194             :     assert( base_members < iface_td->nAllMembers );
     195             :     sal_Int32 base_members_function_pos =
     196           0 :         iface_td->pMapMemberIndexToFunctionIndex[ base_members ];
     197           0 :     sal_Int32 member_pos = base_members + local_member_index;
     198             :     SAL_WARN_IF(
     199             :         member_pos >= iface_td->nAllMembers, "bridges",
     200             :         "member pos out of range");
     201             :     sal_Int32 function_pos =
     202           0 :         iface_td->pMapMemberIndexToFunctionIndex[ member_pos ]
     203           0 :         + function_pos_offset;
     204             :     SAL_WARN_IF(
     205             :         (function_pos < base_members_function_pos
     206             :          || function_pos >= iface_td->nMapFunctionIndexToMemberIndex),
     207             :         "bridges", "illegal function index");
     208           0 :     function_pos -= base_members_function_pos;
     209             : 
     210             :     JNI_interface_type_info const * info =
     211             :         static_cast< JNI_interface_type_info const * >(
     212           0 :             m_jni_info->get_type_info( jni, &iface_td->aBase ) );
     213           0 :     jmethodID method_id = info->m_methods[ function_pos ];
     214             : 
     215             : #if OSL_DEBUG_LEVEL > 0
     216             :     OUStringBuffer trace_buf( 128 );
     217             :     trace_buf.append( "calling " );
     218             :     JLocalAutoRef jo_method(
     219             :         jni, jni->ToReflectedMethod( info->m_class, method_id, JNI_FALSE ) );
     220             :     jni.ensure_no_exception();
     221             :     JLocalAutoRef jo_descr(
     222             :         jni, jni->CallObjectMethodA(
     223             :             jo_method.get(), m_jni_info->m_method_Object_toString, 0 ) );
     224             :     jni.ensure_no_exception();
     225             :     trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
     226             :     trace_buf.append( " on " );
     227             :     jo_descr.reset(
     228             :         jni->CallObjectMethodA(
     229             :             javaI, m_jni_info->m_method_Object_toString, 0 ) );
     230             :     jni.ensure_no_exception();
     231             :     trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
     232             :     trace_buf.append( " (" );
     233             :     JLocalAutoRef jo_class( jni, jni->GetObjectClass( javaI ) );
     234             :     jo_descr.reset(
     235             :         jni->CallObjectMethodA(
     236             :             jo_class.get(), m_jni_info->m_method_Object_toString, 0 ) );
     237             :     jni.ensure_no_exception();
     238             :     trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
     239             :     trace_buf.append( ")" );
     240             :     SAL_INFO("bridges", trace_buf.makeStringAndClear());
     241             : #endif
     242             : 
     243             :     // complex return value
     244           0 :     JLocalAutoRef java_ret( jni );
     245             : 
     246           0 :     switch (return_type->eTypeClass)
     247             :     {
     248             :     case typelib_TypeClass_VOID:
     249           0 :         jni->CallVoidMethodA( javaI, method_id, java_args );
     250           0 :         break;
     251             :     case typelib_TypeClass_CHAR:
     252             :         *(sal_Unicode *)uno_ret =
     253           0 :             jni->CallCharMethodA( javaI, method_id, java_args );
     254           0 :         break;
     255             :     case typelib_TypeClass_BOOLEAN:
     256             :         *(sal_Bool *)uno_ret =
     257           0 :             jni->CallBooleanMethodA( javaI, method_id, java_args );
     258           0 :         break;
     259             :     case typelib_TypeClass_BYTE:
     260             :         *(sal_Int8 *)uno_ret =
     261           0 :             jni->CallByteMethodA( javaI, method_id, java_args );
     262           0 :         break;
     263             :     case typelib_TypeClass_SHORT:
     264             :     case typelib_TypeClass_UNSIGNED_SHORT:
     265             :         *(sal_Int16 *)uno_ret =
     266           0 :             jni->CallShortMethodA( javaI, method_id, java_args );
     267           0 :         break;
     268             :     case typelib_TypeClass_LONG:
     269             :     case typelib_TypeClass_UNSIGNED_LONG:
     270             :         *(sal_Int32 *)uno_ret =
     271           0 :             jni->CallIntMethodA( javaI, method_id, java_args );
     272           0 :         break;
     273             :     case typelib_TypeClass_HYPER:
     274             :     case typelib_TypeClass_UNSIGNED_HYPER:
     275             :         *(sal_Int64 *)uno_ret =
     276           0 :             jni->CallLongMethodA( javaI, method_id, java_args );
     277           0 :         break;
     278             :     case typelib_TypeClass_FLOAT:
     279             :         *(float *)uno_ret =
     280           0 :             jni->CallFloatMethodA( javaI, method_id, java_args );
     281           0 :         break;
     282             :     case typelib_TypeClass_DOUBLE:
     283             :         *(double *)uno_ret =
     284           0 :             jni->CallDoubleMethodA( javaI, method_id, java_args );
     285           0 :         break;
     286             :     default:
     287             :         java_ret.reset(
     288           0 :             jni->CallObjectMethodA( javaI, method_id, java_args ) );
     289           0 :         break;
     290             :     }
     291             : 
     292           0 :     if (jni->ExceptionCheck())
     293             :     {
     294           0 :         JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
     295           0 :         jni->ExceptionClear();
     296             : 
     297             :         // release temp java local refs
     298           0 :         for ( nPos = 0; nPos < nParams; ++nPos )
     299             :         {
     300           0 :             typelib_MethodParameter const & param = params[ nPos ];
     301           0 :             if (param.bOut ||
     302           0 :                 typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
     303             :             {
     304           0 :                 jni->DeleteLocalRef( java_args[ nPos ].l );
     305             :             }
     306             :         }
     307             : 
     308           0 :         handle_java_exc( jni, jo_exc, *uno_exc );
     309             :     }
     310             :     else // no exception
     311             :     {
     312           0 :         for ( nPos = 0; nPos < nParams; ++nPos )
     313             :         {
     314           0 :             typelib_MethodParameter const & param = params[ nPos ];
     315           0 :             if (param.bOut)
     316             :             {
     317             :                 try
     318             :                 {
     319             :                     map_to_uno(
     320           0 :                         jni, uno_args[ nPos ],
     321             :                         java_args[ nPos ], param.pTypeRef, 0,
     322             :                         sal_False != param.bIn /* assign if inout */,
     323           0 :                         true /* out param */ );
     324             :                 }
     325           0 :                 catch (...)
     326             :                 {
     327             :                     // cleanup uno pure out
     328           0 :                     for ( sal_Int32 n = 0; n < nPos; ++n )
     329             :                     {
     330           0 :                         typelib_MethodParameter const & p = params[ n ];
     331           0 :                         if (! p.bIn)
     332             :                         {
     333             :                             uno_type_destructData(
     334           0 :                                 uno_args[ n ], p.pTypeRef, 0 );
     335             :                         }
     336             :                     }
     337             :                     // cleanup java temp local refs
     338           0 :                     for ( ; nPos < nParams; ++nPos )
     339             :                     {
     340           0 :                         typelib_MethodParameter const & p = params[ nPos ];
     341           0 :                         if (p.bOut ||
     342           0 :                             typelib_TypeClass_DOUBLE <
     343             :                               p.pTypeRef->eTypeClass)
     344             :                         {
     345           0 :                             jni->DeleteLocalRef( java_args[ nPos ].l );
     346             :                         }
     347             :                     }
     348             : #ifdef BROKEN_ALLOCA
     349             :             free( java_args );
     350             : #endif
     351           0 :                     throw;
     352             :                 }
     353           0 :                 jni->DeleteLocalRef( java_args[ nPos ].l );
     354             :             }
     355             :             else // pure temp in param
     356             :             {
     357           0 :                 if (typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
     358           0 :                     jni->DeleteLocalRef( java_args[ nPos ].l );
     359             :             }
     360             :         }
     361             : 
     362             :         // return value
     363           0 :         if (typelib_TypeClass_DOUBLE < return_type->eTypeClass)
     364             :         {
     365             :             try
     366             :             {
     367             :                 jvalue val;
     368           0 :                 val.l = java_ret.get();
     369             :                 map_to_uno(
     370             :                     jni, uno_ret, val, return_type, 0,
     371           0 :                     false /* no assign */, false /* no out param */ );
     372             :             }
     373           0 :             catch (...)
     374             :             {
     375             :                 // cleanup uno pure out
     376           0 :                 for ( sal_Int32 i = 0; i < nParams; ++i )
     377             :                 {
     378           0 :                     typelib_MethodParameter const & param = params[ i ];
     379           0 :                     if (! param.bIn)
     380             :                     {
     381             :                         uno_type_destructData(
     382           0 :                             uno_args[ i ], param.pTypeRef, 0 );
     383             :                     }
     384             :                 }
     385             : #ifdef BROKEN_ALLOCA
     386             :         free( java_args );
     387             : #endif
     388           0 :                 throw;
     389             :             }
     390             :         } // else: already set integral uno return value
     391             : 
     392             :         // no exception occurred
     393           0 :         *uno_exc = 0;
     394           0 :     }
     395             : #ifdef BROKEN_ALLOCA
     396             :     free( java_args );
     397             : #endif
     398           0 : }
     399             : 
     400             : //==== a uno proxy wrapping a java interface ===================================
     401           0 : struct UNO_proxy : public uno_Interface
     402             : {
     403             :     mutable oslInterlockedCount         m_ref;
     404             :     Bridge const *                      m_bridge;
     405             : 
     406             :     // mapping information
     407             :     jobject                             m_javaI;
     408             :     jstring                             m_jo_oid;
     409             :     OUString                            m_oid;
     410             :     JNI_interface_type_info const *     m_type_info;
     411             : 
     412             :     inline void acquire() const;
     413             :     inline void release() const;
     414             : 
     415             :     // ctor
     416             :     inline UNO_proxy(
     417             :         JNI_context const & jni, Bridge const * bridge,
     418             :         jobject javaI, jstring jo_oid, OUString const & oid,
     419             :         JNI_interface_type_info const * info );
     420             : };
     421             : 
     422             : 
     423           0 : inline UNO_proxy::UNO_proxy(
     424             :     JNI_context const & jni, Bridge const * bridge,
     425             :     jobject javaI, jstring jo_oid, OUString const & oid,
     426             :     JNI_interface_type_info const * info )
     427             :     : m_ref( 1 ),
     428             :       m_oid( oid ),
     429           0 :       m_type_info( info )
     430             : {
     431           0 :     JNI_info const * jni_info = bridge->m_jni_info;
     432             :     JLocalAutoRef jo_string_array(
     433           0 :         jni, jni->NewObjectArray( 1, jni_info->m_class_String, jo_oid ) );
     434           0 :     jni.ensure_no_exception();
     435             :     jvalue args[ 3 ];
     436           0 :     args[ 0 ].l = javaI;
     437           0 :     args[ 1 ].l = jo_string_array.get();
     438           0 :     args[ 2 ].l = info->m_type;
     439             :     jobject jo_iface = jni->CallObjectMethodA(
     440             :         jni_info->m_object_java_env,
     441           0 :         jni_info->m_method_IEnvironment_registerInterface, args );
     442           0 :     jni.ensure_no_exception();
     443             : 
     444           0 :     m_javaI = jni->NewGlobalRef( jo_iface );
     445           0 :     m_jo_oid = (jstring) jni->NewGlobalRef( jo_oid );
     446           0 :     bridge->acquire();
     447           0 :     m_bridge = bridge;
     448             : 
     449             :     // uno_Interface
     450           0 :     uno_Interface::acquire = UNO_proxy_acquire;
     451           0 :     uno_Interface::release = UNO_proxy_release;
     452           0 :     uno_Interface::pDispatcher = UNO_proxy_dispatch;
     453           0 : }
     454             : 
     455             : 
     456           0 : inline void UNO_proxy::acquire() const
     457             : {
     458           0 :     if (1 == osl_atomic_increment( &m_ref ))
     459             :     {
     460             :         // rebirth of proxy zombie
     461           0 :         void * that = const_cast< UNO_proxy * >( this );
     462             :         // register at uno env
     463             :         (*m_bridge->m_uno_env->registerProxyInterface)(
     464             :             m_bridge->m_uno_env, &that,
     465             :             UNO_proxy_free, m_oid.pData,
     466           0 :             (typelib_InterfaceTypeDescription *)m_type_info->m_td.get() );
     467             :         assert( this == (void const * const)that );
     468             :     }
     469           0 : }
     470             : 
     471             : 
     472           0 : inline void UNO_proxy::release() const
     473             : {
     474           0 :     if (0 == osl_atomic_decrement( &m_ref ))
     475             :     {
     476             :         // revoke from uno env on last release
     477             :         (*m_bridge->m_uno_env->revokeInterface)(
     478           0 :             m_bridge->m_uno_env, const_cast< UNO_proxy * >( this ) );
     479             :     }
     480           0 : }
     481             : 
     482             : 
     483             : 
     484           0 : uno_Interface * Bridge::map_to_uno(
     485             :     JNI_context const & jni,
     486             :     jobject javaI, JNI_interface_type_info const * info ) const
     487             : {
     488           0 :     JLocalAutoRef jo_oid( jni, compute_oid( jni, javaI ) );
     489           0 :     OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
     490             : 
     491           0 :     uno_Interface * pUnoI = 0;
     492             :     (*m_uno_env->getRegisteredInterface)(
     493             :         m_uno_env, (void **)&pUnoI,
     494           0 :         oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
     495             : 
     496           0 :     if (0 == pUnoI) // no existing interface, register new proxy
     497             :     {
     498             :         // refcount initially 1
     499             :         pUnoI = new UNO_proxy(
     500             :             jni, const_cast< Bridge * >( this ),
     501           0 :             javaI, (jstring) jo_oid.get(), oid, info );
     502             : 
     503             :         (*m_uno_env->registerProxyInterface)(
     504             :             m_uno_env, (void **)&pUnoI,
     505             :             UNO_proxy_free,
     506           0 :             oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
     507             :     }
     508           0 :     return pUnoI;
     509             : }
     510             : 
     511             : }
     512             : 
     513             : using namespace ::jni_uno;
     514             : 
     515             : namespace
     516             : {
     517             : extern "C"
     518             : {
     519             : 
     520             : 
     521           0 : void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
     522             :     SAL_THROW_EXTERN_C()
     523             : {
     524           0 :     UNO_proxy const * that = reinterpret_cast< UNO_proxy const * >( proxy );
     525           0 :     Bridge const * bridge = that->m_bridge;
     526             : 
     527             :     assert(env == bridge->m_uno_env); (void) env;
     528             :     SAL_INFO("bridges", "freeing binary uno proxy: " << that->m_oid);
     529             : 
     530             :     try
     531             :     {
     532             :         JNI_guarded_context jni(
     533             :             bridge->m_jni_info,
     534             :             reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
     535           0 :                 bridge->m_java_env->pContext ) );
     536             : 
     537           0 :         jni->DeleteGlobalRef( that->m_javaI );
     538           0 :         jni->DeleteGlobalRef( that->m_jo_oid );
     539             :     }
     540           0 :     catch (BridgeRuntimeError & err)
     541             :     {
     542             :         SAL_WARN(
     543             :             "bridges",
     544             :             "ignoring BridgeRuntimeError \"" << err.m_message << "\"");
     545             :     }
     546           0 :     catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
     547             :     {
     548             :         SAL_WARN("bridges", "attaching current thread to java failed");
     549             :     }
     550             : 
     551           0 :     bridge->release();
     552             : #if OSL_DEBUG_LEVEL > 0
     553             :     *(int *)that = 0xdeadcafe;
     554             : #endif
     555           0 :     delete that;
     556           0 : }
     557             : 
     558             : 
     559           0 : void SAL_CALL UNO_proxy_acquire( uno_Interface * pUnoI )
     560             :     SAL_THROW_EXTERN_C()
     561             : {
     562           0 :     UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
     563           0 :     that->acquire();
     564           0 : }
     565             : 
     566             : 
     567           0 : void SAL_CALL UNO_proxy_release( uno_Interface * pUnoI )
     568             :     SAL_THROW_EXTERN_C()
     569             : {
     570           0 :     UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
     571           0 :     that->release();
     572           0 : }
     573             : 
     574             : 
     575           0 : void SAL_CALL UNO_proxy_dispatch(
     576             :     uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
     577             :     void * uno_ret, void * uno_args [], uno_Any ** uno_exc )
     578             :     SAL_THROW_EXTERN_C()
     579             : {
     580           0 :     UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
     581           0 :     Bridge const * bridge = that->m_bridge;
     582             : 
     583             :     SAL_INFO(
     584             :         "bridges",
     585             :         "uno->java call: " << OUString::unacquired(&member_td->pTypeName)
     586             :             << " on oid " << that->m_oid);
     587             : 
     588             :     try
     589             :     {
     590           0 :         switch (member_td->eTypeClass)
     591             :         {
     592             :         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
     593             :         {
     594             :             typelib_InterfaceAttributeTypeDescription const * attrib_td =
     595             :                 reinterpret_cast<
     596             :                 typelib_InterfaceAttributeTypeDescription const * >(
     597           0 :                     member_td );
     598           0 :             com::sun::star::uno::TypeDescription attrib_holder;
     599           0 :             while ( attrib_td->pBaseRef != 0 ) {
     600           0 :                 attrib_holder = com::sun::star::uno::TypeDescription(
     601           0 :                     attrib_td->pBaseRef );
     602             :                 assert(
     603             :                     attrib_holder.get()->eTypeClass
     604             :                     == typelib_TypeClass_INTERFACE_ATTRIBUTE );
     605             :                 attrib_td = reinterpret_cast<
     606             :                     typelib_InterfaceAttributeTypeDescription * >(
     607           0 :                         attrib_holder.get() );
     608             :             }
     609           0 :             typelib_InterfaceTypeDescription * iface_td = attrib_td->pInterface;
     610             : 
     611           0 :             if (0 == uno_ret) // is setter method
     612             :             {
     613             :                 typelib_MethodParameter param;
     614           0 :                 param.pTypeRef = attrib_td->pAttributeTypeRef;
     615           0 :                 param.bIn = sal_True;
     616           0 :                 param.bOut = sal_False;
     617             : 
     618             :                 bridge->call_java(
     619             :                     that->m_javaI, iface_td,
     620             :                     attrib_td->nIndex, 1, // get, then set method
     621             :                     bridge->m_jni_info->m_void_type.getTypeLibType(),
     622             :                     &param, 1,
     623           0 :                     0, uno_args, uno_exc );
     624             :             }
     625             :             else // is getter method
     626             :             {
     627             :                 bridge->call_java(
     628             :                     that->m_javaI, iface_td, attrib_td->nIndex, 0,
     629             :                     attrib_td->pAttributeTypeRef,
     630             :                     0, 0, // no params
     631           0 :                     uno_ret, 0, uno_exc );
     632             :             }
     633           0 :             break;
     634             :         }
     635             :         case typelib_TypeClass_INTERFACE_METHOD:
     636             :         {
     637             :             typelib_InterfaceMethodTypeDescription const * method_td =
     638             :                 reinterpret_cast<
     639             :                 typelib_InterfaceMethodTypeDescription const * >(
     640           0 :                     member_td );
     641           0 :             com::sun::star::uno::TypeDescription method_holder;
     642           0 :             while ( method_td->pBaseRef != 0 ) {
     643           0 :                 method_holder = com::sun::star::uno::TypeDescription(
     644           0 :                     method_td->pBaseRef );
     645             :                 assert(
     646             :                     method_holder.get()->eTypeClass
     647             :                     == typelib_TypeClass_INTERFACE_METHOD );
     648             :                 method_td = reinterpret_cast<
     649             :                     typelib_InterfaceMethodTypeDescription * >(
     650           0 :                         method_holder.get() );
     651             :             }
     652           0 :             typelib_InterfaceTypeDescription * iface_td = method_td->pInterface;
     653             : 
     654           0 :             switch ( method_td->aBase.nPosition )
     655             :             {
     656             :             case 0: // queryInterface()
     657             :             {
     658             :                 TypeDescr demanded_td(
     659             :                     *reinterpret_cast< typelib_TypeDescriptionReference ** >(
     660           0 :                         uno_args[ 0 ] ) );
     661           0 :                 if (typelib_TypeClass_INTERFACE !=
     662           0 :                       demanded_td.get()->eTypeClass)
     663             :                 {
     664             :                     throw BridgeRuntimeError(
     665           0 :                         "queryInterface() call demands an INTERFACE type!" );
     666             :                 }
     667             : 
     668           0 :                 uno_Interface * pInterface = 0;
     669             :                 (*bridge->m_uno_env->getRegisteredInterface)(
     670             :                     bridge->m_uno_env,
     671             :                     (void **) &pInterface, that->m_oid.pData,
     672           0 :                     (typelib_InterfaceTypeDescription *)demanded_td.get() );
     673             : 
     674           0 :                 if (0 == pInterface)
     675             :                 {
     676           0 :                     JNI_info const * jni_info = bridge->m_jni_info;
     677             :                     JNI_guarded_context jni(
     678             :                         jni_info,
     679             :                         reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
     680           0 :                             bridge->m_java_env->pContext ) );
     681             : 
     682             :                     JNI_interface_type_info const * info =
     683             :                         static_cast< JNI_interface_type_info const * >(
     684           0 :                             jni_info->get_type_info( jni, demanded_td.get() ) );
     685             : 
     686             :                     jvalue args[ 2 ];
     687           0 :                     args[ 0 ].l = info->m_type;
     688           0 :                     args[ 1 ].l = that->m_javaI;
     689             : 
     690             :                     JLocalAutoRef jo_ret(
     691             :                         jni, jni->CallStaticObjectMethodA(
     692             :                             jni_info->m_class_UnoRuntime,
     693             :                             jni_info->m_method_UnoRuntime_queryInterface,
     694           0 :                             args ) );
     695             : 
     696           0 :                     if (jni->ExceptionCheck())
     697             :                     {
     698           0 :                         JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
     699           0 :                         jni->ExceptionClear();
     700           0 :                         bridge->handle_java_exc( jni, jo_exc, *uno_exc );
     701             :                     }
     702             :                     else
     703             :                     {
     704           0 :                         if (jo_ret.is())
     705             :                         {
     706             :                             SAL_WARN_IF(
     707             :                                 (jstring_to_oustring(
     708             :                                     jni,
     709             :                                     static_cast<jstring>(
     710             :                                         JLocalAutoRef(
     711             :                                             jni, compute_oid(jni, jo_ret.get()))
     712             :                                         .get()))
     713             :                                  != that->m_oid),
     714             :                                 "bridges", "different oids");
     715             :                             // refcount initially 1
     716             :                             uno_Interface * pUnoI2 = new UNO_proxy(
     717             :                                 jni, bridge, jo_ret.get(),
     718           0 :                                 that->m_jo_oid, that->m_oid, info );
     719             : 
     720             :                             (*bridge->m_uno_env->registerProxyInterface)(
     721             :                                 bridge->m_uno_env,
     722             :                                 (void **) &pUnoI2,
     723             :                                 UNO_proxy_free, that->m_oid.pData,
     724             :                                 reinterpret_cast<
     725             :                                   typelib_InterfaceTypeDescription * >(
     726           0 :                                       info->m_td.get() ) );
     727             : 
     728             :                             uno_any_construct(
     729             :                                 (uno_Any *)uno_ret, &pUnoI2,
     730           0 :                                 demanded_td.get(), 0 );
     731           0 :                             (*pUnoI2->release)( pUnoI2 );
     732             :                         }
     733             :                         else // object does not support demanded interface
     734             :                         {
     735             :                             uno_any_construct(
     736             :                                 reinterpret_cast< uno_Any * >( uno_ret ),
     737           0 :                                 0, 0, 0 );
     738             :                         }
     739             :                         // no exception occurred
     740           0 :                         *uno_exc = 0;
     741           0 :                     }
     742             :                 }
     743             :                 else
     744             :                 {
     745             :                     uno_any_construct(
     746             :                         reinterpret_cast< uno_Any * >( uno_ret ),
     747           0 :                         &pInterface, demanded_td.get(), 0 );
     748           0 :                     (*pInterface->release)( pInterface );
     749           0 :                     *uno_exc = 0;
     750             :                 }
     751           0 :                 break;
     752             :             }
     753             :             case 1: // acquire this proxy
     754           0 :                 that->acquire();
     755           0 :                 *uno_exc = 0;
     756           0 :                 break;
     757             :             case 2: // release this proxy
     758           0 :                 that->release();
     759           0 :                 *uno_exc = 0;
     760           0 :                 break;
     761             :             default: // arbitrary method call
     762             :                 bridge->call_java(
     763             :                     that->m_javaI, iface_td, method_td->nIndex, 0,
     764             :                     method_td->pReturnTypeRef,
     765             :                     method_td->pParams, method_td->nParams,
     766           0 :                     uno_ret, uno_args, uno_exc );
     767           0 :                 break;
     768             :             }
     769           0 :             break;
     770             :         }
     771             :         default:
     772             :         {
     773             :             throw BridgeRuntimeError(
     774           0 :                 "illegal member type description!" );
     775             :         }
     776             :         }
     777             :     }
     778           0 :     catch (BridgeRuntimeError & err)
     779             :     {
     780           0 :         OUStringBuffer buf( 128 );
     781           0 :         buf.append( "[jni_uno bridge error] UNO calling Java method " );
     782           0 :         if (typelib_TypeClass_INTERFACE_METHOD == member_td->eTypeClass ||
     783           0 :             typelib_TypeClass_INTERFACE_ATTRIBUTE == member_td->eTypeClass)
     784             :         {
     785             :             buf.append( OUString::unacquired(
     786             :                             &reinterpret_cast<
     787             :                             typelib_InterfaceMemberTypeDescription const * >(
     788           0 :                                 member_td )->pMemberName ) );
     789             :         }
     790           0 :         buf.append( ": " );
     791           0 :         buf.append( err.m_message );
     792             :         // binary identical struct
     793             :         ::com::sun::star::uno::RuntimeException exc(
     794             :             buf.makeStringAndClear(),
     795             :             ::com::sun::star::uno::Reference<
     796           0 :               ::com::sun::star::uno::XInterface >() );
     797           0 :         ::com::sun::star::uno::Type const & exc_type = ::getCppuType( &exc );
     798           0 :         uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 );
     799           0 :         SAL_INFO("bridges", exc.Message);
     800             :     }
     801           0 :     catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
     802             :     {
     803             :         // binary identical struct
     804             :         ::com::sun::star::uno::RuntimeException exc(
     805             :             "[jni_uno bridge error] attaching current thread to java failed!",
     806             :             ::com::sun::star::uno::Reference<
     807           0 :               ::com::sun::star::uno::XInterface >() );
     808           0 :         ::com::sun::star::uno::Type const & exc_type = ::getCppuType( &exc );
     809           0 :         uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 );
     810           0 :         SAL_WARN("bridges", exc.Message);
     811             :     }
     812           0 : }
     813             : 
     814             : }
     815             : }
     816             : 
     817             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10