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