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

Generated by: LCOV version 1.10