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