summaryrefslogtreecommitdiff
path: root/bridges/source/jni_uno
diff options
context:
space:
mode:
Diffstat (limited to 'bridges/source/jni_uno')
-rw-r--r--bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java52
-rw-r--r--bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java218
-rw-r--r--bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk53
-rw-r--r--bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/manifest1
-rw-r--r--bridges/source/jni_uno/java_uno.map27
-rw-r--r--bridges/source/jni_uno/jni_base.h292
-rw-r--r--bridges/source/jni_uno/jni_bridge.cxx569
-rw-r--r--bridges/source/jni_uno/jni_bridge.h124
-rw-r--r--bridges/source/jni_uno/jni_data.cxx2576
-rw-r--r--bridges/source/jni_uno/jni_helper.h162
-rw-r--r--bridges/source/jni_uno/jni_info.cxx996
-rw-r--r--bridges/source/jni_uno/jni_info.h375
-rw-r--r--bridges/source/jni_uno/jni_java2uno.cxx704
-rw-r--r--bridges/source/jni_uno/jni_uno2java.cxx873
-rw-r--r--bridges/source/jni_uno/makefile.mk85
-rw-r--r--bridges/source/jni_uno/nativethreadpool.cxx230
16 files changed, 7337 insertions, 0 deletions
diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java
new file mode 100644
index 000000000000..223b53a7013f
--- /dev/null
+++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.bridges.jni_uno;
+
+import com.sun.star.lib.util.NativeLibraryLoader;
+
+//==============================================================================
+public final class JNI_info_holder
+{
+ static {
+ NativeLibraryLoader.loadLibrary(JNI_info_holder.class.getClassLoader(),
+ "java_uno");
+ }
+
+ private static JNI_info_holder s_holder = new JNI_info_holder();
+
+ private static long s_jni_info_handle;
+
+ //__________________________________________________________________________
+ private native void finalize( long jni_info_handle );
+
+ //__________________________________________________________________________
+ protected void finalize()
+ {
+ finalize( s_jni_info_handle );
+ }
+}
diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java
new file mode 100644
index 000000000000..076d568e9c91
--- /dev/null
+++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java
@@ -0,0 +1,218 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.bridges.jni_uno;
+
+import com.sun.star.lib.util.AsynchronousFinalizer;
+import com.sun.star.lib.util.NativeLibraryLoader;
+import com.sun.star.uno.Type;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.IEnvironment;
+import com.sun.star.uno.IQueryInterface;
+
+
+//==============================================================================
+public final class JNI_proxy implements java.lang.reflect.InvocationHandler
+{
+ static {
+ NativeLibraryLoader.loadLibrary(JNI_proxy.class.getClassLoader(),
+ "java_uno");
+ }
+ protected static ClassLoader s_classloader =
+ JNI_proxy.class.getClassLoader();
+ protected static Class s_InvocationHandler [] =
+ new Class [] { java.lang.reflect.InvocationHandler.class };
+
+ protected long m_bridge_handle;
+ protected IEnvironment m_java_env;
+ protected long m_receiver_handle;
+ protected long m_td_handle;
+ protected Type m_type;
+ protected String m_oid;
+ protected Class m_class;
+
+ //__________________________________________________________________________
+ public static String get_stack_trace( Throwable throwable )
+ throws Throwable
+ {
+ boolean current_trace = false;
+ if (null == throwable)
+ {
+ throwable = new Throwable();
+ current_trace = true;
+ }
+ java.io.StringWriter string_writer =
+ new java.io.StringWriter();
+ java.io.PrintWriter print_writer =
+ new java.io.PrintWriter( string_writer, true );
+ throwable.printStackTrace( print_writer );
+ print_writer.flush();
+ print_writer.close();
+ string_writer.flush();
+ String trace = string_writer.toString();
+ if (current_trace)
+ {
+ // cut out first two lines
+ int n = trace.indexOf( '\n' );
+ n = trace.indexOf( '\n', n +1 );
+ trace = trace.substring( n +1 );
+ }
+ return "\njava stack trace:\n" + trace;
+ }
+
+ //__________________________________________________________________________
+ private native void finalize( long bridge_handle );
+
+ //__________________________________________________________________________
+ public void finalize()
+ {
+ AsynchronousFinalizer.add(new AsynchronousFinalizer.Job() {
+ public void run() throws Throwable {
+ JNI_proxy.this.finalize( m_bridge_handle );
+ }
+ });
+ }
+
+ //__________________________________________________________________________
+ private JNI_proxy(
+ long bridge_handle, IEnvironment java_env,
+ long receiver_handle, long td_handle, Type type, String oid )
+ {
+ m_bridge_handle = bridge_handle;
+ m_java_env = java_env;
+ m_receiver_handle = receiver_handle;
+ m_td_handle = td_handle;
+ m_type = type;
+ m_oid = oid;
+ m_class = m_type.getZClass();
+ }
+
+ //__________________________________________________________________________
+ public static Object create(
+ long bridge_handle, IEnvironment java_env,
+ long receiver_handle, long td_handle, Type type, String oid,
+ java.lang.reflect.Constructor proxy_ctor )
+ throws Throwable
+ {
+ JNI_proxy handler = new JNI_proxy(
+ bridge_handle, java_env, receiver_handle, td_handle, type, oid );
+ Object proxy = proxy_ctor.newInstance( new Object [] { handler } );
+ return java_env.registerInterface( proxy, new String [] { oid }, type );
+ }
+
+ //__________________________________________________________________________
+ public static java.lang.reflect.Constructor get_proxy_ctor( Class clazz )
+ throws Throwable
+ {
+ Class proxy_class = java.lang.reflect.Proxy.getProxyClass(
+ s_classloader,
+ new Class [] { clazz, IQueryInterface.class,
+ com.sun.star.lib.uno.Proxy.class } );
+ return proxy_class.getConstructor( s_InvocationHandler );
+ }
+
+ //__________________________________________________________________________
+ private native Object dispatch_call(
+ long bridge_handle, String decl_class, String method, Object args [] )
+ throws Throwable;
+
+ // InvocationHandler impl
+ //__________________________________________________________________________
+ public Object invoke(
+ Object proxy, java.lang.reflect.Method method, Object args [] )
+ throws Throwable
+ {
+ Class decl_class = method.getDeclaringClass();
+ String method_name = method.getName();
+
+ if (Object.class.equals( decl_class ))
+ {
+ if (method_name.equals( "hashCode" ))
+ {
+ // int hashCode()
+ return new Integer( m_oid.hashCode() );
+ }
+ else if (method_name.equals( "equals" ))
+ {
+ // boolean equals( Object obj )
+ return isSame(args[0]);
+ }
+ else if (method_name.equals( "toString" ))
+ {
+ // String toString()
+ return this.toString() + " [oid=" + m_oid +
+ ", type=" + m_type.getTypeName() + "]";
+ }
+ }
+ // UNO interface call
+ else if (decl_class.isAssignableFrom( m_class ))
+ {
+ // dispatch interface call
+ return dispatch_call(
+ m_bridge_handle, decl_class.getName(), method_name, args );
+ }
+ // IQueryInterface impl
+ else if (IQueryInterface.class.equals( decl_class ))
+ {
+ if (method_name.equals( "queryInterface" ))
+ {
+ // Object queryInterface( Type type )
+ Object registered_proxy =
+ m_java_env.getRegisteredInterface( m_oid, (Type)args[ 0 ] );
+ if (null == registered_proxy)
+ {
+ return dispatch_call(
+ m_bridge_handle,
+ "com.sun.star.uno.XInterface", method_name, args );
+ }
+ else
+ {
+ return registered_proxy;
+ }
+ }
+ else if (method_name.equals( "isSame" ))
+ {
+ // boolean isSame( Object object )
+ return isSame(args[0]);
+ }
+ else if (method_name.equals( "getOid" ))
+ {
+ // String getOid()
+ return m_oid;
+ }
+ }
+
+ throw new com.sun.star.uno.RuntimeException(
+ "[jni_uno bridge error] unexpected call on proxy " +
+ proxy.toString() + ": " + method.toString() );
+ }
+
+ private Boolean isSame(Object obj) {
+ return new Boolean(obj != null
+ && m_oid.equals(UnoRuntime.generateOid(obj)));
+ }
+}
diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk
new file mode 100644
index 000000000000..5d3eb9fea1f5
--- /dev/null
+++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+PRJ=..$/..$/..$/..$/..$/..$/..$/..
+
+PRJNAME=bridges
+TARGET=java_uno
+PACKAGE=com$/sun$/star$/bridges$/jni_uno
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+JARFILES=jurt.jar ridl.jar
+JAVAFILES=$(subst,$(CLASSDIR)$/$(PACKAGE)$/, $(subst,.class,.java $(JAVACLASSFILES)))
+
+JAVACLASSFILES= \
+ $(CLASSDIR)$/$(PACKAGE)$/JNI_proxy.class \
+ $(CLASSDIR)$/$(PACKAGE)$/JNI_info_holder.class
+
+JARCLASSDIRS=$(PACKAGE)
+JARTARGET=$(TARGET).jar
+JARCOMPRESS=TRUE
+JARCLASSPATH = $(JARFILES) ../../lib/ ../bin/
+CUSTOMMANIFESTFILE = manifest
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/manifest b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/manifest
new file mode 100644
index 000000000000..7ad02e156d9a
--- /dev/null
+++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/manifest
@@ -0,0 +1 @@
+Sealed: true
diff --git a/bridges/source/jni_uno/java_uno.map b/bridges/source/jni_uno/java_uno.map
new file mode 100644
index 000000000000..376f7ea979bb
--- /dev/null
+++ b/bridges/source/jni_uno/java_uno.map
@@ -0,0 +1,27 @@
+UDK_3_0_0 {
+ global:
+ uno_initEnvironment;
+ uno_ext_getMapping;
+ component_canUnload;
+ local:
+ *;
+};
+
+UDK_3.1 {
+ global:
+ Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J;
+ Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call;
+ Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J;
+} UDK_3_0_0;
+
+UDK_3.2 {
+ global:
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_attach;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_create;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_destroy;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_detach;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_dispose;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_enter;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_threadId;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_putJob;
+} UDK_3.1;
diff --git a/bridges/source/jni_uno/jni_base.h b/bridges/source/jni_uno/jni_base.h
new file mode 100644
index 000000000000..2a1ad425db12
--- /dev/null
+++ b/bridges/source/jni_uno/jni_base.h
@@ -0,0 +1,292 @@
+/*************************************************************************
+ *
+ * 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_BASE_H
+#define INCLUDED_JNI_BASE_H
+
+#if defined (__SUNPRO_CC) || defined (__SUNPRO_C)
+// workaround solaris include trouble on jumbo
+#include <stdarg.h>
+namespace std
+{
+typedef __va_list va_list;
+}
+#endif
+#include <memory>
+
+#include "jvmaccess/unovirtualmachine.hxx"
+#include "jvmaccess/virtualmachine.hxx"
+
+#include "osl/diagnose.h"
+
+#include "rtl/alloc.h"
+#include "rtl/ustring.hxx"
+
+#include "uno/environment.h"
+#include "typelib/typedescription.h"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+
+namespace jni_uno
+{
+
+class JNI_info;
+
+//==============================================================================
+struct BridgeRuntimeError
+{
+ ::rtl::OUString m_message;
+
+ inline BridgeRuntimeError( ::rtl::OUString const & message )
+ : m_message( message )
+ {}
+};
+
+
+//==============================================================================
+class JNI_context
+{
+ JNI_info const * m_jni_info;
+ JNIEnv * m_env;
+ jobject m_class_loader;
+
+ JNI_context( JNI_context & ); // not impl
+ void operator = ( JNI_context ); // not impl
+
+ void java_exc_occured() const;
+public:
+ inline explicit JNI_context(
+ JNI_info const * jni_info, JNIEnv * env, jobject class_loader )
+ : m_jni_info( jni_info ),
+ m_env( env ),
+ m_class_loader( class_loader )
+ {}
+
+ inline JNI_info const * get_info() const
+ { return m_jni_info; }
+
+ inline JNIEnv * operator -> () const
+ { return m_env; }
+ inline JNIEnv * get_jni_env() const
+ { return m_env; }
+
+ // does not handle exceptions, *classClass will be null if exception
+ // occurred:
+ void getClassForName(jclass * classClass, jmethodID * methodForName) const;
+
+ // if inException, does not handle exceptions, in which case returned value
+ // will be null if exception occurred:
+ jclass findClass(
+ char const * name, jclass classClass, jmethodID methodForName,
+ bool inException) const;
+
+ inline void ensure_no_exception() const; // throws BridgeRuntimeError
+ inline bool assert_no_exception() const; // asserts and clears exception
+
+ ::rtl::OUString get_stack_trace( jobject jo_exc = 0 ) const;
+};
+
+//______________________________________________________________________________
+inline void JNI_context::ensure_no_exception() const
+{
+ if (JNI_FALSE != m_env->ExceptionCheck())
+ {
+ java_exc_occured();
+ }
+}
+
+//______________________________________________________________________________
+inline bool JNI_context::assert_no_exception() const
+{
+ if (JNI_FALSE != m_env->ExceptionCheck())
+ {
+ m_env->ExceptionClear();
+ OSL_ENSURE( 0, "unexpected java exception occured!" );
+ return false;
+ }
+ return true;
+}
+
+
+//==============================================================================
+class JNI_guarded_context
+ : private ::jvmaccess::VirtualMachine::AttachGuard,
+ public JNI_context
+{
+ JNI_guarded_context( JNI_guarded_context & ); // not impl
+ void operator = ( JNI_guarded_context ); // not impl
+
+public:
+ inline explicit JNI_guarded_context(
+ JNI_info const * jni_info, ::jvmaccess::UnoVirtualMachine * vm_access )
+ : AttachGuard( vm_access->getVirtualMachine() ),
+ JNI_context(
+ jni_info, AttachGuard::getEnvironment(),
+ static_cast< jobject >(vm_access->getClassLoader()) )
+ {}
+};
+
+
+//==============================================================================
+class JLocalAutoRef
+{
+ JNI_context const & m_jni;
+ jobject m_jo;
+
+public:
+ inline JLocalAutoRef( JNI_context const & jni )
+ : m_jni( jni ),
+ m_jo( 0 )
+ {}
+ inline explicit JLocalAutoRef( JNI_context const & jni, jobject jo )
+ : m_jni( jni ),
+ m_jo( jo )
+ {}
+ inline JLocalAutoRef( JLocalAutoRef & auto_ref );
+ inline ~JLocalAutoRef() SAL_THROW( () );
+
+ inline jobject get() const
+ { return m_jo; }
+ inline bool is() const
+ { return (0 != m_jo); }
+ inline jobject release();
+ inline void reset();
+ inline void reset( jobject jo );
+ inline JLocalAutoRef & operator = ( JLocalAutoRef & auto_ref );
+};
+
+//______________________________________________________________________________
+inline JLocalAutoRef::~JLocalAutoRef() SAL_THROW( () )
+{
+ if (0 != m_jo)
+ m_jni->DeleteLocalRef( m_jo );
+}
+
+//______________________________________________________________________________
+inline JLocalAutoRef::JLocalAutoRef( JLocalAutoRef & auto_ref )
+ : m_jni( auto_ref.m_jni ),
+ m_jo( auto_ref.m_jo )
+{
+ auto_ref.m_jo = 0;
+}
+
+//______________________________________________________________________________
+inline jobject JLocalAutoRef::release()
+{
+ jobject jo = m_jo;
+ m_jo = 0;
+ return jo;
+}
+
+//______________________________________________________________________________
+inline void JLocalAutoRef::reset()
+{
+ if (0 != m_jo)
+ m_jni->DeleteLocalRef( m_jo );
+ m_jo = 0;
+}
+
+//______________________________________________________________________________
+inline void JLocalAutoRef::reset( jobject jo )
+{
+ if (jo != m_jo)
+ {
+ if (0 != m_jo)
+ m_jni->DeleteLocalRef( m_jo );
+ m_jo = jo;
+ }
+}
+
+//______________________________________________________________________________
+inline JLocalAutoRef & JLocalAutoRef::operator = ( JLocalAutoRef & auto_ref )
+{
+ OSL_ASSERT( m_jni.get_jni_env() == auto_ref.m_jni.get_jni_env() );
+ reset( auto_ref.m_jo );
+ auto_ref.m_jo = 0;
+ return *this;
+}
+
+
+//==============================================================================
+struct rtl_mem
+{
+ inline static void * operator new ( size_t nSize )
+ { return rtl_allocateMemory( nSize ); }
+ inline static void operator delete ( void * mem )
+ { if (mem) rtl_freeMemory( mem ); }
+ inline static void * operator new ( size_t, void * mem )
+ { return mem; }
+ inline static void operator delete ( void *, void * )
+ {}
+
+ static inline ::std::auto_ptr< rtl_mem > allocate( ::std::size_t bytes );
+};
+
+//______________________________________________________________________________
+inline ::std::auto_ptr< rtl_mem > rtl_mem::allocate( ::std::size_t bytes )
+{
+ void * p = rtl_allocateMemory( bytes );
+ if (0 == p)
+ throw BridgeRuntimeError( OUSTR("out of memory!") );
+ return ::std::auto_ptr< rtl_mem >( (rtl_mem *)p );
+}
+
+
+//==============================================================================
+class TypeDescr
+{
+ typelib_TypeDescription * m_td;
+
+ TypeDescr( TypeDescr & ); // not impl
+ void operator = ( TypeDescr ); // not impl
+
+public:
+ inline explicit TypeDescr( typelib_TypeDescriptionReference * td_ref );
+ inline ~TypeDescr() SAL_THROW( () )
+ { TYPELIB_DANGER_RELEASE( m_td ); }
+
+ inline typelib_TypeDescription * get() const
+ { return m_td; }
+};
+
+//______________________________________________________________________________
+inline TypeDescr::TypeDescr( typelib_TypeDescriptionReference * td_ref )
+ : m_td( 0 )
+{
+ TYPELIB_DANGER_GET( &m_td, td_ref );
+ if (0 == m_td)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("cannot get comprehensive type description for ") +
+ ::rtl::OUString::unacquired( &td_ref->pTypeName ) );
+ }
+}
+
+}
+
+#endif
diff --git a/bridges/source/jni_uno/jni_bridge.cxx b/bridges/source/jni_uno/jni_bridge.cxx
new file mode 100644
index 000000000000..e9c1270b1f9b
--- /dev/null
+++ b/bridges/source/jni_uno/jni_bridge.cxx
@@ -0,0 +1,569 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "jni_bridge.h"
+
+#include "jvmaccess/unovirtualmachine.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/unload.h"
+#include "rtl/strbuf.hxx"
+#include "uno/lbnames.h"
+
+
+using namespace ::std;
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::jni_uno;
+
+namespace
+{
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+void SAL_CALL Mapping_acquire( uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ Mapping const * that = static_cast< Mapping const * >( mapping );
+ that->m_bridge->acquire();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL Mapping_release( uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ Mapping const * that = static_cast< Mapping const * >( mapping );
+ that->m_bridge->release();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL Mapping_map_to_uno(
+ uno_Mapping * mapping, void ** ppOut,
+ void * pIn, typelib_InterfaceTypeDescription * td )
+ SAL_THROW_EXTERN_C()
+{
+ uno_Interface ** ppUnoI = (uno_Interface **)ppOut;
+ jobject javaI = (jobject) pIn;
+
+ OSL_ASSERT( sizeof (void *) == sizeof (jobject) );
+ OSL_ENSURE( ppUnoI && td, "### null ptr!" );
+
+ if (0 == javaI)
+ {
+ if (0 != *ppUnoI)
+ {
+ uno_Interface * p = *(uno_Interface **)ppUnoI;
+ (*p->release)( p );
+ *ppUnoI = 0;
+ }
+ }
+ else
+ {
+ try
+ {
+ Bridge const * bridge =
+ static_cast< Mapping const * >( mapping )->m_bridge;
+ JNI_guarded_context jni(
+ bridge->m_jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+
+ JNI_interface_type_info const * info =
+ static_cast< JNI_interface_type_info const * >(
+ bridge->m_jni_info->get_type_info(
+ jni, (typelib_TypeDescription *)td ) );
+ uno_Interface * pUnoI = bridge->map_to_uno( jni, javaI, info );
+ if (0 != *ppUnoI)
+ {
+ uno_Interface * p = *(uno_Interface **)ppUnoI;
+ (*p->release)( p );
+ }
+ *ppUnoI = pUnoI;
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("[jni_uno bridge error] ") + err.m_message,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+#else
+ (void) err; // unused
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(
+ 0,
+ "[jni_uno bridge error] attaching current thread "
+ "to java failed!" );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL Mapping_map_to_java(
+ uno_Mapping * mapping, void ** ppOut,
+ void * pIn, typelib_InterfaceTypeDescription * td )
+ SAL_THROW_EXTERN_C()
+{
+ jobject * ppJavaI = (jobject *) ppOut;
+ uno_Interface * pUnoI = (uno_Interface *)pIn;
+
+ OSL_ASSERT( sizeof (void *) == sizeof (jobject) );
+ OSL_ENSURE( ppJavaI && td, "### null ptr!" );
+
+ try
+ {
+ if (0 == pUnoI)
+ {
+ if (0 != *ppJavaI)
+ {
+ Bridge const * bridge =
+ static_cast< Mapping const * >( mapping )->m_bridge;
+ JNI_guarded_context jni(
+ bridge->m_jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+ jni->DeleteGlobalRef( *ppJavaI );
+ *ppJavaI = 0;
+ }
+ }
+ else
+ {
+ Bridge const * bridge =
+ static_cast< Mapping const * >( mapping )->m_bridge;
+ JNI_guarded_context jni(
+ bridge->m_jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+
+ JNI_interface_type_info const * info =
+ static_cast< JNI_interface_type_info const * >(
+ bridge->m_jni_info->get_type_info(
+ jni, (typelib_TypeDescription *)td ) );
+ jobject jlocal = bridge->map_to_java( jni, pUnoI, info );
+ if (0 != *ppJavaI)
+ jni->DeleteGlobalRef( *ppJavaI );
+ *ppJavaI = jni->NewGlobalRef( jlocal );
+ jni->DeleteLocalRef( jlocal );
+ }
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("[jni_uno bridge error] ") + err.m_message,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+#else
+ (void) err; // unused
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(
+ 0,
+ "[jni_uno bridge error] attaching current thread to java failed!" );
+ }
+}
+
+//______________________________________________________________________________
+void SAL_CALL Bridge_free( uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ Mapping * that = static_cast< Mapping * >( mapping );
+ delete that->m_bridge;
+}
+
+}
+
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+}
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+void Bridge::acquire() const SAL_THROW( () )
+{
+ if (1 == osl_incrementInterlockedCount( &m_ref ))
+ {
+ if (m_registered_java2uno)
+ {
+ uno_Mapping * mapping = const_cast< Mapping * >( &m_java2uno );
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ m_java_env, (uno_Environment *)m_uno_env, 0 );
+ }
+ else
+ {
+ uno_Mapping * mapping = const_cast< Mapping * >( &m_uno2java );
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ (uno_Environment *)m_uno_env, m_java_env, 0 );
+ }
+ }
+}
+
+//______________________________________________________________________________
+void Bridge::release() const SAL_THROW( () )
+{
+ if (! osl_decrementInterlockedCount( &m_ref ))
+ {
+ uno_revokeMapping(
+ m_registered_java2uno
+ ? const_cast< Mapping * >( &m_java2uno )
+ : const_cast< Mapping * >( &m_uno2java ) );
+ }
+}
+
+//______________________________________________________________________________
+Bridge::Bridge(
+ uno_Environment * java_env, uno_ExtEnvironment * uno_env,
+ bool registered_java2uno )
+ : m_ref( 1 ),
+ m_uno_env( uno_env ),
+ m_java_env( java_env ),
+ m_registered_java2uno( registered_java2uno )
+{
+ // bootstrapping bridge jni_info
+ m_jni_info = JNI_info::get_jni_info(
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ m_java_env->pContext ) );
+
+ OSL_ASSERT( 0 != m_java_env && 0 != m_uno_env );
+ (*((uno_Environment *)m_uno_env)->acquire)( (uno_Environment *)m_uno_env );
+ (*m_java_env->acquire)( m_java_env );
+
+ // java2uno
+ m_java2uno.acquire = Mapping_acquire;
+ m_java2uno.release = Mapping_release;
+ m_java2uno.mapInterface = Mapping_map_to_uno;
+ m_java2uno.m_bridge = this;
+ // uno2java
+ m_uno2java.acquire = Mapping_acquire;
+ m_uno2java.release = Mapping_release;
+ m_uno2java.mapInterface = Mapping_map_to_java;
+ m_uno2java.m_bridge = this;
+
+ (*g_moduleCount.modCnt.acquire)( &g_moduleCount.modCnt );
+}
+
+//______________________________________________________________________________
+Bridge::~Bridge() SAL_THROW( () )
+{
+ (*m_java_env->release)( m_java_env );
+ (*((uno_Environment *)m_uno_env)->release)( (uno_Environment *)m_uno_env );
+
+ (*g_moduleCount.modCnt.release)( &g_moduleCount.modCnt );
+}
+
+
+//______________________________________________________________________________
+void JNI_context::java_exc_occured() const
+{
+ // !don't rely on JNI_info!
+
+ JLocalAutoRef jo_exc( *this, m_env->ExceptionOccurred() );
+ m_env->ExceptionClear();
+ OSL_ASSERT( jo_exc.is() );
+ if (! jo_exc.is())
+ {
+ throw BridgeRuntimeError(
+ OUSTR("java exception occured, but not available!?") +
+ get_stack_trace() );
+ }
+
+ // call toString(); don't rely on m_jni_info
+ jclass jo_class = m_env->FindClass( "java/lang/Object" );
+ if (JNI_FALSE != m_env->ExceptionCheck())
+ {
+ m_env->ExceptionClear();
+ throw BridgeRuntimeError(
+ OUSTR("cannot get class java.lang.Object!") + get_stack_trace() );
+ }
+ JLocalAutoRef jo_Object( *this, jo_class );
+ // method Object.toString()
+ jmethodID method_Object_toString = m_env->GetMethodID(
+ (jclass) jo_Object.get(), "toString", "()Ljava/lang/String;" );
+ if (JNI_FALSE != m_env->ExceptionCheck())
+ {
+ m_env->ExceptionClear();
+ throw BridgeRuntimeError(
+ OUSTR("cannot get method id of java.lang.Object.toString()!") +
+ get_stack_trace() );
+ }
+ OSL_ASSERT( 0 != method_Object_toString );
+
+ JLocalAutoRef jo_descr(
+ *this, m_env->CallObjectMethodA(
+ jo_exc.get(), method_Object_toString, 0 ) );
+ if (m_env->ExceptionCheck()) // no chance at all
+ {
+ m_env->ExceptionClear();
+ throw BridgeRuntimeError(
+ OUSTR("error examining java exception object!") +
+ get_stack_trace() );
+ }
+
+ jsize len = m_env->GetStringLength( (jstring) jo_descr.get() );
+ auto_ptr< rtl_mem > ustr_mem(
+ rtl_mem::allocate(
+ sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) );
+ rtl_uString * ustr = (rtl_uString *)ustr_mem.get();
+ m_env->GetStringRegion( (jstring) jo_descr.get(), 0, len, ustr->buffer );
+ if (m_env->ExceptionCheck())
+ {
+ m_env->ExceptionClear();
+ throw BridgeRuntimeError(
+ OUSTR("invalid java string object!") + get_stack_trace() );
+ }
+ ustr->refCount = 1;
+ ustr->length = len;
+ ustr->buffer[ len ] = '\0';
+ OUString message( (rtl_uString *)ustr_mem.release(), SAL_NO_ACQUIRE );
+
+ throw BridgeRuntimeError( message + get_stack_trace( jo_exc.get() ) );
+}
+
+//______________________________________________________________________________
+void JNI_context::getClassForName(
+ jclass * classClass, jmethodID * methodForName) const
+{
+ jclass c = m_env->FindClass("java/lang/Class");
+ if (c != 0) {
+ *methodForName = m_env->GetStaticMethodID(
+ c, "forName",
+ "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
+ }
+ *classClass = c;
+}
+
+//______________________________________________________________________________
+jclass JNI_context::findClass(
+ char const * name, jclass classClass, jmethodID methodForName,
+ bool inException) const
+{
+ jclass c = 0;
+ JLocalAutoRef s(*this, m_env->NewStringUTF(name));
+ if (s.is()) {
+ jvalue a[3];
+ a[0].l = s.get();
+ a[1].z = JNI_FALSE;
+ a[2].l = m_class_loader;
+ c = static_cast< jclass >(
+ m_env->CallStaticObjectMethodA(classClass, methodForName, a));
+ }
+ if (!inException) {
+ ensure_no_exception();
+ }
+ return c;
+}
+
+//______________________________________________________________________________
+OUString JNI_context::get_stack_trace( jobject jo_exc ) const
+{
+ JLocalAutoRef jo_JNI_proxy(
+ *this,
+ find_class( *this, "com.sun.star.bridges.jni_uno.JNI_proxy", true ) );
+ if (assert_no_exception())
+ {
+ // static method JNI_proxy.get_stack_trace()
+ jmethodID method = m_env->GetStaticMethodID(
+ (jclass) jo_JNI_proxy.get(), "get_stack_trace",
+ "(Ljava/lang/Throwable;)Ljava/lang/String;" );
+ if (assert_no_exception() && (0 != method))
+ {
+ jvalue arg;
+ arg.l = jo_exc;
+ JLocalAutoRef jo_stack_trace(
+ *this, m_env->CallStaticObjectMethodA(
+ (jclass) jo_JNI_proxy.get(), method, &arg ) );
+ if (assert_no_exception())
+ {
+ jsize len =
+ m_env->GetStringLength( (jstring) jo_stack_trace.get() );
+ auto_ptr< rtl_mem > ustr_mem(
+ rtl_mem::allocate(
+ sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) );
+ rtl_uString * ustr = (rtl_uString *)ustr_mem.get();
+ m_env->GetStringRegion(
+ (jstring) jo_stack_trace.get(), 0, len, ustr->buffer );
+ if (assert_no_exception())
+ {
+ ustr->refCount = 1;
+ ustr->length = len;
+ ustr->buffer[ len ] = '\0';
+ return OUString(
+ (rtl_uString *)ustr_mem.release(), SAL_NO_ACQUIRE );
+ }
+ }
+ }
+ }
+ return OUString();
+}
+
+}
+
+using namespace ::jni_uno;
+
+extern "C"
+{
+namespace
+{
+
+//------------------------------------------------------------------------------
+void SAL_CALL java_env_disposing( uno_Environment * java_env )
+ SAL_THROW_EXTERN_C()
+{
+ ::jvmaccess::UnoVirtualMachine * machine =
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ java_env->pContext );
+ java_env->pContext = 0;
+ machine->release();
+}
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL uno_initEnvironment( uno_Environment * java_env )
+ SAL_THROW_EXTERN_C()
+{
+ java_env->environmentDisposing = java_env_disposing;
+ java_env->pExtEnv = 0; // no extended support
+ OSL_ASSERT( 0 != java_env->pContext );
+
+ ::jvmaccess::UnoVirtualMachine * machine =
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ java_env->pContext );
+ machine->acquire();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL uno_ext_getMapping(
+ uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ASSERT( 0 != ppMapping && 0 != pFrom && 0 != pTo );
+ if (0 != *ppMapping)
+ {
+ (*(*ppMapping)->release)( *ppMapping );
+ *ppMapping = 0;
+ }
+
+ OSL_ASSERT( JNI_FALSE == sal_False );
+ OSL_ASSERT( JNI_TRUE == sal_True );
+ OSL_ASSERT( sizeof (jboolean) == sizeof (sal_Bool) );
+ OSL_ASSERT( sizeof (jchar) == sizeof (sal_Unicode) );
+ OSL_ASSERT( sizeof (jdouble) == sizeof (double) );
+ OSL_ASSERT( sizeof (jfloat) == sizeof (float) );
+ OSL_ASSERT( sizeof (jbyte) == sizeof (sal_Int8) );
+ OSL_ASSERT( sizeof (jshort) == sizeof (sal_Int16) );
+ OSL_ASSERT( sizeof (jint) == sizeof (sal_Int32) );
+ OSL_ASSERT( sizeof (jlong) == sizeof (sal_Int64) );
+ if ((JNI_FALSE == sal_False) &&
+ (JNI_TRUE == sal_True) &&
+ (sizeof (jboolean) == sizeof (sal_Bool)) &&
+ (sizeof (jchar) == sizeof (sal_Unicode)) &&
+ (sizeof (jdouble) == sizeof (double)) &&
+ (sizeof (jfloat) == sizeof (float)) &&
+ (sizeof (jbyte) == sizeof (sal_Int8)) &&
+ (sizeof (jshort) == sizeof (sal_Int16)) &&
+ (sizeof (jint) == sizeof (sal_Int32)) &&
+ (sizeof (jlong) == sizeof (sal_Int64)))
+ {
+ OUString const & from_env_typename =
+ OUString::unacquired( &pFrom->pTypeName );
+ OUString const & to_env_typename =
+ OUString::unacquired( &pTo->pTypeName );
+
+ uno_Mapping * mapping = 0;
+
+ try
+ {
+ if (from_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(UNO_LB_JAVA) ) &&
+ to_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ))
+ {
+ Bridge * bridge =
+ new Bridge( pFrom, pTo->pExtEnv, true ); // ref count = 1
+ mapping = &bridge->m_java2uno;
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ pFrom, (uno_Environment *)pTo->pExtEnv, 0 );
+ }
+ else if (from_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ) &&
+ to_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(UNO_LB_JAVA) ))
+ {
+ Bridge * bridge =
+ new Bridge( pTo, pFrom->pExtEnv, false ); // ref count = 1
+ mapping = &bridge->m_uno2java;
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ (uno_Environment *)pFrom->pExtEnv, pTo, 0 );
+ }
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("[jni_uno bridge error] ") + err.m_message,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+#else
+ (void) err; // unused
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(
+ 0,
+ "[jni_uno bridge error] attaching current thread "
+ "to java failed!" );
+ }
+
+ *ppMapping = mapping;
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL component_canUnload( TimeValue * pTime )
+ SAL_THROW_EXTERN_C()
+{
+ return (*g_moduleCount.canUnload)( &g_moduleCount, pTime );
+}
+}
diff --git a/bridges/source/jni_uno/jni_bridge.h b/bridges/source/jni_uno/jni_bridge.h
new file mode 100644
index 000000000000..464d181e0a9f
--- /dev/null
+++ b/bridges/source/jni_uno/jni_bridge.h
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * 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_BRIDGE_H
+#define INCLUDED_JNI_BRIDGE_H
+
+#include "jni_base.h"
+#include "jni_info.h"
+#include "jni_helper.h"
+
+#include "osl/diagnose.h"
+#include "osl/interlck.h"
+
+#include "uno/mapping.h"
+#include "uno/dispatcher.h"
+
+#include "com/sun/star/uno/XInterface.hpp"
+
+
+namespace jni_uno
+{
+
+//==== holds environments and mappings =========================================
+struct Bridge;
+struct Mapping : public uno_Mapping
+{
+ Bridge * m_bridge;
+};
+
+//==============================================================================
+struct Bridge
+{
+ mutable oslInterlockedCount m_ref;
+
+ uno_ExtEnvironment * m_uno_env;
+ uno_Environment * m_java_env;
+
+ Mapping m_java2uno;
+ Mapping m_uno2java;
+ bool m_registered_java2uno;
+
+ JNI_info const * m_jni_info;
+
+ //
+ ~Bridge() SAL_THROW( () );
+ explicit Bridge(
+ uno_Environment * java_env, uno_ExtEnvironment * uno_env,
+ bool registered_java2uno );
+
+ void acquire() const;
+ void release() const;
+
+ // jni_data.cxx
+ void map_to_uno(
+ JNI_context const & jni,
+ void * uno_data, jvalue java_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */,
+ bool assign, bool out_param,
+ bool special_wrapped_integral_types = false ) const;
+ void map_to_java(
+ JNI_context const & jni,
+ jvalue * java_data, void const * uno_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */,
+ bool in_param, bool out_param,
+ bool special_wrapped_integral_types = false ) const;
+
+ // jni_uno2java.cxx
+ void handle_uno_exc(
+ JNI_context const & jni, uno_Any * uno_exc ) const;
+ void call_java(
+ jobject javaI,
+ typelib_InterfaceTypeDescription * iface_td,
+ sal_Int32 local_member_index, sal_Int32 function_pos_offset,
+ typelib_TypeDescriptionReference * return_type,
+ typelib_MethodParameter * params, sal_Int32 nParams,
+ void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const;
+ jobject map_to_java(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, JNI_interface_type_info const * info ) const;
+
+ // jni_java2uno.cxx
+ void handle_java_exc(
+ JNI_context const & jni,
+ JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) const;
+ jobject call_uno(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, typelib_TypeDescription * member_td,
+ typelib_TypeDescriptionReference * return_tdref,
+ sal_Int32 nParams, typelib_MethodParameter const * pParams,
+ jobjectArray jo_args ) const;
+ uno_Interface * map_to_uno(
+ JNI_context const & jni,
+ jobject javaI, JNI_interface_type_info const * info ) const;
+};
+
+}
+
+#endif
diff --git a/bridges/source/jni_uno/jni_data.cxx b/bridges/source/jni_uno/jni_data.cxx
new file mode 100644
index 000000000000..0b19a8d99c2d
--- /dev/null
+++ b/bridges/source/jni_uno/jni_data.cxx
@@ -0,0 +1,2576 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "jni_bridge.h"
+
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "uno/sequence2.h"
+
+
+using namespace ::std;
+using namespace ::rtl;
+
+namespace jni_uno
+{
+
+//------------------------------------------------------------------------------
+inline rtl_mem * seq_allocate( sal_Int32 nElements, sal_Int32 nSize )
+{
+ auto_ptr< rtl_mem > seq(
+ rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
+ uno_Sequence * p = (uno_Sequence *)seq.get();
+ p->nRefCount = 1;
+ p->nElements = nElements;
+ return seq.release();
+}
+
+//______________________________________________________________________________
+namespace {
+
+void createDefaultUnoValue(
+ JNI_context const & jni, void * uno_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */, bool assign)
+{
+ switch (type->eTypeClass) {
+ case typelib_TypeClass_BOOLEAN:
+ *static_cast< sal_Bool * >(uno_data) = false;
+ break;
+
+ case typelib_TypeClass_BYTE:
+ *static_cast< sal_Int8 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_SHORT:
+ *static_cast< sal_Int16 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *static_cast< sal_uInt16 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_LONG:
+ *static_cast< sal_Int32 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *static_cast< sal_uInt32 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_HYPER:
+ *static_cast< sal_Int64 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *static_cast< sal_uInt64 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ *static_cast< float * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ *static_cast< double * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_CHAR:
+ *static_cast< sal_Unicode * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_STRING:
+ if (!assign) {
+ *static_cast< rtl_uString ** >(uno_data) = 0;
+ }
+ rtl_uString_new(static_cast< rtl_uString ** >(uno_data));
+ break;
+
+ case typelib_TypeClass_TYPE:
+ if (assign) {
+ typelib_typedescriptionreference_release(
+ *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
+ }
+ *static_cast< typelib_TypeDescriptionReference ** >(uno_data)
+ = *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID);
+ OSL_ASSERT(
+ *static_cast< typelib_TypeDescriptionReference ** >(uno_data) != 0);
+ typelib_typedescriptionreference_acquire(
+ *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
+ break;
+
+ case typelib_TypeClass_ANY:
+ if (assign) {
+ uno_any_destruct(static_cast< uno_Any * >(uno_data), 0);
+ }
+ uno_any_construct(
+ static_cast< uno_Any * >(uno_data), 0,
+ jni.get_info()->m_XInterface_type_info->m_td.get(), 0);
+ break;
+
+ case typelib_TypeClass_SEQUENCE:
+ {
+ auto_ptr< rtl_mem > seq(seq_allocate(0, 0));
+ if (assign) {
+ uno_type_destructData(uno_data, type, 0);
+ }
+ *static_cast< uno_Sequence ** >(uno_data)
+ = reinterpret_cast< uno_Sequence * >(seq.release());
+ break;
+ }
+
+ case typelib_TypeClass_ENUM:
+ {
+ typelib_TypeDescription * td = 0;
+ TYPELIB_DANGER_GET(&td, type);
+ *static_cast< sal_Int32 * >(uno_data)
+ = (reinterpret_cast< typelib_EnumTypeDescription * >(td)->
+ nDefaultEnumValue);
+ TYPELIB_DANGER_RELEASE(td);
+ break;
+ }
+
+ case typelib_TypeClass_STRUCT:
+ {
+ if (info == 0) {
+ info = jni.get_info()->get_type_info(jni, type);
+ }
+ JNI_compound_type_info const * comp_info
+ = static_cast< JNI_compound_type_info const * >(info);
+ typelib_CompoundTypeDescription * comp_td
+ = reinterpret_cast< typelib_CompoundTypeDescription * >(
+ comp_info->m_td.get());
+ sal_Int32 nPos = 0;
+ sal_Int32 nMembers = comp_td->nMembers;
+ try {
+ if (comp_td->pBaseTypeDescription != 0) {
+ createDefaultUnoValue(
+ jni, uno_data,
+ comp_td->pBaseTypeDescription->aBase.pWeakRef,
+ comp_info->m_base, assign);
+ }
+ for (; nPos < nMembers; ++nPos) {
+ createDefaultUnoValue(
+ jni,
+ (static_cast< char * >(uno_data)
+ + comp_td->pMemberOffsets[nPos]),
+ comp_td->ppTypeRefs[nPos], 0, assign);
+ }
+ } catch (...) {
+ if (!assign) {
+ for (sal_Int32 i = 0; i < nPos; ++i) {
+ uno_type_destructData(
+ (static_cast< char * >(uno_data)
+ + comp_td->pMemberOffsets[i]),
+ comp_td->ppTypeRefs[i], 0);
+ }
+ if (comp_td->pBaseTypeDescription != 0) {
+ uno_destructData(
+ uno_data, &comp_td->pBaseTypeDescription->aBase, 0);
+ }
+ }
+ throw;
+ }
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE:
+ if (assign) {
+ uno_Interface * p = *static_cast< uno_Interface ** >(uno_data);
+ if (p != 0) {
+ (*p->release)(p);
+ }
+ }
+ *static_cast< uno_Interface ** >(uno_data) = 0;
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+}
+
+}
+
+void Bridge::map_to_uno(
+ JNI_context const & jni,
+ void * uno_data, jvalue java_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */,
+ bool assign, bool out_param,
+ bool special_wrapped_integral_types ) const
+{
+ OSL_ASSERT(
+ !out_param ||
+ (1 == jni->GetArrayLength( (jarray) java_data.l )) );
+
+ switch (type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (out_param)
+ {
+ jni->GetCharArrayRegion(
+ (jcharArray) java_data.l, 0, 1, (jchar *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jchar *) uno_data = jni->CallCharMethodA(
+ java_data.l, m_jni_info->m_method_Character_charValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jchar *) uno_data = java_data.c;
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (out_param)
+ {
+ jni->GetBooleanArrayRegion(
+ (jbooleanArray) java_data.l, 0, 1, (jboolean *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jboolean *) uno_data = jni->CallBooleanMethodA(
+ java_data.l, m_jni_info->m_method_Boolean_booleanValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jboolean *) uno_data = java_data.z;
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (out_param)
+ {
+ jni->GetByteArrayRegion(
+ (jbyteArray) java_data.l, 0, 1, (jbyte *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jbyte *) uno_data = jni->CallByteMethodA(
+ java_data.l, m_jni_info->m_method_Byte_byteValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jbyte *) uno_data = java_data.b;
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (out_param)
+ {
+ jni->GetShortArrayRegion(
+ (jshortArray) java_data.l, 0, 1, (jshort *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jshort *) uno_data = jni->CallShortMethodA(
+ java_data.l, m_jni_info->m_method_Short_shortValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jshort *) uno_data = java_data.s;
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (out_param)
+ {
+ jni->GetIntArrayRegion(
+ (jintArray) java_data.l, 0, 1, (jint *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jint *) uno_data = jni->CallIntMethodA(
+ java_data.l, m_jni_info->m_method_Integer_intValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jint *) uno_data = java_data.i;
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (out_param)
+ {
+ jni->GetLongArrayRegion(
+ (jlongArray) java_data.l, 0, 1, (jlong *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jlong *) uno_data = jni->CallLongMethodA(
+ java_data.l, m_jni_info->m_method_Long_longValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jlong *) uno_data = java_data.j;
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (out_param)
+ {
+ jni->GetFloatArrayRegion(
+ (jfloatArray) java_data.l, 0, 1, (jfloat *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jfloat *) uno_data = jni->CallFloatMethodA(
+ java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jfloat *) uno_data = java_data.f;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (out_param)
+ {
+ jni->GetDoubleArrayRegion(
+ (jdoubleArray) java_data.l, 0, 1, (jdouble *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jdouble *) uno_data = jni->CallDoubleMethodA(
+ java_data.l, m_jni_info->m_method_Double_doubleValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jdouble *) uno_data = java_data.d;
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ if (! assign)
+ *(rtl_uString **)uno_data = 0;
+ jstring_to_ustring(
+ jni, (rtl_uString **)uno_data, (jstring) java_data.l );
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ // type name
+ JLocalAutoRef jo_type_name(
+ jni, jni->GetObjectField(
+ java_data.l, m_jni_info->m_field_Type__typeName ) );
+ if (! jo_type_name.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] incomplete type object: "
+ "no type name!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ OUString type_name(
+ jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
+ ::com::sun::star::uno::TypeDescription td( type_name );
+ if (! td.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] UNO type not found: ") );
+ buf.append( type_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
+ if (assign)
+ {
+ typelib_typedescriptionreference_release(
+ *(typelib_TypeDescriptionReference **)uno_data );
+ }
+ *(typelib_TypeDescriptionReference **)uno_data = td.get()->pWeakRef;
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+
+ uno_Any * pAny = (uno_Any *)uno_data;
+ if (0 == java_data.l) // null-ref maps to XInterface null-ref
+ {
+ if (assign)
+ uno_any_destruct( pAny, 0 );
+ uno_any_construct(
+ pAny, 0, m_jni_info->m_XInterface_type_info->m_td.get(), 0 );
+ break;
+ }
+
+ JLocalAutoRef jo_type( jni );
+ JLocalAutoRef jo_wrapped_holder( jni );
+
+ if (JNI_FALSE != jni->IsInstanceOf(
+ java_data.l, m_jni_info->m_class_Any ))
+ {
+ // boxed any
+ jo_type.reset( jni->GetObjectField(
+ java_data.l, m_jni_info->m_field_Any__type ) );
+ if (! jo_type.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] no type set at "
+ "com.sun.star.uno.Any!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ // wrapped value
+ jo_wrapped_holder.reset(
+ jni->GetObjectField(
+ java_data.l, m_jni_info->m_field_Any__object ) );
+ java_data.l = jo_wrapped_holder.get();
+ }
+ else
+ {
+ // create type out of class
+ JLocalAutoRef jo_class( jni, jni->GetObjectClass( java_data.l ) );
+ jo_type.reset( create_type( jni, (jclass) jo_class.get() ) );
+#if OSL_DEBUG_LEVEL > 1
+ {
+ JLocalAutoRef jo_toString(
+ jni, jni->CallObjectMethodA(
+ java_data.l, m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ OUString toString(
+ jstring_to_oustring( jni, (jstring) jo_toString.get() ) );
+ }
+#endif
+ }
+
+ // get type name
+ JLocalAutoRef jo_type_name(
+ jni, jni->GetObjectField(
+ jo_type.get(), m_jni_info->m_field_Type__typeName ) );
+ jni.ensure_no_exception();
+ OUString type_name(
+ jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
+
+ ::com::sun::star::uno::TypeDescription value_td( type_name );
+ if (! value_td.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] UNO type not found: ") );
+ buf.append( type_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ typelib_TypeClass type_class = value_td.get()->eTypeClass;
+
+ if (assign)
+ {
+ uno_any_destruct( pAny, 0 );
+ }
+ try
+ {
+ switch (type_class)
+ {
+ case typelib_TypeClass_VOID:
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_CHAR:
+ *(jchar *) &pAny->pReserved = jni->CallCharMethodA(
+ java_data.l, m_jni_info->m_method_Character_charValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ *(jboolean *) &pAny->pReserved = jni->CallBooleanMethodA(
+ java_data.l, m_jni_info->m_method_Boolean_booleanValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_BYTE:
+ *(jbyte *) &pAny->pReserved = jni->CallByteMethodA(
+ java_data.l, m_jni_info->m_method_Byte_byteValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(jshort *) &pAny->pReserved = jni->CallShortMethodA(
+ java_data.l, m_jni_info->m_method_Short_shortValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *(jint *) &pAny->pReserved = jni->CallIntMethodA(
+ java_data.l, m_jni_info->m_method_Integer_intValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (sizeof (sal_Int64) <= sizeof (void *))
+ {
+ *(jlong *) &pAny->pReserved = jni->CallLongMethodA(
+ java_data.l, m_jni_info->m_method_Long_longValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ }
+ else
+ {
+ auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate( sizeof (sal_Int64) ) );
+ *(jlong *) mem.get() = jni->CallLongMethodA(
+ java_data.l, m_jni_info->m_method_Long_longValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = mem.release();
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (sizeof (float) <= sizeof (void *))
+ {
+ *(jfloat *) &pAny->pReserved = jni->CallFloatMethodA(
+ java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ }
+ else
+ {
+ auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate( sizeof (float) ) );
+ *(jfloat *) mem.get() = jni->CallFloatMethodA(
+ java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = mem.release();
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (sizeof (double) <= sizeof (void *))
+ {
+ *(jdouble *) &pAny->pReserved =
+ jni->CallDoubleMethodA(
+ java_data.l,
+ m_jni_info->m_method_Double_doubleValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = &pAny->pReserved;
+ }
+ else
+ {
+ auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate( sizeof (double) ) );
+ *(jdouble *) mem.get() =
+ jni->CallDoubleMethodA(
+ java_data.l,
+ m_jni_info->m_method_Double_doubleValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = mem.release();
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ // opt: anies often contain strings; copy string directly
+ pAny->pReserved = 0;
+ jstring_to_ustring(
+ jni, (rtl_uString **)&pAny->pReserved,
+ (jstring) java_data.l );
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ map_to_uno(
+ jni, &pAny->pReserved, java_data,
+ value_td.get()->pWeakRef, 0,
+ false /* no assign */, false /* no out param */ );
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate( value_td.get()->nSize ) );
+ map_to_uno(
+ jni, mem.get(), java_data, value_td.get()->pWeakRef, 0,
+ false /* no assign */, false /* no out param */ );
+ pAny->pData = mem.release();
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( type_name );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] unsupported value type "
+ "of any!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+ }
+ catch (...)
+ {
+ if (assign)
+ {
+ // restore to valid any
+ uno_any_construct( pAny, 0, 0, 0 );
+ }
+ throw;
+ }
+ typelib_typedescriptionreference_acquire( value_td.get()->pWeakRef );
+ pAny->pType = value_td.get()->pWeakRef;
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ *(jint *) uno_data = jni->GetIntField(
+ java_data.l, m_jni_info->m_field_Enum_m_value );
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ JNI_compound_type_info const * comp_info =
+ static_cast< JNI_compound_type_info const * >( info );
+
+ typelib_CompoundTypeDescription * comp_td =
+ (typelib_CompoundTypeDescription *)comp_info->m_td.get();
+ bool polymorphic
+ = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ comp_td)->pParameterizedTypes != 0;
+
+ sal_Int32 nPos = 0;
+ sal_Int32 nMembers = comp_td->nMembers;
+ try
+ {
+ if (0 != comp_td->pBaseTypeDescription)
+ {
+ map_to_uno(
+ jni, uno_data, java_data,
+ ((typelib_TypeDescription *) comp_td->pBaseTypeDescription)
+ ->pWeakRef,
+ comp_info->m_base,
+ assign, false /* no out param */ );
+ }
+
+ for ( ; nPos < nMembers; ++nPos )
+ {
+ void * p = (char *)uno_data + comp_td->pMemberOffsets[ nPos ];
+ typelib_TypeDescriptionReference * member_type =
+ comp_td->ppTypeRefs[ nPos ];
+ jfieldID field_id = comp_info->m_fields[ nPos ];
+ bool parameterizedType = polymorphic
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ comp_td)->pParameterizedTypes[nPos];
+ switch (member_type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jchar *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jchar *) p = jni->GetCharField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jboolean *) p = false;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jboolean *) p = jni->GetBooleanField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jbyte *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jbyte *) p = jni->GetByteField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jshort *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jshort *) p = jni->GetShortField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jint *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jint *) p = jni->GetIntField( java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jlong *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jlong *) p = jni->GetLongField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jfloat *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jfloat *) p = jni->GetFloatField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jdouble *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jdouble *) p = jni->GetDoubleField(
+ java_data.l, field_id );
+ }
+ break;
+ default:
+ {
+ JLocalAutoRef jo_field( jni );
+ bool checkNull;
+ if (0 == field_id)
+ {
+ // special for Message: call Throwable.getMessage()
+ OSL_ASSERT(
+ type_equals(
+ type,
+ m_jni_info->m_Exception_type.getTypeLibType() )
+ || type_equals(
+ type,
+ m_jni_info->m_RuntimeException_type.
+ getTypeLibType() ) );
+ OSL_ASSERT( 0 == nPos ); // first member
+ // call getMessage()
+ jo_field.reset(
+ jni->CallObjectMethodA(
+ java_data.l,
+ m_jni_info->m_method_Throwable_getMessage, 0 )
+ );
+ jni.ensure_no_exception();
+ checkNull = true;
+ }
+ else
+ {
+ jo_field.reset(
+ jni->GetObjectField( java_data.l, field_id ) );
+ checkNull = parameterizedType;
+ }
+ if (checkNull && !jo_field.is()) {
+ createDefaultUnoValue(jni, p, member_type, 0, assign);
+ } else {
+ jvalue val;
+ val.l = jo_field.get();
+ map_to_uno(
+ jni, p, val, member_type, 0,
+ assign, false /* no out param */ );
+ }
+ break;
+ }
+ }
+ }
+ }
+ catch (...)
+ {
+ if (! assign)
+ {
+ // cleanup
+ for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
+ {
+ void * p =
+ (char *)uno_data + comp_td->pMemberOffsets[ nCleanup ];
+ uno_type_destructData(
+ p, comp_td->ppTypeRefs[ nCleanup ], 0 );
+ }
+ if (0 != comp_td->pBaseTypeDescription)
+ {
+ uno_destructData(
+ uno_data,
+ (typelib_TypeDescription *) comp_td
+ ->pBaseTypeDescription, 0 );
+ }
+ }
+ throw;
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ TypeDescr td( type );
+ typelib_TypeDescriptionReference * element_type =
+ ((typelib_IndirectTypeDescription *)td.get())->pType;
+
+ auto_ptr< rtl_mem > seq;
+ sal_Int32 nElements = jni->GetArrayLength( (jarray) java_data.l );
+
+ switch (element_type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Unicode) ) );
+ jni->GetCharArrayRegion(
+ (jcharArray) java_data.l, 0, nElements,
+ (jchar *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Bool) ) );
+ jni->GetBooleanArrayRegion(
+ (jbooleanArray) java_data.l, 0, nElements,
+ (jboolean *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_BYTE:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Int8) ) );
+ jni->GetByteArrayRegion(
+ (jbyteArray) java_data.l, 0, nElements,
+ (jbyte *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Int16) ) );
+ jni->GetShortArrayRegion(
+ (jshortArray) java_data.l, 0, nElements,
+ (jshort *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Int32) ) );
+ jni->GetIntArrayRegion(
+ (jintArray) java_data.l, 0, nElements,
+ (jint *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Int64) ) );
+ jni->GetLongArrayRegion(
+ (jlongArray) java_data.l, 0, nElements,
+ (jlong *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_FLOAT:
+ seq.reset( seq_allocate( nElements, sizeof (float) ) );
+ jni->GetFloatArrayRegion(
+ (jfloatArray) java_data.l, 0, nElements,
+ (jfloat *)((uno_Sequence *)seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_DOUBLE:
+ seq.reset( seq_allocate( nElements, sizeof (double) ) );
+ jni->GetDoubleArrayRegion(
+ (jdoubleArray) java_data.l, 0, nElements,
+ (jdouble *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ {
+ TypeDescr element_td( element_type );
+ seq.reset( seq_allocate( nElements, element_td.get()->nSize ) );
+
+ JNI_type_info const * element_info;
+ if (typelib_TypeClass_STRUCT == element_type->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == element_type->eTypeClass ||
+ typelib_TypeClass_INTERFACE == element_type->eTypeClass)
+ {
+ element_info =
+ m_jni_info->get_type_info( jni, element_td.get() );
+ }
+ else
+ {
+ element_info = 0;
+ }
+
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ try
+ {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectArrayElement(
+ (jobjectArray) java_data.l, nPos ) );
+ jni.ensure_no_exception();
+ jvalue val;
+ val.l = jo.get();
+ void * p =
+ ((uno_Sequence *)seq.get())->elements +
+ (nPos * element_td.get()->nSize);
+ map_to_uno(
+ jni, p, val, element_td.get()->pWeakRef, element_info,
+ false /* no assign */, false /* no out param */ );
+ }
+ catch (...)
+ {
+ // cleanup
+ for ( sal_Int32 nCleanPos = 0;
+ nCleanPos < nPos; ++nCleanPos )
+ {
+ void * p =
+ ((uno_Sequence *)seq.get())->elements +
+ (nCleanPos * element_td.get()->nSize);
+ uno_destructData( p, element_td.get(), 0 );
+ }
+ throw;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] unsupported sequence element"
+ " type: ") );
+ buf.append( OUString::unacquired( &element_type->pTypeName ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+
+ if (assign)
+ uno_destructData( uno_data, td.get(), 0 );
+ *(uno_Sequence **)uno_data = (uno_Sequence *)seq.release();
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+
+ if (0 == java_data.l) // null-ref
+ {
+ if (assign)
+ {
+ uno_Interface * p = *(uno_Interface **)uno_data;
+ if (0 != p)
+ (*p->release)( p );
+ }
+ *(uno_Interface **)uno_data = 0;
+ }
+ else
+ {
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >( info );
+ uno_Interface * pUnoI = map_to_uno( jni, java_data.l, iface_info );
+ if (assign)
+ {
+ uno_Interface * p = *(uno_Interface **)uno_data;
+ if (0 != p)
+ (*p->release)( p );
+ }
+ *(uno_Interface **)uno_data = pUnoI;
+ }
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+void Bridge::map_to_java(
+ JNI_context const & jni,
+ jvalue * java_data, void const * uno_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */,
+ bool in_param, bool out_param,
+ bool special_wrapped_integral_types ) const
+{
+ switch (type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewCharArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetCharArrayRegion(
+ (jcharArray) jo_ar.get(), 0, 1, (jchar *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetCharArrayRegion(
+ (jcharArray) java_data->l, 0, 1, (jchar *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.c = *(jchar const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Character,
+ m_jni_info->m_ctor_Character_with_char, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->c = *(jchar const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewBooleanArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetBooleanArrayRegion(
+ (jbooleanArray) jo_ar.get(),
+ 0, 1, (jboolean *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetBooleanArrayRegion(
+ (jbooleanArray) java_data->l,
+ 0, 1, (jboolean *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.z = *(jboolean const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Boolean,
+ m_jni_info->m_ctor_Boolean_with_boolean, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->z = *(jboolean const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewByteArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetByteArrayRegion(
+ (jbyteArray) jo_ar.get(), 0, 1, (jbyte *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetByteArrayRegion(
+ (jbyteArray) java_data->l, 0, 1, (jbyte *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.b = *(jbyte const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Byte,
+ m_jni_info->m_ctor_Byte_with_byte, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->b = *(jbyte const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewShortArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetShortArrayRegion(
+ (jshortArray) jo_ar.get(), 0, 1, (jshort *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetShortArrayRegion(
+ (jshortArray) java_data->l, 0, 1, (jshort *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.s = *(jshort const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Short,
+ m_jni_info->m_ctor_Short_with_short, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->s = *(jshort const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewIntArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetIntArrayRegion(
+ (jintArray) jo_ar.get(), 0, 1, (jint *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetIntArrayRegion(
+ (jintArray) java_data->l, 0, 1, (jint *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.i = *(jint const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Integer,
+ m_jni_info->m_ctor_Integer_with_int, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->i = *(jint const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewLongArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetLongArrayRegion(
+ (jlongArray)jo_ar.get(), 0, 1, (jlong *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetLongArrayRegion(
+ (jlongArray)java_data->l, 0, 1, (jlong *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.j = *(jlong const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Long,
+ m_jni_info->m_ctor_Long_with_long, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->j = *(jlong const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewFloatArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetFloatArrayRegion(
+ (jfloatArray) jo_ar.get(), 0, 1, (jfloat *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetFloatArrayRegion(
+ (jfloatArray) java_data->l, 0, 1, (jfloat *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.f = *(jfloat const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Float,
+ m_jni_info->m_ctor_Float_with_float, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->f = *(jfloat const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewDoubleArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetDoubleArrayRegion(
+ (jdoubleArray) jo_ar.get(),
+ 0, 1, (jdouble *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetDoubleArrayRegion(
+ (jdoubleArray) java_data->l,
+ 0, 1, (jdouble *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.d = *(double const *)uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Double,
+ m_jni_info->m_ctor_Double_with_double, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->d = *(jdouble const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ {
+ if (out_param)
+ {
+ JLocalAutoRef jo_in( jni );
+ if (in_param)
+ {
+ jo_in.reset(
+ ustring_to_jstring(
+ jni, *(rtl_uString * const *) uno_data ) );
+ }
+ if (0 == java_data->l)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, m_jni_info->m_class_String, jo_in.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_in.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ OSL_ASSERT( in_param );
+ java_data->l =
+ ustring_to_jstring( jni, *(rtl_uString * const *) uno_data );
+ }
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ if (out_param)
+ {
+ JLocalAutoRef jo_in( jni );
+ if (in_param)
+ {
+ jo_in.reset(
+ create_type(
+ jni,
+ *(typelib_TypeDescriptionReference * const *) uno_data )
+ );
+ }
+ if (0 == java_data->l)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, m_jni_info->m_class_Type, jo_in.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_in.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ OSL_ASSERT( in_param );
+ java_data->l =
+ create_type(
+ jni,
+ *(typelib_TypeDescriptionReference * const *) uno_data );
+ }
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ JLocalAutoRef jo_any( jni );
+ if (in_param)
+ {
+ uno_Any const * pAny = (uno_Any const *)uno_data;
+
+#if defined BRIDGES_JNI_UNO_FORCE_BOXED_ANY
+ if (typelib_TypeClass_VOID == pAny->pType->eTypeClass)
+ {
+ jo_any.reset(
+ jni->NewLocalRef( m_jni_info->m_object_Any_VOID ) );
+ }
+ else
+ {
+ jvalue args[ 2 ];
+ map_to_java(
+ jni, &args[ 1 ], pAny->pData, pAny->pType, 0,
+ true /* in */, false /* no out */,
+ true /* create integral wrappers */ );
+ jo_any.reset( args[ 1 ].l );
+ // build up com.sun.star.uno.Any
+ JLocalAutoRef jo_type( jni, create_type( jni, pAny->pType ) );
+ args[ 0 ].l = jo_type.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ }
+#else
+ switch (pAny->pType->eTypeClass)
+ {
+ case typelib_TypeClass_VOID:
+ jo_any.reset(
+ jni->NewLocalRef( m_jni_info->m_object_Any_VOID ) );
+ break;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ {
+ jvalue args[ 2 ];
+ args[ 0 ].s = *(jshort const *) &pAny->pReserved;
+ JLocalAutoRef jo_val(
+ jni, jni->NewObjectA(
+ m_jni_info->m_class_Short,
+ m_jni_info->m_ctor_Short_with_short, args ) );
+ jni.ensure_no_exception();
+ // box up in com.sun.star.uno.Any
+ args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_SHORT;
+ args[ 1 ].l = jo_val.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ break;
+ }
+ case typelib_TypeClass_UNSIGNED_LONG:
+ {
+ jvalue args[ 2 ];
+ args[ 0 ].i = *(jint const *) &pAny->pReserved;
+ JLocalAutoRef jo_val(
+ jni, jni->NewObjectA(
+ m_jni_info->m_class_Integer,
+ m_jni_info->m_ctor_Integer_with_int, args ) );
+ jni.ensure_no_exception();
+ // box up in com.sun.star.uno.Any
+ args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_LONG;
+ args[ 1 ].l = jo_val.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ break;
+ }
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ jvalue args[ 2 ];
+ args[ 0 ].j = *(jlong const *) pAny->pData;
+ JLocalAutoRef jo_val(
+ jni, jni->NewObjectA(
+ m_jni_info->m_class_Long,
+ m_jni_info->m_ctor_Long_with_long, args ) );
+ jni.ensure_no_exception();
+ // box up in com.sun.star.uno.Any
+ args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_HYPER;
+ args[ 1 ].l = jo_val.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ break;
+ }
+ case typelib_TypeClass_STRING: // opt strings
+ jo_any.reset( ustring_to_jstring(
+ jni, (rtl_uString *) pAny->pReserved ) );
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ {
+ jvalue java_data2;
+ // prefetch sequence td
+ TypeDescr seq_td( pAny->pType );
+ map_to_java(
+ jni, &java_data2, pAny->pData, seq_td.get()->pWeakRef, 0,
+ true /* in */, false /* no out */,
+ true /* create integral wrappers */ );
+ jo_any.reset( java_data2.l );
+
+ // determine inner element type
+ ::com::sun::star::uno::Type element_type(
+ ((typelib_IndirectTypeDescription *)seq_td.get())->pType );
+ while (typelib_TypeClass_SEQUENCE ==
+ element_type.getTypeLibType()->eTypeClass)
+ {
+ TypeDescr element_td( element_type.getTypeLibType() );
+ typelib_typedescriptionreference_assign(
+ reinterpret_cast< typelib_TypeDescriptionReference ** >(
+ &element_type ),
+ ((typelib_IndirectTypeDescription *)element_td.get())
+ ->pType );
+ }
+ // box up only if unsigned element type
+ switch (element_type.getTypeLibType()->eTypeClass)
+ {
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ jvalue args[ 2 ];
+ JLocalAutoRef jo_type(
+ jni, create_type( jni, seq_td.get()->pWeakRef ) );
+ args[ 0 ].l = jo_type.get();
+ args[ 1 ].l = jo_any.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ uno_Interface * pUnoI = (uno_Interface *)pAny->pReserved;
+ if (is_XInterface( pAny->pType ))
+ {
+ if (0 != pUnoI)
+ {
+ jo_any.reset(
+ map_to_java(
+ jni, pUnoI,
+ m_jni_info->m_XInterface_type_info ) );
+ }
+ // else: empty XInterface ref maps to null-ref
+ }
+ else
+ {
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >(
+ m_jni_info->get_type_info( jni, pAny->pType ) );
+ if (0 != pUnoI)
+ {
+ jo_any.reset( map_to_java( jni, pUnoI, iface_info ) );
+ }
+ // box up in com.sun.star.uno.Any
+ jvalue args[ 2 ];
+ args[ 0 ].l = iface_info->m_type;
+ args[ 1 ].l = jo_any.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ }
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ {
+ // Do not lose information about type arguments of instantiated
+ // polymorphic struct types:
+ rtl::OUString const & name = rtl::OUString::unacquired(
+ &pAny->pType->pTypeName);
+ OSL_ASSERT(name.getLength() > 0);
+ if (name[name.getLength() - 1] == '>')
+ {
+ // Box up in com.sun.star.uno.Any:
+ JLocalAutoRef jo_type(jni, create_type(jni, pAny->pType));
+ jvalue java_data2;
+ map_to_java(
+ jni, &java_data2, pAny->pData, pAny->pType, 0, true,
+ false);
+ jo_any.reset(java_data2.l);
+ jvalue args[2];
+ args[0].l = jo_type.get();
+ args[1].l = jo_any.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args));
+ jni.ensure_no_exception();
+ break;
+ }
+ // fall through
+ }
+ default:
+ {
+ jvalue java_data2;
+ map_to_java(
+ jni, &java_data2, pAny->pData, pAny->pType, 0,
+ true /* in */, false /* no out */,
+ true /* create integral wrappers */ );
+ jo_any.reset( java_data2.l );
+ break;
+ }
+ }
+#endif
+ }
+
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, m_jni_info->m_class_Object, jo_any.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_any.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_any.release();
+ }
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ {
+ OUString const & type_name = OUString::unacquired( &type->pTypeName );
+ OString class_name(
+ OUStringToOString( type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
+ JLocalAutoRef jo_enum_class(
+ jni, find_class( jni, class_name.getStr() ) );
+
+ JLocalAutoRef jo_enum( jni );
+ if (in_param)
+ {
+ // call static <enum_class>.fromInt( int )
+ OStringBuffer sig_buf( 5 + class_name.getLength() );
+ sig_buf.append( RTL_CONSTASCII_STRINGPARAM("(I)L") );
+ sig_buf.append( class_name.replace( '.', '/' ) );
+ sig_buf.append( ';' );
+ OString sig( sig_buf.makeStringAndClear() );
+ jmethodID method_id = jni->GetStaticMethodID(
+ (jclass) jo_enum_class.get(), "fromInt", sig.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != method_id );
+
+ jvalue arg;
+ arg.i = *(jint const *) uno_data;
+ jo_enum.reset(
+ jni->CallStaticObjectMethodA(
+ (jclass) jo_enum_class.get(), method_id, &arg ) );
+ jni.ensure_no_exception();
+ }
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, (jclass) jo_enum_class.get(), jo_enum.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_enum.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_enum.release();
+ }
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ JNI_compound_type_info const * comp_info =
+ static_cast< JNI_compound_type_info const * >( info );
+
+ JLocalAutoRef jo_comp( jni );
+ if (in_param)
+ {
+ if (typelib_TypeClass_EXCEPTION == type->eTypeClass)
+ {
+ JLocalAutoRef jo_message(
+ jni, ustring_to_jstring( jni, *(rtl_uString **)uno_data ) );
+ jvalue arg;
+ arg.l = jo_message.get();
+ jo_comp.reset(
+ jni->NewObjectA(
+ comp_info->m_class, comp_info->m_exc_ctor, &arg ) );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jo_comp.reset( jni->AllocObject( comp_info->m_class ) );
+ jni.ensure_no_exception();
+ }
+
+ for ( JNI_compound_type_info const * linfo = comp_info;
+ 0 != linfo;
+ linfo = static_cast< JNI_compound_type_info const * >(
+ linfo->m_base ) )
+ {
+ typelib_CompoundTypeDescription * comp_td =
+ (typelib_CompoundTypeDescription *)linfo->m_td.get();
+ typelib_TypeDescriptionReference ** ppMemberTypeRefs =
+ comp_td->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
+ bool polymorphic
+ = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ comp_td)->pParameterizedTypes != 0;
+ for ( sal_Int32 nPos = comp_td->nMembers; nPos--; )
+ {
+ jfieldID field_id = linfo->m_fields[ nPos ];
+ if (0 != field_id)
+ {
+ void const * p =
+ (char const *)uno_data + pMemberOffsets[ nPos ];
+ typelib_TypeDescriptionReference * member_type =
+ ppMemberTypeRefs[ nPos ];
+ bool parameterizedType = polymorphic
+ && (reinterpret_cast<
+ typelib_StructTypeDescription * >(comp_td)->
+ pParameterizedTypes[nPos]);
+ switch (member_type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.c = *(jchar const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Character,
+ m_jni_info->m_ctor_Character_with_char,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetCharField(
+ jo_comp.get(),
+ field_id, *(jchar const *) p );
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.z = *(jboolean const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Boolean,
+ m_jni_info->m_ctor_Boolean_with_boolean,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetBooleanField(
+ jo_comp.get(),
+ field_id, *(jboolean const *) p );
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.b = *(jbyte const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Byte,
+ m_jni_info->m_ctor_Byte_with_byte,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetByteField(
+ jo_comp.get(),
+ field_id, *(jbyte const *) p );
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.s = *(jshort const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Short,
+ m_jni_info->m_ctor_Short_with_short,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetShortField(
+ jo_comp.get(),
+ field_id, *(jshort const *) p );
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.i = *(jint const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Integer,
+ m_jni_info->m_ctor_Integer_with_int,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetIntField(
+ jo_comp.get(),
+ field_id, *(jint const *) p );
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.j = *(jlong const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Long,
+ m_jni_info->m_ctor_Long_with_long,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetLongField(
+ jo_comp.get(),
+ field_id, *(jlong const *) p );
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.f = *(jfloat const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Float,
+ m_jni_info->m_ctor_Float_with_float,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetFloatField(
+ jo_comp.get(),
+ field_id, *(jfloat const *) p );
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.d = *(jdouble const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Double,
+ m_jni_info->m_ctor_Double_with_double,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetDoubleField(
+ jo_comp.get(),
+ field_id, *(jdouble const *) p );
+ }
+ break;
+ case typelib_TypeClass_STRING: // string opt here
+ {
+ JLocalAutoRef jo_string(
+ jni, ustring_to_jstring(
+ jni, *(rtl_uString * const *) p ) );
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo_string.get() );
+ break;
+ }
+ default:
+ {
+ jvalue java_data2;
+ map_to_java(
+ jni, &java_data2, p, member_type, 0,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_obj( jni, java_data2.l );
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo_obj.get() );
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ java_data->l =
+ jni->NewObjectArray( 1, comp_info->m_class, jo_comp.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_comp.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_comp.release();
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ // xxx todo: possible opt for pure out sequences
+ JLocalAutoRef jo_ar( jni );
+
+ sal_Int32 nElements;
+ uno_Sequence const * seq = 0;
+ if (in_param)
+ {
+ seq = *(uno_Sequence * const *)uno_data;
+ nElements = seq->nElements;
+ }
+ else
+ {
+ nElements = 0;
+ }
+
+ TypeDescr td( type );
+ typelib_TypeDescriptionReference * element_type =
+ ((typelib_IndirectTypeDescription *)td.get())->pType;
+
+ switch (element_type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ jo_ar.reset( jni->NewCharArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetCharArrayRegion(
+ (jcharArray) jo_ar.get(),
+ 0, nElements, (jchar *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ jo_ar.reset( jni->NewBooleanArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetBooleanArrayRegion(
+ (jbooleanArray) jo_ar.get(),
+ 0, nElements, (jboolean *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ jo_ar.reset( jni->NewByteArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetByteArrayRegion(
+ (jbyteArray) jo_ar.get(),
+ 0, nElements, (jbyte *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ jo_ar.reset( jni->NewShortArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetShortArrayRegion(
+ (jshortArray) jo_ar.get(),
+ 0, nElements, (jshort *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ jo_ar.reset( jni->NewIntArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetIntArrayRegion(
+ (jintArray) jo_ar.get(),
+ 0, nElements, (jint *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ jo_ar.reset( jni->NewLongArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetLongArrayRegion(
+ (jlongArray) jo_ar.get(),
+ 0, nElements, (jlong *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ jo_ar.reset( jni->NewFloatArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetFloatArrayRegion(
+ (jfloatArray) jo_ar.get(),
+ 0, nElements, (jfloat *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ jo_ar.reset( jni->NewDoubleArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetDoubleArrayRegion(
+ (jdoubleArray) jo_ar.get(),
+ 0, nElements, (jdouble *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ jo_ar.reset(
+ jni->NewObjectArray(
+ nElements, m_jni_info->m_class_String, 0 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ rtl_uString * const * pp =
+ (rtl_uString * const *) seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ JLocalAutoRef jo_string(
+ jni, ustring_to_jstring( jni, pp[ nPos ] ) );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_string.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ case typelib_TypeClass_TYPE:
+ jo_ar.reset(
+ jni->NewObjectArray( nElements, m_jni_info->m_class_Type, 0 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ typelib_TypeDescriptionReference * const * pp =
+ (typelib_TypeDescriptionReference * const *)seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue val;
+ map_to_java(
+ jni, &val, &pp[ nPos ], element_type, 0,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_element( jni, val.l );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_element.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ case typelib_TypeClass_ANY:
+ jo_ar.reset(
+ jni->NewObjectArray(
+ nElements, m_jni_info->m_class_Object, 0 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ uno_Any const * p = (uno_Any const *)seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue val;
+ map_to_java(
+ jni, &val, &p[ nPos ], element_type, 0,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_element( jni, val.l );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_element.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ case typelib_TypeClass_ENUM:
+ {
+ OUString const & element_type_name =
+ OUString::unacquired( &element_type->pTypeName );
+ OString class_name(
+ OUStringToOString(
+ element_type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
+ JLocalAutoRef jo_enum_class(
+ jni, find_class( jni, class_name.getStr() ) );
+
+ jo_ar.reset(
+ jni->NewObjectArray(
+ nElements, (jclass) jo_enum_class.get(), 0 ) );
+ jni.ensure_no_exception();
+
+ if (0 < nElements)
+ {
+ // call static <enum_class>.fromInt( int )
+ OStringBuffer sig_buf( 5 + class_name.getLength() );
+ sig_buf.append( RTL_CONSTASCII_STRINGPARAM("(I)L") );
+ sig_buf.append( class_name.replace( '.', '/' ) );
+ sig_buf.append( ';' );
+ OString sig( sig_buf.makeStringAndClear() );
+ jmethodID method_id = jni->GetStaticMethodID(
+ (jclass) jo_enum_class.get(), "fromInt", sig.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != method_id );
+
+ sal_Int32 const * p = (sal_Int32 const *)seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue arg;
+ arg.i = p[ nPos ];
+ JLocalAutoRef jo_enum(
+ jni, jni->CallStaticObjectMethodA(
+ (jclass) jo_enum_class.get(), method_id, &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_enum.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ JNI_type_info const * element_info =
+ m_jni_info->get_type_info( jni, element_type );
+
+ jo_ar.reset(
+ jni->NewObjectArray( nElements, element_info->m_class, 0 ) );
+ jni.ensure_no_exception();
+
+ if (0 < nElements)
+ {
+ char * p = (char *)seq->elements;
+ sal_Int32 nSize = element_info->m_td.get()->nSize;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue val;
+ map_to_java(
+ jni, &val, p + (nSize * nPos),
+ element_type, element_info,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_element( jni, val.l );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_element.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ OStringBuffer buf( 64 );
+ JNI_info::append_sig(
+ &buf, element_type, false /* use class XInterface */,
+ false /* '.' instead of '/' */ );
+ OString class_name( buf.makeStringAndClear() );
+ JLocalAutoRef jo_seq_class(
+ jni, find_class( jni, class_name.getStr() ) );
+
+ jo_ar.reset(
+ jni->NewObjectArray(
+ nElements, (jclass) jo_seq_class.get(), 0 ) );
+ jni.ensure_no_exception();
+
+ if (0 < nElements)
+ {
+ TypeDescr element_td( element_type );
+ uno_Sequence ** elements = (uno_Sequence **) seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue java_data2;
+ map_to_java(
+ jni, &java_data2, elements + nPos, element_type, 0,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_seq( jni, java_data2.l );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_seq.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >(
+ m_jni_info->get_type_info( jni, element_type ) );
+
+ jo_ar.reset(
+ jni->NewObjectArray( nElements, iface_info->m_class, 0 ) );
+ jni.ensure_no_exception();
+
+ if (0 < nElements)
+ {
+ uno_Interface ** pp = (uno_Interface **)seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ uno_Interface * pUnoI = pp[ nPos ];
+ if (0 != pUnoI)
+ {
+ JLocalAutoRef jo_element(
+ jni, map_to_java( jni, pUnoI, iface_info ) );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(),
+ nPos, jo_element.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_java():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] unsupported element type: ") );
+ buf.append( OUString::unacquired( &element_type->pTypeName ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_element_class(
+ jni, jni->GetObjectClass( jo_ar.get() ) );
+ if (in_param)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, (jclass) jo_element_class.get(), jo_ar.get() );
+ }
+ else
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, (jclass) jo_element_class.get(), 0 );
+ }
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_ar.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_ar.release();
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ JLocalAutoRef jo_iface( jni );
+ if (in_param)
+ {
+ uno_Interface * pUnoI = *(uno_Interface * const *)uno_data;
+ if (0 != pUnoI)
+ {
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >( info );
+ jo_iface.reset( map_to_java( jni, pUnoI, iface_info ) );
+ }
+ }
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ java_data->l =
+ jni->NewObjectArray( 1, info->m_class, jo_iface.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_iface.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_iface.release();
+ }
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_java():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+}
+
+}
diff --git a/bridges/source/jni_uno/jni_helper.h b/bridges/source/jni_uno/jni_helper.h
new file mode 100644
index 000000000000..8020f65c68f6
--- /dev/null
+++ b/bridges/source/jni_uno/jni_helper.h
@@ -0,0 +1,162 @@
+/*************************************************************************
+ *
+ * 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_HELPER_H
+#define INCLUDED_JNI_HELPER_H
+
+#include "jni_base.h"
+#include "jni_info.h"
+
+
+namespace jni_uno
+{
+
+//------------------------------------------------------------------------------
+inline void jstring_to_ustring(
+ JNI_context const & jni, rtl_uString ** out_ustr, jstring jstr )
+{
+ if (0 == jstr)
+ {
+ rtl_uString_new( out_ustr );
+ }
+ else
+ {
+ jsize len = jni->GetStringLength( jstr );
+ ::std::auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate(
+ sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) );
+ rtl_uString * ustr = (rtl_uString *)mem.get();
+ jni->GetStringRegion( jstr, 0, len, (jchar *) ustr->buffer );
+ jni.ensure_no_exception();
+ ustr->refCount = 1;
+ ustr->length = len;
+ ustr->buffer[ len ] = '\0';
+ mem.release();
+ if (0 != *out_ustr)
+ rtl_uString_release( *out_ustr );
+ *out_ustr = ustr;
+ }
+}
+
+//------------------------------------------------------------------------------
+inline ::rtl::OUString jstring_to_oustring(
+ JNI_context const & jni, jstring jstr )
+{
+ rtl_uString * ustr = 0;
+ jstring_to_ustring( jni, &ustr, jstr );
+ return ::rtl::OUString( ustr, SAL_NO_ACQUIRE );
+}
+
+//------------------------------------------------------------------------------
+inline jstring ustring_to_jstring(
+ JNI_context const & jni, rtl_uString const * ustr )
+{
+ jstring jstr = jni->NewString( (jchar const *) ustr->buffer, ustr->length );
+ jni.ensure_no_exception();
+ return jstr;
+}
+
+
+//------------------------------------------------------------------------------
+// if inException, does not handle exceptions, in which case returned value will
+// be null if exception occurred:
+inline jclass find_class(
+ JNI_context const & jni, char const * class_name, bool inException = false )
+{
+ // find_class may be called before the JNI_info is set:
+ jclass c=0;
+ jmethodID m;
+ JNI_info const * info = jni.get_info();
+ if (info == 0) {
+ jni.getClassForName(&c, &m);
+ if (c == 0) {
+ if (inException) {
+ return 0;
+ }
+ jni.ensure_no_exception();
+ }
+ } else {
+ c = info->m_class_Class;
+ m = info->m_method_Class_forName;
+ }
+ return jni.findClass(class_name, c, m, inException);
+}
+
+
+//------------------------------------------------------------------------------
+inline jobject create_type( JNI_context const & jni, jclass clazz )
+{
+ JNI_info const * jni_info = jni.get_info();
+ jvalue arg;
+ arg.l = clazz;
+ jobject jo_type = jni->NewObjectA(
+ jni_info->m_class_Type, jni_info->m_ctor_Type_with_Class, &arg );
+ jni.ensure_no_exception();
+ return jo_type;
+}
+
+//------------------------------------------------------------------------------
+inline jobject create_type(
+ JNI_context const & jni, typelib_TypeDescriptionReference * type )
+{
+ JNI_info const * jni_info = jni.get_info();
+ jvalue args[ 2 ];
+ // get type class
+ args[ 0 ].i = type->eTypeClass;
+ JLocalAutoRef jo_type_class(
+ jni, jni->CallStaticObjectMethodA(
+ jni_info->m_class_TypeClass,
+ jni_info->m_method_TypeClass_fromInt, args ) );
+ jni.ensure_no_exception();
+ // construct type
+ JLocalAutoRef jo_type_name(
+ jni, ustring_to_jstring( jni, type->pTypeName ) );
+ args[ 0 ].l = jo_type_name.get();
+ args[ 1 ].l = jo_type_class.get();
+ jobject jo_type = jni->NewObjectA(
+ jni_info->m_class_Type,
+ jni_info->m_ctor_Type_with_Name_TypeClass, args );
+ jni.ensure_no_exception();
+ return jo_type;
+}
+
+//------------------------------------------------------------------------------
+inline jobject compute_oid( JNI_context const & jni, jobject jo )
+{
+ JNI_info const * jni_info = jni.get_info();
+ jvalue arg;
+ arg.l= jo;
+ jobject jo_oid = jni->CallStaticObjectMethodA(
+ jni_info->m_class_UnoRuntime,
+ jni_info->m_method_UnoRuntime_generateOid, &arg );
+ jni.ensure_no_exception();
+ return jo_oid;
+}
+
+}
+
+#endif
diff --git a/bridges/source/jni_uno/jni_info.cxx b/bridges/source/jni_uno/jni_info.cxx
new file mode 100644
index 000000000000..b6cde712a882
--- /dev/null
+++ b/bridges/source/jni_uno/jni_info.cxx
@@ -0,0 +1,996 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include "jni_bridge.h"
+
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include "jvmaccess/unovirtualmachine.hxx"
+#include "rtl/string.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+
+#include "uno/lbnames.h"
+
+
+namespace css = ::com::sun::star;
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+JNI_type_info::JNI_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td )
+ : m_td( td ),
+ m_class( 0 )
+{
+ m_td.makeComplete();
+ if (! m_td.get()->bComplete)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("cannot make type complete: ") );
+ buf.append( OUString::unacquired( &m_td.get()->pTypeName ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+}
+
+
+//______________________________________________________________________________
+void JNI_interface_type_info::destroy( JNIEnv * jni_env )
+{
+ JNI_type_info::destruct( jni_env );
+ jni_env->DeleteGlobalRef( m_proxy_ctor );
+ jni_env->DeleteGlobalRef( m_type );
+ delete [] m_methods;
+ delete this;
+}
+
+//______________________________________________________________________________
+JNI_interface_type_info::JNI_interface_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td_ )
+ : JNI_type_info( jni, td_ )
+{
+ OSL_ASSERT( typelib_TypeClass_INTERFACE == m_td.get()->eTypeClass );
+
+ OUString const & uno_name = OUString::unacquired( &m_td.get()->pTypeName );
+ JNI_info const * jni_info = jni.get_info();
+
+ JLocalAutoRef jo_class(
+ jni,
+ find_class(
+ jni,
+ ( OUStringToOString( uno_name, RTL_TEXTENCODING_JAVA_UTF8 ).
+ getStr() ) ) );
+ JLocalAutoRef jo_type( jni, create_type( jni, (jclass) jo_class.get() ) );
+
+ // get proxy ctor
+ jvalue arg;
+ arg.l = jo_class.get();
+ JLocalAutoRef jo_proxy_ctor(
+ jni, jni->CallStaticObjectMethodA(
+ jni_info->m_class_JNI_proxy,
+ jni_info->m_method_JNI_proxy_get_proxy_ctor, &arg ) );
+
+ if (is_XInterface( m_td.get()->pWeakRef ))
+ {
+ m_methods = 0; // no methods
+ }
+ else
+ {
+ // retrieve method ids for all direct members
+ try
+ {
+ typelib_InterfaceTypeDescription * td =
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ m_td.get() );
+ m_methods = new jmethodID[ td->nMapFunctionIndexToMemberIndex ];
+ sal_Int32 nMethodIndex = 0;
+ typelib_TypeDescriptionReference ** ppMembers = td->ppMembers;
+ sal_Int32 nMembers = td->nMembers;
+
+ for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos )
+ {
+ TypeDescr member_td( ppMembers[ nPos ] );
+
+ OStringBuffer sig_buf( 64 );
+
+ if (typelib_TypeClass_INTERFACE_METHOD ==
+ member_td.get()->eTypeClass) // method
+ {
+ typelib_InterfaceMethodTypeDescription * method_td =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member_td.get() );
+
+ sig_buf.append( '(' );
+ for ( sal_Int32 i = 0; i < method_td->nParams; ++i )
+ {
+ typelib_MethodParameter const & param =
+ method_td->pParams[ i ];
+ if (param.bOut)
+ sig_buf.append( '[' );
+ JNI_info::append_sig( &sig_buf, param.pTypeRef );
+ }
+ sig_buf.append( ')' );
+ JNI_info::append_sig( &sig_buf, method_td->pReturnTypeRef );
+
+ OString method_signature( sig_buf.makeStringAndClear() );
+ OString method_name(
+ OUStringToOString( OUString::unacquired(
+ &method_td->aBase.pMemberName ),
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+
+ m_methods[ nMethodIndex ] = jni->GetMethodID(
+ (jclass) jo_class.get(), method_name.getStr(),
+ method_signature.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_methods[ nMethodIndex ] );
+ ++nMethodIndex;
+ }
+ else // attribute
+ {
+ OSL_ASSERT(
+ typelib_TypeClass_INTERFACE_ATTRIBUTE ==
+ member_td.get()->eTypeClass );
+ typelib_InterfaceAttributeTypeDescription * attribute_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member_td.get() );
+
+ // type sig
+ JNI_info::append_sig(
+ &sig_buf, attribute_td->pAttributeTypeRef );
+ OString type_sig( sig_buf.makeStringAndClear() );
+ sig_buf.ensureCapacity( 64 );
+ // member name
+ OUString const & member_name =
+ OUString::unacquired(
+ &attribute_td->aBase.pMemberName );
+
+ // getter
+ sig_buf.append( RTL_CONSTASCII_STRINGPARAM("()") );
+ sig_buf.append( type_sig );
+ OString method_signature( sig_buf.makeStringAndClear() );
+ OUStringBuffer name_buf( 3 + member_name.getLength() );
+ name_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("get") );
+ name_buf.append( member_name );
+ OString method_name(
+ OUStringToOString(
+ name_buf.makeStringAndClear(),
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+ m_methods[ nMethodIndex ] = jni->GetMethodID(
+ (jclass) jo_class.get(), method_name.getStr(),
+ method_signature.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_methods[ nMethodIndex ] );
+ ++nMethodIndex;
+ if (! attribute_td->bReadOnly)
+ {
+ // setter
+ sig_buf.ensureCapacity( 64 );
+ sig_buf.append( '(' );
+ sig_buf.append( type_sig );
+ sig_buf.append( RTL_CONSTASCII_STRINGPARAM(")V") );
+ method_signature = sig_buf.makeStringAndClear();
+ name_buf.ensureCapacity( 3 + member_name.getLength() );
+ name_buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("set") );
+ name_buf.append( member_name );
+ method_name = OUStringToOString(
+ name_buf.makeStringAndClear(),
+ RTL_TEXTENCODING_JAVA_UTF8 );
+ m_methods[ nMethodIndex ] = jni->GetMethodID(
+ (jclass) jo_class.get(), method_name.getStr(),
+ method_signature.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_methods[ nMethodIndex ] );
+ ++nMethodIndex;
+ }
+ }
+ }
+ }
+ catch (...)
+ {
+ delete [] m_methods;
+ throw;
+ }
+ }
+ m_class = (jclass) jni->NewGlobalRef( jo_class.get() );
+ m_type = jni->NewGlobalRef( jo_type.get() );
+ m_proxy_ctor = jni->NewGlobalRef( jo_proxy_ctor.get() );
+}
+
+
+//______________________________________________________________________________
+void JNI_compound_type_info::destroy( JNIEnv * jni_env )
+{
+ JNI_type_info::destruct( jni_env );
+ delete [] m_fields;
+ delete this;
+}
+
+//______________________________________________________________________________
+JNI_compound_type_info::JNI_compound_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td_ )
+ : JNI_type_info( jni, td_ ),
+ m_exc_ctor( 0 ),
+ m_fields( 0 )
+{
+ OSL_ASSERT( typelib_TypeClass_STRUCT == m_td.get()->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass );
+ typelib_CompoundTypeDescription * td =
+ reinterpret_cast< typelib_CompoundTypeDescription * >( m_td.get() );
+
+ OUString const & uno_name =
+ OUString::unacquired( &((typelib_TypeDescription *)td)->pTypeName );
+
+ // Erase type arguments of instantiated polymorphic struct types:
+ OUString nucleus;
+ sal_Int32 i = uno_name.indexOf( '<' );
+ if ( i < 0 ) {
+ nucleus = uno_name;
+ } else {
+ nucleus = uno_name.copy( 0, i );
+ }
+ JLocalAutoRef jo_class(
+ jni,
+ find_class(
+ jni,
+ OUStringToOString(
+ nucleus, RTL_TEXTENCODING_JAVA_UTF8 ).getStr() ) );
+
+ JNI_info const * jni_info = jni.get_info();
+
+ if (typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass)
+ {
+ // retrieve exc ctor( msg )
+ m_exc_ctor = jni->GetMethodID(
+ (jclass) jo_class.get(), "<init>", "(Ljava/lang/String;)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_exc_ctor );
+ }
+
+ // retrieve info for base type
+ typelib_TypeDescription * base_td =
+ reinterpret_cast< typelib_TypeDescription * >(
+ td->pBaseTypeDescription );
+ m_base = (0 == base_td ? 0 : jni_info->get_type_info( jni, base_td ));
+
+ try
+ {
+ if (type_equals(
+ ((typelib_TypeDescription *)td)->pWeakRef,
+ jni_info->m_Exception_type.getTypeLibType() ) ||
+ type_equals(
+ ((typelib_TypeDescription *)td)->pWeakRef,
+ jni_info->m_RuntimeException_type.getTypeLibType() ))
+ {
+ m_fields = new jfieldID[ 2 ];
+ m_fields[ 0 ] = 0; // special Throwable.getMessage()
+ // field Context
+ m_fields[ 1 ] = jni->GetFieldID(
+ (jclass) jo_class.get(), "Context", "Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_fields[ 1 ] );
+ }
+ else
+ {
+ // retrieve field ids for all direct members
+ sal_Int32 nMembers = td->nMembers;
+ m_fields = new jfieldID[ nMembers ];
+
+ for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos )
+ {
+ OString sig;
+ if (td->aBase.eTypeClass == typelib_TypeClass_STRUCT
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ td)->pParameterizedTypes != 0
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ td)->pParameterizedTypes[nPos])
+ {
+ sig = OString(
+ RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;"));
+ } else {
+ OStringBuffer sig_buf( 32 );
+ JNI_info::append_sig( &sig_buf, td->ppTypeRefs[ nPos ] );
+ sig = sig_buf.makeStringAndClear();
+ }
+
+ OString member_name(
+ OUStringToOString(
+ OUString::unacquired( &td->ppMemberNames[ nPos ] ),
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+
+ m_fields[ nPos ] = jni->GetFieldID(
+ (jclass) jo_class.get(), member_name.getStr(),
+ sig.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_fields[ nPos ] );
+ }
+ }
+ }
+ catch (...)
+ {
+ delete [] m_fields;
+ throw;
+ }
+
+ m_class = (jclass) jni->NewGlobalRef( jo_class.get() );
+}
+
+
+//______________________________________________________________________________
+JNI_type_info const * JNI_info::create_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td ) const
+{
+ OUString const & uno_name = OUString::unacquired( &td->pTypeName );
+
+ JNI_type_info * new_info;
+ switch (td->eTypeClass)
+ {
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ new_info = new JNI_compound_type_info( jni, td );
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ new_info = new JNI_interface_type_info( jni, td );
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("type info not supported for ") );
+ buf.append( uno_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+
+ // look up
+ JNI_type_info * info;
+ ClearableMutexGuard guard( m_mutex );
+ JNI_type_info_holder & holder = m_type_map[ uno_name ];
+ if (0 == holder.m_info) // new insertion
+ {
+ holder.m_info = new_info;
+ guard.clear();
+ info = new_info;
+ }
+ else // inserted in the meantime
+ {
+ info = holder.m_info;
+ guard.clear();
+ new_info->destroy( jni.get_jni_env() );
+ }
+ return info;
+}
+
+//______________________________________________________________________________
+JNI_type_info const * JNI_info::get_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td ) const
+{
+ if (is_XInterface( td->pWeakRef ))
+ {
+ return m_XInterface_type_info;
+ }
+
+ OUString const & uno_name = OUString::unacquired( &td->pTypeName );
+ JNI_type_info const * info;
+ ClearableMutexGuard guard( m_mutex );
+
+ t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
+ if (iFind == m_type_map.end())
+ {
+ guard.clear();
+ info = create_type_info( jni, td );
+ }
+ else
+ {
+ info = iFind->second.m_info;
+ }
+
+ return info;
+}
+
+//______________________________________________________________________________
+JNI_type_info const * JNI_info::get_type_info(
+ JNI_context const & jni, typelib_TypeDescriptionReference * type ) const
+{
+ if (is_XInterface( type ))
+ {
+ return m_XInterface_type_info;
+ }
+
+ OUString const & uno_name = OUString::unacquired( &type->pTypeName );
+ JNI_type_info const * info;
+ ClearableMutexGuard guard( m_mutex );
+ t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
+ if (iFind == m_type_map.end())
+ {
+ guard.clear();
+ TypeDescr td( type );
+ info = create_type_info( jni, td.get() );
+ }
+ else
+ {
+ info = iFind->second.m_info;
+ }
+
+ return info;
+}
+
+//______________________________________________________________________________
+JNI_type_info const * JNI_info::get_type_info(
+ JNI_context const & jni, OUString const & uno_name ) const
+{
+ if (uno_name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ))
+ {
+ return m_XInterface_type_info;
+ }
+
+ JNI_type_info const * info;
+ ClearableMutexGuard guard( m_mutex );
+ t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
+ if (iFind == m_type_map.end())
+ {
+ guard.clear();
+ css::uno::TypeDescription td( uno_name );
+ if (! td.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("UNO type not found: ") );
+ buf.append( uno_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ info = create_type_info( jni, td.get() );
+ }
+ else
+ {
+ info = iFind->second.m_info;
+ }
+
+ return info;
+}
+
+//______________________________________________________________________________
+JNI_info::JNI_info(
+ JNIEnv * jni_env, jobject class_loader, jclass classClass,
+ jmethodID methodForName )
+ : m_class_Class( classClass ),
+ m_method_Class_forName( methodForName ),
+ m_class_JNI_proxy( 0 ),
+ m_XInterface_queryInterface_td(
+ (reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ css::uno::TypeDescription(
+ ::getCppuType(
+ (css::uno::Reference< css::uno::XInterface > const *)0 ) )
+ .get())->ppMembers[ 0 ] ) ),
+ m_Exception_type( ::getCppuType( (css::uno::Exception const *)0 ) ),
+ m_RuntimeException_type(
+ ::getCppuType( (css::uno::RuntimeException const *)0 ) ),
+ m_void_type( ::getCppuVoidType() ),
+ m_XInterface_type_info( 0 )
+{
+ JNI_context jni( this, jni_env, class_loader ); // !no proper jni_info!
+
+ // class lookup
+ JLocalAutoRef jo_Object(
+ jni, find_class( jni, "java.lang.Object" ) );
+ JLocalAutoRef jo_Class(
+ jni, find_class( jni, "java.lang.Class" ) );
+ JLocalAutoRef jo_Throwable(
+ jni, find_class( jni, "java.lang.Throwable" ) );
+ JLocalAutoRef jo_Character(
+ jni, find_class( jni, "java.lang.Character" ) );
+ JLocalAutoRef jo_Boolean(
+ jni, find_class( jni, "java.lang.Boolean" ) );
+ JLocalAutoRef jo_Byte(
+ jni, find_class( jni, "java.lang.Byte" ) );
+ JLocalAutoRef jo_Short(
+ jni, find_class( jni, "java.lang.Short" ) );
+ JLocalAutoRef jo_Integer(
+ jni, find_class( jni, "java.lang.Integer" ) );
+ JLocalAutoRef jo_Long(
+ jni, find_class( jni, "java.lang.Long" ) );
+ JLocalAutoRef jo_Float(
+ jni, find_class( jni, "java.lang.Float" ) );
+ JLocalAutoRef jo_Double(
+ jni, find_class( jni, "java.lang.Double" ) );
+ JLocalAutoRef jo_String(
+ jni, find_class( jni, "java.lang.String" ) );
+ JLocalAutoRef jo_RuntimeException(
+ jni, find_class( jni, "com.sun.star.uno.RuntimeException" ) );
+ JLocalAutoRef jo_UnoRuntime(
+ jni, find_class( jni, "com.sun.star.uno.UnoRuntime" ) );
+ JLocalAutoRef jo_Any(
+ jni, find_class( jni, "com.sun.star.uno.Any" ) );
+ JLocalAutoRef jo_Enum(
+ jni, find_class( jni, "com.sun.star.uno.Enum" ) );
+ JLocalAutoRef jo_Type(
+ jni, find_class( jni, "com.sun.star.uno.Type" ) );
+ JLocalAutoRef jo_TypeClass(
+ jni, find_class( jni, "com.sun.star.uno.TypeClass" ) );
+ JLocalAutoRef jo_IEnvironment(
+ jni, find_class( jni, "com.sun.star.uno.IEnvironment" ) );
+ JLocalAutoRef jo_JNI_proxy(
+ jni, find_class( jni, "com.sun.star.bridges.jni_uno.JNI_proxy" ) );
+
+ // method Object.toString()
+ m_method_Object_toString = jni->GetMethodID(
+ (jclass) jo_Object.get(), "toString", "()Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Object_toString );
+ // method Class.getName()
+ m_method_Class_getName = jni->GetMethodID(
+ (jclass) jo_Class.get(), "getName", "()Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Class_getName );
+
+ // method Throwable.getMessage()
+ m_method_Throwable_getMessage = jni->GetMethodID(
+ (jclass) jo_Throwable.get(), "getMessage", "()Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Throwable_getMessage );
+
+ // method Character.charValue()
+ m_method_Character_charValue = jni->GetMethodID(
+ (jclass) jo_Character.get(), "charValue", "()C" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Character_charValue );
+ // method Boolean.booleanValue()
+ m_method_Boolean_booleanValue = jni->GetMethodID(
+ (jclass) jo_Boolean.get(), "booleanValue", "()Z" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Boolean_booleanValue );
+ // method Byte.byteValue()
+ m_method_Byte_byteValue = jni->GetMethodID(
+ (jclass) jo_Byte.get(), "byteValue", "()B" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Byte_byteValue );
+ // method Short.shortValue()
+ m_method_Short_shortValue = jni->GetMethodID(
+ (jclass) jo_Short.get(), "shortValue", "()S" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Short_shortValue );
+ // method Integer.intValue()
+ m_method_Integer_intValue = jni->GetMethodID(
+ (jclass) jo_Integer.get(), "intValue", "()I" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Integer_intValue );
+ // method Long.longValue()
+ m_method_Long_longValue = jni->GetMethodID(
+ (jclass) jo_Long.get(), "longValue", "()J" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Long_longValue );
+ // method Float.floatValue()
+ m_method_Float_floatValue = jni->GetMethodID(
+ (jclass) jo_Float.get(), "floatValue", "()F" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Float_floatValue );
+ // method Double.doubleValue()
+ m_method_Double_doubleValue = jni->GetMethodID(
+ (jclass) jo_Double.get(), "doubleValue", "()D" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Double_doubleValue );
+
+ // ctor Character( char )
+ m_ctor_Character_with_char = jni->GetMethodID(
+ (jclass) jo_Character.get(), "<init>", "(C)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Character_with_char );
+ // ctor Boolean( boolean )
+ m_ctor_Boolean_with_boolean = jni->GetMethodID(
+ (jclass) jo_Boolean.get(), "<init>", "(Z)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Boolean_with_boolean );
+ // ctor Byte( byte )
+ m_ctor_Byte_with_byte = jni->GetMethodID(
+ (jclass) jo_Byte.get(), "<init>", "(B)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Byte_with_byte );
+ // ctor Short( short )
+ m_ctor_Short_with_short = jni->GetMethodID(
+ (jclass) jo_Short.get(), "<init>", "(S)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Short_with_short );
+ // ctor Integer( int )
+ m_ctor_Integer_with_int = jni->GetMethodID(
+ (jclass) jo_Integer.get(), "<init>", "(I)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Integer_with_int );
+ // ctor Long( long )
+ m_ctor_Long_with_long = jni->GetMethodID(
+ (jclass) jo_Long.get(), "<init>", "(J)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Long_with_long );
+ // ctor Float( float )
+ m_ctor_Float_with_float = jni->GetMethodID(
+ (jclass) jo_Float.get(), "<init>", "(F)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Float_with_float );
+ // ctor Double( double )
+ m_ctor_Double_with_double = jni->GetMethodID(
+ (jclass) jo_Double.get(), "<init>", "(D)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Double_with_double );
+
+ // static method UnoRuntime.generateOid()
+ m_method_UnoRuntime_generateOid = jni->GetStaticMethodID(
+ (jclass) jo_UnoRuntime.get(),
+ "generateOid", "(Ljava/lang/Object;)Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_UnoRuntime_generateOid );
+ // static method UnoRuntime.queryInterface()
+ m_method_UnoRuntime_queryInterface = jni->GetStaticMethodID(
+ (jclass) jo_UnoRuntime.get(),
+ "queryInterface",
+ "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_UnoRuntime_queryInterface );
+
+ // field Enum.m_value
+ m_field_Enum_m_value = jni->GetFieldID(
+ (jclass) jo_Enum.get(), "m_value", "I" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_Enum_m_value );
+
+ // static method TypeClass.fromInt()
+ m_method_TypeClass_fromInt = jni->GetStaticMethodID(
+ (jclass) jo_TypeClass.get(),
+ "fromInt", "(I)Lcom/sun/star/uno/TypeClass;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_TypeClass_fromInt );
+
+ // ctor Type( Class )
+ m_ctor_Type_with_Class = jni->GetMethodID(
+ (jclass) jo_Type.get(), "<init>", "(Ljava/lang/Class;)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Type_with_Class );
+ // ctor Type( String, TypeClass )
+ m_ctor_Type_with_Name_TypeClass = jni->GetMethodID(
+ (jclass) jo_Type.get(),
+ "<init>", "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Type_with_Name_TypeClass );
+ // field Type._typeName
+ m_field_Type__typeName = jni->GetFieldID(
+ (jclass) jo_Type.get(), "_typeName", "Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_Type__typeName );
+
+ // ctor Any( Type, Object )
+ m_ctor_Any_with_Type_Object = jni->GetMethodID(
+ (jclass) jo_Any.get(),
+ "<init>", "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Any_with_Type_Object );
+
+ // field Any._type
+ m_field_Any__type = jni->GetFieldID(
+ (jclass) jo_Any.get(), "_type", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_Any__type );
+ // field Any._object
+ m_field_Any__object = jni->GetFieldID(
+ (jclass) jo_Any.get(), "_object", "Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_Any__object );
+
+ // method IEnvironment.getRegisteredInterface()
+ m_method_IEnvironment_getRegisteredInterface = jni->GetMethodID(
+ (jclass) jo_IEnvironment.get(),
+ "getRegisteredInterface",
+ "(Ljava/lang/String;Lcom/sun/star/uno/Type;)Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_IEnvironment_getRegisteredInterface );
+ // method IEnvironment.registerInterface()
+ m_method_IEnvironment_registerInterface = jni->GetMethodID(
+ (jclass) jo_IEnvironment.get(), "registerInterface",
+ "(Ljava/lang/Object;[Ljava/lang/String;Lcom/sun/star/uno/Type;)"
+ "Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_IEnvironment_registerInterface );
+
+ // static method JNI_proxy.get_proxy_ctor()
+ m_method_JNI_proxy_get_proxy_ctor = jni->GetStaticMethodID(
+ (jclass) jo_JNI_proxy.get(), "get_proxy_ctor",
+ "(Ljava/lang/Class;)Ljava/lang/reflect/Constructor;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_JNI_proxy_get_proxy_ctor );
+ // static method JNI_proxy.create()
+ m_method_JNI_proxy_create = jni->GetStaticMethodID(
+ (jclass) jo_JNI_proxy.get(), "create",
+ "(JLcom/sun/star/uno/IEnvironment;JJLcom/sun/star/uno/Type;Ljava/lang"
+ "/String;Ljava/lang/reflect/Constructor;)Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_JNI_proxy_create );
+ // field JNI_proxy.m_receiver_handle
+ m_field_JNI_proxy_m_receiver_handle = jni->GetFieldID(
+ (jclass) jo_JNI_proxy.get(), "m_receiver_handle", "J" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_JNI_proxy_m_receiver_handle );
+ // field JNI_proxy.m_td_handle
+ m_field_JNI_proxy_m_td_handle = jni->GetFieldID(
+ (jclass) jo_JNI_proxy.get(), "m_td_handle", "J" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_JNI_proxy_m_td_handle );
+ // field JNI_proxy.m_type
+ m_field_JNI_proxy_m_type = jni->GetFieldID(
+ (jclass) jo_JNI_proxy.get(), "m_type", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_JNI_proxy_m_type );
+ // field JNI_proxy.m_oid
+ m_field_JNI_proxy_m_oid = jni->GetFieldID(
+ (jclass) jo_JNI_proxy.get(), "m_oid", "Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_JNI_proxy_m_oid );
+
+ // get java env
+ OUString java_env_type_name( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_JAVA) );
+ JLocalAutoRef jo_java(
+ jni, ustring_to_jstring( jni, java_env_type_name.pData ) );
+ jvalue args[ 2 ];
+ args[ 0 ].l = jo_java.get();
+ args[ 1 ].l = 0;
+ jmethodID method_getEnvironment = jni->GetStaticMethodID(
+ (jclass) jo_UnoRuntime.get(), "getEnvironment",
+ "(Ljava/lang/String;Ljava/lang/Object;)"
+ "Lcom/sun/star/uno/IEnvironment;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != method_getEnvironment );
+ JLocalAutoRef jo_java_env(
+ jni, jni->CallStaticObjectMethodA(
+ (jclass) jo_UnoRuntime.get(), method_getEnvironment, args ) );
+
+ // get com.sun.star.uno.Any.VOID
+ jfieldID field_Any_VOID = jni->GetStaticFieldID(
+ (jclass) jo_Any.get(), "VOID", "Lcom/sun/star/uno/Any;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_Any_VOID );
+ JLocalAutoRef jo_Any_VOID(
+ jni, jni->GetStaticObjectField(
+ (jclass) jo_Any.get(), field_Any_VOID ) );
+ // get com.sun.star.uno.Type.UNSIGNED_SHORT
+ jfieldID field_Type_UNSIGNED_SHORT = jni->GetStaticFieldID(
+ (jclass) jo_Type.get(), "UNSIGNED_SHORT", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_Type_UNSIGNED_SHORT );
+ JLocalAutoRef jo_Type_UNSIGNED_SHORT(
+ jni, jni->GetStaticObjectField(
+ (jclass) jo_Type.get(), field_Type_UNSIGNED_SHORT ) );
+ // get com.sun.star.uno.Type.UNSIGNED_LONG
+ jfieldID field_Type_UNSIGNED_LONG = jni->GetStaticFieldID(
+ (jclass) jo_Type.get(), "UNSIGNED_LONG", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_Type_UNSIGNED_LONG );
+ JLocalAutoRef jo_Type_UNSIGNED_LONG(
+ jni, jni->GetStaticObjectField(
+ (jclass) jo_Type.get(), field_Type_UNSIGNED_LONG ) );
+ // get com.sun.star.uno.Type.UNSIGNED_HYPER
+ jfieldID field_Type_UNSIGNED_HYPER = jni->GetStaticFieldID(
+ (jclass) jo_Type.get(), "UNSIGNED_HYPER", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_Type_UNSIGNED_HYPER );
+ JLocalAutoRef jo_Type_UNSIGNED_HYPER(
+ jni, jni->GetStaticObjectField(
+ (jclass) jo_Type.get(), field_Type_UNSIGNED_HYPER ) );
+
+ // make global refs
+ m_class_UnoRuntime =
+ (jclass) jni->NewGlobalRef( jo_UnoRuntime.get() );
+ m_class_RuntimeException =
+ (jclass) jni->NewGlobalRef( jo_RuntimeException.get() );
+ m_class_Any =
+ (jclass) jni->NewGlobalRef( jo_Any.get() );
+ m_class_Type =
+ (jclass) jni->NewGlobalRef( jo_Type.get() );
+ m_class_TypeClass =
+ (jclass) jni->NewGlobalRef( jo_TypeClass.get() );
+ m_class_JNI_proxy =
+ (jclass) jni->NewGlobalRef( jo_JNI_proxy.get() );
+
+ m_class_Character =
+ (jclass) jni->NewGlobalRef( jo_Character.get() );
+ m_class_Boolean =
+ (jclass) jni->NewGlobalRef( jo_Boolean.get() );
+ m_class_Byte =
+ (jclass) jni->NewGlobalRef( jo_Byte.get() );
+ m_class_Short =
+ (jclass) jni->NewGlobalRef( jo_Short.get() );
+ m_class_Integer =
+ (jclass) jni->NewGlobalRef( jo_Integer.get() );
+ m_class_Long =
+ (jclass) jni->NewGlobalRef( jo_Long.get() );
+ m_class_Float =
+ (jclass) jni->NewGlobalRef( jo_Float.get() );
+ m_class_Double =
+ (jclass) jni->NewGlobalRef( jo_Double.get() );
+ m_class_String =
+ (jclass) jni->NewGlobalRef( jo_String.get() );
+ m_class_Object =
+ (jclass) jni->NewGlobalRef( jo_Object.get() );
+ m_class_Class =
+ (jclass) jni->NewGlobalRef( m_class_Class );
+
+ m_object_Any_VOID =
+ jni->NewGlobalRef( jo_Any_VOID.get() );
+ m_object_Type_UNSIGNED_SHORT =
+ jni->NewGlobalRef( jo_Type_UNSIGNED_SHORT.get() );
+ m_object_Type_UNSIGNED_LONG =
+ jni->NewGlobalRef( jo_Type_UNSIGNED_LONG.get() );
+ m_object_Type_UNSIGNED_HYPER =
+ jni->NewGlobalRef( jo_Type_UNSIGNED_HYPER.get() );
+ m_object_java_env = jni->NewGlobalRef( jo_java_env.get() );
+
+ try
+ {
+ css::uno::TypeDescription XInterface_td(
+ ::getCppuType(
+ (css::uno::Reference< css::uno::XInterface > const *)0 ) );
+ m_XInterface_type_info =
+ new JNI_interface_type_info( jni, XInterface_td.get() );
+ }
+ catch (...)
+ {
+ destruct( jni_env );
+ throw;
+ }
+}
+
+//______________________________________________________________________________
+void JNI_info::destruct( JNIEnv * jni_env )
+{
+ t_str2type::const_iterator iPos( m_type_map.begin() );
+ t_str2type::const_iterator const iEnd( m_type_map.begin() );
+ for ( ; iPos != iEnd; ++iPos )
+ {
+ iPos->second.m_info->destroy( jni_env );
+ }
+ if (0 != m_XInterface_type_info)
+ {
+ const_cast< JNI_interface_type_info * >(
+ m_XInterface_type_info )->destroy( jni_env );
+ }
+
+ // free global refs
+ jni_env->DeleteGlobalRef( m_object_java_env );
+ jni_env->DeleteGlobalRef( m_object_Any_VOID );
+ jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_SHORT );
+ jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_LONG );
+ jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_HYPER );
+
+ jni_env->DeleteGlobalRef( m_class_Class );
+ jni_env->DeleteGlobalRef( m_class_Object );
+ jni_env->DeleteGlobalRef( m_class_String );
+ jni_env->DeleteGlobalRef( m_class_Double );
+ jni_env->DeleteGlobalRef( m_class_Float );
+ jni_env->DeleteGlobalRef( m_class_Long );
+ jni_env->DeleteGlobalRef( m_class_Integer );
+ jni_env->DeleteGlobalRef( m_class_Short );
+ jni_env->DeleteGlobalRef( m_class_Byte );
+ jni_env->DeleteGlobalRef( m_class_Boolean );
+ jni_env->DeleteGlobalRef( m_class_Character );
+
+ jni_env->DeleteGlobalRef( m_class_JNI_proxy );
+ jni_env->DeleteGlobalRef( m_class_RuntimeException );
+ jni_env->DeleteGlobalRef( m_class_UnoRuntime );
+ jni_env->DeleteGlobalRef( m_class_TypeClass );
+ jni_env->DeleteGlobalRef( m_class_Type );
+ jni_env->DeleteGlobalRef( m_class_Any );
+}
+
+//______________________________________________________________________________
+JNI_info const * JNI_info::get_jni_info(
+ rtl::Reference< jvmaccess::UnoVirtualMachine > const & uno_vm )
+{
+ // !!!no JNI_info available at JNI_context!!!
+ ::jvmaccess::VirtualMachine::AttachGuard guard(
+ uno_vm->getVirtualMachine() );
+ JNIEnv * jni_env = guard.getEnvironment();
+ JNI_context jni(
+ 0, jni_env, static_cast< jobject >(uno_vm->getClassLoader()) );
+
+ jclass jo_class;
+ jmethodID jo_forName;
+ jni.getClassForName( &jo_class, &jo_forName );
+ jni.ensure_no_exception();
+ JLocalAutoRef jo_JNI_info_holder(
+ jni,
+ jni.findClass(
+ "com.sun.star.bridges.jni_uno.JNI_info_holder", jo_class,
+ jo_forName, false ) );
+ // field JNI_info_holder.m_jni_info_handle
+ jfieldID field_s_jni_info_handle =
+ jni->GetStaticFieldID(
+ (jclass) jo_JNI_info_holder.get(), "s_jni_info_handle", "J" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_s_jni_info_handle );
+
+ JNI_info const * jni_info =
+ reinterpret_cast< JNI_info const * >(
+ jni->GetStaticLongField(
+ (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle ) );
+ if (0 == jni_info) // un-initialized?
+ {
+ JNI_info * new_info = new JNI_info(
+ jni_env, static_cast< jobject >(uno_vm->getClassLoader()), jo_class,
+ jo_forName );
+
+ ClearableMutexGuard g( Mutex::getGlobalMutex() );
+ jni_info =
+ reinterpret_cast< JNI_info const * >(
+ jni->GetStaticLongField(
+ (jclass) jo_JNI_info_holder.get(),
+ field_s_jni_info_handle ) );
+ if (0 == jni_info) // still un-initialized?
+ {
+ jni->SetStaticLongField(
+ (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle,
+ reinterpret_cast< jlong >( new_info ) );
+ jni_info = new_info;
+ }
+ else
+ {
+ g.clear();
+ new_info->destroy( jni_env );
+ }
+ }
+
+ return jni_info;
+}
+
+}
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+JNIEXPORT void
+JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J(
+ JNIEnv * jni_env, jobject, jlong jni_info_handle )
+ SAL_THROW_EXTERN_C()
+{
+ ::jni_uno::JNI_info * jni_info =
+ reinterpret_cast< ::jni_uno::JNI_info * >( jni_info_handle );
+ jni_info->destroy( jni_env );
+}
+
+}
diff --git a/bridges/source/jni_uno/jni_info.h b/bridges/source/jni_uno/jni_info.h
new file mode 100644
index 000000000000..861ab9d5a52b
--- /dev/null
+++ b/bridges/source/jni_uno/jni_info.h
@@ -0,0 +1,375 @@
+/*************************************************************************
+ *
+ * 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 <hash_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;
+ ::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 ::std::hash_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
diff --git a/bridges/source/jni_uno/jni_java2uno.cxx b/bridges/source/jni_uno/jni_java2uno.cxx
new file mode 100644
index 000000000000..0ff4872804bb
--- /dev/null
+++ b/bridges/source/jni_uno/jni_java2uno.cxx
@@ -0,0 +1,704 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include "jni_bridge.h"
+//#include "jni_finalizer.h"
+
+#include <rtl/ustrbuf.hxx>
+
+#include <algorithm>
+
+
+using namespace ::rtl;
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+jobject Bridge::map_to_java(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, JNI_interface_type_info const * info ) const
+{
+ // get oid
+ rtl_uString * pOid = 0;
+ (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI );
+ OSL_ASSERT( 0 != pOid );
+ OUString oid( pOid, SAL_NO_ACQUIRE );
+
+ // opt getRegisteredInterface()
+ JLocalAutoRef jo_oid( jni, ustring_to_jstring( jni, oid.pData ) );
+ jvalue args[ 2 ];
+ args[ 0 ].l = jo_oid.get();
+ args[ 1 ].l = info->m_type;
+ jobject jo_iface = jni->CallObjectMethodA(
+ m_jni_info->m_object_java_env,
+ m_jni_info->m_method_IEnvironment_getRegisteredInterface, args );
+ jni.ensure_no_exception();
+
+ if (0 == jo_iface) // no registered iface
+ {
+ // register uno interface
+ (*m_uno_env->registerInterface)(
+ m_uno_env, reinterpret_cast< void ** >( &pUnoI ),
+ oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
+
+ // create java and register java proxy
+ jvalue args2[ 7 ];
+ acquire();
+ args2[ 0 ].j = reinterpret_cast< sal_Int64 >( this );
+ (*pUnoI->acquire)( pUnoI );
+ args2[ 1 ].l = m_jni_info->m_object_java_env;
+ args2[ 2 ].j = reinterpret_cast< sal_Int64 >( pUnoI );
+ typelib_typedescription_acquire( info->m_td.get() );
+ args2[ 3 ].j = reinterpret_cast< sal_Int64 >( info->m_td.get() );
+ args2[ 4 ].l = info->m_type;
+ args2[ 5 ].l = jo_oid.get();
+ args2[ 6 ].l = info->m_proxy_ctor;
+ jo_iface = jni->CallStaticObjectMethodA(
+ m_jni_info->m_class_JNI_proxy,
+ m_jni_info->m_method_JNI_proxy_create, args2 );
+ jni.ensure_no_exception();
+ }
+
+ OSL_ASSERT( 0 != jo_iface );
+ return jo_iface;
+}
+
+
+//______________________________________________________________________________
+void Bridge::handle_uno_exc( JNI_context const & jni, uno_Any * uno_exc ) const
+{
+ if (typelib_TypeClass_EXCEPTION == uno_exc->pType->eTypeClass)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // append java stack trace to Message member
+ reinterpret_cast< ::com::sun::star::uno::Exception * >(
+ uno_exc->pData )->Message += jni.get_stack_trace();
+#endif
+
+#if OSL_DEBUG_LEVEL > 1
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("exception occured java->uno: [") );
+ buf.append( OUString::unacquired( &uno_exc->pType->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
+ buf.append(
+ reinterpret_cast< ::com::sun::star::uno::Exception const * >(
+ uno_exc->pData )->Message );
+ OString cstr_msg(
+ OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+ }
+#endif
+ // signal exception
+ jvalue java_exc;
+ try
+ {
+ map_to_java(
+ jni, &java_exc, uno_exc->pData, uno_exc->pType, 0,
+ true /* in */, false /* no out */ );
+ }
+ catch (...)
+ {
+ uno_any_destruct( uno_exc, 0 );
+ throw;
+ }
+ uno_any_destruct( uno_exc, 0 );
+
+ JLocalAutoRef jo_exc( jni, java_exc.l );
+ jint res = jni->Throw( (jthrowable) jo_exc.get() );
+ if (0 != res)
+ {
+ // call toString()
+ JLocalAutoRef jo_descr(
+ jni, jni->CallObjectMethodA(
+ jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "throwing java exception failed: ") );
+ buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ OUString message(
+ OUSTR("thrown exception is no uno exception: ") +
+ OUString::unacquired( &uno_exc->pType->pTypeName ) +
+ jni.get_stack_trace() );
+ uno_any_destruct( uno_exc, 0 );
+ throw BridgeRuntimeError( message );
+ }
+}
+
+union largest
+{
+ sal_Int64 n;
+ double d;
+ void * p;
+ uno_Any a;
+};
+
+//______________________________________________________________________________
+jobject Bridge::call_uno(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, typelib_TypeDescription * member_td,
+ typelib_TypeDescriptionReference * return_type,
+ sal_Int32 nParams, typelib_MethodParameter const * pParams,
+ jobjectArray jo_args /* may be 0 */ ) const
+{
+ // return mem
+ sal_Int32 return_size;
+ switch (return_type->eTypeClass) {
+ case typelib_TypeClass_VOID:
+ return_size = 0;
+ break;
+
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ return_size = std::max(
+ TypeDescr(return_type).get()->nSize,
+ static_cast< sal_Int32 >(sizeof (largest)));
+ break;
+
+ default:
+ return_size = sizeof (largest);
+ break;
+ }
+
+#ifdef BROKEN_ALLOCA
+ char * mem = (char *) malloc(
+#else
+ char * mem = (char *) alloca(
+#endif
+ (nParams * sizeof (void *)) +
+ return_size + (nParams * sizeof (largest)) );
+ void ** uno_args = (void **) mem;
+ void * uno_ret = return_size == 0 ? 0 : (mem + (nParams * sizeof (void *)));
+ largest * uno_args_mem = (largest *)
+ (mem + (nParams * sizeof (void *)) + return_size);
+
+ OSL_ASSERT( (0 == nParams) || (nParams == jni->GetArrayLength( jo_args )) );
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = pParams[ nPos ];
+ typelib_TypeDescriptionReference * type = param.pTypeRef;
+
+ uno_args[ nPos ] = &uno_args_mem[ nPos ];
+ if (typelib_TypeClass_STRUCT == type->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == type->eTypeClass)
+ {
+ TypeDescr td( type );
+ if (sal::static_int_cast< sal_uInt32 >(td.get()->nSize)
+ > sizeof (largest))
+#ifdef BROKEN_ALLOCA
+ uno_args[ nPos ] = malloc( td.get()->nSize );
+#else
+ uno_args[ nPos ] = alloca( td.get()->nSize );
+#endif
+ }
+
+ if (param.bIn)
+ {
+ try
+ {
+ JLocalAutoRef jo_arg(
+ jni, jni->GetObjectArrayElement( jo_args, nPos ) );
+ jni.ensure_no_exception();
+ jvalue java_arg;
+ java_arg.l = jo_arg.get();
+ map_to_uno(
+ jni, uno_args[ nPos ], java_arg, type, 0,
+ false /* no assign */, sal_False != param.bOut,
+ true /* special wrapped integral types */ );
+ }
+ catch (...)
+ {
+ // cleanup uno in args
+ for ( sal_Int32 n = 0; n < nPos; ++n )
+ {
+ typelib_MethodParameter const & p = pParams[ n ];
+ if (p.bIn)
+ {
+ uno_type_destructData(
+ uno_args[ n ], p.pTypeRef, 0 );
+ }
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ throw;
+ }
+ }
+ }
+
+ uno_Any uno_exc_holder;
+ uno_Any * uno_exc = &uno_exc_holder;
+ // call binary uno
+ (*pUnoI->pDispatcher)( pUnoI, member_td, uno_ret, uno_args, &uno_exc );
+
+ if (0 == uno_exc)
+ {
+ // convert out args; destruct uno args
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = pParams[ nPos ];
+ typelib_TypeDescriptionReference * type = param.pTypeRef;
+ if (param.bOut)
+ {
+ try
+ {
+ // get out holder array[ 1 ]
+ JLocalAutoRef jo_out_holder(
+ jni, jni->GetObjectArrayElement( jo_args, nPos ) );
+ jni.ensure_no_exception();
+ jvalue java_arg;
+ java_arg.l = jo_out_holder.get();
+ map_to_java(
+ jni, &java_arg, uno_args[ nPos ], type, 0,
+ true /* in */, true /* out holder */ );
+ }
+ catch (...)
+ {
+ // cleanup further uno args
+ for ( sal_Int32 n = nPos; n < nParams; ++n )
+ {
+ uno_type_destructData(
+ uno_args[ n ], pParams[ n ].pTypeRef, 0 );
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+ // cleanup uno return value
+ uno_type_destructData( uno_ret, return_type, 0 );
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ throw;
+ }
+ }
+ if (typelib_TypeClass_DOUBLE < type->eTypeClass &&
+ typelib_TypeClass_ENUM != type->eTypeClass) // opt
+ {
+ uno_type_destructData( uno_args[ nPos ], type, 0 );
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+ }
+
+ if (typelib_TypeClass_VOID != return_type->eTypeClass)
+ {
+ // convert uno return value
+ jvalue java_ret;
+ try
+ {
+ map_to_java(
+ jni, &java_ret, uno_ret, return_type, 0,
+ true /* in */, false /* no out */,
+ true /* special_wrapped_integral_types */ );
+ }
+ catch (...)
+ {
+ uno_type_destructData( uno_ret, return_type, 0 );
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ throw;
+ }
+ if (typelib_TypeClass_DOUBLE < return_type->eTypeClass &&
+ typelib_TypeClass_ENUM != return_type->eTypeClass) // opt
+ {
+ uno_type_destructData( uno_ret, return_type, 0 );
+ }
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ return java_ret.l;
+ }
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ return 0; // void return
+ }
+ else // exception occured
+ {
+ // destruct uno in args
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = pParams[ nPos ];
+ if (param.bIn)
+ uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 );
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+
+ handle_uno_exc( jni, uno_exc );
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ return 0;
+ }
+}
+
+}
+
+using namespace ::jni_uno;
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+JNIEXPORT jobject
+JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call(
+ JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle, jstring,
+ jstring jo_method, jobjectArray jo_args /* may be 0 */ )
+ SAL_THROW_EXTERN_C()
+{
+ Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JNI_context jni(
+ jni_info, jni_env,
+ static_cast< jobject >(
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext )->getClassLoader() ) );
+
+ OUString method_name;
+
+ try
+ {
+ method_name = jstring_to_oustring( jni, jo_method );
+#if OSL_DEBUG_LEVEL > 1
+ {
+ OUStringBuffer trace_buf( 64 );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("java->uno call: ") );
+ trace_buf.append( method_name );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") );
+ JLocalAutoRef jo_oid(
+ jni, jni->GetObjectField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
+ OString cstr_msg(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+ }
+#endif
+
+ // special IQueryInterface.queryInterface()
+ if (method_name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("queryInterface") ))
+ {
+ // oid
+ JLocalAutoRef jo_oid(
+ jni, jni->GetObjectField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
+ // type
+ JLocalAutoRef jo_type(
+ jni, jni->GetObjectArrayElement( jo_args, 0 ) );
+ jni.ensure_no_exception();
+
+ JLocalAutoRef jo_type_name(
+ jni, jni->GetObjectField(
+ jo_type.get(), jni_info->m_field_Type__typeName ) );
+ if (! jo_type_name.is())
+ {
+ throw BridgeRuntimeError(
+ OUSTR("incomplete type object: no type name!") +
+ jni.get_stack_trace() );
+ }
+ OUString type_name(
+ jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
+ JNI_type_info const * info =
+ jni_info->get_type_info( jni, type_name );
+ if (typelib_TypeClass_INTERFACE != info->m_td.get()->eTypeClass)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("queryInterface() call demands an INTERFACE type!") );
+ }
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >( info );
+
+ // getRegisteredInterface() already tested in JNI_proxy:
+ // perform queryInterface call on binary uno interface
+ uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
+
+ uno_Any uno_ret;
+ void * uno_args[] = { &iface_info->m_td.get()->pWeakRef };
+ uno_Any uno_exc_holder;
+ uno_Any * uno_exc = &uno_exc_holder;
+ // call binary uno
+ (*pUnoI->pDispatcher)(
+ pUnoI, jni_info->m_XInterface_queryInterface_td.get(),
+ &uno_ret, uno_args, &uno_exc );
+ if (0 == uno_exc)
+ {
+ jobject jo_ret = 0;
+ if (typelib_TypeClass_INTERFACE == uno_ret.pType->eTypeClass)
+ {
+ uno_Interface * pUnoRet =
+ (uno_Interface *) uno_ret.pReserved;
+ if (0 != pUnoRet)
+ {
+ try
+ {
+ jo_ret =
+ bridge->map_to_java( jni, pUnoRet, iface_info );
+ }
+ catch (...)
+ {
+ uno_any_destruct( &uno_ret, 0 );
+ throw;
+ }
+ }
+ }
+ uno_any_destruct( &uno_ret, 0 );
+ return jo_ret;
+ }
+ else
+ {
+ bridge->handle_uno_exc( jni, uno_exc );
+ return 0;
+ }
+ }
+
+ typelib_InterfaceTypeDescription * td =
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
+ uno_Interface * pUnoI =
+ reinterpret_cast< uno_Interface * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
+
+ typelib_TypeDescriptionReference ** ppAllMembers = td->ppAllMembers;
+ for ( sal_Int32 nPos = td->nAllMembers; nPos--; )
+ {
+ // try to avoid getting typedescription as long as possible,
+ // because of a Mutex.acquire() in
+ // typelib_typedescriptionreference_getDescription()
+ typelib_TypeDescriptionReference * member_type =
+ ppAllMembers[ nPos ];
+
+ // check method_name against fully qualified type_name
+ // of member_type; type_name is of the form
+ // <name> "::" <method_name> *(":@" <idx> "," <idx> ":" <name>)
+ OUString const & type_name =
+ OUString::unacquired( &member_type->pTypeName );
+ sal_Int32 offset = type_name.indexOf( ':' ) + 2;
+ OSL_ASSERT(
+ offset >= 2 && offset < type_name.getLength()
+ && type_name[offset - 1] == ':' );
+ sal_Int32 remainder = type_name.getLength() - offset;
+ if (typelib_TypeClass_INTERFACE_METHOD == member_type->eTypeClass)
+ {
+ if ((method_name.getLength() == remainder
+ || (method_name.getLength() < remainder
+ && type_name[offset + method_name.getLength()] == ':'))
+ && type_name.match(method_name, offset))
+ {
+ TypeDescr member_td( member_type );
+ typelib_InterfaceMethodTypeDescription * method_td =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member_td.get() );
+ return bridge->call_uno(
+ jni, pUnoI, member_td.get(),
+ method_td->pReturnTypeRef,
+ method_td->nParams, method_td->pParams,
+ jo_args );
+ }
+ }
+ else // attribute
+ {
+ OSL_ASSERT(
+ typelib_TypeClass_INTERFACE_ATTRIBUTE ==
+ member_type->eTypeClass );
+
+ if (method_name.getLength() >= 3
+ && (method_name.getLength() - 3 == remainder
+ || (method_name.getLength() - 3 < remainder
+ && type_name[
+ offset + (method_name.getLength() - 3)] == ':'))
+ && method_name[1] == 'e' && method_name[2] == 't'
+ && rtl_ustr_compare_WithLength(
+ type_name.getStr() + offset,
+ method_name.getLength() - 3,
+ method_name.getStr() + 3,
+ method_name.getLength() - 3) == 0)
+ {
+ if ('g' == method_name[ 0 ])
+ {
+ TypeDescr member_td( member_type );
+ typelib_InterfaceAttributeTypeDescription * attr_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member_td.get() );
+ return bridge->call_uno(
+ jni, pUnoI, member_td.get(),
+ attr_td->pAttributeTypeRef,
+ 0, 0,
+ jo_args );
+ }
+ else if ('s' == method_name[ 0 ])
+ {
+ TypeDescr member_td( member_type );
+ typelib_InterfaceAttributeTypeDescription * attr_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member_td.get() );
+ if (! attr_td->bReadOnly)
+ {
+ typelib_MethodParameter param;
+ param.pTypeRef = attr_td->pAttributeTypeRef;
+ param.bIn = sal_True;
+ param.bOut = sal_False;
+ return bridge->call_uno(
+ jni, pUnoI, member_td.get(),
+ jni_info->m_void_type.getTypeLibType(),
+ 1, &param,
+ jo_args );
+ }
+ }
+ }
+ }
+ }
+ // the thing that should not be... no method info found!
+ OUStringBuffer buf( 64 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "calling undeclared function on interface ") );
+ buf.append( OUString::unacquired(
+ &((typelib_TypeDescription *)td)->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ buf.append( method_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ catch (BridgeRuntimeError & err)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("[jni_uno bridge error] "
+ "Java calling UNO method ") );
+ buf.append( method_name );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ buf.append( err.m_message );
+ // notify RuntimeException
+ OString cstr_msg(
+ OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_JAVA_UTF8 ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+ if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
+ != 0)
+ {
+ OSL_ASSERT( false );
+ }
+ return 0;
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OString cstr_msg(
+ OString( RTL_CONSTASCII_STRINGPARAM(
+ "[jni_uno bridge error] "
+ "attaching current thread to java failed!") ) +
+ OUStringToOString(
+ jni.get_stack_trace(), RTL_TEXTENCODING_JAVA_UTF8 ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+ if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
+ != 0)
+ {
+ OSL_ASSERT( false );
+ }
+ return 0;
+ }
+}
+
+//------------------------------------------------------------------------------
+JNIEXPORT void
+JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J(
+ JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle )
+ SAL_THROW_EXTERN_C()
+{
+ Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JNI_context jni(
+ jni_info, jni_env,
+ static_cast< jobject >(
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext )->getClassLoader() ) );
+
+ uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
+ typelib_TypeDescription * td =
+ reinterpret_cast< typelib_TypeDescription * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
+
+#if OSL_DEBUG_LEVEL > 1
+ {
+ JLocalAutoRef jo_oid(
+ jni, jni->GetObjectField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
+ OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("freeing java uno proxy: ") + oid,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+ }
+#endif
+ // revoke from uno env; has already been revoked from java env
+ (*bridge->m_uno_env->revokeInterface)( bridge->m_uno_env, pUnoI );
+ // release receiver
+ (*pUnoI->release)( pUnoI );
+ // release typedescription handle
+ typelib_typedescription_release( td );
+ // release bridge handle
+ bridge->release();
+}
+
+}
diff --git a/bridges/source/jni_uno/jni_uno2java.cxx b/bridges/source/jni_uno/jni_uno2java.cxx
new file mode 100644
index 000000000000..81ae922ae717
--- /dev/null
+++ b/bridges/source/jni_uno/jni_uno2java.cxx
@@ -0,0 +1,873 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include "rtl/ustrbuf.hxx"
+
+#include "jni_bridge.h"
+
+
+using namespace ::std;
+using namespace ::rtl;
+
+namespace
+{
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
+ SAL_THROW_EXTERN_C();
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_acquire( uno_Interface * pUnoI )
+ SAL_THROW_EXTERN_C();
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_release( uno_Interface * pUnoI )
+ SAL_THROW_EXTERN_C();
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_dispatch(
+ uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
+ void * uno_ret, void * uno_args[], uno_Any ** uno_exc )
+ SAL_THROW_EXTERN_C();
+}
+}
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+void Bridge::handle_java_exc(
+ JNI_context const & jni,
+ JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) const
+{
+ OSL_ASSERT( jo_exc.is() );
+ if (! jo_exc.is())
+ {
+ throw BridgeRuntimeError(
+ OUSTR("java exception occured, but no java exception available!?") +
+ jni.get_stack_trace() );
+ }
+
+ JLocalAutoRef jo_class( jni, jni->GetObjectClass( jo_exc.get() ) );
+ JLocalAutoRef jo_class_name(
+ jni, jni->CallObjectMethodA(
+ jo_class.get(), m_jni_info->m_method_Class_getName, 0 ) );
+ jni.ensure_no_exception();
+ OUString exc_name(
+ jstring_to_oustring( jni, (jstring) jo_class_name.get() ) );
+
+ ::com::sun::star::uno::TypeDescription td( exc_name.pData );
+ if (!td.is() || (typelib_TypeClass_EXCEPTION != td.get()->eTypeClass))
+ {
+ // call toString()
+ JLocalAutoRef jo_descr(
+ jni, jni->CallObjectMethodA(
+ jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("non-UNO exception occurred: ") );
+ buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ buf.append( jni.get_stack_trace( jo_exc.get() ) );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ auto_ptr< rtl_mem > uno_data( rtl_mem::allocate( td.get()->nSize ) );
+ jvalue val;
+ val.l = jo_exc.get();
+ map_to_uno(
+ jni, uno_data.get(), val, td.get()->pWeakRef, 0,
+ false /* no assign */, false /* no out param */ );
+
+#if OSL_DEBUG_LEVEL > 0
+ // patch Message, append stack trace
+ reinterpret_cast< ::com::sun::star::uno::Exception * >(
+ uno_data.get() )->Message += jni.get_stack_trace( jo_exc.get() );
+#endif
+
+ typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
+ uno_exc->pType = td.get()->pWeakRef;
+ uno_exc->pData = uno_data.release();
+
+#if OSL_DEBUG_LEVEL > 1
+ OUStringBuffer trace_buf( 128 );
+ trace_buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("exception occured uno->java: [") );
+ trace_buf.append( exc_name );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
+ trace_buf.append(
+ reinterpret_cast< ::com::sun::star::uno::Exception const * >(
+ uno_exc->pData )->Message );
+ OString cstr_trace(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_trace.getStr() );
+#endif
+}
+
+//______________________________________________________________________________
+void Bridge::call_java(
+ jobject javaI, typelib_InterfaceTypeDescription * iface_td,
+ sal_Int32 local_member_index, sal_Int32 function_pos_offset,
+ typelib_TypeDescriptionReference * return_type,
+ typelib_MethodParameter * params, sal_Int32 nParams,
+ void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const
+{
+ OSL_ASSERT( function_pos_offset == 0 || function_pos_offset == 1 );
+
+ JNI_guarded_context jni(
+ m_jni_info, reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ m_java_env->pContext ) );
+
+ // assure fully initialized iface_td:
+ ::com::sun::star::uno::TypeDescription iface_holder;
+ if (! iface_td->aBase.bComplete) {
+ iface_holder = ::com::sun::star::uno::TypeDescription(
+ reinterpret_cast<typelib_TypeDescription *>(iface_td) );
+ iface_holder.makeComplete();
+ if (! iface_holder.get()->bComplete) {
+ OUStringBuffer buf;
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("cannot make type complete: ") );
+ buf.append( OUString::unacquired(&iface_holder.get()->pTypeName) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ iface_td = reinterpret_cast<typelib_InterfaceTypeDescription *>(
+ iface_holder.get() );
+ OSL_ASSERT( iface_td->aBase.eTypeClass == typelib_TypeClass_INTERFACE );
+ }
+
+ // prepare java args, save param td
+#ifdef BROKEN_ALLOCA
+ jvalue * java_args = (jvalue *) malloc( sizeof (jvalue) * nParams );
+#else
+ jvalue * java_args = (jvalue *) alloca( sizeof (jvalue) * nParams );
+#endif
+
+ sal_Int32 nPos;
+ for ( nPos = 0; nPos < nParams; ++nPos )
+ {
+ try
+ {
+ typelib_MethodParameter const & param = params[ nPos ];
+ java_args[ nPos ].l = 0; // if out: build up array[ 1 ]
+ map_to_java(
+ jni, &java_args[ nPos ],
+ uno_args[ nPos ],
+ param.pTypeRef, 0,
+ sal_False != param.bIn /* convert uno value */,
+ sal_False != param.bOut /* build up array[ 1 ] */ );
+ }
+ catch (...)
+ {
+ // cleanup
+ for ( sal_Int32 n = 0; n < nPos; ++n )
+ {
+ typelib_MethodParameter const & param = params[ n ];
+ if (param.bOut ||
+ typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
+ {
+ jni->DeleteLocalRef( java_args[ n ].l );
+ }
+ }
+#ifdef BROKEN_ALLOCA
+ free( java_args );
+#endif
+ throw;
+ }
+ }
+
+ sal_Int32 base_members = iface_td->nAllMembers - iface_td->nMembers;
+ OSL_ASSERT( base_members < iface_td->nAllMembers );
+ sal_Int32 base_members_function_pos =
+ iface_td->pMapMemberIndexToFunctionIndex[ base_members ];
+ sal_Int32 member_pos = base_members + local_member_index;
+ OSL_ENSURE(
+ member_pos < iface_td->nAllMembers, "### member pos out of range!" );
+ sal_Int32 function_pos =
+ iface_td->pMapMemberIndexToFunctionIndex[ member_pos ]
+ + function_pos_offset;
+ OSL_ENSURE(
+ function_pos >= base_members_function_pos
+ && function_pos < iface_td->nMapFunctionIndexToMemberIndex,
+ "### illegal function index!" );
+ function_pos -= base_members_function_pos;
+
+ JNI_interface_type_info const * info =
+ static_cast< JNI_interface_type_info const * >(
+ m_jni_info->get_type_info( jni, &iface_td->aBase ) );
+ jmethodID method_id = info->m_methods[ function_pos ];
+
+#if OSL_DEBUG_LEVEL > 1
+ OUStringBuffer trace_buf( 128 );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("calling ") );
+ JLocalAutoRef jo_method(
+ jni, jni->ToReflectedMethod( info->m_class, method_id, JNI_FALSE ) );
+ jni.ensure_no_exception();
+ JLocalAutoRef jo_descr(
+ jni, jni->CallObjectMethodA(
+ jo_method.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on ") );
+ jo_descr.reset(
+ jni->CallObjectMethodA(
+ javaI, m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (") );
+ JLocalAutoRef jo_class( jni, jni->GetObjectClass( javaI ) );
+ jo_descr.reset(
+ jni->CallObjectMethodA(
+ jo_class.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(")") );
+ OString cstr_trace(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_trace.getStr() );
+#endif
+
+ // complex return value
+ JLocalAutoRef java_ret( jni );
+
+ switch (return_type->eTypeClass)
+ {
+ case typelib_TypeClass_VOID:
+ jni->CallVoidMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_CHAR:
+ *(sal_Unicode *)uno_ret =
+ jni->CallCharMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ *(sal_Bool *)uno_ret =
+ jni->CallBooleanMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_BYTE:
+ *(sal_Int8 *)uno_ret =
+ jni->CallByteMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(sal_Int16 *)uno_ret =
+ jni->CallShortMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *(sal_Int32 *)uno_ret =
+ jni->CallIntMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *(sal_Int64 *)uno_ret =
+ jni->CallLongMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float *)uno_ret =
+ jni->CallFloatMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double *)uno_ret =
+ jni->CallDoubleMethodA( javaI, method_id, java_args );
+ break;
+ default:
+ java_ret.reset(
+ jni->CallObjectMethodA( javaI, method_id, java_args ) );
+ break;
+ }
+
+ if (jni->ExceptionCheck())
+ {
+ JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
+ jni->ExceptionClear();
+
+ // release temp java local refs
+ for ( nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = params[ nPos ];
+ if (param.bOut ||
+ typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
+ {
+ jni->DeleteLocalRef( java_args[ nPos ].l );
+ }
+ }
+
+ handle_java_exc( jni, jo_exc, *uno_exc );
+ }
+ else // no exception
+ {
+ for ( nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = params[ nPos ];
+ if (param.bOut)
+ {
+ try
+ {
+ map_to_uno(
+ jni, uno_args[ nPos ],
+ java_args[ nPos ], param.pTypeRef, 0,
+ sal_False != param.bIn /* assign if inout */,
+ true /* out param */ );
+ }
+ catch (...)
+ {
+ // cleanup uno pure out
+ for ( sal_Int32 n = 0; n < nPos; ++n )
+ {
+ typelib_MethodParameter const & p = params[ n ];
+ if (! p.bIn)
+ {
+ uno_type_destructData(
+ uno_args[ n ], p.pTypeRef, 0 );
+ }
+ }
+ // cleanup java temp local refs
+ for ( ; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & p = params[ nPos ];
+ if (p.bOut ||
+ typelib_TypeClass_DOUBLE <
+ p.pTypeRef->eTypeClass)
+ {
+ jni->DeleteLocalRef( java_args[ nPos ].l );
+ }
+ }
+#ifdef BROKEN_ALLOCA
+ free( java_args );
+#endif
+ throw;
+ }
+ jni->DeleteLocalRef( java_args[ nPos ].l );
+ }
+ else // pure temp in param
+ {
+ if (typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
+ jni->DeleteLocalRef( java_args[ nPos ].l );
+ }
+ }
+
+ // return value
+ if (typelib_TypeClass_DOUBLE < return_type->eTypeClass)
+ {
+ try
+ {
+ jvalue val;
+ val.l = java_ret.get();
+ map_to_uno(
+ jni, uno_ret, val, return_type, 0,
+ false /* no assign */, false /* no out param */ );
+ }
+ catch (...)
+ {
+ // cleanup uno pure out
+ for ( sal_Int32 i = 0; i < nParams; ++i )
+ {
+ typelib_MethodParameter const & param = params[ i ];
+ if (! param.bIn)
+ {
+ uno_type_destructData(
+ uno_args[ i ], param.pTypeRef, 0 );
+ }
+ }
+#ifdef BROKEN_ALLOCA
+ free( java_args );
+#endif
+ throw;
+ }
+ } // else: already set integral uno return value
+
+ // no exception occured
+ *uno_exc = 0;
+ }
+#ifdef BROKEN_ALLOCA
+ free( java_args );
+#endif
+}
+
+//==== a uno proxy wrapping a java interface ===================================
+struct UNO_proxy : public uno_Interface
+{
+ mutable oslInterlockedCount m_ref;
+ Bridge const * m_bridge;
+
+ // mapping information
+ jobject m_javaI;
+ jstring m_jo_oid;
+ OUString m_oid;
+ JNI_interface_type_info const * m_type_info;
+
+ inline void acquire() const;
+ inline void release() const;
+
+ // ctor
+ inline UNO_proxy(
+ JNI_context const & jni, Bridge const * bridge,
+ jobject javaI, jstring jo_oid, OUString const & oid,
+ JNI_interface_type_info const * info );
+};
+
+//______________________________________________________________________________
+inline UNO_proxy::UNO_proxy(
+ JNI_context const & jni, Bridge const * bridge,
+ jobject javaI, jstring jo_oid, OUString const & oid,
+ JNI_interface_type_info const * info )
+ : m_ref( 1 ),
+ m_oid( oid ),
+ m_type_info( info )
+{
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JLocalAutoRef jo_string_array(
+ jni, jni->NewObjectArray( 1, jni_info->m_class_String, jo_oid ) );
+ jni.ensure_no_exception();
+ jvalue args[ 3 ];
+ args[ 0 ].l = javaI;
+ args[ 1 ].l = jo_string_array.get();
+ args[ 2 ].l = info->m_type;
+ jobject jo_iface = jni->CallObjectMethodA(
+ jni_info->m_object_java_env,
+ jni_info->m_method_IEnvironment_registerInterface, args );
+ jni.ensure_no_exception();
+
+ m_javaI = jni->NewGlobalRef( jo_iface );
+ m_jo_oid = (jstring) jni->NewGlobalRef( jo_oid );
+ bridge->acquire();
+ m_bridge = bridge;
+
+ // uno_Interface
+ uno_Interface::acquire = UNO_proxy_acquire;
+ uno_Interface::release = UNO_proxy_release;
+ uno_Interface::pDispatcher = UNO_proxy_dispatch;
+}
+
+//______________________________________________________________________________
+inline void UNO_proxy::acquire() const
+{
+ if (1 == osl_incrementInterlockedCount( &m_ref ))
+ {
+ // rebirth of proxy zombie
+ void * that = const_cast< UNO_proxy * >( this );
+ // register at uno env
+ (*m_bridge->m_uno_env->registerProxyInterface)(
+ m_bridge->m_uno_env, &that,
+ UNO_proxy_free, m_oid.pData,
+ (typelib_InterfaceTypeDescription *)m_type_info->m_td.get() );
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ASSERT( this == (void const * const)that );
+#endif
+ }
+}
+
+//______________________________________________________________________________
+inline void UNO_proxy::release() const
+{
+ if (0 == osl_decrementInterlockedCount( &m_ref ))
+ {
+ // revoke from uno env on last release
+ (*m_bridge->m_uno_env->revokeInterface)(
+ m_bridge->m_uno_env, const_cast< UNO_proxy * >( this ) );
+ }
+}
+
+
+//______________________________________________________________________________
+uno_Interface * Bridge::map_to_uno(
+ JNI_context const & jni,
+ jobject javaI, JNI_interface_type_info const * info ) const
+{
+ JLocalAutoRef jo_oid( jni, compute_oid( jni, javaI ) );
+ OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
+
+ uno_Interface * pUnoI = 0;
+ (*m_uno_env->getRegisteredInterface)(
+ m_uno_env, (void **)&pUnoI,
+ oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
+
+ if (0 == pUnoI) // no existing interface, register new proxy
+ {
+ // refcount initially 1
+ pUnoI = new UNO_proxy(
+ jni, const_cast< Bridge * >( this ),
+ javaI, (jstring) jo_oid.get(), oid, info );
+
+ (*m_uno_env->registerProxyInterface)(
+ m_uno_env, (void **)&pUnoI,
+ UNO_proxy_free,
+ oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
+ }
+ return pUnoI;
+}
+
+}
+
+using namespace ::jni_uno;
+
+namespace
+{
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
+ SAL_THROW_EXTERN_C()
+{
+ UNO_proxy const * that = reinterpret_cast< UNO_proxy const * >( proxy );
+ Bridge const * bridge = that->m_bridge;
+
+ if ( env != bridge->m_uno_env ) {
+ OSL_ASSERT(false);
+ }
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("freeing binary uno proxy: ") + that->m_oid,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+#endif
+
+ try
+ {
+ JNI_guarded_context jni(
+ bridge->m_jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+
+ jni->DeleteGlobalRef( that->m_javaI );
+ jni->DeleteGlobalRef( that->m_jo_oid );
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg2(
+ OUStringToOString( err.m_message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg2.getStr() );
+#else
+ (void) err; // unused
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(
+ 0,
+ "[jni_uno bridge error] attaching current thread to java failed!" );
+ }
+
+ bridge->release();
+#if OSL_DEBUG_LEVEL > 1
+ *(int *)that = 0xdeadcafe;
+#endif
+ delete that;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_acquire( uno_Interface * pUnoI )
+ SAL_THROW_EXTERN_C()
+{
+ UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
+ that->acquire();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_release( uno_Interface * pUnoI )
+ SAL_THROW_EXTERN_C()
+{
+ UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
+ that->release();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_dispatch(
+ uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
+ void * uno_ret, void * uno_args [], uno_Any ** uno_exc )
+ SAL_THROW_EXTERN_C()
+{
+ UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
+ Bridge const * bridge = that->m_bridge;
+
+#if OSL_DEBUG_LEVEL > 1
+ OUStringBuffer trace_buf( 64 );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno->java call: ") );
+ trace_buf.append( OUString::unacquired( &member_td->pTypeName ) );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") );
+ trace_buf.append( that->m_oid );
+ OString cstr_msg(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+#endif
+
+ try
+ {
+ switch (member_td->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ typelib_InterfaceAttributeTypeDescription const * attrib_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ member_td );
+ com::sun::star::uno::TypeDescription attrib_holder;
+ while ( attrib_td->pBaseRef != 0 ) {
+ attrib_holder = com::sun::star::uno::TypeDescription(
+ attrib_td->pBaseRef );
+ OSL_ASSERT(
+ attrib_holder.get()->eTypeClass
+ == typelib_TypeClass_INTERFACE_ATTRIBUTE );
+ attrib_td = reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ attrib_holder.get() );
+ }
+ typelib_InterfaceTypeDescription * iface_td = attrib_td->pInterface;
+
+ if (0 == uno_ret) // is setter method
+ {
+ typelib_MethodParameter param;
+ param.pTypeRef = attrib_td->pAttributeTypeRef;
+ param.bIn = sal_True;
+ param.bOut = sal_False;
+
+ bridge->call_java(
+ that->m_javaI, iface_td,
+ attrib_td->nIndex, 1, // get, then set method
+ bridge->m_jni_info->m_void_type.getTypeLibType(),
+ &param, 1,
+ 0, uno_args, uno_exc );
+ }
+ else // is getter method
+ {
+ bridge->call_java(
+ that->m_javaI, iface_td, attrib_td->nIndex, 0,
+ attrib_td->pAttributeTypeRef,
+ 0, 0, // no params
+ uno_ret, 0, uno_exc );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ typelib_InterfaceMethodTypeDescription const * method_td =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ member_td );
+ com::sun::star::uno::TypeDescription method_holder;
+ while ( method_td->pBaseRef != 0 ) {
+ method_holder = com::sun::star::uno::TypeDescription(
+ method_td->pBaseRef );
+ OSL_ASSERT(
+ method_holder.get()->eTypeClass
+ == typelib_TypeClass_INTERFACE_METHOD );
+ method_td = reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ method_holder.get() );
+ }
+ typelib_InterfaceTypeDescription * iface_td = method_td->pInterface;
+
+ switch ( method_td->aBase.nPosition )
+ {
+ case 0: // queryInterface()
+ {
+ TypeDescr demanded_td(
+ *reinterpret_cast< typelib_TypeDescriptionReference ** >(
+ uno_args[ 0 ] ) );
+ if (typelib_TypeClass_INTERFACE !=
+ demanded_td.get()->eTypeClass)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("queryInterface() call demands "
+ "an INTERFACE type!") );
+ }
+
+ uno_Interface * pInterface = 0;
+ (*bridge->m_uno_env->getRegisteredInterface)(
+ bridge->m_uno_env,
+ (void **) &pInterface, that->m_oid.pData,
+ (typelib_InterfaceTypeDescription *)demanded_td.get() );
+
+ if (0 == pInterface)
+ {
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JNI_guarded_context jni(
+ jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+
+ JNI_interface_type_info const * info =
+ static_cast< JNI_interface_type_info const * >(
+ jni_info->get_type_info( jni, demanded_td.get() ) );
+
+ jvalue args[ 2 ];
+ args[ 0 ].l = info->m_type;
+ args[ 1 ].l = that->m_javaI;
+
+ JLocalAutoRef jo_ret(
+ jni, jni->CallStaticObjectMethodA(
+ jni_info->m_class_UnoRuntime,
+ jni_info->m_method_UnoRuntime_queryInterface,
+ args ) );
+
+ if (jni->ExceptionCheck())
+ {
+ JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
+ jni->ExceptionClear();
+ bridge->handle_java_exc( jni, jo_exc, *uno_exc );
+ }
+ else
+ {
+ if (jo_ret.is())
+ {
+#if OSL_DEBUG_LEVEL > 0
+ JLocalAutoRef jo_oid(
+ jni, compute_oid( jni, jo_ret.get() ) );
+ OUString oid( jstring_to_oustring(
+ jni, (jstring) jo_oid.get() ) );
+ OSL_ENSURE(
+ oid.equals( that->m_oid ),
+ "### different oids!" );
+#endif
+ // refcount initially 1
+ uno_Interface * pUnoI2 = new UNO_proxy(
+ jni, bridge, jo_ret.get(),
+ that->m_jo_oid, that->m_oid, info );
+
+ (*bridge->m_uno_env->registerProxyInterface)(
+ bridge->m_uno_env,
+ (void **) &pUnoI2,
+ UNO_proxy_free, that->m_oid.pData,
+ reinterpret_cast<
+ typelib_InterfaceTypeDescription * >(
+ info->m_td.get() ) );
+
+ uno_any_construct(
+ (uno_Any *)uno_ret, &pUnoI2,
+ demanded_td.get(), 0 );
+ (*pUnoI2->release)( pUnoI2 );
+ }
+ else // object does not support demanded interface
+ {
+ uno_any_construct(
+ reinterpret_cast< uno_Any * >( uno_ret ),
+ 0, 0, 0 );
+ }
+ // no exception occured
+ *uno_exc = 0;
+ }
+ }
+ else
+ {
+ uno_any_construct(
+ reinterpret_cast< uno_Any * >( uno_ret ),
+ &pInterface, demanded_td.get(), 0 );
+ (*pInterface->release)( pInterface );
+ *uno_exc = 0;
+ }
+ break;
+ }
+ case 1: // acquire this proxy
+ that->acquire();
+ *uno_exc = 0;
+ break;
+ case 2: // release this proxy
+ that->release();
+ *uno_exc = 0;
+ break;
+ default: // arbitrary method call
+ bridge->call_java(
+ that->m_javaI, iface_td, method_td->nIndex, 0,
+ method_td->pReturnTypeRef,
+ method_td->pParams, method_td->nParams,
+ uno_ret, uno_args, uno_exc );
+ break;
+ }
+ break;
+ }
+ default:
+ {
+ throw BridgeRuntimeError(
+ OUSTR("illegal member type description!") );
+ }
+ }
+ }
+ catch (BridgeRuntimeError & err)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(
+ "[jni_uno bridge error] UNO calling Java method ") );
+ if (typelib_TypeClass_INTERFACE_METHOD == member_td->eTypeClass ||
+ typelib_TypeClass_INTERFACE_ATTRIBUTE == member_td->eTypeClass)
+ {
+ buf.append( OUString::unacquired(
+ &reinterpret_cast<
+ typelib_InterfaceMemberTypeDescription const * >(
+ member_td )->pMemberName ) );
+ }
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ buf.append( err.m_message );
+ // binary identical struct
+ ::com::sun::star::uno::RuntimeException exc(
+ buf.makeStringAndClear(),
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface >() );
+ ::com::sun::star::uno::Type const & exc_type = ::getCppuType( &exc );
+ uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg2(
+ OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( "%s", cstr_msg2.getStr() );
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ // binary identical struct
+ ::com::sun::star::uno::RuntimeException exc(
+ OUSTR("[jni_uno bridge error] attaching current thread "
+ "to java failed!"),
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface >() );
+ ::com::sun::star::uno::Type const & exc_type = ::getCppuType( &exc );
+ uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg2(
+ OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg2.getStr() );
+#endif
+ }
+}
+
+}
+}
diff --git a/bridges/source/jni_uno/makefile.mk b/bridges/source/jni_uno/makefile.mk
new file mode 100644
index 000000000000..da0942cdad29
--- /dev/null
+++ b/bridges/source/jni_uno/makefile.mk
@@ -0,0 +1,85 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=bridges
+TARGET=java_uno
+USE_DEFFILE=TRUE
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(SOLAR_JAVA)"==""
+nojava:
+ @echo "Not building jni-uno bridge because Java is disabled"
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)$(COM)" == "WNTGCC"
+.IF "$(EXCEPTIONS)" == "sjlj"
+CFLAGS += -DBROKEN_ALLOCA
+.ENDIF
+.ENDIF
+
+SLOFILES= \
+ $(SLO)$/jni_info.obj \
+ $(SLO)$/jni_data.obj \
+ $(SLO)$/jni_uno2java.obj \
+ $(SLO)$/jni_java2uno.obj \
+ $(SLO)$/jni_bridge.obj \
+ $(SLO)$/nativethreadpool.obj
+
+SHL1TARGET=$(TARGET)
+
+SHL1STDLIBS= \
+ $(JVMACCESSLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB)
+
+SHL1VERSIONMAP=$(TARGET).map
+
+SHL1IMPLIB=i$(TARGET)
+SHL1LIBS=$(SLB)$/$(TARGET).lib
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+SHL1RPATH=URELIB
+
+.IF "$(debug)" != ""
+.IF "$(COM)" == "MSC"
+CFLAGS += -Ob0
+.ENDIF
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/jni_uno/nativethreadpool.cxx b/bridges/source/jni_uno/nativethreadpool.cxx
new file mode 100644
index 000000000000..5b30ffdafc22
--- /dev/null
+++ b/bridges/source/jni_uno/nativethreadpool.cxx
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "jvmaccess/virtualmachine.hxx"
+#include "rtl/byteseq.h"
+#include "rtl/byteseq.hxx"
+#include "rtl/memory.h"
+#include "rtl/ref.hxx"
+#include "sal/types.h"
+#include "uno/threadpool.h"
+
+#include "jni.h"
+
+#include <new>
+
+/* The native implementation part of
+ * jurt/com/sun/star/lib/uno/environments/remote/NativeThreadPool.java.
+ */
+
+namespace {
+
+struct Pool {
+ Pool(rtl::Reference< jvmaccess::VirtualMachine > const & theVirtualMachine,
+ jmethodID theExecute, uno_ThreadPool thePool):
+ virtualMachine(theVirtualMachine), execute(theExecute), pool(thePool) {}
+
+ rtl::Reference< jvmaccess::VirtualMachine > virtualMachine;
+ jmethodID execute;
+ uno_ThreadPool pool;
+};
+
+struct Job {
+ Job(Pool * thePool, jobject theJob): pool(thePool), job(theJob) {}
+
+ Pool * pool;
+ jobject job;
+};
+
+void throwOutOfMemory(JNIEnv * env) {
+ jclass c = env->FindClass("java/lang/OutOfMemoryError");
+ if (c != 0) {
+ env->ThrowNew(c, "");
+ }
+}
+
+}
+
+extern "C" {
+
+static void SAL_CALL executeRequest(void * data) {
+ Job * job = static_cast< Job * >(data);
+ try {
+ jvmaccess::VirtualMachine::AttachGuard guard(job->pool->virtualMachine);
+ JNIEnv * env = guard.getEnvironment();
+ // Failure of the following Job.execute Java call is ignored; if that
+ // call fails, it should be due to a java.lang.Error, which is not
+ // handled well, anyway:
+ env->CallObjectMethod(job->job, job->pool->execute);
+ env->DeleteGlobalRef(job->job);
+ delete job;
+ } catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &) {
+ //TODO: DeleteGlobalRef(job->job)
+ delete job;
+ }
+}
+
+}
+
+extern "C" JNIEXPORT jbyteArray JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_threadId(
+ JNIEnv * env, jclass) SAL_THROW_EXTERN_C()
+{
+ sal_Sequence * s = 0;
+ uno_getIdOfCurrentThread(&s); //TODO: out of memory
+ uno_releaseIdFromCurrentThread();
+ rtl::ByteSequence seq(s);
+ rtl_byte_sequence_release(s);
+ sal_Int32 n = seq.getLength();
+ jbyteArray a = env->NewByteArray(n);
+ // sal_Int32 and jsize are compatible here
+ if (a == 0) {
+ return 0;
+ }
+ void * p = env->GetPrimitiveArrayCritical(a, 0);
+ if (p == 0) {
+ return 0;
+ }
+ rtl_copyMemory(p, seq.getConstArray(), n);
+ // sal_Int8 and jbyte ought to be compatible
+ env->ReleasePrimitiveArrayCritical(a, p, 0);
+ return a;
+}
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_create(
+ JNIEnv * env, jclass) SAL_THROW_EXTERN_C()
+{
+ JavaVM * vm;
+ if (env->GetJavaVM(&vm) != JNI_OK) { //TODO: no Java exception raised?
+ jclass c = env->FindClass("java/lang/RuntimeException");
+ if (c != 0) {
+ env->ThrowNew(c, "JNI GetJavaVM failed");
+ }
+ return 0;
+ }
+ jclass c = env->FindClass("com/sun/star/lib/uno/environments/remote/Job");
+ if (c == 0) {
+ return 0;
+ }
+ jmethodID execute = env->GetMethodID(c, "execute", "()Ljava/lang/Object;");
+ if (execute == 0) {
+ return 0;
+ }
+ try {
+ return reinterpret_cast< jlong >(new Pool(
+ new jvmaccess::VirtualMachine(vm, env->GetVersion(), false, env),
+ execute, uno_threadpool_create()));
+ } catch (std::bad_alloc) {
+ throwOutOfMemory(env);
+ return 0;
+ }
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_attach(
+ JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ uno_threadpool_attach(reinterpret_cast< Pool * >(pool)->pool);
+}
+
+extern "C" JNIEXPORT jobject JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_enter(
+ JNIEnv * env, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ jobject job;
+ uno_threadpool_enter(
+ reinterpret_cast< Pool * >(pool)->pool,
+ reinterpret_cast< void ** >(&job));
+ if (job == 0) {
+ return 0;
+ }
+ jobject ref = env->NewLocalRef(job);
+ env->DeleteGlobalRef(job);
+ return ref;
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_detach(
+ JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ uno_threadpool_detach(reinterpret_cast< Pool * >(pool)->pool);
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_putJob(
+ JNIEnv * env, jclass, jlong pool, jbyteArray threadId, jobject job,
+ jboolean request, jboolean oneWay) SAL_THROW_EXTERN_C()
+{
+ void * s = env->GetPrimitiveArrayCritical(threadId, 0);
+ if (s == 0) {
+ return;
+ }
+ rtl::ByteSequence seq(
+ static_cast< sal_Int8 * >(s), env->GetArrayLength(threadId));
+ // sal_Int8 and jbyte ought to be compatible; sal_Int32 and jsize are
+ // compatible here
+ //TODO: out of memory
+ env->ReleasePrimitiveArrayCritical(threadId, s, JNI_ABORT);
+ Pool * p = reinterpret_cast< Pool * >(pool);
+ jobject ref = env->NewGlobalRef(job);
+ if (ref == 0) {
+ return;
+ }
+ Job * j = 0;
+ if (request) {
+ j = new(std::nothrow) Job(p, ref);
+ if (j == 0) {
+ env->DeleteGlobalRef(ref);
+ throwOutOfMemory(env);
+ return;
+ }
+ }
+ uno_threadpool_putJob(
+ p->pool, seq.getHandle(),
+ request ? static_cast< void * >(j) : static_cast< void * >(ref),
+ request ? executeRequest : 0, oneWay);
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_dispose(
+ JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ uno_threadpool_dispose(reinterpret_cast< Pool * >(pool)->pool);
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_destroy(
+ JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ Pool * p = reinterpret_cast< Pool * >(pool);
+ uno_threadpool_destroy(p->pool);
+ delete p;
+}