зеркало из https://github.com/mozilla/gecko-dev.git
Bug 279649 - Dynamically create Java proxies. r=darin.
This file was copied in CVS from the following location: mozilla/extensions/java/xpcom/XPCOMJavaProxy.java Original committer: pedemont%us.ibm.com Original revision: 1.1 Original date: 2005/02/23 20:19:55
This commit is contained in:
Родитель
0ebfdd4534
Коммит
2026d88f2f
|
@ -0,0 +1,230 @@
|
|||
/* ***** 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;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
|
||||
/**
|
||||
* 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 final 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
return Proxy.newProxyInstance(aInterface.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)
|
||||
{
|
||||
return (aProxy == aOther ? Boolean.TRUE : Boolean.FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
Class objectClass = aObject.getClass();
|
||||
if (Proxy.isProxyClass(objectClass)) {
|
||||
Class[] interfaces = objectClass.getInterfaces();
|
||||
if (interfaces[interfaces.length-1] == XPCOMJavaProxyBase.class) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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 static native
|
||||
void finalizeProxy(Object aProxy);
|
||||
|
||||
}
|
Загрузка…
Ссылка в новой задаче