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