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

Generated by: LCOV version 1.10