378 lines
14 KiB
C++
378 lines
14 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
#if ! defined INCLUDED_JNI_INFO_H
|
|
#define INCLUDED_JNI_INFO_H
|
|
|
|
#include <boost/unordered_map.hpp>
|
|
|
|
#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;
|
|
::rtl::OUString const & name1 =
|
|
::rtl::OUString::unacquired( &type1->pTypeName );
|
|
::rtl::OUString const & name2 =
|
|
::rtl::OUString::unacquired( &type2->pTypeName );
|
|
return ((type1->eTypeClass == type2->eTypeClass) && name1.equals( name2 ));
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
inline bool is_XInterface( typelib_TypeDescriptionReference * type )
|
|
{
|
|
return ((typelib_TypeClass_INTERFACE == type->eTypeClass) &&
|
|
::rtl::OUString::unacquired( &type->pTypeName ).equalsAsciiL(
|
|
RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ));
|
|
}
|
|
|
|
//==============================================================================
|
|
struct JNI_type_info
|
|
{
|
|
::com::sun::star::uno::TypeDescription m_td;
|
|
jclass m_class;
|
|
|
|
virtual void destroy( JNIEnv * jni_env ) = 0;
|
|
protected:
|
|
inline void destruct( JNIEnv * jni_env )
|
|
{ jni_env->DeleteGlobalRef( m_class ); }
|
|
virtual inline ~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
|
|
jmethodID * m_methods;
|
|
|
|
virtual void destroy( JNIEnv * jni_env );
|
|
explicit JNI_interface_type_info(
|
|
JNI_context const & jni, typelib_TypeDescription * td );
|
|
};
|
|
|
|
//==============================================================================
|
|
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
|
|
jfieldID * m_fields;
|
|
|
|
virtual void destroy( JNIEnv * jni_env );
|
|
explicit JNI_compound_type_info(
|
|
JNI_context const & jni, typelib_TypeDescription * td );
|
|
};
|
|
|
|
//==============================================================================
|
|
struct JNI_type_info_holder
|
|
{
|
|
JNI_type_info * m_info;
|
|
inline JNI_type_info_holder()
|
|
: m_info( 0 )
|
|
{}
|
|
};
|
|
|
|
typedef ::boost::unordered_map<
|
|
::rtl::OUString, JNI_type_info_holder, ::rtl::OUStringHash > 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;
|
|
|
|
//
|
|
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;
|
|
|
|
//
|
|
::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;
|
|
|
|
//
|
|
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,
|
|
::rtl::OUString const & uno_name ) const;
|
|
//
|
|
inline static void append_sig(
|
|
::rtl::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 );
|
|
inline ~JNI_info() {}
|
|
};
|
|
|
|
//______________________________________________________________________________
|
|
inline void JNI_info::destroy( JNIEnv * jni_env )
|
|
{
|
|
destruct( jni_env );
|
|
delete this;
|
|
}
|
|
|
|
//______________________________________________________________________________
|
|
inline void JNI_info::append_sig(
|
|
::rtl::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( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/String;") );
|
|
} else {
|
|
buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava.lang.String;") );
|
|
}
|
|
break;
|
|
case typelib_TypeClass_TYPE:
|
|
if ( use_slashes ) {
|
|
buf->append(
|
|
RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Type;") );
|
|
} else {
|
|
buf->append(
|
|
RTL_CONSTASCII_STRINGPARAM("Lcom.sun.star.uno.Type;") );
|
|
}
|
|
break;
|
|
case typelib_TypeClass_ANY:
|
|
if ( use_slashes ) {
|
|
buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;") );
|
|
} else {
|
|
buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava.lang.Object;") );
|
|
}
|
|
break;
|
|
case typelib_TypeClass_ENUM:
|
|
case typelib_TypeClass_STRUCT:
|
|
case typelib_TypeClass_EXCEPTION:
|
|
{
|
|
::rtl::OUString const & uno_name =
|
|
::rtl::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(
|
|
::rtl::OUStringToOString(
|
|
use_slashes ? uno_name.replace( '.', '/' ) : uno_name,
|
|
RTL_TEXTENCODING_JAVA_UTF8 ) );
|
|
} else {
|
|
rtl::OUString s( uno_name.copy( 0, i ) );
|
|
buf->append(
|
|
::rtl::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, ((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( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;") );
|
|
} else {
|
|
buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava.lang.Object;") );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
::rtl::OUString const & uno_name =
|
|
::rtl::OUString::unacquired( &type->pTypeName );
|
|
buf->append( 'L' );
|
|
buf->append(
|
|
::rtl::OUStringToOString(
|
|
use_slashes ? uno_name.replace( '.', '/' ) : uno_name,
|
|
RTL_TEXTENCODING_JAVA_UTF8 ) );
|
|
buf->append( ';' );
|
|
}
|
|
break;
|
|
default:
|
|
throw BridgeRuntimeError(
|
|
OUSTR("unsupported type: ") +
|
|
::rtl::OUString::unacquired( &type->pTypeName ) );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|