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_INFO_H
25cdf0e10cSrcweir #define INCLUDED_JNI_INFO_H
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include <hash_map>
28cdf0e10cSrcweir
29cdf0e10cSrcweir #include "jni_base.h"
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include "osl/mutex.hxx"
32cdf0e10cSrcweir #include "rtl/ref.hxx"
33cdf0e10cSrcweir #include "rtl/ustring.hxx"
34cdf0e10cSrcweir #include "rtl/strbuf.hxx"
35cdf0e10cSrcweir
36cdf0e10cSrcweir #include "uno/environment.h"
37cdf0e10cSrcweir #include "typelib/typedescription.hxx"
38cdf0e10cSrcweir
39cdf0e10cSrcweir #include "com/sun/star/uno/Type.hxx"
40cdf0e10cSrcweir
41cdf0e10cSrcweir namespace jvmaccess { class UnoVirtualMachine; }
42cdf0e10cSrcweir
43cdf0e10cSrcweir namespace jni_uno
44cdf0e10cSrcweir {
45cdf0e10cSrcweir
46cdf0e10cSrcweir //------------------------------------------------------------------------------
type_equals(typelib_TypeDescriptionReference * type1,typelib_TypeDescriptionReference * type2)47cdf0e10cSrcweir inline bool type_equals(
48cdf0e10cSrcweir typelib_TypeDescriptionReference * type1,
49cdf0e10cSrcweir typelib_TypeDescriptionReference * type2 )
50cdf0e10cSrcweir {
51cdf0e10cSrcweir if (type1 == type2)
52cdf0e10cSrcweir return true;
53cdf0e10cSrcweir ::rtl::OUString const & name1 =
54cdf0e10cSrcweir ::rtl::OUString::unacquired( &type1->pTypeName );
55cdf0e10cSrcweir ::rtl::OUString const & name2 =
56cdf0e10cSrcweir ::rtl::OUString::unacquired( &type2->pTypeName );
57cdf0e10cSrcweir return ((type1->eTypeClass == type2->eTypeClass) && name1.equals( name2 ));
58cdf0e10cSrcweir }
59cdf0e10cSrcweir
60cdf0e10cSrcweir //------------------------------------------------------------------------------
is_XInterface(typelib_TypeDescriptionReference * type)61cdf0e10cSrcweir inline bool is_XInterface( typelib_TypeDescriptionReference * type )
62cdf0e10cSrcweir {
63cdf0e10cSrcweir return ((typelib_TypeClass_INTERFACE == type->eTypeClass) &&
64cdf0e10cSrcweir ::rtl::OUString::unacquired( &type->pTypeName ).equalsAsciiL(
65cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ));
66cdf0e10cSrcweir }
67cdf0e10cSrcweir
68cdf0e10cSrcweir //==============================================================================
69cdf0e10cSrcweir struct JNI_type_info
70cdf0e10cSrcweir {
71cdf0e10cSrcweir ::com::sun::star::uno::TypeDescription m_td;
72cdf0e10cSrcweir jclass m_class;
73cdf0e10cSrcweir
74cdf0e10cSrcweir virtual void destroy( JNIEnv * jni_env ) = 0;
75cdf0e10cSrcweir protected:
destructjni_uno::JNI_type_info76cdf0e10cSrcweir inline void destruct( JNIEnv * jni_env )
77cdf0e10cSrcweir { jni_env->DeleteGlobalRef( m_class ); }
~JNI_type_infojni_uno::JNI_type_info78cdf0e10cSrcweir virtual inline ~JNI_type_info() {}
79cdf0e10cSrcweir explicit JNI_type_info(
80cdf0e10cSrcweir JNI_context const & jni, typelib_TypeDescription * td );
81cdf0e10cSrcweir };
82cdf0e10cSrcweir
83cdf0e10cSrcweir //==============================================================================
84cdf0e10cSrcweir struct JNI_interface_type_info : public JNI_type_info
85cdf0e10cSrcweir {
86cdf0e10cSrcweir jobject m_proxy_ctor; // proxy ctor
87cdf0e10cSrcweir jobject m_type;
88cdf0e10cSrcweir // sorted via typelib function index
89cdf0e10cSrcweir jmethodID * m_methods;
90cdf0e10cSrcweir
91cdf0e10cSrcweir virtual void destroy( JNIEnv * jni_env );
92cdf0e10cSrcweir explicit JNI_interface_type_info(
93cdf0e10cSrcweir JNI_context const & jni, typelib_TypeDescription * td );
94cdf0e10cSrcweir };
95cdf0e10cSrcweir
96cdf0e10cSrcweir //==============================================================================
97cdf0e10cSrcweir struct JNI_compound_type_info : public JNI_type_info
98cdf0e10cSrcweir {
99cdf0e10cSrcweir JNI_type_info const * m_base;
100cdf0e10cSrcweir // ctor( msg ) for exceptions
101cdf0e10cSrcweir jmethodID m_exc_ctor;
102cdf0e10cSrcweir // sorted via typelib member index
103cdf0e10cSrcweir jfieldID * m_fields;
104cdf0e10cSrcweir
105cdf0e10cSrcweir virtual void destroy( JNIEnv * jni_env );
106cdf0e10cSrcweir explicit JNI_compound_type_info(
107cdf0e10cSrcweir JNI_context const & jni, typelib_TypeDescription * td );
108cdf0e10cSrcweir };
109cdf0e10cSrcweir
110cdf0e10cSrcweir //==============================================================================
111cdf0e10cSrcweir struct JNI_type_info_holder
112cdf0e10cSrcweir {
113cdf0e10cSrcweir JNI_type_info * m_info;
JNI_type_info_holderjni_uno::JNI_type_info_holder114cdf0e10cSrcweir inline JNI_type_info_holder()
115cdf0e10cSrcweir : m_info( 0 )
116cdf0e10cSrcweir {}
117cdf0e10cSrcweir };
118cdf0e10cSrcweir
119cdf0e10cSrcweir typedef ::std::hash_map<
120cdf0e10cSrcweir ::rtl::OUString, JNI_type_info_holder, ::rtl::OUStringHash > t_str2type;
121cdf0e10cSrcweir
122cdf0e10cSrcweir //==============================================================================
123cdf0e10cSrcweir class JNI_info
124cdf0e10cSrcweir {
125cdf0e10cSrcweir mutable ::osl::Mutex m_mutex;
126cdf0e10cSrcweir mutable t_str2type m_type_map;
127cdf0e10cSrcweir
128cdf0e10cSrcweir public:
129cdf0e10cSrcweir // These two are needed very early by find_class from within the ctor:
130cdf0e10cSrcweir jclass m_class_Class;
131cdf0e10cSrcweir jmethodID m_method_Class_forName;
132cdf0e10cSrcweir
133cdf0e10cSrcweir //
134cdf0e10cSrcweir jobject m_object_java_env;
135cdf0e10cSrcweir jobject m_object_Any_VOID;
136cdf0e10cSrcweir jobject m_object_Type_UNSIGNED_SHORT;
137cdf0e10cSrcweir jobject m_object_Type_UNSIGNED_LONG;
138cdf0e10cSrcweir jobject m_object_Type_UNSIGNED_HYPER;
139cdf0e10cSrcweir
140cdf0e10cSrcweir //
141cdf0e10cSrcweir jclass m_class_Object;
142cdf0e10cSrcweir jclass m_class_Character;
143cdf0e10cSrcweir jclass m_class_Boolean;
144cdf0e10cSrcweir jclass m_class_Byte;
145cdf0e10cSrcweir jclass m_class_Short;
146cdf0e10cSrcweir jclass m_class_Integer;
147cdf0e10cSrcweir jclass m_class_Long;
148cdf0e10cSrcweir jclass m_class_Float;
149cdf0e10cSrcweir jclass m_class_Double;
150cdf0e10cSrcweir jclass m_class_String;
151cdf0e10cSrcweir
152cdf0e10cSrcweir jclass m_class_UnoRuntime;
153cdf0e10cSrcweir jclass m_class_RuntimeException;
154cdf0e10cSrcweir jclass m_class_Any;
155cdf0e10cSrcweir jclass m_class_Type;
156cdf0e10cSrcweir jclass m_class_TypeClass;
157cdf0e10cSrcweir jclass m_class_JNI_proxy;
158cdf0e10cSrcweir
159cdf0e10cSrcweir //
160cdf0e10cSrcweir jmethodID m_method_Object_toString;
161cdf0e10cSrcweir jmethodID m_method_Class_getName;
162cdf0e10cSrcweir jmethodID m_method_Throwable_getMessage;
163cdf0e10cSrcweir jmethodID m_ctor_Character_with_char;
164cdf0e10cSrcweir jmethodID m_ctor_Boolean_with_boolean;
165cdf0e10cSrcweir jmethodID m_ctor_Byte_with_byte;
166cdf0e10cSrcweir jmethodID m_ctor_Short_with_short;
167cdf0e10cSrcweir jmethodID m_ctor_Integer_with_int;
168cdf0e10cSrcweir jmethodID m_ctor_Long_with_long;
169cdf0e10cSrcweir jmethodID m_ctor_Float_with_float;
170cdf0e10cSrcweir jmethodID m_ctor_Double_with_double;
171cdf0e10cSrcweir jmethodID m_method_Boolean_booleanValue;
172cdf0e10cSrcweir jmethodID m_method_Byte_byteValue;
173cdf0e10cSrcweir jmethodID m_method_Character_charValue;
174cdf0e10cSrcweir jmethodID m_method_Double_doubleValue;
175cdf0e10cSrcweir jmethodID m_method_Float_floatValue;
176cdf0e10cSrcweir jmethodID m_method_Integer_intValue;
177cdf0e10cSrcweir jmethodID m_method_Long_longValue;
178cdf0e10cSrcweir jmethodID m_method_Short_shortValue;
179cdf0e10cSrcweir
180cdf0e10cSrcweir //
181cdf0e10cSrcweir jmethodID m_method_IEnvironment_getRegisteredInterface;
182cdf0e10cSrcweir jmethodID m_method_IEnvironment_registerInterface;
183cdf0e10cSrcweir jmethodID m_method_UnoRuntime_generateOid;
184cdf0e10cSrcweir jmethodID m_method_UnoRuntime_queryInterface;
185cdf0e10cSrcweir jmethodID m_ctor_Any_with_Type_Object;
186cdf0e10cSrcweir jfieldID m_field_Any__type;
187cdf0e10cSrcweir jfieldID m_field_Any__object;
188cdf0e10cSrcweir jmethodID m_ctor_Type_with_Class;
189cdf0e10cSrcweir jmethodID m_ctor_Type_with_Name_TypeClass;
190cdf0e10cSrcweir jfieldID m_field_Type__typeName;
191cdf0e10cSrcweir jmethodID m_method_TypeClass_fromInt;
192cdf0e10cSrcweir jfieldID m_field_Enum_m_value;
193cdf0e10cSrcweir
194cdf0e10cSrcweir //
195cdf0e10cSrcweir jmethodID m_method_JNI_proxy_get_proxy_ctor;
196cdf0e10cSrcweir jmethodID m_method_JNI_proxy_create;
197cdf0e10cSrcweir jfieldID m_field_JNI_proxy_m_receiver_handle;
198cdf0e10cSrcweir jfieldID m_field_JNI_proxy_m_td_handle;
199cdf0e10cSrcweir jfieldID m_field_JNI_proxy_m_type;
200cdf0e10cSrcweir jfieldID m_field_JNI_proxy_m_oid;
201cdf0e10cSrcweir
202cdf0e10cSrcweir //
203cdf0e10cSrcweir ::com::sun::star::uno::TypeDescription m_XInterface_queryInterface_td;
204cdf0e10cSrcweir ::com::sun::star::uno::Type const & m_Exception_type;
205cdf0e10cSrcweir ::com::sun::star::uno::Type const & m_RuntimeException_type;
206cdf0e10cSrcweir ::com::sun::star::uno::Type const & m_void_type;
207cdf0e10cSrcweir //
208cdf0e10cSrcweir JNI_interface_type_info const * m_XInterface_type_info;
209cdf0e10cSrcweir
210cdf0e10cSrcweir //
211cdf0e10cSrcweir JNI_type_info const * get_type_info(
212cdf0e10cSrcweir JNI_context const & jni,
213cdf0e10cSrcweir typelib_TypeDescription * type ) const;
214cdf0e10cSrcweir JNI_type_info const * get_type_info(
215cdf0e10cSrcweir JNI_context const & jni,
216cdf0e10cSrcweir typelib_TypeDescriptionReference * type ) const;
217cdf0e10cSrcweir JNI_type_info const * get_type_info(
218cdf0e10cSrcweir JNI_context const & jni,
219cdf0e10cSrcweir ::rtl::OUString const & uno_name ) const;
220cdf0e10cSrcweir //
221cdf0e10cSrcweir inline static void append_sig(
222cdf0e10cSrcweir ::rtl::OStringBuffer * buf, typelib_TypeDescriptionReference * type,
223cdf0e10cSrcweir bool use_Object_for_type_XInterface = true, bool use_slashes = true );
224cdf0e10cSrcweir
225cdf0e10cSrcweir // get this
226cdf0e10cSrcweir static JNI_info const * get_jni_info(
227cdf0e10cSrcweir rtl::Reference< jvmaccess::UnoVirtualMachine > const & uno_vm );
228cdf0e10cSrcweir inline void destroy( JNIEnv * jni_env );
229cdf0e10cSrcweir
230cdf0e10cSrcweir private:
231cdf0e10cSrcweir JNI_type_info const * create_type_info(
232cdf0e10cSrcweir JNI_context const & jni, typelib_TypeDescription * td ) const;
233cdf0e10cSrcweir
234cdf0e10cSrcweir void destruct( JNIEnv * jni_env );
235cdf0e10cSrcweir
236cdf0e10cSrcweir JNI_info( JNIEnv * jni_env, jobject class_loader,
237cdf0e10cSrcweir jclass classClass, jmethodID methodForName );
~JNI_info()238cdf0e10cSrcweir inline ~JNI_info() {}
239cdf0e10cSrcweir };
240cdf0e10cSrcweir
241cdf0e10cSrcweir //______________________________________________________________________________
destroy(JNIEnv * jni_env)242cdf0e10cSrcweir inline void JNI_info::destroy( JNIEnv * jni_env )
243cdf0e10cSrcweir {
244cdf0e10cSrcweir destruct( jni_env );
245cdf0e10cSrcweir delete this;
246cdf0e10cSrcweir }
247cdf0e10cSrcweir
248cdf0e10cSrcweir //______________________________________________________________________________
append_sig(::rtl::OStringBuffer * buf,typelib_TypeDescriptionReference * type,bool use_Object_for_type_XInterface,bool use_slashes)249cdf0e10cSrcweir inline void JNI_info::append_sig(
250cdf0e10cSrcweir ::rtl::OStringBuffer * buf, typelib_TypeDescriptionReference * type,
251cdf0e10cSrcweir bool use_Object_for_type_XInterface, bool use_slashes )
252cdf0e10cSrcweir {
253cdf0e10cSrcweir switch (type->eTypeClass)
254cdf0e10cSrcweir {
255cdf0e10cSrcweir case typelib_TypeClass_VOID:
256cdf0e10cSrcweir buf->append( 'V' );
257cdf0e10cSrcweir break;
258cdf0e10cSrcweir case typelib_TypeClass_CHAR:
259cdf0e10cSrcweir buf->append( 'C' );
260cdf0e10cSrcweir break;
261cdf0e10cSrcweir case typelib_TypeClass_BOOLEAN:
262cdf0e10cSrcweir buf->append( 'Z' );
263cdf0e10cSrcweir break;
264cdf0e10cSrcweir case typelib_TypeClass_BYTE:
265cdf0e10cSrcweir buf->append( 'B' );
266cdf0e10cSrcweir break;
267cdf0e10cSrcweir case typelib_TypeClass_SHORT:
268cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_SHORT:
269cdf0e10cSrcweir buf->append( 'S' );
270cdf0e10cSrcweir break;
271cdf0e10cSrcweir case typelib_TypeClass_LONG:
272cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_LONG:
273cdf0e10cSrcweir buf->append( 'I' );
274cdf0e10cSrcweir break;
275cdf0e10cSrcweir case typelib_TypeClass_HYPER:
276cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER:
277cdf0e10cSrcweir buf->append( 'J' );
278cdf0e10cSrcweir break;
279cdf0e10cSrcweir case typelib_TypeClass_FLOAT:
280cdf0e10cSrcweir buf->append( 'F' );
281cdf0e10cSrcweir break;
282cdf0e10cSrcweir case typelib_TypeClass_DOUBLE:
283cdf0e10cSrcweir buf->append( 'D' );
284cdf0e10cSrcweir break;
285cdf0e10cSrcweir case typelib_TypeClass_STRING:
286cdf0e10cSrcweir if ( use_slashes ) {
287cdf0e10cSrcweir buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/String;") );
288cdf0e10cSrcweir } else {
289cdf0e10cSrcweir buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava.lang.String;") );
290cdf0e10cSrcweir }
291cdf0e10cSrcweir break;
292cdf0e10cSrcweir case typelib_TypeClass_TYPE:
293cdf0e10cSrcweir if ( use_slashes ) {
294cdf0e10cSrcweir buf->append(
295cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Type;") );
296cdf0e10cSrcweir } else {
297cdf0e10cSrcweir buf->append(
298cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("Lcom.sun.star.uno.Type;") );
299cdf0e10cSrcweir }
300cdf0e10cSrcweir break;
301cdf0e10cSrcweir case typelib_TypeClass_ANY:
302cdf0e10cSrcweir if ( use_slashes ) {
303cdf0e10cSrcweir buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;") );
304cdf0e10cSrcweir } else {
305cdf0e10cSrcweir buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava.lang.Object;") );
306cdf0e10cSrcweir }
307cdf0e10cSrcweir break;
308cdf0e10cSrcweir case typelib_TypeClass_ENUM:
309cdf0e10cSrcweir case typelib_TypeClass_STRUCT:
310cdf0e10cSrcweir case typelib_TypeClass_EXCEPTION:
311cdf0e10cSrcweir {
312cdf0e10cSrcweir ::rtl::OUString const & uno_name =
313cdf0e10cSrcweir ::rtl::OUString::unacquired( &type->pTypeName );
314cdf0e10cSrcweir buf->append( 'L' );
315cdf0e10cSrcweir // Erase type arguments of instantiated polymorphic struct types:
316cdf0e10cSrcweir sal_Int32 i = uno_name.indexOf( '<' );
317cdf0e10cSrcweir if ( i < 0 ) {
318cdf0e10cSrcweir buf->append(
319cdf0e10cSrcweir ::rtl::OUStringToOString(
320cdf0e10cSrcweir use_slashes ? uno_name.replace( '.', '/' ) : uno_name,
321cdf0e10cSrcweir RTL_TEXTENCODING_JAVA_UTF8 ) );
322cdf0e10cSrcweir } else {
323cdf0e10cSrcweir rtl::OUString s( uno_name.copy( 0, i ) );
324cdf0e10cSrcweir buf->append(
325cdf0e10cSrcweir ::rtl::OUStringToOString(
326cdf0e10cSrcweir use_slashes ? s.replace( '.', '/' ) : s,
327cdf0e10cSrcweir RTL_TEXTENCODING_JAVA_UTF8 ) );
328cdf0e10cSrcweir }
329cdf0e10cSrcweir buf->append( ';' );
330cdf0e10cSrcweir break;
331cdf0e10cSrcweir }
332cdf0e10cSrcweir case typelib_TypeClass_SEQUENCE:
333cdf0e10cSrcweir {
334cdf0e10cSrcweir buf->append( '[' );
335cdf0e10cSrcweir TypeDescr td( type );
336cdf0e10cSrcweir append_sig(
337cdf0e10cSrcweir buf, ((typelib_IndirectTypeDescription *)td.get())->pType,
338cdf0e10cSrcweir use_Object_for_type_XInterface, use_slashes );
339cdf0e10cSrcweir break;
340cdf0e10cSrcweir }
341cdf0e10cSrcweir case typelib_TypeClass_INTERFACE:
342cdf0e10cSrcweir if (use_Object_for_type_XInterface && is_XInterface( type ))
343cdf0e10cSrcweir {
344cdf0e10cSrcweir if ( use_slashes ) {
345cdf0e10cSrcweir buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;") );
346cdf0e10cSrcweir } else {
347cdf0e10cSrcweir buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava.lang.Object;") );
348cdf0e10cSrcweir }
349cdf0e10cSrcweir }
350cdf0e10cSrcweir else
351cdf0e10cSrcweir {
352cdf0e10cSrcweir ::rtl::OUString const & uno_name =
353cdf0e10cSrcweir ::rtl::OUString::unacquired( &type->pTypeName );
354cdf0e10cSrcweir buf->append( 'L' );
355cdf0e10cSrcweir buf->append(
356cdf0e10cSrcweir ::rtl::OUStringToOString(
357cdf0e10cSrcweir use_slashes ? uno_name.replace( '.', '/' ) : uno_name,
358cdf0e10cSrcweir RTL_TEXTENCODING_JAVA_UTF8 ) );
359cdf0e10cSrcweir buf->append( ';' );
360cdf0e10cSrcweir }
361cdf0e10cSrcweir break;
362cdf0e10cSrcweir default:
363cdf0e10cSrcweir throw BridgeRuntimeError(
364cdf0e10cSrcweir OUSTR("unsupported type: ") +
365cdf0e10cSrcweir ::rtl::OUString::unacquired( &type->pTypeName ) );
366cdf0e10cSrcweir }
367cdf0e10cSrcweir }
368cdf0e10cSrcweir
369cdf0e10cSrcweir }
370cdf0e10cSrcweir
371cdf0e10cSrcweir #endif
372