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