LibreOffice Module bridges (master) 1
JNI_proxy.java
Go to the documentation of this file.
1// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20package com.sun.star.bridges.jni_uno;
21
22import com.sun.star.lib.util.AsynchronousFinalizer;
23import com.sun.star.lib.util.NativeLibraryLoader;
24import com.sun.star.uno.Type;
25import com.sun.star.uno.UnoRuntime;
26import com.sun.star.uno.IEnvironment;
27import com.sun.star.uno.IQueryInterface;
28
29
30
31public final class JNI_proxy implements java.lang.reflect.InvocationHandler
32{
33 static {
34 if ("The Android Project".equals(System.getProperty("java.vendor"))) {
35 // See corresponding code in
36 // javaunohelper/com/sun/star/comp/helper/Bootstrap.java for more
37 // comments.
38
39 boolean disable_dynloading = false;
40 try {
41 System.loadLibrary("lo-bootstrap");
42 } catch (UnsatisfiedLinkError e) {
43 disable_dynloading = true;
44 }
45
46 if (!disable_dynloading)
47 NativeLibraryLoader.loadLibrary(JNI_info_holder.class.getClassLoader(),
48 "java_uno");
49 } else
50 NativeLibraryLoader.loadLibrary(JNI_proxy.class.getClassLoader(),
51 "java_uno");
52 }
53 private static ClassLoader s_classloader =
54 JNI_proxy.class.getClassLoader();
55 private static Class s_InvocationHandler [] =
56 new Class [] { java.lang.reflect.InvocationHandler.class };
57
58 private long m_bridge_handle;
59 private final IEnvironment m_java_env;
61 private long m_receiver_handle; // on the C++ side, this is a "UNO_Interface *"
62 private long m_td_handle; // on the C++ side, this is a "typelib_TypeDescription *"
63 private final Type m_type;
64 private final String m_oid;
65 private final Class m_class;
66 private final AsynchronousFinalizer m_finalizer;
67
68 public static String get_stack_trace( Throwable throwable )
69 throws Throwable
70 {
71 boolean current_trace = false;
72 if (null == throwable)
73 {
74 throwable = new Throwable();
75 current_trace = true;
76 }
77 java.io.StringWriter string_writer =
78 new java.io.StringWriter();
79 java.io.PrintWriter print_writer =
80 new java.io.PrintWriter( string_writer, true );
81 throwable.printStackTrace( print_writer );
82 print_writer.flush();
83 print_writer.close();
84 string_writer.flush();
85 String trace = string_writer.toString();
86 if (current_trace)
87 {
88 // cut out first two lines
89 int n = trace.indexOf( '\n' );
90 n = trace.indexOf( '\n', n +1 );
91 trace = trace.substring( n +1 );
92 }
93 return "\njava stack trace:\n" + trace;
94 }
95
96 private native void finalize( long bridge_handle );
97
98 @Override
99 protected void finalize()
100 {
101 if (m_finalizer != null) {
102 m_finalizer.add(new AsynchronousFinalizer.Job() {
103 public void run() throws Throwable {
104 JNI_proxy.this.finalize( m_bridge_handle );
105 }
106 });
107 }
108 }
109
110 private JNI_proxy(
111 long bridge_handle, IEnvironment java_env,
112 long receiver_handle, long td_handle, Type type, String oid,
113 AsynchronousFinalizer finalizer)
114 {
115 m_bridge_handle = bridge_handle;
116 m_java_env = java_env;
117 m_receiver_handle = receiver_handle;
118 m_td_handle = td_handle;
119 m_type = type;
120 m_oid = oid;
121 m_class = m_type.getZClass();
122 m_finalizer = finalizer;
123 }
124
125 public static Object create(
126 long bridge_handle, IEnvironment java_env,
127 long receiver_handle, long td_handle, Type type, String oid,
128 java.lang.reflect.Constructor proxy_ctor,
129 AsynchronousFinalizer finalizer)
130 throws Throwable
131 {
132 JNI_proxy handler = new JNI_proxy(
133 bridge_handle, java_env, receiver_handle, td_handle, type, oid,
134 finalizer);
135 Object proxy = proxy_ctor.newInstance( new Object [] { handler } );
136 return java_env.registerInterface( proxy, new String [] { oid }, type );
137 }
138
139 public static java.lang.reflect.Constructor get_proxy_ctor( Class clazz )
140 throws Throwable
141 {
142 Class proxy_class = java.lang.reflect.Proxy.getProxyClass(
143 s_classloader,
144 new Class [] { clazz, IQueryInterface.class,
145 com.sun.star.lib.uno.Proxy.class } );
146 return proxy_class.getConstructor( s_InvocationHandler );
147 }
148
150 long bridge_handle, String method, Object args [] )
151 throws Throwable;
152
153 // InvocationHandler impl
154
156 Object proxy, java.lang.reflect.Method method, Object args [] )
157 throws Throwable
158 {
159 Class<?> decl_class = method.getDeclaringClass();
160 String method_name = method.getName();
161
162 if (Object.class.equals( decl_class ))
163 {
164 if (method_name.equals( "hashCode" ))
165 {
166 // int hashCode()
167 return Integer.valueOf( m_oid.hashCode() );
168 }
169 else if (method_name.equals( "equals" ))
170 {
171 // boolean equals( Object obj )
172 return isSame(args[0]);
173 }
174 else if (method_name.equals( "toString" ))
175 {
176 // String toString()
177 return this.toString() + " [oid=" + m_oid +
178 ", type=" + m_type.getTypeName() + "]";
179 }
180 }
181 // UNO interface call
182 else if (decl_class.isAssignableFrom( m_class ))
183 {
184 // dispatch interface call
185 return dispatch_call( m_bridge_handle, method_name, args );
186 }
187 // IQueryInterface impl
188 else if (IQueryInterface.class.equals( decl_class ))
189 {
190 if (method_name.equals( "queryInterface" ))
191 {
192 Object registered_proxy =
193 m_java_env.getRegisteredInterface( m_oid, (Type)args[ 0 ] );
194 if (null == registered_proxy)
195 {
196 return dispatch_call( m_bridge_handle, method_name, args );
197 }
198 else
199 {
200 return registered_proxy;
201 }
202 }
203 else if (method_name.equals( "isSame" ))
204 {
205 // boolean isSame( Object object )
206 return isSame(args[0]);
207 }
208 else if (method_name.equals( "getOid" ))
209 {
210 return m_oid;
211 }
212 }
213
214 throw new com.sun.star.uno.RuntimeException(
215 "[jni_uno bridge error] unexpected call on proxy " +
216 proxy.toString() + ": " + method.toString() );
217 }
218
219 private Boolean isSame(Object obj) {
220 return Boolean.valueOf(obj != null
221 && m_oid.equals(UnoRuntime.generateOid(obj)));
222 }
223}
224
225// vim:set shiftwidth=4 softtabstop=4 expandtab:
static java.lang.reflect.Constructor get_proxy_ctor(Class clazz)
Definition: JNI_proxy.java:139
static String get_stack_trace(Throwable throwable)
Definition: JNI_proxy.java:68
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, AsynchronousFinalizer finalizer)
Definition: JNI_proxy.java:125
native void finalize(long bridge_handle)
JNI_proxy(long bridge_handle, IEnvironment java_env, long receiver_handle, long td_handle, Type type, String oid, AsynchronousFinalizer finalizer)
Definition: JNI_proxy.java:110
final AsynchronousFinalizer m_finalizer
Definition: JNI_proxy.java:66
native Object dispatch_call(long bridge_handle, String method, Object args[])
Object invoke(Object proxy, java.lang.reflect.Method method, Object args[])
Definition: JNI_proxy.java:155
long m_receiver_handle
these 2 fields are accessed directly from C++
Definition: JNI_proxy.java:61
const Type m_type
sal_Int64 n
OUString m_oid
Type
native
args
OUString toString(OptionInfo const *info)
ResultType type