From e24e39cc5a8ef770f35646d5133302d50ee838b1 Mon Sep 17 00:00:00 2001 From: "pedemont%us.ibm.com" Date: Tue, 13 Feb 2007 18:55:34 +0000 Subject: [PATCH] Bug 369410 - Provide API for wrapping XPCOM and Java objects. XULRunner only. Not part of default build. --- .../java/xpcom/glue/nsJavaXPCOMGlue.cpp | 31 ++++++++- extensions/java/xpcom/interfaces/Makefile.in | 1 + .../org/mozilla/xpcom/IJavaXPCOMUtils.java | 59 +++++++++++++++++ .../interfaces/org/mozilla/xpcom/Mozilla.java | 29 ++++++++- .../java/xpcom/src/dlldeps-javaxpcom.cpp | 4 ++ .../java/xpcom/src/nsJavaInterfaces.cpp | 64 +++++++++++++++++++ extensions/java/xpcom/src/nsJavaInterfaces.h | 10 +++ .../xpcom/internal/JavaXPCOMMethods.java | 8 ++- 8 files changed, 199 insertions(+), 7 deletions(-) create mode 100644 extensions/java/xpcom/interfaces/org/mozilla/xpcom/IJavaXPCOMUtils.java diff --git a/extensions/java/xpcom/glue/nsJavaXPCOMGlue.cpp b/extensions/java/xpcom/glue/nsJavaXPCOMGlue.cpp index cd2d89996f5a..229ad027c47b 100644 --- a/extensions/java/xpcom/glue/nsJavaXPCOMGlue.cpp +++ b/extensions/java/xpcom/glue/nsJavaXPCOMGlue.cpp @@ -85,10 +85,12 @@ enum { kFunc_FinalizeProxy, kFunc_IsSameXPCOMObject, kFunc_ReleaseProfileLock, - kFunc_GetNativeHandleFromAWT + kFunc_GetNativeHandleFromAWT, + kFunc_WrapJavaObject, + kFunc_WrapXPCOMObject }; -#define JX_NUM_FUNCS 16 +#define JX_NUM_FUNCS 18 // Get path string from java.io.File object. @@ -167,6 +169,10 @@ LoadXULMethods(JNIEnv* env, jobject aXPCOMPath, void** aFunctions) (NSFuncPtr*) &aFunctions[kFunc_ReleaseProfileLock] }, { "_Java_org_mozilla_xpcom_internal_MozillaImpl_getNativeHandleFromAWT@12", (NSFuncPtr*) &aFunctions[kFunc_GetNativeHandleFromAWT] }, + { "_Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_wrapJavaObject@16", + (NSFuncPtr*) &aFunctions[kFunc_WrapJavaObject] }, + { "_Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_wrapXPCOMObject@16", + (NSFuncPtr*) &aFunctions[kFunc_WrapXPCOMObject] }, { nsnull, nsnull } }; #else @@ -203,6 +209,10 @@ LoadXULMethods(JNIEnv* env, jobject aXPCOMPath, void** aFunctions) (NSFuncPtr*) &aFunctions[kFunc_ReleaseProfileLock] }, { "Java_org_mozilla_xpcom_internal_MozillaImpl_getNativeHandleFromAWT", (NSFuncPtr*) &aFunctions[kFunc_GetNativeHandleFromAWT] }, + { "Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_wrapJavaObject", + (NSFuncPtr*) &aFunctions[kFunc_WrapJavaObject] }, + { "Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_wrapXPCOMObject", + (NSFuncPtr*) &aFunctions[kFunc_WrapXPCOMObject] }, { nsnull, nsnull } }; #endif @@ -304,11 +314,18 @@ RegisterNativeMethods(JNIEnv* env, void** aFunctions) (void*) aFunctions[kFunc_IsSameXPCOMObject] } }; - JNINativeMethod lockProxy_methods[] = { + JNINativeMethod lockProxy_methods[] = { { "releaseNative", "(J)V", (void*) aFunctions[kFunc_ReleaseProfileLock] } }; + JNINativeMethod util_methods[] = { + { "wrapJavaObject", "(Ljava/lang/Object;Ljava/lang/String;)J", + (void*) aFunctions[kFunc_WrapJavaObject] }, + { "wrapXPCOMObject", "(JLjava/lang/String;)Ljava/lang/Object;", + (void*) aFunctions[kFunc_WrapXPCOMObject] } + }; + jint rc = -1; jclass clazz = env->FindClass("org/mozilla/xpcom/internal/MozillaImpl"); if (clazz) { @@ -349,6 +366,14 @@ RegisterNativeMethods(JNIEnv* env, void** aFunctions) } NS_ENSURE_TRUE(rc == 0, NS_ERROR_FAILURE); + rc = -1; + clazz = env->FindClass("org/mozilla/xpcom/internal/JavaXPCOMMethods"); + if (clazz) { + rc = env->RegisterNatives(clazz, util_methods, + sizeof(util_methods) / sizeof(util_methods[0])); + } + NS_ENSURE_TRUE(rc == 0, NS_ERROR_FAILURE); + return NS_OK; } diff --git a/extensions/java/xpcom/interfaces/Makefile.in b/extensions/java/xpcom/interfaces/Makefile.in index 4658048458c3..521bde90c5e3 100644 --- a/extensions/java/xpcom/interfaces/Makefile.in +++ b/extensions/java/xpcom/interfaces/Makefile.in @@ -54,6 +54,7 @@ JAVA_SRCS = \ $(PACKAGE_DIR)/IMozilla.java \ $(PACKAGE_DIR)/IGRE.java \ $(PACKAGE_DIR)/IXPCOM.java \ + $(PACKAGE_DIR)/IJavaXPCOMUtils.java \ $(PACKAGE_DIR)/IAppFileLocProvider.java \ $(PACKAGE_DIR)/INIParser.java \ $(PACKAGE_DIR)/VersionComparator.java \ diff --git a/extensions/java/xpcom/interfaces/org/mozilla/xpcom/IJavaXPCOMUtils.java b/extensions/java/xpcom/interfaces/org/mozilla/xpcom/IJavaXPCOMUtils.java new file mode 100644 index 000000000000..7b70caf9a3dd --- /dev/null +++ b/extensions/java/xpcom/interfaces/org/mozilla/xpcom/IJavaXPCOMUtils.java @@ -0,0 +1,59 @@ +/* ***** 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) 2007 + * 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; + +public interface IJavaXPCOMUtils { + + /** + * Returns a pointer to a C++ proxy object for the given Java object. + * + * @param aJavaObject Java object to encapsulate in C++ proxy + * @param aIID interface ID for requested proxy + * @return C pointer (as long) of new proxy + */ + long wrapJavaObject(Object aJavaObject, String aIID); + + /** + * Returns a Java proxy for the given C++ XPCOM object + * + * @param aXPCOMObject C++ XPCOM object to encapsulate in Java proxy + * @param aIID interface ID for requested proxy + * @return new Proxy + */ + Object wrapXPCOMObject(long aXPCOMObject, String aIID); + +} diff --git a/extensions/java/xpcom/interfaces/org/mozilla/xpcom/Mozilla.java b/extensions/java/xpcom/interfaces/org/mozilla/xpcom/Mozilla.java index 3e8c9aca76ee..440b04c71428 100644 --- a/extensions/java/xpcom/interfaces/org/mozilla/xpcom/Mozilla.java +++ b/extensions/java/xpcom/interfaces/org/mozilla/xpcom/Mozilla.java @@ -85,17 +85,17 @@ import org.mozilla.interfaces.nsISupports; * * @see http://www.mozilla.org/projects/embedding/GRE.html */ -public class Mozilla implements IMozilla, IGRE, IXPCOM, IXPCOMError { +public class Mozilla implements IMozilla, IGRE, IXPCOM, IJavaXPCOMUtils, +IXPCOMError { private static Mozilla mozillaInstance = new Mozilla(); private static final String JAVAXPCOM_JAR = "javaxpcom.jar"; private IMozilla mozilla = null; - private IGRE gre = null; - private IXPCOM xpcom = null; + private IJavaXPCOMUtils jxutils = null; /** * @return @@ -655,6 +655,11 @@ public class Mozilla implements IMozilla, IGRE, IXPCOM, IXPCOMError { Class xpcomClass = Class.forName("org.mozilla.xpcom.internal.XPCOMImpl", true, loader); xpcom = (IXPCOM) xpcomClass.newInstance(); + + Class javaXPCOMClass = + Class.forName("org.mozilla.xpcom.internal.JavaXPCOMMethods", + true, loader); + jxutils = (IJavaXPCOMUtils) javaXPCOMClass.newInstance(); } catch (Exception e) { throw new XPCOMInitializationException("Could not load " + "org.mozilla.xpcom.internal.* classes", e); @@ -1041,4 +1046,22 @@ public class Mozilla implements IMozilla, IGRE, IXPCOM, IXPCOMError { } } + public long wrapJavaObject(Object aJavaObject, String aIID) { + try { + return jxutils.wrapJavaObject(aJavaObject, aIID); + } catch (NullPointerException e) { + throw new XPCOMInitializationException("Must call " + + "Mozilla.getInstance().initialize() before using this method", e); + } + } + + public Object wrapXPCOMObject(long aXPCOMObject, String aIID) { + try { + return jxutils.wrapXPCOMObject(aXPCOMObject, aIID); + } catch (NullPointerException e) { + throw new XPCOMInitializationException("Must call " + + "Mozilla.getInstance().initialize() before using this method", e); + } + } + } diff --git a/extensions/java/xpcom/src/dlldeps-javaxpcom.cpp b/extensions/java/xpcom/src/dlldeps-javaxpcom.cpp index f353557c4112..5f26c23b9cfd 100644 --- a/extensions/java/xpcom/src/dlldeps-javaxpcom.cpp +++ b/extensions/java/xpcom/src/dlldeps-javaxpcom.cpp @@ -74,5 +74,9 @@ void XXXNeverCalled_javaxpcom() LOCKPROXY_NATIVE(release) (nsnull, nsnull, nsnull); MOZILLA_NATIVE(getNativeHandleFromAWT) (nsnull, nsnull, nsnull); + + JXUTILS_NATIVE(wrapJavaObject) (nsnull, nsnull, nsnull, nsnull); + + JXUTILS_NATIVE(wrapXPCOMObject) (nsnull, nsnull, nsnull, nsnull); } diff --git a/extensions/java/xpcom/src/nsJavaInterfaces.cpp b/extensions/java/xpcom/src/nsJavaInterfaces.cpp index b4d884c0887d..0d454870353a 100644 --- a/extensions/java/xpcom/src/nsJavaInterfaces.cpp +++ b/extensions/java/xpcom/src/nsJavaInterfaces.cpp @@ -356,3 +356,67 @@ MOZILLA_NATIVE(getNativeHandleFromAWT) (JNIEnv* env, jobject clazz, return handle; } + +extern "C" NS_EXPORT jlong +JXUTILS_NATIVE(wrapJavaObject) (JNIEnv* env, jobject, jobject aJavaObject, + jstring aIID) +{ + nsresult rv; + nsISupports* xpcomObject = nsnull; + + if (!aJavaObject || !aIID) { + rv = NS_ERROR_NULL_POINTER; + } else { + const char* str = env->GetStringUTFChars(aIID, nsnull); + if (!str) { + rv = NS_ERROR_OUT_OF_MEMORY; + } else { + nsID iid; + if (iid.Parse(str)) { + rv = GetNewOrUsedXPCOMObject(env, aJavaObject, iid, &xpcomObject); + } else { + rv = NS_ERROR_INVALID_ARG; + } + + env->ReleaseStringUTFChars(aIID, str); + } + } + + if (NS_FAILED(rv)) { + ThrowException(env, rv, "Failed to create XPCOM proxy for Java object"); + } + return NS_REINTERPRET_CAST(jlong, xpcomObject); +} + +extern "C" NS_EXPORT jobject +JXUTILS_NATIVE(wrapXPCOMObject) (JNIEnv* env, jobject, jlong aXPCOMObject, + jstring aIID) +{ + nsresult rv; + jobject javaObject = nsnull; + nsISupports* xpcomObject = NS_REINTERPRET_CAST(nsISupports*, aXPCOMObject); + + if (!xpcomObject || !aIID) { + rv = NS_ERROR_NULL_POINTER; + } else { + const char* str = env->GetStringUTFChars(aIID, nsnull); + if (!str) { + rv = NS_ERROR_OUT_OF_MEMORY; + } else { + nsID iid; + if (iid.Parse(str)) { + // XXX Should we be passing something other than NULL for aObjectLoader? + rv = GetNewOrUsedJavaObject(env, xpcomObject, iid, nsnull, &javaObject); + } else { + rv = NS_ERROR_INVALID_ARG; + } + + env->ReleaseStringUTFChars(aIID, str); + } + } + + if (NS_FAILED(rv)) { + ThrowException(env, rv, "Failed to create XPCOM proxy for Java object"); + } + return javaObject; +} diff --git a/extensions/java/xpcom/src/nsJavaInterfaces.h b/extensions/java/xpcom/src/nsJavaInterfaces.h index d04202513e80..53c3f15c1d3d 100644 --- a/extensions/java/xpcom/src/nsJavaInterfaces.h +++ b/extensions/java/xpcom/src/nsJavaInterfaces.h @@ -46,6 +46,8 @@ #define JAVAPROXY_NATIVE(func) \ Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_##func #define LOCKPROXY_NATIVE(func) Java_org_mozilla_xpcom_ProfileLock_##func +#define JXUTILS_NATIVE(func) \ + Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_##func extern "C" NS_EXPORT void JNICALL @@ -101,4 +103,12 @@ LOCKPROXY_NATIVE(release) (JNIEnv *env, jclass that, jlong aLockObject); extern "C" NS_EXPORT jlong JNICALL MOZILLA_NATIVE(getNativeHandleFromAWT) (JNIEnv* env, jobject, jobject widget); +extern "C" NS_EXPORT jlong JNICALL +JXUTILS_NATIVE(wrapJavaObject) (JNIEnv* env, jobject, jobject aJavaObject, + jstring aIID); + +extern "C" NS_EXPORT jobject JNICALL +JXUTILS_NATIVE(wrapXPCOMObject) (JNIEnv* env, jobject, jlong aXPCOMObject, + jstring aIID); + #endif // _nsJavaInterfaces_h_ diff --git a/extensions/java/xpcom/src/org/mozilla/xpcom/internal/JavaXPCOMMethods.java b/extensions/java/xpcom/src/org/mozilla/xpcom/internal/JavaXPCOMMethods.java index 098352aa5e51..0fb3a9354bc8 100644 --- a/extensions/java/xpcom/src/org/mozilla/xpcom/internal/JavaXPCOMMethods.java +++ b/extensions/java/xpcom/src/org/mozilla/xpcom/internal/JavaXPCOMMethods.java @@ -38,8 +38,10 @@ package org.mozilla.xpcom.internal; import java.io.File; +import org.mozilla.xpcom.IJavaXPCOMUtils; -public class JavaXPCOMMethods { + +public class JavaXPCOMMethods implements IJavaXPCOMUtils { public static void registerJavaXPCOMMethods(File aLibXULDirectory) { // load JNI library @@ -85,5 +87,9 @@ public class JavaXPCOMMethods { } } + public native long wrapJavaObject(Object aJavaObject, String aIID); + + public native Object wrapXPCOMObject(long aXPCOMObject, String aIID); + }