1*61dff127SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*61dff127SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*61dff127SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*61dff127SAndrew Rist  * distributed with this work for additional information
6*61dff127SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*61dff127SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*61dff127SAndrew Rist  * "License"); you may not use this file except in compliance
9*61dff127SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*61dff127SAndrew Rist  *
11*61dff127SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*61dff127SAndrew Rist  *
13*61dff127SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*61dff127SAndrew Rist  * software distributed under the License is distributed on an
15*61dff127SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*61dff127SAndrew Rist  * KIND, either express or implied.  See the License for the
17*61dff127SAndrew Rist  * specific language governing permissions and limitations
18*61dff127SAndrew Rist  * under the License.
19*61dff127SAndrew Rist  *
20*61dff127SAndrew Rist  *************************************************************/
21*61dff127SAndrew Rist 
22*61dff127SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_bridges.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "jni_bridge.h"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "jvmaccess/unovirtualmachine.hxx"
30cdf0e10cSrcweir #include "rtl/ref.hxx"
31cdf0e10cSrcweir #include "rtl/unload.h"
32cdf0e10cSrcweir #include "rtl/strbuf.hxx"
33cdf0e10cSrcweir #include "uno/lbnames.h"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir 
36cdf0e10cSrcweir using namespace ::std;
37cdf0e10cSrcweir using namespace ::rtl;
38cdf0e10cSrcweir using namespace ::osl;
39cdf0e10cSrcweir using namespace ::jni_uno;
40cdf0e10cSrcweir 
41cdf0e10cSrcweir namespace
42cdf0e10cSrcweir {
43cdf0e10cSrcweir extern "C"
44cdf0e10cSrcweir {
45cdf0e10cSrcweir 
46cdf0e10cSrcweir //------------------------------------------------------------------------------
47cdf0e10cSrcweir void SAL_CALL Mapping_acquire( uno_Mapping * mapping )
48cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
49cdf0e10cSrcweir {
50cdf0e10cSrcweir     Mapping const * that = static_cast< Mapping const * >( mapping );
51cdf0e10cSrcweir     that->m_bridge->acquire();
52cdf0e10cSrcweir }
53cdf0e10cSrcweir 
54cdf0e10cSrcweir //------------------------------------------------------------------------------
55cdf0e10cSrcweir void SAL_CALL Mapping_release( uno_Mapping * mapping )
56cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
57cdf0e10cSrcweir {
58cdf0e10cSrcweir     Mapping const * that = static_cast< Mapping const * >( mapping );
59cdf0e10cSrcweir     that->m_bridge->release();
60cdf0e10cSrcweir }
61cdf0e10cSrcweir 
62cdf0e10cSrcweir //------------------------------------------------------------------------------
63cdf0e10cSrcweir void SAL_CALL Mapping_map_to_uno(
64cdf0e10cSrcweir     uno_Mapping * mapping, void ** ppOut,
65cdf0e10cSrcweir     void * pIn, typelib_InterfaceTypeDescription * td )
66cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
67cdf0e10cSrcweir {
68cdf0e10cSrcweir     uno_Interface ** ppUnoI = (uno_Interface **)ppOut;
69cdf0e10cSrcweir     jobject javaI = (jobject) pIn;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir     OSL_ASSERT( sizeof (void *) == sizeof (jobject) );
72cdf0e10cSrcweir 	OSL_ENSURE( ppUnoI && td, "### null ptr!" );
73cdf0e10cSrcweir 
74cdf0e10cSrcweir 	if (0 == javaI)
75cdf0e10cSrcweir     {
76cdf0e10cSrcweir         if (0 != *ppUnoI)
77cdf0e10cSrcweir         {
78cdf0e10cSrcweir             uno_Interface * p = *(uno_Interface **)ppUnoI;
79cdf0e10cSrcweir             (*p->release)( p );
80cdf0e10cSrcweir             *ppUnoI = 0;
81cdf0e10cSrcweir         }
82cdf0e10cSrcweir     }
83cdf0e10cSrcweir     else
84cdf0e10cSrcweir 	{
85cdf0e10cSrcweir         try
86cdf0e10cSrcweir         {
87cdf0e10cSrcweir             Bridge const * bridge =
88cdf0e10cSrcweir                 static_cast< Mapping const * >( mapping )->m_bridge;
89cdf0e10cSrcweir             JNI_guarded_context jni(
90cdf0e10cSrcweir                 bridge->m_jni_info,
91cdf0e10cSrcweir                 reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
92cdf0e10cSrcweir                     bridge->m_java_env->pContext ) );
93cdf0e10cSrcweir 
94cdf0e10cSrcweir             JNI_interface_type_info const * info =
95cdf0e10cSrcweir                 static_cast< JNI_interface_type_info const * >(
96cdf0e10cSrcweir                     bridge->m_jni_info->get_type_info(
97cdf0e10cSrcweir                         jni, (typelib_TypeDescription *)td ) );
98cdf0e10cSrcweir             uno_Interface * pUnoI = bridge->map_to_uno( jni, javaI, info );
99cdf0e10cSrcweir             if (0 != *ppUnoI)
100cdf0e10cSrcweir             {
101cdf0e10cSrcweir                 uno_Interface * p = *(uno_Interface **)ppUnoI;
102cdf0e10cSrcweir                 (*p->release)( p );
103cdf0e10cSrcweir             }
104cdf0e10cSrcweir             *ppUnoI = pUnoI;
105cdf0e10cSrcweir         }
106cdf0e10cSrcweir         catch (BridgeRuntimeError & err)
107cdf0e10cSrcweir         {
108cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
109cdf0e10cSrcweir             OString cstr_msg(
110cdf0e10cSrcweir                 OUStringToOString(
111cdf0e10cSrcweir                     OUSTR("[jni_uno bridge error] ") + err.m_message,
112cdf0e10cSrcweir                     RTL_TEXTENCODING_ASCII_US ) );
113cdf0e10cSrcweir             OSL_ENSURE( 0, cstr_msg.getStr() );
114cdf0e10cSrcweir #else
115cdf0e10cSrcweir             (void) err; // unused
116cdf0e10cSrcweir #endif
117cdf0e10cSrcweir         }
118cdf0e10cSrcweir         catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
119cdf0e10cSrcweir         {
120cdf0e10cSrcweir             OSL_ENSURE(
121cdf0e10cSrcweir                 0,
122cdf0e10cSrcweir                 "[jni_uno bridge error] attaching current thread "
123cdf0e10cSrcweir                 "to java failed!" );
124cdf0e10cSrcweir         }
125cdf0e10cSrcweir 	}
126cdf0e10cSrcweir }
127cdf0e10cSrcweir 
128cdf0e10cSrcweir //------------------------------------------------------------------------------
129cdf0e10cSrcweir void SAL_CALL Mapping_map_to_java(
130cdf0e10cSrcweir     uno_Mapping * mapping, void ** ppOut,
131cdf0e10cSrcweir     void * pIn, typelib_InterfaceTypeDescription * td )
132cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
133cdf0e10cSrcweir {
134cdf0e10cSrcweir     jobject * ppJavaI = (jobject *) ppOut;
135cdf0e10cSrcweir     uno_Interface * pUnoI = (uno_Interface *)pIn;
136cdf0e10cSrcweir 
137cdf0e10cSrcweir     OSL_ASSERT( sizeof (void *) == sizeof (jobject) );
138cdf0e10cSrcweir 	OSL_ENSURE( ppJavaI && td, "### null ptr!" );
139cdf0e10cSrcweir 
140cdf0e10cSrcweir     try
141cdf0e10cSrcweir     {
142cdf0e10cSrcweir         if (0 == pUnoI)
143cdf0e10cSrcweir         {
144cdf0e10cSrcweir             if (0 != *ppJavaI)
145cdf0e10cSrcweir             {
146cdf0e10cSrcweir                 Bridge const * bridge =
147cdf0e10cSrcweir                     static_cast< Mapping const * >( mapping )->m_bridge;
148cdf0e10cSrcweir                 JNI_guarded_context jni(
149cdf0e10cSrcweir                     bridge->m_jni_info,
150cdf0e10cSrcweir                     reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
151cdf0e10cSrcweir                         bridge->m_java_env->pContext ) );
152cdf0e10cSrcweir                 jni->DeleteGlobalRef( *ppJavaI );
153cdf0e10cSrcweir                 *ppJavaI = 0;
154cdf0e10cSrcweir             }
155cdf0e10cSrcweir         }
156cdf0e10cSrcweir         else
157cdf0e10cSrcweir         {
158cdf0e10cSrcweir             Bridge const * bridge =
159cdf0e10cSrcweir                 static_cast< Mapping const * >( mapping )->m_bridge;
160cdf0e10cSrcweir             JNI_guarded_context jni(
161cdf0e10cSrcweir                 bridge->m_jni_info,
162cdf0e10cSrcweir                 reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
163cdf0e10cSrcweir                     bridge->m_java_env->pContext ) );
164cdf0e10cSrcweir 
165cdf0e10cSrcweir             JNI_interface_type_info const * info =
166cdf0e10cSrcweir                 static_cast< JNI_interface_type_info const * >(
167cdf0e10cSrcweir                     bridge->m_jni_info->get_type_info(
168cdf0e10cSrcweir                         jni, (typelib_TypeDescription *)td ) );
169cdf0e10cSrcweir             jobject jlocal = bridge->map_to_java( jni, pUnoI, info );
170cdf0e10cSrcweir             if (0 != *ppJavaI)
171cdf0e10cSrcweir                 jni->DeleteGlobalRef( *ppJavaI );
172cdf0e10cSrcweir             *ppJavaI = jni->NewGlobalRef( jlocal );
173cdf0e10cSrcweir             jni->DeleteLocalRef( jlocal );
174cdf0e10cSrcweir         }
175cdf0e10cSrcweir     }
176cdf0e10cSrcweir     catch (BridgeRuntimeError & err)
177cdf0e10cSrcweir     {
178cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
179cdf0e10cSrcweir         OString cstr_msg(
180cdf0e10cSrcweir             OUStringToOString(
181cdf0e10cSrcweir                 OUSTR("[jni_uno bridge error] ") + err.m_message,
182cdf0e10cSrcweir                 RTL_TEXTENCODING_ASCII_US ) );
183cdf0e10cSrcweir         OSL_ENSURE( 0, cstr_msg.getStr() );
184cdf0e10cSrcweir #else
185cdf0e10cSrcweir             (void) err; // unused
186cdf0e10cSrcweir #endif
187cdf0e10cSrcweir     }
188cdf0e10cSrcweir     catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
189cdf0e10cSrcweir     {
190cdf0e10cSrcweir         OSL_ENSURE(
191cdf0e10cSrcweir             0,
192cdf0e10cSrcweir             "[jni_uno bridge error] attaching current thread to java failed!" );
193cdf0e10cSrcweir     }
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
196cdf0e10cSrcweir //______________________________________________________________________________
197cdf0e10cSrcweir void SAL_CALL Bridge_free( uno_Mapping * mapping )
198cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
199cdf0e10cSrcweir {
200cdf0e10cSrcweir     Mapping * that = static_cast< Mapping * >( mapping );
201cdf0e10cSrcweir     delete that->m_bridge;
202cdf0e10cSrcweir }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir }
205cdf0e10cSrcweir 
206cdf0e10cSrcweir rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
207cdf0e10cSrcweir 
208cdf0e10cSrcweir }
209cdf0e10cSrcweir 
210cdf0e10cSrcweir namespace jni_uno
211cdf0e10cSrcweir {
212cdf0e10cSrcweir 
213cdf0e10cSrcweir //______________________________________________________________________________
214cdf0e10cSrcweir void Bridge::acquire() const SAL_THROW( () )
215cdf0e10cSrcweir {
216cdf0e10cSrcweir     if (1 == osl_incrementInterlockedCount( &m_ref ))
217cdf0e10cSrcweir     {
218cdf0e10cSrcweir         if (m_registered_java2uno)
219cdf0e10cSrcweir         {
220cdf0e10cSrcweir             uno_Mapping * mapping = const_cast< Mapping * >( &m_java2uno );
221cdf0e10cSrcweir             uno_registerMapping(
222cdf0e10cSrcweir                 &mapping, Bridge_free,
223cdf0e10cSrcweir                 m_java_env, (uno_Environment *)m_uno_env, 0 );
224cdf0e10cSrcweir         }
225cdf0e10cSrcweir         else
226cdf0e10cSrcweir         {
227cdf0e10cSrcweir             uno_Mapping * mapping = const_cast< Mapping * >( &m_uno2java );
228cdf0e10cSrcweir             uno_registerMapping(
229cdf0e10cSrcweir                 &mapping, Bridge_free,
230cdf0e10cSrcweir                 (uno_Environment *)m_uno_env, m_java_env, 0 );
231cdf0e10cSrcweir         }
232cdf0e10cSrcweir     }
233cdf0e10cSrcweir }
234cdf0e10cSrcweir 
235cdf0e10cSrcweir //______________________________________________________________________________
236cdf0e10cSrcweir void Bridge::release() const SAL_THROW( () )
237cdf0e10cSrcweir {
238cdf0e10cSrcweir     if (! osl_decrementInterlockedCount( &m_ref ))
239cdf0e10cSrcweir     {
240cdf0e10cSrcweir         uno_revokeMapping(
241cdf0e10cSrcweir             m_registered_java2uno
242cdf0e10cSrcweir             ? const_cast< Mapping * >( &m_java2uno )
243cdf0e10cSrcweir             : const_cast< Mapping * >( &m_uno2java ) );
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir //______________________________________________________________________________
248cdf0e10cSrcweir Bridge::Bridge(
249cdf0e10cSrcweir     uno_Environment * java_env, uno_ExtEnvironment * uno_env,
250cdf0e10cSrcweir     bool registered_java2uno )
251cdf0e10cSrcweir     : m_ref( 1 ),
252cdf0e10cSrcweir       m_uno_env( uno_env ),
253cdf0e10cSrcweir       m_java_env( java_env ),
254cdf0e10cSrcweir       m_registered_java2uno( registered_java2uno )
255cdf0e10cSrcweir {
256cdf0e10cSrcweir     // bootstrapping bridge jni_info
257cdf0e10cSrcweir     m_jni_info = JNI_info::get_jni_info(
258cdf0e10cSrcweir         reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
259cdf0e10cSrcweir             m_java_env->pContext ) );
260cdf0e10cSrcweir 
261cdf0e10cSrcweir     OSL_ASSERT( 0 != m_java_env && 0 != m_uno_env );
262cdf0e10cSrcweir     (*((uno_Environment *)m_uno_env)->acquire)( (uno_Environment *)m_uno_env );
263cdf0e10cSrcweir     (*m_java_env->acquire)( m_java_env );
264cdf0e10cSrcweir 
265cdf0e10cSrcweir     // java2uno
266cdf0e10cSrcweir     m_java2uno.acquire = Mapping_acquire;
267cdf0e10cSrcweir     m_java2uno.release = Mapping_release;
268cdf0e10cSrcweir     m_java2uno.mapInterface = Mapping_map_to_uno;
269cdf0e10cSrcweir     m_java2uno.m_bridge = this;
270cdf0e10cSrcweir     // uno2java
271cdf0e10cSrcweir     m_uno2java.acquire = Mapping_acquire;
272cdf0e10cSrcweir     m_uno2java.release = Mapping_release;
273cdf0e10cSrcweir     m_uno2java.mapInterface = Mapping_map_to_java;
274cdf0e10cSrcweir     m_uno2java.m_bridge = this;
275cdf0e10cSrcweir 
276cdf0e10cSrcweir     (*g_moduleCount.modCnt.acquire)( &g_moduleCount.modCnt );
277cdf0e10cSrcweir }
278cdf0e10cSrcweir 
279cdf0e10cSrcweir //______________________________________________________________________________
280cdf0e10cSrcweir Bridge::~Bridge() SAL_THROW( () )
281cdf0e10cSrcweir {
282cdf0e10cSrcweir     (*m_java_env->release)( m_java_env );
283cdf0e10cSrcweir     (*((uno_Environment *)m_uno_env)->release)( (uno_Environment *)m_uno_env );
284cdf0e10cSrcweir 
285cdf0e10cSrcweir     (*g_moduleCount.modCnt.release)( &g_moduleCount.modCnt );
286cdf0e10cSrcweir }
287cdf0e10cSrcweir 
288cdf0e10cSrcweir 
289cdf0e10cSrcweir //______________________________________________________________________________
290cdf0e10cSrcweir void JNI_context::java_exc_occured() const
291cdf0e10cSrcweir {
292cdf0e10cSrcweir     // !don't rely on JNI_info!
293cdf0e10cSrcweir 
294cdf0e10cSrcweir     JLocalAutoRef jo_exc( *this, m_env->ExceptionOccurred() );
295cdf0e10cSrcweir     m_env->ExceptionClear();
296cdf0e10cSrcweir     OSL_ASSERT( jo_exc.is() );
297cdf0e10cSrcweir     if (! jo_exc.is())
298cdf0e10cSrcweir     {
299cdf0e10cSrcweir         throw BridgeRuntimeError(
300cdf0e10cSrcweir             OUSTR("java exception occured, but not available!?") +
301cdf0e10cSrcweir             get_stack_trace() );
302cdf0e10cSrcweir     }
303cdf0e10cSrcweir 
304cdf0e10cSrcweir     // call toString(); don't rely on m_jni_info
305cdf0e10cSrcweir     jclass jo_class = m_env->FindClass( "java/lang/Object" );
306cdf0e10cSrcweir     if (JNI_FALSE != m_env->ExceptionCheck())
307cdf0e10cSrcweir     {
308cdf0e10cSrcweir         m_env->ExceptionClear();
309cdf0e10cSrcweir         throw BridgeRuntimeError(
310cdf0e10cSrcweir             OUSTR("cannot get class java.lang.Object!") + get_stack_trace() );
311cdf0e10cSrcweir     }
312cdf0e10cSrcweir     JLocalAutoRef jo_Object( *this, jo_class );
313cdf0e10cSrcweir     // method Object.toString()
314cdf0e10cSrcweir     jmethodID method_Object_toString = m_env->GetMethodID(
315cdf0e10cSrcweir         (jclass) jo_Object.get(), "toString", "()Ljava/lang/String;" );
316cdf0e10cSrcweir     if (JNI_FALSE != m_env->ExceptionCheck())
317cdf0e10cSrcweir     {
318cdf0e10cSrcweir         m_env->ExceptionClear();
319cdf0e10cSrcweir         throw BridgeRuntimeError(
320cdf0e10cSrcweir             OUSTR("cannot get method id of java.lang.Object.toString()!") +
321cdf0e10cSrcweir             get_stack_trace() );
322cdf0e10cSrcweir     }
323cdf0e10cSrcweir     OSL_ASSERT( 0 != method_Object_toString );
324cdf0e10cSrcweir 
325cdf0e10cSrcweir     JLocalAutoRef jo_descr(
326cdf0e10cSrcweir         *this, m_env->CallObjectMethodA(
327cdf0e10cSrcweir             jo_exc.get(), method_Object_toString, 0 ) );
328cdf0e10cSrcweir     if (m_env->ExceptionCheck()) // no chance at all
329cdf0e10cSrcweir     {
330cdf0e10cSrcweir         m_env->ExceptionClear();
331cdf0e10cSrcweir         throw BridgeRuntimeError(
332cdf0e10cSrcweir             OUSTR("error examining java exception object!") +
333cdf0e10cSrcweir             get_stack_trace() );
334cdf0e10cSrcweir     }
335cdf0e10cSrcweir 
336cdf0e10cSrcweir     jsize len = m_env->GetStringLength( (jstring) jo_descr.get() );
337cdf0e10cSrcweir     auto_ptr< rtl_mem > ustr_mem(
338cdf0e10cSrcweir         rtl_mem::allocate(
339cdf0e10cSrcweir             sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) );
340cdf0e10cSrcweir     rtl_uString * ustr = (rtl_uString *)ustr_mem.get();
341cdf0e10cSrcweir     m_env->GetStringRegion( (jstring) jo_descr.get(), 0, len, ustr->buffer );
342cdf0e10cSrcweir     if (m_env->ExceptionCheck())
343cdf0e10cSrcweir     {
344cdf0e10cSrcweir         m_env->ExceptionClear();
345cdf0e10cSrcweir         throw BridgeRuntimeError(
346cdf0e10cSrcweir             OUSTR("invalid java string object!") + get_stack_trace() );
347cdf0e10cSrcweir     }
348cdf0e10cSrcweir     ustr->refCount = 1;
349cdf0e10cSrcweir     ustr->length = len;
350cdf0e10cSrcweir     ustr->buffer[ len ] = '\0';
351cdf0e10cSrcweir     OUString message( (rtl_uString *)ustr_mem.release(), SAL_NO_ACQUIRE );
352cdf0e10cSrcweir 
353cdf0e10cSrcweir     throw BridgeRuntimeError( message + get_stack_trace( jo_exc.get() ) );
354cdf0e10cSrcweir }
355cdf0e10cSrcweir 
356cdf0e10cSrcweir //______________________________________________________________________________
357cdf0e10cSrcweir void JNI_context::getClassForName(
358cdf0e10cSrcweir     jclass * classClass, jmethodID * methodForName) const
359cdf0e10cSrcweir {
360cdf0e10cSrcweir     jclass c = m_env->FindClass("java/lang/Class");
361cdf0e10cSrcweir     if (c != 0) {
362cdf0e10cSrcweir         *methodForName = m_env->GetStaticMethodID(
363cdf0e10cSrcweir             c, "forName",
364cdf0e10cSrcweir             "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
365cdf0e10cSrcweir     }
366cdf0e10cSrcweir     *classClass = c;
367cdf0e10cSrcweir }
368cdf0e10cSrcweir 
369cdf0e10cSrcweir //______________________________________________________________________________
370cdf0e10cSrcweir jclass JNI_context::findClass(
371cdf0e10cSrcweir     char const * name, jclass classClass, jmethodID methodForName,
372cdf0e10cSrcweir     bool inException) const
373cdf0e10cSrcweir {
374cdf0e10cSrcweir     jclass c = 0;
375cdf0e10cSrcweir     JLocalAutoRef s(*this, m_env->NewStringUTF(name));
376cdf0e10cSrcweir     if (s.is()) {
377cdf0e10cSrcweir         jvalue a[3];
378cdf0e10cSrcweir         a[0].l = s.get();
379cdf0e10cSrcweir         a[1].z = JNI_FALSE;
380cdf0e10cSrcweir         a[2].l = m_class_loader;
381cdf0e10cSrcweir         c = static_cast< jclass >(
382cdf0e10cSrcweir             m_env->CallStaticObjectMethodA(classClass, methodForName, a));
383cdf0e10cSrcweir     }
384cdf0e10cSrcweir     if (!inException) {
385cdf0e10cSrcweir         ensure_no_exception();
386cdf0e10cSrcweir     }
387cdf0e10cSrcweir     return c;
388cdf0e10cSrcweir }
389cdf0e10cSrcweir 
390cdf0e10cSrcweir //______________________________________________________________________________
391cdf0e10cSrcweir OUString JNI_context::get_stack_trace( jobject jo_exc ) const
392cdf0e10cSrcweir {
393cdf0e10cSrcweir     JLocalAutoRef jo_JNI_proxy(
394cdf0e10cSrcweir         *this,
395cdf0e10cSrcweir         find_class( *this, "com.sun.star.bridges.jni_uno.JNI_proxy", true ) );
396cdf0e10cSrcweir     if (assert_no_exception())
397cdf0e10cSrcweir     {
398cdf0e10cSrcweir         // static method JNI_proxy.get_stack_trace()
399cdf0e10cSrcweir         jmethodID method = m_env->GetStaticMethodID(
400cdf0e10cSrcweir             (jclass) jo_JNI_proxy.get(), "get_stack_trace",
401cdf0e10cSrcweir             "(Ljava/lang/Throwable;)Ljava/lang/String;" );
402cdf0e10cSrcweir         if (assert_no_exception() && (0 != method))
403cdf0e10cSrcweir         {
404cdf0e10cSrcweir             jvalue arg;
405cdf0e10cSrcweir             arg.l = jo_exc;
406cdf0e10cSrcweir             JLocalAutoRef jo_stack_trace(
407cdf0e10cSrcweir                 *this, m_env->CallStaticObjectMethodA(
408cdf0e10cSrcweir                     (jclass) jo_JNI_proxy.get(), method, &arg ) );
409cdf0e10cSrcweir             if (assert_no_exception())
410cdf0e10cSrcweir             {
411cdf0e10cSrcweir                 jsize len =
412cdf0e10cSrcweir                     m_env->GetStringLength( (jstring) jo_stack_trace.get() );
413cdf0e10cSrcweir                 auto_ptr< rtl_mem > ustr_mem(
414cdf0e10cSrcweir                     rtl_mem::allocate(
415cdf0e10cSrcweir                         sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) );
416cdf0e10cSrcweir                 rtl_uString * ustr = (rtl_uString *)ustr_mem.get();
417cdf0e10cSrcweir                 m_env->GetStringRegion(
418cdf0e10cSrcweir                     (jstring) jo_stack_trace.get(), 0, len, ustr->buffer );
419cdf0e10cSrcweir                 if (assert_no_exception())
420cdf0e10cSrcweir                 {
421cdf0e10cSrcweir                     ustr->refCount = 1;
422cdf0e10cSrcweir                     ustr->length = len;
423cdf0e10cSrcweir                     ustr->buffer[ len ] = '\0';
424cdf0e10cSrcweir                     return OUString(
425cdf0e10cSrcweir                         (rtl_uString *)ustr_mem.release(), SAL_NO_ACQUIRE );
426cdf0e10cSrcweir                 }
427cdf0e10cSrcweir             }
428cdf0e10cSrcweir         }
429cdf0e10cSrcweir     }
430cdf0e10cSrcweir     return OUString();
431cdf0e10cSrcweir }
432cdf0e10cSrcweir 
433cdf0e10cSrcweir }
434cdf0e10cSrcweir 
435cdf0e10cSrcweir using namespace ::jni_uno;
436cdf0e10cSrcweir 
437cdf0e10cSrcweir extern "C"
438cdf0e10cSrcweir {
439cdf0e10cSrcweir namespace
440cdf0e10cSrcweir {
441cdf0e10cSrcweir 
442cdf0e10cSrcweir //------------------------------------------------------------------------------
443cdf0e10cSrcweir void SAL_CALL java_env_disposing( uno_Environment * java_env )
444cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
445cdf0e10cSrcweir {
446cdf0e10cSrcweir     ::jvmaccess::UnoVirtualMachine * machine =
447cdf0e10cSrcweir           reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
448cdf0e10cSrcweir               java_env->pContext );
449cdf0e10cSrcweir     java_env->pContext = 0;
450cdf0e10cSrcweir     machine->release();
451cdf0e10cSrcweir }
452cdf0e10cSrcweir }
453cdf0e10cSrcweir 
454cdf0e10cSrcweir //------------------------------------------------------------------------------
455cdf0e10cSrcweir void SAL_CALL uno_initEnvironment( uno_Environment * java_env )
456cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
457cdf0e10cSrcweir {
458cdf0e10cSrcweir     java_env->environmentDisposing = java_env_disposing;
459cdf0e10cSrcweir     java_env->pExtEnv = 0; // no extended support
460cdf0e10cSrcweir     OSL_ASSERT( 0 != java_env->pContext );
461cdf0e10cSrcweir 
462cdf0e10cSrcweir     ::jvmaccess::UnoVirtualMachine * machine =
463cdf0e10cSrcweir           reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
464cdf0e10cSrcweir               java_env->pContext );
465cdf0e10cSrcweir     machine->acquire();
466cdf0e10cSrcweir }
467cdf0e10cSrcweir 
468cdf0e10cSrcweir //------------------------------------------------------------------------------
469cdf0e10cSrcweir void SAL_CALL uno_ext_getMapping(
470cdf0e10cSrcweir     uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo )
471cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
472cdf0e10cSrcweir {
473cdf0e10cSrcweir     OSL_ASSERT( 0 != ppMapping && 0 != pFrom && 0 != pTo );
474cdf0e10cSrcweir     if (0 != *ppMapping)
475cdf0e10cSrcweir     {
476cdf0e10cSrcweir         (*(*ppMapping)->release)( *ppMapping );
477cdf0e10cSrcweir         *ppMapping = 0;
478cdf0e10cSrcweir     }
479cdf0e10cSrcweir 
480cdf0e10cSrcweir     OSL_ASSERT( JNI_FALSE == sal_False );
481cdf0e10cSrcweir     OSL_ASSERT( JNI_TRUE == sal_True );
482cdf0e10cSrcweir     OSL_ASSERT( sizeof (jboolean) == sizeof (sal_Bool) );
483cdf0e10cSrcweir     OSL_ASSERT( sizeof (jchar) == sizeof (sal_Unicode) );
484cdf0e10cSrcweir     OSL_ASSERT( sizeof (jdouble) == sizeof (double) );
485cdf0e10cSrcweir     OSL_ASSERT( sizeof (jfloat) == sizeof (float) );
486cdf0e10cSrcweir     OSL_ASSERT( sizeof (jbyte) == sizeof (sal_Int8) );
487cdf0e10cSrcweir     OSL_ASSERT( sizeof (jshort) == sizeof (sal_Int16) );
488cdf0e10cSrcweir     OSL_ASSERT( sizeof (jint) == sizeof (sal_Int32) );
489cdf0e10cSrcweir     OSL_ASSERT( sizeof (jlong) == sizeof (sal_Int64) );
490cdf0e10cSrcweir     if ((JNI_FALSE == sal_False) &&
491cdf0e10cSrcweir         (JNI_TRUE == sal_True) &&
492cdf0e10cSrcweir         (sizeof (jboolean) == sizeof (sal_Bool)) &&
493cdf0e10cSrcweir         (sizeof (jchar) == sizeof (sal_Unicode)) &&
494cdf0e10cSrcweir         (sizeof (jdouble) == sizeof (double)) &&
495cdf0e10cSrcweir         (sizeof (jfloat) == sizeof (float)) &&
496cdf0e10cSrcweir         (sizeof (jbyte) == sizeof (sal_Int8)) &&
497cdf0e10cSrcweir         (sizeof (jshort) == sizeof (sal_Int16)) &&
498cdf0e10cSrcweir         (sizeof (jint) == sizeof (sal_Int32)) &&
499cdf0e10cSrcweir         (sizeof (jlong) == sizeof (sal_Int64)))
500cdf0e10cSrcweir     {
501cdf0e10cSrcweir         OUString const & from_env_typename =
502cdf0e10cSrcweir             OUString::unacquired( &pFrom->pTypeName );
503cdf0e10cSrcweir         OUString const & to_env_typename =
504cdf0e10cSrcweir             OUString::unacquired( &pTo->pTypeName );
505cdf0e10cSrcweir 
506cdf0e10cSrcweir         uno_Mapping * mapping = 0;
507cdf0e10cSrcweir 
508cdf0e10cSrcweir         try
509cdf0e10cSrcweir         {
510cdf0e10cSrcweir             if (from_env_typename.equalsAsciiL(
511cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM(UNO_LB_JAVA) ) &&
512cdf0e10cSrcweir                 to_env_typename.equalsAsciiL(
513cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ))
514cdf0e10cSrcweir             {
515cdf0e10cSrcweir                 Bridge * bridge =
516cdf0e10cSrcweir                     new Bridge( pFrom, pTo->pExtEnv, true ); // ref count = 1
517cdf0e10cSrcweir                 mapping = &bridge->m_java2uno;
518cdf0e10cSrcweir                 uno_registerMapping(
519cdf0e10cSrcweir                     &mapping, Bridge_free,
520cdf0e10cSrcweir                     pFrom, (uno_Environment *)pTo->pExtEnv, 0 );
521cdf0e10cSrcweir             }
522cdf0e10cSrcweir             else if (from_env_typename.equalsAsciiL(
523cdf0e10cSrcweir                          RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ) &&
524cdf0e10cSrcweir                      to_env_typename.equalsAsciiL(
525cdf0e10cSrcweir                          RTL_CONSTASCII_STRINGPARAM(UNO_LB_JAVA) ))
526cdf0e10cSrcweir             {
527cdf0e10cSrcweir                 Bridge * bridge =
528cdf0e10cSrcweir                     new Bridge( pTo, pFrom->pExtEnv, false ); // ref count = 1
529cdf0e10cSrcweir                 mapping = &bridge->m_uno2java;
530cdf0e10cSrcweir                 uno_registerMapping(
531cdf0e10cSrcweir                     &mapping, Bridge_free,
532cdf0e10cSrcweir                     (uno_Environment *)pFrom->pExtEnv, pTo, 0 );
533cdf0e10cSrcweir             }
534cdf0e10cSrcweir         }
535cdf0e10cSrcweir         catch (BridgeRuntimeError & err)
536cdf0e10cSrcweir         {
537cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
538cdf0e10cSrcweir             OString cstr_msg(
539cdf0e10cSrcweir                 OUStringToOString(
540cdf0e10cSrcweir                     OUSTR("[jni_uno bridge error] ") + err.m_message,
541cdf0e10cSrcweir                     RTL_TEXTENCODING_ASCII_US ) );
542cdf0e10cSrcweir             OSL_ENSURE( 0, cstr_msg.getStr() );
543cdf0e10cSrcweir #else
544cdf0e10cSrcweir             (void) err; // unused
545cdf0e10cSrcweir #endif
546cdf0e10cSrcweir         }
547cdf0e10cSrcweir         catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
548cdf0e10cSrcweir         {
549cdf0e10cSrcweir             OSL_ENSURE(
550cdf0e10cSrcweir                 0,
551cdf0e10cSrcweir                 "[jni_uno bridge error] attaching current thread "
552cdf0e10cSrcweir                 "to java failed!" );
553cdf0e10cSrcweir         }
554cdf0e10cSrcweir 
555cdf0e10cSrcweir         *ppMapping = mapping;
556cdf0e10cSrcweir     }
557cdf0e10cSrcweir }
558cdf0e10cSrcweir 
559cdf0e10cSrcweir //------------------------------------------------------------------------------
560cdf0e10cSrcweir sal_Bool SAL_CALL component_canUnload( TimeValue * pTime )
561cdf0e10cSrcweir     SAL_THROW_EXTERN_C()
562cdf0e10cSrcweir {
563cdf0e10cSrcweir     return (*g_moduleCount.canUnload)( &g_moduleCount, pTime );
564cdf0e10cSrcweir }
565cdf0e10cSrcweir }
566