xref: /trunk/main/bridges/source/jni_uno/jni_base.h (revision 9eab2a37)
1*9eab2a37SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9eab2a37SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9eab2a37SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9eab2a37SAndrew Rist  * distributed with this work for additional information
6*9eab2a37SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9eab2a37SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9eab2a37SAndrew Rist  * "License"); you may not use this file except in compliance
9*9eab2a37SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*9eab2a37SAndrew Rist  *
11*9eab2a37SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*9eab2a37SAndrew Rist  *
13*9eab2a37SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9eab2a37SAndrew Rist  * software distributed under the License is distributed on an
15*9eab2a37SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9eab2a37SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9eab2a37SAndrew Rist  * specific language governing permissions and limitations
18*9eab2a37SAndrew Rist  * under the License.
19*9eab2a37SAndrew Rist  *
20*9eab2a37SAndrew Rist  *************************************************************/
21*9eab2a37SAndrew Rist 
22*9eab2a37SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #if ! defined INCLUDED_JNI_BASE_H
25cdf0e10cSrcweir #define INCLUDED_JNI_BASE_H
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #if defined (__SUNPRO_CC) || defined (__SUNPRO_C)
28cdf0e10cSrcweir // workaround solaris include trouble on jumbo
29cdf0e10cSrcweir #include <stdarg.h>
30cdf0e10cSrcweir namespace std
31cdf0e10cSrcweir {
32cdf0e10cSrcweir typedef __va_list va_list;
33cdf0e10cSrcweir }
34cdf0e10cSrcweir #endif
35cdf0e10cSrcweir #include <memory>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include "jvmaccess/unovirtualmachine.hxx"
38cdf0e10cSrcweir #include "jvmaccess/virtualmachine.hxx"
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #include "osl/diagnose.h"
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include "rtl/alloc.h"
43cdf0e10cSrcweir #include "rtl/ustring.hxx"
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #include "uno/environment.h"
46cdf0e10cSrcweir #include "typelib/typedescription.h"
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
49cdf0e10cSrcweir 
50cdf0e10cSrcweir 
51cdf0e10cSrcweir namespace jni_uno
52cdf0e10cSrcweir {
53cdf0e10cSrcweir 
54cdf0e10cSrcweir class JNI_info;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir //==============================================================================
57cdf0e10cSrcweir struct BridgeRuntimeError
58cdf0e10cSrcweir {
59cdf0e10cSrcweir     ::rtl::OUString m_message;
60cdf0e10cSrcweir 
61cdf0e10cSrcweir     inline BridgeRuntimeError( ::rtl::OUString const & message )
62cdf0e10cSrcweir         : m_message( message )
63cdf0e10cSrcweir         {}
64cdf0e10cSrcweir };
65cdf0e10cSrcweir 
66cdf0e10cSrcweir 
67cdf0e10cSrcweir //==============================================================================
68cdf0e10cSrcweir class JNI_context
69cdf0e10cSrcweir {
70cdf0e10cSrcweir     JNI_info const * m_jni_info;
71cdf0e10cSrcweir     JNIEnv *         m_env;
72cdf0e10cSrcweir     jobject          m_class_loader;
73cdf0e10cSrcweir 
74cdf0e10cSrcweir     JNI_context( JNI_context & ); // not impl
75cdf0e10cSrcweir     void operator = ( JNI_context ); // not impl
76cdf0e10cSrcweir 
77cdf0e10cSrcweir     void java_exc_occured() const;
78cdf0e10cSrcweir public:
79cdf0e10cSrcweir     inline explicit JNI_context(
80cdf0e10cSrcweir         JNI_info const * jni_info, JNIEnv * env, jobject class_loader )
81cdf0e10cSrcweir         : m_jni_info( jni_info ),
82cdf0e10cSrcweir           m_env( env ),
83cdf0e10cSrcweir           m_class_loader( class_loader )
84cdf0e10cSrcweir         {}
85cdf0e10cSrcweir 
86cdf0e10cSrcweir     inline JNI_info const * get_info() const
87cdf0e10cSrcweir         { return m_jni_info; }
88cdf0e10cSrcweir 
89cdf0e10cSrcweir     inline JNIEnv * operator -> () const
90cdf0e10cSrcweir         { return m_env; }
91cdf0e10cSrcweir     inline JNIEnv * get_jni_env() const
92cdf0e10cSrcweir         { return m_env; }
93cdf0e10cSrcweir 
94cdf0e10cSrcweir     // does not handle exceptions, *classClass will be null if exception
95cdf0e10cSrcweir     // occurred:
96cdf0e10cSrcweir     void getClassForName(jclass * classClass, jmethodID * methodForName) const;
97cdf0e10cSrcweir 
98cdf0e10cSrcweir     // if inException, does not handle exceptions, in which case returned value
99cdf0e10cSrcweir     // will be null if exception occurred:
100cdf0e10cSrcweir     jclass findClass(
101cdf0e10cSrcweir         char const * name, jclass classClass, jmethodID methodForName,
102cdf0e10cSrcweir         bool inException) const;
103cdf0e10cSrcweir 
104cdf0e10cSrcweir     inline void ensure_no_exception() const; // throws BridgeRuntimeError
105cdf0e10cSrcweir     inline bool assert_no_exception() const; // asserts and clears exception
106cdf0e10cSrcweir 
107cdf0e10cSrcweir     ::rtl::OUString get_stack_trace( jobject jo_exc = 0 ) const;
108cdf0e10cSrcweir };
109cdf0e10cSrcweir 
110cdf0e10cSrcweir //______________________________________________________________________________
111cdf0e10cSrcweir inline void JNI_context::ensure_no_exception() const
112cdf0e10cSrcweir {
113cdf0e10cSrcweir     if (JNI_FALSE != m_env->ExceptionCheck())
114cdf0e10cSrcweir     {
115cdf0e10cSrcweir         java_exc_occured();
116cdf0e10cSrcweir     }
117cdf0e10cSrcweir }
118cdf0e10cSrcweir 
119cdf0e10cSrcweir //______________________________________________________________________________
120cdf0e10cSrcweir inline bool JNI_context::assert_no_exception() const
121cdf0e10cSrcweir {
122cdf0e10cSrcweir     if (JNI_FALSE != m_env->ExceptionCheck())
123cdf0e10cSrcweir     {
124cdf0e10cSrcweir         m_env->ExceptionClear();
125cdf0e10cSrcweir         OSL_ENSURE( 0, "unexpected java exception occured!" );
126cdf0e10cSrcweir         return false;
127cdf0e10cSrcweir     }
128cdf0e10cSrcweir     return true;
129cdf0e10cSrcweir }
130cdf0e10cSrcweir 
131cdf0e10cSrcweir 
132cdf0e10cSrcweir //==============================================================================
133cdf0e10cSrcweir class JNI_guarded_context
134cdf0e10cSrcweir     : private ::jvmaccess::VirtualMachine::AttachGuard,
135cdf0e10cSrcweir       public JNI_context
136cdf0e10cSrcweir {
137cdf0e10cSrcweir     JNI_guarded_context( JNI_guarded_context & ); // not impl
138cdf0e10cSrcweir     void operator = ( JNI_guarded_context ); // not impl
139cdf0e10cSrcweir 
140cdf0e10cSrcweir public:
141cdf0e10cSrcweir     inline explicit JNI_guarded_context(
142cdf0e10cSrcweir         JNI_info const * jni_info, ::jvmaccess::UnoVirtualMachine * vm_access )
143cdf0e10cSrcweir         : AttachGuard( vm_access->getVirtualMachine() ),
144cdf0e10cSrcweir           JNI_context(
145cdf0e10cSrcweir               jni_info, AttachGuard::getEnvironment(),
146cdf0e10cSrcweir               static_cast< jobject >(vm_access->getClassLoader()) )
147cdf0e10cSrcweir         {}
148cdf0e10cSrcweir };
149cdf0e10cSrcweir 
150cdf0e10cSrcweir 
151cdf0e10cSrcweir //==============================================================================
152cdf0e10cSrcweir class JLocalAutoRef
153cdf0e10cSrcweir {
154cdf0e10cSrcweir     JNI_context const & m_jni;
155cdf0e10cSrcweir     jobject m_jo;
156cdf0e10cSrcweir 
157cdf0e10cSrcweir public:
158cdf0e10cSrcweir     inline JLocalAutoRef( JNI_context const & jni )
159cdf0e10cSrcweir         : m_jni( jni ),
160cdf0e10cSrcweir           m_jo( 0 )
161cdf0e10cSrcweir         {}
162cdf0e10cSrcweir     inline explicit JLocalAutoRef( JNI_context const & jni, jobject jo )
163cdf0e10cSrcweir         : m_jni( jni ),
164cdf0e10cSrcweir           m_jo( jo )
165cdf0e10cSrcweir         {}
166cdf0e10cSrcweir     inline JLocalAutoRef( JLocalAutoRef & auto_ref );
167cdf0e10cSrcweir     inline ~JLocalAutoRef() SAL_THROW( () );
168cdf0e10cSrcweir 
169cdf0e10cSrcweir     inline jobject get() const
170cdf0e10cSrcweir         { return m_jo; }
171cdf0e10cSrcweir     inline bool is() const
172cdf0e10cSrcweir         { return (0 != m_jo); }
173cdf0e10cSrcweir     inline jobject release();
174cdf0e10cSrcweir     inline void reset();
175cdf0e10cSrcweir     inline void reset( jobject jo );
176cdf0e10cSrcweir     inline JLocalAutoRef & operator = ( JLocalAutoRef & auto_ref );
177cdf0e10cSrcweir };
178cdf0e10cSrcweir 
179cdf0e10cSrcweir //______________________________________________________________________________
180cdf0e10cSrcweir inline JLocalAutoRef::~JLocalAutoRef() SAL_THROW( () )
181cdf0e10cSrcweir {
182cdf0e10cSrcweir     if (0 != m_jo)
183cdf0e10cSrcweir         m_jni->DeleteLocalRef( m_jo );
184cdf0e10cSrcweir }
185cdf0e10cSrcweir 
186cdf0e10cSrcweir //______________________________________________________________________________
187cdf0e10cSrcweir inline JLocalAutoRef::JLocalAutoRef( JLocalAutoRef & auto_ref )
188cdf0e10cSrcweir     : m_jni( auto_ref.m_jni ),
189cdf0e10cSrcweir       m_jo( auto_ref.m_jo )
190cdf0e10cSrcweir {
191cdf0e10cSrcweir     auto_ref.m_jo = 0;
192cdf0e10cSrcweir }
193cdf0e10cSrcweir 
194cdf0e10cSrcweir //______________________________________________________________________________
195cdf0e10cSrcweir inline jobject JLocalAutoRef::release()
196cdf0e10cSrcweir {
197cdf0e10cSrcweir     jobject jo = m_jo;
198cdf0e10cSrcweir     m_jo = 0;
199cdf0e10cSrcweir     return jo;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
202cdf0e10cSrcweir //______________________________________________________________________________
203cdf0e10cSrcweir inline void JLocalAutoRef::reset()
204cdf0e10cSrcweir {
205cdf0e10cSrcweir     if (0 != m_jo)
206cdf0e10cSrcweir         m_jni->DeleteLocalRef( m_jo );
207cdf0e10cSrcweir     m_jo = 0;
208cdf0e10cSrcweir }
209cdf0e10cSrcweir 
210cdf0e10cSrcweir //______________________________________________________________________________
211cdf0e10cSrcweir inline void JLocalAutoRef::reset( jobject jo )
212cdf0e10cSrcweir {
213cdf0e10cSrcweir     if (jo != m_jo)
214cdf0e10cSrcweir     {
215cdf0e10cSrcweir         if (0 != m_jo)
216cdf0e10cSrcweir             m_jni->DeleteLocalRef( m_jo );
217cdf0e10cSrcweir         m_jo = jo;
218cdf0e10cSrcweir     }
219cdf0e10cSrcweir }
220cdf0e10cSrcweir 
221cdf0e10cSrcweir //______________________________________________________________________________
222cdf0e10cSrcweir inline JLocalAutoRef & JLocalAutoRef::operator = ( JLocalAutoRef & auto_ref )
223cdf0e10cSrcweir {
224cdf0e10cSrcweir     OSL_ASSERT( m_jni.get_jni_env() == auto_ref.m_jni.get_jni_env() );
225cdf0e10cSrcweir     reset( auto_ref.m_jo );
226cdf0e10cSrcweir     auto_ref.m_jo = 0;
227cdf0e10cSrcweir     return *this;
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 
231cdf0e10cSrcweir //==============================================================================
232cdf0e10cSrcweir struct rtl_mem
233cdf0e10cSrcweir {
234cdf0e10cSrcweir 	inline static void * operator new ( size_t nSize )
235cdf0e10cSrcweir 		{ return rtl_allocateMemory( nSize ); }
236cdf0e10cSrcweir 	inline static void operator delete ( void * mem )
237cdf0e10cSrcweir 		{ if (mem) rtl_freeMemory( mem ); }
238cdf0e10cSrcweir 	inline static void * operator new ( size_t, void * mem )
239cdf0e10cSrcweir 		{ return mem; }
240cdf0e10cSrcweir 	inline static void operator delete ( void *, void * )
241cdf0e10cSrcweir 		{}
242cdf0e10cSrcweir 
243cdf0e10cSrcweir     static inline ::std::auto_ptr< rtl_mem > allocate( ::std::size_t bytes );
244cdf0e10cSrcweir };
245cdf0e10cSrcweir 
246cdf0e10cSrcweir //______________________________________________________________________________
247cdf0e10cSrcweir inline ::std::auto_ptr< rtl_mem > rtl_mem::allocate( ::std::size_t bytes )
248cdf0e10cSrcweir {
249cdf0e10cSrcweir     void * p = rtl_allocateMemory( bytes );
250cdf0e10cSrcweir     if (0 == p)
251cdf0e10cSrcweir         throw BridgeRuntimeError( OUSTR("out of memory!") );
252cdf0e10cSrcweir     return ::std::auto_ptr< rtl_mem >( (rtl_mem *)p );
253cdf0e10cSrcweir }
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 
256cdf0e10cSrcweir //==============================================================================
257cdf0e10cSrcweir class TypeDescr
258cdf0e10cSrcweir {
259cdf0e10cSrcweir     typelib_TypeDescription * m_td;
260cdf0e10cSrcweir 
261cdf0e10cSrcweir     TypeDescr( TypeDescr & ); // not impl
262cdf0e10cSrcweir     void operator = ( TypeDescr ); // not impl
263cdf0e10cSrcweir 
264cdf0e10cSrcweir public:
265cdf0e10cSrcweir     inline explicit TypeDescr( typelib_TypeDescriptionReference * td_ref );
266cdf0e10cSrcweir     inline ~TypeDescr() SAL_THROW( () )
267cdf0e10cSrcweir         { TYPELIB_DANGER_RELEASE( m_td ); }
268cdf0e10cSrcweir 
269cdf0e10cSrcweir     inline typelib_TypeDescription * get() const
270cdf0e10cSrcweir         { return m_td; }
271cdf0e10cSrcweir };
272cdf0e10cSrcweir 
273cdf0e10cSrcweir //______________________________________________________________________________
274cdf0e10cSrcweir inline TypeDescr::TypeDescr( typelib_TypeDescriptionReference * td_ref )
275cdf0e10cSrcweir     : m_td( 0 )
276cdf0e10cSrcweir {
277cdf0e10cSrcweir     TYPELIB_DANGER_GET( &m_td, td_ref );
278cdf0e10cSrcweir     if (0 == m_td)
279cdf0e10cSrcweir     {
280cdf0e10cSrcweir         throw BridgeRuntimeError(
281cdf0e10cSrcweir             OUSTR("cannot get comprehensive type description for ") +
282cdf0e10cSrcweir             ::rtl::OUString::unacquired( &td_ref->pTypeName ) );
283cdf0e10cSrcweir     }
284cdf0e10cSrcweir }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir }
287cdf0e10cSrcweir 
288cdf0e10cSrcweir #endif
289