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