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