Bug 279649 - Dynamically create Java proxies. r=darin.
git-svn-id: svn://10.0.0.236/trunk@169666 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
7fa761ebfe
commit
c9c27d63d5
@ -1513,14 +1513,9 @@ $(XPIDL_GEN_DIR)/org/mozilla/xpcom/.done: $(XPIDL_GEN_DIR)/.done
|
||||
@if test ! -d $(XPIDL_GEN_DIR)/org/mozilla/xpcom; then echo Creating $(XPIDL_GEN_DIR)/org/mozilla/xpcom/.done; rm -rf $(XPIDL_GEN_DIR)/org; mkdir $(XPIDL_GEN_DIR)/org; mkdir $(XPIDL_GEN_DIR)/org/mozilla; mkdir $(XPIDL_GEN_DIR)/org/mozilla/xpcom; fi
|
||||
@touch $@
|
||||
|
||||
$(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs/.done: $(XPIDL_GEN_DIR)/org/mozilla/xpcom/.done
|
||||
@if test ! -d $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs; then echo Creating $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs/.done; rm -rf $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs; mkdir $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs; fi
|
||||
@touch $@
|
||||
|
||||
$(XPIDL_GEN_DIR)/org/mozilla/xpcom/.%.java.pp: %.idl $(JAVA_IDL_COMPILE) $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs/.done
|
||||
$(XPIDL_GEN_DIR)/org/mozilla/xpcom/.%.java.pp: %.idl $(JAVA_IDL_COMPILE) $(XPIDL_GEN_DIR)/org/mozilla/xpcom/.done
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(JAVA_IDL_COMPILE) -m java -p org.mozilla.xpcom -w -I$(srcdir) -I$(IDL_DIR) -o $(XPIDL_GEN_DIR)/org/mozilla/xpcom/$* $(_VPATH_SRCS)
|
||||
$(ELOG) $(JAVA_IDL_COMPILE) -m javastub -p org.mozilla.xpcom -w -I$(srcdir) -I$(IDL_DIR) -o $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs/$*_Stub $(_VPATH_SRCS)
|
||||
@touch $@
|
||||
|
||||
|
||||
@ -1532,7 +1527,6 @@ export:: $(JAVA_DIST_DIR)
|
||||
export:: $(JAVADEPFILES)
|
||||
ifndef NO_DIST_INSTALL
|
||||
$(INSTALL) $(IFLAGS1) $(XPIDL_GEN_DIR)/org/mozilla/xpcom/*.java $(JAVA_DIST_DIR)/org/mozilla/xpcom/
|
||||
$(INSTALL) $(IFLAGS1) $(XPIDL_GEN_DIR)/org/mozilla/xpcom/stubs/*.java $(JAVA_DIST_DIR)/org/mozilla/xpcom/stubs/
|
||||
endif
|
||||
|
||||
endif # JAVA_XPIDLSRCS
|
||||
|
||||
@ -69,7 +69,8 @@ CPPSRCS = \
|
||||
|
||||
JAVA_SRCS = \
|
||||
XPCOM.java \
|
||||
XPCOMPrivate.java \
|
||||
XPCOMJavaProxy.java \
|
||||
XPCOMJavaProxyBase.java \
|
||||
XPCOMException.java \
|
||||
GeckoEmbed.java \
|
||||
AppFileLocProvider.java \
|
||||
|
||||
230
mozilla/extensions/java/xpcom/XPCOMJavaProxy.java
Normal file
230
mozilla/extensions/java/xpcom/XPCOMJavaProxy.java
Normal file
@ -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);
|
||||
|
||||
}
|
||||
53
mozilla/extensions/java/xpcom/XPCOMJavaProxyBase.java
Normal file
53
mozilla/extensions/java/xpcom/XPCOMJavaProxyBase.java
Normal file
@ -0,0 +1,53 @@
|
||||
/* ***** 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;
|
||||
|
||||
|
||||
/**
|
||||
* This interface forms the foundation of any XPCOMJavaProxy that is created.
|
||||
* It allows us to handle any JVM calls to <code>finalize</code> when the Proxy
|
||||
* is garbage collected.
|
||||
*/
|
||||
public interface XPCOMJavaProxyBase {
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#finalize()
|
||||
*/
|
||||
void finalize() throws Throwable;
|
||||
|
||||
}
|
||||
@ -51,20 +51,19 @@ GARBAGE_DIRS += org
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifdef MOZ_DEBUG
|
||||
JAVAC_FLAGS = -g
|
||||
endif
|
||||
|
||||
org/mozilla/xpcom/.class_done:
|
||||
@echo Compiling Java interface classes
|
||||
@$(JAVAC) -classpath . -d . $(JAVA_DIST_DIR)/org/mozilla/xpcom/*.java
|
||||
@$(JAVAC) $(JAVAC_FLAGS) -classpath . -d . $(JAVA_DIST_DIR)/org/mozilla/xpcom/*.java
|
||||
@touch $@
|
||||
|
||||
org/mozilla/xpcom/stubs/.class_done:
|
||||
@echo Compiling Java stub classes
|
||||
@$(JAVAC) -classpath . -d . $(JAVA_DIST_DIR)/org/mozilla/xpcom/stubs/*.java
|
||||
@touch $@
|
||||
|
||||
$(JARFILE): org/mozilla/xpcom/.class_done org/mozilla/xpcom/stubs/.class_done
|
||||
$(JARFILE): org/mozilla/xpcom/.class_done Makefile
|
||||
$(JAR) cf $@ org
|
||||
|
||||
$(JARFILE_SRC):
|
||||
$(JARFILE_SRC): $(JARFILE)
|
||||
$(JAR) cf $@ -C $(JAVA_DIST_DIR) org
|
||||
|
||||
libs:: $(JARFILE) $(JARFILE_SRC)
|
||||
|
||||
@ -47,48 +47,61 @@
|
||||
#include "nsEnumeratorUtils.h"
|
||||
#include "nsArray.h"
|
||||
#include "nsAppFileLocProviderProxy.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
|
||||
#define GECKO_NATIVE(func) Java_org_mozilla_xpcom_GeckoEmbed_##func
|
||||
#define XPCOM_NATIVE(func) Java_org_mozilla_xpcom_XPCOM_##func
|
||||
#define XPCOMPRIVATE_NATIVE(func) Java_org_mozilla_xpcom_XPCOMPrivate_##func
|
||||
|
||||
|
||||
nsresult
|
||||
InitEmbedding_Impl(JNIEnv* env, jobject aMozBinDirectory,
|
||||
jobject aAppFileLocProvider)
|
||||
{
|
||||
nsresult rv;
|
||||
if (!InitializeJavaGlobals(env))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// create an nsILocalFile from given java.io.File
|
||||
nsCOMPtr<nsILocalFile> directory;
|
||||
if (aMozBinDirectory) {
|
||||
rv = File_to_nsILocalFile(env, aMozBinDirectory, getter_AddRefs(directory));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// create nsAppFileLocProviderProxy from given Java object
|
||||
nsAppFileLocProviderProxy* provider = nsnull;
|
||||
if (aAppFileLocProvider) {
|
||||
provider = new nsAppFileLocProviderProxy(env, aAppFileLocProvider);
|
||||
if (!provider)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// init Gecko
|
||||
rv = NS_InitEmbedding(directory, provider);
|
||||
if (provider) {
|
||||
delete provider;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// init Event Queue
|
||||
nsCOMPtr<nsIEventQueueService>
|
||||
eventQService(do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventQService->CreateThreadEventQueue();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT void JNICALL
|
||||
GECKO_NATIVE(initEmbedding) (JNIEnv* env, jclass, jobject aMozBinDirectory,
|
||||
jobject aAppFileLocProvider)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!InitializeJavaGlobals(env)) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
} else {
|
||||
// Create an nsILocalFile from given java.io.File
|
||||
nsCOMPtr<nsILocalFile> directory;
|
||||
if (aMozBinDirectory) {
|
||||
rv = File_to_nsILocalFile(env, aMozBinDirectory, getter_AddRefs(directory));
|
||||
}
|
||||
nsresult rv = InitEmbedding_Impl(env, aMozBinDirectory, aAppFileLocProvider);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAppFileLocProviderProxy* provider = nsnull;
|
||||
if (aAppFileLocProvider) {
|
||||
provider = new nsAppFileLocProviderProxy(env, aAppFileLocProvider);
|
||||
if (!provider)
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = NS_InitEmbedding(directory, provider);
|
||||
if (provider) {
|
||||
delete provider;
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowException(env, rv, "Failure in initEmbedding");
|
||||
FreeJavaGlobals(env);
|
||||
}
|
||||
|
||||
ThrowException(env, rv, "Failure in initEmbedding");
|
||||
FreeJavaGlobals(env);
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT void JNICALL
|
||||
@ -101,46 +114,61 @@ GECKO_NATIVE(termEmbedding) (JNIEnv *env, jclass)
|
||||
FreeJavaGlobals(env);
|
||||
}
|
||||
|
||||
nsresult
|
||||
InitXPCOM_Impl(JNIEnv* env, jobject aMozBinDirectory,
|
||||
jobject aAppFileLocProvider, jobject* aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
if (!InitializeJavaGlobals(env))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// create an nsILocalFile from given java.io.File
|
||||
nsCOMPtr<nsILocalFile> directory;
|
||||
if (aMozBinDirectory) {
|
||||
rv = File_to_nsILocalFile(env, aMozBinDirectory, getter_AddRefs(directory));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// create nsAppFileLocProviderProxy from given Java object
|
||||
nsAppFileLocProviderProxy* provider = nsnull;
|
||||
if (aAppFileLocProvider) {
|
||||
provider = new nsAppFileLocProviderProxy(env, aAppFileLocProvider);
|
||||
if (!provider)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// init XPCOM
|
||||
nsIServiceManager* servMan = nsnull;
|
||||
rv = NS_InitXPCOM2(&servMan, directory, provider);
|
||||
if (provider) {
|
||||
delete provider;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// init Event Queue
|
||||
nsCOMPtr<nsIEventQueueService>
|
||||
eventQService(do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventQService->CreateThreadEventQueue();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// create Java proxy for service manager returned by NS_InitXPCOM2
|
||||
rv = CreateJavaProxy(env, servMan, NS_GET_IID(nsIServiceManager),
|
||||
aResult);
|
||||
NS_RELEASE(servMan); // Java proxy has owning ref
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jobject JNICALL
|
||||
XPCOM_NATIVE(initXPCOM) (JNIEnv* env, jclass, jobject aMozBinDirectory,
|
||||
jobject aAppFileLocProvider)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!InitializeJavaGlobals(env)) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
} else {
|
||||
// Create an nsILocalFile from given java.io.File
|
||||
nsCOMPtr<nsILocalFile> directory;
|
||||
if (aMozBinDirectory) {
|
||||
rv = File_to_nsILocalFile(env, aMozBinDirectory, getter_AddRefs(directory));
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAppFileLocProviderProxy* provider = nsnull;
|
||||
if (aAppFileLocProvider) {
|
||||
provider = new nsAppFileLocProviderProxy(env, aAppFileLocProvider);
|
||||
if (!provider)
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsIServiceManager* servMan = nsnull;
|
||||
rv = NS_InitXPCOM2(&servMan, directory, provider);
|
||||
if (provider) {
|
||||
delete provider;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
jobject javaProxy;
|
||||
rv = CreateJavaProxy(env, servMan, NS_GET_IID(nsIServiceManager),
|
||||
&javaProxy);
|
||||
NS_RELEASE(servMan); // JavaXPCOMInstance has owning ref
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return javaProxy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
jobject servMan;
|
||||
nsresult rv = InitXPCOM_Impl(env, aMozBinDirectory, aAppFileLocProvider,
|
||||
&servMan);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return servMan;
|
||||
|
||||
ThrowException(env, rv, "Failure in initXPCOM");
|
||||
FreeJavaGlobals(env);
|
||||
@ -150,23 +178,24 @@ XPCOM_NATIVE(initXPCOM) (JNIEnv* env, jclass, jobject aMozBinDirectory,
|
||||
extern "C" JX_EXPORT void JNICALL
|
||||
XPCOM_NATIVE(shutdownXPCOM) (JNIEnv *env, jclass, jobject aServMgr)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIServiceManager> servMgr;
|
||||
if (aServMgr) {
|
||||
// Find corresponding XPCOM object
|
||||
void* xpcomObj = gBindings->GetXPCOMObject(env, aServMgr);
|
||||
NS_ASSERTION(xpcomObj != nsnull, "Failed to get XPCOM obj for ServiceMgr.");
|
||||
// Get native XPCOM instance
|
||||
void* xpcom_obj;
|
||||
rv = GetXPCOMInstFromProxy(env, aServMgr, &xpcom_obj);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to get XPCOM obj for ServiceMgr.");
|
||||
|
||||
// Even if we failed to get the matching xpcom object, we don't abort this
|
||||
// function. Just call NS_ShutdownXPCOM with a null service manager.
|
||||
|
||||
if (xpcomObj) {
|
||||
NS_ASSERTION(!IsXPTCStub(xpcomObj),
|
||||
"Expected JavaXPCOMInstance, but got nsJavaXPTCStub");
|
||||
servMgr = do_QueryInterface(((JavaXPCOMInstance*) xpcomObj)->GetInstance());
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
JavaXPCOMInstance* inst = NS_STATIC_CAST(JavaXPCOMInstance*, xpcom_obj);
|
||||
servMgr = do_QueryInterface(inst->GetInstance());
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = NS_ShutdownXPCOM(servMgr);
|
||||
rv = NS_ShutdownXPCOM(servMgr);
|
||||
if (NS_FAILED(rv))
|
||||
ThrowException(env, rv, "NS_ShutdownXPCOM failed");
|
||||
|
||||
@ -261,239 +290,3 @@ XPCOM_NATIVE(getServiceManager) (JNIEnv *env, jclass)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT void JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodVoid) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jboolean JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodBool) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return rc.z;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jbooleanArray JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodBoolA) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return (jbooleanArray) rc.l;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jbyte JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodByte) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return rc.b;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jbyteArray JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodByteA) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return (jbyteArray) rc.l;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jchar JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodChar) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return rc.c;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jcharArray JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodCharA) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return (jcharArray) rc.l;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jshort JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodShort) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return rc.s;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jshortArray JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodShortA) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return (jshortArray) rc.l;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jint JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodInt) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return rc.i;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jintArray JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodIntA) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return (jintArray) rc.l;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jlong JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodLong) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return rc.j;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jlongArray JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodLongA) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return (jlongArray) rc.l;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jfloat JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodFloat) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return rc.f;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jfloatArray JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodFloatA) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return (jfloatArray) rc.l;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jdouble JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodDouble) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return rc.d;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jdoubleArray JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodDoubleA) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return (jdoubleArray) rc.l;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jobject JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodObj) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return rc.l;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT jobjectArray JNICALL
|
||||
XPCOMPRIVATE_NATIVE(CallXPCOMMethodObjA) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject,
|
||||
jint aMethodIndex,
|
||||
jobjectArray aParams)
|
||||
{
|
||||
jvalue rc;
|
||||
CallXPCOMMethod(env, that, aJavaObject, aMethodIndex, aParams, rc);
|
||||
return (jobjectArray) rc.l;
|
||||
}
|
||||
|
||||
extern "C" JX_EXPORT void JNICALL
|
||||
XPCOMPRIVATE_NATIVE(FinalizeStub) (JNIEnv *env, jclass that,
|
||||
jobject aJavaObject)
|
||||
{
|
||||
#ifdef DEBUG_pedemonte
|
||||
jclass clazz = env->GetObjectClass(aJavaObject);
|
||||
jstring name = (jstring) env->CallObjectMethod(clazz, getNameMID);
|
||||
const char* javaObjectName = env->GetStringUTFChars(name, nsnull);
|
||||
LOG(("*** Finalize(java_obj=%s)\n", javaObjectName));
|
||||
env->ReleaseStringUTFChars(name, javaObjectName);
|
||||
#endif
|
||||
|
||||
// Due to Java's garbage collection, this finalize statement may get called
|
||||
// after FreeJavaGlobals(). So check to make sure that everything is still
|
||||
// initialized.
|
||||
if (gJavaXPCOMInitialized) {
|
||||
void* obj = gBindings->GetXPCOMObject(env, aJavaObject);
|
||||
NS_ASSERTION(obj != nsnull, "No matching XPCOM obj in FinalizeStub");
|
||||
|
||||
if (obj) {
|
||||
NS_ASSERTION(!IsXPTCStub(obj),
|
||||
"Expecting JavaXPCOMInstance, got nsJavaXPTCStub");
|
||||
gBindings->RemoveBinding(env, aJavaObject, nsnull);
|
||||
delete (JavaXPCOMInstance*) obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -45,6 +45,8 @@
|
||||
#include "nsCRT.h"
|
||||
#include "prmem.h"
|
||||
|
||||
#define JAVAPROXY_NATIVE(func) Java_org_mozilla_xpcom_XPCOMJavaProxy_##func
|
||||
|
||||
static nsID nullID = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
|
||||
|
||||
|
||||
@ -328,13 +330,29 @@ SetupParams(JNIEnv *env, const jobject aParam, const nsXPTParamInfo &aParamInfo,
|
||||
java_obj = (jobject) aParam;
|
||||
} else { // 'inout'
|
||||
if (aParam)
|
||||
java_obj = (jobject) env->GetObjectArrayElement((jobjectArray) aParam, 0);
|
||||
java_obj = (jobject)
|
||||
env->GetObjectArrayElement((jobjectArray) aParam, 0);
|
||||
}
|
||||
|
||||
void* xpcom_obj;
|
||||
if (java_obj) {
|
||||
// Check if we already have a corresponding XPCOM object
|
||||
void* inst = gBindings->GetXPCOMObject(env, java_obj);
|
||||
jboolean isProxy = env->CallStaticBooleanMethod(xpcomJavaProxyClass,
|
||||
isXPCOMJavaProxyMID,
|
||||
java_obj);
|
||||
if (env->ExceptionCheck()) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
void* inst;
|
||||
if (isProxy) {
|
||||
rv = GetXPCOMInstFromProxy(env, java_obj, &inst);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
} else {
|
||||
inst = gBindings->GetXPCOMObject(env, java_obj);
|
||||
}
|
||||
|
||||
// Get IID for this param
|
||||
nsID iid;
|
||||
@ -767,7 +785,7 @@ nsresult
|
||||
SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
||||
const nsXPTMethodInfo* aMethodInfo, nsIInterfaceInfo* aIInfo,
|
||||
PRUint16 aMethodIndex, nsXPTCVariant* aDispatchParams,
|
||||
nsXPTCVariant &aVariant, jvalue &aResult)
|
||||
nsXPTCVariant &aVariant, jobject* result)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
const nsXPTType &type = aParamInfo.GetType();
|
||||
@ -776,54 +794,52 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
||||
{
|
||||
case nsXPTType::T_I8:
|
||||
case nsXPTType::T_U8:
|
||||
aResult.b = aVariant.val.u8;
|
||||
*result = env->NewObject(byteClass, byteInitMID, aVariant.val.u8);
|
||||
break;
|
||||
|
||||
case nsXPTType::T_I16:
|
||||
case nsXPTType::T_U16:
|
||||
aResult.s = aVariant.val.u16;
|
||||
*result = env->NewObject(shortClass, shortInitMID, aVariant.val.u16);
|
||||
break;
|
||||
|
||||
case nsXPTType::T_I32:
|
||||
case nsXPTType::T_U32:
|
||||
aResult.i = aVariant.val.u32;
|
||||
*result = env->NewObject(intClass, intInitMID, aVariant.val.u32);
|
||||
break;
|
||||
|
||||
case nsXPTType::T_I64:
|
||||
case nsXPTType::T_U64:
|
||||
aResult.j = aVariant.val.u64;
|
||||
*result = env->NewObject(longClass, longInitMID, aVariant.val.u64);
|
||||
break;
|
||||
|
||||
case nsXPTType::T_FLOAT:
|
||||
aResult.f = aVariant.val.f;
|
||||
*result = env->NewObject(floatClass, floatInitMID, aVariant.val.f);
|
||||
break;
|
||||
|
||||
case nsXPTType::T_DOUBLE:
|
||||
aResult.d = aVariant.val.d;
|
||||
*result = env->NewObject(doubleClass, doubleInitMID, aVariant.val.d);
|
||||
break;
|
||||
|
||||
case nsXPTType::T_BOOL:
|
||||
aResult.z = aVariant.val.b;
|
||||
*result = env->NewObject(booleanClass, booleanInitMID, aVariant.val.b);
|
||||
break;
|
||||
|
||||
case nsXPTType::T_CHAR:
|
||||
aResult.c = aVariant.val.c;
|
||||
*result = env->NewObject(charClass, charInitMID, aVariant.val.c);
|
||||
break;
|
||||
|
||||
case nsXPTType::T_WCHAR:
|
||||
aResult.c = aVariant.val.wc;
|
||||
*result = env->NewObject(charClass, charInitMID, aVariant.val.wc);
|
||||
break;
|
||||
|
||||
case nsXPTType::T_CHAR_STR:
|
||||
{
|
||||
if (aVariant.ptr) {
|
||||
aResult.l = env->NewStringUTF((const char*) aVariant.ptr);
|
||||
if (aResult.l == nsnull) {
|
||||
*result = env->NewStringUTF((const char*) aVariant.ptr);
|
||||
if (*result == nsnull) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
aResult.l = nsnull;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -832,13 +848,11 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
||||
{
|
||||
if (aVariant.ptr) {
|
||||
PRUint32 length = nsCRT::strlen((const PRUnichar*) aVariant.ptr);
|
||||
aResult.l = env->NewString((const jchar*) aVariant.ptr, length);
|
||||
if (aResult.l == nsnull) {
|
||||
*result = env->NewString((const jchar*) aVariant.ptr, length);
|
||||
if (*result == nsnull) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
aResult.l = nsnull;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -849,15 +863,13 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
||||
nsID* iid = (nsID*) aVariant.ptr;
|
||||
char* iid_str = iid->ToString();
|
||||
if (iid_str) {
|
||||
aResult.l = env->NewStringUTF(iid_str);
|
||||
*result = env->NewStringUTF(iid_str);
|
||||
}
|
||||
if (iid_str == nsnull || aResult.l == nsnull) {
|
||||
if (iid_str == nsnull || *result == nsnull) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
PR_Free(iid_str);
|
||||
} else {
|
||||
aResult.l = nsnull;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -888,9 +900,7 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
||||
NS_RELEASE(stub);
|
||||
}
|
||||
|
||||
aResult.l = java_obj;
|
||||
} else {
|
||||
aResult.l = nsnull;
|
||||
*result = java_obj;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -900,13 +910,11 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
||||
{
|
||||
if (aVariant.ptr) {
|
||||
nsString* str = (nsString*) aVariant.ptr;
|
||||
aResult.l = env->NewString(str->get(), str->Length());
|
||||
if (aResult.l == nsnull) {
|
||||
*result = env->NewString(str->get(), str->Length());
|
||||
if (*result == nsnull) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
aResult.l = nsnull;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -916,13 +924,11 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
||||
{
|
||||
if (aVariant.ptr) {
|
||||
nsCString* str = (nsCString*) aVariant.ptr;
|
||||
aResult.l = env->NewStringUTF(str->get());
|
||||
if (aResult.l == nsnull) {
|
||||
*result = env->NewStringUTF(str->get());
|
||||
if (*result == nsnull) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
aResult.l = nsnull;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -930,7 +936,7 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
||||
case nsXPTType::T_VOID:
|
||||
// handle "void *" as an "int" in Java
|
||||
LOG((" returns int (void*)"));
|
||||
aResult.i = (jint) aVariant.val.p;
|
||||
*result = env->NewObject(intClass, intInitMID, aVariant.val.p);
|
||||
break;
|
||||
|
||||
case nsXPTType::T_ARRAY:
|
||||
@ -945,31 +951,132 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
|
||||
jint aMethodIndex, jobjectArray aParams, jvalue &aResult)
|
||||
/**
|
||||
* Given an interface info struct and a method name, returns the method info
|
||||
* and index, if that method exists.
|
||||
*
|
||||
* Most method names are lower case. Unfortunately, the method names of some
|
||||
* interfaces (such as nsIAppShell) start with a capital letter. This function
|
||||
* will try all of the permutations.
|
||||
*/
|
||||
nsresult
|
||||
QueryMethodInfo(nsIInterfaceInfo* aIInfo, const char* aMethodName,
|
||||
PRUint16* aMethodIndex, const nsXPTMethodInfo** aMethodInfo)
|
||||
{
|
||||
// Find corresponding XPCOM object
|
||||
void* xpcomObj = gBindings->GetXPCOMObject(env, aJavaObject);
|
||||
if (xpcomObj == nsnull) {
|
||||
ThrowException(env, 0, "Failed to get matching XPCOM object");
|
||||
return;
|
||||
// The common case is that the method name is lower case, so we check
|
||||
// that first.
|
||||
nsresult rv;
|
||||
rv = aIInfo->GetMethodInfoForName(aMethodName, aMethodIndex, aMethodInfo);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return rv;
|
||||
|
||||
// If there is no method called <aMethodName>, then maybe it is an
|
||||
// 'attribute'. An 'attribute' will start with "get" or "set". But first,
|
||||
// we check the length, in order to skip over method names that match exactly
|
||||
// "get" or "set".
|
||||
if (strlen(aMethodName) > 3) {
|
||||
if (strncmp("get", aMethodName, 3) == 0) {
|
||||
char* getterName = strdup(aMethodName + 3);
|
||||
getterName[0] = tolower(getterName[0]);
|
||||
rv = aIInfo->GetMethodInfoForName(getterName, aMethodIndex, aMethodInfo);
|
||||
free(getterName);
|
||||
} else if (strncmp("set", aMethodName, 3) == 0) {
|
||||
char* setterName = strdup(aMethodName + 3);
|
||||
setterName[0] = tolower(setterName[0]);
|
||||
rv = aIInfo->GetMethodInfoForName(setterName, aMethodIndex, aMethodInfo);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// If this succeeded, GetMethodInfoForName will have returned the
|
||||
// method info for the 'getter'. We want the 'setter', so increase
|
||||
// method index by one ('setter' immediately follows the 'getter'),
|
||||
// and get its method info.
|
||||
(*aMethodIndex)++;
|
||||
rv = aIInfo->GetMethodInfo(*aMethodIndex, aMethodInfo);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Double check that this methodInfo matches the given method.
|
||||
if (!(*aMethodInfo)->IsSetter() ||
|
||||
strcmp(setterName, (*aMethodInfo)->name) != 0) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(setterName);
|
||||
}
|
||||
}
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return rv;
|
||||
|
||||
// If we get here, then maybe the method name is capitalized.
|
||||
char* methodName = strdup(aMethodName);
|
||||
methodName[0] = toupper(methodName[0]);
|
||||
rv = aIInfo->GetMethodInfoForName(methodName, aMethodIndex, aMethodInfo);
|
||||
free(methodName);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return rv;
|
||||
|
||||
// If there is no method called <aMethodName>, then maybe it is an
|
||||
// 'attribute'.
|
||||
if (strlen(aMethodName) > 3) {
|
||||
if (strncmp("get", aMethodName, 3) == 0) {
|
||||
char* getterName = strdup(aMethodName + 3);
|
||||
rv = aIInfo->GetMethodInfoForName(getterName, aMethodIndex, aMethodInfo);
|
||||
free(getterName);
|
||||
} else if (strncmp("set", aMethodName, 3) == 0) {
|
||||
char* setterName = strdup(aMethodName + 3);
|
||||
rv = aIInfo->GetMethodInfoForName(setterName, aMethodIndex, aMethodInfo);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// If this succeeded, GetMethodInfoForName will have returned the
|
||||
// method info for the 'getter'. We want the 'setter', so increase
|
||||
// method index by one ('setter' immediately follows the 'getter'),
|
||||
// and get its method info.
|
||||
(*aMethodIndex)++;
|
||||
rv = aIInfo->GetMethodInfo(*aMethodIndex, aMethodInfo);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Double check that this methodInfo matches the given method.
|
||||
if (!(*aMethodInfo)->IsSetter() ||
|
||||
strcmp(setterName, (*aMethodInfo)->name) != 0) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(setterName);
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(!IsXPTCStub(xpcomObj),
|
||||
"Expected JavaXPCOMInstance, but got nsJavaXPTCStub");
|
||||
JavaXPCOMInstance* inst = (JavaXPCOMInstance*) xpcomObj;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* org.mozilla.xpcom.XPCOMJavaProxy.callXPCOMMethod
|
||||
*/
|
||||
extern "C" JX_EXPORT jobject JNICALL
|
||||
JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
|
||||
jstring aMethodName, jobjectArray aParams)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Get native XPCOM instance
|
||||
void* xpcom_obj;
|
||||
rv = GetXPCOMInstFromProxy(env, aJavaProxy, &xpcom_obj);
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowException(env, 0, "Failed to get matching XPCOM object");
|
||||
return nsnull;
|
||||
}
|
||||
JavaXPCOMInstance* inst = NS_STATIC_CAST(JavaXPCOMInstance*, xpcom_obj);
|
||||
|
||||
// Get method info
|
||||
PRUint16 methodIndex;
|
||||
const nsXPTMethodInfo* methodInfo;
|
||||
nsIInterfaceInfo* iinfo = inst->InterfaceInfo();
|
||||
nsresult rv = iinfo->GetMethodInfo(aMethodIndex, &methodInfo);
|
||||
const char* methodName = env->GetStringUTFChars(aMethodName, nsnull);
|
||||
rv = QueryMethodInfo(iinfo, methodName, &methodIndex, &methodInfo);
|
||||
env->ReleaseStringUTFChars(aMethodName, methodName);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowException(env, rv, "GetMethodInfo failed");
|
||||
return;
|
||||
ThrowException(env, rv, "GetMethodInfoForName failed");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_pedemonte
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
const char* ifaceName;
|
||||
iinfo->GetNameShared(&ifaceName);
|
||||
LOG(("=> Calling %s::%s()\n", ifaceName, methodInfo->GetName()));
|
||||
@ -983,7 +1090,7 @@ CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
|
||||
params = new nsXPTCVariant[paramCount];
|
||||
if (!params) {
|
||||
ThrowException(env, NS_ERROR_OUT_OF_MEMORY, "Can't create params array");
|
||||
return;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)
|
||||
@ -993,7 +1100,7 @@ CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
|
||||
|
||||
if (paramInfo.IsIn() && !paramInfo.IsDipper()) {
|
||||
rv = SetupParams(env, env->GetObjectArrayElement(aParams, i), paramInfo,
|
||||
methodInfo, iinfo, aMethodIndex, params, params[i]);
|
||||
methodInfo, iinfo, methodIndex, params, params[i]);
|
||||
} else if (paramInfo.IsDipper()) {
|
||||
LOG(("dipper"));
|
||||
const nsXPTType &type = paramInfo.GetType();
|
||||
@ -1036,32 +1143,33 @@ CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowException(env, rv, "SetupParams failed");
|
||||
return;
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// Call the XPCOM method
|
||||
nsresult invokeResult;
|
||||
invokeResult = XPTC_InvokeByIndex(inst->GetInstance(), aMethodIndex,
|
||||
invokeResult = XPTC_InvokeByIndex(inst->GetInstance(), methodIndex,
|
||||
paramCount, params);
|
||||
|
||||
// Clean up params
|
||||
jobject result = nsnull;
|
||||
for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)
|
||||
{
|
||||
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(i);
|
||||
|
||||
if (!paramInfo.IsRetval()) {
|
||||
rv = FinalizeParams(env, env->GetObjectArrayElement(aParams, i),
|
||||
paramInfo, methodInfo, iinfo, aMethodIndex,
|
||||
paramInfo, methodInfo, iinfo, methodIndex,
|
||||
params, params[i]);
|
||||
} else {
|
||||
rv = SetRetval(env, paramInfo, methodInfo, iinfo, aMethodIndex, params,
|
||||
params[i], aResult);
|
||||
rv = SetRetval(env, paramInfo, methodInfo, iinfo, methodIndex, params,
|
||||
params[i], &result);
|
||||
}
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
ThrowException(env, rv, "FinalizeParams/SetRetval failed");
|
||||
return;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Normally, we would delete any created nsID object in the above loop.
|
||||
@ -1091,7 +1199,7 @@ CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
|
||||
ThrowException(env, invokeResult, message.get());
|
||||
}
|
||||
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -1102,8 +1210,6 @@ CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
|
||||
if (!aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
jobject java_obj = nsnull;
|
||||
|
||||
nsCOMPtr<nsIInterfaceInfoManager> iim = XPTI_GetInterfaceInfoManager();
|
||||
NS_ASSERTION(iim != nsnull, "Failed to get InterfaceInfoManager");
|
||||
if (!iim)
|
||||
@ -1125,19 +1231,19 @@ CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
|
||||
rv = info->GetNameShared(&iface_name);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Create proxy class name
|
||||
nsCAutoString class_name("org/mozilla/xpcom/stubs/");
|
||||
class_name.AppendASCII(iface_name);
|
||||
class_name.AppendLiteral("_Stub");
|
||||
jobject java_obj = nsnull;
|
||||
|
||||
// Create java proxy object
|
||||
jclass clazz;
|
||||
clazz = env->FindClass(class_name.get());
|
||||
if (clazz) {
|
||||
jmethodID constructor = env->GetMethodID(clazz, "<init>", "()V");
|
||||
if (constructor) {
|
||||
java_obj = env->NewObject(clazz, constructor);
|
||||
}
|
||||
// Create proper Java interface name
|
||||
nsCAutoString class_name("org/mozilla/xpcom/");
|
||||
class_name.AppendASCII(iface_name);
|
||||
jclass ifaceClass = env->FindClass(class_name.get());
|
||||
|
||||
if (ifaceClass) {
|
||||
java_obj = env->CallStaticObjectMethod(xpcomJavaProxyClass,
|
||||
createProxyMID, ifaceClass,
|
||||
NS_REINTERPRET_CAST(jlong, inst));
|
||||
if (env->ExceptionCheck())
|
||||
java_obj = nsnull;
|
||||
}
|
||||
|
||||
if (java_obj) {
|
||||
@ -1157,3 +1263,53 @@ CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetXPCOMInstFromProxy(JNIEnv* env, jobject aJavaObject, void** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (!aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
long xpcom_obj = env->CallStaticIntMethod(xpcomJavaProxyClass,
|
||||
getNativeXPCOMInstMID, aJavaObject);
|
||||
|
||||
if (!xpcom_obj || env->ExceptionCheck()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aResult = NS_REINTERPRET_CAST(void*, xpcom_obj);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* org.mozilla.xpcom.XPCOMJavaProxy.finalizeProxy
|
||||
*/
|
||||
extern "C" JX_EXPORT void JNICALL
|
||||
JAVAPROXY_NATIVE(finalizeProxy) (JNIEnv *env, jclass that, jobject aJavaProxy)
|
||||
{
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
jstring string = nsnull;
|
||||
string = (jstring) env->CallStaticObjectMethod(xpcomJavaProxyClass,
|
||||
proxyToStringMID, aJavaProxy);
|
||||
const char* javaObjectName = env->GetStringUTFChars(string, nsnull);
|
||||
LOG(("*** Finalize(java_obj=%s)\n", javaObjectName));
|
||||
env->ReleaseStringUTFChars(string, javaObjectName);
|
||||
#endif
|
||||
|
||||
// Due to Java's garbage collection, this finalize statement may get called
|
||||
// after FreeJavaGlobals(). So check to make sure that everything is still
|
||||
// initialized.
|
||||
if (gJavaXPCOMLock) {
|
||||
nsAutoLock lock(gJavaXPCOMLock);
|
||||
|
||||
// Get native XPCOM instance
|
||||
void* xpcom_obj;
|
||||
nsresult rv = GetXPCOMInstFromProxy(env, aJavaProxy, &xpcom_obj);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
JavaXPCOMInstance* inst = NS_STATIC_CAST(JavaXPCOMInstance*, xpcom_obj);
|
||||
gBindings->RemoveBinding(env, aJavaProxy, nsnull);
|
||||
delete inst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -42,11 +42,31 @@
|
||||
#include "nsISupports.h"
|
||||
|
||||
|
||||
void CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,
|
||||
jint aMethodIndex, jobjectArray aParams, jvalue &aResult);
|
||||
|
||||
// Creates a Java proxy for the given XPCOM object.
|
||||
/**
|
||||
* Creates a Java proxy around an XPCOM C++ object.
|
||||
*
|
||||
* @param env pointer to Java context
|
||||
* @param aXPCOMObject XPCOM object to create proxy for
|
||||
* @param aIID IID for XPCOM object
|
||||
* @param aResult on exit, holds reference to Java proxy
|
||||
*
|
||||
* @return NS_OK if Java proxy was successfully created;
|
||||
* any other value denotes an error condition.
|
||||
*/
|
||||
nsresult CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject,
|
||||
const nsIID& aIID, jobject* aResult);
|
||||
|
||||
/**
|
||||
* Returns the XPCOM object for which the given Java proxy was created.
|
||||
*
|
||||
* @param env pointer to Java context
|
||||
* @param aJavaObject a Java proxy created by CreateJavaProxy()
|
||||
* @param aResult on exit, holds pointer to XPCOM instance
|
||||
*
|
||||
* @return NS_OK if the XPCOM object was successfully retrieved;
|
||||
* any other value denotes an error condition.
|
||||
*/
|
||||
nsresult GetXPCOMInstFromProxy(JNIEnv* env, jobject aJavaObject,
|
||||
void** aResult);
|
||||
|
||||
#endif // _nsJavaWrapper_h_
|
||||
|
||||
@ -47,26 +47,47 @@
|
||||
|
||||
|
||||
/* Java JNI globals */
|
||||
jclass booleanClass = nsnull;
|
||||
jclass charClass = nsnull;
|
||||
jclass byteClass = nsnull;
|
||||
jclass shortClass = nsnull;
|
||||
jclass intClass = nsnull;
|
||||
jclass longClass = nsnull;
|
||||
jclass floatClass = nsnull;
|
||||
jclass doubleClass = nsnull;
|
||||
jclass stringClass = nsnull;
|
||||
jclass nsISupportsClass = nsnull;
|
||||
jclass xpcomExceptionClass = nsnull;
|
||||
jclass xpcomJavaProxyClass = nsnull;
|
||||
|
||||
jmethodID hashCodeMID = nsnull;
|
||||
jmethodID booleanValueMID = nsnull;
|
||||
jmethodID booleanInitMID = nsnull;
|
||||
jmethodID charValueMID = nsnull;
|
||||
jmethodID charInitMID = nsnull;
|
||||
jmethodID byteValueMID = nsnull;
|
||||
jmethodID byteInitMID = nsnull;
|
||||
jmethodID shortValueMID = nsnull;
|
||||
jmethodID shortInitMID = nsnull;
|
||||
jmethodID intValueMID = nsnull;
|
||||
jmethodID intInitMID = nsnull;
|
||||
jmethodID longValueMID = nsnull;
|
||||
jmethodID longInitMID = nsnull;
|
||||
jmethodID floatValueMID = nsnull;
|
||||
jmethodID floatInitMID = nsnull;
|
||||
jmethodID doubleValueMID = nsnull;
|
||||
jmethodID doubleInitMID = nsnull;
|
||||
jmethodID createProxyMID = nsnull;
|
||||
jmethodID isXPCOMJavaProxyMID = nsnull;
|
||||
jmethodID getNativeXPCOMInstMID = nsnull;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
jmethodID getNameMID = nsnull;
|
||||
jmethodID proxyToStringMID = nsnull;
|
||||
#endif
|
||||
|
||||
nsJavaXPCOMBindings* gBindings = nsnull;
|
||||
PRBool gJavaXPCOMInitialized = PR_FALSE;
|
||||
PRLock* gJavaXPCOMLock = nsnull;
|
||||
|
||||
|
||||
/**************************************
|
||||
@ -274,7 +295,7 @@ nsJavaXPCOMBindings::GetXPCOMObject(JNIEnv* env, jobject aJavaObject)
|
||||
PL_DHASH_LOOKUP));
|
||||
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
||||
#ifdef DEBUG_pedemonte
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
void* xpcomObjKey = nsnull;
|
||||
if (IsXPTCStub(entry->mXPCOMInstance))
|
||||
xpcomObjKey = GetXPTCStubAddr(entry->mXPCOMInstance);
|
||||
@ -331,7 +352,7 @@ nsJavaXPCOMBindings::GetJavaObject(JNIEnv* env, void* aXPCOMObject,
|
||||
NS_RELEASE(xpcom_obj); // Owning ref passed on
|
||||
}
|
||||
|
||||
#ifdef DEBUG_pedemonte
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
if (*aResult) {
|
||||
LOG(("< Get Java<->XPCOM binding (Java=0x%08x | XPCOM=0x%08x)\n",
|
||||
env->CallIntMethod(*aResult, hashCodeMID), (int) aXPCOMObject));
|
||||
@ -348,96 +369,148 @@ nsJavaXPCOMBindings::GetJavaObject(JNIEnv* env, void* aXPCOMObject,
|
||||
PRBool
|
||||
InitializeJavaGlobals(JNIEnv *env)
|
||||
{
|
||||
if (gJavaXPCOMInitialized)
|
||||
if (gJavaXPCOMLock)
|
||||
return PR_TRUE;
|
||||
|
||||
jclass clazz;
|
||||
if (!(clazz = env->FindClass("java/lang/Object")) ||
|
||||
!(hashCodeMID = env->GetMethodID(clazz, "hashCode","()I")))
|
||||
{
|
||||
NS_WARNING("Problem creating java.lang.Object globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
if (!(clazz = env->FindClass("java/lang/Boolean")) ||
|
||||
!(booleanValueMID = env->GetMethodID(clazz,"booleanValue","()Z")))
|
||||
!(booleanClass = (jclass) env->NewGlobalRef(clazz)) ||
|
||||
!(booleanValueMID = env->GetMethodID(clazz, "booleanValue", "()Z")) ||
|
||||
!(booleanInitMID = env->GetMethodID(clazz, "<init>", "(Z)V")))
|
||||
{
|
||||
NS_WARNING("Problem creating java.lang.Boolean globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
if (!(clazz = env->FindClass("java/lang/Character")) ||
|
||||
!(charValueMID = env->GetMethodID(clazz,"charValue","()C")))
|
||||
!(charClass = (jclass) env->NewGlobalRef(clazz)) ||
|
||||
!(charValueMID = env->GetMethodID(clazz, "charValue", "()C")) ||
|
||||
!(charInitMID = env->GetMethodID(clazz, "<init>", "(C)V")))
|
||||
{
|
||||
NS_WARNING("Problem creating java.lang.Character globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
if (!(clazz = env->FindClass("java/lang/Byte")) ||
|
||||
!(byteValueMID = env->GetMethodID(clazz,"byteValue","()B")))
|
||||
!(byteClass = (jclass) env->NewGlobalRef(clazz)) ||
|
||||
!(byteValueMID = env->GetMethodID(clazz, "byteValue", "()B")) ||
|
||||
!(byteInitMID = env->GetMethodID(clazz, "<init>", "(B)V")))
|
||||
{
|
||||
NS_WARNING("Problem creating java.lang.Byte globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
if (!(clazz = env->FindClass("java/lang/Short")) ||
|
||||
!(shortValueMID = env->GetMethodID(clazz,"shortValue","()S")))
|
||||
!(shortClass = (jclass) env->NewGlobalRef(clazz)) ||
|
||||
!(shortValueMID = env->GetMethodID(clazz, "shortValue", "()S")) ||
|
||||
!(shortInitMID = env->GetMethodID(clazz, "<init>", "(S)V")))
|
||||
{
|
||||
NS_WARNING("Problem creating java.lang.Short globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
if (!(clazz = env->FindClass("java/lang/Integer")) ||
|
||||
!(intValueMID = env->GetMethodID(clazz,"intValue","()I")))
|
||||
!(intClass = (jclass) env->NewGlobalRef(clazz)) ||
|
||||
!(intValueMID = env->GetMethodID(clazz, "intValue", "()I")) ||
|
||||
!(intInitMID = env->GetMethodID(clazz, "<init>", "(I)V")))
|
||||
{
|
||||
NS_WARNING("Problem creating java.lang.Integer globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
if (!(clazz = env->FindClass("java/lang/Long")) ||
|
||||
!(longValueMID = env->GetMethodID(clazz,"longValue","()J")))
|
||||
!(longClass = (jclass) env->NewGlobalRef(clazz)) ||
|
||||
!(longValueMID = env->GetMethodID(clazz, "longValue", "()J")) ||
|
||||
!(longInitMID = env->GetMethodID(clazz, "<init>", "(J)V")))
|
||||
{
|
||||
NS_WARNING("Problem creating java.lang.Long globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
if (!(clazz = env->FindClass("java/lang/Float")) ||
|
||||
!(floatValueMID = env->GetMethodID(clazz,"floatValue","()F")))
|
||||
!(floatClass = (jclass) env->NewGlobalRef(clazz)) ||
|
||||
!(floatValueMID = env->GetMethodID(clazz, "floatValue", "()F")) ||
|
||||
!(floatInitMID = env->GetMethodID(clazz, "<init>", "(F)V")))
|
||||
{
|
||||
NS_WARNING("Problem creating java.lang.Float globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
if (!(clazz = env->FindClass("java/lang/Double")) ||
|
||||
!(doubleValueMID = env->GetMethodID(clazz,"doubleValue","()D")))
|
||||
!(doubleClass = (jclass) env->NewGlobalRef(clazz)) ||
|
||||
!(doubleValueMID = env->GetMethodID(clazz, "doubleValue", "()D")) ||
|
||||
!(doubleInitMID = env->GetMethodID(clazz, "<init>", "(D)V")))
|
||||
{
|
||||
NS_WARNING("Problem creating java.lang.Double globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
if (!(clazz = env->FindClass("java/lang/String")) ||
|
||||
!(stringClass = (jclass) env->NewGlobalRef(clazz)))
|
||||
{
|
||||
NS_WARNING("Problem creating java.lang.String globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
if (!(clazz = env->FindClass("org/mozilla/xpcom/nsISupports")) ||
|
||||
!(nsISupportsClass = (jclass) env->NewGlobalRef(clazz)))
|
||||
{
|
||||
NS_WARNING("Problem creating org.mozilla.xpcom.nsISupports globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
if (!(clazz = env->FindClass("org/mozilla/xpcom/XPCOMException")) ||
|
||||
!(xpcomExceptionClass = (jclass) env->NewGlobalRef(clazz)))
|
||||
{
|
||||
NS_WARNING("Problem creating org.mozilla.xpcom.XPCOMException globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!(clazz = env->FindClass("org/mozilla/xpcom/XPCOMJavaProxy")) ||
|
||||
!(xpcomJavaProxyClass = (jclass) env->NewGlobalRef(clazz)) ||
|
||||
!(createProxyMID = env->GetStaticMethodID(clazz, "createProxy",
|
||||
"(Ljava/lang/Class;J)Ljava/lang/Object;")) ||
|
||||
!(isXPCOMJavaProxyMID = env->GetStaticMethodID(clazz, "isXPCOMJavaProxy",
|
||||
"(Ljava/lang/Object;)Z")) ||
|
||||
!(getNativeXPCOMInstMID = env->GetStaticMethodID(xpcomJavaProxyClass,
|
||||
"getNativeXPCOMInstance",
|
||||
"(Ljava/lang/Object;)J")))
|
||||
{
|
||||
NS_WARNING("Problem creating org.mozilla.xpcom.XPCOMJavaProxy globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
if (!(clazz = env->FindClass("java/lang/Class")) ||
|
||||
!(getNameMID = env->GetMethodID(clazz, "getName","()Ljava/lang/String;")))
|
||||
{
|
||||
NS_WARNING("Problem creating java.lang.Class globals");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
if (!(proxyToStringMID = env->GetStaticMethodID(xpcomJavaProxyClass,
|
||||
"proxyToString",
|
||||
"(Ljava/lang/Object;)Ljava/lang/String;")))
|
||||
{
|
||||
NS_WARNING("Problem creating proxyToString global");
|
||||
goto init_error;
|
||||
}
|
||||
#endif
|
||||
|
||||
gBindings = new nsJavaXPCOMBindings();
|
||||
if (NS_FAILED(gBindings->Init())) {
|
||||
NS_WARNING("Problem creating JavaXPCOMBindings");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
gJavaXPCOMInitialized = PR_TRUE;
|
||||
gJavaXPCOMLock = PR_NewLock();
|
||||
return PR_TRUE;
|
||||
|
||||
init_error:
|
||||
@ -453,6 +526,40 @@ init_error:
|
||||
void
|
||||
FreeJavaGlobals(JNIEnv* env)
|
||||
{
|
||||
PR_Lock(gJavaXPCOMLock);
|
||||
|
||||
if (booleanClass) {
|
||||
env->DeleteGlobalRef(booleanClass);
|
||||
booleanClass = nsnull;
|
||||
}
|
||||
if (charClass) {
|
||||
env->DeleteGlobalRef(charClass);
|
||||
charClass = nsnull;
|
||||
}
|
||||
if (byteClass) {
|
||||
env->DeleteGlobalRef(byteClass);
|
||||
byteClass = nsnull;
|
||||
}
|
||||
if (shortClass) {
|
||||
env->DeleteGlobalRef(shortClass);
|
||||
shortClass = nsnull;
|
||||
}
|
||||
if (intClass) {
|
||||
env->DeleteGlobalRef(intClass);
|
||||
intClass = nsnull;
|
||||
}
|
||||
if (longClass) {
|
||||
env->DeleteGlobalRef(longClass);
|
||||
longClass = nsnull;
|
||||
}
|
||||
if (floatClass) {
|
||||
env->DeleteGlobalRef(floatClass);
|
||||
floatClass = nsnull;
|
||||
}
|
||||
if (doubleClass) {
|
||||
env->DeleteGlobalRef(doubleClass);
|
||||
doubleClass = nsnull;
|
||||
}
|
||||
if (stringClass) {
|
||||
env->DeleteGlobalRef(stringClass);
|
||||
stringClass = nsnull;
|
||||
@ -465,13 +572,19 @@ FreeJavaGlobals(JNIEnv* env)
|
||||
env->DeleteGlobalRef(xpcomExceptionClass);
|
||||
xpcomExceptionClass = nsnull;
|
||||
}
|
||||
if (xpcomJavaProxyClass) {
|
||||
env->DeleteGlobalRef(xpcomJavaProxyClass);
|
||||
xpcomJavaProxyClass = nsnull;
|
||||
}
|
||||
|
||||
if (gBindings) {
|
||||
delete gBindings;
|
||||
gBindings = nsnull;
|
||||
}
|
||||
|
||||
gJavaXPCOMInitialized = PR_FALSE;
|
||||
PR_Unlock(gJavaXPCOMLock);
|
||||
PR_DestroyLock(gJavaXPCOMLock);
|
||||
gJavaXPCOMLock = nsnull;
|
||||
}
|
||||
|
||||
|
||||
@ -484,14 +597,18 @@ JavaXPCOMInstance::JavaXPCOMInstance(nsISupports* aInstance,
|
||||
mIInfo(aIInfo)
|
||||
{
|
||||
NS_ADDREF(mInstance);
|
||||
NS_ADDREF(mIInfo);
|
||||
}
|
||||
|
||||
JavaXPCOMInstance::~JavaXPCOMInstance()
|
||||
{
|
||||
// Need to release these objects on the main thread.
|
||||
nsCOMPtr<nsIEventQueue> eventQ;
|
||||
nsresult rv = NS_GetMainEventQ(getter_AddRefs(eventQ));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = NS_ProxyRelease(eventQ, mInstance);
|
||||
rv += NS_ProxyRelease(eventQ, mIInfo);
|
||||
}
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to release using NS_ProxyRelease");
|
||||
}
|
||||
|
||||
|
||||
@ -43,8 +43,10 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "pldhash.h"
|
||||
#include "nsAutoLock.h"
|
||||
|
||||
#ifdef DEBUG_pedemonte
|
||||
//#define DEBUG_JAVAXPCOM
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
#define LOG(x) printf x
|
||||
#else
|
||||
#define LOG(x) /* nothing */
|
||||
@ -60,28 +62,49 @@
|
||||
/*********************
|
||||
* Java JNI globals
|
||||
*********************/
|
||||
extern jclass booleanClass;
|
||||
extern jclass charClass;
|
||||
extern jclass byteClass;
|
||||
extern jclass shortClass;
|
||||
extern jclass intClass;
|
||||
extern jclass longClass;
|
||||
extern jclass floatClass;
|
||||
extern jclass doubleClass;
|
||||
extern jclass stringClass;
|
||||
extern jclass nsISupportsClass;
|
||||
extern jclass xpcomExceptionClass;
|
||||
extern jclass xpcomJavaProxyClass;
|
||||
|
||||
extern jmethodID hashCodeMID;
|
||||
extern jmethodID booleanValueMID;
|
||||
extern jmethodID booleanInitMID;
|
||||
extern jmethodID charValueMID;
|
||||
extern jmethodID charInitMID;
|
||||
extern jmethodID byteValueMID;
|
||||
extern jmethodID byteInitMID;
|
||||
extern jmethodID shortValueMID;
|
||||
extern jmethodID shortInitMID;
|
||||
extern jmethodID intValueMID;
|
||||
extern jmethodID intInitMID;
|
||||
extern jmethodID longValueMID;
|
||||
extern jmethodID longInitMID;
|
||||
extern jmethodID floatValueMID;
|
||||
extern jmethodID floatInitMID;
|
||||
extern jmethodID doubleValueMID;
|
||||
extern jmethodID doubleInitMID;
|
||||
extern jmethodID createProxyMID;
|
||||
extern jmethodID isXPCOMJavaProxyMID;
|
||||
extern jmethodID getNativeXPCOMInstMID;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
extern jmethodID getNameMID;
|
||||
extern jmethodID proxyToStringMID;
|
||||
#endif
|
||||
|
||||
class nsJavaXPCOMBindings;
|
||||
extern nsJavaXPCOMBindings* gBindings;
|
||||
|
||||
extern PRBool gJavaXPCOMInitialized;
|
||||
extern PRLock* gJavaXPCOMLock;
|
||||
PRBool InitializeJavaGlobals(JNIEnv *env);
|
||||
void FreeJavaGlobals(JNIEnv* env);
|
||||
|
||||
@ -100,8 +123,8 @@ public:
|
||||
nsIInterfaceInfo* InterfaceInfo() { return mIInfo; }
|
||||
|
||||
private:
|
||||
nsISupports* mInstance;
|
||||
nsCOMPtr<nsIInterfaceInfo> mIInfo;
|
||||
nsISupports* mInstance;
|
||||
nsIInterfaceInfo* mIInfo;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -53,13 +53,14 @@ nsJavaXPTCStub::nsJavaXPTCStub(JNIEnv* aJavaEnv, jobject aJavaObject,
|
||||
{
|
||||
mJavaObject = aJavaEnv->NewGlobalRef(aJavaObject);
|
||||
|
||||
#ifdef DEBUG_pedemonte
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
jstring name;
|
||||
const char* javaObjectName = nsnull;
|
||||
jclass clazz = mJavaEnv->GetObjectClass(mJavaObject);
|
||||
if (clazz) {
|
||||
name = (jstring) mJavaEnv->CallObjectMethod(clazz, getNameMID);
|
||||
javaObjectName = mJavaEnv->GetStringUTFChars(name, nsnull);
|
||||
if (name)
|
||||
javaObjectName = mJavaEnv->GetStringUTFChars(name, nsnull);
|
||||
}
|
||||
|
||||
nsID* iid = nsnull;
|
||||
@ -75,7 +76,8 @@ nsJavaXPTCStub::nsJavaXPTCStub(JNIEnv* aJavaEnv, jobject aJavaObject,
|
||||
LOG(("+++ nsJavaXPTCStub(this=0x%08x java_obj=0x%08x %s iid=%s)\n", (int) this,
|
||||
mJavaEnv->CallIntMethod(mJavaObject, hashCodeMID),
|
||||
javaObjectName ? javaObjectName : "<-->", iid_str ? iid_str : "NULL"));
|
||||
mJavaEnv->ReleaseStringUTFChars(name, javaObjectName);
|
||||
if (name)
|
||||
mJavaEnv->ReleaseStringUTFChars(name, javaObjectName);
|
||||
if (iid_str)
|
||||
nsMemory::Free(iid_str);
|
||||
#endif
|
||||
@ -83,19 +85,21 @@ nsJavaXPTCStub::nsJavaXPTCStub(JNIEnv* aJavaEnv, jobject aJavaObject,
|
||||
|
||||
nsJavaXPTCStub::~nsJavaXPTCStub()
|
||||
{
|
||||
#ifdef DEBUG_pedemonte
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
jstring name;
|
||||
const char* javaObjectName = nsnull;
|
||||
jclass clazz = mJavaEnv->GetObjectClass(mJavaObject);
|
||||
if (clazz) {
|
||||
name = (jstring) mJavaEnv->CallObjectMethod(clazz, getNameMID);
|
||||
javaObjectName = mJavaEnv->GetStringUTFChars(name, nsnull);
|
||||
if (name)
|
||||
javaObjectName = mJavaEnv->GetStringUTFChars(name, nsnull);
|
||||
}
|
||||
|
||||
LOG(("--- ~nsJavaXPTCStub(this=0x%08x java_obj=0x%08x %s)\n", (int) this,
|
||||
mJavaEnv->CallIntMethod(mJavaObject, hashCodeMID),
|
||||
javaObjectName ? javaObjectName : "<-->"));
|
||||
mJavaEnv->ReleaseStringUTFChars(name, javaObjectName);
|
||||
if (name)
|
||||
mJavaEnv->ReleaseStringUTFChars(name, javaObjectName);
|
||||
#endif
|
||||
|
||||
if (!mMaster) {
|
||||
@ -309,7 +313,7 @@ nsJavaXPTCStub::CallMethod(PRUint16 aMethodIndex,
|
||||
const nsXPTMethodInfo *aMethodInfo,
|
||||
nsXPTCMiniVariant *aParams)
|
||||
{
|
||||
#ifdef DEBUG_pedemonte
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
const char* ifaceName;
|
||||
mIInfo->GetNameShared(&ifaceName);
|
||||
LOG(("nsJavaXPTCStub::CallMethod [%s::%s]\n", ifaceName, aMethodInfo->GetName()));
|
||||
@ -1346,7 +1350,23 @@ nsJavaXPTCStub::FinalizeJavaParams(const nsXPTParamInfo &aParamInfo,
|
||||
nsISupports** variant = NS_STATIC_CAST(nsISupports**, aVariant.val.p);
|
||||
if (java_obj) {
|
||||
// Check if we already have a corresponding XPCOM object
|
||||
void* inst = gBindings->GetXPCOMObject(mJavaEnv, java_obj);
|
||||
jboolean isProxy;
|
||||
isProxy = mJavaEnv->CallStaticBooleanMethod(xpcomJavaProxyClass,
|
||||
isXPCOMJavaProxyMID,
|
||||
java_obj);
|
||||
if (mJavaEnv->ExceptionCheck()) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
void* inst;
|
||||
if (isProxy) {
|
||||
rv = GetXPCOMInstFromProxy(mJavaEnv, java_obj, &inst);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
} else {
|
||||
inst = gBindings->GetXPCOMObject(mJavaEnv, java_obj);
|
||||
}
|
||||
|
||||
// Get IID for this param
|
||||
nsID iid;
|
||||
|
||||
@ -61,7 +61,6 @@ CSRCS = \
|
||||
xpidl_typelib.c \
|
||||
xpidl_doc.c \
|
||||
xpidl_java.c \
|
||||
xpidl_javastub.c \
|
||||
$(NULL)
|
||||
|
||||
SDK_BINARY = \
|
||||
|
||||
@ -46,7 +46,6 @@ static ModeData modes[] = {
|
||||
{"typelib", "Generate XPConnect typelib", "xpt", xpidl_typelib_dispatch},
|
||||
{"doc", "Generate HTML documentation", "html", xpidl_doc_dispatch},
|
||||
{"java", "Generate Java interface", "java", xpidl_java_dispatch},
|
||||
{"javastub","Generate Java Stub", "java", xpidl_javastub_dispatch},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
@ -112,7 +112,6 @@ extern backend *xpidl_header_dispatch(void);
|
||||
extern backend *xpidl_typelib_dispatch(void);
|
||||
extern backend *xpidl_doc_dispatch(void);
|
||||
extern backend *xpidl_java_dispatch(void);
|
||||
extern backend *xpidl_javastub_dispatch(void);
|
||||
|
||||
typedef struct ModeData {
|
||||
char *mode;
|
||||
|
||||
@ -760,8 +760,7 @@ xpidl_process_idl(char *filename, IncludePathEntry *include_path,
|
||||
}
|
||||
|
||||
/* don't create/open file here for Java */
|
||||
if (strcmp(mode->mode, "java") == 0 ||
|
||||
strcmp(mode->mode, "javastub") == 0)
|
||||
if (strcmp(mode->mode, "java") == 0)
|
||||
{
|
||||
state.filename = real_outname;
|
||||
} else {
|
||||
@ -785,8 +784,7 @@ xpidl_process_idl(char *filename, IncludePathEntry *include_path,
|
||||
if (emitter->emit_epilog)
|
||||
emitter->emit_epilog(&state);
|
||||
|
||||
if (strcmp(mode->mode, "java") != 0 &&
|
||||
strcmp(mode->mode, "javastub") != 0)
|
||||
if (strcmp(mode->mode, "java") != 0)
|
||||
{
|
||||
if (state.file != stdout)
|
||||
fclose(state.file);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user