summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxy.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxy.java')
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxy.java257
1 files changed, 257 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxy.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxy.java
new file mode 100644
index 00000000..c6485708
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxy.java
@@ -0,0 +1,257 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Java XPCOM Bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Javier Pedemonte (jhpedemonte@gmail.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.xpcom.internal;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.mozilla.xpcom.XPCOMException;
+
+
+/**
+ * This class is used to pass XPCOM objects to Java functions. A
+ * <code>java.lang.reflect.Proxy</code> instance is created using the expected
+ * interface, and all calls to the proxy are forwarded to the XPCOM object.
+ */
+public class XPCOMJavaProxy implements InvocationHandler {
+
+ /**
+ * Pointer to the XPCOM object for which we are a proxy.
+ */
+ protected long nativeXPCOMPtr;
+
+ /**
+ * Default constructor.
+ *
+ * @param aXPCOMInstance address of XPCOM object as a long
+ */
+ public XPCOMJavaProxy(long aXPCOMInstance) {
+ nativeXPCOMPtr = aXPCOMInstance;
+ }
+
+ /**
+ * Returns the XPCOM object that the given proxy references.
+ *
+ * @param aProxy Proxy created by <code>createProxy</code>
+ *
+ * @return address of XPCOM object as a long
+ */
+ protected static long getNativeXPCOMInstance(Object aProxy) {
+ XPCOMJavaProxy proxy = (XPCOMJavaProxy) Proxy.getInvocationHandler(aProxy);
+ return proxy.nativeXPCOMPtr;
+ }
+
+ /**
+ * Creates a Proxy for the given XPCOM object.
+ *
+ * @param aInterface interface from which to create Proxy
+ * @param aXPCOMInstance address of XPCOM object as a long
+ *
+ * @return Proxy of given XPCOM object
+ */
+ protected static Object createProxy(Class aInterface, long aXPCOMInstance) {
+ // XXX We should really get the class loader from |aInterface|. However,
+ // that class loader doesn't know about |XPCOMJavaProxyBase|. So for
+ // now, we get the class loader that loaded |XPCOMJavaProxy|. When
+ // we get rid of the "XPCOMJavaProxyBase.java" class, we can revert
+ // to the old method below.
+// return Proxy.newProxyInstance(aInterface.getClassLoader(),
+ return Proxy.newProxyInstance(XPCOMJavaProxy.class.getClassLoader(),
+ new Class[] { aInterface, XPCOMJavaProxyBase.class },
+ new XPCOMJavaProxy(aXPCOMInstance));
+ }
+
+ /**
+ * All calls to the Java proxy are forwarded to this method. This method
+ * takes care of a few of the <code>Object</code> method calls; all other
+ * calls are forwarded to the XPCOM object.
+ *
+ * @param aProxy Proxy created by <code>createProxy</code>
+ * @param aMethod object that describes the called method
+ * @param aParams array of the arguments passed to the method
+ *
+ * @return return value as defined by given <code>aMethod</code>
+ */
+ public Object invoke(Object aProxy, Method aMethod, Object[] aParams)
+ throws Throwable {
+ String methodName = aMethod.getName();
+
+ // Handle the three java.lang.Object methods that are passed to us.
+ if (aMethod.getDeclaringClass() == Object.class) {
+ if (methodName.equals("hashCode")) {
+ return proxyHashCode(aProxy);
+ }
+ if (methodName.equals("equals")) {
+ return proxyEquals(aProxy, aParams[0]);
+ }
+ if (methodName.equals("toString")) {
+ return proxyToString(aProxy);
+ }
+ System.err.println("WARNING: Unhandled Object method [" +
+ methodName + "]");
+ return null;
+ }
+
+ // Handle the 'finalize' method called during garbage collection
+ if (aMethod.getDeclaringClass() == XPCOMJavaProxyBase.class) {
+ if (methodName.equals("finalize")) {
+ finalizeProxy(aProxy);
+ } else {
+ System.err.println("WARNING: Unhandled XPCOMJavaProxyBase method [" +
+ methodName + "]");
+ }
+ return null;
+ }
+
+ // If not already handled, pass method calls to XPCOM object.
+ return callXPCOMMethod(aProxy, methodName, aParams);
+ }
+
+ /**
+ * Handles method calls of <code>java.lang.Object.hashCode</code>
+ *
+ * @param aProxy Proxy created by <code>createProxy</code>
+ *
+ * @return Integer object representing hash code of given object
+ *
+ * @see Object#hashCode()
+ */
+ protected static Integer proxyHashCode(Object aProxy) {
+ return new Integer(System.identityHashCode(aProxy));
+ }
+
+ /**
+ * Handles method calls of <code>java.lang.Object.equals</code>
+ *
+ * @param aProxy Proxy created by <code>createProxy</code>
+ * @param aOther another object
+ *
+ * @return <code>true</code> if the given objects are the same;
+ * <code>false</code> otherwise
+ *
+ * @see Object#equals(Object)
+ */
+ protected static Boolean proxyEquals(Object aProxy, Object aOther) {
+ // See if the two are the same Java object
+ if (aProxy == aOther) {
+ return Boolean.TRUE;
+ } else {
+ // If not, then see if they represent the same XPCOM object. But first,
+ // we need to check if |aOther| is an XPCOMJavaProxy.
+ if (isXPCOMJavaProxy(aOther) && isSameXPCOMObject(aProxy, aOther)) {
+ return Boolean.TRUE;
+ }
+ }
+ return Boolean.FALSE;
+ }
+
+ /**
+ * Indicates whether the given object is an XPCOMJavaProxy.
+ *
+ * @param aObject object to check
+ *
+ * @return <code>true</code> if the given object is an XPCOMJavaProxy;
+ * <code>false</code> otherwise
+ */
+ protected static boolean isXPCOMJavaProxy(Object aObject) {
+ if (aObject != null && Proxy.isProxyClass(aObject.getClass())) {
+ InvocationHandler h = Proxy.getInvocationHandler(aObject);
+ if (h instanceof XPCOMJavaProxy) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if the two given XPCOMJavaProxy objects are proxies for
+ * the same XPCOM object.
+ *
+ * @param aProxy1 XPCOMJavaProxy created by <code>createProxy</code>
+ * @param aProxy2 XPCOMJavaProxy created by <code>createProxy</code>
+ *
+ * @return <code>true</code> if both proxies represent the same XPCOM object;
+ * <code>false</code> otherwise
+ */
+ protected static native boolean isSameXPCOMObject(Object aProxy1,
+ Object aProxy2);
+
+ /**
+ * Handles method calls of <code>java.lang.Object.toString</code>
+ *
+ * @param aProxy Proxy created by <code>createProxy</code>
+ *
+ * @return String representation of given object
+ *
+ * @see Object#toString()
+ */
+ protected static String proxyToString(Object aProxy) {
+ return aProxy.getClass().getInterfaces()[0].getName() + '@' +
+ Integer.toHexString(aProxy.hashCode());
+ }
+
+ /**
+ * Called when the proxy is garbage collected by the JVM. Allows us to clean
+ * up any references to the XPCOM object.
+ *
+ * @param aProxy reference to Proxy that is being garbage collected
+ */
+ protected void finalizeProxy(Object aProxy) throws Throwable {
+ finalizeProxyNative(aProxy);
+ super.finalize();
+ }
+
+ protected static native void finalizeProxyNative(Object aProxy);
+
+ /**
+ * Calls the XPCOM object referenced by the proxy with the given method.
+ *
+ * @param aProxy Proxy created by <code>createProxy</code>
+ * @param aMethodName name of method that we want to call
+ * @param aParams array of params passed to method
+ *
+ * @return return value as defined by given method
+ *
+ * @exception XPCOMException if XPCOM method failed. Values of XPCOMException
+ * are defined by the method called.
+ */
+ protected static native Object callXPCOMMethod(Object aProxy,
+ String aMethodName, Object[] aParams);
+
+}