summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/xpcom18a4/java')
-rw-r--r--src/libs/xpcom18a4/java/Makefile.kmk233
-rw-r--r--src/libs/xpcom18a4/java/README.vbox5
-rw-r--r--src/libs/xpcom18a4/java/src/MacJawt.mm47
-rw-r--r--src/libs/xpcom18a4/java/src/dlldeps-javaxpcom.cpp81
-rw-r--r--src/libs/xpcom18a4/java/src/nsAppFileLocProviderProxy.cpp253
-rw-r--r--src/libs/xpcom18a4/java/src/nsAppFileLocProviderProxy.h65
-rw-r--r--src/libs/xpcom18a4/java/src/nsFileStreams.cpp475
-rw-r--r--src/libs/xpcom18a4/java/src/nsFileStreams.h153
-rw-r--r--src/libs/xpcom18a4/java/src/nsIFileStreams.h209
-rw-r--r--src/libs/xpcom18a4/java/src/nsJavaInterfaces.cpp557
-rw-r--r--src/libs/xpcom18a4/java/src/nsJavaInterfaces.h121
-rw-r--r--src/libs/xpcom18a4/java/src/nsJavaWrapper.cpp2020
-rw-r--r--src/libs/xpcom18a4/java/src/nsJavaWrapper.h75
-rw-r--r--src/libs/xpcom18a4/java/src/nsJavaXPCOMBindingUtils.cpp1084
-rw-r--r--src/libs/xpcom18a4/java/src/nsJavaXPCOMBindingUtils.h392
-rw-r--r--src/libs/xpcom18a4/java/src/nsJavaXPCOMGlue.cpp535
-rw-r--r--src/libs/xpcom18a4/java/src/nsJavaXPTCStub.cpp1711
-rw-r--r--src/libs/xpcom18a4/java/src/nsJavaXPTCStub.h153
-rw-r--r--src/libs/xpcom18a4/java/src/nsJavaXPTCStubWeakRef.cpp98
-rw-r--r--src/libs/xpcom18a4/java/src/nsJavaXPTCStubWeakRef.h63
-rw-r--r--src/libs/xpcom18a4/java/src/nsThreadUtils.h399
-rw-r--r--src/libs/xpcom18a4/java/src/nsXPTCUtils.h128
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/GREVersionRange.java80
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IAppFileLocProvider.java92
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IGRE.java127
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IJavaXPCOMUtils.java59
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IMozilla.java63
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/INIParser.java243
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IXPCOM.java137
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/Mozilla.java1079
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/ProfileLock.java63
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/VersionComparator.java272
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/XPCOMException.java95
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/XPCOMInitializationException.java56
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/GREImpl.java63
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/JavaXPCOMMethods.java104
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/MozillaImpl.java56
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMImpl.java73
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxy.java257
-rw-r--r--src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxyBase.java53
-rw-r--r--src/libs/xpcom18a4/java/src/org/virtualbox/VBoxObjectBase.java31
-rwxr-xr-xsrc/libs/xpcom18a4/java/tools/gen-nsError.pl161
-rw-r--r--src/libs/xpcom18a4/java/tools/genifaces/GenerateJavaInterfaces.cpp952
-rw-r--r--src/libs/xpcom18a4/java/tools/genjifaces.xsl600
44 files changed, 13573 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/java/Makefile.kmk b/src/libs/xpcom18a4/java/Makefile.kmk
new file mode 100644
index 00000000..56c34c95
--- /dev/null
+++ b/src/libs/xpcom18a4/java/Makefile.kmk
@@ -0,0 +1,233 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-Makefile for Java bindings
+#
+
+#
+# Copyright (C) 2010-2022 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-3.0-only
+#
+
+SUB_DEPTH = ../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+#
+# Globals
+#
+VBOX_JXPCOM_SRC := $(PATH_SUB_CURRENT)
+
+VBOX_JXPCOM_TARGET := $(PATH_TARGET)/vboxjxpcom-gen
+VBOX_JXPCOM_JDEST := $(VBOX_JXPCOM_TARGET)/jdest
+
+VBOX_GLUE_XSLT_DIR := $(PATH_ROOT)/src/VBox/Main/glue
+
+ifndef VBOX_ONLY_SDK
+#
+# VBoxJXpcom - Java<->XPCOM native library
+#
+DLLS += VBoxJXpcom
+
+VBoxJXpcom_TEMPLATE = XPCOM
+VBoxJXpcom_CXXFLAGS = -Wno-write-strings
+VBoxJXpcom_DEFS = \
+ EXPORT_XPTI_API \
+ EXPORT_XPT_API \
+ VBOX_WITH_XPCOM
+VBoxJXpcom_NAME = libvboxjxpcom
+VBoxJXpcom_DLLSUFF.darwin = .jnilib
+VBoxJXpcom_INCS = \
+ src \
+ $(VBOX_JAVA_INC) \
+ $(VBOX_PATH_XPCOM_SRC)/xpcom/glue \
+ $(VBOX_PATH_XPCOM_SRC)/xpcom/build \
+ $(VBOX_JXPCOM_JDEST)
+VBoxJXpcom_SOURCES = \
+ src/nsAppFileLocProviderProxy.cpp \
+ src/nsJavaWrapper.cpp \
+ src/nsJavaXPCOMBindingUtils.cpp \
+ src/nsJavaXPTCStub.cpp \
+ src/nsJavaXPTCStubWeakRef.cpp \
+ src/nsJavaXPCOMGlue.cpp \
+ src/nsJavaInterfaces.cpp
+VBoxJXpcom_LIBS = \
+ $(PATH_STAGE_LIB)/VBoxCOM$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_BIN)/VBoxXPCOM$(VBOX_SUFF_DLL)
+
+#VBoxJXpcom_ORDERDEPS = $(VBOX_JXPCOM_GENH)
+#VBoxJXpcom_CLEAN = $(VBOX_JXPCOM_GENH)
+VBOX_JXPCOM_GENH = \
+ $(VBOX_JXPCOM_JDEST)/org_mozilla_xpcom_internal_XPCOMImpl.h \
+ $(VBOX_JXPCOM_JDEST)/org_mozilla_xpcom_internal_GREImpl.h \
+ $(VBOX_JXPCOM_JDEST)/org_mozilla_xpcom_internal_MozillaImpl.h \
+ $(VBOX_JXPCOM_JDEST)/org_mozilla_xpcom_internal_XPCOMJavaProxy.h \
+ $(VBOX_JXPCOM_JDEST)/org_mozilla_xpcom_internal_JavaXPCOMMethods.h \
+ $(VBOX_JXPCOM_JDEST)/org_mozilla_xpcom_ProfileLock.h
+
+
+else # VBOX_ONLY_SDK
+# Nothing yet
+endif # VBOX_ONLY_SDK
+
+#
+# Install JAR files
+#
+INSTALLS += VBoxJXpcom-inst-jar
+
+VBOX_JXPCOM_JAR = $(VBoxJXpcom-inst-jar_0_OUTDIR)/vboxjxpcom.jar
+VBOX_JXPCOM_NSERROR = $(VBOX_JXPCOM_GEN)/java/XPCOMError.java
+ifndef VBOX_WITH_JAVA_SUPPORT_IN_XPIDL
+VBOX_JXPCOM_GEN = $(VBOX_JXPCOM_TARGET)/jxpcomgen
+else
+VBOX_JXPCOM_GEN = $(VBOX_JXPCOM_TARGET)/jxpcomgen-idl
+endif
+
+VBoxJXpcom-inst-jar_INST = $(INST_SDK)bindings/xpcom/java/
+VBoxJXpcom-inst-jar_MODE = a+r,u+w
+VBoxJXpcom-inst-jar_SOURCES = \
+ $(VBOX_JXPCOM_JAR)
+VBoxJXpcom-inst-jar_CLEAN = \
+ $(VBOX_JXPCOM_JAR) \
+ $(VBOX_JXPCOM_NSERROR) \
+ $(VBOX_JXPCOM_GEN)/jxpcomgen.list \
+ $(VBOX_JXPCOM_GEN)/jxpcomglue.list \
+ $(wildcard \
+ $(VBOX_JXPCOM_GEN)/java/*.java \
+ $(VBOX_JXPCOM_GEN)/java/glue/*.java \
+ $(VBOX_JXPCOM_JDEST)/*.class \
+ $(VBOX_JXPCOM_JDEST)/*/*.class \
+ $(VBOX_JXPCOM_JDEST)/*/*/*.class \
+ $(VBOX_JXPCOM_JDEST)/*/*/*/*.class \
+ $(VBOX_JXPCOM_JDEST)/*/*/*/*/*.class \
+ $(VBOX_JXPCOM_JDEST)/*/*/*/*/*/*.class \
+ )
+VBoxJXpcom-inst-jar_BLDDIRS += $(VBOX_JXPCOM_GEN)/java $(VBOX_JXPCOM_GEN)/java/glue $(VBOX_JXPCOM_GEN)/java/interfaces
+
+#
+# For VBoxJXpcom, not currently used.
+#
+$(VBOX_JXPCOM_GENH): $$(VBOX_JXPCOM_JAR)
+ $(call MSG_L1,Generating $@ from $<)
+ $(QUIET)$(VBOX_JAVAH) -classpath $(VBOX_JXPCOM_JDEST) -d $(VBOX_JXPCOM_JDEST) \
+ org.mozilla.xpcom.internal.XPCOMImpl \
+ org.mozilla.xpcom.internal.GREImpl \
+ org.mozilla.xpcom.internal.MozillaImpl \
+ org.mozilla.xpcom.internal.XPCOMJavaProxy \
+ org.mozilla.xpcom.ProfileLock \
+ org.mozilla.xpcom.internal.JavaXPCOMMethods
+
+#
+# Generate error constants.
+#
+$(VBOX_JXPCOM_NSERROR): $(VBOX_PATH_XPCOM_SRC)/xpcom/base/nsError.h $(VBOX_JXPCOM_SRC)/tools/gen-nsError.pl | $(VBOX_JXPCOM_GEN)/java/
+ $(call MSG_L1,Generating $@)
+ $(QUIET)perl $(VBOX_JXPCOM_SRC)/tools/gen-nsError.pl < $< > $@
+
+ifndef VBOX_WITH_JAVA_SUPPORT_IN_XPIDL
+#
+# Generate .java interface files from .xidl
+#
+
+$(VBOX_JXPCOM_GEN)/jxpcomgen.list: \
+ $(VBOX_XIDL_FILE) \
+ $(VBOX_FILESPLIT) \
+ $(VBOX_JXPCOM_SRC)/tools/genjifaces.xsl \
+ | $(VBOX_JXPCOM_GEN)/java/interfaces/
+ $(call MSG_L1,Generating Java interface files)
+ $(QUIET)$(RM) -f $(wildcard $(VBOX_JXPCOM_GEN)/java/interfaces/*.java)
+ $(QUIET)$(VBOX_XSLTPROC) \
+ -o $(VBOX_JXPCOM_GEN)/java/interfaces/merged.file $(VBOX_JXPCOM_SRC)/tools/genjifaces.xsl $<
+ $(QUIET)$(VBOX_FILESPLIT) $(VBOX_JXPCOM_GEN)/java/interfaces/merged.file $(VBOX_JXPCOM_GEN)/java/interfaces
+ $(QUIET)echo $(VBOX_JXPCOM_GEN)/java/interfaces/*.java > $@
+
+else # VBOX_WITH_JAVA_SUPPORT_IN_XPIDL
+#
+# Generate .java interface files from the XPCOM and VirtualBox IDL files.
+#
+# Note! There is not a 1:1 relationship between input and output files here, unfortunately.
+# Note! VBOX_JXPCOM_NSERROR shares the output directory with us.
+#
+$(VBOX_JXPCOM_GEN)/jxpcomgen.list: \
+ $(VBOX_PATH_SDK)/bindings/xpcom/idl/VirtualBox_XPCOM.idl \
+ $$(addprefix $(VBOX_PATH_XPCOM_SRC)/,$$(XPCOM_IDLFILES)) \
+ $(VBOX_XPIDL) \
+ | $(VBOX_JXPCOM_GEN)/java/
+ $(call MSG_L1,Generating XPCOM Java interface files from IDL)
+ $(QUIET)$(RM) -f $(filter-out %/XPCOMError.java, $(wildcard $(VBOX_JXPCOM_GEN)/java/*.java))
+ $(foreach idl, $(VBOX_PATH_SDK)/bindings/xpcom/idl/VirtualBox_XPCOM.idl $(addprefix $(VBOX_PATH_XPCOM_SRC)/,$(XPCOM_IDLFILES))\
+ , $(NLTAB)$(QUIET)$(VBOX_XPIDL) -m java $(XPIDL_INCS) -e $(VBOX_JXPCOM_GEN)/java/$(basename $(notdir $(idl))).java $(idl) )
+ $(QUIET)echo $(VBOX_JXPCOM_GEN)/java/*.java > $@
+endif # VBOX_WITH_JAVA_SUPPORT_IN_XPIDL
+
+$(VBOX_JXPCOM_GEN)/jxpcomglue.list: \
+ $(VBOX_XIDL_FILE) \
+ $(VBOX_GLUE_XSLT_DIR)/glue-java.xsl \
+ $(VBOX_FILESPLIT) \
+ | $(VBOX_JXPCOM_GEN)/java/glue/
+ $(call MSG_L1,Generating Java glue files from XIDL)
+ $(QUIET)$(RM) -f $(wildcard $(VBOX_JXPCOM_GEN)/java/glue/*.java)
+ $(QUIET)$(VBOX_XSLTPROC) \
+ --stringparam filelistonly "" \
+ --stringparam G_vboxApiSuffix $(VBOX_API_SUFFIX) \
+ --stringparam G_vboxGlueStyle xpcom \
+ --stringparam G_vboxDirPrefix "" \
+ -o $(VBOX_JXPCOM_GEN)/java/glue/merged.file $(VBOX_GLUE_XSLT_DIR)/glue-java.xsl $<
+ $(QUIET)$(VBOX_FILESPLIT) $(VBOX_JXPCOM_GEN)/java/glue/merged.file $(VBOX_JXPCOM_GEN)/java/glue/
+ $(QUIET)echo $(VBOX_JXPCOM_GEN)/java/glue/*.java > $@
+
+#
+# Compile the all java code into a JAR file.
+#
+VBOX_JXPCOM_JSRC = $(VBOX_JXPCOM_SRC)/src/org/mozilla/xpcom
+VBOX_JXPCOM_JAR_SRC = \
+ $(VBOX_JXPCOM_JSRC)/IXPCOM.java \
+ $(VBOX_JXPCOM_JSRC)/Mozilla.java \
+ $(VBOX_JXPCOM_JSRC)/VersionComparator.java \
+ $(VBOX_JXPCOM_JSRC)/GREVersionRange.java \
+ $(VBOX_JXPCOM_JSRC)/IAppFileLocProvider.java \
+ $(VBOX_JXPCOM_JSRC)/ProfileLock.java \
+ $(VBOX_JXPCOM_JSRC)/IGRE.java \
+ $(VBOX_JXPCOM_JSRC)/IJavaXPCOMUtils.java \
+ $(VBOX_JXPCOM_JSRC)/XPCOMException.java \
+ $(VBOX_JXPCOM_JSRC)/IMozilla.java \
+ $(VBOX_JXPCOM_JSRC)/XPCOMInitializationException.java \
+ $(VBOX_JXPCOM_JSRC)/INIParser.java \
+ $(VBOX_JXPCOM_JSRC)/internal/GREImpl.java \
+ $(VBOX_JXPCOM_JSRC)/internal/JavaXPCOMMethods.java \
+ $(VBOX_JXPCOM_JSRC)/internal/MozillaImpl.java \
+ $(VBOX_JXPCOM_JSRC)/internal/XPCOMImpl.java \
+ $(VBOX_JXPCOM_JSRC)/internal/XPCOMJavaProxyBase.java \
+ $(VBOX_JXPCOM_JSRC)/internal/XPCOMJavaProxy.java
+
+$$(VBOX_JXPCOM_JAR): $(VBOX_JXPCOM_JAR_SRC) $(VBOX_JXPCOM_GEN)/jxpcomgen.list $(VBOX_JXPCOM_GEN)/jxpcomglue.list $(VBOX_JXPCOM_NSERROR) $(VBOX_JXPCOM_MGR) | $$(dir $$@)
+ $(call MSG_TOOL,javac,$(notdir $@),jxpcomgen.list,)
+ $(QUIET)$(RM) -Rf $(VBOX_JXPCOM_JDEST)
+ $(QUIET)$(MKDIR) -p $(VBOX_JXPCOM_JDEST)
+ $(QUIET)$(VBOX_JAVAC) $(VBOX_JAVAC_OPTS) @$(VBOX_JXPCOM_GEN)/jxpcomgen.list \
+ -d $(VBOX_JXPCOM_JDEST) -classpath $(VBOX_JXPCOM_JDEST)
+ $(call MSG_TOOL,javac,$(notdir $@),...,)
+ $(QUIET)$(VBOX_JAVAC) $(VBOX_JAVAC_OPTS) \
+ $(VBOX_JXPCOM_JAR_SRC) \
+ $(VBOX_JXPCOM_NSERROR) \
+ @$(VBOX_JXPCOM_GEN)/jxpcomglue.list \
+ -d $(VBOX_JXPCOM_JDEST) -classpath $(VBOX_JXPCOM_JDEST)
+ $(call MSG_LINK,$(notdir $@),$@)
+ $(QUIET)$(VBOX_JAR) cf $@ -C $(VBOX_JXPCOM_JDEST) .
+
+include $(FILE_KBUILD_SUB_FOOTER)
diff --git a/src/libs/xpcom18a4/java/README.vbox b/src/libs/xpcom18a4/java/README.vbox
new file mode 100644
index 00000000..b22acc4d
--- /dev/null
+++ b/src/libs/xpcom18a4/java/README.vbox
@@ -0,0 +1,5 @@
+ JavaXPCOM sources (see https://developer.mozilla.org/en/JavaXPCOM) were taken from
+:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot, directory extensions/java/xpcom,
+Apr 29 2010.
+
+ Imported to VirtualBox codebase in revision .
diff --git a/src/libs/xpcom18a4/java/src/MacJawt.mm b/src/libs/xpcom18a4/java/src/MacJawt.mm
new file mode 100644
index 00000000..a2d0d3f8
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/MacJawt.mm
@@ -0,0 +1,47 @@
+/* ***** 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) 2006
+ * 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 ***** */
+
+#include <jni.h>
+#import <JavaVM/jawt_md.h>
+#include "prtypes.h"
+
+
+PRUint64 GetPlatformHandle(JAWT_DrawingSurfaceInfo* dsi)
+{
+ JAWT_MacOSXDrawingSurfaceInfo* dsi_mac =
+ static_cast<JAWT_MacOSXDrawingSurfaceInfo*> (dsi->platformInfo);
+ return reinterpret_cast<PRUint64> (dsi_mac->cocoaViewRef);
+}
diff --git a/src/libs/xpcom18a4/java/src/dlldeps-javaxpcom.cpp b/src/libs/xpcom18a4/java/src/dlldeps-javaxpcom.cpp
new file mode 100644
index 00000000..a78d6c1d
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/dlldeps-javaxpcom.cpp
@@ -0,0 +1,81 @@
+/* ***** 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) 2006
+ * 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 ***** */
+
+#include "nsJavaInterfaces.h"
+
+
+void XXXNeverCalled_javaxpcom()
+{
+ MOZILLA_NATIVE(initialize) (nsnull, nsnull);
+
+ GRE_NATIVE(initEmbedding) (nsnull, nsnull, nsnull, nsnull, nsnull);
+
+ GRE_NATIVE(termEmbedding) (nsnull, nsnull);
+
+ GRE_NATIVE(lockProfileDirectory) (nsnull, nsnull, nsnull);
+
+ GRE_NATIVE(notifyProfile) (nsnull, nsnull);
+
+ GRE_NATIVE(lockProfileDirectory) (nsnull, nsnull, nsnull);
+
+ GRE_NATIVE(notifyProfile) (nsnull, nsnull);
+
+ XPCOM_NATIVE(initXPCOM) (nsnull, nsnull, nsnull, nsnull);
+
+ XPCOM_NATIVE(shutdownXPCOM) (nsnull, nsnull, nsnull);
+
+ XPCOM_NATIVE(newLocalFile) (nsnull, nsnull, nsnull, nsnull);
+
+ XPCOM_NATIVE(getComponentManager) (nsnull, nsnull);
+
+ XPCOM_NATIVE(getComponentRegistrar) (nsnull, nsnull);
+
+ XPCOM_NATIVE(getServiceManager) (nsnull, nsnull);
+
+ JAVAPROXY_NATIVE(callXPCOMMethod) (nsnull, nsnull, nsnull, nsnull, nsnull);
+
+ JAVAPROXY_NATIVE(finalizeProxy) (nsnull, nsnull, nsnull);
+
+ JAVAPROXY_NATIVE(isSameXPCOMObject) (nsnull, nsnull, nsnull, nsnull);
+
+ 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/src/libs/xpcom18a4/java/src/nsAppFileLocProviderProxy.cpp b/src/libs/xpcom18a4/java/src/nsAppFileLocProviderProxy.cpp
new file mode 100644
index 00000000..c10bf4c1
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsAppFileLocProviderProxy.cpp
@@ -0,0 +1,253 @@
+/* ***** 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) 2005
+ * 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 ***** */
+
+#include "nsAppFileLocProviderProxy.h"
+#include "nsJavaXPCOMBindingUtils.h"
+#include "nsILocalFile.h"
+#include "nsISimpleEnumerator.h"
+
+
+nsAppFileLocProviderProxy::nsAppFileLocProviderProxy(jobject aJavaObject)
+{
+ mJavaLocProvider = GetJNIEnv()->NewGlobalRef(aJavaObject);
+}
+
+nsAppFileLocProviderProxy::~nsAppFileLocProviderProxy()
+{
+ GetJNIEnv()->DeleteGlobalRef(mJavaLocProvider);
+}
+
+NS_IMPL_ISUPPORTS2(nsAppFileLocProviderProxy,
+ nsIDirectoryServiceProvider,
+ nsIDirectoryServiceProvider2)
+
+
+// nsIDirectoryServiceProvider
+
+NS_IMETHODIMP
+nsAppFileLocProviderProxy::GetFile(const char* aProp, PRBool* aIsPersistant,
+ nsIFile** aResult)
+{
+ // Setup params for calling Java function
+ JNIEnv* env = GetJNIEnv();
+ jstring prop = env->NewStringUTF(aProp);
+ if (!prop)
+ return NS_ERROR_OUT_OF_MEMORY;
+ jbooleanArray persistant = env->NewBooleanArray(1);
+ if (!persistant)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ // Create method ID
+ jmethodID mid = nsnull;
+ jclass clazz = env->GetObjectClass(mJavaLocProvider);
+ if (clazz) {
+ mid = env->GetMethodID(clazz, "getFile",
+ "(Ljava/lang/String;[Z)Ljava/io/File;");
+ }
+ if (!mid)
+ return NS_ERROR_FAILURE;
+
+ // Call Java function
+ jobject javaFile = nsnull;
+ javaFile = env->CallObjectMethod(mJavaLocProvider, mid, prop, persistant);
+ if (javaFile == nsnull || env->ExceptionCheck())
+ return NS_ERROR_FAILURE;
+
+ // Set boolean output value
+ env->GetBooleanArrayRegion(persistant, 0, 1, (jboolean*) aIsPersistant);
+
+ // Set nsIFile result value
+ nsCOMPtr<nsILocalFile> localFile;
+ nsresult rv = File_to_nsILocalFile(env, javaFile, getter_AddRefs(localFile));
+ if (NS_SUCCEEDED(rv)) {
+ return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)aResult);
+ }
+
+ return rv;
+}
+
+
+// nsIDirectoryServiceProvider2
+
+class DirectoryEnumerator : public nsISimpleEnumerator
+{
+public:
+ NS_DECL_ISUPPORTS
+
+ DirectoryEnumerator(jobjectArray aJavaFileArray)
+ : mIndex(0)
+ {
+ JNIEnv* env = GetJNIEnv();
+ mJavaFileArray = static_cast<jobjectArray>
+ (env->NewGlobalRef(aJavaFileArray));
+ mArraySize = env->GetArrayLength(aJavaFileArray);
+ }
+
+ ~DirectoryEnumerator()
+ {
+ GetJNIEnv()->DeleteGlobalRef(mJavaFileArray);
+ }
+
+ NS_IMETHOD HasMoreElements(PRBool* aResult)
+ {
+ if (!mJavaFileArray) {
+ *aResult = PR_FALSE;
+ } else {
+ *aResult = (mIndex < mArraySize);
+ }
+ return NS_OK;
+ }
+
+ NS_IMETHOD GetNext(nsISupports** aResult)
+ {
+ nsresult rv = NS_ERROR_FAILURE;
+
+ JNIEnv* env = GetJNIEnv();
+ jobject javaFile = env->GetObjectArrayElement(mJavaFileArray, mIndex++);
+ if (javaFile) {
+ nsCOMPtr<nsILocalFile> localFile;
+ rv = File_to_nsILocalFile(env, javaFile, getter_AddRefs(localFile));
+ env->DeleteLocalRef(javaFile);
+
+ if (NS_SUCCEEDED(rv)) {
+ return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)aResult);
+ }
+ }
+
+ env->ExceptionClear();
+ return NS_ERROR_FAILURE;
+ }
+
+private:
+ jobjectArray mJavaFileArray;
+ PRUint32 mArraySize;
+ PRUint32 mIndex;
+};
+
+NS_IMPL_ISUPPORTS1(DirectoryEnumerator, nsISimpleEnumerator)
+
+NS_IMETHODIMP
+nsAppFileLocProviderProxy::GetFiles(const char* aProp,
+ nsISimpleEnumerator** aResult)
+{
+ nsresult rv = NS_OK;
+
+ // Setup params for calling Java function
+ JNIEnv* env = GetJNIEnv();
+ jstring prop = env->NewStringUTF(aProp);
+ if (!prop)
+ rv = NS_ERROR_OUT_OF_MEMORY;
+
+ // Create method ID
+ jmethodID mid = nsnull;
+ if (NS_SUCCEEDED(rv)) {
+ jclass clazz = env->GetObjectClass(mJavaLocProvider);
+ if (clazz) {
+ mid = env->GetMethodID(clazz, "getFiles",
+ "(Ljava/lang/String;)[Ljava/io/File;");
+ env->DeleteLocalRef(clazz);
+ }
+ if (!mid)
+ rv = NS_ERROR_FAILURE;
+ }
+
+ // Call Java function
+ jobject javaFileArray = nsnull;
+ if (NS_SUCCEEDED(rv)) {
+ javaFileArray = env->CallObjectMethod(mJavaLocProvider, mid, prop);
+
+ // Handle any exception thrown by Java method.
+ jthrowable exp = env->ExceptionOccurred();
+ if (exp) {
+#ifdef DEBUG
+ env->ExceptionDescribe();
+#endif
+
+ // If the exception is an instance of XPCOMException, then get the
+ // nsresult from the exception instance. Else, default to
+ // NS_ERROR_FAILURE.
+ if (env->IsInstanceOf(exp, xpcomExceptionClass)) {
+ jfieldID fid;
+ fid = env->GetFieldID(xpcomExceptionClass, "errorcode", "J");
+ if (fid) {
+ rv = env->GetLongField(exp, fid);
+ } else {
+ rv = NS_ERROR_FAILURE;
+ }
+ NS_ASSERTION(fid, "Couldn't get 'errorcode' field of XPCOMException");
+ } else {
+ rv = NS_ERROR_FAILURE;
+ }
+ } else {
+ // No exception thrown. Check the result.
+ if (javaFileArray == nsnull) {
+ rv = NS_ERROR_FAILURE;
+ }
+ }
+ }
+
+ if (NS_SUCCEEDED(rv)) {
+ // Parse return value
+ *aResult = new DirectoryEnumerator(static_cast<jobjectArray>
+ (javaFileArray));
+ NS_ADDREF(*aResult);
+ return NS_OK;
+ }
+
+ // Handle error conditions
+ *aResult = nsnull;
+ env->ExceptionClear();
+ return rv;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+nsresult
+NS_NewAppFileLocProviderProxy(jobject aJavaLocProvider,
+ nsIDirectoryServiceProvider** aResult)
+{
+ nsAppFileLocProviderProxy* provider =
+ new nsAppFileLocProviderProxy(aJavaLocProvider);
+ if (provider == nsnull)
+ return NS_ERROR_OUT_OF_MEMORY;
+ NS_ADDREF(provider);
+
+ *aResult = provider;
+ return NS_OK;
+}
+
diff --git a/src/libs/xpcom18a4/java/src/nsAppFileLocProviderProxy.h b/src/libs/xpcom18a4/java/src/nsAppFileLocProviderProxy.h
new file mode 100644
index 00000000..d3b90880
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsAppFileLocProviderProxy.h
@@ -0,0 +1,65 @@
+/* ***** 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) 2005
+ * 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 ***** */
+
+#ifndef _nsAppFileLocProviderProxy_h_
+#define _nsAppFileLocProviderProxy_h_
+
+#include "nsIDirectoryService.h"
+#include "jni.h"
+
+
+class nsAppFileLocProviderProxy : public nsIDirectoryServiceProvider2
+{
+public:
+ nsAppFileLocProviderProxy(jobject aJavaLocProvider);
+ ~nsAppFileLocProviderProxy();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIDIRECTORYSERVICEPROVIDER
+ NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
+
+private:
+ jobject mJavaLocProvider;
+};
+
+extern "C" nsresult
+NS_NewAppFileLocProviderProxy(jobject aJavaLocProvider,
+ nsIDirectoryServiceProvider** aResult);
+
+
+#endif //_nsAppFileLocProviderProxy_h_
+
diff --git a/src/libs/xpcom18a4/java/src/nsFileStreams.cpp b/src/libs/xpcom18a4/java/src/nsFileStreams.cpp
new file mode 100644
index 00000000..435df58b
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsFileStreams.cpp
@@ -0,0 +1,475 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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 mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 ***** */
+
+#if defined(XP_UNIX) || defined(XP_BEOS)
+#include <unistd.h>
+#elif defined(XP_MAC)
+#include <Files.h>
+#elif defined(XP_WIN)
+#include <windows.h>
+#elif defined(XP_OS2)
+#define INCL_DOSERRORS
+#include <os2.h>
+#else
+// XXX add necessary include file for ftruncate (or equivalent)
+#endif
+
+#if defined(XP_MAC)
+#include "pprio.h"
+#else
+#include "private/pprio.h"
+#endif
+
+#include "nsFileStreams.h"
+#include "nsILocalFile.h"
+#include "nsXPIDLString.h"
+#include "prerror.h"
+#include "nsCRT.h"
+#include "nsInt64.h"
+#include "nsIFile.h"
+
+#define NS_NO_INPUT_BUFFERING 1 // see http://bugzilla.mozilla.org/show_bug.cgi?id=41067
+
+#if defined(PR_LOGGING)
+//
+// Log module for nsFileTransport logging...
+//
+// To enable logging (see prlog.h for full details):
+//
+// set NSPR_LOG_MODULES=nsFileIO:5
+// set NSPR_LOG_FILE=nspr.log
+//
+// this enables PR_LOG_DEBUG level information and places all output in
+// the file nspr.log
+//
+PRLogModuleInfo* gFileIOLog = nsnull;
+
+#endif /* PR_LOGGING */
+
+
+////////////////////////////////////////////////////////////////////////////////
+// nsFileStream
+
+nsFileStream::nsFileStream()
+ : mFD(nsnull)
+ , mCloseFD(PR_TRUE)
+{
+}
+
+nsFileStream::~nsFileStream()
+{
+ if (mCloseFD)
+ Close();
+}
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsFileStream, nsISeekableStream)
+
+nsresult
+nsFileStream::InitWithFileDescriptor(PRFileDesc* fd, nsISupports* parent)
+{
+ NS_ENSURE_TRUE(mFD == nsnull, NS_ERROR_ALREADY_INITIALIZED);
+ //
+ // this file stream is dependent on its parent to keep the
+ // file descriptor valid. an owning reference to the parent
+ // prevents the file descriptor from going away prematurely.
+ //
+ mFD = fd;
+ mCloseFD = PR_FALSE;
+ mParent = parent;
+ return NS_OK;
+}
+
+nsresult
+nsFileStream::Close()
+{
+ nsresult rv = NS_OK;
+ if (mFD) {
+ if (mCloseFD)
+ if (PR_Close(mFD) == PR_FAILURE)
+ rv = NS_BASE_STREAM_OSERROR;
+ mFD = nsnull;
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsFileStream::Seek(PRInt32 whence, PRInt64 offset)
+{
+ if (mFD == nsnull)
+ return NS_BASE_STREAM_CLOSED;
+
+ nsInt64 cnt = PR_Seek64(mFD, offset, (PRSeekWhence)whence);
+ if (cnt == nsInt64(-1)) {
+ return NS_ErrorAccordingToNSPR();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsFileStream::Tell(PRInt64 *result)
+{
+ if (mFD == nsnull)
+ return NS_BASE_STREAM_CLOSED;
+
+ nsInt64 cnt = PR_Seek64(mFD, 0, PR_SEEK_CUR);
+ if (cnt == nsInt64(-1)) {
+ return NS_ErrorAccordingToNSPR();
+ }
+ *result = cnt;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsFileStream::SetEOF()
+{
+ if (mFD == nsnull)
+ return NS_BASE_STREAM_CLOSED;
+
+#if defined(XP_UNIX) || defined(XP_MAC) || defined(XP_OS2) || defined(XP_BEOS)
+ // Some system calls require an EOF offset.
+ PRInt64 offset;
+ nsresult rv = Tell(&offset);
+ if (NS_FAILED(rv)) return rv;
+#endif
+
+#if defined(XP_UNIX) || defined(XP_BEOS)
+ if (ftruncate(PR_FileDesc2NativeHandle(mFD), offset) != 0) {
+ NS_ERROR("ftruncate failed");
+ return NS_ERROR_FAILURE;
+ }
+#elif defined(XP_MAC)
+ if (::SetEOF(PR_FileDesc2NativeHandle(mFD), offset) != 0) {
+ NS_ERROR("SetEOF failed");
+ return NS_ERROR_FAILURE;
+ }
+#elif defined(XP_WIN)
+ if (!SetEndOfFile((HANDLE) PR_FileDesc2NativeHandle(mFD))) {
+ NS_ERROR("SetEndOfFile failed");
+ return NS_ERROR_FAILURE;
+ }
+#elif defined(XP_OS2)
+ if (DosSetFileSize((HFILE) PR_FileDesc2NativeHandle(mFD), offset) != NO_ERROR) {
+ NS_ERROR("DosSetFileSize failed");
+ return NS_ERROR_FAILURE;
+ }
+#else
+ // XXX not implemented
+#endif
+
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsFileInputStream
+
+NS_IMPL_ISUPPORTS_INHERITED3(nsFileInputStream,
+ nsFileStream,
+ nsIInputStream,
+ nsIFileInputStream,
+ nsILineInputStream)
+
+NS_METHOD
+nsFileInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+ NS_ENSURE_NO_AGGREGATION(aOuter);
+
+ nsFileInputStream* stream = new nsFileInputStream();
+ if (stream == nsnull)
+ return NS_ERROR_OUT_OF_MEMORY;
+ NS_ADDREF(stream);
+ nsresult rv = stream->QueryInterface(aIID, aResult);
+ NS_RELEASE(stream);
+ return rv;
+}
+
+nsresult
+nsFileInputStream::Open(nsIFile* aFile, PRInt32 aIOFlags, PRInt32 aPerm)
+{
+ nsresult rv = NS_OK;
+
+ // If the previous file is open, close it
+ if (mFD) {
+ rv = Close();
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ // Open the file
+ nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(aFile, &rv);
+ if (NS_FAILED(rv)) return rv;
+ if (aIOFlags == -1)
+ aIOFlags = PR_RDONLY;
+ if (aPerm == -1)
+ aPerm = 0;
+
+ PRFileDesc* fd;
+ rv = localFile->OpenNSPRFileDesc(aIOFlags, aPerm, &fd);
+ if (NS_FAILED(rv)) return rv;
+
+ mFD = fd;
+
+ if (mBehaviorFlags & DELETE_ON_CLOSE) {
+ // POSIX compatible filesystems allow a file to be unlinked while a
+ // file descriptor is still referencing the file. since we've already
+ // opened the file descriptor, we'll try to remove the file. if that
+ // fails, then we'll just remember the nsIFile and remove it after we
+ // close the file descriptor.
+ rv = aFile->Remove(PR_FALSE);
+ if (NS_FAILED(rv) && !(mBehaviorFlags & REOPEN_ON_REWIND)) {
+ // If REOPEN_ON_REWIND is not happenin', we haven't saved the file yet
+ mFile = aFile;
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsFileInputStream::Init(nsIFile* aFile, PRInt32 aIOFlags, PRInt32 aPerm,
+ PRInt32 aBehaviorFlags)
+{
+ NS_ENSURE_TRUE(!mFD, NS_ERROR_ALREADY_INITIALIZED);
+ NS_ENSURE_TRUE(!mParent, NS_ERROR_ALREADY_INITIALIZED);
+
+ mBehaviorFlags = aBehaviorFlags;
+
+ // If the file will be reopened on rewind, save the info to open the file
+ if (mBehaviorFlags & REOPEN_ON_REWIND) {
+ mFile = aFile;
+ mIOFlags = aIOFlags;
+ mPerm = aPerm;
+ }
+
+ return Open(aFile, aIOFlags, aPerm);
+}
+
+NS_IMETHODIMP
+nsFileInputStream::Close()
+{
+ nsresult rv = nsFileStream::Close();
+ if (NS_FAILED(rv)) return rv;
+ if (mFile && (mBehaviorFlags & DELETE_ON_CLOSE)) {
+ rv = mFile->Remove(PR_FALSE);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "failed to delete file");
+ // If we don't need to save the file for reopening, free it up
+ if (!(mBehaviorFlags & REOPEN_ON_REWIND)) {
+ mFile = nsnull;
+ }
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsFileInputStream::Available(PRUint32* aResult)
+{
+ if (!mFD) {
+ return NS_BASE_STREAM_CLOSED;
+ }
+
+ PRInt32 avail = PR_Available(mFD);
+ if (avail == -1) {
+ return NS_ErrorAccordingToNSPR();
+ }
+ *aResult = avail;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsFileInputStream::Read(char* aBuf, PRUint32 aCount, PRUint32* aResult)
+{
+ if (!mFD) {
+ return NS_BASE_STREAM_CLOSED;
+ }
+
+ PRInt32 bytesRead = PR_Read(mFD, aBuf, aCount);
+ if (bytesRead == -1) {
+ return NS_ErrorAccordingToNSPR();
+ }
+ // Check if we're at the end of file and need to close
+ if (mBehaviorFlags & CLOSE_ON_EOF) {
+ if (bytesRead == 0) {
+ Close();
+ }
+ }
+
+ *aResult = bytesRead;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsFileInputStream::ReadLine(nsACString& aLine, PRBool* aResult)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsFileInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
+ PRUint32 aCount, PRUint32* aResult)
+{
+ // ReadSegments is not implemented because it would be inefficient when
+ // the writer does not consume all data. If you want to call ReadSegments,
+ // wrap a BufferedInputStream around the file stream. That will call
+ // Read().
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsFileInputStream::IsNonBlocking(PRBool *aNonBlocking)
+{
+ *aNonBlocking = PR_FALSE;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsFileInputStream::Seek(PRInt32 aWhence, PRInt64 aOffset)
+{
+ if (!mFD) {
+ if (mBehaviorFlags & REOPEN_ON_REWIND) {
+ nsresult rv = Reopen();
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ } else {
+ return NS_BASE_STREAM_CLOSED;
+ }
+ }
+
+ return nsFileStream::Seek(aWhence, aOffset);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsFileOutputStream
+
+NS_IMPL_ISUPPORTS_INHERITED2(nsFileOutputStream,
+ nsFileStream,
+ nsIOutputStream,
+ nsIFileOutputStream)
+
+NS_METHOD
+nsFileOutputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+ NS_ENSURE_NO_AGGREGATION(aOuter);
+
+ nsFileOutputStream* stream = new nsFileOutputStream();
+ if (stream == nsnull)
+ return NS_ERROR_OUT_OF_MEMORY;
+ NS_ADDREF(stream);
+ nsresult rv = stream->QueryInterface(aIID, aResult);
+ NS_RELEASE(stream);
+ return rv;
+}
+
+NS_IMETHODIMP
+nsFileOutputStream::Init(nsIFile* file, PRInt32 ioFlags, PRInt32 perm,
+ PRInt32 behaviorFlags)
+{
+ NS_ENSURE_TRUE(mFD == nsnull, NS_ERROR_ALREADY_INITIALIZED);
+
+ nsresult rv;
+ nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file, &rv);
+ if (NS_FAILED(rv)) return rv;
+ if (ioFlags == -1)
+ ioFlags = PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE;
+ if (perm <= 0)
+ perm = 0664;
+
+ PRFileDesc* fd;
+ rv = localFile->OpenNSPRFileDesc(ioFlags, perm, &fd);
+ if (NS_FAILED(rv)) return rv;
+
+ mFD = fd;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsFileOutputStream::Close()
+{
+ return nsFileStream::Close();
+}
+
+NS_IMETHODIMP
+nsFileOutputStream::Write(const char *buf, PRUint32 count, PRUint32 *result)
+{
+ if (mFD == nsnull)
+ return NS_BASE_STREAM_CLOSED;
+
+ PRInt32 cnt = PR_Write(mFD, buf, count);
+ if (cnt == -1) {
+ return NS_ErrorAccordingToNSPR();
+ }
+ *result = cnt;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsFileOutputStream::Flush(void)
+{
+ if (mFD == nsnull)
+ return NS_BASE_STREAM_CLOSED;
+
+ PRInt32 cnt = PR_Sync(mFD);
+ if (cnt == -1) {
+ return NS_ErrorAccordingToNSPR();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsFileOutputStream::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval)
+{
+ NS_NOTREACHED("WriteFrom (see source comment)");
+ return NS_ERROR_NOT_IMPLEMENTED;
+ // File streams intentionally do not support this method.
+ // If you need something like this, then you should wrap
+ // the file stream using nsIBufferedOutputStream
+}
+
+NS_IMETHODIMP
+nsFileOutputStream::WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval)
+{
+ NS_NOTREACHED("WriteSegments (see source comment)");
+ return NS_ERROR_NOT_IMPLEMENTED;
+ // File streams intentionally do not support this method.
+ // If you need something like this, then you should wrap
+ // the file stream using nsIBufferedOutputStream
+}
+
+NS_IMETHODIMP
+nsFileOutputStream::IsNonBlocking(PRBool *aNonBlocking)
+{
+ *aNonBlocking = PR_FALSE;
+ return NS_OK;
+}
diff --git a/src/libs/xpcom18a4/java/src/nsFileStreams.h b/src/libs/xpcom18a4/java/src/nsFileStreams.h
new file mode 100644
index 00000000..7d713fc5
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsFileStreams.h
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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 mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 ***** */
+
+#ifndef nsFileStreams_h__
+#define nsFileStreams_h__
+
+#include "nsIFileStreams.h"
+#include "nsIFile.h"
+#include "nsIInputStream.h"
+#include "nsIOutputStream.h"
+#include "nsISeekableStream.h"
+#include "nsILineInputStream.h"
+#include "nsCOMPtr.h"
+#include "prlog.h"
+#include "prio.h"
+
+template<class CharType> class nsLineBuffer;
+
+////////////////////////////////////////////////////////////////////////////////
+
+class nsFileStream : public nsISeekableStream
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSISEEKABLESTREAM
+
+ nsFileStream();
+ virtual ~nsFileStream();
+
+ nsresult Close();
+ nsresult InitWithFileDescriptor(PRFileDesc* fd, nsISupports* parent);
+
+protected:
+ PRFileDesc* mFD;
+ nsCOMPtr<nsISupports> mParent; // strong reference to parent nsFileIO,
+ // which ensures mFD remains valid.
+ PRBool mCloseFD;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class nsFileInputStream : public nsFileStream,
+ public nsIFileInputStream,
+ public nsILineInputStream
+{
+public:
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_NSIINPUTSTREAM
+ NS_DECL_NSIFILEINPUTSTREAM
+ NS_DECL_NSILINEINPUTSTREAM
+
+ // Overrided from nsFileStream
+ NS_IMETHOD Seek(PRInt32 aWhence, PRInt64 aOffset);
+
+ nsFileInputStream() : nsFileStream()
+ {
+ mBehaviorFlags = 0;
+ }
+ virtual ~nsFileInputStream()
+ {
+ Close();
+ }
+
+ static NS_METHOD
+ Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+
+protected:
+ /**
+ * The file being opened. Only stored when DELETE_ON_CLOSE or
+ * REOPEN_ON_REWIND are true.
+ */
+ nsCOMPtr<nsIFile> mFile;
+ /**
+ * The IO flags passed to Init() for the file open.
+ * Only set for REOPEN_ON_REWIND.
+ */
+ PRInt32 mIOFlags;
+ /**
+ * The permissions passed to Init() for the file open.
+ * Only set for REOPEN_ON_REWIND.
+ */
+ PRInt32 mPerm;
+ /**
+ * Flags describing our behavior. See the IDL file for possible values.
+ */
+ PRInt32 mBehaviorFlags;
+
+protected:
+ /**
+ * Internal, called to open a file. Parameters are the same as their
+ * Init() analogues.
+ */
+ nsresult Open(nsIFile* file, PRInt32 ioFlags, PRInt32 perm);
+ /**
+ * Reopen the file (for OPEN_ON_READ only!)
+ */
+ nsresult Reopen() { return Open(mFile, mIOFlags, mPerm); }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class nsFileOutputStream : public nsFileStream,
+ public nsIFileOutputStream
+{
+public:
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_NSIOUTPUTSTREAM
+ NS_DECL_NSIFILEOUTPUTSTREAM
+
+ nsFileOutputStream() : nsFileStream() {}
+ virtual ~nsFileOutputStream() { nsFileOutputStream::Close(); }
+
+ static NS_METHOD
+ Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+#endif // nsFileStreams_h__
diff --git a/src/libs/xpcom18a4/java/src/nsIFileStreams.h b/src/libs/xpcom18a4/java/src/nsIFileStreams.h
new file mode 100644
index 00000000..3df02b55
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsIFileStreams.h
@@ -0,0 +1,209 @@
+/*
+ * DO NOT EDIT. THIS FILE IS GENERATED FROM nsIFileStreams.idl
+ */
+
+#ifndef __gen_nsIFileStreams_h__
+#define __gen_nsIFileStreams_h__
+
+
+#ifndef __gen_nsIInputStream_h__
+#include "nsIInputStream.h"
+#endif
+
+#ifndef __gen_nsIOutputStream_h__
+#include "nsIOutputStream.h"
+#endif
+
+/* For IDL files that don't want to include root IDL files. */
+#ifndef NS_NO_VTABLE
+#define NS_NO_VTABLE
+#endif
+class nsIFile; /* forward declaration */
+
+
+/* starting interface: nsIFileInputStream */
+#define NS_IFILEINPUTSTREAM_IID_STR "e3d56a20-c7ec-11d3-8cda-0060b0fc14a3"
+
+#define NS_IFILEINPUTSTREAM_IID \
+ {0xe3d56a20, 0xc7ec, 0x11d3, \
+ { 0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3 }}
+
+/**
+ * An input stream that allows you to read from a file.
+ */
+class NS_NO_VTABLE nsIFileInputStream : public nsIInputStream {
+ public:
+
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFILEINPUTSTREAM_IID)
+
+ /**
+ * @param file file to read from (must QI to nsILocalFile)
+ * @param ioFlags file open flags listed in prio.h
+ * @param perm file mode bits listed in prio.h
+ * @param behaviorFlags flags specifying various behaviors of the class
+ * (see enumerations in the class)
+ */
+ /* void init (in nsIFile file, in long ioFlags, in long perm, in long behaviorFlags); */
+ NS_IMETHOD Init(nsIFile *file, PRInt32 ioFlags, PRInt32 perm, PRInt32 behaviorFlags) = 0;
+
+ /**
+ * If this is set, the file will be deleted by the time the stream is
+ * closed. It may be removed before the stream is closed if it is possible
+ * to delete it and still read from it.
+ *
+ * If OPEN_ON_READ is defined, and the file was recreated after the first
+ * delete, the file will be deleted again when it is closed again.
+ */
+ enum { DELETE_ON_CLOSE = 2 };
+
+ /**
+ * If this is set, the file will close automatically when the end of the
+ * file is reached.
+ */
+ enum { CLOSE_ON_EOF = 4 };
+
+ /**
+ * If this is set, the file will be reopened whenever Seek(0) occurs. If
+ * the file is already open and the seek occurs, it will happen naturally.
+ * (The file will only be reopened if it is closed for some reason.)
+ */
+ enum { REOPEN_ON_REWIND = 8 };
+
+};
+
+/* Use this macro when declaring classes that implement this interface. */
+#define NS_DECL_NSIFILEINPUTSTREAM \
+ NS_IMETHOD Init(nsIFile *file, PRInt32 ioFlags, PRInt32 perm, PRInt32 behaviorFlags); \
+
+/* Use this macro to declare functions that forward the behavior of this interface to another object. */
+#define NS_FORWARD_NSIFILEINPUTSTREAM(_to) \
+ NS_IMETHOD Init(nsIFile *file, PRInt32 ioFlags, PRInt32 perm, PRInt32 behaviorFlags) { return _to Init(file, ioFlags, perm, behaviorFlags); } \
+
+/* Use this macro to declare functions that forward the behavior of this interface to another object in a safe way. */
+#define NS_FORWARD_SAFE_NSIFILEINPUTSTREAM(_to) \
+ NS_IMETHOD Init(nsIFile *file, PRInt32 ioFlags, PRInt32 perm, PRInt32 behaviorFlags) { return !_to ? NS_ERROR_NULL_POINTER : _to->Init(file, ioFlags, perm, behaviorFlags); } \
+
+#if 0
+/* Use the code below as a template for the implementation class for this interface. */
+
+/* Header file */
+class nsFileInputStream : public nsIFileInputStream
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIFILEINPUTSTREAM
+
+ nsFileInputStream();
+
+private:
+ ~nsFileInputStream();
+
+protected:
+ /* additional members */
+};
+
+/* Implementation file */
+NS_IMPL_ISUPPORTS1(nsFileInputStream, nsIFileInputStream)
+
+nsFileInputStream::nsFileInputStream()
+{
+ /* member initializers and constructor code */
+}
+
+nsFileInputStream::~nsFileInputStream()
+{
+ /* destructor code */
+}
+
+/* void init (in nsIFile file, in long ioFlags, in long perm, in long behaviorFlags); */
+NS_IMETHODIMP nsFileInputStream::Init(nsIFile *file, PRInt32 ioFlags, PRInt32 perm, PRInt32 behaviorFlags)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* End of implementation class template. */
+#endif
+
+
+/* starting interface: nsIFileOutputStream */
+#define NS_IFILEOUTPUTSTREAM_IID_STR "e6f68040-c7ec-11d3-8cda-0060b0fc14a3"
+
+#define NS_IFILEOUTPUTSTREAM_IID \
+ {0xe6f68040, 0xc7ec, 0x11d3, \
+ { 0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3 }}
+
+/**
+ * An output stream that lets you stream to a file.
+ */
+class NS_NO_VTABLE nsIFileOutputStream : public nsIOutputStream {
+ public:
+
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFILEOUTPUTSTREAM_IID)
+
+ /**
+ * @param file - file to write to (must QI to nsILocalFile)
+ * @param ioFlags - file open flags listed in prio.h
+ * @param perm - file mode bits listed in prio.h
+ * @param behaviorFlags flags specifying various behaviors of the class
+ * (currently none supported)
+ */
+ /* void init (in nsIFile file, in long ioFlags, in long perm, in long behaviorFlags); */
+ NS_IMETHOD Init(nsIFile *file, PRInt32 ioFlags, PRInt32 perm, PRInt32 behaviorFlags) = 0;
+
+};
+
+/* Use this macro when declaring classes that implement this interface. */
+#define NS_DECL_NSIFILEOUTPUTSTREAM \
+ NS_IMETHOD Init(nsIFile *file, PRInt32 ioFlags, PRInt32 perm, PRInt32 behaviorFlags);
+
+/* Use this macro to declare functions that forward the behavior of this interface to another object. */
+#define NS_FORWARD_NSIFILEOUTPUTSTREAM(_to) \
+ NS_IMETHOD Init(nsIFile *file, PRInt32 ioFlags, PRInt32 perm, PRInt32 behaviorFlags) { return _to Init(file, ioFlags, perm, behaviorFlags); }
+
+/* Use this macro to declare functions that forward the behavior of this interface to another object in a safe way. */
+#define NS_FORWARD_SAFE_NSIFILEOUTPUTSTREAM(_to) \
+ NS_IMETHOD Init(nsIFile *file, PRInt32 ioFlags, PRInt32 perm, PRInt32 behaviorFlags) { return !_to ? NS_ERROR_NULL_POINTER : _to->Init(file, ioFlags, perm, behaviorFlags); }
+
+#if 0
+/* Use the code below as a template for the implementation class for this interface. */
+
+/* Header file */
+class nsFileOutputStream : public nsIFileOutputStream
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIFILEOUTPUTSTREAM
+
+ nsFileOutputStream();
+
+private:
+ ~nsFileOutputStream();
+
+protected:
+ /* additional members */
+};
+
+/* Implementation file */
+NS_IMPL_ISUPPORTS1(nsFileOutputStream, nsIFileOutputStream)
+
+nsFileOutputStream::nsFileOutputStream()
+{
+ /* member initializers and constructor code */
+}
+
+nsFileOutputStream::~nsFileOutputStream()
+{
+ /* destructor code */
+}
+
+/* void init (in nsIFile file, in long ioFlags, in long perm, in long behaviorFlags); */
+NS_IMETHODIMP nsFileOutputStream::Init(nsIFile *file, PRInt32 ioFlags, PRInt32 perm, PRInt32 behaviorFlags)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* End of implementation class template. */
+#endif
+
+
+#endif /* __gen_nsIFileStreams_h__ */
diff --git a/src/libs/xpcom18a4/java/src/nsJavaInterfaces.cpp b/src/libs/xpcom18a4/java/src/nsJavaInterfaces.cpp
new file mode 100644
index 00000000..103f2f37
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsJavaInterfaces.cpp
@@ -0,0 +1,557 @@
+/* ***** 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 ***** */
+
+#include "nsJavaInterfaces.h"
+#include "nsJavaWrapper.h"
+#include "nsJavaXPCOMBindingUtils.h"
+#include "nsJavaXPTCStub.h"
+#include "nsIComponentRegistrar.h"
+#include "nsString.h"
+#include "nsISimpleEnumerator.h"
+#include "nsIInterfaceInfoManager.h"
+#include "nsIInputStream.h"
+#include "nsEnumeratorUtils.h"
+#include "nsAppFileLocProviderProxy.h"
+#ifndef VBOX
+#include "nsXULAppAPI.h"
+#endif
+#include "nsILocalFile.h"
+
+#ifdef XP_MACOSX
+#include "jawt.h"
+#endif
+
+
+#ifdef VBOX
+#if 0
+#include "org_mozilla_xpcom_internal_GREImpl.h"
+#include "org_mozilla_xpcom_internal_JavaXPCOMMethods.h"
+#include "org_mozilla_xpcom_internal_MozillaImpl.h"
+#include "org_mozilla_xpcom_internal_XPCOMImpl.h"
+#include "org_mozilla_xpcom_internal_XPCOMJavaProxy.h"
+#include "org_mozilla_xpcom_ProfileLock.h"
+#endif
+#include <VBox/com/com.h>
+using namespace com;
+#include <iprt/initterm.h>
+#include <iprt/string.h>
+#include <alloca.h>
+#endif
+
+extern "C" NS_EXPORT void JNICALL
+MOZILLA_NATIVE(initialize) (JNIEnv* env, jobject)
+{
+ if (!InitializeJavaGlobals(env)) {
+ jclass clazz =
+ env->FindClass("org/mozilla/xpcom/XPCOMInitializationException");
+ if (clazz) {
+ env->ThrowNew(clazz, "Failed to initialize JavaXPCOM");
+ }
+ }
+}
+
+nsresult
+InitEmbedding_Impl(JNIEnv* env, jobject aLibXULDirectory,
+ jobject aAppDirectory, jobject aAppDirProvider)
+{
+ nsresult rv;
+
+ // create an nsILocalFile from given java.io.File
+ nsCOMPtr<nsILocalFile> libXULDir;
+ if (aLibXULDirectory) {
+ rv = File_to_nsILocalFile(env, aLibXULDirectory, getter_AddRefs(libXULDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ nsCOMPtr<nsILocalFile> appDir;
+ if (aAppDirectory) {
+ rv = File_to_nsILocalFile(env, aAppDirectory, getter_AddRefs(appDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // create nsAppFileLocProviderProxy from given Java object
+ nsCOMPtr<nsIDirectoryServiceProvider> provider;
+ if (aAppDirProvider) {
+ rv = NS_NewAppFileLocProviderProxy(aAppDirProvider,
+ getter_AddRefs(provider));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // init libXUL
+#ifdef VBOX
+ return 0;
+#else
+ return XRE_InitEmbedding(libXULDir, appDir, provider, nsnull, 0);
+#endif
+}
+
+extern "C" NS_EXPORT void JNICALL
+GRE_NATIVE(initEmbedding) (JNIEnv* env, jobject, jobject aLibXULDirectory,
+ jobject aAppDirectory, jobject aAppDirProvider)
+{
+ nsresult rv = InitEmbedding_Impl(env, aLibXULDirectory, aAppDirectory,
+ aAppDirProvider);
+
+ if (NS_FAILED(rv)) {
+ ThrowException(env, rv, "Failure in initEmbedding");
+ FreeJavaGlobals(env);
+ }
+}
+
+extern "C" NS_EXPORT void JNICALL
+GRE_NATIVE(termEmbedding) (JNIEnv *env, jobject)
+{
+ // Free globals before calling XRE_TermEmbedding(), since we need some
+ // XPCOM services.
+ FreeJavaGlobals(env);
+
+#ifndef VBOX
+ XRE_TermEmbedding();
+#endif
+}
+#ifdef VBOX
+nsresult
+InitXPCOMVBox_Impl(JNIEnv* env, jobject aVBoxBinDirectory)
+{
+#if defined(VBOX_PATH_APP_PRIVATE_ARCH) && defined(VBOX_PATH_SHARED_LIBS)
+ rv = RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
+#else
+ const char *pszHome = nsnull;
+ const char *jhome = nsnull;
+ jstring path = nsnull;
+
+ int rv;
+ jclass clazz;
+ jmethodID getPathMID;
+
+ if (aVBoxBinDirectory &&
+ (clazz = env->FindClass("java/io/File")) &&
+ (getPathMID = env->GetMethodID(clazz, "getAbsolutePath",
+ "()Ljava/lang/String;"))
+ )
+ {
+ path = (jstring)env->CallObjectMethod(aVBoxBinDirectory, getPathMID);
+ pszHome = jhome = env->GetStringUTFChars(path, nsnull);
+ }
+
+ if (pszHome == nsnull)
+ pszHome = getenv("VBOX_PROGRAM_PATH");
+
+ if (pszHome) {
+ size_t cchHome = strlen(pszHome);
+ char *pszExePath = (char *)alloca(cchHome + 32);
+ memcpy(pszExePath, pszHome, cchHome);
+ memcpy(pszExePath + cchHome, "/javafake", sizeof("/javafake"));
+ rv = RTR3InitEx(RTR3INIT_VER_CUR, RTR3INIT_FLAGS_DLL | RTR3INIT_FLAGS_UNOBTRUSIVE, 0, NULL, pszExePath);
+ } else {
+ rv = RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
+ }
+
+ if (jhome)
+ env->ReleaseStringUTFChars(path, jhome);
+#endif
+
+ return com::Initialize();
+}
+#endif
+
+nsresult
+InitXPCOM_Impl(JNIEnv* env, jobject aMozBinDirectory,
+ jobject aAppFileLocProvider, jobject* aResult)
+{
+ nsresult rv;
+ // 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
+ nsCOMPtr<nsIDirectoryServiceProvider> provider;
+ if (aAppFileLocProvider) {
+ rv = NS_NewAppFileLocProviderProxy(aAppFileLocProvider,
+ getter_AddRefs(provider));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // init XPCOM
+ nsCOMPtr<nsIServiceManager> servMan;
+ rv = NS_InitXPCOM2(getter_AddRefs(servMan), directory, provider);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // create Java proxy for service manager returned by NS_InitXPCOM2
+ return NativeInterfaceToJavaObject(env, servMan, NS_GET_IID(nsIServiceManager),
+ nsnull, aResult);
+}
+
+extern "C" NS_EXPORT jobject JNICALL
+XPCOM_NATIVE(initXPCOM) (JNIEnv* env, jobject, jobject aMozBinDirectory,
+ jobject aAppFileLocProvider)
+{
+#ifdef VBOX
+ nsresult rv = InitXPCOMVBox_Impl(env, aMozBinDirectory);
+ if (NS_SUCCEEDED(rv))
+ return nsnull;
+#else
+ jobject servMan;
+ nsresult rv = InitXPCOM_Impl(env, aMozBinDirectory, aAppFileLocProvider,
+ &servMan);
+ if (NS_SUCCEEDED(rv))
+ return servMan;
+#endif
+
+ ThrowException(env, rv, "Failure in initXPCOM");
+ FreeJavaGlobals(env);
+ return nsnull;
+}
+
+extern "C" NS_EXPORT void JNICALL
+#ifdef VBOX
+XPCOM_NATIVE2(shutdownXPCOM) (JNIEnv *env, jobject, jobject aServMgr)
+#else
+XPCOM_NATIVE(shutdownXPCOM) (JNIEnv *env, jobject, jobject aServMgr)
+#endif
+{
+#ifdef VBOX
+ // Free globals before calling NS_ShutdownXPCOM(), since we need some
+ // XPCOM services.
+ //FreeJavaGlobals(env);
+ //com::Shutdown();
+#else
+ nsresult rv;
+ nsIServiceManager* servMgr = nsnull;
+ if (aServMgr) {
+ // Get native XPCOM instance
+ nsISupports* instancePtr = nsnull;
+ rv = JavaObjectToNativeInterface(env, aServMgr,
+ NS_GET_IID(nsIServiceManager), (void**) &instancePtr);
+ NS_ASSERTION(NS_SUCCEEDED(rv) && instancePtr != nsnull,
+ "Failed to get XPCOM obj for ServiceMgr.");
+ if (NS_SUCCEEDED(rv)) {
+ rv = instancePtr->QueryInterface(NS_GET_IID(nsIServiceManager),
+ (void**) &servMgr);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "QI for nsIServiceManager failed");
+ }
+
+ // 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.
+ }
+
+ // Free globals before calling NS_ShutdownXPCOM(), since we need some
+ // XPCOM services.
+ FreeJavaGlobals(env);
+
+ rv = NS_ShutdownXPCOM(servMgr);
+ if (NS_FAILED(rv))
+ ThrowException(env, rv, "NS_ShutdownXPCOM failed");
+#endif
+}
+
+extern "C" NS_EXPORT jobject JNICALL
+XPCOM_NATIVE(newLocalFile) (JNIEnv *env, jobject, jstring aPath,
+ jboolean aFollowLinks)
+{
+ // Create a Mozilla string from the jstring
+ const PRUnichar* buf = nsnull;
+ if (aPath) {
+ buf = env->GetStringChars(aPath, nsnull);
+ if (!buf)
+ return nsnull; // exception already thrown
+ }
+
+ nsAutoString path_str(buf);
+ env->ReleaseStringChars(aPath, buf);
+
+ // Make call to given function
+ nsCOMPtr<nsILocalFile> file;
+ nsresult rv = NS_NewLocalFile(path_str, aFollowLinks, getter_AddRefs(file));
+
+ if (NS_SUCCEEDED(rv)) {
+ jobject javaProxy;
+ rv = NativeInterfaceToJavaObject(env, file, NS_GET_IID(nsILocalFile),
+ nsnull, &javaProxy);
+ if (NS_SUCCEEDED(rv))
+ return javaProxy;
+ }
+
+ ThrowException(env, rv, "Failure in newLocalFile");
+ return nsnull;
+}
+
+extern "C" NS_EXPORT jobject JNICALL
+#ifdef VBOX
+XPCOM_NATIVE2(getComponentManager) (JNIEnv *env, jobject)
+#else
+XPCOM_NATIVE(getComponentManager) (JNIEnv *env, jobject)
+#endif
+{
+ // Call XPCOM method
+ nsCOMPtr<nsIComponentManager> cm;
+ nsresult rv = NS_GetComponentManager(getter_AddRefs(cm));
+
+ if (NS_SUCCEEDED(rv)) {
+ jobject javaProxy;
+ rv = NativeInterfaceToJavaObject(env, cm, NS_GET_IID(nsIComponentManager),
+ nsnull, &javaProxy);
+ if (NS_SUCCEEDED(rv))
+ return javaProxy;
+ }
+
+ ThrowException(env, rv, "Failure in getComponentManager");
+ return nsnull;
+}
+
+extern "C" NS_EXPORT jobject JNICALL
+XPCOM_NATIVE(getComponentRegistrar) (JNIEnv *env, jobject)
+{
+ // Call XPCOM method
+ nsCOMPtr<nsIComponentRegistrar> cr;
+ nsresult rv = NS_GetComponentRegistrar(getter_AddRefs(cr));
+
+ if (NS_SUCCEEDED(rv)) {
+ jobject javaProxy;
+ rv = NativeInterfaceToJavaObject(env, cr, NS_GET_IID(nsIComponentRegistrar),
+ nsnull, &javaProxy);
+ if (NS_SUCCEEDED(rv))
+ return javaProxy;
+ }
+
+ ThrowException(env, rv, "Failure in getComponentRegistrar");
+ return nsnull;
+}
+
+#ifdef VBOX
+# include <VBox/com/NativeEventQueue.h>
+# include <iprt/err.h>
+
+extern "C" NS_EXPORT jint JNICALL
+XPCOM_NATIVE2(waitForEvents) (JNIEnv *env, jobject, jlong aTimeout)
+{
+ com::NativeEventQueue* aEventQ = com::NativeEventQueue::getMainEventQueue();
+ NS_WARN_IF_FALSE(aEventQ != nsnull, "Null main event queue");
+ if (!aEventQ)
+ return -1;
+
+ int rc = aEventQ->processEventQueue(aTimeout < 0 ? RT_INDEFINITE_WAIT : (uint32_t)aTimeout);
+
+ if (RT_SUCCESS(rc))
+ return 0;
+
+ if ( rc == VERR_TIMEOUT
+ || rc == VERR_INTERRUPTED)
+ return 1;
+
+ return 2;
+}
+#endif
+
+extern "C" NS_EXPORT jobject JNICALL
+#ifdef VBOX
+XPCOM_NATIVE2(getServiceManager) (JNIEnv *env, jobject)
+#else
+XPCOM_NATIVE(getServiceManager) (JNIEnv *env, jobject)
+#endif
+{
+ // Call XPCOM method
+ nsCOMPtr<nsIServiceManager> sm;
+ nsresult rv = NS_GetServiceManager(getter_AddRefs(sm));
+
+ if (NS_SUCCEEDED(rv)) {
+ jobject javaProxy;
+ rv = NativeInterfaceToJavaObject(env, sm, NS_GET_IID(nsIServiceManager),
+ nsnull, &javaProxy);
+ if (NS_SUCCEEDED(rv))
+ return javaProxy;
+ }
+
+ ThrowException(env, rv, "Failure in getServiceManager");
+ return nsnull;
+}
+
+extern "C" NS_EXPORT jobject JNICALL
+GRE_NATIVE(lockProfileDirectory) (JNIEnv* env, jobject, jobject aDirectory)
+{
+ nsresult rv = NS_ERROR_FAILURE;
+
+ if (aDirectory) {
+ nsCOMPtr<nsILocalFile> profileDir;
+ rv = File_to_nsILocalFile(env, aDirectory, getter_AddRefs(profileDir));
+
+ if (NS_SUCCEEDED(rv)) {
+ nsISupports* lock;
+#ifdef VBOX
+ rv = 0;
+ lock = 0;
+#else
+ rv = XRE_LockProfileDirectory(profileDir, &lock);
+#endif
+
+ if (NS_SUCCEEDED(rv)) {
+ jclass clazz =
+ env->FindClass("org/mozilla/xpcom/ProfileLock");
+ if (clazz) {
+ jmethodID mid = env->GetMethodID(clazz, "<init>", "(J)V");
+ if (mid) {
+ return env->NewObject(clazz, mid, reinterpret_cast<jlong>(lock));
+ }
+ }
+
+ // if we get here, then something failed
+ rv = NS_ERROR_FAILURE;
+ }
+ }
+ }
+
+ ThrowException(env, rv, "Failure in lockProfileDirectory");
+ return nsnull;
+}
+
+extern "C" NS_EXPORT void JNICALL
+GRE_NATIVE(notifyProfile) (JNIEnv *env, jobject)
+{
+#ifndef VBOX
+ XRE_NotifyProfile();
+#endif
+}
+
+#ifdef XP_MACOSX
+extern PRUint64 GetPlatformHandle(JAWT_DrawingSurfaceInfo* dsi);
+#endif
+
+extern "C" NS_EXPORT jlong JNICALL
+MOZILLA_NATIVE(getNativeHandleFromAWT) (JNIEnv* env, jobject clazz,
+ jobject widget)
+{
+ PRUint64 handle = 0;
+
+#if defined(XP_MACOSX) && !defined(VBOX)
+ JAWT awt;
+ awt.version = JAWT_VERSION_1_4;
+ jboolean result = JAWT_GetAWT(env, &awt);
+ if (result == JNI_FALSE)
+ return 0;
+
+ JAWT_DrawingSurface* ds = awt.GetDrawingSurface(env, widget);
+ if (ds != nsnull) {
+ jint lock = ds->Lock(ds);
+ if (!(lock & JAWT_LOCK_ERROR)) {
+ JAWT_DrawingSurfaceInfo* dsi = ds->GetDrawingSurfaceInfo(ds);
+ if (dsi) {
+ handle = GetPlatformHandle(dsi);
+ ds->FreeDrawingSurfaceInfo(dsi);
+ }
+
+ ds->Unlock(ds);
+ }
+
+ awt.FreeDrawingSurface(ds);
+ }
+#else
+ NS_WARNING("getNativeHandleFromAWT JNI method not implemented");
+#endif
+
+ return handle;
+}
+
+extern "C" NS_EXPORT jlong JNICALL
+JXUTILS_NATIVE(wrapJavaObject) (JNIEnv* env, jobject, jobject aJavaObject,
+ jstring aIID)
+{
+ nsresult rv;
+ void* 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 = JavaObjectToNativeInterface(env, aJavaObject, iid, &xpcomObject);
+ if (NS_SUCCEEDED(rv)) {
+ nsISupports *xpcom_nat_obj = (nsISupports*) xpcomObject;
+ rv = xpcom_nat_obj->QueryInterface(iid, &xpcomObject);
+ NS_IF_RELEASE(xpcom_nat_obj);
+ }
+ } 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 reinterpret_cast<jlong>(xpcomObject);
+}
+
+extern "C" NS_EXPORT jobject JNICALL
+JXUTILS_NATIVE(wrapXPCOMObject) (JNIEnv* env, jobject, jlong aXPCOMObject,
+ jstring aIID)
+{
+ nsresult rv;
+ jobject javaObject = nsnull;
+ nsISupports* xpcomObject = 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 = NativeInterfaceToJavaObject(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/src/libs/xpcom18a4/java/src/nsJavaInterfaces.h b/src/libs/xpcom18a4/java/src/nsJavaInterfaces.h
new file mode 100644
index 00000000..69d2f680
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsJavaInterfaces.h
@@ -0,0 +1,121 @@
+/* ***** 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) 2006
+ * 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 ***** */
+
+#ifndef _nsJavaInterfaces_h_
+#define _nsJavaInterfaces_h_
+
+#include "jni.h"
+#include "nscore.h"
+
+#ifdef VBOX
+#define MOZILLA_NATIVE(func) Java_org_mozilla_xpcom_internal_MozillaImpl_##func##Native
+#define GRE_NATIVE(func) Java_org_mozilla_xpcom_internal_GREImpl_##func##Native
+#define XPCOM_NATIVE(func) Java_org_mozilla_xpcom_internal_XPCOMImpl_##func##Native
+#define XPCOM_NATIVE2(func) Java_org_mozilla_xpcom_internal_XPCOMImpl_##func
+#else
+#define MOZILLA_NATIVE(func) Java_org_mozilla_xpcom_internal_MozillaImpl_##func
+#define GRE_NATIVE(func) Java_org_mozilla_xpcom_internal_GREImpl_##func
+#define XPCOM_NATIVE(func) Java_org_mozilla_xpcom_internal_XPCOMImpl_##func
+#endif
+#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
+MOZILLA_NATIVE(initialize) (JNIEnv* env, jobject);
+
+extern "C" NS_EXPORT void JNICALL
+GRE_NATIVE(initEmbedding) (JNIEnv* env, jobject, jobject aLibXULDirectory,
+ jobject aAppDirectory, jobject aAppDirProvider);
+
+extern "C" NS_EXPORT void JNICALL
+GRE_NATIVE(termEmbedding) (JNIEnv *env, jobject);
+
+extern "C" NS_EXPORT jobject JNICALL
+GRE_NATIVE(lockProfileDirectory) (JNIEnv *, jobject, jobject aDirectory);
+
+extern "C" NS_EXPORT void JNICALL
+GRE_NATIVE(notifyProfile) (JNIEnv *env, jobject);
+
+extern "C" NS_EXPORT jobject JNICALL
+XPCOM_NATIVE(initXPCOM) (JNIEnv* env, jobject, jobject aMozBinDirectory,
+ jobject aAppFileLocProvider);
+
+extern "C" NS_EXPORT void JNICALL
+XPCOM_NATIVE(shutdownXPCOM) (JNIEnv *env, jobject, jobject aServMgr);
+
+extern "C" NS_EXPORT jobject JNICALL
+XPCOM_NATIVE(newLocalFile) (JNIEnv *env, jobject, jstring aPath,
+ jboolean aFollowLinks);
+
+extern "C" NS_EXPORT jobject JNICALL
+XPCOM_NATIVE(getComponentManager) (JNIEnv *env, jobject);
+
+extern "C" NS_EXPORT jobject JNICALL
+XPCOM_NATIVE(getComponentRegistrar) (JNIEnv *env, jobject);
+
+extern "C" NS_EXPORT jobject JNICALL
+XPCOM_NATIVE(getServiceManager) (JNIEnv *env, jobject);
+
+extern "C" NS_EXPORT jobject JNICALL
+JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
+ jstring aMethodName, jobjectArray aParams);
+
+extern "C" NS_EXPORT void JNICALL
+JAVAPROXY_NATIVE(finalizeProxy) (JNIEnv *env, jclass that, jobject aJavaProxy);
+
+extern "C" NS_EXPORT jboolean JNICALL
+JAVAPROXY_NATIVE(isSameXPCOMObject) (JNIEnv *env, jclass that, jobject aProxy1,
+ jobject aProxy2);
+
+extern "C" NS_EXPORT void JNICALL
+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/src/libs/xpcom18a4/java/src/nsJavaWrapper.cpp b/src/libs/xpcom18a4/java/src/nsJavaWrapper.cpp
new file mode 100644
index 00000000..a046c8a3
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsJavaWrapper.cpp
@@ -0,0 +1,2020 @@
+/* ***** 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) 2006
+ * 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 ***** */
+
+#include "nsJavaInterfaces.h"
+#include "nsJavaWrapper.h"
+#include "nsJavaXPTCStub.h"
+#include "nsJavaXPCOMBindingUtils.h"
+#include "jni.h"
+#include "xptcall.h"
+#include "nsIInterfaceInfoManager.h"
+#include "nsString.h"
+#include "nsCRT.h"
+#include "prmem.h"
+#include "nsServiceManagerUtils.h"
+#include "nsThreadUtils.h"
+#include "nsProxyRelease.h"
+
+static nsID nullID = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
+
+#ifdef VBOX
+#include "nsIThread.h"
+static nsresult
+NS_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
+ PRUint32 paramCount, nsXPTCVariant* params)
+{
+ return XPTC_InvokeByIndex(that, methodIndex, paramCount, params);
+}
+
+#endif
+
+nsresult
+CreateJavaArray(JNIEnv* env, PRUint8 aType, PRUint32 aSize, const nsID& aIID,
+ jobject* aResult)
+{
+ jobject array = nsnull;
+ switch (aType)
+ {
+ case nsXPTType::T_I8:
+ array = env->NewByteArray(aSize);
+ break;
+
+ case nsXPTType::T_I16:
+ case nsXPTType::T_U8:
+ array = env->NewShortArray(aSize);
+ break;
+
+ case nsXPTType::T_I32:
+ case nsXPTType::T_U16:
+ array = env->NewIntArray(aSize);
+ break;
+
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U32:
+ array = env->NewLongArray(aSize);
+ break;
+
+ case nsXPTType::T_FLOAT:
+ array = env->NewFloatArray(aSize);
+ break;
+
+ // XXX how do we handle unsigned 64-bit values?
+ case nsXPTType::T_U64:
+ case nsXPTType::T_DOUBLE:
+ array = env->NewDoubleArray(aSize);
+ break;
+
+ case nsXPTType::T_BOOL:
+ array = env->NewBooleanArray(aSize);
+ break;
+
+ case nsXPTType::T_CHAR:
+ case nsXPTType::T_WCHAR:
+ array = env->NewCharArray(aSize);
+ break;
+
+ case nsXPTType::T_CHAR_STR:
+ case nsXPTType::T_WCHAR_STR:
+ case nsXPTType::T_IID:
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING:
+ case nsXPTType::T_UTF8STRING:
+ case nsXPTType::T_CSTRING:
+ array = env->NewObjectArray(aSize, stringClass, nsnull);
+ break;
+
+ case nsXPTType::T_INTERFACE:
+ case nsXPTType::T_INTERFACE_IS:
+ {
+ nsCOMPtr<nsIInterfaceInfoManager>
+ iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
+ NS_ASSERTION(iim, "Failed to get InterfaceInfoManager");
+ if (!iim)
+ return NS_ERROR_FAILURE;
+
+ // Get interface info for given IID
+ nsCOMPtr<nsIInterfaceInfo> info;
+ nsresult rv = iim->GetInfoForIID(&aIID, getter_AddRefs(info));
+ if (NS_FAILED(rv))
+ return rv;
+
+ // Get interface name
+ const char* iface_name;
+ rv = info->GetNameShared(&iface_name);
+ if (NS_FAILED(rv))
+ return rv;
+
+ // Create proper Java interface name
+ nsCAutoString class_name("org/mozilla/interfaces/");
+ class_name.AppendASCII(iface_name);
+ jclass ifaceClass = env->FindClass(class_name.get());
+ if (!ifaceClass)
+ return NS_ERROR_FAILURE;
+
+ array = env->NewObjectArray(aSize, ifaceClass, nsnull);
+ break;
+ }
+
+ case nsXPTType::T_VOID:
+ array = env->NewLongArray(aSize);
+ break;
+
+ default:
+ NS_WARNING("unknown type");
+ return NS_ERROR_FAILURE;
+ }
+
+ if (!array)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ *aResult = array;
+ return NS_OK;
+}
+
+nsresult
+GetNativeArrayElement(PRUint8 aType, void* aArray, PRUint32 aIndex,
+ nsXPTCVariant* aResult)
+{
+ switch (aType)
+ {
+ case nsXPTType::T_I8:
+ case nsXPTType::T_U8:
+ aResult->val.u8 = static_cast<PRUint8*>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_I16:
+ case nsXPTType::T_U16:
+ aResult->val.u16 = static_cast<PRUint16*>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_I32:
+ case nsXPTType::T_U32:
+ aResult->val.u32 = static_cast<PRUint32*>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U64:
+ aResult->val.u64 = static_cast<PRUint64*>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_FLOAT:
+ aResult->val.f = static_cast<float*>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_DOUBLE:
+ aResult->val.d = static_cast<double*>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_BOOL:
+ aResult->val.b = static_cast<PRBool*>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_CHAR:
+ aResult->val.c = static_cast<char*>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_WCHAR:
+ aResult->val.wc = static_cast<PRUnichar*>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_CHAR_STR:
+ aResult->val.p = static_cast<char**>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_WCHAR_STR:
+ aResult->val.p = static_cast<PRUnichar**>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_IID:
+ aResult->val.p = static_cast<nsID**>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_INTERFACE:
+ case nsXPTType::T_INTERFACE_IS:
+ aResult->val.p = static_cast<nsISupports**>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING:
+ aResult->val.p = static_cast<nsString**>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_UTF8STRING:
+ case nsXPTType::T_CSTRING:
+ aResult->val.p = static_cast<nsCString**>(aArray)[aIndex];
+ break;
+
+ case nsXPTType::T_VOID:
+ aResult->val.p = static_cast<void**>(aArray)[aIndex];
+ break;
+
+ default:
+ NS_WARNING("unknown type");
+ return NS_ERROR_FAILURE;
+ }
+
+ return NS_OK;
+}
+
+nsresult
+CreateNativeArray(PRUint8 aType, PRUint32 aSize, void** aResult)
+{
+ void* array = nsnull;
+ switch (aType)
+ {
+ case nsXPTType::T_I8:
+ case nsXPTType::T_U8:
+ array = PR_Malloc(aSize * sizeof(PRUint8));
+ break;
+
+ case nsXPTType::T_I16:
+ case nsXPTType::T_U16:
+ array = PR_Malloc(aSize * sizeof(PRUint16));
+ break;
+
+ case nsXPTType::T_I32:
+ case nsXPTType::T_U32:
+ array = PR_Malloc(aSize * sizeof(PRUint32));
+ break;
+
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U64:
+ array = PR_Malloc(aSize * sizeof(PRUint64));
+ break;
+
+ case nsXPTType::T_FLOAT:
+ array = PR_Malloc(aSize * sizeof(float));
+ break;
+
+ case nsXPTType::T_DOUBLE:
+ array = PR_Malloc(aSize * sizeof(double));
+ break;
+
+ case nsXPTType::T_BOOL:
+ array = PR_Malloc(aSize * sizeof(PRBool));
+ break;
+
+ case nsXPTType::T_CHAR:
+ array = PR_Malloc(aSize * sizeof(char));
+ break;
+
+ case nsXPTType::T_WCHAR:
+ array = PR_Malloc(aSize * sizeof(PRUnichar));
+ break;
+
+ case nsXPTType::T_CHAR_STR:
+ case nsXPTType::T_WCHAR_STR:
+ case nsXPTType::T_IID:
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING:
+ case nsXPTType::T_UTF8STRING:
+ case nsXPTType::T_CSTRING:
+ case nsXPTType::T_INTERFACE:
+ case nsXPTType::T_INTERFACE_IS:
+ array = PR_Malloc(aSize * sizeof(void*));
+ break;
+
+ case nsXPTType::T_VOID:
+ array = PR_Malloc(aSize * sizeof(void*));
+ break;
+
+ default:
+ NS_WARNING("unknown type");
+ return NS_ERROR_FAILURE;
+ }
+
+ if (!array)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ *aResult = array;
+ return NS_OK;
+}
+
+/**
+ * Handle 'in' and 'inout' params.
+ */
+nsresult
+SetupParams(JNIEnv *env, const jobject aParam, PRUint8 aType, PRBool aIsOut,
+ const nsID& aIID, PRUint8 aArrayType, PRUint32 aArraySize,
+ PRBool aIsArrayElement, PRUint32 aIndex, nsXPTCVariant &aVariant)
+{
+ nsresult rv = NS_OK;
+
+ switch (aType)
+ {
+ case nsXPTType::T_I8:
+ {
+ LOG(("byte\n"));
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ aVariant.val.i8 = env->CallByteMethod(aParam, byteValueMID);
+ } else { // 'inout' & 'array'
+ jbyte value;
+ if (aParam) {
+ env->GetByteArrayRegion((jbyteArray) aParam, aIndex, 1, &value);
+ }
+
+ if (aIsOut) { // 'inout'
+ if (aParam) {
+ aVariant.val.i8 = value;
+ aVariant.ptr = &aVariant.val;
+ } else {
+ aVariant.ptr = nsnull;
+ }
+ aVariant.SetPtrIsData();
+ } else { // 'array'
+ static_cast<PRInt8*>(aVariant.val.p)[aIndex] = value;
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_I16:
+ case nsXPTType::T_U8: // C++ unsigned octet <=> Java short
+ {
+ LOG(("short\n"));
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ jshort value = env->CallShortMethod(aParam, shortValueMID);
+ if (aType == nsXPTType::T_I16)
+ aVariant.val.i16 = value;
+ else
+ aVariant.val.u8 = value;
+ } else { // 'inout' & 'array'
+ jshort value;
+ if (aParam) {
+ env->GetShortArrayRegion((jshortArray) aParam, aIndex, 1, &value);
+ }
+
+ if (aIsOut) { // 'inout'
+ if (aParam) {
+ if (aType == nsXPTType::T_I16)
+ aVariant.val.i16 = value;
+ else
+ aVariant.val.u8 = value;
+ aVariant.ptr = &aVariant.val;
+ } else {
+ aVariant.ptr = nsnull;
+ }
+ aVariant.SetPtrIsData();
+ } else { // 'array'
+ if (aType == nsXPTType::T_I16)
+ static_cast<PRInt16*>(aVariant.val.p)[aIndex] = value;
+ else
+ static_cast<PRUint8*>(aVariant.val.p)[aIndex] = value;
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_I32:
+ case nsXPTType::T_U16: // C++ unsigned short <=> Java int
+ {
+ LOG(("int\n"));
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ jint value = env->CallIntMethod(aParam, intValueMID);
+ if (aType == nsXPTType::T_I32)
+ aVariant.val.i32 = value;
+ else
+ aVariant.val.u16 = value;
+ } else { // 'inout' & 'array'
+ jint value;
+ if (aParam) {
+ env->GetIntArrayRegion((jintArray) aParam, aIndex, 1, &value);
+ }
+
+ if (aIsOut) { // 'inout'
+ if (aParam) {
+ if (aType == nsXPTType::T_I32)
+ aVariant.val.i32 = value;
+ else
+ aVariant.val.u16 = value;
+ aVariant.ptr = &aVariant.val;
+ } else {
+ aVariant.ptr = nsnull;
+ }
+ aVariant.SetPtrIsData();
+ } else { // 'array'
+ if (aType == nsXPTType::T_I32)
+ static_cast<PRInt32*>(aVariant.val.p)[aIndex] = value;
+ else
+ static_cast<PRUint16*>(aVariant.val.p)[aIndex] = value;
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U32: // C++ unsigned int <=> Java long
+ {
+ LOG(("long\n"));
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ jlong value = env->CallLongMethod(aParam, longValueMID);
+ if (aType == nsXPTType::T_I64)
+ aVariant.val.i64 = value;
+ else
+ aVariant.val.u32 = value;
+ } else { // 'inout' & 'array'
+ jlong value;
+ if (aParam) {
+ env->GetLongArrayRegion((jlongArray) aParam, aIndex, 1, &value);
+ }
+
+ if (aIsOut) { // 'inout'
+ if (aParam) {
+ if (aType == nsXPTType::T_I64)
+ aVariant.val.i64 = value;
+ else
+ aVariant.val.u32 = value;
+ aVariant.ptr = &aVariant.val;
+ } else {
+ aVariant.ptr = nsnull;
+ }
+ aVariant.SetPtrIsData();
+ } else { // 'array'
+ if (aType == nsXPTType::T_I64)
+ static_cast<PRInt64*>(aVariant.val.p)[aIndex] = value;
+ else
+ static_cast<PRUint32*>(aVariant.val.p)[aIndex] = value;
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_FLOAT:
+ {
+ LOG(("float\n"));
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ aVariant.val.f = env->CallFloatMethod(aParam, floatValueMID);
+ } else { // 'inout' & 'array'
+ jfloat value;
+ if (aParam) {
+ env->GetFloatArrayRegion((jfloatArray) aParam, aIndex, 1, &value);
+ }
+
+ if (aIsOut) { // 'inout'
+ if (aParam) {
+ aVariant.val.f = value;
+ aVariant.ptr = &aVariant.val;
+ } else {
+ aVariant.ptr = nsnull;
+ }
+ aVariant.SetPtrIsData();
+ } else { // 'array'
+ static_cast<float*>(aVariant.val.p)[aIndex] = value;
+ }
+ }
+ break;
+ }
+
+ // XXX how do we handle unsigned 64-bit value?
+ case nsXPTType::T_U64: // C++ unsigned long <=> Java double
+ case nsXPTType::T_DOUBLE:
+ {
+ LOG(("double\n"));
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ jdouble value = env->CallDoubleMethod(aParam, doubleValueMID);
+ if (aType == nsXPTType::T_DOUBLE)
+ aVariant.val.d = value;
+ else
+ aVariant.val.u64 = static_cast<PRUint64>(value);
+ } else { // 'inout' & 'array'
+ jdouble value;
+ if (aParam) {
+ env->GetDoubleArrayRegion((jdoubleArray) aParam, aIndex, 1, &value);
+ }
+
+ if (aIsOut) { // 'inout'
+ if (aParam) {
+ if (aType == nsXPTType::T_DOUBLE)
+ aVariant.val.d = value;
+ else
+ aVariant.val.u64 = static_cast<PRUint64>(value);
+ aVariant.ptr = &aVariant.val;
+ } else {
+ aVariant.ptr = nsnull;
+ }
+ aVariant.SetPtrIsData();
+ } else { // 'array'
+ if (aType == nsXPTType::T_DOUBLE)
+ static_cast<double*>(aVariant.val.p)[aIndex] = value;
+ else
+ static_cast<PRUint64*>(aVariant.val.p)[aIndex] =
+ static_cast<PRUint64>(value);
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_BOOL:
+ {
+ LOG(("boolean\n"));
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ aVariant.val.b = env->CallBooleanMethod(aParam, booleanValueMID);
+ } else { // 'inout' & 'array'
+ jboolean value;
+ if (aParam) {
+ env->GetBooleanArrayRegion((jbooleanArray) aParam, aIndex, 1, &value);
+ }
+
+ if (aIsOut) { // 'inout'
+ if (aParam) {
+ aVariant.val.b = value;
+ aVariant.ptr = &aVariant.val;
+ } else {
+ aVariant.ptr = nsnull;
+ }
+ aVariant.SetPtrIsData();
+ } else { // 'array'
+ static_cast<PRBool*>(aVariant.val.p)[aIndex] = value;
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_CHAR:
+ {
+ LOG(("char\n"));
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ aVariant.val.c = env->CallCharMethod(aParam, charValueMID);
+ } else { // 'inout' & 'array'
+ jchar value;
+ if (aParam) {
+ env->GetCharArrayRegion((jcharArray) aParam, aIndex, 1, &value);
+ }
+
+ if (aIsOut) { // 'inout'
+ if (aParam) {
+ aVariant.val.c = value;
+ aVariant.ptr = &aVariant.val;
+ } else {
+ aVariant.ptr = nsnull;
+ }
+ aVariant.SetPtrIsData();
+ } else { // 'array'
+ static_cast<char*>(aVariant.val.p)[aIndex] = value;
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_WCHAR:
+ {
+ LOG(("char\n"));
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ aVariant.val.wc = env->CallCharMethod(aParam, charValueMID);
+ } else { // 'inout' & 'array'
+ jchar value;
+ if (aParam) {
+ env->GetCharArrayRegion((jcharArray) aParam, aIndex, 1, &value);
+ }
+
+ if (aIsOut) { // 'inout'
+ if (aParam) {
+ aVariant.val.wc = value;
+ aVariant.ptr = &aVariant.val;
+ } else {
+ aVariant.ptr = nsnull;
+ }
+ aVariant.SetPtrIsData();
+ } else { // 'array'
+ static_cast<PRUnichar*>(aVariant.val.p)[aIndex] = value;
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_CHAR_STR:
+ case nsXPTType::T_WCHAR_STR:
+ {
+ LOG(("String\n"));
+ jstring data = nsnull;
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ data = (jstring) aParam;
+ } else if (aParam) { // 'inout' & 'array'
+ data = (jstring) env->GetObjectArrayElement((jobjectArray) aParam,
+ aIndex);
+ }
+
+ void* buf = nsnull;
+ if (data) {
+ jsize uniLength = env->GetStringLength(data);
+ if (uniLength > 0) {
+ if (aType == nsXPTType::T_CHAR_STR) {
+ jsize utf8Length = env->GetStringUTFLength(data);
+ buf = nsMemory::Alloc((utf8Length + 1) * sizeof(char));
+ if (!buf) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ char* char_str = static_cast<char*>(buf);
+ env->GetStringUTFRegion(data, 0, uniLength, char_str);
+ char_str[utf8Length] = '\0';
+
+ } else { // if T_WCHAR_STR
+ buf = nsMemory::Alloc((uniLength + 1) * sizeof(jchar));
+ if (!buf) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ jchar* jchar_str = static_cast<jchar*>(buf);
+ env->GetStringRegion(data, 0, uniLength, jchar_str);
+ jchar_str[uniLength] = '\0';
+ }
+ } else {
+ // create empty string
+ buf = nsMemory::Alloc(2);
+ if (!buf) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ ((jchar*)buf)[0] = '\0';
+ }
+ }
+
+ if (!aIsArrayElement) { // 'in' & 'inout'
+ aVariant.val.p = buf;
+ if (aIsOut) { // 'inout'
+ aVariant.ptr = &aVariant.val;
+ aVariant.SetPtrIsData();
+ }
+ } else { // 'array'
+ if (aType == nsXPTType::T_CHAR_STR) {
+ char* str = static_cast<char*>(buf);
+ static_cast<char**>(aVariant.val.p)[aIndex] = str;
+ } else {
+ PRUnichar* str = static_cast<PRUnichar*>(buf);
+ static_cast<PRUnichar**>(aVariant.val.p)[aIndex] = str;
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_IID:
+ {
+ LOG(("String(IID)\n"));
+ jstring data = nsnull;
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ data = (jstring) aParam;
+ } else if (aParam) { // 'inout' & 'array'
+ data = (jstring) env->GetObjectArrayElement((jobjectArray) aParam,
+ aIndex);
+ }
+
+ nsID* iid = new nsID;
+ if (!iid) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ if (data) {
+ // extract IID string from Java string
+ const char* str = env->GetStringUTFChars(data, nsnull);
+ if (!str) {
+ delete iid;
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ // parse string into IID object
+ iid->Parse(str);
+ env->ReleaseStringUTFChars(data, str);
+ } else {
+ *iid = nullID;
+ }
+
+ if (!aIsArrayElement) { // 'in' & 'inout'
+ aVariant.val.p = iid;
+ if (aIsOut) { // 'inout'
+ aVariant.ptr = &aVariant.val;
+ aVariant.SetPtrIsData();
+ }
+ } else { // 'array'
+ static_cast<nsID**>(aVariant.val.p)[aIndex] = iid;
+ }
+ break;
+ }
+
+ case nsXPTType::T_INTERFACE:
+ case nsXPTType::T_INTERFACE_IS:
+ {
+ LOG(("nsISupports\n"));
+ jobject java_obj = nsnull;
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ java_obj = (jobject) aParam;
+ } else if (aParam) { // 'inout' & 'array'
+ java_obj = (jobject) env->GetObjectArrayElement((jobjectArray) aParam,
+ aIndex);
+ }
+
+ void* xpcom_obj;
+ if (java_obj) {
+ // If the requested interface is nsIWeakReference, then we look for or
+ // create a stub for the nsISupports interface. Then we create a weak
+ // reference from that stub.
+ PRBool isWeakRef;
+ nsID iid;
+ if (aIID.Equals(NS_GET_IID(nsIWeakReference))) {
+ isWeakRef = PR_TRUE;
+ iid = NS_GET_IID(nsISupports);
+ } else {
+ isWeakRef = PR_FALSE;
+ iid = aIID;
+ }
+
+ rv = JavaObjectToNativeInterface(env, java_obj, iid, &xpcom_obj);
+ if (NS_FAILED(rv))
+ break;
+ NS_ENSURE_TRUE(xpcom_obj, NS_ERROR_FAILURE);
+ nsISupports *xpcom_nat_obj = (nsISupports*) xpcom_obj;
+ rv = xpcom_nat_obj->QueryInterface(iid, &xpcom_obj);
+ NS_IF_RELEASE(xpcom_nat_obj);
+ if (NS_FAILED(rv))
+ break;
+
+ // If the function expects a weak reference, then we need to
+ // create it here.
+ if (isWeakRef) {
+ nsISupports* isupports = (nsISupports*) xpcom_obj;
+ nsCOMPtr<nsISupportsWeakReference> supportsweak =
+ do_QueryInterface(isupports);
+ if (supportsweak) {
+ nsWeakPtr weakref;
+ supportsweak->GetWeakReference(getter_AddRefs(weakref));
+ NS_RELEASE(isupports);
+ xpcom_obj = weakref;
+ NS_ADDREF((nsISupports*) xpcom_obj);
+ } else {
+ xpcom_obj = nsnull;
+ }
+ }
+ } else {
+ xpcom_obj = nsnull;
+ }
+
+ if (!aIsArrayElement) { // 'in' & 'inout'
+ aVariant.val.p = xpcom_obj;
+ aVariant.SetValIsInterface();
+ if (aIsOut) { // 'inout'
+ aVariant.ptr = &aVariant.val;
+ aVariant.SetPtrIsData();
+ }
+ } else { // 'array'
+ static_cast<void**>(aVariant.val.p)[aIndex] = xpcom_obj;
+ }
+ break;
+ }
+
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING:
+ {
+ LOG(("String\n"));
+ // Expecting only 'in' and 'in dipper'
+ NS_PRECONDITION(!aIsOut, "unexpected param descriptor");
+ if (aIsOut) {
+ rv = NS_ERROR_UNEXPECTED;
+ break;
+ }
+
+ jstring jstr = static_cast<jstring>(aParam);
+ nsAString* str = jstring_to_nsAString(env, jstr);
+ if (!str) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ aVariant.val.p = str;
+ aVariant.SetValIsDOMString();
+ break;
+ }
+
+ case nsXPTType::T_UTF8STRING:
+ case nsXPTType::T_CSTRING:
+ {
+ LOG(("StringUTF\n"));
+ // Expecting only 'in' and 'in dipper'
+ NS_PRECONDITION(!aIsOut, "unexpected param descriptor");
+ if (aIsOut) {
+ rv = NS_ERROR_UNEXPECTED;
+ break;
+ }
+
+ jstring jstr = static_cast<jstring>(aParam);
+ nsACString* str = jstring_to_nsACString(env, jstr);
+ if (!str) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ aVariant.val.p = str;
+ if (aType == nsXPTType::T_CSTRING) {
+ aVariant.SetValIsCString();
+ } else {
+ aVariant.SetValIsUTF8String();
+ }
+ break;
+ }
+
+ // handle "void *" as an "long" in Java
+ case nsXPTType::T_VOID:
+ {
+ LOG(("long (void*)\n"));
+ if (!aIsOut && !aIsArrayElement) { // 'in'
+ aVariant.val.p =
+ reinterpret_cast<void*>(env->CallLongMethod(aParam, longValueMID));
+ } else { // 'inout' & 'array'
+ jlong value;
+ if (aParam) {
+ env->GetLongArrayRegion((jlongArray) aParam, aIndex, 1, &value);
+ }
+
+ if (aIsOut) { // 'inout'
+ if (aParam) {
+ aVariant.val.p = reinterpret_cast<void*>(value);
+ aVariant.ptr = &aVariant.val;
+ } else {
+ aVariant.ptr = nsnull;
+ }
+ aVariant.SetPtrIsData();
+ } else { // 'array'
+ static_cast<void**>(aVariant.val.p)[aIndex] =
+ reinterpret_cast<void*>(value);
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_ARRAY:
+ {
+ jobject sourceArray = nsnull;
+ if (!aIsOut) { // 'in'
+ sourceArray = aParam;
+ } else if (aParam) { // 'inout'
+ jobjectArray array = static_cast<jobjectArray>(aParam);
+ sourceArray = env->GetObjectArrayElement(array, 0);
+ }
+
+ if (sourceArray) {
+ rv = CreateNativeArray(aArrayType, aArraySize, &aVariant.val.p);
+
+ for (PRUint32 i = 0; i < aArraySize && NS_SUCCEEDED(rv); i++) {
+ rv = SetupParams(env, sourceArray, aArrayType, PR_FALSE, aIID, 0, 0,
+ PR_TRUE, i, aVariant);
+ }
+ }
+
+ if (aIsOut) { // 'inout'
+ aVariant.ptr = &aVariant.val.p;
+ aVariant.SetPtrIsData();
+ }
+ break;
+ }
+
+ case nsXPTType::T_PSTRING_SIZE_IS:
+ case nsXPTType::T_PWSTRING_SIZE_IS:
+ {
+ NS_PRECONDITION(!aIsArrayElement, "sized string array not supported");
+
+ LOG(("Sized string\n"));
+ jstring data = nsnull;
+ if (!aIsOut) { // 'in'
+ data = (jstring) aParam;
+ } else if (aParam) { // 'inout'
+ data = (jstring) env->GetObjectArrayElement((jobjectArray) aParam,
+ aIndex);
+ }
+
+ PRUint32 length = 0;
+ if (data) {
+ if (aType == nsXPTType::T_PSTRING_SIZE_IS) {
+ length = env->GetStringUTFLength(data);
+ } else {
+ length = env->GetStringLength(data);
+ }
+ if (length > aArraySize) {
+ rv = NS_ERROR_ILLEGAL_VALUE;
+ break;
+ }
+ }
+
+ PRUint32 size_of_char = (aType == nsXPTType::T_PSTRING_SIZE_IS) ?
+ sizeof(char) : sizeof(jchar);
+ PRUint32 allocLength = (aArraySize + 1) * size_of_char;
+ void* buf = nsMemory::Alloc(allocLength);
+ if (!buf) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ if (data) {
+ if (aType == nsXPTType::T_PSTRING_SIZE_IS) {
+ const char* str = env->GetStringUTFChars(data, nsnull);
+ if (!str) {
+ nsMemory::Free(buf);
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ memcpy(buf, str, length);
+ env->ReleaseStringUTFChars(data, str);
+ } else {
+ jchar* jchar_str = static_cast<jchar*>(buf);
+ env->GetStringRegion(data, 0, length, jchar_str);
+ }
+ }
+
+ aVariant.val.p = buf;
+ if (aIsOut) { // 'inout'
+ aVariant.ptr = &aVariant.val;
+ aVariant.SetPtrIsData();
+ }
+
+ break;
+ }
+
+ default:
+ NS_WARNING("unexpected parameter type");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return rv;
+}
+
+/**
+ * Does any cleanup from objects created in SetupParams, as well as converting
+ * any out params to Java.
+ *
+ * NOTE: If aInvokeResult is an error condition, then we just do cleanup in
+ * this function.
+ */
+nsresult
+FinalizeParams(JNIEnv *env, const nsXPTParamInfo &aParamInfo, PRUint8 aType,
+ nsXPTCVariant &aVariant, const nsID& aIID,
+ PRBool aIsArrayElement, PRUint8 aArrayType, PRUint32 aArraySize,
+ PRUint32 aIndex, nsresult aInvokeResult, jobject* aParam)
+{
+ nsresult rv = NS_OK;
+
+ switch (aType)
+ {
+ case nsXPTType::T_I8:
+ {
+ if (NS_SUCCEEDED(aInvokeResult)) {
+ jbyte value = aVariant.val.i8;
+ if (aParamInfo.IsRetval() && !aIsArrayElement) {
+ *aParam = env->NewObject(byteClass, byteInitMID, value);
+ } else if ((aParamInfo.IsOut() || aIsArrayElement) && *aParam) {
+ env->SetByteArrayRegion((jbyteArray) *aParam, aIndex, 1, &value);
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_I16:
+ case nsXPTType::T_U8:
+ {
+ if (NS_SUCCEEDED(aInvokeResult)) {
+ jshort value = (aType == nsXPTType::T_I16) ? aVariant.val.i16 :
+ aVariant.val.u8;
+ if (aParamInfo.IsRetval() && !aIsArrayElement) {
+ *aParam = env->NewObject(shortClass, shortInitMID, value);
+ } else if ((aParamInfo.IsOut() || aIsArrayElement) && *aParam) {
+ env->SetShortArrayRegion((jshortArray) *aParam, aIndex, 1, &value);
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_I32:
+ case nsXPTType::T_U16:
+ {
+ if (NS_SUCCEEDED(aInvokeResult)) {
+ jint value = (aType == nsXPTType::T_I32) ? aVariant.val.i32 :
+ aVariant.val.u16;
+ if (aParamInfo.IsRetval() && !aIsArrayElement) {
+ *aParam = env->NewObject(intClass, intInitMID, value);
+ } else if ((aParamInfo.IsOut() || aIsArrayElement) && *aParam) {
+ env->SetIntArrayRegion((jintArray) *aParam, aIndex, 1, &value);
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U32:
+ {
+ if (NS_SUCCEEDED(aInvokeResult)) {
+ jlong value = (aType == nsXPTType::T_I64) ? aVariant.val.i64 :
+ aVariant.val.u32;
+ if (aParamInfo.IsRetval() && !aIsArrayElement) {
+ *aParam = env->NewObject(longClass, longInitMID, value);
+ } else if ((aParamInfo.IsOut() || aIsArrayElement) && *aParam) {
+ env->SetLongArrayRegion((jlongArray) *aParam, aIndex, 1, &value);
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_FLOAT:
+ {
+ if (NS_SUCCEEDED(aInvokeResult)) {
+ jfloat value = aVariant.val.f;
+ if (aParamInfo.IsRetval() && !aIsArrayElement) {
+ *aParam = env->NewObject(floatClass, floatInitMID, value);
+ } else if ((aParamInfo.IsOut() || aIsArrayElement) && *aParam) {
+ env->SetFloatArrayRegion((jfloatArray) *aParam, aIndex, 1, &value);
+ }
+ }
+ break;
+ }
+
+ // XXX how do we handle unsigned 64-bit values?
+ case nsXPTType::T_U64:
+ case nsXPTType::T_DOUBLE:
+ {
+ if (NS_SUCCEEDED(aInvokeResult)) {
+ jdouble value = (aType == nsXPTType::T_DOUBLE) ? aVariant.val.d :
+ aVariant.val.u64;
+ if (aParamInfo.IsRetval() && !aIsArrayElement) {
+ *aParam = env->NewObject(doubleClass, doubleInitMID, value);
+ } else if ((aParamInfo.IsOut() || aIsArrayElement) && *aParam) {
+ env->SetDoubleArrayRegion((jdoubleArray) *aParam, aIndex, 1, &value);
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_BOOL:
+ {
+ if (NS_SUCCEEDED(aInvokeResult)) {
+ jboolean value = aVariant.val.b;
+ if (aParamInfo.IsRetval() && !aIsArrayElement) {
+ *aParam = env->NewObject(booleanClass, booleanInitMID, value);
+ } else if ((aParamInfo.IsOut() || aIsArrayElement) && *aParam) {
+ env->SetBooleanArrayRegion((jbooleanArray) *aParam, aIndex, 1, &value);
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_CHAR:
+ case nsXPTType::T_WCHAR:
+ {
+ if (NS_SUCCEEDED(aInvokeResult)) {
+ jchar value;
+ if (aType == nsXPTType::T_CHAR)
+ value = aVariant.val.c;
+ else
+ value = aVariant.val.wc;
+ if (aParamInfo.IsRetval() && !aIsArrayElement) {
+ *aParam = env->NewObject(charClass, charInitMID, value);
+ } else if ((aParamInfo.IsOut() || aIsArrayElement) && *aParam) {
+ env->SetCharArrayRegion((jcharArray) *aParam, aIndex, 1, &value);
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_CHAR_STR:
+ case nsXPTType::T_WCHAR_STR:
+ {
+ if ((aParamInfo.IsOut() || aIsArrayElement) &&
+ NS_SUCCEEDED(aInvokeResult))
+ {
+ // create new string from data
+ jstring str = nsnull;
+ if (aVariant.val.p) {
+ if (aType == nsXPTType::T_CHAR_STR) {
+ str = env->NewStringUTF((const char*) aVariant.val.p);
+ } else {
+ PRUint32 length = nsCRT::strlen((const PRUnichar*) aVariant.val.p);
+ str = env->NewString((const jchar*) aVariant.val.p, length);
+ }
+ if (!str) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ }
+
+ if (aParamInfo.IsRetval() && !aIsArrayElement) {
+ *aParam = str;
+ } else if (*aParam) {
+ // put new string into output array
+ env->SetObjectArrayElement((jobjectArray) *aParam, aIndex, str);
+ }
+ }
+
+ // cleanup
+ if (aVariant.val.p)
+ nsMemory::Free(aVariant.val.p);
+ break;
+ }
+
+ case nsXPTType::T_IID:
+ {
+ nsID* iid = static_cast<nsID*>(aVariant.val.p);
+
+ if ((aParamInfo.IsOut() || aIsArrayElement) &&
+ NS_SUCCEEDED(aInvokeResult))
+ {
+ // Create the string from nsID
+ jstring str = nsnull;
+ if (iid) {
+ char iid_str[NSID_LENGTH];
+ iid->ToProvidedString(iid_str);
+ str = env->NewStringUTF(iid_str);
+ if (!str) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ }
+
+ if (aParamInfo.IsRetval() && !aIsArrayElement) {
+ *aParam = str;
+ } else if (*aParam) {
+ // put new string into output array
+ env->SetObjectArrayElement((jobjectArray) *aParam, aIndex, str);
+ }
+ }
+
+ // Ordinarily, we would delete 'iid' here. But we cannot do that until
+ // we've handled all of the params. See comment in CallXPCOMMethod.
+ // We can safely delete array elements, though.
+ if (aIsArrayElement)
+ delete iid;
+
+ break;
+ }
+
+ case nsXPTType::T_INTERFACE:
+ case nsXPTType::T_INTERFACE_IS:
+ {
+ nsISupports* xpcom_obj = static_cast<nsISupports*>(aVariant.val.p);
+
+ if ((aParamInfo.IsOut() || aIsArrayElement) &&
+ NS_SUCCEEDED(aInvokeResult))
+ {
+ jobject java_obj = nsnull;
+ if (xpcom_obj) {
+ // Get matching Java object for given xpcom object
+ rv = NativeInterfaceToJavaObject(env, xpcom_obj, aIID, nsnull,
+ &java_obj);
+ if (NS_FAILED(rv))
+ break;
+ }
+
+ if (aParamInfo.IsRetval() && !aIsArrayElement) {
+ *aParam = java_obj;
+ } else if (*aParam) {
+ // put new Java object into output array
+ env->SetObjectArrayElement((jobjectArray) *aParam, aIndex, java_obj);
+ }
+ }
+
+ // cleanup
+ NS_IF_RELEASE(xpcom_obj);
+ break;
+ }
+
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING:
+ {
+ NS_PRECONDITION(aParamInfo.IsIn(), "unexpected param descriptor");
+ if (!aParamInfo.IsIn()) {
+ rv = NS_ERROR_UNEXPECTED;
+ break;
+ }
+
+ nsString* str = static_cast<nsString*>(aVariant.val.p);
+ if (NS_SUCCEEDED(aInvokeResult) && aParamInfo.IsDipper()) {
+ // Create Java string from returned nsString
+ jstring jstr = nsnull;
+ if (str && !str->IsVoid()) {
+ jstr = env->NewString((const jchar*) str->get(), str->Length());
+ if (!jstr) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ }
+
+ *aParam = jstr;
+ }
+
+ // cleanup
+ if (str) {
+ delete str;
+ }
+ break;
+ }
+
+ case nsXPTType::T_UTF8STRING:
+ case nsXPTType::T_CSTRING:
+ {
+ NS_PRECONDITION(aParamInfo.IsIn(), "unexpected param descriptor");
+ if (!aParamInfo.IsIn()) {
+ rv = NS_ERROR_UNEXPECTED;
+ break;
+ }
+
+ nsCString* str = static_cast<nsCString*>(aVariant.val.p);
+ if (NS_SUCCEEDED(aInvokeResult) && aParamInfo.IsDipper()) {
+ // Create Java string from returned nsString
+ jstring jstr = nsnull;
+ if (str && !str->IsVoid()) {
+ jstr = env->NewStringUTF((const char*) str->get());
+ if (!jstr) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ }
+
+ *aParam = jstr;
+ }
+
+ // cleanup
+ if (str) {
+ delete str;
+ }
+ break;
+ }
+
+ case nsXPTType::T_VOID:
+ {
+ if (NS_SUCCEEDED(aInvokeResult)) {
+ jlong value = reinterpret_cast<jlong>(aVariant.val.p);
+ if (aParamInfo.IsRetval() && !aIsArrayElement) {
+ *aParam = env->NewObject(longClass, longInitMID, value);
+ } else if ((aParamInfo.IsOut() || aIsArrayElement) && *aParam) {
+ env->SetLongArrayRegion((jlongArray) *aParam, aIndex, 1, &value);
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_ARRAY:
+ {
+ if (aParamInfo.IsOut() && NS_SUCCEEDED(aInvokeResult)) {
+ // Create Java array from returned native array
+ jobject jarray = nsnull;
+ if (aVariant.val.p) {
+ rv = CreateJavaArray(env, aArrayType, aArraySize, aIID, &jarray);
+ if (NS_FAILED(rv))
+ break;
+
+ nsXPTCVariant var;
+ for (PRUint32 i = 0; i < aArraySize && NS_SUCCEEDED(rv); i++) {
+ rv = GetNativeArrayElement(aArrayType, aVariant.val.p, i, &var);
+ if (NS_SUCCEEDED(rv)) {
+ rv = FinalizeParams(env, aParamInfo, aArrayType, var, aIID,
+ PR_TRUE, 0, 0, i, aInvokeResult, &jarray);
+ }
+ }
+ }
+
+ if (aParamInfo.IsRetval()) {
+ *aParam = jarray;
+ } else if (*aParam) {
+ // put new Java array into output array
+ env->SetObjectArrayElement((jobjectArray) *aParam, 0, jarray);
+ }
+ }
+
+ // cleanup
+ // If this is not an out param or if the invokeResult is a failure case,
+ // then the array elements have not been cleaned up. Do so now.
+ if (!aParamInfo.IsOut() || (NS_FAILED(aInvokeResult) && aVariant.val.p)) {
+ nsXPTCVariant var;
+ for (PRUint32 i = 0; i < aArraySize; i++) {
+ rv = GetNativeArrayElement(aArrayType, aVariant.val.p, i, &var);
+ if (NS_SUCCEEDED(rv)) {
+ FinalizeParams(env, aParamInfo, aArrayType, var, aIID, PR_TRUE,
+ 0, 0, i, NS_ERROR_FAILURE, nsnull);
+ }
+ }
+ }
+ PR_Free(aVariant.val.p);
+ break;
+ }
+
+ case nsXPTType::T_PSTRING_SIZE_IS:
+ case nsXPTType::T_PWSTRING_SIZE_IS:
+ {
+ NS_PRECONDITION(!aIsArrayElement, "sized string array not supported");
+
+ if ((aParamInfo.IsOut()) && NS_SUCCEEDED(aInvokeResult))
+ {
+ // create new string from data
+ jstring str = nsnull;
+ if (aVariant.val.p) {
+ if (aType == nsXPTType::T_PSTRING_SIZE_IS) {
+ PRUint32 len = (aArraySize + 1) * sizeof(char);
+ char* buf = (char*) nsMemory::Alloc(len);
+ if (buf) {
+ memcpy(buf, aVariant.val.p, len);
+ buf[aArraySize] = '\0';
+ str = env->NewStringUTF((const char*) buf);
+ nsMemory::Free(buf);
+ }
+ } else {
+ str = env->NewString((const jchar*) aVariant.val.p, aArraySize);
+ }
+ if (!str) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ }
+
+ if (aParamInfo.IsRetval()) {
+ *aParam = str;
+ } else if (*aParam) {
+ // put new string into output array
+ env->SetObjectArrayElement((jobjectArray) *aParam, aIndex, str);
+ }
+ }
+
+ // cleanup
+ if (aVariant.val.p)
+ nsMemory::Free(aVariant.val.p);
+ break;
+ }
+
+ default:
+ NS_WARNING("unexpected parameter type");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ // Check for Java exception, but don't overwrite pre-existing error code.
+ if (NS_SUCCEEDED(rv) && env->ExceptionCheck())
+ rv = NS_ERROR_FAILURE;
+
+ return rv;
+}
+
+nsresult
+QueryAttributeInfo(nsIInterfaceInfo* aIInfo, const char* aMethodName,
+ PRBool aCapitalizedAttr, PRUint16* aMethodIndex,
+ const nsXPTMethodInfo** aMethodInfo)
+
+{
+ nsresult rv = NS_ERROR_FAILURE;
+
+ // An 'attribute' will start with either "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);
+ if (!aCapitalizedAttr) {
+ 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);
+ if (!aCapitalizedAttr) {
+ 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);
+ }
+ }
+
+ return rv;
+}
+
+/**
+ * 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)
+{
+ // Skip over any leading underscores, since these are methods that conflicted
+ // with existing Java keywords
+ const char* methodName = aMethodName;
+ if (methodName[0] == '_') {
+ methodName++;
+ }
+
+ // The common case is that the method name is lower case, so we check
+ // that first.
+ nsresult rv;
+ rv = aIInfo->GetMethodInfoForName(methodName, aMethodIndex, aMethodInfo);
+ if (NS_SUCCEEDED(rv))
+ return rv;
+
+ // If there is no method called <aMethodName>, then maybe it is an
+ // 'attribute'.
+ rv = QueryAttributeInfo(aIInfo, methodName, PR_FALSE, aMethodIndex,
+ aMethodInfo);
+ if (NS_SUCCEEDED(rv))
+ return rv;
+
+ // If we get here, then maybe the method name is capitalized.
+ char* name = strdup(methodName);
+ name[0] = toupper(name[0]);
+ rv = aIInfo->GetMethodInfoForName(name, aMethodIndex, aMethodInfo);
+ free(name);
+ if (NS_SUCCEEDED(rv))
+ return rv;
+
+ // If there is no method called <aMethodName>, then maybe it is an
+ // 'attribute'.
+ rv = QueryAttributeInfo(aIInfo, methodName, PR_TRUE, aMethodIndex,
+ aMethodInfo);
+
+ return rv;
+}
+
+#ifdef VBOX
+#include <nsIExceptionService.h>
+#include <iprt/err.h>
+#include "nspr.h"
+
+static void makeErrorMessage(nsresult r, char* msg, size_t msgSize)
+{
+ bool gotMsg = false;
+
+ if (!gotMsg)
+ {
+ nsresult rc;
+ nsCOMPtr <nsIExceptionService> es;
+ es = do_GetService (NS_EXCEPTIONSERVICE_CONTRACTID, &rc);
+ if (NS_SUCCEEDED (rc))
+ {
+ nsCOMPtr <nsIExceptionManager> em;
+ rc = es->GetCurrentExceptionManager (getter_AddRefs (em));
+ if (NS_SUCCEEDED (rc))
+ {
+ nsCOMPtr <nsIException> ex;
+ rc = em->GetCurrentException(getter_AddRefs (ex));
+ if (NS_SUCCEEDED (rc) && ex)
+ {
+ nsXPIDLCString emsg;
+ ex->GetMessage(getter_Copies(emsg));
+ PR_snprintf(msg, msgSize, "%s",
+ emsg.get());
+ gotMsg = true;
+ }
+ }
+ }
+ }
+
+ if (!gotMsg)
+ {
+ const RTCOMERRMSG* pMsg = RTErrCOMGet(r);
+ if (strncmp(pMsg->pszMsgFull, "Unknown", 7) != 0)
+ {
+ PR_snprintf(msg, msgSize, "%s (%s)",
+ pMsg->pszMsgFull, pMsg->pszDefine);
+ gotMsg = true;
+ }
+ }
+
+ if (!gotMsg)
+ {
+ PR_snprintf(msg, msgSize, "Error 0x%x in module 0x%x",
+ NS_ERROR_GET_CODE(r), NS_ERROR_GET_MODULE(r));
+ }
+}
+#endif
+
+/**
+ * org.mozilla.xpcom.XPCOMJavaProxy.internal.callXPCOMMethod
+ */
+extern "C" NS_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 = static_cast<JavaXPCOMInstance*>(xpcom_obj);
+
+ // Get method info
+ PRUint16 methodIndex;
+ const nsXPTMethodInfo* methodInfo;
+ nsIInterfaceInfo* iinfo = inst->InterfaceInfo();
+ const char* methodName = env->GetStringUTFChars(aMethodName, nsnull);
+ rv = QueryMethodInfo(iinfo, methodName, &methodIndex, &methodInfo);
+ env->ReleaseStringUTFChars(aMethodName, methodName);
+
+ if (NS_FAILED(rv)) {
+ ThrowException(env, rv, "GetMethodInfoForName failed");
+ return nsnull;
+ }
+
+#ifdef DEBUG_JAVAXPCOM
+ const char* ifaceName;
+ iinfo->GetNameShared(&ifaceName);
+ LOG(("===> (XPCOM) %s::%s()\n", ifaceName, methodInfo->GetName()));
+#endif
+
+ // Convert the Java params
+ PRUint8 paramCount = methodInfo->GetParamCount();
+ nsXPTCVariant* params = nsnull;
+ if (paramCount)
+ {
+ params = new nsXPTCVariant[paramCount];
+ if (!params) {
+ ThrowException(env, NS_ERROR_OUT_OF_MEMORY, "Can't create params array");
+ return nsnull;
+ }
+ memset(params, 0, paramCount * sizeof(nsXPTCVariant));
+
+ PRBool foundDependentParam = PR_FALSE;
+ for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)
+ {
+ LOG(("\t Param %d: ", i));
+ const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);
+ params[i].type = paramInfo.GetType();
+
+ if (params[i].type.IsDependent() && paramInfo.IsIn()) {
+ foundDependentParam = PR_TRUE;
+ continue;
+ }
+
+ if (paramInfo.IsIn()) {
+ PRUint8 type = params[i].type.TagPart();
+
+ // get IID for interface params
+ nsID iid;
+ if (type == nsXPTType::T_INTERFACE) {
+ rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, type,
+ methodIndex, params, PR_TRUE, iid);
+ }
+
+ if (NS_SUCCEEDED(rv)) {
+ jobject param = nsnull;
+ if (aParams && !paramInfo.IsRetval()) {
+ param = env->GetObjectArrayElement(aParams, i);
+ }
+ rv = SetupParams(env, param, type, paramInfo.IsOut(), iid, 0, 0,
+ PR_FALSE, 0, params[i]);
+ }
+ } else {
+ LOG(("out/retval\n"));
+ params[i].ptr = &(params[i].val);
+ params[i].SetPtrIsData();
+ }
+ }
+
+ // Handle any dependent params by doing a second pass
+ if (foundDependentParam) {
+
+ for (PRUint8 j = 0; j < paramCount && NS_SUCCEEDED(rv); j++) {
+
+ const nsXPTParamInfo &paramInfo = methodInfo->GetParam(j);
+ params[j].type = paramInfo.GetType();
+
+ if (!params[j].type.IsDependent())
+ continue;
+
+ if (paramInfo.IsIn()) {
+ PRUint8 type = params[j].type.TagPart();
+
+ // is paramater an array or sized string?
+ PRUint8 arrayType = 0;
+ PRUint32 arraySize = 0;
+ PRBool isArray = params[j].type.IsArray();
+ PRBool isSizedString = isArray ? PR_FALSE :
+ type == nsXPTType::T_PSTRING_SIZE_IS ||
+ type == nsXPTType::T_PWSTRING_SIZE_IS;
+
+ if (isArray) {
+ // get array type
+ nsXPTType xpttype;
+ rv = iinfo->GetTypeForParam(methodIndex, &paramInfo, 1, &xpttype);
+ if (NS_FAILED(rv))
+ break;
+ arrayType = xpttype.TagPart();
+ // IDL 'octet' arrays are not 'promoted' to short, but kept as 'byte';
+ // therefore, treat as a signed 8bit value
+ if (arrayType == nsXPTType::T_U8)
+ arrayType = nsXPTType::T_I8;
+ }
+
+ if (isArray || isSizedString) {
+ // get size of array or string
+ PRUint8 argnum;
+ rv = iinfo->GetSizeIsArgNumberForParam(methodIndex, &paramInfo, 0,
+ &argnum);
+ if (NS_FAILED(rv))
+ break;
+ arraySize = params[argnum].val.u32;
+ }
+
+ // get IID for interface params
+ nsID iid;
+ if (type == nsXPTType::T_INTERFACE_IS ||
+ (type == nsXPTType::T_ARRAY &&
+ (arrayType == nsXPTType::T_INTERFACE ||
+ arrayType == nsXPTType::T_INTERFACE_IS)))
+ {
+ PRUint8 paramType = type == nsXPTType::T_ARRAY ? arrayType : type;
+ rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, paramType,
+ methodIndex, params, PR_TRUE, iid);
+ }
+
+ if (NS_SUCCEEDED(rv)) {
+ jobject param = nsnull;
+ if (aParams && !paramInfo.IsRetval()) {
+ param = env->GetObjectArrayElement(aParams, j);
+ }
+ rv = SetupParams(env, param, type, paramInfo.IsOut(), iid, arrayType,
+ arraySize, PR_FALSE, 0, params[j]);
+ }
+ }
+ }
+ }
+
+ if (NS_FAILED(rv)) {
+ ThrowException(env, rv, "SetupParams failed");
+ return nsnull;
+ }
+ }
+
+ // Call the XPCOM method
+ const nsIID* iid;
+ iinfo->GetIIDShared(&iid);
+ nsISupports* realObject;
+ rv = inst->GetInstance()->QueryInterface(*iid, (void**) &realObject);
+ if (NS_FAILED(rv)) {
+ ThrowException(env, rv, "Failed to get real XPCOM object");
+ return nsnull;
+ }
+ nsresult invokeResult = NS_InvokeByIndex(realObject, methodIndex,
+ paramCount, params);
+ NS_RELEASE(realObject);
+
+ // Clean up params
+ jobject result = nsnull;
+ for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)
+ {
+ const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);
+ PRUint8 type = paramInfo.GetType().TagPart();
+
+ // is paramater an array or sized string?
+ PRUint8 arrayType = 0;
+ PRUint32 arraySize = 0;
+ PRBool isArray = params[i].type.IsArray();
+ PRBool isSizedString = isArray ? PR_FALSE :
+ type == nsXPTType::T_PSTRING_SIZE_IS ||
+ type == nsXPTType::T_PWSTRING_SIZE_IS;
+
+ if (isArray) {
+ // get array type
+ nsXPTType array_xpttype;
+ rv = iinfo->GetTypeForParam(methodIndex, &paramInfo, 1, &array_xpttype);
+ if (NS_FAILED(rv))
+ break;
+ arrayType = array_xpttype.TagPart();
+ // IDL 'octet' arrays are not 'promoted' to short, but kept as 'byte';
+ // therefore, treat as a signed 8bit value
+ if (arrayType == nsXPTType::T_U8)
+ arrayType = nsXPTType::T_I8;
+ }
+
+ if (isArray || isSizedString) {
+ // get size of array
+ PRUint8 argnum;
+ rv = iinfo->GetSizeIsArgNumberForParam(methodIndex, &paramInfo, 0,
+ &argnum);
+ if (NS_FAILED(rv))
+ break;
+ arraySize = params[argnum].val.u32;
+ }
+
+ // get IID for interface params
+ nsID iid;
+ if (type == nsXPTType::T_INTERFACE || type == nsXPTType::T_INTERFACE_IS ||
+ (type == nsXPTType::T_ARRAY && (arrayType == nsXPTType::T_INTERFACE ||
+ arrayType == nsXPTType::T_INTERFACE_IS)))
+ {
+ PRUint8 paramType = type == nsXPTType::T_ARRAY ? arrayType : type;
+ rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, paramType,
+ methodIndex, params, PR_TRUE, iid);
+ if (NS_FAILED(rv))
+ break;
+ }
+
+ jobject* javaElement;
+ jobject element = nsnull;
+ if (!paramInfo.IsRetval()) {
+ element = env->GetObjectArrayElement(aParams, i);
+ javaElement = &element;
+ } else {
+ javaElement = &result;
+ }
+ rv = FinalizeParams(env, paramInfo, type, params[i], iid, PR_FALSE,
+ arrayType, arraySize, 0, invokeResult, javaElement);
+ }
+
+ // Normally, we would delete any created nsID object in the above loop.
+ // However, GetIIDForMethodParam may need some of the nsID params when it's
+ // looking for the IID of an INTERFACE_IS. Therefore, we can't delete it
+ // until we've gone through the 'Finalize' loop once and created the result.
+ for (PRUint8 j = 0; j < paramCount; j++)
+ {
+ const nsXPTParamInfo &paramInfo = methodInfo->GetParam(j);
+ const nsXPTType &type = paramInfo.GetType();
+ if (type.TagPart() == nsXPTType::T_IID) {
+ nsID* iid = (nsID*) params[j].val.p;
+ delete iid;
+ }
+ }
+
+ if (params) {
+ delete params;
+ }
+
+ // If the XPCOM method invocation failed, we don't immediately throw an
+ // exception and return so that we can clean up any parameters.
+ if (NS_FAILED(invokeResult)) {
+ nsCAutoString message("The function \"");
+ message.AppendASCII(methodInfo->GetName());
+ message.AppendLiteral("\" returned an error condition");
+#ifdef VBOX
+ char vboxMsg[1024];
+ message.AppendLiteral(": \"");
+ makeErrorMessage(invokeResult, vboxMsg, sizeof vboxMsg);
+ message.AppendASCII(vboxMsg);
+ message.AppendLiteral("\"");
+#endif
+ ThrowException(env, invokeResult, message.get());
+ }
+ if (NS_FAILED(rv)) {
+ ThrowException(env, rv, "FinalizeParams failed");
+ return nsnull;
+ }
+
+ LOG(("<=== (XPCOM) %s::%s()\n", ifaceName, methodInfo->GetName()));
+ return result;
+}
+
+nsresult
+GetNewOrUsedJavaWrapper(JNIEnv* env, nsISupports* aXPCOMObject,
+ const nsIID& aIID, jobject aObjectLoader,
+ jobject* aResult)
+{
+ NS_PRECONDITION(aResult != nsnull, "null ptr");
+ if (!aResult)
+ return NS_ERROR_NULL_POINTER;
+
+ // Get the root nsISupports of the xpcom object
+ nsresult rv;
+ nsCOMPtr<nsISupports> rootObject = do_QueryInterface(aXPCOMObject, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Get associated Java object from hash table
+ rv = gNativeToJavaProxyMap->Find(env, rootObject, aIID, aResult);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (*aResult)
+ return NS_OK;
+
+ // No Java object is associated with the given XPCOM object, so we
+ // create a Java proxy.
+
+ nsCOMPtr<nsIInterfaceInfoManager>
+ iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
+ NS_ASSERTION(iim, "Failed to get InterfaceInfoManager");
+ if (!iim)
+ return NS_ERROR_FAILURE;
+
+ // Get interface info for class
+ nsCOMPtr<nsIInterfaceInfo> info;
+ rv = iim->GetInfoForIID(&aIID, getter_AddRefs(info));
+ if (NS_FAILED(rv))
+ return rv;
+
+ // Wrap XPCOM object (addrefs rootObject)
+ JavaXPCOMInstance* inst = new JavaXPCOMInstance(rootObject, info);
+ if (!inst)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ // Get interface name
+ const char* iface_name;
+ rv = info->GetNameShared(&iface_name);
+
+ if (NS_SUCCEEDED(rv)) {
+ jobject java_obj = nsnull;
+
+ // Create proper Java interface name
+ nsCAutoString class_name("org.mozilla.interfaces.");
+ class_name.AppendASCII(iface_name);
+ jclass ifaceClass = FindClassInLoader(env, aObjectLoader, class_name.get());
+
+ if (ifaceClass) {
+ java_obj = env->CallStaticObjectMethod(xpcomJavaProxyClass,
+ createProxyMID, ifaceClass,
+ reinterpret_cast<jlong>(inst));
+ if (env->ExceptionCheck())
+ java_obj = nsnull;
+ }
+
+ if (java_obj) {
+#ifdef DEBUG_JAVAXPCOM
+ char* iid_str = aIID.ToString();
+ LOG(("+ CreateJavaProxy (Java=%08x | XPCOM=%08x | IID=%s)\n",
+ (PRUint32) env->CallStaticIntMethod(systemClass, hashCodeMID,
+ java_obj),
+ (PRUint32) rootObject, iid_str));
+ PR_Free(iid_str);
+#endif
+
+ // Associate XPCOM object with Java proxy
+ rv = gNativeToJavaProxyMap->Add(env, rootObject, aIID, java_obj);
+ if (NS_SUCCEEDED(rv)) {
+ *aResult = java_obj;
+ return NS_OK;
+ }
+ } else {
+ rv = NS_ERROR_FAILURE;
+ }
+ }
+
+ // If there was an error, clean up.
+ delete inst;
+ return rv;
+}
+
+nsresult
+GetXPCOMInstFromProxy(JNIEnv* env, jobject aJavaObject, void** aResult)
+{
+ NS_PRECONDITION(aResult != nsnull, "null ptr");
+ if (!aResult)
+ return NS_ERROR_NULL_POINTER;
+
+ jlong xpcom_obj = env->CallStaticLongMethod(xpcomJavaProxyClass,
+ getNativeXPCOMInstMID, aJavaObject);
+
+ if (!xpcom_obj || env->ExceptionCheck()) {
+ return NS_ERROR_FAILURE;
+ }
+
+ *aResult = reinterpret_cast<void*>(xpcom_obj);
+#ifdef DEBUG_JAVAXPCOM
+ JavaXPCOMInstance* inst = static_cast<JavaXPCOMInstance*>(*aResult);
+ nsIID* iid;
+ inst->InterfaceInfo()->GetInterfaceIID(&iid);
+ char* iid_str = iid->ToString();
+ LOG(("< GetXPCOMInstFromProxy (Java=%08x | XPCOM=%08x | IID=%s)\n",
+ (PRUint32) env->CallStaticIntMethod(systemClass, hashCodeMID,
+ aJavaObject),
+ (PRUint32) inst->GetInstance(), iid_str));
+ PR_Free(iid_str);
+ nsMemory::Free(iid);
+#endif
+ return NS_OK;
+}
+
+/**
+ * org.mozilla.xpcom.internal.XPCOMJavaProxy.finalizeProxy
+ */
+extern "C" NS_EXPORT void JNICALL
+JAVAPROXY_NATIVE(finalizeProxy) (JNIEnv *env, jclass that, jobject aJavaProxy)
+{
+#ifdef DEBUG_JAVAXPCOM
+ PRUint32 xpcom_addr = 0;
+#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);
+
+ // If may be possible for the lock to be acquired here when FreeGlobals is
+ // in the middle of running. If so, then this thread will sleep until
+ // FreeGlobals releases its lock. At that point, we resume this thread
+ // here, but JavaXPCOM may no longer be initialized. So we need to check
+ // that everything is legit after acquiring the lock.
+ if (gJavaXPCOMInitialized) {
+ // Get native XPCOM instance
+ void* xpcom_obj;
+ nsresult rv = GetXPCOMInstFromProxy(env, aJavaProxy, &xpcom_obj);
+ if (NS_SUCCEEDED(rv)) {
+ JavaXPCOMInstance* inst = static_cast<JavaXPCOMInstance*>(xpcom_obj);
+#ifdef DEBUG_JAVAXPCOM
+ xpcom_addr = reinterpret_cast<PRUint32>(inst->GetInstance());
+#endif
+ nsIID* iid;
+ rv = inst->InterfaceInfo()->GetInterfaceIID(&iid);
+ if (NS_SUCCEEDED(rv)) {
+ rv = gNativeToJavaProxyMap->Remove(env, inst->GetInstance(), *iid);
+ nsMemory::Free(iid);
+ }
+ NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to RemoveJavaProxy");
+ // Release gJavaXPCOMLock before deleting inst (see bug 340022)
+ lock.unlock();
+ delete inst;
+ }
+ }
+ }
+
+#ifdef DEBUG_JAVAXPCOM
+ LOG(("- Finalize (Java=%08x | XPCOM=%08x)\n",
+ (PRUint32) env->CallStaticIntMethod(systemClass, hashCodeMID,
+ aJavaProxy),
+ xpcom_addr));
+#endif
+}
+
+/**
+ * org.mozilla.xpcom.XPCOMJavaProxy.isSameXPCOMObject
+ */
+extern "C" NS_EXPORT jboolean JNICALL
+JAVAPROXY_NATIVE(isSameXPCOMObject) (JNIEnv *env, jclass that,
+ jobject aProxy1, jobject aProxy2)
+{
+ void* xpcom_obj1;
+ nsresult rv = GetXPCOMInstFromProxy(env, aProxy1, &xpcom_obj1);
+ if (NS_SUCCEEDED(rv)) {
+ void* xpcom_obj2;
+ rv = GetXPCOMInstFromProxy(env, aProxy2, &xpcom_obj2);
+ if (NS_SUCCEEDED(rv)) {
+ JavaXPCOMInstance* inst1 = static_cast<JavaXPCOMInstance*>(xpcom_obj1);
+ JavaXPCOMInstance* inst2 = static_cast<JavaXPCOMInstance*>(xpcom_obj2);
+ if (inst1->GetInstance() == inst2->GetInstance()) {
+ return JNI_TRUE;
+ }
+ }
+ }
+ return JNI_FALSE;
+}
+
+/**
+ * org.mozilla.xpcom.ProfileLock.release
+ */
+extern "C" NS_EXPORT void JNICALL
+LOCKPROXY_NATIVE(release) (JNIEnv *env, jclass that, jlong aLockObject)
+{
+ // Need to release object on the main thread.
+ nsresult rv = NS_ERROR_FAILURE;
+#ifdef VBOX
+ rv = NS_ProxyRelease(do_GetMainThreadQueue().get(), reinterpret_cast<nsISupports*>(aLockObject));
+#else
+ nsCOMPtr<nsIThread> thread = do_GetMainThread();
+ if (thread) {
+ rv = NS_ProxyRelease(thread, reinterpret_cast<nsISupports*>(aLockObject));
+ }
+#endif
+ NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to release using NS_ProxyRelease");
+}
diff --git a/src/libs/xpcom18a4/java/src/nsJavaWrapper.h b/src/libs/xpcom18a4/java/src/nsJavaWrapper.h
new file mode 100644
index 00000000..c441a41c
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsJavaWrapper.h
@@ -0,0 +1,75 @@
+/* ***** 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 ***** */
+
+#ifndef _nsJavaWrapper_h_
+#define _nsJavaWrapper_h_
+
+#include "jni.h"
+#include "nsISupports.h"
+
+
+/**
+ * Finds the associated Java wraper for the given XPCOM object and IID. If no
+ * such Java wrapper exists, then a new one is created.
+ *
+ * @param env Java environment pointer
+ * @param aXPCOMObject XPCOM object for which to find/create Java wrapper
+ * @param aIID desired interface IID for Java wrapper
+ * @param aObjectLoader Java wrapper whose class loader we use for finding
+ * classes; can be null
+ * @param aResult on success, holds reference to Java wrapper
+ *
+ * @return NS_OK if succeeded; all other return values are error codes.
+ */
+nsresult GetNewOrUsedJavaWrapper(JNIEnv* env, nsISupports* aXPCOMObject,
+ const nsIID& aIID, jobject aObjectLoader,
+ 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_
diff --git a/src/libs/xpcom18a4/java/src/nsJavaXPCOMBindingUtils.cpp b/src/libs/xpcom18a4/java/src/nsJavaXPCOMBindingUtils.cpp
new file mode 100644
index 00000000..f91fdd83
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsJavaXPCOMBindingUtils.cpp
@@ -0,0 +1,1084 @@
+/* ***** 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) 2005
+ * 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 ***** */
+
+
+#include "nsJavaXPCOMBindingUtils.h"
+#include "nsJavaXPTCStub.h"
+#include "nsJavaWrapper.h"
+#include "jni.h"
+#include "nsIInterfaceInfoManager.h"
+#include "nsThreadUtils.h"
+#include "nsProxyRelease.h"
+#ifdef VBOX
+#ifndef NS_INT32_TO_PTR
+#define NS_INT32_TO_PTR(x) ((void *)((char *)0 + (x)))
+#endif
+#endif
+
+
+/* Java JNI globals */
+
+JavaVM* gCachedJVM = nsnull;
+
+jclass systemClass = nsnull;
+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;
+jclass weakReferenceClass = nsnull;
+jclass javaXPCOMUtilsClass = 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;
+jmethodID weakReferenceConstructorMID = nsnull;
+jmethodID getReferentMID = nsnull;
+jmethodID clearReferentMID = nsnull;
+jmethodID findClassInLoaderMID = nsnull;
+
+#ifdef DEBUG_JAVAXPCOM
+jmethodID getNameMID = nsnull;
+jmethodID proxyToStringMID = nsnull;
+#endif
+
+NativeToJavaProxyMap* gNativeToJavaProxyMap = nsnull;
+JavaToXPTCStubMap* gJavaToXPTCStubMap = nsnull;
+
+PRBool gJavaXPCOMInitialized = PR_FALSE;
+PRLock* gJavaXPCOMLock = nsnull;
+
+static const char* kJavaKeywords[] = {
+ "abstract", "default" , "if" , "private" , "throw" ,
+ "boolean" , "do" , "implements", "protected" , "throws" ,
+ "break" , "double" , "import", "public" , "transient" ,
+ "byte" , "else" , "instanceof", "return" , "try" ,
+ "case" , "extends" , "int" , "short" , "void" ,
+ "catch" , "final" , "interface" , "static" , "volatile" ,
+ "char" , "finally" , "long" , "super" , "while" ,
+ "class" , "float" , "native" , "switch" ,
+ "const" , "for" , "new" , "synchronized",
+ "continue", "goto" , "package" , "this" ,
+ /* added in Java 1.2 */
+ "strictfp",
+ /* added in Java 1.4 */
+ "assert" ,
+ /* added in Java 5.0 */
+ "enum" ,
+ /* Java constants */
+ "true" , "false" , "null" ,
+ /* java.lang.Object methods *
+ * - don't worry about "toString", since it does the same thing *
+ * as Object's "toString" */
+ "clone" , "equals" , "finalize" , "getClass" , "hashCode" ,
+ "notify" , "notifyAll", /*"toString" ,*/ "wait"
+};
+
+nsTHashtable<nsDepCharHashKey>* gJavaKeywords = nsnull;
+
+
+/******************************
+ * InitializeJavaGlobals
+ ******************************/
+PRBool
+InitializeJavaGlobals(JNIEnv *env)
+{
+ if (gJavaXPCOMInitialized)
+ return PR_TRUE;
+
+ // Save pointer to JavaVM, which is valid across threads.
+ jint rc = env->GetJavaVM(&gCachedJVM);
+ if (rc != 0) {
+ NS_WARNING("Failed to get JavaVM");
+ goto init_error;
+ }
+
+ jclass clazz;
+ if (!(clazz = env->FindClass("java/lang/System")) ||
+ !(systemClass = (jclass) env->NewGlobalRef(clazz)) ||
+ !(hashCodeMID = env->GetStaticMethodID(clazz, "identityHashCode",
+ "(Ljava/lang/Object;)I")))
+ {
+ NS_WARNING("Problem creating java.lang.System globals");
+ goto init_error;
+ }
+
+ if (!(clazz = env->FindClass("java/lang/Boolean")) ||
+ !(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")) ||
+ !(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")) ||
+ !(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")) ||
+ !(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")) ||
+ !(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")) ||
+ !(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")) ||
+ !(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")) ||
+ !(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/interfaces/nsISupports")) ||
+ !(nsISupportsClass = (jclass) env->NewGlobalRef(clazz)))
+ {
+ NS_WARNING("Problem creating org.mozilla.interfaces.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;
+ }
+
+ if (!(clazz = env->FindClass("org/mozilla/xpcom/internal/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.internal.XPCOMJavaProxy globals");
+ goto init_error;
+ }
+
+ if (!(clazz = env->FindClass("java/lang/ref/WeakReference")) ||
+ !(weakReferenceClass = (jclass) env->NewGlobalRef(clazz)) ||
+ !(weakReferenceConstructorMID = env->GetMethodID(weakReferenceClass,
+ "<init>","(Ljava/lang/Object;)V")) ||
+ !(getReferentMID = env->GetMethodID(weakReferenceClass,
+ "get", "()Ljava/lang/Object;")) ||
+ !(clearReferentMID = env->GetMethodID(weakReferenceClass,
+ "clear", "()V")))
+ {
+ NS_WARNING("Problem creating java.lang.ref.WeakReference globals");
+ goto init_error;
+ }
+
+ if (!(clazz = env->FindClass("org/mozilla/xpcom/internal/JavaXPCOMMethods")) ||
+ !(javaXPCOMUtilsClass = (jclass) env->NewGlobalRef(clazz)) ||
+ !(findClassInLoaderMID = env->GetStaticMethodID(clazz,
+ "findClassInLoader",
+ "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Class;")))
+ {
+ NS_WARNING("Problem creating org.mozilla.xpcom.internal.JavaXPCOMMethods 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
+
+ gNativeToJavaProxyMap = new NativeToJavaProxyMap();
+ if (!gNativeToJavaProxyMap || NS_FAILED(gNativeToJavaProxyMap->Init())) {
+ NS_WARNING("Problem creating NativeToJavaProxyMap");
+ goto init_error;
+ }
+ gJavaToXPTCStubMap = new JavaToXPTCStubMap();
+ if (!gJavaToXPTCStubMap || NS_FAILED(gJavaToXPTCStubMap->Init())) {
+ NS_WARNING("Problem creating JavaToXPTCStubMap");
+ goto init_error;
+ }
+
+ {
+ nsresult rv = NS_OK;
+ PRUint32 size = NS_ARRAY_LENGTH(kJavaKeywords);
+ gJavaKeywords = new nsTHashtable<nsDepCharHashKey>();
+ if (!gJavaKeywords || NS_FAILED(gJavaKeywords->Init(size))) {
+ NS_WARNING("Failed to init JavaKeywords HashSet");
+ goto init_error;
+ }
+ for (PRUint32 i = 0; i < size && NS_SUCCEEDED(rv); i++) {
+ if (!gJavaKeywords->PutEntry(kJavaKeywords[i])) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Failed to populate JavaKeywords hash");
+ goto init_error;
+ }
+ }
+
+ gJavaXPCOMLock = PR_NewLock();
+ gJavaXPCOMInitialized = PR_TRUE;
+ return PR_TRUE;
+
+init_error:
+ // If we encounter an error during initialization, then free any globals that
+ // were allocated, and return false.
+ FreeJavaGlobals(env);
+ return PR_FALSE;
+}
+
+/*************************
+ * FreeJavaGlobals
+ *************************/
+void
+FreeJavaGlobals(JNIEnv* env)
+{
+ PRLock* tempLock = nsnull;
+ if (gJavaXPCOMLock) {
+ PR_Lock(gJavaXPCOMLock);
+
+ // null out global lock so no one else can use it
+ tempLock = gJavaXPCOMLock;
+ gJavaXPCOMLock = nsnull;
+ }
+
+ gJavaXPCOMInitialized = PR_FALSE;
+
+ // Free the mappings first, since that process depends on some of the Java
+ // globals that are freed later.
+ if (gNativeToJavaProxyMap) {
+ gNativeToJavaProxyMap->Destroy(env);
+ delete gNativeToJavaProxyMap;
+ gNativeToJavaProxyMap = nsnull;
+ }
+ if (gJavaToXPTCStubMap) {
+ gJavaToXPTCStubMap->Destroy();
+ delete gJavaToXPTCStubMap;
+ gJavaToXPTCStubMap = nsnull;
+ }
+
+ // Free remaining Java globals
+ if (systemClass) {
+ env->DeleteGlobalRef(systemClass);
+ systemClass = nsnull;
+ }
+ 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;
+ }
+ if (nsISupportsClass) {
+ env->DeleteGlobalRef(nsISupportsClass);
+ nsISupportsClass = nsnull;
+ }
+ if (xpcomExceptionClass) {
+ env->DeleteGlobalRef(xpcomExceptionClass);
+ xpcomExceptionClass = nsnull;
+ }
+ if (xpcomJavaProxyClass) {
+ env->DeleteGlobalRef(xpcomJavaProxyClass);
+ xpcomJavaProxyClass = nsnull;
+ }
+ if (weakReferenceClass) {
+ env->DeleteGlobalRef(weakReferenceClass);
+ weakReferenceClass = nsnull;
+ }
+
+ if (gJavaKeywords) {
+ delete gJavaKeywords;
+ gJavaKeywords = nsnull;
+ }
+
+ if (tempLock) {
+ PR_Unlock(tempLock);
+ PR_DestroyLock(tempLock);
+ }
+}
+
+
+/**************************************
+ * Java<->XPCOM object mappings
+ **************************************/
+
+// NativeToJavaProxyMap: The common case is that each XPCOM object will have
+// one Java proxy. But there are instances where there will be multiple Java
+// proxies for a given XPCOM object, each representing a different interface.
+// So we optimize the common case by using a hash table. Then, if there are
+// multiple Java proxies, we cycle through the linked list, comparing IIDs.
+
+nsresult
+NativeToJavaProxyMap::Init()
+{
+ mHashTable = PL_NewDHashTable(PL_DHashGetStubOps(), nsnull,
+ sizeof(Entry), 16);
+ if (!mHashTable)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+PLDHashOperator
+DestroyJavaProxyMappingEnum(PLDHashTable* aTable, PLDHashEntryHdr* aHeader,
+ PRUint32 aNumber, void* aData)
+{
+ JNIEnv* env = static_cast<JNIEnv*>(aData);
+ NativeToJavaProxyMap::Entry* entry =
+ static_cast<NativeToJavaProxyMap::Entry*>(aHeader);
+
+ // first, delete XPCOM instances from the Java proxies
+ nsresult rv;
+ NativeToJavaProxyMap::ProxyList* item = entry->list;
+ while(item != nsnull) {
+ void* xpcom_obj;
+ jobject javaObject = env->CallObjectMethod(item->javaObject, getReferentMID);
+ rv = GetXPCOMInstFromProxy(env, javaObject, &xpcom_obj);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to get XPCOM instance from Java proxy");
+
+ if (NS_SUCCEEDED(rv)) {
+ JavaXPCOMInstance* inst = static_cast<JavaXPCOMInstance*>(xpcom_obj);
+#ifdef DEBUG_JAVAXPCOM
+ char* iid_str = item->iid.ToString();
+ LOG(("- NativeToJavaProxyMap (Java=%08x | XPCOM=%08x | IID=%s)\n",
+ (PRUint32) env->CallStaticIntMethod(systemClass, hashCodeMID,
+ javaObject),
+ (PRUint32) entry, iid_str));
+ PR_Free(iid_str);
+#endif
+ delete inst; // releases native XPCOM object
+ }
+
+ NativeToJavaProxyMap::ProxyList* next = item->next;
+ env->CallVoidMethod(item->javaObject, clearReferentMID);
+ env->DeleteGlobalRef(item->javaObject);
+ delete item;
+ item = next;
+ }
+
+ return PL_DHASH_REMOVE;
+}
+
+nsresult
+NativeToJavaProxyMap::Destroy(JNIEnv* env)
+{
+ // This is only called from FreeGlobals(), which already holds the lock.
+ // nsAutoLock lock(gJavaXPCOMLock);
+
+ PL_DHashTableEnumerate(mHashTable, DestroyJavaProxyMappingEnum, env);
+ PL_DHashTableDestroy(mHashTable);
+ mHashTable = nsnull;
+
+ return NS_OK;
+}
+
+nsresult
+NativeToJavaProxyMap::Add(JNIEnv* env, nsISupports* aXPCOMObject,
+ const nsIID& aIID, jobject aProxy)
+{
+ nsAutoLock lock(gJavaXPCOMLock);
+
+ Entry* e = static_cast<Entry*>(PL_DHashTableOperate(mHashTable,
+ aXPCOMObject,
+ PL_DHASH_ADD));
+ if (!e)
+ return NS_ERROR_FAILURE;
+
+ jobject ref = nsnull;
+ jobject weakRefObj = env->NewObject(weakReferenceClass,
+ weakReferenceConstructorMID, aProxy);
+ if (weakRefObj)
+ ref = env->NewGlobalRef(weakRefObj);
+ if (!ref)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ // Add Java proxy weak reference ref to start of list
+ ProxyList* item = new ProxyList(ref, aIID, e->list);
+ e->key = aXPCOMObject;
+ e->list = item;
+
+#ifdef DEBUG_JAVAXPCOM
+ char* iid_str = aIID.ToString();
+ LOG(("+ NativeToJavaProxyMap (Java=%08x | XPCOM=%08x | IID=%s)\n",
+ (PRUint32) env->CallStaticIntMethod(systemClass, hashCodeMID, aProxy),
+ (PRUint32) aXPCOMObject, iid_str));
+ PR_Free(iid_str);
+#endif
+ return NS_OK;
+}
+
+nsresult
+NativeToJavaProxyMap::Find(JNIEnv* env, nsISupports* aNativeObject,
+ const nsIID& aIID, jobject* aResult)
+{
+ NS_PRECONDITION(aResult != nsnull, "null ptr");
+ if (!aResult)
+ return NS_ERROR_FAILURE;
+
+ nsAutoLock lock(gJavaXPCOMLock);
+
+ *aResult = nsnull;
+ Entry* e = static_cast<Entry*>(PL_DHashTableOperate(mHashTable,
+ aNativeObject,
+ PL_DHASH_LOOKUP));
+
+ if (PL_DHASH_ENTRY_IS_FREE(e))
+ return NS_OK;
+
+ ProxyList* item = e->list;
+ while (item != nsnull && *aResult == nsnull) {
+ if (item->iid.Equals(aIID)) {
+ jobject referentObj = env->CallObjectMethod(item->javaObject,
+ getReferentMID);
+ if (!env->IsSameObject(referentObj, NULL)) {
+ *aResult = referentObj;
+#ifdef DEBUG_JAVAXPCOM
+ char* iid_str = aIID.ToString();
+ LOG(("< NativeToJavaProxyMap (Java=%08x | XPCOM=%08x | IID=%s)\n",
+ (PRUint32) env->CallStaticIntMethod(systemClass, hashCodeMID,
+ *aResult),
+ (PRUint32) aNativeObject, iid_str));
+ PR_Free(iid_str);
+#endif
+ }
+ }
+ item = item->next;
+ }
+
+ return NS_OK;
+}
+
+nsresult
+NativeToJavaProxyMap::Remove(JNIEnv* env, nsISupports* aNativeObject,
+ const nsIID& aIID)
+{
+ // This is only called from finalizeProxy(), which already holds the lock.
+ // nsAutoLock lock(gJavaXPCOMLock);
+
+ Entry* e = static_cast<Entry*>(PL_DHashTableOperate(mHashTable,
+ aNativeObject,
+ PL_DHASH_LOOKUP));
+
+ if (PL_DHASH_ENTRY_IS_FREE(e)) {
+ NS_WARNING("XPCOM object not found in hash table");
+ return NS_ERROR_FAILURE;
+ }
+
+ ProxyList* item = e->list;
+ ProxyList* last = e->list;
+ while (item != nsnull) {
+ if (item->iid.Equals(aIID)) {
+#ifdef DEBUG_JAVAXPCOM
+ char* iid_str = aIID.ToString();
+ LOG(("- NativeToJavaProxyMap (Java=%08x | XPCOM=%08x | IID=%s)\n",
+ (PRUint32) env->CallStaticIntMethod(systemClass, hashCodeMID,
+ item->javaObject),
+ (PRUint32) aNativeObject, iid_str));
+ PR_Free(iid_str);
+#endif
+
+ env->CallVoidMethod(item->javaObject, clearReferentMID);
+ env->DeleteGlobalRef(item->javaObject);
+ if (item == e->list) {
+ e->list = item->next;
+ if (e->list == nsnull)
+ PL_DHashTableOperate(mHashTable, aNativeObject, PL_DHASH_REMOVE);
+ } else {
+ last->next = item->next;
+ }
+
+ delete item;
+ return NS_OK;
+ }
+
+ last = item;
+ item = item->next;
+ }
+
+ NS_WARNING("Java proxy matching given IID not found");
+ return NS_ERROR_FAILURE;
+}
+
+nsresult
+JavaToXPTCStubMap::Init()
+{
+ mHashTable = PL_NewDHashTable(PL_DHashGetStubOps(), nsnull,
+ sizeof(Entry), 16);
+ if (!mHashTable)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+
+PLDHashOperator
+DestroyXPTCMappingEnum(PLDHashTable* aTable, PLDHashEntryHdr* aHeader,
+ PRUint32 aNumber, void* aData)
+{
+ JavaToXPTCStubMap::Entry* entry =
+ static_cast<JavaToXPTCStubMap::Entry*>(aHeader);
+
+ // The XPTC stub will be released by the XPCOM side, if it hasn't been
+ // already. We just need to delete the Java global ref held by the XPTC stub,
+ // so the Java garbage collector can handle the Java object when necessary.
+ entry->xptcstub->DeleteStrongRef();
+
+ return PL_DHASH_REMOVE;
+}
+
+nsresult
+JavaToXPTCStubMap::Destroy()
+{
+ // This is only called from FreeGlobals(), which already holds the lock.
+ // nsAutoLock lock(gJavaXPCOMLock);
+
+ PL_DHashTableEnumerate(mHashTable, DestroyXPTCMappingEnum, nsnull);
+ PL_DHashTableDestroy(mHashTable);
+ mHashTable = nsnull;
+
+ return NS_OK;
+}
+
+nsresult
+JavaToXPTCStubMap::Add(jint aJavaObjectHashCode, nsJavaXPTCStub* aProxy)
+{
+ nsAutoLock lock(gJavaXPCOMLock);
+
+ Entry* e = static_cast<Entry*>
+ (PL_DHashTableOperate(mHashTable,
+ NS_INT32_TO_PTR(aJavaObjectHashCode),
+ PL_DHASH_ADD));
+ if (!e)
+ return NS_ERROR_FAILURE;
+
+ NS_ASSERTION(e->key == nsnull,
+ "XPTCStub for given Java object already exists in hash table");
+ e->key = aJavaObjectHashCode;
+ e->xptcstub = aProxy;
+
+#ifdef DEBUG_JAVAXPCOM
+ nsIInterfaceInfo* iface_info;
+ aProxy->GetInterfaceInfo(&iface_info);
+ nsIID* iid;
+ iface_info->GetInterfaceIID(&iid);
+ char* iid_str = iid->ToString();
+ LOG(("+ JavaToXPTCStubMap (Java=%08x | XPCOM=%08x | IID=%s)\n",
+ (PRUint32) aJavaObjectHashCode, (PRUint32) aProxy, iid_str));
+ PR_Free(iid_str);
+ nsMemory::Free(iid);
+ NS_RELEASE(iface_info);
+#endif
+ return NS_OK;
+}
+
+nsresult
+JavaToXPTCStubMap::Find(jint aJavaObjectHashCode, const nsIID& aIID,
+ nsJavaXPTCStub** aResult)
+{
+ NS_PRECONDITION(aResult != nsnull, "null ptr");
+ if (!aResult)
+ return NS_ERROR_FAILURE;
+
+ nsAutoLock lock(gJavaXPCOMLock);
+
+ *aResult = nsnull;
+ Entry* e = static_cast<Entry*>
+ (PL_DHashTableOperate(mHashTable,
+ NS_INT32_TO_PTR(aJavaObjectHashCode),
+ PL_DHASH_LOOKUP));
+
+ if (PL_DHASH_ENTRY_IS_FREE(e))
+ return NS_OK;
+
+ nsresult rv = e->xptcstub->QueryInterface(aIID, (void**) aResult);
+
+#ifdef DEBUG_JAVAXPCOM
+ if (NS_SUCCEEDED(rv)) {
+ char* iid_str = aIID.ToString();
+ LOG(("< JavaToXPTCStubMap (Java=%08x | XPCOM=%08x | IID=%s)\n",
+ (PRUint32) aJavaObjectHashCode, (PRUint32) *aResult, iid_str));
+ PR_Free(iid_str);
+ }
+#endif
+
+ // NS_NOINTERFACE is not an error condition
+ if (rv == NS_NOINTERFACE)
+ rv = NS_OK;
+ return rv;
+}
+
+nsresult
+JavaToXPTCStubMap::Remove(jint aJavaObjectHashCode)
+{
+ PL_DHashTableOperate(mHashTable, NS_INT32_TO_PTR(aJavaObjectHashCode),
+ PL_DHASH_REMOVE);
+
+#ifdef DEBUG_JAVAXPCOM
+ LOG(("- JavaToXPTCStubMap (Java=%08x)\n", (PRUint32) aJavaObjectHashCode));
+#endif
+
+ return NS_OK;
+}
+
+
+/**********************************************************
+ * JavaXPCOMInstance
+ *********************************************************/
+JavaXPCOMInstance::JavaXPCOMInstance(nsISupports* aInstance,
+ nsIInterfaceInfo* aIInfo)
+ : mInstance(aInstance)
+ , mIInfo(aIInfo)
+{
+ NS_ADDREF(mInstance);
+ NS_ADDREF(mIInfo);
+}
+
+JavaXPCOMInstance::~JavaXPCOMInstance()
+{
+ nsresult rv = NS_OK;
+
+#ifdef VBOX
+# if 0
+ nsCOMPtr<nsIEventQueue> eq = do_GetMainThreadQueue();
+ rv = NS_ProxyRelease(eq.get(), mInstance);
+ rv |= NS_ProxyRelease(eq.get(), mIInfo);
+# else
+ // The above code crashes in nsTraceRefcntImpl::LogAddCOMPtr() (@bugref 7620)
+ NS_RELEASE(mInstance);
+ NS_RELEASE(mIInfo);
+ rv = NS_OK;
+# endif
+#else
+ // Need to release these objects on the main thread.
+ nsCOMPtr<nsIThread> thread = do_GetMainThread();
+ if (thread) {
+ rv = NS_ProxyRelease(thread, mInstance);
+ rv |= NS_ProxyRelease(thread, mIInfo);
+ }
+#endif
+ NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to release using NS_ProxyRelease");
+}
+
+
+/*******************************
+ * Helper functions
+ *******************************/
+
+nsresult
+NativeInterfaceToJavaObject(JNIEnv* env, nsISupports* aXPCOMObject,
+ const nsIID& aIID, jobject aObjectLoader,
+ jobject* aResult)
+{
+ NS_PRECONDITION(aResult != nsnull, "null ptr");
+ if (!aResult)
+ return NS_ERROR_NULL_POINTER;
+
+ // If the object is an nsJavaXPTCStub, then get the Java object directly
+ nsJavaXPTCStub* stub = nsnull;
+ aXPCOMObject->QueryInterface(NS_GET_IID(nsJavaXPTCStub), (void**) &stub);
+ if (stub) {
+ *aResult = stub->GetJavaObject();
+ NS_ASSERTION(*aResult != nsnull, "nsJavaXPTCStub w/o matching Java object");
+ NS_RELEASE(stub);
+ return NS_OK;
+ }
+
+ // ... else, get a Java wrapper for the native object
+ return GetNewOrUsedJavaWrapper(env, aXPCOMObject, aIID, aObjectLoader,
+ aResult);
+}
+
+nsresult
+JavaObjectToNativeInterface(JNIEnv* env, jobject aJavaObject, const nsIID& aIID,
+ void** aResult)
+{
+ NS_PRECONDITION(aResult != nsnull, "null ptr");
+ if (!aResult)
+ return NS_ERROR_NULL_POINTER;
+
+ nsresult rv;
+ *aResult = nsnull;
+
+ // If the given Java object is one of our Java proxies, then query the
+ // associated XPCOM object directly from the proxy.
+ jboolean isProxy = env->CallStaticBooleanMethod(xpcomJavaProxyClass,
+ isXPCOMJavaProxyMID,
+ aJavaObject);
+ if (env->ExceptionCheck())
+ return NS_ERROR_FAILURE;
+
+ if (isProxy) {
+ void* inst;
+ rv = GetXPCOMInstFromProxy(env, aJavaObject, &inst);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsISupports* rootObject =
+ static_cast<JavaXPCOMInstance*>(inst)->GetInstance();
+ rv = rootObject->QueryInterface(aIID, aResult);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+ }
+
+ // ... else, we get an nsJavaXPTCStub
+ return nsJavaXPTCStub::GetNewOrUsed(env, aJavaObject, aIID, aResult);
+}
+
+nsresult
+GetIIDForMethodParam(nsIInterfaceInfo *iinfo,
+ const XPTMethodDescriptor *methodInfo,
+ const nsXPTParamInfo &paramInfo, PRUint8 paramType,
+ PRUint16 methodIndex, nsXPTCMiniVariant *dispatchParams,
+ PRBool isFullVariantArray, nsID &result)
+{
+ nsresult rv;
+
+ switch (paramType)
+ {
+ case nsXPTType::T_INTERFACE:
+ rv = iinfo->GetIIDForParamNoAlloc(methodIndex, &paramInfo, &result);
+ break;
+
+ case nsXPTType::T_INTERFACE_IS:
+ {
+ PRUint8 argnum;
+ rv = iinfo->GetInterfaceIsArgNumberForParam(methodIndex, &paramInfo,
+ &argnum);
+ if (NS_FAILED(rv))
+ break;
+
+ const nsXPTParamInfo& arg_param = methodInfo->params[argnum];
+ const nsXPTType& arg_type = arg_param.GetType();
+
+ // The xpidl compiler ensures this. We reaffirm it for safety.
+ if (!arg_type.IsPointer() || arg_type.TagPart() != nsXPTType::T_IID) {
+ rv = NS_ERROR_UNEXPECTED;
+ break;
+ }
+
+ nsID *p = nsnull;
+ if (isFullVariantArray) {
+ p = (nsID *) ((nsXPTCVariant*) dispatchParams)[argnum].val.p;
+ } else {
+ p = (nsID *) dispatchParams[argnum].val.p;
+ }
+ if (!p)
+ return NS_ERROR_UNEXPECTED;
+
+ result = *p;
+ break;
+ }
+
+ default:
+ rv = NS_ERROR_UNEXPECTED;
+ }
+ return rv;
+}
+
+
+/*******************************
+ * JNI helper functions
+ *******************************/
+
+JNIEnv*
+GetJNIEnv()
+{
+ JNIEnv* env = nsnull;
+ jint rc = gCachedJVM->GetEnv((void**) &env, JNI_VERSION_1_2);
+#ifdef VBOX
+ if (env == nsnull)
+ {
+ rc = gCachedJVM->AttachCurrentThreadAsDaemon((void**)&env, nsnull);
+ printf("attaching\n");
+ }
+#endif
+ NS_ASSERTION(rc == JNI_OK && env != nsnull,
+ "Current thread not attached to given JVM instance");
+ return env;
+}
+
+void
+ThrowException(JNIEnv* env, const nsresult aErrorCode, const char* aMessage)
+{
+ // Only throw this exception if one hasn't already been thrown, so we don't
+ // mask a previous exception/error.
+ if (env->ExceptionCheck())
+ return;
+
+ // If the error code we get is for an Out Of Memory error, try to throw an
+ // OutOfMemoryError. The JVM may have enough memory to create this error.
+ if (aErrorCode == NS_ERROR_OUT_OF_MEMORY) {
+ jclass clazz = env->FindClass("java/lang/OutOfMemoryError");
+ if (clazz) {
+ env->ThrowNew(clazz, aMessage);
+ }
+ env->DeleteLocalRef(clazz);
+ return;
+ }
+
+ // If the error was not handled above, then create an XPCOMException with the
+ // given error code and message.
+
+ // Create parameters and method signature. Max of 2 params. The error code
+ // comes before the message string.
+ PRInt64 errorCode = aErrorCode ? aErrorCode : NS_ERROR_FAILURE;
+ nsCAutoString methodSig("(J");
+ jstring message = nsnull;
+ if (aMessage) {
+ message = env->NewStringUTF(aMessage);
+ if (!message) {
+ return;
+ }
+ methodSig.AppendLiteral("Ljava/lang/String;");
+ }
+ methodSig.AppendLiteral(")V");
+
+ // In some instances (such as in shutdownXPCOM() and termEmbedding()), we
+ // will need to throw an exception when JavaXPCOM has already been
+ // terminated. In such a case, 'xpcomExceptionClass' will be null. So we
+ // reset it temporarily in order to throw the appropriate exception.
+ if (xpcomExceptionClass == nsnull) {
+ xpcomExceptionClass = env->FindClass("org/mozilla/xpcom/XPCOMException");
+ if (!xpcomExceptionClass) {
+ return;
+ }
+ }
+
+ // create exception object
+ jthrowable throwObj = nsnull;
+ jmethodID mid = env->GetMethodID(xpcomExceptionClass, "<init>",
+ methodSig.get());
+ if (mid) {
+ throwObj = (jthrowable) env->NewObject(xpcomExceptionClass, mid, errorCode,
+ message);
+ }
+ NS_ASSERTION(throwObj, "Failed to create XPCOMException object");
+
+ // throw exception
+ if (throwObj) {
+ env->Throw(throwObj);
+ }
+}
+
+nsAString*
+jstring_to_nsAString(JNIEnv* env, jstring aString)
+{
+ const PRUnichar* buf = nsnull;
+ if (aString) {
+ buf = env->GetStringChars(aString, nsnull);
+ if (!buf)
+ return nsnull; // exception already thrown
+ }
+
+ nsString* str = new nsString(buf);
+
+ if (aString) {
+ env->ReleaseStringChars(aString, buf);
+ } else {
+ str->SetIsVoid(PR_TRUE);
+ }
+
+ // returns string, or nsnull if 'new' failed
+ return str;
+}
+
+nsACString*
+jstring_to_nsACString(JNIEnv* env, jstring aString)
+{
+ const char* buf = nsnull;
+ if (aString) {
+ buf = env->GetStringUTFChars(aString, nsnull);
+ if (!buf)
+ return nsnull; // exception already thrown
+ }
+
+ nsCString* str = new nsCString(buf);
+
+ if (aString) {
+ env->ReleaseStringUTFChars(aString, buf);
+ } else {
+ str->SetIsVoid(PR_TRUE);
+ }
+
+ // returns string, or nsnull if 'new' failed
+ return str;
+}
+
+nsresult
+File_to_nsILocalFile(JNIEnv* env, jobject aFile, nsILocalFile** aLocalFile)
+{
+ nsresult rv = NS_ERROR_FAILURE;
+ jstring pathName = nsnull;
+ jclass clazz = env->FindClass("java/io/File");
+ if (clazz) {
+ jmethodID pathMID = env->GetMethodID(clazz, "getCanonicalPath",
+ "()Ljava/lang/String;");
+ if (pathMID) {
+ pathName = (jstring) env->CallObjectMethod(aFile, pathMID);
+ if (pathName != nsnull && !env->ExceptionCheck())
+ rv = NS_OK;
+ }
+ }
+
+ if (NS_SUCCEEDED(rv)) {
+ nsAString* path = jstring_to_nsAString(env, pathName);
+ if (!path)
+ rv = NS_ERROR_OUT_OF_MEMORY;
+
+ if (NS_SUCCEEDED(rv)) {
+ rv = NS_NewLocalFile(*path, false, aLocalFile);
+ delete path;
+ }
+ }
+
+ return rv;
+}
diff --git a/src/libs/xpcom18a4/java/src/nsJavaXPCOMBindingUtils.h b/src/libs/xpcom18a4/java/src/nsJavaXPCOMBindingUtils.h
new file mode 100644
index 00000000..894a8cb8
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsJavaXPCOMBindingUtils.h
@@ -0,0 +1,392 @@
+/* ***** 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) 2005
+ * 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 ***** */
+
+#ifndef _nsJavaXPCOMBindingUtils_h_
+#define _nsJavaXPCOMBindingUtils_h_
+
+#include "jni.h"
+#include "xptcall.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "pldhash.h"
+#include "nsJavaXPTCStub.h"
+#include "nsAutoLock.h"
+#include "nsTHashtable.h"
+#include "nsHashKeys.h"
+#include "nsILocalFile.h"
+
+//#define DEBUG_JAVAXPCOM
+//#define DEBUG_JAVAXPCOM_REFCNT
+
+#ifdef DEBUG_JAVAXPCOM
+#define LOG(x) printf x
+#else
+#define LOG(x) /* nothing */
+#endif
+
+
+/*********************
+ * Java JNI globals
+ *********************/
+
+extern jclass systemClass;
+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 jclass weakReferenceClass;
+extern jclass javaXPCOMUtilsClass;
+
+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;
+extern jmethodID weakReferenceConstructorMID;
+extern jmethodID getReferentMID;
+extern jmethodID clearReferentMID;
+extern jmethodID findClassInLoaderMID;
+
+#ifdef DEBUG_JAVAXPCOM
+extern jmethodID getNameMID;
+extern jmethodID proxyToStringMID;
+#endif
+
+class NativeToJavaProxyMap;
+extern NativeToJavaProxyMap* gNativeToJavaProxyMap;
+class JavaToXPTCStubMap;
+extern JavaToXPTCStubMap* gJavaToXPTCStubMap;
+
+extern nsTHashtable<nsDepCharHashKey>* gJavaKeywords;
+
+// The Java garbage collector runs in a separate thread. Since it calls the
+// finalizeProxy() function in nsJavaWrapper.cpp, we need to make sure that
+// all the structures touched by finalizeProxy() are multithread aware.
+extern PRLock* gJavaXPCOMLock;
+
+extern PRBool gJavaXPCOMInitialized;
+
+/**
+ * Initialize global structures used by JavaXPCOM.
+ * @param env Java environment pointer
+ * @return PR_TRUE if JavaXPCOM is initialized; PR_FALSE if an error occurred
+ */
+PRBool InitializeJavaGlobals(JNIEnv *env);
+
+/**
+ * Frees global structures that were allocated by InitializeJavaGlobals().
+ * @param env Java environment pointer
+ */
+void FreeJavaGlobals(JNIEnv* env);
+
+
+/*************************
+ * JavaXPCOMInstance
+ *************************/
+
+class JavaXPCOMInstance
+{
+public:
+ JavaXPCOMInstance(nsISupports* aInstance, nsIInterfaceInfo* aIInfo);
+ ~JavaXPCOMInstance();
+
+ nsISupports* GetInstance() { return mInstance; }
+ nsIInterfaceInfo* InterfaceInfo() { return mIInfo; }
+
+private:
+ nsISupports* mInstance;
+ nsIInterfaceInfo* mIInfo;
+};
+
+
+/**************************************
+ * Java<->XPCOM object mappings
+ **************************************/
+
+/**
+ * Maps native XPCOM objects to their associated Java proxy object.
+ */
+class NativeToJavaProxyMap
+{
+ friend PLDHashOperator DestroyJavaProxyMappingEnum(PLDHashTable* aTable,
+ PLDHashEntryHdr* aHeader,
+ PRUint32 aNumber,
+ void* aData);
+
+protected:
+ struct ProxyList
+ {
+ ProxyList(const jobject aRef, const nsIID& aIID, ProxyList* aList)
+ : javaObject(aRef)
+ , iid(aIID)
+ , next(aList)
+ { }
+
+ const jobject javaObject;
+ const nsIID iid;
+ ProxyList* next;
+ };
+
+ struct Entry : public PLDHashEntryHdr
+ {
+ nsISupports* key;
+ ProxyList* list;
+ };
+
+public:
+ NativeToJavaProxyMap()
+ : mHashTable(nsnull)
+ { }
+
+ ~NativeToJavaProxyMap()
+ {
+ NS_ASSERTION(mHashTable == nsnull,
+ "MUST call Destroy() before deleting object");
+ }
+
+ nsresult Init();
+
+ nsresult Destroy(JNIEnv* env);
+
+ nsresult Add(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
+ jobject aProxy);
+
+ nsresult Find(JNIEnv* env, nsISupports* aNativeObject, const nsIID& aIID,
+ jobject* aResult);
+
+ nsresult Remove(JNIEnv* env, nsISupports* aNativeObject, const nsIID& aIID);
+
+protected:
+ PLDHashTable* mHashTable;
+};
+
+/**
+ * Maps Java objects to their associated nsJavaXPTCStub.
+ */
+class JavaToXPTCStubMap
+{
+ friend PLDHashOperator DestroyXPTCMappingEnum(PLDHashTable* aTable,
+ PLDHashEntryHdr* aHeader,
+ PRUint32 aNumber, void* aData);
+
+protected:
+ struct Entry : public PLDHashEntryHdr
+ {
+ jint key;
+ nsJavaXPTCStub* xptcstub;
+ };
+
+public:
+ JavaToXPTCStubMap()
+ : mHashTable(nsnull)
+ { }
+
+ ~JavaToXPTCStubMap()
+ {
+ NS_ASSERTION(mHashTable == nsnull,
+ "MUST call Destroy() before deleting object");
+ }
+
+ nsresult Init();
+
+ nsresult Destroy();
+
+ nsresult Add(jint aJavaObjectHashCode, nsJavaXPTCStub* aProxy);
+
+ nsresult Find(jint aJavaObjectHashCode, const nsIID& aIID,
+ nsJavaXPTCStub** aResult);
+
+ nsresult Remove(jint aJavaObjectHashCode);
+
+protected:
+ PLDHashTable* mHashTable;
+};
+
+
+/*******************************
+ * Helper functions
+ *******************************/
+
+/**
+ * Convert a native nsISupports to a Java object.
+ *
+ * @param env Java environment pointer
+ * @param aXPCOMObject XPCOM object for which to find/create Java object
+ * @param aIID desired interface IID for Java object
+ * @param aObjectLoader Java object whose class loader we use for finding
+ * classes; can be null
+ * @param aResult on success, holds reference to Java object
+ *
+ * @return NS_OK if succeeded; all other return values are error codes.
+ */
+nsresult NativeInterfaceToJavaObject(JNIEnv* env, nsISupports* aXPCOMObject,
+ const nsIID& aIID, jobject aObjectLoader,
+ jobject* aResult);
+
+/**
+ * Convert a Java object to a native nsISupports object.
+ *
+ * @param env Java environment pointer
+ * @param aJavaObject Java object for which to find/create XPCOM object
+ * @param aIID desired interface IID for XPCOM object
+ * @param aResult on success, holds AddRef'd reference to XPCOM object
+ *
+ * @return NS_OK if succeeded; all other return values are error codes.
+ */
+nsresult JavaObjectToNativeInterface(JNIEnv* env, jobject aJavaObject,
+ const nsIID& aIID, void** aResult);
+
+nsresult GetIIDForMethodParam(nsIInterfaceInfo *iinfo,
+ const XPTMethodDescriptor *methodInfo,
+ const nsXPTParamInfo &paramInfo,
+ PRUint8 paramType, PRUint16 methodIndex,
+ nsXPTCMiniVariant *dispatchParams,
+ PRBool isFullVariantArray,
+ nsID &result);
+
+/**
+ * Returns the Class object associated with the class or interface with the
+ * given string name, using the class loader of the given object.
+ *
+ * @param env Java environment pointer
+ * @param aObjectLoader Java object whose class loader is used to load class
+ * @param aClassName fully qualified name of class to load
+ *
+ * @return java.lang.Class object of requested Class; NULL if the class
+ * wasn't found
+ *
+ * @see http://java.sun.com/j2se/1.3/docs/guide/jni/jni-12.html#classops
+ */
+inline jclass
+FindClassInLoader(JNIEnv* env, jobject aObjectLoader, const char* aClassName)
+{
+ jclass clazz = nsnull;
+ jstring name = env->NewStringUTF(aClassName);
+ if (name)
+ clazz = (jclass) env->CallStaticObjectMethod(javaXPCOMUtilsClass,
+ findClassInLoaderMID, aObjectLoader, name);
+
+#ifdef DEBUG
+ if (!clazz)
+ fprintf(stderr, "WARNING: failed to find class [%s]\n", aClassName);
+#endif
+ return clazz;
+}
+
+
+/*******************************
+ * JNI helper functions
+ *******************************/
+
+/**
+ * Returns a pointer to the appropriate JNIEnv structure. This function is
+ * useful in callbacks or other functions that are not called directly from
+ * Java and therefore do not have the JNIEnv structure passed in.
+ *
+ * @return pointer to JNIEnv structure for current thread
+ */
+JNIEnv* GetJNIEnv();
+
+/**
+ * Constructs and throws an exception. Some error codes (such as
+ * NS_ERROR_OUT_OF_MEMORY) are handled by the appropriate Java exception/error.
+ * Otherwise, an instance of XPCOMException is created with the given error
+ * code and message.
+ *
+ * @param env Java environment pointer
+ * @param aErrorCode The error code returned by an XPCOM/Gecko function. Pass
+ * zero for the default behaviour.
+ * @param aMessage A string that provides details for throwing this
+ * exception. Pass in <code>nsnull</code> for the default
+ * behaviour.
+ *
+ * @throws OutOfMemoryError if aErrorCode == NS_ERROR_OUT_OF_MEMORY
+ * XPCOMException for all other error codes
+ */
+void ThrowException(JNIEnv* env, const nsresult aErrorCode,
+ const char* aMessage);
+
+/**
+ * Helper functions for converting from java.lang.String to
+ * nsAString/nsACstring. Caller must delete nsAString/nsACString.
+ *
+ * @param env Java environment pointer
+ * @param aString Java string to convert
+ *
+ * @return nsAString/nsACString with same content as given Java string;
+ * a 'void' nsAString/nsACString object if aString is
+ * <code>null</code>; or <code>nsnull</code> if out of memory
+ */
+nsAString* jstring_to_nsAString(JNIEnv* env, jstring aString);
+nsACString* jstring_to_nsACString(JNIEnv* env, jstring aString);
+
+/**
+ * Helper function for converting from java.io.File to nsILocalFile.
+ *
+ * @param env Java environment pointer
+ * @param aFile Java File to convert
+ * @param aLocalFile returns the converted nsILocalFile
+ *
+ * @return NS_OK for success; other values indicate error in conversion
+ */
+nsresult File_to_nsILocalFile(JNIEnv* env, jobject aFile,
+ nsILocalFile** aLocalFile);
+
+#endif // _nsJavaXPCOMBindingUtils_h_
diff --git a/src/libs/xpcom18a4/java/src/nsJavaXPCOMGlue.cpp b/src/libs/xpcom18a4/java/src/nsJavaXPCOMGlue.cpp
new file mode 100644
index 00000000..b0b6b72c
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsJavaXPCOMGlue.cpp
@@ -0,0 +1,535 @@
+/* ***** 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) 2006
+ * 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 ***** */
+
+#include "jni.h"
+#include "nsXPCOMPrivate.h" // for XPCOM_DLL defines.
+#include "nsXPCOMGlue.h"
+#include <stdlib.h>
+
+
+#ifdef VBOX
+#include <string.h>
+#include "nsDebug.h"
+#endif
+
+#if defined(XP_WIN) || defined(XP_OS2)
+#define JX_EXPORT JNIEXPORT
+#else
+#define JX_EXPORT JNIEXPORT NS_EXPORT
+#endif
+
+
+/***********************
+ * JNI Load & Unload
+ ***********************/
+
+extern "C" JX_EXPORT jint JNICALL
+JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+ // Let the JVM know that we are using JDK 1.2 JNI features.
+ return JNI_VERSION_1_2;
+}
+
+extern "C" JX_EXPORT void JNICALL
+JNI_OnUnload(JavaVM* vm, void* reserved)
+{
+}
+
+/********************************
+ * JavaXPCOM JNI interfaces
+ ********************************/
+
+#define JXM_NATIVE(func) Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_##func
+
+enum {
+ kFunc_Initialize,
+ kFunc_InitEmbedding,
+ kFunc_TermEmbedding,
+ kFunc_LockProfileDirectory,
+ kFunc_NotifyProfile,
+ kFunc_InitXPCOM,
+ kFunc_ShutdownXPCOM,
+ kFunc_GetComponentManager,
+ kFunc_GetComponentRegistrar,
+ kFunc_GetServiceManager,
+ kFunc_NewLocalFile,
+ kFunc_CallXPCOMMethod,
+ kFunc_FinalizeProxy,
+ kFunc_IsSameXPCOMObject,
+ kFunc_ReleaseProfileLock,
+ kFunc_GetNativeHandleFromAWT,
+ kFunc_WrapJavaObject,
+ kFunc_WrapXPCOMObject
+};
+
+#define JX_NUM_FUNCS 18
+
+
+// Get path string from java.io.File object.
+jstring
+GetJavaFilePath(JNIEnv* env, jobject aFile)
+{
+ jclass clazz = env->FindClass("java/io/File");
+ if (clazz) {
+ jmethodID pathMID = env->GetMethodID(clazz, "getCanonicalPath",
+ "()Ljava/lang/String;");
+ if (pathMID) {
+ return (jstring) env->CallObjectMethod(aFile, pathMID);
+ }
+ }
+
+ return nsnull;
+}
+#ifdef VBOX
+
+#include "nsXPTCUtils.h"
+#include "nsCOMPtr.h"
+#include "nsIInterfaceInfoManager.h"
+#include "nsJavaInterfaces.h"
+
+void
+ThrowException(JNIEnv* env, const nsresult aErrorCode, const char* aMessage);
+
+class nsXPTCJStub : public nsXPTCStubBase
+{
+ nsCOMPtr<nsIInterfaceInfo> mII;
+ nsIXPTCProxy* mOuter;
+ public:
+ NS_DECL_ISUPPORTS_INHERITED
+
+ nsXPTCJStub(REFNSIID aIID, nsIXPTCProxy* aOuter, nsIInterfaceInfo* ii)
+ {
+ mOuter = aOuter;
+ mII = ii;
+ }
+
+ virtual ~nsXPTCJStub()
+ {
+ }
+
+ NS_IMETHOD GetInterfaceInfo(nsIInterfaceInfo** info)
+ {
+ *info = mII;
+ (*info)->AddRef();
+ return NS_OK;
+ }
+ // call this method and return result
+ NS_IMETHOD CallMethod(PRUint16 methodIndex,
+ const nsXPTMethodInfo* info,
+ nsXPTCMiniVariant* params)
+ {
+ return mOuter->CallMethod(methodIndex, info, params);
+ }
+};
+
+NS_IMETHODIMP_(nsrefcnt)
+nsXPTCJStub::AddRef()
+{
+ return mOuter->AddRef();
+}
+
+NS_IMETHODIMP_(nsrefcnt)
+nsXPTCJStub::Release()
+{
+ return mOuter->Release();
+}
+
+NS_IMETHODIMP nsXPTCJStub::QueryInterface(REFNSIID aIID, void** aInstancePtr)
+{
+ nsIID* mIID;
+ mII->GetInterfaceIID(&mIID);
+
+ if (mIID->Equals(aIID)) {
+ NS_ADDREF_THIS();
+ *aInstancePtr = static_cast<nsISupports*>(this);
+ return NS_OK;
+ }
+
+ return mOuter->QueryInterface(aIID, aInstancePtr);
+}
+
+nsresult
+NS_GetXPTCallStub(REFNSIID aIID, nsIXPTCProxy* aOuter,
+ nsISomeInterface* *aResult)
+{
+ NS_ENSURE_ARG(aOuter && aResult);
+#if 0
+ xptiInterfaceInfoManager *iim =
+ xptiInterfaceInfoManager::GetInterfaceInfoManagerNoAddRef();
+ NS_ENSURE_TRUE(iim, NS_ERROR_NOT_INITIALIZED);
+
+ xptiInterfaceEntry *iie = iim->GetInterfaceEntryForIID(&aIID);
+ if (!iie || !iie->EnsureResolved())
+ return NS_ERROR_FAILURE;
+
+ nsXPTCStubBase* newbase = new nsXPTCStubBase(aOuter, iie);
+ if (!newbase)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ *aResult = newbase;
+#else
+ nsCOMPtr<nsIInterfaceInfoManager> iim = XPTI_GetInterfaceInfoManager();
+ nsCOMPtr<nsIInterfaceInfo> ii;
+ nsresult rv;
+
+ rv = iim->GetInfoForIID(&aIID, getter_AddRefs(ii));
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsXPTCStubBase* newbase = new nsXPTCJStub(aIID, aOuter, ii);
+ if (!newbase)
+ return NS_ERROR_OUT_OF_MEMORY;
+ *aResult = newbase;
+#endif
+ return NS_OK;
+}
+
+void
+NS_DestroyXPTCallStub(nsISomeInterface* aStub)
+{
+ nsXPTCStubBase* stub = static_cast<nsXPTCStubBase*>(aStub);
+ delete(stub);
+}
+
+
+extern "C" void JAVAPROXY_NATIVE(finalizeProxy)(JNIEnv *env, jclass that, jobject aJavaProxy);
+
+nsresult
+FindVBoxMethods(JNIEnv* env, jobject aXPCOMPath, void** aFunctions)
+{
+ nsresult rv = 0;
+
+ // We only need to care about this function because the C function we offer
+ // is different from what the Java side expects
+ aFunctions[kFunc_FinalizeProxy] = (void*)JAVAPROXY_NATIVE(finalizeProxy);
+
+ return rv;
+}
+#else
+// Calls XPCOMGlueStartup using the given java.io.File object, and loads
+// the JavaXPCOM methods from the XUL shared library.
+nsresult
+LoadXULMethods(JNIEnv* env, jobject aXPCOMPath, void** aFunctions)
+{
+ jstring pathString = GetJavaFilePath(env, aXPCOMPath);
+ if (!pathString)
+ return NS_ERROR_FAILURE;
+ const char* path = env->GetStringUTFChars(pathString, nsnull);
+ if (!path)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ int len = strlen(path);
+ char* xpcomPath = (char*) malloc(len + sizeof(XPCOM_DLL) +
+ sizeof(XPCOM_FILE_PATH_SEPARATOR) + 1);
+ if (!xpcomPath)
+ return NS_ERROR_OUT_OF_MEMORY;
+ sprintf(xpcomPath, "%s" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, path);
+
+ nsresult rv = XPCOMGlueStartup(xpcomPath);
+ free(xpcomPath);
+ if (NS_FAILED(rv))
+ return rv;
+
+#ifdef XP_WIN32
+ // The JNICALL calling convention defines to "__stdcall" on Win32, which
+ // mangles the name.
+ nsDynamicFunctionLoad funcs[] = {
+ { "_Java_org_mozilla_xpcom_internal_MozillaImpl_initialize@8",
+ (NSFuncPtr*) &aFunctions[kFunc_Initialize] },
+ { "_Java_org_mozilla_xpcom_internal_GREImpl_initEmbedding@20",
+ (NSFuncPtr*) &aFunctions[kFunc_InitEmbedding] },
+ { "_Java_org_mozilla_xpcom_internal_GREImpl_termEmbedding@8",
+ (NSFuncPtr*) &aFunctions[kFunc_TermEmbedding] },
+ { "_Java_org_mozilla_xpcom_internal_GREImpl_lockProfileDirectory@12",
+ (NSFuncPtr*) &aFunctions[kFunc_LockProfileDirectory] },
+ { "_Java_org_mozilla_xpcom_internal_GREImpl_notifyProfile@8",
+ (NSFuncPtr*) &aFunctions[kFunc_NotifyProfile] },
+ { "_Java_org_mozilla_xpcom_internal_XPCOMImpl_initXPCOM@16",
+ (NSFuncPtr*) &aFunctions[kFunc_InitXPCOM] },
+ { "_Java_org_mozilla_xpcom_internal_XPCOMImpl_shutdownXPCOM@12",
+ (NSFuncPtr*) &aFunctions[kFunc_ShutdownXPCOM] },
+ { "_Java_org_mozilla_xpcom_internal_XPCOMImpl_getComponentManager@8",
+ (NSFuncPtr*) &aFunctions[kFunc_GetComponentManager] },
+ { "_Java_org_mozilla_xpcom_internal_XPCOMImpl_getComponentRegistrar@8",
+ (NSFuncPtr*) &aFunctions[kFunc_GetComponentRegistrar] },
+ { "_Java_org_mozilla_xpcom_internal_XPCOMImpl_getServiceManager@8",
+ (NSFuncPtr*) &aFunctions[kFunc_GetServiceManager] },
+ { "_Java_org_mozilla_xpcom_internal_XPCOMImpl_newLocalFile@16",
+ (NSFuncPtr*) &aFunctions[kFunc_NewLocalFile] },
+ { "_Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_callXPCOMMethod@20",
+ (NSFuncPtr*) &aFunctions[kFunc_CallXPCOMMethod] },
+ { "_Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_finalizeProxy@12",
+ (NSFuncPtr*) &aFunctions[kFunc_FinalizeProxy] },
+ { "_Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_isSameXPCOMObject@16",
+ (NSFuncPtr*) &aFunctions[kFunc_IsSameXPCOMObject] },
+ { "_Java_org_mozilla_xpcom_ProfileLock_release@16",
+ (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@20",
+ (NSFuncPtr*) &aFunctions[kFunc_WrapXPCOMObject] },
+ { nsnull, nsnull }
+ };
+#else
+ nsDynamicFunctionLoad funcs[] = {
+ { "Java_org_mozilla_xpcom_internal_MozillaImpl_initialize",
+ (NSFuncPtr*) &aFunctions[kFunc_Initialize] },
+ { "Java_org_mozilla_xpcom_internal_GREImpl_initEmbedding",
+ (NSFuncPtr*) &aFunctions[kFunc_InitEmbedding] },
+ { "Java_org_mozilla_xpcom_internal_GREImpl_termEmbedding",
+ (NSFuncPtr*) &aFunctions[kFunc_TermEmbedding] },
+ { "Java_org_mozilla_xpcom_internal_GREImpl_lockProfileDirectory",
+ (NSFuncPtr*) &aFunctions[kFunc_LockProfileDirectory] },
+ { "Java_org_mozilla_xpcom_internal_GREImpl_notifyProfile",
+ (NSFuncPtr*) &aFunctions[kFunc_NotifyProfile] },
+ { "Java_org_mozilla_xpcom_internal_XPCOMImpl_initXPCOM",
+ (NSFuncPtr*) &aFunctions[kFunc_InitXPCOM] },
+ { "Java_org_mozilla_xpcom_internal_XPCOMImpl_shutdownXPCOM",
+ (NSFuncPtr*) &aFunctions[kFunc_ShutdownXPCOM] },
+ { "Java_org_mozilla_xpcom_internal_XPCOMImpl_getComponentManager",
+ (NSFuncPtr*) &aFunctions[kFunc_GetComponentManager] },
+ { "Java_org_mozilla_xpcom_internal_XPCOMImpl_getComponentRegistrar",
+ (NSFuncPtr*) &aFunctions[kFunc_GetComponentRegistrar] },
+ { "Java_org_mozilla_xpcom_internal_XPCOMImpl_getServiceManager",
+ (NSFuncPtr*) &aFunctions[kFunc_GetServiceManager] },
+ { "Java_org_mozilla_xpcom_internal_XPCOMImpl_newLocalFile",
+ (NSFuncPtr*) &aFunctions[kFunc_NewLocalFile] },
+ { "Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_callXPCOMMethod",
+ (NSFuncPtr*) &aFunctions[kFunc_CallXPCOMMethod] },
+ { "Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_finalizeProxy",
+ (NSFuncPtr*) &aFunctions[kFunc_FinalizeProxy] },
+ { "Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_isSameXPCOMObject",
+ (NSFuncPtr*) &aFunctions[kFunc_IsSameXPCOMObject] },
+ { "Java_org_mozilla_xpcom_ProfileLock_release",
+ (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
+
+ rv = XPCOMGlueLoadXULFunctions(funcs);
+ if (NS_FAILED(rv))
+ return rv;
+
+ return NS_OK;
+}
+
+void
+ThrowException(JNIEnv* env, const nsresult aErrorCode, const char* aMessage)
+{
+ // Only throw this exception if one hasn't already been thrown, so we don't
+ // mask a previous exception/error.
+ if (env->ExceptionCheck())
+ return;
+
+ // If the error code we get is for an Out Of Memory error, try to throw an
+ // OutOfMemoryError. The JVM may have enough memory to create this error.
+ if (aErrorCode == NS_ERROR_OUT_OF_MEMORY) {
+ jclass clazz = env->FindClass("java/lang/OutOfMemoryError");
+ if (clazz) {
+ env->ThrowNew(clazz, aMessage);
+ }
+ env->DeleteLocalRef(clazz);
+ return;
+ }
+
+ // If the error was not handled above, then create an XPCOMException with the
+ // given error code.
+ jthrowable throwObj = nsnull;
+ jclass exceptionClass = env->FindClass("org/mozilla/xpcom/XPCOMException");
+ if (exceptionClass) {
+ jmethodID mid = env->GetMethodID(exceptionClass, "<init>",
+ "(JLjava/lang/String;)V");
+ if (mid) {
+ throwObj = (jthrowable) env->NewObject(exceptionClass, mid,
+ (PRInt64) aErrorCode,
+ env->NewStringUTF(aMessage));
+ }
+ }
+ NS_ASSERTION(throwObj, "Failed to create XPCOMException object");
+
+ // throw exception
+ if (throwObj) {
+ env->Throw(throwObj);
+ }
+}
+#endif // VBOX
+
+// Register the JavaXPCOM native methods. This associates a native Java
+// method with its C implementation.
+nsresult
+RegisterNativeMethods(JNIEnv* env, void** aFunctions)
+{
+ JNINativeMethod mozilla_methods[] = {
+ { "initializeNative", "()V",
+ (void*) aFunctions[kFunc_Initialize] },
+ { "getNativeHandleFromAWT", "(Ljava/lang/Object;)J",
+ (void*) aFunctions[kFunc_GetNativeHandleFromAWT] }
+ };
+
+ JNINativeMethod gre_methods[] = {
+ { "initEmbeddingNative",
+ "(Ljava/io/File;Ljava/io/File;Lorg/mozilla/xpcom/IAppFileLocProvider;)V",
+ (void*) aFunctions[kFunc_InitEmbedding] },
+ { "termEmbedding", "()V",
+ (void*) aFunctions[kFunc_TermEmbedding] },
+ { "lockProfileDirectory", "(Ljava/io/File;)Lorg/mozilla/xpcom/ProfileLock;",
+ (void*) aFunctions[kFunc_LockProfileDirectory] },
+ { "notifyProfile", "()V",
+ (void*) aFunctions[kFunc_NotifyProfile] },
+ };
+
+ JNINativeMethod xpcom_methods[] = {
+ { "initXPCOMNative",
+ "(Ljava/io/File;Lorg/mozilla/xpcom/IAppFileLocProvider;)Lorg/mozilla/interfaces/nsIServiceManager;",
+ (void*) aFunctions[kFunc_InitXPCOM] },
+ { "shutdownXPCOM", "(Lorg/mozilla/interfaces/nsIServiceManager;)V",
+ (void*) aFunctions[kFunc_ShutdownXPCOM] },
+ { "getComponentManager", "()Lorg/mozilla/interfaces/nsIComponentManager;",
+ (void*) aFunctions[kFunc_GetComponentManager] },
+ { "getComponentRegistrar", "()Lorg/mozilla/interfaces/nsIComponentRegistrar;",
+ (void*) aFunctions[kFunc_GetComponentRegistrar] },
+ { "getServiceManager", "()Lorg/mozilla/interfaces/nsIServiceManager;",
+ (void*) aFunctions[kFunc_GetServiceManager] },
+ { "newLocalFile", "(Ljava/lang/String;Z)Lorg/mozilla/interfaces/nsILocalFile;",
+ (void*) aFunctions[kFunc_NewLocalFile] }
+ };
+
+ JNINativeMethod proxy_methods[] = {
+ { "callXPCOMMethod",
+ "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;",
+ (void*) aFunctions[kFunc_CallXPCOMMethod] },
+ { "finalizeProxyNative", "(Ljava/lang/Object;)V",
+ (void*) aFunctions[kFunc_FinalizeProxy] },
+ { "isSameXPCOMObject", "(Ljava/lang/Object;Ljava/lang/Object;)Z",
+ (void*) aFunctions[kFunc_IsSameXPCOMObject] }
+ };
+
+ 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) {
+ rc = env->RegisterNatives(clazz, mozilla_methods,
+ sizeof(mozilla_methods) / sizeof(mozilla_methods[0]));
+ }
+ NS_ENSURE_TRUE(rc == 0, NS_ERROR_FAILURE);
+
+ rc = -1;
+ clazz = env->FindClass("org/mozilla/xpcom/internal/GREImpl");
+ if (clazz) {
+ rc = env->RegisterNatives(clazz, gre_methods,
+ sizeof(gre_methods) / sizeof(gre_methods[0]));
+ }
+ NS_ENSURE_TRUE(rc == 0, NS_ERROR_FAILURE);
+
+ rc = -1;
+ clazz = env->FindClass("org/mozilla/xpcom/internal/XPCOMImpl");
+ if (clazz) {
+ rc = env->RegisterNatives(clazz, xpcom_methods,
+ sizeof(xpcom_methods) / sizeof(xpcom_methods[0]));
+ }
+ NS_ENSURE_TRUE(rc == 0, NS_ERROR_FAILURE);
+
+ rc = -1;
+ clazz = env->FindClass("org/mozilla/xpcom/internal/XPCOMJavaProxy");
+ if (clazz) {
+ rc = env->RegisterNatives(clazz, proxy_methods,
+ sizeof(proxy_methods) / sizeof(proxy_methods[0]));
+ }
+ NS_ENSURE_TRUE(rc == 0, NS_ERROR_FAILURE);
+
+ rc = -1;
+ clazz = env->FindClass("org/mozilla/xpcom/ProfileLock");
+ if (clazz) {
+ rc = env->RegisterNatives(clazz, lockProxy_methods,
+ sizeof(lockProxy_methods) / sizeof(lockProxy_methods[0]));
+ }
+ 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;
+}
+
+// Load the JavaXPCOM methods from the XUL shared library, and registers them
+// as Java native methods.
+extern "C" JX_EXPORT void JNICALL
+JXM_NATIVE(registerJavaXPCOMMethodsNative) (JNIEnv *env, jclass that,
+ jobject aXPCOMPath)
+{
+ void* functions[JX_NUM_FUNCS];
+ memset(functions, 0, JX_NUM_FUNCS * sizeof(void*));
+
+#ifdef VBOX
+ nsresult rv = FindVBoxMethods(env, aXPCOMPath, functions);
+ if (NS_SUCCEEDED(rv)) {
+ rv = RegisterNativeMethods(env, functions);
+ }
+#else
+ nsresult rv = LoadXULMethods(env, aXPCOMPath, functions);
+ if (NS_SUCCEEDED(rv)) {
+ rv = RegisterNativeMethods(env, functions);
+ }
+#endif
+
+ if (NS_FAILED(rv)) {
+ ThrowException(env, rv, "Failed to register JavaXPCOM methods");
+ }
+}
diff --git a/src/libs/xpcom18a4/java/src/nsJavaXPTCStub.cpp b/src/libs/xpcom18a4/java/src/nsJavaXPTCStub.cpp
new file mode 100644
index 00000000..c8136ec4
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsJavaXPTCStub.cpp
@@ -0,0 +1,1711 @@
+/* ***** 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) 2005
+ * 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 ***** */
+
+#include "nsJavaXPTCStub.h"
+#include "nsJavaWrapper.h"
+#include "nsJavaXPCOMBindingUtils.h"
+#include "prmem.h"
+#include "nsIInterfaceInfoManager.h"
+#include "nsString.h"
+#include "nsString.h"
+#include "nsCRT.h"
+#include "nsServiceManagerUtils.h"
+
+
+nsJavaXPTCStub::nsJavaXPTCStub(jobject aJavaObject, nsIInterfaceInfo *aIInfo,
+ nsresult *rv)
+ : mJavaStrongRef(nsnull)
+ , mIInfo(aIInfo)
+ , mMaster(nsnull)
+ , mWeakRefCnt(0)
+{
+ const nsIID *iid = nsnull;
+ aIInfo->GetIIDShared(&iid);
+ NS_ASSERTION(iid, "GetIIDShared must not fail!");
+
+ *rv = InitStub(*iid);
+ if (NS_FAILED(*rv))
+ return;
+
+ JNIEnv* env = GetJNIEnv();
+ jobject weakref = env->NewObject(weakReferenceClass,
+ weakReferenceConstructorMID, aJavaObject);
+ mJavaWeakRef = env->NewGlobalRef(weakref);
+ mJavaRefHashCode = env->CallStaticIntMethod(systemClass, hashCodeMID,
+ aJavaObject);
+
+#ifdef DEBUG_JAVAXPCOM
+ char* iid_str = iid->ToString();
+ LOG(("+ nsJavaXPTCStub (Java=%08x | XPCOM=%08x | IID=%s)\n",
+ (PRUint32) mJavaRefHashCode, (PRUint32) this, iid_str));
+ PR_Free(iid_str);
+#endif
+}
+
+nsJavaXPTCStub::~nsJavaXPTCStub()
+{
+}
+
+NS_IMETHODIMP_(nsrefcnt)
+nsJavaXPTCStub::AddRefInternal()
+{
+ // If this is the first AddRef call, we create a strong global ref to the
+ // Java object to keep it from being garbage collected.
+ if (mRefCnt == 0) {
+ JNIEnv* env = GetJNIEnv();
+ jobject referent = env->CallObjectMethod(mJavaWeakRef, getReferentMID);
+ if (!env->IsSameObject(referent, NULL)) {
+ mJavaStrongRef = env->NewGlobalRef(referent);
+ }
+ NS_ASSERTION(mJavaStrongRef != nsnull, "Failed to acquire strong ref");
+ }
+
+ // if this is the master interface
+ NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
+ NS_ASSERT_OWNINGTHREAD(nsJavaXPTCStub);
+ ++mRefCnt;
+ NS_LOG_ADDREF(this, mRefCnt, "nsJavaXPTCStub", sizeof(*this));
+ return mRefCnt;
+}
+
+NS_IMETHODIMP_(nsrefcnt)
+nsJavaXPTCStub::AddRef()
+{
+#ifdef DEBUG_JAVAXPCOM_REFCNT
+ nsIID* iid;
+ mIInfo->GetInterfaceIID(&iid);
+ char* iid_str = iid->ToString();
+ int refcnt = PRInt32(mMaster ? mMaster->mRefCnt : mRefCnt) + 1;
+ LOG(("= nsJavaXPTCStub::AddRef (XPCOM=%08x | refcnt = %d | IID=%s)\n",
+ (int) this, refcnt, iid_str));
+ PR_Free(iid_str);
+ nsMemory::Free(iid);
+#endif
+
+ nsJavaXPTCStub* master = mMaster ? mMaster : this;
+ return master->AddRefInternal();
+}
+
+NS_IMETHODIMP_(nsrefcnt)
+nsJavaXPTCStub::ReleaseInternal()
+{
+ NS_PRECONDITION(0 != mRefCnt, "dup release");
+ NS_ASSERT_OWNINGTHREAD(nsJavaXPTCStub);
+ --mRefCnt;
+ NS_LOG_RELEASE(this, mRefCnt, "nsJavaXPTCStub");
+ if (mRefCnt == 0) {
+ // delete strong ref; allows Java object to be garbage collected
+ DeleteStrongRef();
+
+ // If we have a weak ref, we don't delete this object.
+ if (mWeakRefCnt == 0) {
+ mRefCnt = 1; /* stabilize */
+ Destroy();
+ delete this;
+ }
+ return 0;
+ }
+ return mRefCnt;
+}
+
+NS_IMETHODIMP_(nsrefcnt)
+nsJavaXPTCStub::Release()
+{
+#ifdef DEBUG_JAVAXPCOM_REFCNT
+ nsIID* iid;
+ mIInfo->GetInterfaceIID(&iid);
+ char* iid_str = iid->ToString();
+ int refcnt = PRInt32(mMaster ? mMaster->mRefCnt : mRefCnt) - 1;
+ LOG(("= nsJavaXPTCStub::Release (XPCOM=%08x | refcnt = %d | IID=%s)\n",
+ (int) this, refcnt, iid_str));
+ PR_Free(iid_str);
+ nsMemory::Free(iid);
+#endif
+
+ nsJavaXPTCStub* master = mMaster ? mMaster : this;
+ return master->ReleaseInternal();
+}
+
+void
+nsJavaXPTCStub::Destroy()
+{
+ JNIEnv* env = GetJNIEnv();
+
+#ifdef DEBUG_JAVAXPCOM
+ nsIID* iid;
+ mIInfo->GetInterfaceIID(&iid);
+ char* iid_str = iid->ToString();
+ LOG(("- nsJavaXPTCStub (Java=%08x | XPCOM=%08x | IID=%s)\n",
+ (PRUint32) mJavaRefHashCode, (PRUint32) this, iid_str));
+ PR_Free(iid_str);
+ nsMemory::Free(iid);
+#endif
+
+ if (!mMaster) {
+ // delete each child stub
+ for (PRInt32 i = 0; i < mChildren.Count(); i++) {
+ delete (nsJavaXPTCStub*) mChildren[i];
+ }
+
+ // Since we are destroying this stub, also remove the mapping.
+ // It is possible for mJavaStrongRef to be NULL here. That is why we
+ // store the hash code value earlier.
+ if (gJavaXPCOMInitialized) {
+ gJavaToXPTCStubMap->Remove(mJavaRefHashCode);
+ }
+ }
+
+ env->CallVoidMethod(mJavaWeakRef, clearReferentMID);
+ env->DeleteGlobalRef(mJavaWeakRef);
+}
+
+void
+nsJavaXPTCStub::ReleaseWeakRef()
+{
+ // if this is a child
+ if (mMaster)
+ mMaster->ReleaseWeakRef();
+
+ --mWeakRefCnt;
+
+ // If there are no more associated weak refs, and no one else holds a strong
+ // ref to this object, then delete it.
+ if (mWeakRefCnt == 0 && mRefCnt == 0) {
+ NS_ASSERT_OWNINGTHREAD(nsJavaXPTCStub);
+ mRefCnt = 1; /* stabilize */
+ Destroy();
+ delete this;
+ }
+}
+
+void
+nsJavaXPTCStub::DeleteStrongRef()
+{
+ if (mJavaStrongRef == nsnull)
+ return;
+
+ GetJNIEnv()->DeleteGlobalRef(mJavaStrongRef);
+ mJavaStrongRef = nsnull;
+}
+
+NS_IMETHODIMP
+nsJavaXPTCStub::QueryInterface(const nsID &aIID, void **aInstancePtr)
+{
+ nsresult rv;
+
+ LOG(("JavaStub::QueryInterface()\n"));
+ *aInstancePtr = nsnull;
+ nsJavaXPTCStub *master = mMaster ? mMaster : this;
+
+ // This helps us differentiate between the help classes.
+ if (aIID.Equals(NS_GET_IID(nsJavaXPTCStub)))
+ {
+ *aInstancePtr = master;
+ NS_ADDREF(this);
+ return NS_OK;
+ }
+
+ // always return the master stub for nsISupports
+ if (aIID.Equals(NS_GET_IID(nsISupports)))
+ {
+ *aInstancePtr = master->mXPTCStub;
+ NS_ADDREF(master);
+ return NS_OK;
+ }
+
+ // All Java objects support weak references
+ if (aIID.Equals(NS_GET_IID(nsISupportsWeakReference)))
+ {
+ *aInstancePtr = static_cast<nsISupportsWeakReference*>(master);
+ NS_ADDREF(master);
+ return NS_OK;
+ }
+
+ // does any existing stub support the requested IID?
+ nsJavaXPTCStub *stub = master->FindStubSupportingIID(aIID);
+ if (stub)
+ {
+ *aInstancePtr = stub->mXPTCStub;
+ NS_ADDREF(stub);
+ return NS_OK;
+ }
+
+ JNIEnv* env = GetJNIEnv();
+
+ // Query Java object
+ LOG(("\tCalling Java object queryInterface\n"));
+ jobject javaObject = env->CallObjectMethod(mJavaWeakRef, getReferentMID);
+
+ jmethodID qiMID = 0;
+ jclass clazz = env->GetObjectClass(javaObject);
+ if (clazz) {
+ char* sig = "(Ljava/lang/String;)Lorg/mozilla/interfaces/nsISupports;";
+ qiMID = env->GetMethodID(clazz, "queryInterface", sig);
+ NS_ASSERTION(qiMID, "Failed to get queryInterface method ID");
+ }
+
+ if (qiMID == 0) {
+ env->ExceptionClear();
+ return NS_NOINTERFACE;
+ }
+
+ // construct IID string
+ jstring iid_jstr = nsnull;
+ char* iid_str = aIID.ToString();
+ if (iid_str) {
+ iid_jstr = env->NewStringUTF(iid_str);
+ }
+ if (!iid_str || !iid_jstr) {
+ env->ExceptionClear();
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ PR_Free(iid_str);
+
+ // call queryInterface method
+ jobject obj = env->CallObjectMethod(javaObject, qiMID, iid_jstr);
+ if (env->ExceptionCheck()) {
+ env->ExceptionClear();
+ return NS_ERROR_FAILURE;
+ }
+ if (!obj)
+ return NS_NOINTERFACE;
+
+ // Get interface info for new java object
+ nsCOMPtr<nsIInterfaceInfoManager>
+ iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIInterfaceInfo> iinfo;
+ rv = iim->GetInfoForIID(&aIID, getter_AddRefs(iinfo));
+ if (NS_FAILED(rv))
+ return rv;
+
+ stub = new nsJavaXPTCStub(obj, iinfo, &rv);
+ if (!stub)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ if (NS_FAILED(rv)) {
+ delete stub;
+ return rv;
+ }
+
+ // add stub to the master's list of children, so we can preserve
+ // symmetry in future QI calls. the master will delete each child
+ // when it is destroyed. the refcount of each child is bound to
+ // the refcount of the master. this is done to deal with code
+ // like this:
+ //
+ // nsCOMPtr<nsIBar> bar = ...;
+ // nsIFoo *foo;
+ // {
+ // nsCOMPtr<nsIFoo> temp = do_QueryInterface(bar);
+ // foo = temp;
+ // }
+ // foo->DoStuff();
+ //
+ // while this code is not valid XPCOM (since it is using |foo|
+ // after having called Release on it), such code is unfortunately
+ // very common in the mozilla codebase. the assumption this code
+ // is making is that so long as |bar| is alive, it should be valid
+ // to access |foo| even if the code doesn't own a strong reference
+ // to |foo|! clearly wrong, but we need to support it anyways.
+
+ stub->mMaster = master;
+ master->mChildren.AppendElement(stub);
+
+ *aInstancePtr = stub->mXPTCStub;
+ NS_ADDREF(stub);
+ return NS_OK;
+}
+
+PRBool
+nsJavaXPTCStub::SupportsIID(const nsID &iid)
+{
+ PRBool match;
+ nsCOMPtr<nsIInterfaceInfo> iter = mIInfo;
+ do
+ {
+ if (NS_SUCCEEDED(iter->IsIID(&iid, &match)) && match)
+ return PR_TRUE;
+
+ nsCOMPtr<nsIInterfaceInfo> parent;
+ iter->GetParent(getter_AddRefs(parent));
+ iter = parent;
+ }
+ while (iter != nsnull);
+
+ return PR_FALSE;
+}
+
+nsJavaXPTCStub *
+nsJavaXPTCStub::FindStubSupportingIID(const nsID &iid)
+{
+ NS_ASSERTION(mMaster == nsnull, "this is not a master stub");
+
+ if (SupportsIID(iid))
+ return this;
+
+ for (PRInt32 i = 0; i < mChildren.Count(); i++)
+ {
+ nsJavaXPTCStub *child = (nsJavaXPTCStub *) mChildren[i];
+ if (child->SupportsIID(iid))
+ return child;
+ }
+ return nsnull;
+}
+
+NS_IMETHODIMP
+nsJavaXPTCStub::CallMethod(PRUint16 aMethodIndex,
+ const XPTMethodDescriptor *aMethodInfo,
+ nsXPTCMiniVariant *aParams)
+{
+#ifdef DEBUG_JAVAXPCOM
+ const char* ifaceName;
+ mIInfo->GetNameShared(&ifaceName);
+ LOG(("---> (Java) %s::%s()\n", ifaceName, aMethodInfo->name));
+#endif
+
+ nsresult rv = NS_OK;
+ JNIEnv* env = GetJNIEnv();
+ jobject javaObject = env->CallObjectMethod(mJavaWeakRef, getReferentMID);
+
+ nsCAutoString methodSig("(");
+
+ // Create jvalue array to hold Java params
+ PRUint8 paramCount = aMethodInfo->num_args;
+ jvalue* java_params = nsnull;
+ const nsXPTParamInfo* retvalInfo = nsnull;
+ if (paramCount) {
+ java_params = new jvalue[paramCount];
+ if (!java_params)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)
+ {
+ const nsXPTParamInfo &paramInfo = aMethodInfo->params[i];
+ if (!paramInfo.IsRetval()) {
+ rv = SetupJavaParams(paramInfo, aMethodInfo, aMethodIndex, aParams,
+ aParams[i], java_params[i], methodSig);
+ } else {
+ retvalInfo = &paramInfo;
+ }
+ }
+ NS_ASSERTION(NS_SUCCEEDED(rv), "SetupJavaParams failed");
+ }
+
+ // Finish method signature
+ if (NS_SUCCEEDED(rv)) {
+ methodSig.Append(')');
+ if (retvalInfo) {
+ nsCAutoString retvalSig;
+ rv = GetRetvalSig(retvalInfo, aMethodInfo, aMethodIndex, aParams,
+ retvalSig);
+ methodSig.Append(retvalSig);
+ } else {
+ methodSig.Append('V');
+ }
+ NS_ASSERTION(NS_SUCCEEDED(rv), "GetRetvalSig failed");
+ }
+
+ // Get Java method to call
+ jmethodID mid = nsnull;
+ if (NS_SUCCEEDED(rv)) {
+ nsCAutoString methodName;
+ if (XPT_MD_IS_GETTER(aMethodInfo->flags) ||
+ XPT_MD_IS_SETTER(aMethodInfo->flags)) {
+ if (XPT_MD_IS_GETTER(aMethodInfo->flags))
+ methodName.AppendLiteral("get");
+ else
+ methodName.AppendLiteral("set");
+ methodName.AppendASCII(aMethodInfo->name);
+ methodName.SetCharAt(toupper(methodName[3]), 3);
+ } else {
+ methodName.AppendASCII(aMethodInfo->name);
+ methodName.SetCharAt(tolower(methodName[0]), 0);
+ }
+ // If it's a Java keyword, then prepend an underscore
+ if (gJavaKeywords->GetEntry(methodName.get())) {
+ methodName.Insert('_', 0);
+ }
+
+ jclass clazz = env->GetObjectClass(javaObject);
+ if (clazz)
+ mid = env->GetMethodID(clazz, methodName.get(), methodSig.get());
+ NS_ASSERTION(mid, "Failed to get requested method for Java object");
+ if (!mid)
+ rv = NS_ERROR_FAILURE;
+ }
+
+ // Call method
+ jvalue retval;
+ if (NS_SUCCEEDED(rv)) {
+ if (!retvalInfo) {
+ env->CallVoidMethodA(javaObject, mid, java_params);
+ } else {
+ switch (retvalInfo->GetType().TagPart())
+ {
+ case nsXPTType::T_I8:
+ retval.b = env->CallByteMethodA(javaObject, mid, java_params);
+ break;
+
+ case nsXPTType::T_I16:
+ case nsXPTType::T_U8:
+ retval.s = env->CallShortMethodA(javaObject, mid, java_params);
+ break;
+
+ case nsXPTType::T_I32:
+ case nsXPTType::T_U16:
+ retval.i = env->CallIntMethodA(javaObject, mid, java_params);
+ break;
+
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U32:
+ retval.j = env->CallLongMethodA(javaObject, mid, java_params);
+ break;
+
+ case nsXPTType::T_FLOAT:
+ retval.f = env->CallFloatMethodA(javaObject, mid, java_params);
+ break;
+
+ case nsXPTType::T_U64:
+ case nsXPTType::T_DOUBLE:
+ retval.d = env->CallDoubleMethodA(javaObject, mid, java_params);
+ break;
+
+ case nsXPTType::T_BOOL:
+ retval.z = env->CallBooleanMethodA(javaObject, mid, java_params);
+ break;
+
+ case nsXPTType::T_CHAR:
+ case nsXPTType::T_WCHAR:
+ retval.c = env->CallCharMethodA(javaObject, mid, java_params);
+ break;
+
+ case nsXPTType::T_CHAR_STR:
+ case nsXPTType::T_WCHAR_STR:
+ case nsXPTType::T_IID:
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING:
+ case nsXPTType::T_UTF8STRING:
+ case nsXPTType::T_CSTRING:
+ case nsXPTType::T_INTERFACE:
+ case nsXPTType::T_INTERFACE_IS:
+ retval.l = env->CallObjectMethodA(javaObject, mid, java_params);
+ break;
+
+ case nsXPTType::T_VOID:
+ retval.j = env->CallLongMethodA(javaObject, mid, java_params);
+ break;
+
+ default:
+ NS_WARNING("Unhandled retval type");
+ break;
+ }
+ }
+
+ // Check for exception from called Java function
+ jthrowable exp = env->ExceptionOccurred();
+ if (exp) {
+ // If the exception is an instance of XPCOMException, then get the
+ // nsresult from the exception instance. Else, default to
+ // NS_ERROR_FAILURE.
+ if (env->IsInstanceOf(exp, xpcomExceptionClass)) {
+ jfieldID fid;
+ fid = env->GetFieldID(xpcomExceptionClass, "errorcode", "J");
+ if (fid) {
+ rv = env->GetLongField(exp, fid);
+ } else {
+ rv = NS_ERROR_FAILURE;
+ }
+ NS_ASSERTION(fid, "Couldn't get 'errorcode' field of XPCOMException");
+ } else {
+ rv = NS_ERROR_FAILURE;
+ }
+ }
+ }
+
+ // Handle any 'inout', 'out' and 'retval' params
+ if (NS_SUCCEEDED(rv)) {
+ for (PRUint8 i = 0; i < paramCount; i++)
+ {
+ const nsXPTParamInfo &paramInfo = aMethodInfo->params[i];
+ if (paramInfo.IsIn() && !paramInfo.IsOut() && !paramInfo.IsDipper()) // 'in'
+ continue;
+
+ // If param is null, then caller is not expecting an output value.
+ if (aParams[i].val.p == nsnull)
+ continue;
+
+ if (!paramInfo.IsRetval()) {
+ rv = FinalizeJavaParams(paramInfo, aMethodInfo, aMethodIndex, aParams,
+ aParams[i], java_params[i]);
+ } else {
+ rv = FinalizeJavaParams(paramInfo, aMethodInfo, aMethodIndex, aParams,
+ aParams[i], retval);
+ }
+ }
+ NS_ASSERTION(NS_SUCCEEDED(rv), "FinalizeJavaParams/SetXPCOMRetval failed");
+ }
+
+ if (java_params)
+ delete [] java_params;
+
+#ifdef DEBUG
+ if (env->ExceptionCheck())
+ env->ExceptionDescribe();
+#endif
+ env->ExceptionClear();
+
+ LOG(("<--- (Java) %s::%s()\n", ifaceName, aMethodInfo->name));
+ return rv;
+}
+
+/**
+ * Handle 'in', 'inout', and 'out' params
+ */
+nsresult
+nsJavaXPTCStub::SetupJavaParams(const nsXPTParamInfo &aParamInfo,
+ const XPTMethodDescriptor* aMethodInfo,
+ PRUint16 aMethodIndex,
+ nsXPTCMiniVariant* aDispatchParams,
+ nsXPTCMiniVariant &aVariant, jvalue &aJValue,
+ nsACString &aMethodSig)
+{
+ nsresult rv = NS_OK;
+ JNIEnv* env = GetJNIEnv();
+ const nsXPTType &type = aParamInfo.GetType();
+
+ PRUint8 tag = type.TagPart();
+ switch (tag)
+ {
+ case nsXPTType::T_I8:
+ {
+ if (!aParamInfo.IsOut()) { // 'in'
+ aJValue.b = aVariant.val.i8;
+ aMethodSig.Append('B');
+ } else { // 'inout' & 'out'
+ if (aVariant.val.p) {
+ jbyteArray array = env->NewByteArray(1);
+ if (!array) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ env->SetByteArrayRegion(array, 0, 1, (jbyte*) aVariant.val.p);
+ aJValue.l = array;
+ } else {
+ aJValue.l = nsnull;
+ }
+ aMethodSig.AppendLiteral("[B");
+ }
+ }
+ break;
+
+ case nsXPTType::T_I16:
+ case nsXPTType::T_U8:
+ {
+ if (!aParamInfo.IsOut()) { // 'in'
+ aJValue.s = (tag == nsXPTType::T_I16) ? aVariant.val.i16 :
+ aVariant.val.u8;
+ aMethodSig.Append('S');
+ } else { // 'inout' & 'out'
+ if (aVariant.val.p) {
+ jshortArray array = env->NewShortArray(1);
+ if (!array) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ env->SetShortArrayRegion(array, 0, 1, (jshort*) aVariant.val.p);
+ aJValue.l = array;
+ } else {
+ aJValue.l = nsnull;
+ }
+ aMethodSig.AppendLiteral("[S");
+ }
+ }
+ break;
+
+ case nsXPTType::T_I32:
+ case nsXPTType::T_U16:
+ {
+ if (!aParamInfo.IsOut()) { // 'in'
+ aJValue.i = (tag == nsXPTType::T_I32) ? aVariant.val.i32 :
+ aVariant.val.u16;
+ aMethodSig.Append('I');
+ } else { // 'inout' & 'out'
+ if (aVariant.val.p) {
+ jintArray array = env->NewIntArray(1);
+ if (!array) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ env->SetIntArrayRegion(array, 0, 1, (jint*) aVariant.val.p);
+ aJValue.l = array;
+ } else {
+ aJValue.l = nsnull;
+ }
+ aMethodSig.AppendLiteral("[I");
+ }
+ }
+ break;
+
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U32:
+ {
+ if (!aParamInfo.IsOut()) { // 'in'
+ aJValue.j = (tag == nsXPTType::T_I64) ? aVariant.val.i64 :
+ aVariant.val.u32;
+ aMethodSig.Append('J');
+ } else { // 'inout' & 'out'
+ if (aVariant.val.p) {
+ jlongArray array = env->NewLongArray(1);
+ if (!array) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ env->SetLongArrayRegion(array, 0, 1, (jlong*) aVariant.val.p);
+ aJValue.l = array;
+ } else {
+ aJValue.l = nsnull;
+ }
+ aMethodSig.AppendLiteral("[J");
+ }
+ }
+ break;
+
+ case nsXPTType::T_FLOAT:
+ {
+ if (!aParamInfo.IsOut()) { // 'in'
+ aJValue.f = aVariant.val.f;
+ aMethodSig.Append('F');
+ } else { // 'inout' & 'out'
+ if (aVariant.val.p) {
+ jfloatArray array = env->NewFloatArray(1);
+ if (!array) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ env->SetFloatArrayRegion(array, 0, 1, (jfloat*) aVariant.val.p);
+ aJValue.l = array;
+ } else {
+ aJValue.l = nsnull;
+ }
+ aMethodSig.AppendLiteral("[F");
+ }
+ }
+ break;
+
+ // XXX how do we handle unsigned 64-bit values?
+ case nsXPTType::T_U64:
+ case nsXPTType::T_DOUBLE:
+ {
+ if (!aParamInfo.IsOut()) { // 'in'
+ aJValue.d = (tag == nsXPTType::T_DOUBLE) ? aVariant.val.d :
+ aVariant.val.u64;
+ aMethodSig.Append('D');
+ } else { // 'inout' & 'out'
+ if (aVariant.val.p) {
+ jdoubleArray array = env->NewDoubleArray(1);
+ if (!array) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ env->SetDoubleArrayRegion(array, 0, 1, (jdouble*) aVariant.val.p);
+ aJValue.l = array;
+ } else {
+ aJValue.l = nsnull;
+ }
+ aMethodSig.AppendLiteral("[D");
+ }
+ }
+ break;
+
+ case nsXPTType::T_BOOL:
+ {
+ if (!aParamInfo.IsOut()) { // 'in'
+ aJValue.z = aVariant.val.b;
+ aMethodSig.Append('Z');
+ } else { // 'inout' & 'out'
+ if (aVariant.val.p) {
+ jbooleanArray array = env->NewBooleanArray(1);
+ if (!array) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ env->SetBooleanArrayRegion(array, 0, 1, (jboolean*) aVariant.val.p);
+ aJValue.l = array;
+ } else {
+ aJValue.l = nsnull;
+ }
+ aMethodSig.AppendLiteral("[Z");
+ }
+ }
+ break;
+
+ case nsXPTType::T_CHAR:
+ case nsXPTType::T_WCHAR:
+ {
+ if (!aParamInfo.IsOut()) { // 'in'
+ if (tag == nsXPTType::T_CHAR)
+ aJValue.c = aVariant.val.c;
+ else
+ aJValue.c = aVariant.val.wc;
+ aMethodSig.Append('C');
+ } else { // 'inout' & 'out'
+ if (aVariant.val.p) {
+ jcharArray array = env->NewCharArray(1);
+ if (!array) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ env->SetCharArrayRegion(array, 0, 1, (jchar*) aVariant.val.p);
+ aJValue.l = array;
+ } else {
+ aJValue.l = nsnull;
+ }
+ aMethodSig.AppendLiteral("[C");
+ }
+ }
+ break;
+
+ case nsXPTType::T_CHAR_STR:
+ case nsXPTType::T_WCHAR_STR:
+ {
+ void* ptr = nsnull;
+ if (!aParamInfo.IsOut()) { // 'in'
+ ptr = aVariant.val.p;
+ } else if (aVariant.val.p) { // 'inout' & 'out'
+ void** variant = static_cast<void**>(aVariant.val.p);
+ ptr = *variant;
+ }
+
+ jobject str;
+ if (ptr) {
+ if (tag == nsXPTType::T_CHAR_STR) {
+ str = env->NewStringUTF((const char*) ptr);
+ } else {
+ const PRUnichar* buf = (const PRUnichar*) ptr;
+ str = env->NewString(buf, nsCRT::strlen(buf));
+ }
+ if (!str) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ } else {
+ str = nsnull;
+ }
+
+ if (!aParamInfo.IsOut()) { // 'in'
+ aJValue.l = str;
+ aMethodSig.AppendLiteral("Ljava/lang/String;");
+ } else { // 'inout' & 'out'
+ if (aVariant.val.p) {
+ aJValue.l = env->NewObjectArray(1, stringClass, str);
+ if (aJValue.l == nsnull) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ } else {
+ aJValue.l = nsnull;
+ }
+ aMethodSig.AppendLiteral("[Ljava/lang/String;");
+ }
+ }
+ break;
+
+ case nsXPTType::T_IID:
+ {
+ nsID* iid = nsnull;
+ if (!aParamInfo.IsOut()) { // 'in'
+ iid = static_cast<nsID*>(aVariant.val.p);
+ } else if (aVariant.val.p) { // 'inout' & 'out'
+ nsID** variant = static_cast<nsID**>(aVariant.val.p);
+ iid = *variant;
+ }
+
+ jobject str = nsnull;
+ if (iid) {
+ char iid_str[NSID_LENGTH];
+ iid->ToProvidedString(iid_str);
+ str = env->NewStringUTF(iid_str);
+ if (!str) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ }
+
+ if (!aParamInfo.IsOut()) { // 'in'
+ aJValue.l = str;
+ aMethodSig.AppendLiteral("Ljava/lang/String;");
+ } else { // 'inout' & 'out'
+ if (aVariant.val.p) {
+ aJValue.l = env->NewObjectArray(1, stringClass, str);
+ if (aJValue.l == nsnull) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ } else {
+ aJValue.l = nsnull;
+ }
+ aMethodSig.AppendLiteral("[Ljava/lang/String;");
+ }
+ }
+ break;
+
+ case nsXPTType::T_INTERFACE:
+ case nsXPTType::T_INTERFACE_IS:
+ {
+ nsISupports* xpcom_obj = nsnull;
+ if (!aParamInfo.IsOut()) { // 'in'
+ xpcom_obj = static_cast<nsISupports*>(aVariant.val.p);
+ } else if (aVariant.val.p) { // 'inout' & 'out'
+ nsISupports** variant = static_cast<nsISupports**>(aVariant.val.p);
+ xpcom_obj = *variant;
+ }
+
+ nsID iid;
+ rv = GetIIDForMethodParam(mIInfo, aMethodInfo, aParamInfo,
+ aParamInfo.GetType().TagPart(), aMethodIndex,
+ aDispatchParams, PR_FALSE, iid);
+ if (NS_FAILED(rv))
+ break;
+
+ // get name of interface
+ char* iface_name = nsnull;
+ nsCOMPtr<nsIInterfaceInfoManager>
+ iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv));
+ if (NS_FAILED(rv))
+ break;
+
+ rv = iim->GetNameForIID(&iid, &iface_name);
+ if (NS_FAILED(rv) || !iface_name)
+ break;
+
+ jobject java_stub = nsnull;
+ if (xpcom_obj) {
+ // Get matching Java object for given xpcom object
+ jobject objLoader = env->CallObjectMethod(mJavaWeakRef, getReferentMID);
+ rv = NativeInterfaceToJavaObject(env, xpcom_obj, iid, objLoader,
+ &java_stub);
+ if (NS_FAILED(rv))
+ break;
+ }
+
+ if (!aParamInfo.IsOut()) { // 'in'
+ aJValue.l = java_stub;
+ } else { // 'inout' & 'out'
+ if (aVariant.val.p) {
+ aJValue.l = env->NewObjectArray(1, nsISupportsClass, java_stub);
+ if (aJValue.l == nsnull) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ } else {
+ aJValue.l = nsnull;
+ }
+ aMethodSig.Append('[');
+ }
+
+ if (tag != nsXPTType::T_INTERFACE_IS) {
+ aMethodSig.AppendLiteral("Lorg/mozilla/interfaces/");
+ aMethodSig.AppendASCII(iface_name);
+ aMethodSig.Append(';');
+ } else {
+ aMethodSig.AppendLiteral("Lorg/mozilla/interfaces/nsISupports;");
+ }
+
+ nsMemory::Free(iface_name);
+ }
+ break;
+
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING:
+ {
+ // This only handle 'in' or 'in dipper' params. In XPIDL, the 'out'
+ // descriptor is mapped to 'in dipper'.
+ NS_PRECONDITION(aParamInfo.IsIn(), "unexpected param descriptor");
+ if (!aParamInfo.IsIn()) {
+ rv = NS_ERROR_UNEXPECTED;
+ break;
+ }
+
+ nsString* str = static_cast<nsString*>(aVariant.val.p);
+ if (!str) {
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+
+ jstring jstr = nsnull;
+ if (!str->IsVoid()) {
+ jstr = env->NewString(str->get(), str->Length());
+ if (!jstr) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ }
+
+ aJValue.l = jstr;
+ aMethodSig.AppendLiteral("Ljava/lang/String;");
+ }
+ break;
+
+ case nsXPTType::T_UTF8STRING:
+ case nsXPTType::T_CSTRING:
+ {
+ // This only handle 'in' or 'in dipper' params. In XPIDL, the 'out'
+ // descriptor is mapped to 'in dipper'.
+ NS_PRECONDITION(aParamInfo.IsIn(), "unexpected param descriptor");
+ if (!aParamInfo.IsIn()) {
+ rv = NS_ERROR_UNEXPECTED;
+ break;
+ }
+
+ nsCString* str = static_cast<nsCString*>(aVariant.val.p);
+ if (!str) {
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+
+ jstring jstr = nsnull;
+ if (!str->IsVoid()) {
+ jstr = env->NewStringUTF(str->get());
+ if (!jstr) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ }
+
+ aJValue.l = jstr;
+ aMethodSig.AppendLiteral("Ljava/lang/String;");
+ }
+ break;
+
+ // Pass the 'void*' address as a long
+ case nsXPTType::T_VOID:
+ {
+ if (!aParamInfo.IsOut()) { // 'in'
+ aJValue.j = reinterpret_cast<jlong>(aVariant.val.p);
+ aMethodSig.Append('J');
+ } else { // 'inout' & 'out'
+ if (aVariant.val.p) {
+ jlongArray array = env->NewLongArray(1);
+ if (!array) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ env->SetLongArrayRegion(array, 0, 1, (jlong*) aVariant.val.p);
+ aJValue.l = array;
+ } else {
+ aJValue.l = nsnull;
+ }
+ aMethodSig.AppendLiteral("[J");
+ }
+ }
+ break;
+
+ case nsXPTType::T_ARRAY:
+ NS_WARNING("array types are not yet supported");
+ return NS_ERROR_NOT_IMPLEMENTED;
+ break;
+
+ case nsXPTType::T_PSTRING_SIZE_IS:
+ case nsXPTType::T_PWSTRING_SIZE_IS:
+ default:
+ NS_WARNING("unexpected parameter type");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return rv;
+}
+
+nsresult
+nsJavaXPTCStub::GetRetvalSig(const nsXPTParamInfo* aParamInfo,
+ const XPTMethodDescriptor* aMethodInfo,
+ PRUint16 aMethodIndex,
+ nsXPTCMiniVariant* aDispatchParams,
+ nsACString &aRetvalSig)
+{
+ PRUint8 type = aParamInfo->GetType().TagPart();
+ switch (type)
+ {
+ case nsXPTType::T_I8:
+ aRetvalSig.Append('B');
+ break;
+
+ case nsXPTType::T_I16:
+ case nsXPTType::T_U8:
+ aRetvalSig.Append('S');
+ break;
+
+ case nsXPTType::T_I32:
+ case nsXPTType::T_U16:
+ aRetvalSig.Append('I');
+ break;
+
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U32:
+ aRetvalSig.Append('J');
+ break;
+
+ case nsXPTType::T_FLOAT:
+ aRetvalSig.Append('F');
+ break;
+
+ case nsXPTType::T_U64:
+ case nsXPTType::T_DOUBLE:
+ aRetvalSig.Append('D');
+ break;
+
+ case nsXPTType::T_BOOL:
+ aRetvalSig.Append('Z');
+ break;
+
+ case nsXPTType::T_CHAR:
+ case nsXPTType::T_WCHAR:
+ aRetvalSig.Append('C');
+ break;
+
+ case nsXPTType::T_CHAR_STR:
+ case nsXPTType::T_WCHAR_STR:
+ case nsXPTType::T_IID:
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING:
+ case nsXPTType::T_UTF8STRING:
+ case nsXPTType::T_CSTRING:
+ aRetvalSig.AppendLiteral("Ljava/lang/String;");
+ break;
+
+ case nsXPTType::T_INTERFACE:
+ {
+ nsID iid;
+ nsresult rv = GetIIDForMethodParam(mIInfo, aMethodInfo, *aParamInfo, type,
+ aMethodIndex, aDispatchParams,
+ PR_FALSE, iid);
+ if (NS_FAILED(rv))
+ break;
+
+ // get name of interface
+ char* iface_name = nsnull;
+ nsCOMPtr<nsIInterfaceInfoManager>
+ iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv));
+ if (NS_FAILED(rv))
+ break;
+
+ rv = iim->GetNameForIID(&iid, &iface_name);
+ if (NS_FAILED(rv) || !iface_name)
+ break;
+
+ aRetvalSig.AppendLiteral("Lorg/mozilla/interfaces/");
+ aRetvalSig.AppendASCII(iface_name);
+ aRetvalSig.Append(';');
+ nsMemory::Free(iface_name);
+ break;
+ }
+
+ case nsXPTType::T_INTERFACE_IS:
+ aRetvalSig.AppendLiteral("Lorg/mozilla/interfaces/nsISupports;");
+ break;
+
+ case nsXPTType::T_VOID:
+ aRetvalSig.Append('J');
+ break;
+
+ case nsXPTType::T_ARRAY:
+ NS_WARNING("array types are not yet supported");
+ return NS_ERROR_NOT_IMPLEMENTED;
+ break;
+
+ case nsXPTType::T_PSTRING_SIZE_IS:
+ case nsXPTType::T_PWSTRING_SIZE_IS:
+ default:
+ NS_WARNING("unexpected parameter type");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return NS_OK;
+}
+
+/**
+ * Handle 'inout', 'out', and 'retval' params
+ */
+nsresult
+nsJavaXPTCStub::FinalizeJavaParams(const nsXPTParamInfo &aParamInfo,
+ const XPTMethodDescriptor *aMethodInfo,
+ PRUint16 aMethodIndex,
+ nsXPTCMiniVariant* aDispatchParams,
+ nsXPTCMiniVariant &aVariant, jvalue &aJValue)
+{
+ nsresult rv = NS_OK;
+ JNIEnv* env = GetJNIEnv();
+ const nsXPTType &type = aParamInfo.GetType();
+
+ PRUint8 tag = type.TagPart();
+ switch (tag)
+ {
+ case nsXPTType::T_I8:
+ {
+ jbyte value;
+ if (aParamInfo.IsRetval()) { // 'retval'
+ value = aJValue.b;
+ } else if (aJValue.l) { // 'inout' & 'out'
+ env->GetByteArrayRegion((jbyteArray) aJValue.l, 0, 1, &value);
+ }
+ if (aVariant.val.p)
+ *((PRInt8 *) aVariant.val.p) = value;
+ }
+ break;
+
+ case nsXPTType::T_U8:
+ case nsXPTType::T_I16:
+ {
+ jshort value = 0;
+ if (aParamInfo.IsRetval()) { // 'retval'
+ value = aJValue.s;
+ } else if (aJValue.l) { // 'inout' & 'out'
+ env->GetShortArrayRegion((jshortArray) aJValue.l, 0, 1, &value);
+ }
+
+ if (aVariant.val.p) {
+ if (tag == nsXPTType::T_U8)
+ *((PRUint8 *) aVariant.val.p) = value;
+ else
+ *((PRInt16 *) aVariant.val.p) = value;
+ }
+ }
+ break;
+
+ case nsXPTType::T_U16:
+ case nsXPTType::T_I32:
+ {
+ jint value = 0;
+ if (aParamInfo.IsRetval()) { // 'retval'
+ value = aJValue.i;
+ } else if (aJValue.l) { // 'inout' & 'out'
+ env->GetIntArrayRegion((jintArray) aJValue.l, 0, 1, &value);
+ }
+
+ if (aVariant.val.p) {
+ if (tag == nsXPTType::T_U16)
+ *((PRUint16 *) aVariant.val.p) = value;
+ else
+ *((PRInt32 *) aVariant.val.p) = value;
+ }
+ }
+ break;
+
+ case nsXPTType::T_U32:
+ case nsXPTType::T_I64:
+ {
+ jlong value = 0;
+ if (aParamInfo.IsRetval()) { // 'retval'
+ value = aJValue.j;
+ } else if (aJValue.l) { // 'inout' & 'out'
+ env->GetLongArrayRegion((jlongArray) aJValue.l, 0, 1, &value);
+ }
+
+ if (aVariant.val.p) {
+ if (tag == nsXPTType::T_U32)
+ *((PRUint32 *) aVariant.val.p) = value;
+ else
+ *((PRInt64 *) aVariant.val.p) = value;
+ }
+ }
+ break;
+
+ case nsXPTType::T_FLOAT:
+ {
+ if (aParamInfo.IsRetval()) { // 'retval'
+ *((float *) aVariant.val.p) = aJValue.f;
+ } else if (aJValue.l) { // 'inout' & 'out'
+ env->GetFloatArrayRegion((jfloatArray) aJValue.l, 0, 1,
+ (jfloat*) aVariant.val.p);
+ }
+ }
+ break;
+
+ // XXX how do we handle 64-bit values?
+ case nsXPTType::T_U64:
+ case nsXPTType::T_DOUBLE:
+ {
+ jdouble value = 0;
+ if (aParamInfo.IsRetval()) { // 'retval'
+ value = aJValue.d;
+ } else if (aJValue.l) { // 'inout' & 'out'
+ env->GetDoubleArrayRegion((jdoubleArray) aJValue.l, 0, 1, &value);
+ }
+
+ if (aVariant.val.p) {
+ if (tag == nsXPTType::T_DOUBLE)
+ *((double *) aVariant.val.p) = value;
+ else
+ *((PRUint64 *) aVariant.val.p) = static_cast<PRUint64>(value);
+ }
+ }
+ break;
+
+ case nsXPTType::T_BOOL:
+ {
+ if (aParamInfo.IsRetval()) { // 'retval'
+ *((PRBool *) aVariant.val.p) = aJValue.z;
+ } else if (aJValue.l) { // 'inout' & 'out'
+ env->GetBooleanArrayRegion((jbooleanArray) aJValue.l, 0, 1,
+ (jboolean*) aVariant.val.p);
+ }
+ }
+ break;
+
+ case nsXPTType::T_CHAR:
+ case nsXPTType::T_WCHAR:
+ {
+ if (aParamInfo.IsRetval()) { // 'retval'
+ if (type.TagPart() == nsXPTType::T_CHAR)
+ *((char *) aVariant.val.p) = aJValue.c;
+ else
+ *((PRUnichar *) aVariant.val.p) = aJValue.c;
+ } else if (aJValue.l) { // 'inout' & 'out'
+ jchar* array = env->GetCharArrayElements((jcharArray) aJValue.l,
+ nsnull);
+ if (!array) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ if (type.TagPart() == nsXPTType::T_CHAR)
+ *((char *) aVariant.val.p) = array[0];
+ else
+ *((PRUnichar *) aVariant.val.p) = array[0];
+
+ env->ReleaseCharArrayElements((jcharArray) aJValue.l, array, JNI_ABORT);
+ }
+ }
+ break;
+
+ case nsXPTType::T_CHAR_STR:
+ {
+ jstring str = nsnull;
+ if (aParamInfo.IsRetval()) { // 'retval'
+ str = (jstring) aJValue.l;
+ } else { // 'inout' & 'out'
+ str = (jstring) env->GetObjectArrayElement((jobjectArray) aJValue.l, 0);
+ }
+
+ char** variant = static_cast<char**>(aVariant.val.p);
+ if (str) {
+ // Get string buffer
+ const char* char_ptr = env->GetStringUTFChars(str, nsnull);
+ if (!char_ptr) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ // If new string is different from one passed in, free old string
+ // and replace with new string.
+ if (aParamInfo.IsRetval() ||
+ *variant == nsnull || strcmp(*variant, char_ptr) != 0)
+ {
+ if (!aParamInfo.IsRetval() && *variant)
+ PR_Free(*variant);
+
+ *variant = strdup(char_ptr);
+ if (*variant == nsnull) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ // don't 'break'; fall through to release chars
+ }
+ }
+
+ // Release string buffer
+ env->ReleaseStringUTFChars(str, char_ptr);
+ } else {
+ // If we were passed in a string, delete it now, and set to null.
+ // (Only for 'inout' & 'out' params)
+ if (*variant && !aParamInfo.IsRetval()) {
+ PR_Free(*variant);
+ }
+ *variant = nsnull;
+ }
+ }
+ break;
+
+ case nsXPTType::T_WCHAR_STR:
+ {
+ jstring str = nsnull;
+ if (aParamInfo.IsRetval()) { // 'retval'
+ str = (jstring) aJValue.l;
+ } else { // 'inout' & 'out'
+ str = (jstring) env->GetObjectArrayElement((jobjectArray) aJValue.l, 0);
+ }
+
+ PRUnichar** variant = static_cast<PRUnichar**>(aVariant.val.p);
+ if (str) {
+ // Get string buffer
+ const jchar* wchar_ptr = env->GetStringChars(str, nsnull);
+ if (!wchar_ptr) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ // If new string is different from one passed in, free old string
+ // and replace with new string. We
+ if (aParamInfo.IsRetval() ||
+ *variant == nsnull || nsCRT::strcmp(*variant, wchar_ptr) != 0)
+ {
+ if (!aParamInfo.IsRetval() && *variant)
+ PR_Free(*variant);
+
+ PRUint32 length = nsCRT::strlen(wchar_ptr);
+ *variant = (PRUnichar*) PR_Malloc((length + 1) * sizeof(PRUnichar));
+ if (*variant) {
+ memcpy(*variant, wchar_ptr, length * sizeof(PRUnichar));
+ (*variant)[length] = 0;
+ } else {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ // don't 'break'; fall through to release chars
+ }
+ }
+
+ // Release string buffer
+ env->ReleaseStringChars(str, wchar_ptr);
+ } else {
+ // If we were passed in a string, delete it now, and set to null.
+ // (Only for 'inout' & 'out' params)
+ if (*variant && !aParamInfo.IsRetval()) {
+ PR_Free(*variant);
+ }
+ *variant = nsnull;
+ }
+ }
+ break;
+
+ case nsXPTType::T_IID:
+ {
+ jstring str = nsnull;
+ if (aParamInfo.IsRetval()) { // 'retval'
+ str = (jstring) aJValue.l;
+ } else { // 'inout' & 'out'
+ str = (jstring) env->GetObjectArrayElement((jobjectArray) aJValue.l, 0);
+ }
+
+ nsID** variant = static_cast<nsID**>(aVariant.val.p);
+ if (str) {
+ // Get string buffer
+ const char* char_ptr = env->GetStringUTFChars(str, nsnull);
+ if (!char_ptr) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ if (!aParamInfo.IsRetval() && *variant) {
+ // If we were given an nsID, set it to the new string
+ nsID* oldIID = *variant;
+ oldIID->Parse(char_ptr);
+ } else {
+ // If the argument that was passed in was null, then we need to
+ // create a new nsID.
+ nsID* newIID = new nsID;
+ if (newIID) {
+ newIID->Parse(char_ptr);
+ *variant = newIID;
+ } else {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ // don't 'break'; fall through to release chars
+ }
+ }
+
+ // Release string buffer
+ env->ReleaseStringUTFChars(str, char_ptr);
+ } else {
+ // If we were passed in an nsID, delete it now, and set to null.
+ // (Free only 'inout' & 'out' params)
+ if (*variant && !aParamInfo.IsRetval()) {
+ delete *variant;
+ }
+ *variant = nsnull;
+ }
+ }
+ break;
+
+ case nsXPTType::T_INTERFACE:
+ case nsXPTType::T_INTERFACE_IS:
+ {
+ jobject java_obj = nsnull;
+ if (aParamInfo.IsRetval()) { // 'retval'
+ java_obj = aJValue.l;
+ } else if (aJValue.l) { // 'inout' & 'out'
+ java_obj = env->GetObjectArrayElement((jobjectArray) aJValue.l, 0);
+ }
+
+ void* xpcom_obj = nsnull;
+ if (java_obj) {
+ // Get IID for this param
+ nsID iid;
+ rv = GetIIDForMethodParam(mIInfo, aMethodInfo, aParamInfo,
+ aParamInfo.GetType().TagPart(), aMethodIndex,
+ aDispatchParams, PR_FALSE, iid);
+ if (NS_FAILED(rv))
+ break;
+
+ // If the requested interface is nsIWeakReference, then we look for or
+ // create a stub for the nsISupports interface. Then we create a weak
+ // reference from that stub.
+ PRBool isWeakRef;
+ if (iid.Equals(NS_GET_IID(nsIWeakReference))) {
+ isWeakRef = PR_TRUE;
+ iid = NS_GET_IID(nsISupports);
+ } else {
+ isWeakRef = PR_FALSE;
+ }
+
+ rv = JavaObjectToNativeInterface(env, java_obj, iid, &xpcom_obj);
+ if (NS_FAILED(rv))
+ break;
+ rv = ((nsISupports*) xpcom_obj)->QueryInterface(iid, &xpcom_obj);
+ if (NS_FAILED(rv))
+ break;
+
+ // If the function expects a weak reference, then we need to
+ // create it here.
+ if (isWeakRef) {
+ nsISupports* isupports = (nsISupports*) xpcom_obj;
+ nsCOMPtr<nsISupportsWeakReference> supportsweak =
+ do_QueryInterface(isupports);
+ if (supportsweak) {
+ nsWeakPtr weakref;
+ supportsweak->GetWeakReference(getter_AddRefs(weakref));
+ NS_RELEASE(isupports);
+ xpcom_obj = weakref;
+ NS_ADDREF((nsISupports*) xpcom_obj);
+ } else {
+ xpcom_obj = nsnull;
+ }
+ }
+ }
+
+ // For 'inout' params, if the resulting xpcom value is different than the
+ // one passed in, then we must release the incoming xpcom value.
+ nsISupports** variant = static_cast<nsISupports**>(aVariant.val.p);
+ if (aParamInfo.IsIn() && *variant) {
+ nsCOMPtr<nsISupports> in = do_QueryInterface(*variant);
+ nsCOMPtr<nsISupports> out = do_QueryInterface((nsISupports*) xpcom_obj);
+ if (in != out) {
+ NS_RELEASE(*variant);
+ }
+ }
+
+ *(static_cast<void**>(aVariant.val.p)) = xpcom_obj;
+ }
+ break;
+
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING:
+ {
+ NS_PRECONDITION(aParamInfo.IsDipper(), "string argument is not dipper");
+ if (!aParamInfo.IsDipper()) {
+ rv = NS_ERROR_UNEXPECTED;
+ break;
+ }
+
+ jstring jstr = (jstring) aJValue.l;
+ nsString* variant = static_cast<nsString*>(aVariant.val.p);
+
+ if (jstr) {
+ // Get string buffer
+ const jchar* wchar_ptr = env->GetStringChars(jstr, nsnull);
+ if (!wchar_ptr) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ variant->Assign(wchar_ptr);
+
+ // release String buffer
+ env->ReleaseStringChars(jstr, wchar_ptr);
+ } else {
+ variant->SetIsVoid(PR_TRUE);
+ }
+ }
+ break;
+
+ case nsXPTType::T_UTF8STRING:
+ case nsXPTType::T_CSTRING:
+ {
+ NS_PRECONDITION(aParamInfo.IsDipper(), "string argument is not dipper");
+ if (!aParamInfo.IsDipper()) {
+ rv = NS_ERROR_UNEXPECTED;
+ break;
+ }
+
+ jstring jstr = (jstring) aJValue.l;
+ nsCString* variant = static_cast<nsCString*>(aVariant.val.p);
+
+ if (jstr) {
+ // Get string buffer
+ const char* char_ptr = env->GetStringUTFChars(jstr, nsnull);
+ if (!char_ptr) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ variant->Assign(char_ptr);
+
+ // release String buffer
+ env->ReleaseStringUTFChars(jstr, char_ptr);
+ } else {
+ variant->SetIsVoid(PR_TRUE);
+ }
+ }
+ break;
+
+ case nsXPTType::T_VOID:
+ {
+ if (aParamInfo.IsRetval()) { // 'retval'
+ aVariant.val.p = reinterpret_cast<void*>(aJValue.j);
+ } else if (aJValue.l) { // 'inout' & 'out'
+ env->GetLongArrayRegion((jlongArray) aJValue.l, 0, 1,
+ (jlong*) aVariant.val.p);
+ }
+ }
+ break;
+
+ default:
+ NS_WARNING("unexpected parameter type");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsJavaXPTCStub::GetWeakReference(nsIWeakReference** aInstancePtr)
+{
+ if (mMaster)
+ return mMaster->GetWeakReference(aInstancePtr);
+
+ LOG(("==> nsJavaXPTCStub::GetWeakReference()\n"));
+
+ if (!aInstancePtr)
+ return NS_ERROR_NULL_POINTER;
+
+ jobject javaObject = GetJNIEnv()->CallObjectMethod(mJavaWeakRef,
+ getReferentMID);
+ nsJavaXPTCStubWeakRef* weakref;
+ weakref = new nsJavaXPTCStubWeakRef(javaObject, this);
+ if (!weakref)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ *aInstancePtr = weakref;
+ NS_ADDREF(*aInstancePtr);
+ ++mWeakRefCnt;
+
+ return NS_OK;
+}
+
+jobject
+nsJavaXPTCStub::GetJavaObject()
+{
+ JNIEnv* env = GetJNIEnv();
+ jobject javaObject = env->CallObjectMethod(mJavaWeakRef, getReferentMID);
+
+#ifdef DEBUG_JAVAXPCOM
+ nsIID* iid;
+ mIInfo->GetInterfaceIID(&iid);
+ char* iid_str = iid->ToString();
+ LOG(("< nsJavaXPTCStub (Java=%08x | XPCOM=%08x | IID=%s)\n",
+ (PRUint32) mJavaRefHashCode, (PRUint32) this, iid_str));
+ PR_Free(iid_str);
+ nsMemory::Free(iid);
+#endif
+
+ return javaObject;
+}
+
+
+/*static*/ nsresult
+nsJavaXPTCStub::GetNewOrUsed(JNIEnv* env, jobject aJavaObject,
+ const nsIID& aIID, void** aResult)
+{
+ nsJavaXPTCStub* stub;
+ jint hash = env->CallStaticIntMethod(systemClass, hashCodeMID, aJavaObject);
+ nsresult rv = gJavaToXPTCStubMap->Find(hash, aIID, &stub);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (stub) {
+ // stub is already AddRef'd and QI'd
+ *aResult = stub;
+ return NS_OK;
+ }
+
+ // If there is no corresponding XPCOM object, then that means that the
+ // parameter is a non-generated class (that is, it is not one of our
+ // Java stubs that represent an exising XPCOM object). So we need to
+ // create an XPCOM stub, that can route any method calls to the class.
+
+ // Get interface info for class
+ nsCOMPtr<nsIInterfaceInfoManager>
+ iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIInterfaceInfo> iinfo;
+ rv = iim->GetInfoForIID(&aIID, getter_AddRefs(iinfo));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Create XPCOM stub
+ stub = new nsJavaXPTCStub(aJavaObject, iinfo, &rv);
+ if (!stub)
+ return NS_ERROR_OUT_OF_MEMORY;
+ if (NS_FAILED(rv)) {
+ delete stub;
+ return rv;
+ }
+
+ rv = gJavaToXPTCStubMap->Add(hash, stub);
+ if (NS_FAILED(rv)) {
+ delete stub;
+ return rv;
+ }
+
+ NS_ADDREF(stub);
+ *aResult = stub;
+
+ return NS_OK;
+}
diff --git a/src/libs/xpcom18a4/java/src/nsJavaXPTCStub.h b/src/libs/xpcom18a4/java/src/nsJavaXPTCStub.h
new file mode 100644
index 00000000..90d42c8f
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsJavaXPTCStub.h
@@ -0,0 +1,153 @@
+/* ***** 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) 2005
+ * 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 ***** */
+
+#ifndef _nsJavaXPTCStub_h_
+#define _nsJavaXPTCStub_h_
+
+#include "nsXPTCUtils.h"
+#include "jni.h"
+#include "nsVoidArray.h"
+#include "nsIInterfaceInfo.h"
+#include "nsCOMPtr.h"
+#include "nsWeakReference.h"
+#include "nsJavaXPTCStubWeakRef.h"
+
+
+#define NS_JAVAXPTCSTUB_IID \
+{0x88dd8130, 0xebe6, 0x4431, {0x9d, 0xa7, 0xe6, 0xb7, 0x54, 0x74, 0xfb, 0x21}}
+
+class nsJavaXPTCStub : protected nsAutoXPTCStub,
+ public nsSupportsWeakReference
+{
+ friend class nsJavaXPTCStubWeakRef;
+
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSISUPPORTSWEAKREFERENCE
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_JAVAXPTCSTUB_IID)
+
+ nsJavaXPTCStub(jobject aJavaObject, nsIInterfaceInfo *aIInfo,
+ nsresult *rv);
+
+ virtual ~nsJavaXPTCStub();
+
+ // call this method and return result
+ NS_IMETHOD CallMethod(PRUint16 aMethodIndex,
+ const XPTMethodDescriptor *aInfo,
+ nsXPTCMiniVariant *aParams);
+
+ nsISomeInterface* GetStub() { return mXPTCStub; }
+
+ // getter for mJavaObject
+ jobject GetJavaObject();
+
+ // Deletes the strong global ref for the Java object, so it can be garbage
+ // collected if necessary. See DestroyXPTCMappingEnum().
+ void DeleteStrongRef();
+
+ /**
+ * Finds the associated nsJavaXPTCStub for the given Java object and IID.
+ * If no such stub exists, then a new one is created.
+ *
+ * @param env Java environment pointer
+ * @param aJavaObject Java object for which to find/create nsJavaXPTCStub
+ * @param aIID desired interface IID for nsJavaXPTCStub
+ * @param aResult on success, holds AddRef'd reference to nsJavaXPTCStub
+ *
+ * @return NS_OK if succeeded; all other return values are error codes.
+ */
+ static nsresult GetNewOrUsed(JNIEnv* env, jobject aJavaObject,
+ const nsIID& aIID, void** aResult);
+
+
+private:
+ NS_IMETHOD_(nsrefcnt) AddRefInternal();
+ NS_IMETHOD_(nsrefcnt) ReleaseInternal();
+
+ // Deletes this object and its members. Called by ReleaseInternal() and
+ // ReleaseWeakRef().
+ void Destroy();
+
+ // When a nsJavaXPTCStubWeakRef associated with this object is released, it
+ // calls this function to let this object know that there is one less weak
+ // ref. If there are no more weakrefs referencing this object, and no one
+ // holds a strong ref, then this function takes care of deleting the object.
+ void ReleaseWeakRef();
+
+ // returns a weak reference to a child supporting the specified interface
+ nsJavaXPTCStub * FindStubSupportingIID(const nsID &aIID);
+
+ // returns true if this stub supports the specified interface
+ PRBool SupportsIID(const nsID &aIID);
+
+ nsresult SetupJavaParams(const nsXPTParamInfo &aParamInfo,
+ const XPTMethodDescriptor* aMethodInfo,
+ PRUint16 aMethodIndex,
+ nsXPTCMiniVariant* aDispatchParams,
+ nsXPTCMiniVariant &aVariant,
+ jvalue &aJValue, nsACString &aMethodSig);
+ nsresult GetRetvalSig(const nsXPTParamInfo* aParamInfo,
+ const XPTMethodDescriptor* aMethodInfo,
+ PRUint16 aMethodIndex,
+ nsXPTCMiniVariant* aDispatchParams,
+ nsACString &aRetvalSig);
+ nsresult FinalizeJavaParams(const nsXPTParamInfo &aParamInfo,
+ const XPTMethodDescriptor* aMethodInfo,
+ PRUint16 aMethodIndex,
+ nsXPTCMiniVariant* aDispatchParams,
+ nsXPTCMiniVariant &aVariant,
+ jvalue &aJValue);
+ nsresult SetXPCOMRetval();
+
+ jobject mJavaWeakRef;
+ jobject mJavaStrongRef;
+ jint mJavaRefHashCode;
+ nsCOMPtr<nsIInterfaceInfo> mIInfo;
+
+ nsVoidArray mChildren; // weak references (cleared by the children)
+ nsJavaXPTCStub *mMaster; // strong reference
+
+ nsAutoRefCnt mWeakRefCnt; // count for number of associated weak refs
+};
+
+#ifdef VBOX
+NS_DEFINE_STATIC_IID_ACCESSOR2(nsJavaXPTCStub, NS_JAVAXPTCSTUB_IID)
+#else
+NS_DEFINE_STATIC_IID_ACCESSOR2(nsJavaXPTCStub, NS_JAVAXPTCSTUB_IID)
+#endif
+
+#endif // _nsJavaXPTCStub_h_
diff --git a/src/libs/xpcom18a4/java/src/nsJavaXPTCStubWeakRef.cpp b/src/libs/xpcom18a4/java/src/nsJavaXPTCStubWeakRef.cpp
new file mode 100644
index 00000000..cb98fc9b
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsJavaXPTCStubWeakRef.cpp
@@ -0,0 +1,98 @@
+/* ***** 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) 2005
+ * 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 ***** */
+
+#include "jni.h"
+#include "nsJavaXPTCStubWeakRef.h"
+#include "nsJavaXPTCStub.h"
+#include "nsJavaXPCOMBindingUtils.h"
+#include "nsIInterfaceInfoManager.h"
+
+
+/**
+ * How we handle XPCOM weak references to a Java object:
+ *
+ * If XPCOM requires or asks for a weak reference of a Java object, we first
+ * find (or create) an nsJavaXPTCStub for that Java object. That way, there is
+ * always an nsJavaXPTCStub for any nsJavaXPTCStubWeakRef. However, the
+ * XPTCStub may not always be 'valid'; that is, its refcount may be zero if
+ * is not currently referenced by any XPCOM class.
+ * When an XPCOM method queries the referent from the weak reference, the
+ * weak ref checks first whether the Java object is still valid. If so, we can
+ * immediately return an addref'd nsJavaXPTCStub. The XPTCStub takes care of
+ * finding an XPTCStub for the required IID.
+ */
+
+nsJavaXPTCStubWeakRef::nsJavaXPTCStubWeakRef(jobject aJavaObject,
+ nsJavaXPTCStub* aXPTCStub)
+ : mXPTCStub(aXPTCStub)
+{
+ JNIEnv* env = GetJNIEnv();
+ jobject weakref = env->NewObject(weakReferenceClass,
+ weakReferenceConstructorMID, aJavaObject);
+ mWeakRef = env->NewGlobalRef(weakref);
+}
+
+nsJavaXPTCStubWeakRef::~nsJavaXPTCStubWeakRef()
+{
+ JNIEnv* env = GetJNIEnv();
+ env->CallVoidMethod(mWeakRef, clearReferentMID);
+ env->DeleteGlobalRef(mWeakRef);
+ mXPTCStub->ReleaseWeakRef();
+}
+
+NS_IMPL_ADDREF(nsJavaXPTCStubWeakRef)
+NS_IMPL_RELEASE(nsJavaXPTCStubWeakRef)
+
+NS_IMPL_QUERY_INTERFACE1(nsJavaXPTCStubWeakRef, nsIWeakReference)
+
+NS_IMETHODIMP
+nsJavaXPTCStubWeakRef::QueryReferent(const nsIID& aIID, void** aInstancePtr)
+{
+ LOG(("nsJavaXPTCStubWeakRef::QueryReferent()\n"));
+
+ // Is weak ref still valid?
+ // We create a strong local ref to make sure Java object isn't garbage
+ // collected during this call.
+ JNIEnv* env = GetJNIEnv();
+ jobject javaObject = env->CallObjectMethod(mWeakRef, getReferentMID);
+ if (env->IsSameObject(javaObject, NULL))
+ return NS_ERROR_NULL_POINTER;
+
+ // Java object has not been garbage collected, so return QI from XPTCStub.
+ return mXPTCStub->QueryInterface(aIID, aInstancePtr);
+}
+
diff --git a/src/libs/xpcom18a4/java/src/nsJavaXPTCStubWeakRef.h b/src/libs/xpcom18a4/java/src/nsJavaXPTCStubWeakRef.h
new file mode 100644
index 00000000..b538eecb
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsJavaXPTCStubWeakRef.h
@@ -0,0 +1,63 @@
+/* ***** 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) 2005
+ * 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 ***** */
+
+#ifndef _nsJavaXPTCStubWeakRef_h_
+#define _nsJavaXPTCStubWeakRef_h_
+
+#include "jni.h"
+#include "nsIWeakReference.h"
+
+
+class nsJavaXPTCStub;
+
+/**
+ * This class represents an XPCOM weak reference to a Java object.
+ */
+class nsJavaXPTCStubWeakRef : public nsIWeakReference
+{
+public:
+ nsJavaXPTCStubWeakRef(jobject aJavaObject, nsJavaXPTCStub* aXPTCStub);
+ virtual ~nsJavaXPTCStubWeakRef();
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIWEAKREFERENCE
+
+protected:
+ jobject mWeakRef;
+ nsJavaXPTCStub* mXPTCStub;
+};
+
+#endif // _nsJavaXPTCStubWeakRef_h_
diff --git a/src/libs/xpcom18a4/java/src/nsThreadUtils.h b/src/libs/xpcom18a4/java/src/nsThreadUtils.h
new file mode 100644
index 00000000..53f3dbdb
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsThreadUtils.h
@@ -0,0 +1,399 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** 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 Mozilla code.
+ *
+ * The Initial Developer of the Original Code is Google Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * 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 ***** */
+
+#ifndef nsThreadUtils_h__
+#define nsThreadUtils_h__
+
+
+#ifdef VBOX
+#include "nsIThread.h"
+
+inline already_AddRefed<nsIThread>
+do_GetMainThread() {
+ nsIThread *thread = nsnull;
+ nsIThread::GetMainThread(&thread);
+ return already_AddRefed<nsIThread>(thread);
+}
+
+#include "VBox/com/NativeEventQueue.h"
+
+inline already_AddRefed<nsIEventQueue> do_GetMainThreadQueue()
+{
+ com::NativeEventQueue* eq = com::NativeEventQueue::getMainEventQueue();
+ NS_ASSERTION(eq != nsnull, "Must be valid");
+ return eq->getIEventQueue();
+}
+
+#else
+#include "prthread.h"
+#include "prinrval.h"
+#include "nsIThreadManager.h"
+#include "nsIThread.h"
+#include "nsIRunnable.h"
+#include "nsStringGlue.h"
+#include "nsCOMPtr.h"
+
+
+// This is needed on some systems to prevent collisions between the symbols
+// appearing in xpcom_core and xpcomglue. It may be unnecessary in the future
+// with better toolchain support.
+#ifdef MOZILLA_INTERNAL_API
+# define NS_NewThread NS_NewThread_P
+# define NS_GetCurrentThread NS_GetCurrentThread_P
+# define NS_GetMainThread NS_GetMainThread_P
+# define NS_IsMainThread NS_IsMainThread_P
+# define NS_DispatchToCurrentThread NS_DispatchToCurrentThread_P
+# define NS_DispatchToMainThread NS_DispatchToMainThread_P
+# define NS_ProcessPendingEvents NS_ProcessPendingEvents_P
+# define NS_HasPendingEvents NS_HasPendingEvents_P
+# define NS_ProcessNextEvent NS_ProcessNextEvent_P
+#endif
+
+//-----------------------------------------------------------------------------
+// These methods are alternatives to the methods on nsIThreadManager, provided
+// for convenience.
+
+/**
+ * Create a new thread, and optionally provide an initial event for the thread.
+ *
+ * @param result
+ * The resulting nsIThread object.
+ * @param initialEvent
+ * The initial event to run on this thread. This parameter may be null.
+ *
+ * @returns NS_ERROR_INVALID_ARG
+ * Indicates that the given name is not unique.
+ */
+extern NS_COM_GLUE NS_METHOD
+NS_NewThread(nsIThread **result, nsIRunnable *initialEvent = nsnull);
+
+/**
+ * Get a reference to the current thread.
+ *
+ * @param result
+ * The resulting nsIThread object.
+ */
+extern NS_COM_GLUE NS_METHOD
+NS_GetCurrentThread(nsIThread **result);
+
+/**
+ * Get a reference to the main thread.
+ *
+ * @param result
+ * The resulting nsIThread object.
+ */
+extern NS_COM_GLUE NS_METHOD
+NS_GetMainThread(nsIThread **result);
+
+/**
+ * Test to see if the current thread is the main thread.
+ *
+ * @returns PR_TRUE if the current thread is the main thread, and PR_FALSE
+ * otherwise.
+ */
+extern NS_COM_GLUE NS_METHOD_(PRBool)
+NS_IsMainThread();
+
+/**
+ * Dispatch the given event to the current thread.
+ *
+ * @param event
+ * The event to dispatch.
+ *
+ * @returns NS_ERROR_INVALID_ARG
+ * If event is null.
+ */
+extern NS_COM_GLUE NS_METHOD
+NS_DispatchToCurrentThread(nsIRunnable *event);
+
+/**
+ * Dispatch the given event to the main thread.
+ *
+ * @param event
+ * The event to dispatch.
+ * @param dispatchFlags
+ * The flags to pass to the main thread's dispatch method.
+ *
+ * @returns NS_ERROR_INVALID_ARG
+ * If event is null.
+ */
+extern NS_COM_GLUE NS_METHOD
+NS_DispatchToMainThread(nsIRunnable *event,
+ PRUint32 dispatchFlags = NS_DISPATCH_NORMAL);
+
+#ifndef XPCOM_GLUE_AVOID_NSPR
+/**
+ * Process all pending events for the given thread before returning. This
+ * method simply calls ProcessNextEvent on the thread while HasPendingEvents
+ * continues to return true and the time spent in NS_ProcessPendingEvents
+ * does not exceed the given timeout value.
+ *
+ * @param thread
+ * The thread object for which to process pending events. If null, then
+ * events will be processed for the current thread.
+ * @param timeout
+ * The maximum number of milliseconds to spend processing pending events.
+ * Events are not pre-empted to honor this timeout. Rather, the timeout
+ * value is simply used to determine whether or not to process another event.
+ * Pass PR_INTERVAL_NO_TIMEOUT to specify no timeout.
+ */
+extern NS_COM_GLUE NS_METHOD
+NS_ProcessPendingEvents(nsIThread *thread,
+ PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT);
+#endif
+
+/**
+ * Shortcut for nsIThread::HasPendingEvents.
+ *
+ * It is an error to call this function when the given thread is not the
+ * current thread. This function will return PR_FALSE if called from some
+ * other thread.
+ *
+ * @param thread
+ * The current thread or null.
+ *
+ * @returns
+ * A boolean value that if "true" indicates that there are pending events
+ * in the current thread's event queue.
+ */
+extern NS_COM_GLUE PRBool
+NS_HasPendingEvents(nsIThread *thread = nsnull);
+
+/**
+ * Shortcut for nsIThread::ProcessNextEvent.
+ *
+ * It is an error to call this function when the given thread is not the
+ * current thread. This function will simply return PR_FALSE if called
+ * from some other thread.
+ *
+ * @param thread
+ * The current thread or null.
+ * @param mayWait
+ * A boolean parameter that if "true" indicates that the method may block
+ * the calling thread to wait for a pending event.
+ *
+ * @returns
+ * A boolean value that if "true" indicates that an event from the current
+ * thread's event queue was processed.
+ */
+extern NS_COM_GLUE PRBool
+NS_ProcessNextEvent(nsIThread *thread = nsnull, PRBool mayWait = PR_TRUE);
+
+//-----------------------------------------------------------------------------
+// Helpers that work with nsCOMPtr:
+
+inline already_AddRefed<nsIThread>
+do_GetCurrentThread() {
+ nsIThread *thread = nsnull;
+ NS_GetCurrentThread(&thread);
+ return already_AddRefed<nsIThread>(thread);
+}
+
+inline already_AddRefed<nsIThread>
+do_GetMainThread() {
+ nsIThread *thread = nsnull;
+ NS_GetMainThread(&thread);
+ return already_AddRefed<nsIThread>(thread);
+}
+
+//-----------------------------------------------------------------------------
+
+#ifdef MOZILLA_INTERNAL_API
+// Fast access to the current thread. Do not release the returned pointer! If
+// you want to use this pointer from some other thread, then you will need to
+// AddRef it. Otherwise, you should only consider this pointer valid from code
+// running on the current thread.
+extern NS_COM_GLUE nsIThread *NS_GetCurrentThread();
+#endif
+
+//-----------------------------------------------------------------------------
+
+#ifndef XPCOM_GLUE_AVOID_NSPR
+
+#undef IMETHOD_VISIBILITY
+#define IMETHOD_VISIBILITY NS_COM_GLUE
+
+// This class is designed to be subclassed.
+class NS_COM_GLUE nsRunnable : public nsIRunnable
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIRUNNABLE
+
+ nsRunnable() {
+ }
+
+protected:
+ virtual ~nsRunnable() {
+ }
+};
+
+#undef IMETHOD_VISIBILITY
+#define IMETHOD_VISIBILITY NS_VISIBILITY_HIDDEN
+
+// An event that can be used to call a method on a class. The class type must
+// support reference counting.
+template <class T>
+class nsRunnableMethod : public nsRunnable
+{
+public:
+ typedef void (T::*Method)();
+
+ nsRunnableMethod(T *obj, Method method)
+ : mObj(obj), mMethod(method) {
+ NS_ADDREF(mObj);
+ }
+
+ NS_IMETHOD Run() {
+ (mObj->*mMethod)();
+ return NS_OK;
+ }
+
+private:
+ virtual ~nsRunnableMethod() {
+ NS_RELEASE(mObj);
+ }
+
+ T *mObj;
+ Method mMethod;
+};
+
+// Use this helper macro like so:
+//
+// nsCOMPtr<nsIRunnable> event =
+// NS_NEW_RUNNABLE_METHOD(MyClass, myObject, HandleEvent);
+// NS_DispatchToCurrentThread(event);
+//
+// Constraints:
+// - myObject must be of type MyClass
+// - MyClass must defined AddRef and Release methods
+//
+// NOTE: Attempts to make this a template function caused VC6 to barf :-(
+//
+#define NS_NEW_RUNNABLE_METHOD(class_, obj_, method_) \
+ new nsRunnableMethod<class_>(obj_, &class_::method_)
+
+#endif // XPCOM_GLUE_AVOID_NSPR
+
+// This class is designed to be used when you have an event class E that has a
+// pointer back to resource class R. If R goes away while E is still pending,
+// then it is important to "revoke" E so that it does not try use R after R has
+// been destroyed. nsRevocableEventPtr makes it easy for R to manage such
+// situations:
+//
+// class R;
+//
+// class E : public nsRunnable {
+// public:
+// void Revoke() {
+// mResource = nsnull;
+// }
+// private:
+// R *mResource;
+// };
+//
+// class R {
+// public:
+// void EventHandled() {
+// mEvent.Forget();
+// }
+// private:
+// nsRevocableEventPtr<E> mEvent;
+// };
+//
+// void R::PostEvent() {
+// // Make sure any pending event is revoked.
+// mEvent->Revoke();
+//
+// nsCOMPtr<nsIRunnable> event = new E();
+// if (NS_SUCCEEDED(NS_DispatchToCurrentThread(event))) {
+// // Keep pointer to event so we can revoke it.
+// mEvent = event;
+// }
+// }
+//
+// NS_IMETHODIMP E::Run() {
+// if (!mResource)
+// return NS_OK;
+// ...
+// mResource->EventHandled();
+// return NS_OK;
+// }
+//
+template <class T>
+class nsRevocableEventPtr {
+public:
+ nsRevocableEventPtr()
+ : mEvent(nsnull) {
+ }
+
+ ~nsRevocableEventPtr() {
+ Revoke();
+ }
+
+ const nsRevocableEventPtr& operator=(T *event) {
+ Revoke();
+ mEvent = event;
+ return *this;
+ }
+
+ void Revoke() {
+ if (mEvent) {
+ mEvent->Revoke();
+ mEvent = nsnull;
+ }
+ }
+
+ void Forget() {
+ mEvent = nsnull;
+ }
+
+ PRBool IsPending() {
+ return mEvent != nsnull;
+ }
+
+private:
+ // Not implemented
+ nsRevocableEventPtr(const nsRevocableEventPtr&);
+ nsRevocableEventPtr& operator=(const nsRevocableEventPtr&);
+
+ T *mEvent;
+};
+#endif
+
+#endif // nsThreadUtils_h__
diff --git a/src/libs/xpcom18a4/java/src/nsXPTCUtils.h b/src/libs/xpcom18a4/java/src/nsXPTCUtils.h
new file mode 100644
index 00000000..9a1fe3cc
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/nsXPTCUtils.h
@@ -0,0 +1,128 @@
+/* ***** 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 Mozilla XPCOM.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Benjamin Smedberg <benjamin@smedbergs.us> - New code
+ *
+ * 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 ***** */
+
+#ifndef nsXPTCUtils_h__
+#define nsXPTCUtils_h__
+
+#include "xptcall.h"
+
+#ifdef VBOX
+
+#define NS_DECLARE_STATIC_IID_ACCESSOR(the_iid) \
+ template <class Dummy> \
+ struct COMTypeInfo \
+ { \
+ static const nsIID kIID NS_HIDDEN; \
+ }; \
+ static const nsIID& GetIID() {return COMTypeInfo<int>::kIID;}
+
+
+#define NS_DEFINE_STATIC_IID_ACCESSOR2(the_interface, the_iid) \
+ template <class Dummy> \
+ const nsIID the_interface::COMTypeInfo<Dummy>::kIID NS_HIDDEN = the_iid;
+
+
+class nsIXPTCProxy : public nsISupports
+{
+public:
+ NS_IMETHOD CallMethod(PRUint16 aMethodIndex,
+ const XPTMethodDescriptor *aInfo,
+ nsXPTCMiniVariant *aParams) = 0;
+};
+
+/**
+ * This is a typedef to avoid confusion between the canonical
+ * nsISupports* that provides object identity and an interface pointer
+ * for inheriting interfaces that aren't known at compile-time.
+ */
+typedef nsISupports nsISomeInterface;
+
+/**
+ * Get a proxy object to implement the specified interface.
+ *
+ * @param aIID The IID of the interface to implement.
+ * @param aOuter An object to receive method calls from the proxy object.
+ * The stub forwards QueryInterface/AddRef/Release to the
+ * outer object. The proxy object does not hold a reference to
+ * the outer object; it is the caller's responsibility to
+ * ensure that this pointer remains valid until the stub has
+ * been destroyed.
+ * @param aStub Out parameter for the new proxy object. The object is
+ * not addrefed. The object never destroys itself. It must be
+ * explicitly destroyed by calling
+ * NS_DestroyXPTCallStub when it is no longer needed.
+ */
+XPTC_PUBLIC_API(nsresult)
+NS_GetXPTCallStub(REFNSIID aIID, nsIXPTCProxy* aOuter,
+ nsISomeInterface* *aStub);
+
+/**
+ * Destroys an XPTCall stub previously created with NS_GetXPTCallStub.
+ */
+XPTC_PUBLIC_API(void)
+NS_DestroyXPTCallStub(nsISomeInterface* aStub);
+
+
+#endif
+
+
+/**
+ * A helper class that initializes an xptcall helper at construction
+ * and releases it at destruction.
+ */
+class nsAutoXPTCStub : protected nsIXPTCProxy
+{
+public:
+ nsISomeInterface* mXPTCStub;
+
+protected:
+ nsAutoXPTCStub() : mXPTCStub(nsnull) { }
+
+ nsresult
+ InitStub(const nsIID& aIID)
+ {
+ return NS_GetXPTCallStub(aIID, this, &mXPTCStub);
+ }
+
+ ~nsAutoXPTCStub()
+ {
+ if (mXPTCStub)
+ NS_DestroyXPTCallStub(mXPTCStub);
+ }
+};
+
+#endif // nsXPTCUtils_h__
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/GREVersionRange.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/GREVersionRange.java
new file mode 100644
index 00000000..ede1a523
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/GREVersionRange.java
@@ -0,0 +1,80 @@
+/* ***** 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) 2005
+ * 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 class GREVersionRange {
+
+ private String lower;
+ private boolean lowerInclusive;
+ private String upper;
+ private boolean upperInclusive;
+
+ public GREVersionRange(String aLower, boolean aLowerInclusive,
+ String aUpper, boolean aUpperInclusive) {
+ lower = aLower;
+ lowerInclusive = aLowerInclusive;
+ upper = aUpper;
+ upperInclusive = aUpperInclusive;
+ }
+
+ public boolean check(String aVersion) {
+ VersionComparator comparator = new VersionComparator();
+ int c = comparator.compare(aVersion, lower);
+ if (c < 0) {
+ return false;
+ }
+
+ if (c == 0 && !lowerInclusive) {
+ return false;
+ }
+
+ c = comparator.compare(aVersion, upper);
+ if (c > 0) {
+ return false;
+ }
+
+ if (c == 0 && !upperInclusive) {
+ return false;
+ }
+
+ return true;
+ }
+
+}
+
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IAppFileLocProvider.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IAppFileLocProvider.java
new file mode 100644
index 00000000..633d8bbc
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IAppFileLocProvider.java
@@ -0,0 +1,92 @@
+/* ***** 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.io.File;
+
+
+/**
+ * Used by XPCOM's Directory Service to get file locations.
+ * <p>
+ * This interface is similar to <code>nsIDirectoryServiceProvider</code> and
+ * <code>nsIDirectoryServiceProvider2</code>, except that its methods use
+ * <code>java.io.File</code> instead of <code>nsIFile</code>.
+ * </p>
+ *
+ * @see Mozilla#initEmbedding
+ * @see Mozilla#initXPCOM
+ * @see <a href=
+ * "http://lxr.mozilla.org/mozilla/source/xpcom/io/nsIDirectoryService.idl">
+ * nsIDirectoryServiceProvider </a>
+ * @see <a href=
+ * "http://lxr.mozilla.org/mozilla/source/xpcom/io/nsDirectoryServiceDefs.h">
+ * Directory Service property names </a>
+ */
+public interface IAppFileLocProvider {
+
+ /**
+ * Directory Service calls this when it gets the first request for
+ * a property or on every request if the property is not persistent.
+ *
+ * @param prop the symbolic name of the file
+ * @param persistent an array of length one used to supply the output value:
+ * <ul>
+ * <li><code>true</code> - The returned file will be
+ * cached by Directory Service. Subsequent requests for
+ * this prop will bypass the provider and use the cache.
+ * </li>
+ * <li><code>false</code> - The provider will be asked
+ * for this prop each time it is requested. </li>
+ * </ul>
+ *
+ * @return the file represented by the property
+ */
+ File getFile(String prop, boolean[] persistent);
+
+ /**
+ * Directory Service calls this when it gets a request for
+ * a property and the requested type is nsISimpleEnumerator.
+ *
+ * @param prop the symbolic name of the file list
+ *
+ * @return an array of file locations
+ */
+ File[] getFiles(String prop);
+
+}
+
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IGRE.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IGRE.java
new file mode 100644
index 00000000..ecf000fe
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IGRE.java
@@ -0,0 +1,127 @@
+/* ***** 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) 2006
+ * 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.io.File;
+
+
+public interface IGRE {
+
+ /**
+ * Initializes libXUL for embedding purposes.
+ * <p>
+ * NOTE: This function must be called from the "main" thread.
+ * <p>
+ * NOTE: At the present time, this function may only be called once in
+ * a given process. Use <code>termEmbedding</code> to clean up and free
+ * resources allocated by <code>initEmbedding</code>.
+ *
+ * @param aLibXULDirectory The directory in which the libXUL shared library
+ * was found.
+ * @param aAppDirectory The directory in which the application components
+ * and resources can be found. This will map to
+ * the "resource:app" directory service key.
+ * @param aAppDirProvider A directory provider for the application. This
+ * provider will be aggregated by a libXUL provider
+ * which will provide the base required GRE keys.
+ *
+ * @throws XPCOMException if a failure occurred during initialization
+ */
+ void initEmbedding(File aLibXULDirectory, File aAppDirectory,
+ IAppFileLocProvider aAppDirProvider) throws XPCOMException;
+
+ /**
+ * Terminates libXUL embedding.
+ * <p>
+ * NOTE: Release any references to XPCOM objects that you may be holding
+ * before calling this function.
+ */
+ void termEmbedding();
+
+ /**
+ * Lock a profile directory using platform-specific semantics.
+ *
+ * @param aDirectory The profile directory to lock.
+ *
+ * @return A lock object. The directory will remain locked until the lock is
+ * released by invoking the <code>release</code> method, or by the
+ * termination of the JVM, whichever comes first.
+ *
+ * @throws XPCOMException if a failure occurred
+ */
+ ProfileLock lockProfileDirectory(File aDirectory) throws XPCOMException;
+
+ /**
+ * Fire notifications to inform the toolkit about a new profile. This
+ * method should be called after <code>initEmbedding</code> if the
+ * embedder wishes to run with a profile.
+ * <p>
+ * Normally the embedder should call <code>lockProfileDirectory</code>
+ * to lock the directory before calling this method.
+ * <p>
+ * NOTE: There are two possibilities for selecting a profile:
+ * <ul>
+ * <li>
+ * Select the profile before calling <code>initEmbedding</code>.
+ * The aAppDirProvider object passed to <code>initEmbedding</code>
+ * should provide the NS_APP_USER_PROFILE_50_DIR key, and
+ * may also provide the following keys:
+ * <ul>
+ * <li>NS_APP_USER_PROFILE_LOCAL_50_DIR
+ * <li>NS_APP_PROFILE_DIR_STARTUP
+ * <li>NS_APP_PROFILE_LOCAL_DIR_STARTUP
+ * </ul>
+ * In this scenario <code>notifyProfile</code> should be called
+ * immediately after <code>initEmbedding</code>. Component
+ * registration information will be stored in the profile and
+ * JS components may be stored in the fastload cache.
+ * </li>
+ * <li>
+ * Select a profile some time after calling <code>initEmbedding</code>.
+ * In this case the embedder must install a directory service
+ * provider which provides NS_APP_USER_PROFILE_50_DIR and optionally
+ * NS_APP_USER_PROFILE_LOCAL_50_DIR. Component registration information
+ * will be stored in the application directory and JS components will not
+ * fastload.
+ * </li>
+ * </ul>
+ */
+ void notifyProfile();
+
+}
+
+
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IJavaXPCOMUtils.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IJavaXPCOMUtils.java
new file mode 100644
index 00000000..7b70caf9
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/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/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IMozilla.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IMozilla.java
new file mode 100644
index 00000000..b148e9a2
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IMozilla.java
@@ -0,0 +1,63 @@
+/* ***** 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) 2006
+ * 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.io.File;
+
+public interface IMozilla {
+
+ /**
+ * Initialize the Mozilla object with the given XULRunner path. All
+ * subsequent Mozilla method invocations be done against the given XULRunner
+ * version.
+ *
+ * @param aLibXULDirectory path of XULRunner build to use
+ *
+ * @throws XPCOMInitializationException if failure occurred during
+ * initialization
+ */
+ void initialize(File aLibXULDirectory) throws XPCOMInitializationException;
+
+ /**
+ * Return the native window handle for an AWT component.
+ *
+ * @param widget An AWT component (such as Canvas, Frame) that is backed by
+ * a real native window.
+ * @return the pointer to the native window (platform specific)
+ */
+ long getNativeHandleFromAWT(Object widget);
+}
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/INIParser.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/INIParser.java
new file mode 100644
index 00000000..ba2f11c7
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/INIParser.java
@@ -0,0 +1,243 @@
+/* ***** 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) 2005
+ * 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.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+
+/**
+ * A simple parser for INI files.
+ */
+public class INIParser {
+
+ private HashMap<String, Properties> mSections;
+
+ /**
+ * Creates a new <code>INIParser</code> instance from the INI file at the
+ * given path. <code>aCharset</code> specifies the character encoding of
+ * the file.
+ *
+ * @param aFilename path of INI file to parse
+ * @param aCharset character encoding of file
+ * @throws FileNotFoundException if <code>aFilename</code> does not exist.
+ * @throws IOException if there is a problem reading the given file.
+ */
+ public INIParser(String aFilename, Charset aCharset)
+ throws FileNotFoundException, IOException {
+ initFromFile(new File(aFilename), aCharset);
+ }
+
+ /**
+ * Creates a new <code>INIParser</code> instance from the INI file at the
+ * given path, which is assumed to be in the <code>UTF-8</code> charset.
+ *
+ * @param aFilename path of INI file to parse
+ * @throws FileNotFoundException if <code>aFilename</code> does not exist.
+ * @throws IOException if there is a problem reading the given file.
+ */
+ public INIParser(String aFilename) throws FileNotFoundException, IOException {
+ initFromFile(new File(aFilename), Charset.forName("UTF-8"));
+ }
+
+ /**
+ * Creates a new <code>INIParser</code> instance from the given file.
+ * <code>aCharset</code> specifies the character encoding of the file.
+ *
+ * @param aFile INI file to parse
+ * @param aCharset character encoding of file
+ * @throws FileNotFoundException if <code>aFile</code> does not exist.
+ * @throws IOException if there is a problem reading the given file.
+ */
+ public INIParser(File aFile, Charset aCharset)
+ throws FileNotFoundException, IOException {
+ initFromFile(aFile, aCharset);
+ }
+
+ /**
+ * Creates a new <code>INIParser</code> instance from the given file,
+ * which is assumed to be in the <code>UTF-8</code> charset.
+ *
+ * @param aFile INI file to parse
+ * @throws FileNotFoundException if <code>aFile</code> does not exist.
+ * @throws IOException if there is a problem reading the given file.
+ */
+ public INIParser(File aFile) throws FileNotFoundException, IOException {
+ initFromFile(aFile, Charset.forName("UTF-8"));
+ }
+
+ /**
+ * Parses given INI file.
+ *
+ * @param aFile INI file to parse
+ * @param aCharset character encoding of file
+ * @throws FileNotFoundException if <code>aFile</code> does not exist.
+ * @throws IOException if there is a problem reading the given file.
+ */
+ private void initFromFile(File aFile, Charset aCharset)
+ throws FileNotFoundException, IOException {
+ FileInputStream fileStream = new FileInputStream(aFile);
+ InputStreamReader inStream = new InputStreamReader(fileStream, aCharset);
+ BufferedReader reader = new BufferedReader(inStream);
+
+ mSections = new HashMap<String, Properties>();
+ String currSection = null;
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ // skip empty lines and comment lines
+ String trimmedLine = line.trim();
+ if (trimmedLine.length() == 0 || trimmedLine.startsWith("#")
+ || trimmedLine.startsWith(";")) {
+ continue;
+ }
+
+ // Look for section headers (i.e. "[Section]").
+ if (line.startsWith("[")) {
+ /*
+ * We are looking for a well-formed "[Section]". If this header is
+ * malformed (i.e. "[Section" or "[Section]Moretext"), just skip it
+ * and go on to next well-formed section header.
+ */
+ if (!trimmedLine.endsWith("]") ||
+ trimmedLine.indexOf("]") != (trimmedLine.length() - 1)) {
+ currSection = null;
+ continue;
+ }
+
+ // remove enclosing brackets
+ currSection = trimmedLine.substring(1, trimmedLine.length() - 1);
+ continue;
+ }
+
+ // If we haven't found a valid section header, continue to next line
+ if (currSection == null) {
+ continue;
+ }
+
+ StringTokenizer tok = new StringTokenizer(line, "=");
+ if (tok.countTokens() != 2) { // looking for value pairs
+ continue;
+ }
+
+ Properties props = mSections.get(currSection);
+ if (props == null) {
+ props = new Properties();
+ mSections.put(currSection, props);
+ }
+ props.setProperty(tok.nextToken(), tok.nextToken());
+ }
+
+ reader.close();
+ }
+
+ /**
+ * Returns an iterator over the section names available in the INI file.
+ *
+ * @return an iterator over the section names
+ */
+ public Iterator getSections() {
+ return mSections.keySet().iterator();
+ }
+
+ /**
+ * Returns an iterator over the keys available within a section.
+ *
+ * @param aSection section name whose keys are to be returned
+ * @return an iterator over section keys, or <code>null</code> if no
+ * such section exists
+ */
+ public Iterator getKeys(String aSection) {
+ /*
+ * Simple wrapper class to convert Enumeration to Iterator
+ */
+ class PropertiesIterator implements Iterator {
+ private Enumeration e;
+
+ public PropertiesIterator(Enumeration aEnum) {
+ e = aEnum;
+ }
+
+ public boolean hasNext() {
+ return e.hasMoreElements();
+ }
+
+ public Object next() {
+ return e.nextElement();
+ }
+
+ public void remove() {
+ return;
+ }
+ }
+
+ Properties props = mSections.get(aSection);
+ if (props == null) {
+ return null;
+ }
+
+ return new PropertiesIterator(props.propertyNames());
+ }
+
+ /**
+ * Gets the string value for a particular section and key.
+ *
+ * @param aSection a section name
+ * @param aKey the key whose value is to be returned.
+ * @return string value of particular section and key
+ */
+ public String getString(String aSection, String aKey) {
+ Properties props = mSections.get(aSection);
+ if (props == null) {
+ return null;
+ }
+
+ return props.getProperty(aKey);
+ }
+
+}
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IXPCOM.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IXPCOM.java
new file mode 100644
index 00000000..8cfbfb30
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/IXPCOM.java
@@ -0,0 +1,137 @@
+/* ***** 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) 2006
+ * 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.io.File;
+
+import org.mozilla.interfaces.nsIComponentManager;
+import org.mozilla.interfaces.nsIComponentRegistrar;
+import org.mozilla.interfaces.nsILocalFile;
+import org.mozilla.interfaces.nsIServiceManager;
+
+
+public interface IXPCOM {
+
+ /**
+ * Initializes XPCOM. You must call this method before proceeding
+ * to use XPCOM.
+ *
+ * @param aMozBinDirectory The directory containing the component
+ * registry and runtime libraries;
+ * or use <code>null</code> to use the working
+ * directory.
+ *
+ * @param aAppFileLocProvider The object to be used by Gecko that specifies
+ * to Gecko where to find profiles, the component
+ * registry preferences and so on; or use
+ * <code>null</code> for the default behaviour.
+ *
+ * @return the service manager
+ *
+ * @throws XPCOMException <ul>
+ * <li> NS_ERROR_NOT_INITIALIZED - if static globals were not initialied,
+ * which can happen if XPCOM is reloaded, but did not completly
+ * shutdown. </li>
+ * <li> Other error codes indicate a failure during initialisation. </li>
+ * </ul>
+ */
+ nsIServiceManager initXPCOM(File aMozBinDirectory,
+ IAppFileLocProvider aAppFileLocProvider) throws XPCOMException;
+
+ /**
+ * Shutdown XPCOM. You must call this method after you are finished
+ * using xpcom.
+ *
+ * @param aServMgr The service manager which was returned by initXPCOM.
+ * This will release servMgr.
+ *
+ * @throws XPCOMException if a failure occurred during termination
+ */
+ void shutdownXPCOM(nsIServiceManager aServMgr) throws XPCOMException;
+
+ /**
+ * Public Method to access to the service manager.
+ *
+ * @return the service manager
+ *
+ * @throws XPCOMException
+ */
+ nsIServiceManager getServiceManager() throws XPCOMException;
+
+ /**
+ * Public Method to access to the component manager.
+ *
+ * @return the component manager
+ *
+ * @throws XPCOMException
+ */
+ nsIComponentManager getComponentManager() throws XPCOMException;
+
+ /**
+ * Public Method to access to the component registration manager.
+ *
+ * @return the component registration manager
+ *
+ * @throws XPCOMException
+ */
+ nsIComponentRegistrar getComponentRegistrar() throws XPCOMException;
+
+ /**
+ * Public Method to create an instance of a nsILocalFile.
+ *
+ * @param aPath A string which specifies a full file path to a
+ * location. Relative paths will be treated as an
+ * error (NS_ERROR_FILE_UNRECOGNIZED_PATH).
+ * @param aFollowLinks This attribute will determine if the nsLocalFile will
+ * auto resolve symbolic links. By default, this value
+ * will be false on all non unix systems. On unix, this
+ * attribute is effectively a noop.
+ *
+ * @return an instance of an nsILocalFile that points to given path
+ *
+ * @throws XPCOMException <ul>
+ * <li> NS_ERROR_FILE_UNRECOGNIZED_PATH - raised for unrecognized paths
+ * or relative paths (must supply full file path) </li>
+ * </ul>
+ */
+ nsILocalFile newLocalFile(String aPath, boolean aFollowLinks)
+ throws XPCOMException;
+
+ // #ifdef VBOX
+ int waitForEvents(long timeout);
+ // #endif VBOX
+}
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/Mozilla.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/Mozilla.java
new file mode 100644
index 00000000..05314c90
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/Mozilla.java
@@ -0,0 +1,1079 @@
+/* ***** 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) 2006
+ * 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.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.mozilla.interfaces.nsIComponentManager;
+import org.mozilla.interfaces.nsIComponentRegistrar;
+import org.mozilla.interfaces.nsILocalFile;
+import org.mozilla.interfaces.nsIServiceManager;
+import org.mozilla.interfaces.nsISupports;
+
+
+/**
+ * A singleton class which provides access to the Mozilla browser. Requires
+ * that XULRunner be installed on the user's system.
+ * <p>
+ * You would use to class to find a XULRunner installation, setup a profile (if
+ * necessary), and initialize embedding. A typical scenario would look like
+ * this:
+ * </p><pre>
+ * Mozilla mozilla = Mozilla.getInstance();
+ * GREVersionRange[] range = new GREVersionRange[1];
+ * range[0] = new GREVersionRange("1.8.0.*", false, "1.8.1.*", true);
+ * try {
+ * File grePath = Mozilla.getGREPathWithProperties(range, null);
+ * mozilla.initialize(grePath);
+ * profLock = mozilla.lockProfileDirectory(profileDir);
+ * // LocationProvider is a user class that implements IAppFileLocProvider
+ * LocationProvider locProvider = new LocationProvider(grePath, profileDir);
+ * mozilla.initEmbedding(grePath, grePath, locProvider);
+ * mozilla.notifyProfile();
+ * } catch (XPCOMInitializationException xie) {
+ * // handle exception
+ * } catch (XPCOMException xe) {
+ * // handle exception
+ * }
+ * </pre>
+ *
+ * @see http://www.mozilla.org/projects/embedding/GRE.html
+ */
+public class Mozilla implements IMozilla, IGRE, IXPCOM, IJavaXPCOMUtils,XPCOMError {
+
+ private static Mozilla mozillaInstance = new Mozilla();
+
+ private static final String JAVAXPCOM_JAR = "vboxjxpcom.jar";
+
+ private IMozilla mozilla = null;
+ private IGRE gre = null;
+ private IXPCOM xpcom = null;
+ private IJavaXPCOMUtils jxutils = null;
+
+ /**
+ * @return
+ */
+ public static Mozilla getInstance() {
+ return mozillaInstance;
+ }
+
+ /**
+ *
+ */
+ private Mozilla() {
+ }
+
+ /**
+ * Locates the path of a GRE with the specified properties. This method
+ * will only return GREs that support Java embedding (looks for the
+ * presence of "javaxpcom.jar").
+ * <p>
+ * Currently this uses a "first-fit" algorithm, it does not select
+ * the newest available GRE.
+ *
+ * @param aVersions An array of version ranges: if any version range
+ * matches, the GRE is considered acceptable.
+ * @param aProperties A list of GRE property/value pairs which must
+ * all be satisfied. This parameter is ignored on
+ * Macintosh, because of the manner in which the
+ * XUL frameworks are installed.
+ *
+ * @return A file object of the appropriate path. If
+ * the "local" GRE is specified (via the USE_LOCAL_GRE
+ * environment variable, for example), returns
+ * <code>null</code>.
+ *
+ * @throws FileNotFoundException if an appropriate GRE could not be found
+ */
+ public static File getGREPathWithProperties(GREVersionRange[] aVersions,
+ Properties aProperties) throws FileNotFoundException {
+ File grePath = null;
+
+ // if GRE_HOME is in the environment, use that GRE
+ String env = System.getProperty("GRE_HOME");
+ if (env != null) {
+ try {
+ grePath = new File(env).getCanonicalFile();
+ } catch (IOException e) {
+ throw new FileNotFoundException("cannot access GRE_HOME");
+ }
+ if (!grePath.exists()) {
+ throw new FileNotFoundException("GRE_HOME doesn't exist");
+ }
+ return grePath;
+ }
+
+ // the Gecko bits that sit next to the application or in the PATH
+ env = System.getProperty("USE_LOCAL_GRE");
+ if (env != null) {
+ return null;
+ }
+
+ // Search for GRE in platform specific locations. We want a GRE that
+ // supports Java, so we look for the "javaxpcom" property by default.
+ if (aProperties == null) {
+ aProperties = new Properties();
+ }
+ aProperties.setProperty("javaxpcom", "1");
+
+ String osName = System.getProperty("os.name").toLowerCase();
+ if (osName.startsWith("mac os x")) {
+ grePath = getGREPathMacOSX(aVersions);
+ } else if (osName.startsWith("windows")) {
+ grePath = getGREPathWindows(aVersions, aProperties);
+ } else {
+ // assume everything else is Unix/Linux
+ grePath = getGREPathUnix(aVersions, aProperties);
+ }
+
+ if (grePath == null) {
+ throw new FileNotFoundException("GRE not found");
+ }
+
+ return grePath;
+ }
+
+ /**
+ * @param aVersions
+ * @return
+ */
+ private static File getGREPathMacOSX(GREVersionRange[] aVersions) {
+ /*
+ * Check the application bundle first, for
+ * <bundle>/Contents/Frameworks/XUL.framework/libxpcom.dylib.
+ */
+ File grePath = findGREBundleFramework();
+ if (grePath != null) {
+ return grePath;
+ }
+
+ // Check ~/Library/Frameworks/XUL.framework/Versions/<version>/libxpcom.dylib
+ String home = System.getProperty("user.home");
+ if (home != null) {
+ grePath = findGREFramework(home, aVersions);
+ if (grePath != null) {
+ return grePath;
+ }
+ }
+
+ // Check /Library/Frameworks/XUL.framework/Versions/<version>/libxpcom.dylib
+ return findGREFramework("", aVersions);
+ }
+
+ /**
+ * @return
+ */
+ private static File findGREBundleFramework() {
+ /*
+ * Use reflection to get Apple's NSBundle class, which can be used
+ * to get the bundle's "Frameworks" directory.
+ */
+ try {
+ URL[] urls = new URL[1];
+ urls[0] = new File("/System/Library/Java/").toURI().toURL();
+ ClassLoader loader = new URLClassLoader(urls);
+ Class<?> bundleClass = Class.forName("com.apple.cocoa.foundation.NSBundle",
+ true, loader);
+
+ // Get the bundle for this app. If this is not executing from
+ // a bundle, this will return null.
+ Method mainBundleMethod = bundleClass.getMethod("mainBundle", (java.lang.Class[])null);
+ Object bundle = mainBundleMethod.invoke(null, (java.lang.Object[])null);
+
+ if (bundle != null) {
+ // Get the path to the bundle's "Frameworks" directory
+ Method fwPathMethod = bundleClass.getMethod("privateFrameworksPath",
+ (java.lang.Class[])null);
+ String path = (String) fwPathMethod.invoke(bundle, (java.lang.Object[])null);
+
+ // look for libxpcom.dylib
+ if (path.length() != 0) {
+ File xulDir = new File(path, "XUL.framework");
+ if (xulDir.isDirectory()) {
+ File xpcomLib = new File(xulDir, "libxpcom.dylib");
+ if (xpcomLib.canRead()) {
+ File grePath = xpcomLib.getCanonicalFile().getParentFile();
+
+ // Since GRE Properties aren't supported on Mac OS X, we check
+ // for the existence of the "javaxpcom.jar" file in the GRE.
+ File jar = new File(grePath, JAVAXPCOM_JAR);
+ if (jar.canRead()) {
+ // found GRE
+ return grePath;
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) { }
+
+ return null;
+ }
+
+ /**
+ * @param aRootPath
+ * @param aVersions
+ * @return
+ */
+ private static File findGREFramework(String aRootPath,
+ GREVersionRange[] aVersions) {
+ File frameworkDir = new File(aRootPath +
+ "/Library/Frameworks/XUL.framework/Versions");
+ if (!frameworkDir.exists())
+ return null;
+
+ File[] files = frameworkDir.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ if (checkVersion(files[i].getName(), aVersions)) {
+ File xpcomLib = new File(files[i], "libxpcom.dylib");
+
+ // Since GRE Properties aren't supported on Mac OS X, we check
+ // for the existence of the "javaxpcom.jar" file in the GRE.
+ File jar = new File(files[i], JAVAXPCOM_JAR);
+ if (xpcomLib.canRead() && jar.canRead()) {
+ return files[i];
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @param aVersions
+ * @param aProperties
+ * @return
+ */
+ private static File getGREPathWindows(GREVersionRange[] aVersions,
+ Properties aProperties) {
+ /*
+ * Note the usage of the "Software\\mozilla.org\\GRE" subkey - this allows
+ * us to have multiple versions of GREs on the same machine by having
+ * subkeys such as 1.0, 1.1, 2.0 etc. under it.
+ *
+ * Please see http://www.mozilla.org/projects/embedding/GRE.html for
+ * more info.
+ */
+
+ final String greKey = "Software\\mozilla.org\\GRE";
+
+ // See if there is a GRE registered for the current user.
+ // If not, look for one on the system.
+ String key = "HKEY_CURRENT_USER" + "\\" + greKey;
+ File grePath = getGREPathFromRegKey(key, aVersions, aProperties);
+ if (grePath == null) {
+ key = "HKEY_LOCAL_MACHINE" + "\\" + greKey;
+ grePath = getGREPathFromRegKey(key, aVersions, aProperties);
+ }
+
+ return grePath;
+ }
+
+ /**
+ * @param aRegKey
+ * @param aVersions
+ * @param aProperties
+ * @return
+ */
+ private static File getGREPathFromRegKey(String aRegKey,
+ GREVersionRange[] aVersions, Properties aProperties) {
+ // create a temp file for the registry export
+ File tempFile;
+ try {
+ tempFile = File.createTempFile("jx_registry", null);
+ } catch (IOException e) {
+ // failed to create temp file. ABORT
+ return null;
+ }
+
+ Process proc;
+ try {
+ proc = Runtime.getRuntime().exec("regedit /e " + "\"" + tempFile.getPath()
+ + "\" \"" + aRegKey + "\"");
+ proc.waitFor();
+ } catch (Exception e) {
+ // Failed to run regedit.exe. Length of temp file is zero, and that's
+ // handled next.
+ }
+
+ // If there is a key by that name in the registry, then the file length
+ // will not be zero.
+ File grePath = null;
+ if (tempFile.length() != 0) {
+ grePath = getGREPathFromRegistryFile(tempFile.getPath(),
+ aRegKey, aVersions, aProperties);
+ }
+
+ tempFile.delete();
+ return grePath;
+ }
+
+ /**
+ * @param aFileName
+ * @param aCharset
+ * @param aKeyName
+ * @param aVersions
+ * @param aProperties
+ * @return
+ */
+ private static File getGREPathFromRegistryFile(String aFileName,
+ String aKeyName, GREVersionRange[] aVersions,
+ Properties aProperties) {
+ INIParser parser;
+ try {
+ parser = new INIParser(aFileName, Charset.forName("UTF-16"));
+ } catch (Exception e) {
+ // Problem reading from file. Bail out.
+ return null;
+ }
+
+ Iterator sectionsIter = parser.getSections();
+ while (sectionsIter.hasNext()) {
+ // get 'section' name, which will be a registry key name
+ String section = (String) sectionsIter.next();
+
+ // Skip over GRE key ("<root>\Software\mozilla.org\GRE")
+ int gre_len = aKeyName.length();
+ if (section.length() <= gre_len) {
+ continue;
+ }
+
+ // Get the GRE subkey; that is, everything after
+ // "<root>\Software\mozilla.org\GRE\"
+ String subkeyName = section.substring(gre_len + 1);
+
+ // We are only interested in _immediate_ subkeys. We want
+ // "<root>\Software\mozilla.org\GRE\<version>" but not
+ // "<root>\Software\mozilla.org\GRE\<version>\<moretext>".
+ if (subkeyName.indexOf('\\') != -1) {
+ continue;
+ }
+
+ // See if this registry key has a "Version" value, and if so, compare
+ // it to our desired versions.
+ String version = parser.getString(section, "\"Version\"");
+ if (version == null) {
+ continue;
+ }
+ // remove quotes around string
+ version = version.substring(1, version.length() - 1);
+ if (!checkVersion(version, aVersions)) {
+ continue;
+ }
+
+ // All properties must match, keeping in mind that the propery/value
+ // pairs returned by regedit.exe have quotes around them.
+ if (aProperties != null) {
+ boolean ok = true;
+ Enumeration e = aProperties.propertyNames();
+ while (ok && e.hasMoreElements()) {
+ String prop = (String) e.nextElement();
+ String greValue = parser.getString(section, "\"" + prop + "\"");
+ if (greValue == null) {
+ // No such property is set for this GRE. Go on to next GRE.
+ ok = false;
+ } else {
+ // See if the value of the property for the GRE matches
+ // the given value.
+ String value = aProperties.getProperty(prop);
+ if (!greValue.equals("\"" + value + "\"")) {
+ ok = false;
+ }
+ }
+ }
+ if (!ok) {
+ continue;
+ }
+ }
+
+ String pathStr = parser.getString(section, "\"GreHome\"");
+ if (pathStr != null) {
+ // remove quotes around string
+ pathStr = pathStr.substring(1, pathStr.length() - 1);
+ File grePath = new File(pathStr);
+ if (grePath.exists()) {
+ File xpcomLib = new File(grePath, "xpcom.dll");
+ if (xpcomLib.canRead()) {
+ // found a good GRE
+ return grePath;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @param aVersions
+ * @param aProperties
+ * @return
+ */
+ private static File getGREPathUnix(GREVersionRange[] aVersions,
+ Properties aProperties) {
+ File grePath = null;
+
+ String env = System.getProperty("MOZ_GRE_CONF");
+ if (env != null) {
+ grePath = getPathFromConfigFile(env, aVersions, aProperties);
+ if (grePath != null) {
+ return grePath;
+ }
+ }
+
+ final String greUserConfFile = ".gre.config";
+ final String greUserConfDir = ".gre.d";
+ final String greConfPath = "/etc/gre.conf";
+ final String greConfDir = "/etc/gre.d";
+
+ env = System.getProperty("user.home");
+ if (env != null) {
+ // Look in ~/.gre.config
+ grePath = getPathFromConfigFile(env + File.separator + greUserConfFile,
+ aVersions, aProperties);
+ if (grePath != null) {
+ return grePath;
+ }
+
+ // Look in ~/.gre.d/*.conf
+ grePath = getPathFromConfigDir(env + File.separator + greUserConfDir,
+ aVersions, aProperties);
+ if (grePath != null) {
+ return grePath;
+ }
+ }
+
+ // Look for a global /etc/gre.conf file
+ grePath = getPathFromConfigFile(greConfPath, aVersions, aProperties);
+ if (grePath != null) {
+ return grePath;
+ }
+
+ // Look for a group of config files in /etc/gre.d/
+ grePath = getPathFromConfigDir(greConfDir, aVersions, aProperties);
+ return grePath;
+ }
+
+ /**
+ * @param aFileName
+ * @param aVersions
+ * @param aProperties
+ * @return
+ */
+ private static File getPathFromConfigFile(String aFileName,
+ GREVersionRange[] aVersions, Properties aProperties) {
+ INIParser parser;
+ try {
+ parser = new INIParser(aFileName);
+ } catch (Exception e) {
+ // Problem reading from file. Bail out.
+ return null;
+ }
+
+ Iterator sectionsIter = parser.getSections();
+ while (sectionsIter.hasNext()) {
+ // get 'section' name, which will be a version string
+ String section = (String) sectionsIter.next();
+
+ // if this isn't one of the versions we are looking for, move
+ // on to next section
+ if (!checkVersion(section, aVersions)) {
+ continue;
+ }
+
+ // all properties must match
+ if (aProperties != null) {
+ boolean ok = true;
+ Enumeration e = aProperties.propertyNames();
+ while (ok && e.hasMoreElements()) {
+ String prop = (String) e.nextElement();
+ String greValue = parser.getString(section, prop);
+ if (greValue == null) {
+ // No such property is set for this GRE. Go on to next GRE.
+ ok = false;
+ } else {
+ // See if the value of the property for the GRE matches
+ // the given value.
+ if (!greValue.equals(aProperties.getProperty(prop))) {
+ ok = false;
+ }
+ }
+ }
+ if (!ok) {
+ continue;
+ }
+ }
+
+ String pathStr = parser.getString(section, "GRE_PATH");
+ if (pathStr != null) {
+ File grePath = new File(pathStr);
+ if (grePath.exists()) {
+ File xpcomLib = new File(grePath, "libxpcom.so");
+ if (xpcomLib.canRead()) {
+ // found a good GRE
+ return grePath;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @param aDirName
+ * @param aVersions
+ * @param aProperties
+ * @return
+ */
+ private static File getPathFromConfigDir(String aDirName,
+ GREVersionRange[] aVersions, Properties aProperties) {
+ /*
+ * Open the directory provided and try to read any files in that
+ * directory that end with .conf. We look for an entry that might
+ * point to the GRE that we're interested in.
+ */
+
+ File dir = new File(aDirName);
+ if (!dir.isDirectory()) {
+ return null;
+ }
+
+ File grePath = null;
+ File[] files = dir.listFiles();
+ for (int i = 0; i < files.length && grePath == null; i++) {
+ // only look for files that end in '.conf'
+ if (!files[i].getName().endsWith(".conf")) {
+ continue;
+ }
+
+ grePath = getPathFromConfigFile(files[i].getPath(), aVersions,
+ aProperties);
+ }
+
+ return grePath;
+ }
+
+ /**
+ * @param aVersionToCheck
+ * @param aVersions
+ * @return
+ */
+ private static boolean checkVersion(String aVersionToCheck,
+ GREVersionRange[] aVersions) {
+ for (int i = 0; i < aVersions.length; i++) {
+ if (aVersions[i].check(aVersionToCheck)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Initialize the Mozilla object with the given XULRunner path. All
+ * subsequent Mozilla method invocations be done against the given XULRunner
+ * version.
+ *
+ * @param aLibXULDirectory path of XULRunner build to use
+ *
+ * @throws XPCOMInitializationException if failure occurred during
+ * initialization
+ */
+ public void initialize(File aLibXULDirectory)
+ throws XPCOMInitializationException {
+ File jar = new File(aLibXULDirectory, JAVAXPCOM_JAR);
+ if (!jar.exists()) {
+ jar = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
+ if (!jar.exists())
+ throw new XPCOMInitializationException("Could not find " + JAVAXPCOM_JAR +
+ " in " + aLibXULDirectory);
+ }
+
+ URL[] urls = new URL[1];
+ try {
+ urls[0] = jar.toURI().toURL();
+ } catch (MalformedURLException e) {
+ throw new XPCOMInitializationException(e);
+ }
+ ClassLoader loader = new URLClassLoader(urls,
+ this.getClass().getClassLoader());
+
+ try {
+ Class mozillaClass = Class.forName("org.mozilla.xpcom.internal.MozillaImpl",
+ true, loader);
+ mozilla = (IMozilla) mozillaClass.newInstance();
+
+ Class greClass = Class.forName("org.mozilla.xpcom.internal.GREImpl",
+ true, loader);
+ gre = (IGRE) greClass.newInstance();
+
+ 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);
+ }
+
+ mozilla.initialize(aLibXULDirectory);
+ }
+
+ /**
+ * Initializes libXUL for embedding purposes.
+ * <p>
+ * NOTE: This function must be called from the "main" thread.
+ * <p>
+ * NOTE: At the present time, this function may only be called once in
+ * a given process. Use <code>termEmbedding</code> to clean up and free
+ * resources allocated by <code>initEmbedding</code>.
+ *
+ * @param aLibXULDirectory The directory in which the libXUL shared library
+ * was found.
+ * @param aAppDirectory The directory in which the application components
+ * and resources can be found. This will map to
+ * the "resource:app" directory service key.
+ * @param aAppDirProvider A directory provider for the application. This
+ * provider will be aggregated by a libXUL provider
+ * which will provide the base required GRE keys.
+ *
+ * @throws XPCOMException if a failure occurred during initialization
+ * @throws XPCOMInitializationException if Mozilla was not properly
+ * initialized
+ */
+ public void initEmbedding(File aLibXULDirectory, File aAppDirectory,
+ IAppFileLocProvider aAppDirProvider) throws XPCOMException {
+ try {
+ gre.initEmbedding(aLibXULDirectory, aAppDirectory, aAppDirProvider);
+ } catch (NullPointerException e) {
+ throw new XPCOMInitializationException("Must call " +
+ "Mozilla.getInstance().initialize() before using this method", e);
+ }
+ }
+
+ /**
+ * Terminates libXUL embedding.
+ * <p>
+ * NOTE: Release any references to XPCOM objects that you may be holding
+ * before calling this function.
+ *
+ * @throws XPCOMInitializationException if Mozilla was not properly
+ * initialized
+ */
+ public void termEmbedding() {
+ try {
+ gre.termEmbedding();
+ } catch (NullPointerException e) {
+ throw new XPCOMInitializationException("Must call " +
+ "Mozilla.getInstance().initialize() before using this method", e);
+ } finally {
+ mozilla = null;
+ gre = null;
+ xpcom = null;
+ }
+ }
+
+ /**
+ * Lock a profile directory using platform-specific semantics.
+ *
+ * @param aDirectory The profile directory to lock.
+ *
+ * @return A lock object. The directory will remain locked until the lock is
+ * released by invoking the <code>release</code> method, or by the
+ * termination of the JVM, whichever comes first.
+ *
+ * @throws XPCOMException if profile is already locked (with
+ * <code>errorcode</code> == <code>NS_ERROR_FILE_ACCESS_DENIED</code>);
+ * or if a failure occurred
+ * @throws XPCOMInitializationException if Mozilla was not properly
+ * initialized
+ */
+ public ProfileLock lockProfileDirectory(File aDirectory)
+ throws XPCOMException {
+ try {
+ return gre.lockProfileDirectory(aDirectory);
+ } catch (NullPointerException e) {
+ throw new XPCOMInitializationException("Must call " +
+ "Mozilla.getInstance().initialize() before using this method", e);
+ }
+ }
+
+ /**
+ * Fire notifications to inform the toolkit about a new profile. This
+ * method should be called after <code>initEmbedding</code> if the
+ * embedder wishes to run with a profile.
+ * <p>
+ * Normally the embedder should call <code>lockProfileDirectory</code>
+ * to lock the directory before calling this method.
+ * <p>
+ * NOTE: There are two possibilities for selecting a profile:
+ * <ul>
+ * <li>
+ * Select the profile before calling <code>initEmbedding</code>.
+ * The aAppDirProvider object passed to <code>initEmbedding</code>
+ * should provide the NS_APP_USER_PROFILE_50_DIR key, and
+ * may also provide the following keys:
+ * <ul>
+ * <li>NS_APP_USER_PROFILE_LOCAL_50_DIR
+ * <li>NS_APP_PROFILE_DIR_STARTUP
+ * <li>NS_APP_PROFILE_LOCAL_DIR_STARTUP
+ * </ul>
+ * In this scenario <code>notifyProfile</code> should be called
+ * immediately after <code>initEmbedding</code>. Component
+ * registration information will be stored in the profile and
+ * JS components may be stored in the fastload cache.
+ * </li>
+ * <li>
+ * Select a profile some time after calling <code>initEmbedding</code>.
+ * In this case the embedder must install a directory service
+ * provider which provides NS_APP_USER_PROFILE_50_DIR and optionally
+ * NS_APP_USER_PROFILE_LOCAL_50_DIR. Component registration information
+ * will be stored in the application directory and JS components will not
+ * fastload.
+ * </li>
+ * </ul>
+ *
+ * @throws XPCOMInitializationException if Mozilla was not properly
+ * initialized
+ */
+ public void notifyProfile() {
+ try {
+ gre.notifyProfile();
+ } catch (NullPointerException e) {
+ throw new XPCOMInitializationException("Must call " +
+ "Mozilla.getInstance().initialize() before using this method", e);
+ }
+ }
+
+ /**
+ * Initializes XPCOM. You must call this method before proceeding
+ * to use XPCOM.
+ *
+ * @param aMozBinDirectory The directory containing the component
+ * registry and runtime libraries;
+ * or use <code>null</code> to use the working
+ * directory.
+ *
+ * @param aAppFileLocProvider The object to be used by Gecko that specifies
+ * to Gecko where to find profiles, the component
+ * registry preferences and so on; or use
+ * <code>null</code> for the default behaviour.
+ *
+ * @return the service manager
+ *
+ * @throws XPCOMException <ul>
+ * <li> NS_ERROR_NOT_INITIALIZED - if static globals were not initialied,
+ * which can happen if XPCOM is reloaded, but did not completly
+ * shutdown. </li>
+ * <li> Other error codes indicate a failure during initialisation. </li>
+ * </ul>
+ * @throws XPCOMInitializationException if Mozilla was not properly
+ * initialized
+ */
+ public nsIServiceManager initXPCOM(File aMozBinDirectory,
+ IAppFileLocProvider aAppFileLocProvider) throws XPCOMException {
+ try {
+ return xpcom.initXPCOM(aMozBinDirectory, aAppFileLocProvider);
+ } catch (NullPointerException e) {
+ throw new XPCOMInitializationException("Must call " +
+ "Mozilla.getInstance().initialize() before using this method", e);
+ }
+ }
+
+ /**
+ * Shutdown XPCOM. You must call this method after you are finished
+ * using xpcom.
+ *
+ * @param aServMgr The service manager which was returned by initXPCOM.
+ * This will release servMgr.
+ *
+ * @throws XPCOMException if a failure occurred during termination
+ * @throws XPCOMInitializationException if Mozilla was not properly
+ * initialized
+ */
+ public void shutdownXPCOM(nsIServiceManager aServMgr) throws XPCOMException {
+ try {
+ xpcom.shutdownXPCOM(aServMgr);
+ } catch (NullPointerException e) {
+ throw new XPCOMInitializationException("Must call " +
+ "Mozilla.getInstance().initialize() before using this method", e);
+ } finally {
+ mozilla = null;
+ gre = null;
+ xpcom = null;
+ }
+ }
+
+ /**
+ * Public Method to access to the service manager.
+ *
+ * @return the service manager
+ *
+ * @throws XPCOMException if a failure occurred
+ * @throws XPCOMInitializationException if Mozilla was not properly
+ * initialized
+ */
+ public nsIServiceManager getServiceManager() throws XPCOMException {
+ try {
+ return xpcom.getServiceManager();
+ } catch (NullPointerException e) {
+ throw new XPCOMInitializationException("Must call " +
+ "Mozilla.getInstance().initialize() before using this method", e);
+ }
+ }
+
+ /**
+ * Public Method to access to the component manager.
+ *
+ * @return the component manager
+ *
+ * @throws XPCOMException if a failure occurred
+ * @throws XPCOMInitializationException if Mozilla was not properly
+ * initialized
+ */
+ public nsIComponentManager getComponentManager() throws XPCOMException {
+ try {
+ return xpcom.getComponentManager();
+ } catch (NullPointerException e) {
+ throw new XPCOMInitializationException("Must call " +
+ "Mozilla.getInstance().initialize() before using this method", e);
+ }
+ }
+
+ /**
+ * Public Method to access to the component registration manager.
+ *
+ * @return the component registration manager
+ *
+ * @throws XPCOMException if a failure occurred
+ * @throws XPCOMInitializationException if Mozilla was not properly
+ * initialized
+ */
+ public nsIComponentRegistrar getComponentRegistrar() throws XPCOMException {
+ try {
+ return xpcom.getComponentRegistrar();
+ } catch (NullPointerException e) {
+ throw new XPCOMInitializationException("Must call " +
+ "Mozilla.getInstance().initialize() before using this method", e);
+ }
+ }
+
+ // #ifdef VBOX
+ public int waitForEvents(long tmo) throws XPCOMException {
+ try {
+ return xpcom.waitForEvents(tmo);
+ } catch (NullPointerException e) {
+ throw new XPCOMInitializationException("Must call " +
+ "Mozilla.getInstance().initialize() before using this method", e);
+ }
+ }
+ // #endif // VBOX
+
+ /**
+ * Public Method to create an instance of a nsILocalFile.
+ *
+ * @param aPath A string which specifies a full file path to a
+ * location. Relative paths will be treated as an
+ * error (NS_ERROR_FILE_UNRECOGNIZED_PATH).
+ * @param aFollowLinks This attribute will determine if the nsLocalFile will
+ * auto resolve symbolic links. By default, this value
+ * will be false on all non unix systems. On unix, this
+ * attribute is effectively a noop.
+ *
+ * @return an instance of an nsILocalFile that points to given path
+ *
+ * @throws XPCOMException <ul>
+ * <li> NS_ERROR_FILE_UNRECOGNIZED_PATH - raised for unrecognized paths
+ * or relative paths (must supply full file path) </li>
+ * </ul>
+ * @throws XPCOMInitializationException if Mozilla was not properly
+ * initialized
+ */
+ public nsILocalFile newLocalFile(String aPath, boolean aFollowLinks)
+ throws XPCOMException {
+ try {
+ return xpcom.newLocalFile(aPath, aFollowLinks);
+ } catch (NullPointerException e) {
+ throw new XPCOMInitializationException("Must call " +
+ "Mozilla.getInstance().initialize() before using this method", e);
+ }
+ }
+
+ /**
+ * If you create a class that implements nsISupports, you will need to provide
+ * an implementation of the <code>queryInterface</code> method. This helper
+ * function provides a simple implementation. Therefore, if your class does
+ * not need to do anything special with <code>queryInterface</code>, your
+ * implementation would look like:
+ * <pre>
+ * public nsISupports queryInterface(String aIID) {
+ * return XPCOM.queryInterface(this, aIID);
+ * }
+ * </pre>
+ *
+ * @param aObject object to query
+ * @param aIID requested interface IID
+ *
+ * @return <code>aObject</code> if the given object supports that
+ * interface;
+ * <code>null</code> otherwise.
+ */
+ public static nsISupports queryInterface(nsISupports aObject, String aIID) {
+ ArrayList<Class> classes = new ArrayList<Class>();
+ classes.add(aObject.getClass());
+
+ while (!classes.isEmpty()) {
+ Class clazz = classes.remove(0);
+
+ // Skip over any class/interface in the "java.*" and "javax.*" domains.
+ String className = clazz.getName();
+ if (className.startsWith("java.") || className.startsWith("javax.")) {
+ continue;
+ }
+
+ // If given IID matches that of the current interface, then we
+ // know that aObject implements the interface specified by the given IID.
+ if (clazz.isInterface() && className.startsWith("org.mozilla")) {
+ String iid = Mozilla.getInterfaceIID(clazz);
+ if (iid != null && aIID.equals(iid)) {
+ return aObject;
+ }
+ }
+
+ // clazz didn't match, so add the interfaces it implements
+ Class[] interfaces = clazz.getInterfaces();
+ for (int i = 0; i < interfaces.length; i++ ) {
+ classes.add(interfaces[i]);
+ }
+
+ // Also add its superclass
+ Class superclass = clazz.getSuperclass();
+ if (superclass != null) {
+ classes.add(superclass);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets the interface IID for a particular Java interface. This is similar
+ * to NS_GET_IID in the C++ Mozilla files.
+ *
+ * @param aInterface interface which has defined an IID
+ *
+ * @return IID for given interface
+ */
+ public static String getInterfaceIID(Class aInterface) {
+ // Get short class name (i.e. "bar", not "org.blah.foo.bar")
+ StringBuffer iidName = new StringBuffer();
+ String fullClassName = aInterface.getName();
+ int index = fullClassName.lastIndexOf(".");
+ String className = index > 0 ? fullClassName.substring(index + 1)
+ : fullClassName;
+
+ // Create iid field name
+ if (className.startsWith("ns")) {
+ iidName.append("NS_");
+ iidName.append(className.substring(2).toUpperCase());
+ } else {
+ iidName.append(className.toUpperCase());
+ }
+ iidName.append("_IID");
+
+ String iid;
+ try {
+ Field iidField = aInterface.getDeclaredField(iidName.toString());
+ iid = (String) iidField.get(null);
+ } catch (NoSuchFieldException e) {
+ // Class may implement non-Mozilla interfaces, which would not have an
+ // IID method. In that case, just null.
+ iid = null;
+ } catch (IllegalAccessException e) {
+ // Not allowed to access that field for some reason. Write out an
+ // error message, but don't fail.
+ System.err.println("ERROR: Could not get field " + iidName.toString());
+ iid = null;
+ }
+
+ return iid;
+ }
+
+ public long getNativeHandleFromAWT(Object widget) {
+ try {
+ return mozilla.getNativeHandleFromAWT(widget);
+ } catch (NullPointerException e) {
+ throw new XPCOMInitializationException("Must call " +
+ "Mozilla.getInstance().initialize() before using this method", e);
+ }
+ }
+
+ 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/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/ProfileLock.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/ProfileLock.java
new file mode 100644
index 00000000..f995a389
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/ProfileLock.java
@@ -0,0 +1,63 @@
+/* ***** 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) 2006
+ * 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 class ProfileLock {
+
+ private long lock = 0;
+
+ public ProfileLock(long aLockObject) {
+ lock = aLockObject;
+ }
+
+ public void release() {
+ releaseNative(lock);
+ lock = 0;
+ }
+
+ private native void releaseNative(long aLockObject);
+
+ public boolean isValid() {
+ return lock != 0;
+ }
+
+ protected void finalize() throws Throwable {
+ release();
+ super.finalize();
+ }
+
+}
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/VersionComparator.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/VersionComparator.java
new file mode 100644
index 00000000..f9fb1058
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/VersionComparator.java
@@ -0,0 +1,272 @@
+/* ***** 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) 2005
+ * 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.util.Enumeration;
+import java.util.StringTokenizer;
+
+import org.mozilla.interfaces.nsISupports;
+/* import org.mozilla.interfaces.nsIVersionComparator; */
+
+
+/**
+ * Version strings are dot-separated sequences of version-parts.
+ * <p>
+ * A version-part consists of up to four parts, all of which are optional:
+ * <br><code>
+ * &lt;number-a&gt;&lt;string-b&gt;&lt;number-c&gt;
+ * &lt;string-d (everything else)&gt;
+ * </code> <p>
+ * A version-part may also consist of a single asterisk "*" which indicates
+ * "infinity".
+ * <p>
+ * Numbers are base-10, and are zero if left out.
+ * Strings are compared bytewise.
+ * <p>
+ * For additional backwards compatibility, if "string-b" is "+" then
+ * "number-a" is incremented by 1 and "string-b" becomes "pre".
+ * <p> <pre>
+ * 1.0pre1
+ * < 1.0pre2
+ * < 1.0 == 1.0.0 == 1.0.0.0
+ * < 1.1pre == 1.1pre0 == 1.0+
+ * < 1.1pre1a
+ * < 1.1pre1
+ * < 1.1pre10a
+ * < 1.1pre10
+ * </pre>
+ * Although not required by this interface, it is recommended that
+ * numbers remain within the limits of a signed char, i.e. -127 to 128.
+ */
+public class VersionComparator implements nsISupports /* implements nsIVersionComparator */ {
+
+ public nsISupports queryInterface(String aIID) {
+ return Mozilla.queryInterface(this, aIID);
+ }
+
+ /**
+ * Compare two version strings
+ * @param A a version string
+ * @param B a version string
+ * @return a value less than 0 if A < B;
+ * the value 0 if A == B;
+ * or a value greater than 0 if A > B
+ */
+ public int compare(String A, String B) {
+ int result;
+ String a = A, b = B;
+
+ do {
+ VersionPart va = new VersionPart();
+ VersionPart vb = new VersionPart();
+ a = parseVersionPart(a, va);
+ b = parseVersionPart(b, vb);
+
+ result = compareVersionPart(va, vb);
+ if (result != 0) {
+ break;
+ }
+ } while (a != null || b != null);
+
+ return result;
+ }
+
+ private class VersionPart {
+ int numA = 0;
+ String strB;
+ int numC = 0;
+ String extraD;
+ }
+
+ private static String parseVersionPart(String aVersion, VersionPart result) {
+ if (aVersion == null || aVersion.length() == 0) {
+ return aVersion;
+ }
+
+ StringTokenizer tok = new StringTokenizer(aVersion.trim(), ".");
+ String part = tok.nextToken();
+
+ if (part.equals("*")) {
+ result.numA = Integer.MAX_VALUE;
+ result.strB = "";
+ } else {
+ VersionPartTokenizer vertok = new VersionPartTokenizer(part);
+ try {
+ result.numA = Integer.parseInt(vertok.nextToken());
+ } catch (NumberFormatException e) {
+ // parsing error; default to zero like 'strtol' C function
+ result.numA = 0;
+ }
+
+ if (vertok.hasMoreElements()) {
+ String str = vertok.nextToken();
+
+ // if part is of type "<num>+"
+ if (str.charAt(0) == '+') {
+ result.numA++;
+ result.strB = "pre";
+ } else {
+ // else if part is of type "<num><alpha>..."
+ result.strB = str;
+
+ if (vertok.hasMoreTokens()) {
+ try {
+ result.numC = Integer.parseInt(vertok.nextToken());
+ } catch (NumberFormatException e) {
+ // parsing error; default to zero like 'strtol' C function
+ result.numC = 0;
+ }
+ if (vertok.hasMoreTokens()) {
+ result.extraD = vertok.getRemainder();
+ }
+ }
+ }
+ }
+ }
+
+ if (tok.hasMoreTokens()) {
+ // return everything after "."
+ return aVersion.substring(part.length() + 1);
+ }
+ return null;
+ }
+
+ private int compareVersionPart(VersionPart va, VersionPart vb) {
+ int res = compareInt(va.numA, vb.numA);
+ if (res != 0) {
+ return res;
+ }
+
+ res = compareString(va.strB, vb.strB);
+ if (res != 0) {
+ return res;
+ }
+
+ res = compareInt(va.numC, vb.numC);
+ if (res != 0) {
+ return res;
+ }
+
+ return compareString(va.extraD, vb.extraD);
+ }
+
+ private int compareInt(int n1, int n2) {
+ return n1 - n2;
+ }
+
+ private int compareString(String str1, String str2) {
+ // any string is *before* no string
+ if (str1 == null) {
+ return (str2 != null) ? 1 : 0;
+ }
+
+ if (str2 == null) {
+ return -1;
+ }
+
+ return str1.compareTo(str2);
+ }
+
+}
+
+/**
+ * Specialized tokenizer for Mozilla version strings. A token can
+ * consist of one of the four sections of a version string: <code>
+ * &lt;number-a&gt;&lt;string-b&gt;&lt;number-c&gt;
+ * &lt;string-d (everything else)&gt;</code>.
+ */
+class VersionPartTokenizer implements Enumeration {
+
+ String part;
+
+ public VersionPartTokenizer(String aPart) {
+ part = aPart;
+ }
+
+ public boolean hasMoreElements() {
+ return part.length() != 0;
+ }
+
+ public boolean hasMoreTokens() {
+ return part.length() != 0;
+ }
+
+ public Object nextElement() {
+ if (part.matches("[\\+\\-]?[0-9].*")) {
+ // if string starts with a number...
+ int index = 0;
+ if (part.charAt(0) == '+' || part.charAt(0) == '-') {
+ index = 1;
+ }
+
+ while (index < part.length() && Character.isDigit(part.charAt(index))) {
+ index++;
+ }
+
+ String numPart = part.substring(0, index);
+ part = part.substring(index);
+ return numPart;
+ } else {
+ // ... or if this is the non-numeric part of version string
+ int index = 0;
+ while (index < part.length() && !Character.isDigit(part.charAt(index))) {
+ index++;
+ }
+
+ String alphaPart = part.substring(0, index);
+ part = part.substring(index);
+ return alphaPart;
+ }
+ }
+
+ public String nextToken() {
+ return (String) nextElement();
+ }
+
+ /**
+ * Returns what remains of the original string, without tokenization. This
+ * method is useful for getting the <code>&lt;string-d (everything else)&gt;
+ * </code> section of a version string.
+ *
+ * @return remaining version string
+ */
+ public String getRemainder() {
+ return part;
+ }
+
+}
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/XPCOMException.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/XPCOMException.java
new file mode 100644
index 00000000..9eca58f6
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/XPCOMException.java
@@ -0,0 +1,95 @@
+/* ***** 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 exception is thrown whenever an internal XPCOM/Gecko error occurs.
+ * You can query the error ID returned by XPCOM by checking
+ * <code>errorcode</code> field.
+ */
+public class XPCOMException extends RuntimeException {
+
+ /**
+ * The XPCOM error value.
+ */
+ public long errorcode;
+
+ private static final long serialVersionUID = 198521829884000593L;
+
+ /**
+ * Constructs a new XPCOMException instance, with a default error
+ * (NS_ERROR_FAILURE) and message.
+ */
+ public XPCOMException() {
+ this(0x80004005L, "Unspecified internal XPCOM error");
+ }
+
+ /**
+ * Constructs a new XPCOMException instance with the given message, passing
+ * NS_ERROR_FAILURE as the error code.
+ *
+ * @param message detailed message of exception
+ */
+ public XPCOMException(String message) {
+ this(0x80004005L, message);
+ }
+
+ /**
+ * Constructs a new XPCOMException instance with the given code, passing
+ * a default message.
+ *
+ * @param code internal XPCOM error ID
+ */
+ public XPCOMException(long code) {
+ this(code, "Internal XPCOM error");
+ }
+
+ /**
+ * Constructs a new XPCOMException instance with an error code and message.
+ *
+ * @param code internal XPCOM error ID
+ * @param message detailed message of exception
+ */
+ public XPCOMException(long code, String message) {
+ super(message + " (0x" + Long.toHexString(code) + ")");
+ this.errorcode = code;
+ }
+
+}
+
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/XPCOMInitializationException.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/XPCOMInitializationException.java
new file mode 100644
index 00000000..26ce5325
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/XPCOMInitializationException.java
@@ -0,0 +1,56 @@
+/* ***** 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) 2006
+ * 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 class XPCOMInitializationException extends RuntimeException {
+
+ private static final long serialVersionUID = -7067350325909231055L;
+
+ public XPCOMInitializationException(String message) {
+ super(message);
+ }
+
+ public XPCOMInitializationException(Throwable cause) {
+ super(cause);
+ }
+
+ public XPCOMInitializationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/GREImpl.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/GREImpl.java
new file mode 100644
index 00000000..74821c36
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/GREImpl.java
@@ -0,0 +1,63 @@
+/* ***** 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) 2006
+ * 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.io.File;
+
+import org.mozilla.xpcom.IAppFileLocProvider;
+import org.mozilla.xpcom.IGRE;
+import org.mozilla.xpcom.ProfileLock;
+
+
+public class GREImpl implements IGRE {
+
+ public void initEmbedding(File aLibXULDirectory, File aAppDirectory,
+ IAppFileLocProvider aAppDirProvider) {
+ initEmbeddingNative(aLibXULDirectory, aAppDirectory, aAppDirProvider);
+ }
+
+ public native void initEmbeddingNative(File aLibXULDirectory,
+ File aAppDirectory, IAppFileLocProvider aAppDirProvider);
+
+ public native void termEmbedding();
+
+ public native ProfileLock lockProfileDirectory(File aDirectory);
+
+ public native void notifyProfile();
+
+}
+
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/JavaXPCOMMethods.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/JavaXPCOMMethods.java
new file mode 100644
index 00000000..ab0ca251
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/JavaXPCOMMethods.java
@@ -0,0 +1,104 @@
+/* ***** 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) 2006
+ * 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.io.File;
+
+import org.mozilla.xpcom.IJavaXPCOMUtils;
+
+
+public class JavaXPCOMMethods implements IJavaXPCOMUtils {
+
+ public static void registerJavaXPCOMMethods(File aLibXULDirectory) {
+ // load JNI library
+ String path = "";
+ if (aLibXULDirectory != null) {
+ path = aLibXULDirectory + File.separator;
+ }
+
+ if (false)
+ {
+ String osName = System.getProperty("os.name").toLowerCase();
+ if (osName.startsWith("os/2")) {
+ System.load(path + System.mapLibraryName("jxpcmglu"));
+ } else {
+ System.load(path + System.mapLibraryName("javaxpcomglue"));
+ }
+ } else {
+ // #ifdef VBOX
+ try {
+ System.load(path + System.mapLibraryName("vboxjxpcom"));
+ } catch (java.lang.UnsatisfiedLinkError ule) {
+ System.loadLibrary("vboxjxpcom");
+ }
+ // #endif
+ }
+ registerJavaXPCOMMethodsNative(aLibXULDirectory);
+ }
+
+ public static native void
+ registerJavaXPCOMMethodsNative(File aLibXULDirectory);
+
+ /**
+ * Returns the Class object associated with the class or interface with the
+ * given string name, using the class loader of the given object.
+ *
+ * @param aObject the Java object whose class loader is used to load class
+ * @param aClassName the fully qualified name of desired class
+ * @return the Class object of requested Class; <code>null</code> if the
+ * class was not found
+ *
+ * @see http://java.sun.com/j2se/1.3/docs/guide/jni/jni-12.html#classops
+ */
+ public static Class findClassInLoader(Object aObject, String aClassName) {
+ try {
+ if (aObject == null) {
+ return Class.forName(aClassName);
+ } else {
+ return Class.forName(aClassName, true,
+ aObject.getClass().getClassLoader());
+ }
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ public native long wrapJavaObject(Object aJavaObject, String aIID);
+
+ public native Object wrapXPCOMObject(long aXPCOMObject, String aIID);
+
+}
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/MozillaImpl.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/MozillaImpl.java
new file mode 100644
index 00000000..27fd9482
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/MozillaImpl.java
@@ -0,0 +1,56 @@
+/* ***** 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) 2006
+ * 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.io.File;
+
+import org.mozilla.xpcom.IMozilla;
+import org.mozilla.xpcom.XPCOMInitializationException;
+
+public class MozillaImpl implements IMozilla {
+
+ public void initialize(File aLibXULDirectory)
+ throws XPCOMInitializationException {
+ JavaXPCOMMethods.registerJavaXPCOMMethods(aLibXULDirectory);
+ initializeNative();
+ }
+
+ private native void initializeNative();
+
+ public native long getNativeHandleFromAWT(Object widget);
+
+}
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMImpl.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMImpl.java
new file mode 100644
index 00000000..1111a9e0
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMImpl.java
@@ -0,0 +1,73 @@
+/* ***** 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) 2006
+ * 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.io.File;
+
+import org.mozilla.xpcom.IAppFileLocProvider;
+import org.mozilla.xpcom.IXPCOM;
+
+import org.mozilla.interfaces.nsIComponentManager;
+import org.mozilla.interfaces.nsIComponentRegistrar;
+import org.mozilla.interfaces.nsILocalFile;
+import org.mozilla.interfaces.nsIServiceManager;
+
+
+public class XPCOMImpl implements IXPCOM {
+
+ public nsIServiceManager initXPCOM(File aMozBinDirectory,
+ IAppFileLocProvider aAppFileLocProvider) {
+ return initXPCOMNative(aMozBinDirectory, aAppFileLocProvider);
+ }
+
+ public native nsIServiceManager initXPCOMNative(File aMozBinDirectory,
+ IAppFileLocProvider aAppFileLocProvider);
+
+ public native void shutdownXPCOM(nsIServiceManager aServMgr);
+
+ public native nsIComponentManager getComponentManager();
+
+ public native nsIComponentRegistrar getComponentRegistrar();
+
+ public native nsIServiceManager getServiceManager();
+
+ public native nsILocalFile newLocalFile(String aPath, boolean aFollowLinks);
+
+ // #ifdef VBOX
+ public native int waitForEvents(long timeout);
+ // #endif VBOX
+}
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);
+
+}
diff --git a/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxyBase.java b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxyBase.java
new file mode 100644
index 00000000..595a7a2c
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/mozilla/xpcom/internal/XPCOMJavaProxyBase.java
@@ -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.internal;
+
+
+/**
+ * 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;
+
+}
diff --git a/src/libs/xpcom18a4/java/src/org/virtualbox/VBoxObjectBase.java b/src/libs/xpcom18a4/java/src/org/virtualbox/VBoxObjectBase.java
new file mode 100644
index 00000000..0a765fa0
--- /dev/null
+++ b/src/libs/xpcom18a4/java/src/org/virtualbox/VBoxObjectBase.java
@@ -0,0 +1,31 @@
+/* $Id: VBoxObjectBase.java $ */
+/*
+ * Copyright (C) 2010-2022 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+import org.mozilla.interfaces.nsISupports;
+
+public abstract class VBoxObjectBase implements nsISupports
+{
+ public nsISupports queryInterface(String iid)
+ {
+ return org.mozilla.xpcom.Mozilla.queryInterface(this, iid);
+ }
+}
diff --git a/src/libs/xpcom18a4/java/tools/gen-nsError.pl b/src/libs/xpcom18a4/java/tools/gen-nsError.pl
new file mode 100755
index 00000000..da866b83
--- /dev/null
+++ b/src/libs/xpcom18a4/java/tools/gen-nsError.pl
@@ -0,0 +1,161 @@
+#! /usr/bin/env perl
+# ***** 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
+# Michal Ceresna.
+# Portions created by the Initial Developer are Copyright (C) 2005
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Michal Ceresna (ceresna@dbai.tuwien.ac.at)
+# 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 *****
+
+# Generates XPCOMError.java from xpcom/base/nsError.h
+#
+# usage: perl gen-nsErrors.pl < <topsrcdir>/xpcom/base/nsError.h > XPCOMError.java
+
+
+print "/* ***** BEGIN LICENSE BLOCK *****\n";
+print " * Version: MPL 1.1/GPL 2.0/LGPL 2.1\n";
+print " *\n";
+print " * The contents of this file are subject to the Mozilla Public License Version\n";
+print " * 1.1 (the \"License\"); you may not use this file except in compliance with\n";
+print " * the License. You may obtain a copy of the License at\n";
+print " * http://www.mozilla.org/MPL/\n";
+print " *\n";
+print " * Software distributed under the License is distributed on an \"AS IS\" basis,\n";
+print " * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n";
+print " * for the specific language governing rights and limitations under the\n";
+print " * License.\n";
+print " *\n";
+print " * The Original Code is mozilla.org code.\n";
+print " *\n";
+print " * The Initial Developer of the Original Code is\n";
+print " * Netscape Communications Corporation.\n";
+print " * Portions created by the Initial Developer are Copyright (C) 1998\n";
+print " * the Initial Developer. All Rights Reserved.\n";
+print " *\n";
+print " * Contributor(s):\n";
+print " *\n";
+print " * Alternatively, the contents of this file may be used under the terms of\n";
+print " * either of the GNU General Public License Version 2 or later (the \"GPL\"),\n";
+print " * or the GNU Lesser General Public License Version 2.1 or later (the \"LGPL\"),\n";
+print " * in which case the provisions of the GPL or the LGPL are applicable instead\n";
+print " * of those above. If you wish to allow use of your version of this file only\n";
+print " * under the terms of either the GPL or the LGPL, and not to allow others to\n";
+print " * use your version of this file under the terms of the MPL, indicate your\n";
+print " * decision by deleting the provisions above and replace them with the notice\n";
+print " * and other provisions required by the GPL or the LGPL. If you do not delete\n";
+print " * the provisions above, a recipient may use your version of this file under\n";
+print " * the terms of any one of the MPL, the GPL or the LGPL.\n";
+print " *\n";
+print " * ***** END LICENSE BLOCK ***** */\n";
+
+print "\n";
+print "package org.mozilla.xpcom;\n";
+print "\n\n";
+
+print "/**\n";
+print " * Mozilla error codes.\n";
+print " *\n";
+print " * THIS FILE GENERATED FROM mozilla/xpcom/base/nsError.h.\n";
+print " * PLEASE SEE THAT FILE FOR FULL DOCUMENTATION.\n";
+print " */\n";
+print "public interface XPCOMError {\n";
+
+while (<STDIN>) {
+ $line = $_;
+
+ if ($prevline) {
+ $_ = $prevline.$_;
+ }
+ if (/(.*)\\$/) {
+ #splitted line
+ $prevline = $1;
+ next;
+ }
+ $prevline = "";
+
+ if (/^\s*#define\s+(NS_[A-Z_]+)\s+(0x)?([0-9a-fA-F]+)\s*$/) {
+ #define NS_ERROR_MODULE_XPCOM 1
+ #define NS_ERROR_MODULE_BASE_OFFSET 0x45
+ print " public static final long $1 = $2$3L;\n";
+ }
+ elsif (/^\s*#define\s+(NS_[A-Z_]+)\s+\((NS_[A-Z_]+)\s+\+\s+(0x)?([0-9a-fA-F]+)\s*\)\s*/) {
+ #define NS_ERROR_NOT_INITIALIZED (NS_ERROR_BASE + 1)
+ #define NS_ERROR_FACTORY_EXISTS (NS_ERROR_BASE + 0x100)
+ print " public static final long $1 = $2 + $3$4L;\n";
+ }
+ elsif (/^\s*#define\s+(NS_[A-Z_]+)\s+(NS_[A-Z_]+)\s\s*/) {
+ #define NS_ERROR_NO_INTERFACE NS_NOINTERFACE
+ print " public static final long $1 = $2;\n";
+ }
+ elsif (/^\s*#define\s+(NS_[A-Z_]+)\s+\(\(nsresult\)\s*(0x)?([0-9a-fA-F]+)L?\)\s*$/) {
+ #define NS_ERROR_BASE ((nsresult) 0xC1F30000)
+ #define NS_ERROR_ABORT ((nsresult) 0x80004004L)
+ print " public static final long $1 = $2$3L;\n";
+ }
+ elsif (/^\s*#define\s+(NS_[A-Z_]+)\s+NS_ERROR_GENERATE_FAILURE\s*\(\s*(NS_[A-Z_]+)\s*,\s*([0-9]+)\s*\)\s*$/) {
+ #define NS_BASE_STREAM_CLOSED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 2)
+ $module = $2;
+ $code = $3;
+ print " public static final long $1 = ((NS_ERROR_SEVERITY_ERROR<<31) | (($module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | $code);\n";
+ }
+ elsif (/^\s*#define\s+(NS_[A-Z_]+)\s+NS_ERROR_GENERATE_SUCCESS\s*\(\s*(NS_[A-Z_]+)\s*,\s*([0-9]+)\s*\)\s*$/) {
+ #define NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 1)
+ $module = $2;
+ $code = $3;
+ print " public static final long $1 = ((NS_ERROR_SEVERITY_SUCCESS<<31) | (($module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | $code);\n";
+ }
+ elsif (/^\s*\/\*(.*)\*\/\s*$/ && !/^\s*\/\*@[\{\}]\*\/\s*$/ &&
+ !/^\s*\/\*\ -\*- Mode:/) {
+ #single line comment, but not
+ #/*@{*/, /*@}*/,
+ #/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+ print " /*$1*/\n";
+ }
+ elsif (/^\s*$/) {
+ #empty line, but write only the first
+ #line from a sequence of empty lines
+ if (!$wasEmpty) {
+ print "\n";
+ }
+ $wasEmpty = 1;
+ next;
+ }
+ else {
+ next;
+ }
+
+ $wasEmpty = 0;
+}
+
+print "}\n";
+
diff --git a/src/libs/xpcom18a4/java/tools/genifaces/GenerateJavaInterfaces.cpp b/src/libs/xpcom18a4/java/tools/genifaces/GenerateJavaInterfaces.cpp
new file mode 100644
index 00000000..60648beb
--- /dev/null
+++ b/src/libs/xpcom18a4/java/tools/genifaces/GenerateJavaInterfaces.cpp
@@ -0,0 +1,952 @@
+/* ***** 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) 2005
+ * 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 ***** */
+
+#include "nsXPCOM.h"
+#include "nsString.h"
+#include "nsILocalFile.h"
+#include "nsIInterfaceInfoManager.h"
+#include "xptinfo.h"
+#include "nsCOMPtr.h"
+#include "prmem.h"
+#include "xptcall.h"
+#ifdef VBOX
+#include "nsFileStreams.h"
+static nsresult
+NS_NewLocalFileInputStream(nsIInputStream **aResult,
+ nsIFile *aFile,
+ PRInt32 aIOFlags = -1,
+ PRInt32 aPerm = -1,
+ PRInt32 aBehaviorFlags = 0)
+{
+ nsFileInputStream* in = new nsFileInputStream();
+ nsresult rv;
+
+ rv = in->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
+ if (NS_SUCCEEDED(rv))
+ NS_ADDREF(*aResult = in);
+
+ return rv;
+}
+
+inline nsresult
+NS_NewLocalFileOutputStream(nsIOutputStream **aResult,
+ nsIFile *aFile,
+ PRInt32 aIOFlags = -1,
+ PRInt32 aPerm = -1,
+ PRInt32 aBehaviorFlags = 0)
+{
+ nsFileOutputStream* in = new nsFileOutputStream();
+ nsresult rv;
+
+ rv = in->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
+ if (NS_SUCCEEDED(rv))
+ NS_ADDREF(*aResult = in);
+
+ return rv;
+}
+
+
+#else
+#include "nsNetUtil.h"
+#endif
+#include "nsHashSets.h"
+#include "nsIWeakReference.h"
+#include <stdio.h>
+
+#ifdef WIN32
+#define snprintf _snprintf
+#endif
+
+#define WRITE_NOSCRIPT_METHODS
+
+
+class TypeInfo
+{
+public:
+ static nsresult GetParentInfo(nsIInterfaceInfo* aIInfo,
+ nsIInterfaceInfo** aParentInfo,
+ PRUint16* aParentMethodCount,
+ PRUint16* aParentConstCount)
+ {
+ nsCOMPtr<nsIInterfaceInfo> parent;
+ nsresult rv = aIInfo->GetParent(getter_AddRefs(parent));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!parent) {
+ *aParentInfo = nsnull;
+ *aParentMethodCount = 0;
+ return NS_OK;
+ }
+
+ rv = parent->GetMethodCount(aParentMethodCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = parent->GetConstantCount(aParentConstCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ *aParentInfo = parent;
+ NS_ADDREF(*aParentInfo);
+ return rv;
+ }
+
+ static nsresult GetInterfaceName(nsIInterfaceInfo* aIInfo,
+ PRUint16 aMethodIndex,
+ const nsXPTParamInfo* aParamInfo,
+ char** aResult)
+ {
+ static const char isupp_str[] = "nsISupports";
+
+ nsIID* iid;
+ nsresult rv = aIInfo->GetIIDForParam(aMethodIndex, aParamInfo, &iid);
+ if (NS_FAILED(rv)) {
+ // GetIIDForParam will sometimes fail to find an interface, particularly
+ // if that interface is not defined in an IDL file. In those cases, just
+ // return |nsISupports|.
+ //
+ // For example, the |onStreamComplete| method for the interface
+ // |nsIUnicharStreamLoaderObserver| takes a param of
+ // |nsIUnicharInputStream|, which is defined in a simple header file, not
+ // an IDL file.
+ *aResult = (char*) nsMemory::Clone(isupp_str, sizeof(isupp_str));
+ rv = (*aResult == nsnull) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
+
+ } else {
+
+ // In Javaconnect, we handle weak references internally; no need for the
+ // |nsIWeakReference| interface. So just return |nsISupports|.
+ if (iid->Equals(NS_GET_IID(nsIWeakReference))) {
+ *aResult = (char*) nsMemory::Clone(isupp_str, sizeof(isupp_str));
+ rv = (*aResult == nsnull) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
+
+ } else {
+
+ // Some methods take parameters of non-scriptable interfaces. But we
+ // only output scriptable interfaces. So if one of the param types is
+ // a non-scriptable interface, output |nsISupports| instead of the
+ // interface name.
+ nsCOMPtr<nsIInterfaceInfo> info;
+ nsCOMPtr<nsIInterfaceInfoManager> iim =
+ getter_AddRefs(XPTI_GetInterfaceInfoManager());
+ NS_ASSERTION(iim, "could not get interface info manager");
+ rv = iim->GetInfoForIID(iid, getter_AddRefs(info));
+ NS_ENSURE_SUCCESS(rv, rv);
+ PRBool scriptable;
+ if (NS_SUCCEEDED(rv)) {
+ info->IsScriptable(&scriptable);
+ }
+ if (NS_FAILED(rv) || !scriptable) {
+ *aResult = (char*) nsMemory::Clone(isupp_str, sizeof(isupp_str));
+ rv = (*aResult == nsnull) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
+ } else {
+
+ // If is scriptable, get name for given IID
+ rv = iim->GetNameForIID(iid, aResult);
+ }
+ }
+
+ nsMemory::Free(iid);
+ }
+
+ return rv;
+ }
+};
+
+
+static const char* kJavaKeywords[] = {
+ "abstract", "default", "if" , "private" , "this" ,
+ "boolean" , "do" , "implements", "protected" , "throw" ,
+ "break" , "double" , "import", "public" , "throws" ,
+ "byte" , "else" , "instanceof", "return" , "transient",
+ "case" , "extends", "int" , "short" , "try" ,
+ "catch" , "final" , "interface" , "static" , "void" ,
+ "char" , "finally", "long" , "strictfp" , "volatile" ,
+ "class" , "float" , "native" , "super" , "while" ,
+ "const" , "for" , "new" , "switch" ,
+ "continue", "goto" , "package" , "synchronized",
+ "assert" , /* added in Java 1.4 */
+ "enum" , /* added in Java 5.0 */
+ "clone" , /* clone is a member function of java.lang.Object */
+ "finalize" /* finalize is a member function of java.lang.Object */
+};
+
+#ifdef WRITE_NOSCRIPT_METHODS
+// SWT uses [noscript] methods of the following interfaces, so we need to
+// output the [noscript] methods for these interfaces.
+static const char* kNoscriptMethodIfaces[] = {
+ "nsIBaseWindow", "nsIEmbeddingSiteWindow"
+};
+#endif
+
+
+class Generate
+{
+ nsILocalFile* mOutputDir;
+ nsCStringHashSet mIfaceTable;
+ nsCStringHashSet mJavaKeywords;
+#ifdef WRITE_NOSCRIPT_METHODS
+ nsCStringHashSet mNoscriptMethodsTable;
+#endif
+
+public:
+ Generate(nsILocalFile* aOutputDir)
+ : mOutputDir(aOutputDir)
+ {
+ mIfaceTable.Init(100);
+
+ PRUint32 size = NS_ARRAY_LENGTH(kJavaKeywords);
+ mJavaKeywords.Init(size);
+ for (PRUint32 i = 0; i < size; i++) {
+ mJavaKeywords.Put(nsDependentCString(kJavaKeywords[i]));
+ }
+
+#ifdef WRITE_NOSCRIPT_METHODS
+ size = NS_ARRAY_LENGTH(kNoscriptMethodIfaces);
+ mNoscriptMethodsTable.Init(size);
+ for (PRUint32 j = 0; j < size; j++) {
+ mNoscriptMethodsTable.Put(nsDependentCString(kNoscriptMethodIfaces[j]));
+ }
+#endif
+ }
+
+ ~Generate()
+ {
+ }
+
+ nsresult GenerateInterfaces()
+ {
+ nsresult rv;
+
+ nsCOMPtr<nsIInterfaceInfoManager> iim =
+ getter_AddRefs(XPTI_GetInterfaceInfoManager());
+ NS_ASSERTION(iim, "could not get interface info manager");
+ nsCOMPtr<nsIEnumerator> etor;
+ rv = iim->EnumerateInterfaces(getter_AddRefs(etor));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // loop over interfaces
+ etor->First();
+ do {
+ // get current interface
+ nsCOMPtr<nsISupports> item;
+ rv = etor->CurrentItem(getter_AddRefs(item));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIInterfaceInfo> iface(do_QueryInterface(item));
+ if (!iface)
+ break;
+
+ // we only care about scriptable interfaces, so skip over those
+ // that aren't
+ PRBool scriptable;
+ iface->IsScriptable(&scriptable);
+ if (!scriptable) {
+ // XXX SWT uses non-scriptable interface 'nsIAppShell' (bug 270892), so
+ // include that one.
+ const char* iface_name;
+ iface->GetNameShared(&iface_name);
+ if (strcmp("nsIAppShell", iface_name) != 0)
+ continue;
+ }
+
+ rv = WriteOneInterface(iface);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ } while (NS_SUCCEEDED(etor->Next()));
+
+ return NS_OK;
+ }
+
+ nsresult WriteOneInterface(nsIInterfaceInfo* aIInfo)
+ {
+ nsresult rv;
+
+ // write each interface only once
+ const char* iface_name;
+ aIInfo->GetNameShared(&iface_name);
+ if (mIfaceTable.Contains(nsDependentCString(iface_name)))
+ return NS_OK;
+
+ // write any parent interface
+ nsCOMPtr<nsIInterfaceInfo> parentInfo;
+ PRUint16 parentMethodCount, parentConstCount;
+ rv = TypeInfo::GetParentInfo(aIInfo, getter_AddRefs(parentInfo),
+ &parentMethodCount, &parentConstCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (parentInfo)
+ WriteOneInterface(parentInfo);
+
+ mIfaceTable.Put(nsDependentCString(iface_name));
+
+ // create file for interface
+ nsCOMPtr<nsIOutputStream> out;
+ rv = OpenIfaceFileStream(iface_name, getter_AddRefs(out));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // write contents to file
+ rv = WriteHeader(out, iface_name);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = WriteInterfaceStart(out, aIInfo, parentInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = WriteIID(out, aIInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = WriteConstants(out, aIInfo, parentConstCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = WriteMethods(out, aIInfo, parentMethodCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = WriteInterfaceEnd(out);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = CloseIfaceFileStream(out);
+
+ return rv;
+ }
+
+ nsresult OpenIfaceFileStream(const char* aIfaceName,
+ nsIOutputStream** aResult)
+ {
+ nsresult rv;
+
+ // create interface file in output dir
+ nsCOMPtr<nsIFile> iface_file;
+ rv = mOutputDir->Clone(getter_AddRefs(iface_file));
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsAutoString filename;
+ filename.AppendASCII(aIfaceName);
+ filename.AppendLiteral(".java");
+ rv = iface_file->Append(filename);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // create interface file
+ PRBool exists;
+ iface_file->Exists(&exists);
+ if (exists)
+ iface_file->Remove(PR_FALSE);
+ rv = iface_file->Create(nsIFile::NORMAL_FILE_TYPE, 0644);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // create output stream for writing to file
+ nsCOMPtr<nsIOutputStream> out;
+ rv = NS_NewLocalFileOutputStream(getter_AddRefs(out), iface_file);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ *aResult = out;
+ NS_ADDREF(*aResult);
+ return NS_OK;
+ }
+
+ nsresult CloseIfaceFileStream(nsIOutputStream* out)
+ {
+ return out->Close();
+ }
+
+ nsresult WriteHeader(nsIOutputStream* out, const char* aIfaceName)
+ {
+ static const char kHeader1[] =
+ "/**\n"
+ " * NOTE: THIS IS A GENERATED FILE. PLEASE CONSULT THE ORIGINAL IDL FILE\n"
+ " * FOR THE FULL DOCUMENTION AND LICENSE.\n"
+ " *\n"
+ " * @see <a href=\"http://lxr.mozilla.org/mozilla/search?string=";
+ static const char kHeader2[]= "\">\n **/\n\n";
+ static const char kPackage[] = "package org.mozilla.interfaces;\n\n";
+
+ PRUint32 count;
+ nsresult rv = out->Write(kHeader1, sizeof(kHeader1) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCAutoString searchTerm;
+ searchTerm.AppendLiteral("interface+");
+ searchTerm.AppendASCII(aIfaceName);
+ // LXR limits to 29 chars
+ rv = out->Write(searchTerm.get(), PR_MIN(29, searchTerm.Length()), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = out->Write(kHeader2, sizeof(kHeader2) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(kPackage, sizeof(kPackage) - 1, &count);
+ return rv;
+ }
+
+ nsresult WriteInterfaceStart(nsIOutputStream* out, nsIInterfaceInfo* aIInfo,
+ nsIInterfaceInfo* aParentInfo)
+ {
+ static const char kIfaceDecl1[] = "public interface ";
+ static const char kParentDecl[] = " extends ";
+ static const char kIfaceDecl2[] = "\n{\n";
+
+ const char* iface_name;
+ aIInfo->GetNameShared(&iface_name);
+ PRUint32 count;
+ nsresult rv = out->Write(kIfaceDecl1, sizeof(kIfaceDecl1) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(iface_name, strlen(iface_name), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (aParentInfo) {
+ const char* parent_name;
+ aParentInfo->GetNameShared(&parent_name);
+ rv = out->Write(kParentDecl, sizeof(kParentDecl) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(parent_name, strlen(parent_name), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ rv = out->Write(kIfaceDecl2, sizeof(kIfaceDecl2) - 1, &count);
+ return rv;
+ }
+
+ nsresult WriteInterfaceEnd(nsIOutputStream* out)
+ {
+ PRUint32 count;
+ return out->Write("}\n", 2, &count);
+ }
+
+ nsresult WriteIID(nsIOutputStream* out, nsIInterfaceInfo* aIInfo)
+ {
+ static const char kIIDDecl1[] = " public static final String ";
+ static const char kIIDDecl2[] = " =\n \"";
+ static const char kIIDDecl3[] = "\";\n\n";
+
+ nsIID* iid = nsnull;
+ aIInfo->GetInterfaceIID(&iid);
+ if (!iid)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ // create iid field name
+ nsCAutoString iid_name;
+ const char* iface_name;
+ aIInfo->GetNameShared(&iface_name);
+ if (strncmp("ns", iface_name, 2) == 0) {
+ iid_name.AppendLiteral("NS_");
+ iid_name.Append(iface_name + 2);
+ } else {
+ iid_name.Append(iface_name);
+ }
+ iid_name.AppendLiteral("_IID");
+ ToUpperCase(iid_name);
+
+ // get iid string
+ char* iid_str = iid->ToString();
+ if (!iid_str)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ PRUint32 count;
+ nsresult rv = out->Write(kIIDDecl1, sizeof(kIIDDecl1) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(iid_name.get(), iid_name.Length(), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(kIIDDecl2, sizeof(kIIDDecl2) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(iid_str, strlen(iid_str), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(kIIDDecl3, sizeof(kIIDDecl3) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // cleanup
+ PR_Free(iid_str);
+ nsMemory::Free(iid);
+ return NS_OK;
+ }
+
+ nsresult WriteConstants(nsIOutputStream* out, nsIInterfaceInfo* aIInfo,
+ PRUint16 aParentConstCount)
+ {
+ static const char kConstDecl1[] = " public static final ";
+ static const char kConstDecl2[] = " = ";
+ static const char kConstDecl3[] = ";\n\n";
+
+ PRUint16 constCount;
+ nsresult rv = aIInfo->GetConstantCount(&constCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ for (PRUint16 i = aParentConstCount; i < constCount; i++) {
+ const nsXPTConstant* constInfo;
+ rv = aIInfo->GetConstant(i, &constInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PRUint32 count;
+ rv = out->Write(kConstDecl1, sizeof(kConstDecl1) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ const nsXPTType &type = constInfo->GetType();
+ rv = WriteType(out, &type, aIInfo, nsnull, nsnull);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(" ", 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ const char* name = constInfo->GetName();
+ rv = out->Write(name, strlen(name), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(kConstDecl2, sizeof(kConstDecl2) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = WriteConstantValue(out, &type, constInfo->GetValue());
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(kConstDecl3, sizeof(kConstDecl3) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+ }
+
+ nsresult WriteConstantValue(nsIOutputStream* out, const nsXPTType* aType,
+ const nsXPTCMiniVariant* aValue)
+ {
+ char buf[32];
+ switch (aType->TagPart()) {
+ case nsXPTType::T_I8:
+ snprintf(buf, sizeof(buf), "%d", aValue->val.i8);
+ break;
+
+ case nsXPTType::T_U8:
+ snprintf(buf, sizeof(buf), "%u", aValue->val.u8);
+ break;
+
+ case nsXPTType::T_I16:
+ snprintf(buf, sizeof(buf), "%d", aValue->val.i16);
+ break;
+
+ case nsXPTType::T_U16:
+ snprintf(buf, sizeof(buf), "%u", aValue->val.u16);
+ break;
+
+ case nsXPTType::T_I32:
+ snprintf(buf, sizeof(buf), "%d", aValue->val.i32);
+ break;
+
+ case nsXPTType::T_U32:
+ snprintf(buf, sizeof(buf), "%uL", aValue->val.u32);
+ break;
+
+ case nsXPTType::T_I64:
+ snprintf(buf, sizeof(buf), "%lldL", aValue->val.i64);
+ break;
+
+ case nsXPTType::T_U64:
+ snprintf(buf, sizeof(buf), "%lluL", aValue->val.u64);
+ break;
+
+ case nsXPTType::T_FLOAT:
+ snprintf(buf, sizeof(buf), "%f", aValue->val.f);
+ break;
+
+ case nsXPTType::T_DOUBLE:
+ snprintf(buf, sizeof(buf), "%f", aValue->val.d);
+ break;
+
+ case nsXPTType::T_BOOL:
+ if (aValue->val.b)
+ sprintf(buf, "true");
+ else
+ sprintf(buf, "false");
+ break;
+
+ case nsXPTType::T_CHAR:
+ snprintf(buf, sizeof(buf), "%c", aValue->val.c);
+ break;
+
+ case nsXPTType::T_WCHAR:
+ snprintf(buf, sizeof(buf), "%c", aValue->val.wc);
+ break;
+
+ default:
+ NS_WARNING("unexpected constant type");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ PRUint32 count;
+ return out->Write(buf, strlen(buf), &count);
+ }
+
+ nsresult WriteMethods(nsIOutputStream* out, nsIInterfaceInfo* aIInfo,
+ PRUint16 aParentMethodCount)
+ {
+ PRUint16 methodCount;
+ nsresult rv = aIInfo->GetMethodCount(&methodCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+#ifdef DEBUG_bird /* attributes first, then method. For making diffing easier. */
+ for (int pass = 0; pass < 2; pass++)
+#endif
+ for (PRUint16 i = aParentMethodCount; i < methodCount; i++) {
+ const nsXPTMethodInfo* methodInfo;
+ rv = aIInfo->GetMethodInfo(i, &methodInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+#ifdef WRITE_NOSCRIPT_METHODS
+ // XXX
+ // SWT makes use of [noscript] methods in some classes, so output them
+ // for those classes.
+
+ // skip [notxpcom] methods
+ if (methodInfo->IsNotXPCOM())
+ continue;
+
+ // skip most hidden ([noscript]) methods
+ if (methodInfo->IsHidden()) {
+ const char* iface_name;
+ aIInfo->GetNameShared(&iface_name);
+ if (!mNoscriptMethodsTable.Contains(nsDependentCString(iface_name)))
+ continue;
+ }
+#else
+ // skip hidden ([noscript]) or [notxpcom] methods
+ if (methodInfo->IsHidden() || methodInfo->IsNotXPCOM())
+ continue;
+#endif
+#ifdef DEBUG_bird /* attributes first, then method. For making diffing easier. */
+ if ((methodInfo->IsSetter() || methodInfo->IsGetter()) == pass)
+ continue;
+#endif
+
+ rv = WriteOneMethod(out, aIInfo, methodInfo, i);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+ }
+
+ nsresult WriteOneMethod(nsIOutputStream* out, nsIInterfaceInfo* aIInfo,
+ const nsXPTMethodInfo* aMethodInfo,
+ PRUint16 aMethodIndex)
+ {
+ static const char kMethodDecl1[] = " public ";
+ static const char kVoidReturn[] = "void";
+ static const char kParamSeparator[] = ", ";
+ static const char kMethodDecl2[] = ");\n\n";
+
+ PRUint32 count;
+ nsresult rv = out->Write(kMethodDecl1, sizeof(kMethodDecl1) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // write return type
+ PRUint8 paramCount = aMethodInfo->GetParamCount();
+ const nsXPTParamInfo* resultInfo = nsnull;
+ for (PRUint8 i = 0; i < paramCount; i++) {
+ const nsXPTParamInfo &paramInfo = aMethodInfo->GetParam(i);
+ if (paramInfo.IsRetval()) {
+ resultInfo = &paramInfo;
+ break;
+ }
+ }
+ if (resultInfo) {
+ rv = WriteParam(out, aIInfo, aMethodIndex, resultInfo, 0);
+ } else {
+ rv = out->Write(kVoidReturn, sizeof(kVoidReturn) - 1, &count);
+ }
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // write method name string
+ nsCAutoString method_name;
+ const char* name = aMethodInfo->GetName();
+ if (aMethodInfo->IsGetter() || aMethodInfo->IsSetter()) {
+ if (aMethodInfo->IsGetter())
+ method_name.AppendLiteral("get");
+ else
+ method_name.AppendLiteral("set");
+ method_name.Append(toupper(name[0]));
+ method_name.AppendASCII(name + 1);
+ } else {
+ method_name.Append(tolower(name[0]));
+ method_name.AppendASCII(name + 1);
+ // don't use Java keywords as method names
+ if (mJavaKeywords.Contains(method_name))
+ method_name.Append('_');
+ }
+ rv = out->Write(" ", 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(method_name.get(), method_name.Length(), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write("(", 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // write parameters
+ for (PRUint8 j = 0; j < paramCount; j++) {
+ const nsXPTParamInfo &paramInfo = aMethodInfo->GetParam(j);
+ if (paramInfo.IsRetval())
+ continue;
+
+ if (j != 0) {
+ rv = out->Write(kParamSeparator, sizeof(kParamSeparator) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ rv = WriteParam(out, aIInfo, aMethodIndex, &paramInfo, j + 1);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ rv = out->Write(kMethodDecl2, sizeof(kMethodDecl2) - 1, &count);
+ return rv;
+ }
+
+ nsresult WriteParam(nsIOutputStream* out, nsIInterfaceInfo* aIInfo,
+ PRUint16 aMethodIndex, const nsXPTParamInfo* aParamInfo,
+ PRUint8 aIndex)
+ {
+ const nsXPTType &type = aParamInfo->GetType();
+ nsresult rv = WriteType(out, &type, aIInfo, aMethodIndex, aParamInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // if parameter is 'out' or 'inout', make it a Java array
+ PRUint32 count;
+ if (aParamInfo->IsOut() && !aParamInfo->IsRetval()) {
+ rv = out->Write("[]", 2, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // write name for parameter (but not for 'retval' param)
+ if (aIndex) {
+ char buf[10];
+ snprintf(buf, sizeof(buf), " arg%d", aIndex);
+ rv = out->Write(buf, strlen(buf), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+ }
+
+ /**
+ * Write out the Java type for the given XPIDL type.
+ *
+ * NOTE: Java doesn't support unsigned types. So for any unsigned XPIDL type,
+ * we move up to the next largest Java type. This way we ensure that we don't
+ * lose any info.
+ */
+ nsresult WriteType(nsIOutputStream* out, const nsXPTType* aType,
+ nsIInterfaceInfo* aIInfo, PRUint16 aMethodIndex,
+ const nsXPTParamInfo* aParamInfo)
+ {
+ nsresult rv;
+ PRUint32 count;
+ switch (aType->TagPart()) {
+ case nsXPTType::T_I8:
+ rv = out->Write("byte", 4, &count);
+ break;
+
+ case nsXPTType::T_I16:
+ case nsXPTType::T_U8:
+ rv = out->Write("short", 5, &count);
+ break;
+
+ case nsXPTType::T_I32:
+ case nsXPTType::T_U16:
+ rv = out->Write("int", 3, &count);
+ break;
+
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U32:
+ rv = out->Write("long", 4, &count);
+ break;
+
+ case nsXPTType::T_FLOAT:
+ rv = out->Write("float", 5, &count);
+ break;
+
+ // XXX how should we handle 64-bit values?
+ case nsXPTType::T_U64:
+ case nsXPTType::T_DOUBLE:
+ rv = out->Write("double", 6, &count);
+ break;
+
+ case nsXPTType::T_BOOL:
+ rv = out->Write("boolean", 7, &count);
+ break;
+
+ case nsXPTType::T_CHAR:
+ case nsXPTType::T_WCHAR:
+ rv = out->Write("char", 4, &count);
+ break;
+
+ case nsXPTType::T_CHAR_STR:
+ case nsXPTType::T_WCHAR_STR:
+ case nsXPTType::T_IID:
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING:
+ case nsXPTType::T_UTF8STRING:
+ case nsXPTType::T_CSTRING:
+ case nsXPTType::T_PSTRING_SIZE_IS:
+ case nsXPTType::T_PWSTRING_SIZE_IS:
+ rv = out->Write("String", 6, &count);
+ break;
+
+ case nsXPTType::T_INTERFACE:
+ {
+ char* iface_name = nsnull;
+ rv = TypeInfo::GetInterfaceName(aIInfo, aMethodIndex, aParamInfo,
+ &iface_name);
+ if (NS_FAILED(rv) || !iface_name) {
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+
+ rv = out->Write(iface_name, strlen(iface_name), &count);
+ nsMemory::Free(iface_name);
+ break;
+ }
+
+ case nsXPTType::T_INTERFACE_IS:
+ rv = out->Write("nsISupports", 11, &count);
+ break;
+
+ case nsXPTType::T_VOID:
+ rv = out->Write("int", 3, &count);
+ break;
+
+ case nsXPTType::T_ARRAY:
+ {
+ // get array type
+ nsXPTType xpttype;
+ rv = aIInfo->GetTypeForParam(aMethodIndex, aParamInfo, 1, &xpttype);
+ if (NS_FAILED(rv))
+ break;
+
+ rv = WriteType(out, &xpttype, aIInfo, aMethodIndex, aParamInfo);
+ if (NS_FAILED(rv))
+ break;
+
+ rv = out->Write("[]", 2, &count);
+ break;
+ }
+
+ default:
+ fprintf(stderr, "WARNING: unexpected parameter type %d\n",
+ aType->TagPart());
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return rv;
+ }
+};
+
+void PrintUsage(char** argv)
+{
+ static const char usage_str[] =
+ "Usage: %s -d path\n"
+ " -d output directory for Java interface files\n";
+ fprintf(stderr, usage_str, argv[0]);
+}
+#ifdef VBOX
+#include <VBox/com/com.h>
+using namespace com;
+
+#include <iprt/initterm.h>
+#include <iprt/string.h>
+#include <iprt/alloca.h>
+#include <iprt/stream.h>
+#endif
+
+int main(int argc, char** argv)
+{
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsILocalFile> output_dir;
+
+#ifdef VBOX
+#if defined(VBOX_PATH_APP_PRIVATE_ARCH) && defined(VBOX_PATH_SHARED_LIBS)
+ rv = RTR3InitExe(argc, &argv, 0);
+#else
+ const char *pszHome = getenv("VBOX_PROGRAM_PATH");
+ if (pszHome) {
+ size_t cchHome = strlen(pszHome);
+ char *pszExePath = (char *)alloca(cchHome + 32);
+ memcpy(pszExePath, pszHome, cchHome);
+ memcpy(pszExePath + cchHome, "/pythonfake", sizeof("/pythonfake"));
+ rc = RTR3InitEx(RTR3INIT_VER_CUR, 0, argc, &argv, pszExePath);
+ } else {
+ rv = RTR3InitExe(argc, &argv, 0);
+ }
+#endif
+#endif
+
+ // handle command line arguments
+ for (int i = 1; i < argc; i++) {
+ if (argv[i][0] != '-') {
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+
+ switch (argv[i][1]) {
+ case 'd': {
+ if (i + 1 == argc) {
+ fprintf(stderr, "ERROR: missing output directory after -d\n");
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+
+ // see if given path exists
+ rv = NS_NewNativeLocalFile(nsDependentCString(argv[++i]), PR_TRUE,
+ getter_AddRefs(output_dir));
+ PRBool val;
+ if (NS_FAILED(rv) || NS_FAILED(output_dir->Exists(&val)) || !val ||
+ NS_FAILED(output_dir->IsDirectory(&val)) || !val)
+ {
+ fprintf(stderr,
+ "ERROR: output directory doesn't exist / isn't a directory\n");
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+
+ break;
+ }
+
+ default: {
+ fprintf(stderr, "ERROR: unknown option %s\n", argv[i]);
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+ }
+ }
+
+ if (NS_FAILED(rv)) {
+ PrintUsage(argv);
+ return 1;
+ }
+
+#ifdef VBOX
+ rv = com::Initialize();
+#else
+ rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
+#endif
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ Generate gen(output_dir);
+ rv = gen.GenerateInterfaces();
+
+#ifdef VBOX
+ // very short-living XPCOM processes trigger problem on shutdown - ignoring it not a big deal anyway
+ //com::Shutdown();
+#else
+ NS_ShutdownXPCOM(nsnull);
+#endif
+ return rv;
+}
diff --git a/src/libs/xpcom18a4/java/tools/genjifaces.xsl b/src/libs/xpcom18a4/java/tools/genjifaces.xsl
new file mode 100644
index 00000000..05455a4d
--- /dev/null
+++ b/src/libs/xpcom18a4/java/tools/genjifaces.xsl
@@ -0,0 +1,600 @@
+<xsl:stylesheet version = '1.0'
+ xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
+ xmlns:vbox="http://www.virtualbox.org/"
+ xmlns:exsl="http://exslt.org/common"
+ extension-element-prefixes="exsl">
+
+<!--
+ genjifaces.xsl:
+ XSLT stylesheet that generates Java XPCOM bridge interface code from VirtualBox.xidl.
+-->
+<!--
+ Copyright (C) 2010-2022 Oracle and/or its affiliates.
+
+ This file is part of VirtualBox base platform packages, as
+ available from https://www.virtualbox.org.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, in version 3 of the
+ License.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses>.
+
+ SPDX-License-Identifier: GPL-3.0-only
+-->
+
+<xsl:output
+ method="text"
+ version="1.0"
+ encoding="utf-8"
+ indent="no"/>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+ global XSLT variables
+ - - - - - - - - - - - - - - - - - - - - - - -->
+
+<xsl:variable name="G_xsltFilename" select="'genjifaces.xsl'" />
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+ Keys for more efficiently looking up of types.
+- - - - - - - - - - - - - - - - - - - - - - -->
+<xsl:key name="G_keyEnumsByName" match="//enum[@name]" use="@name"/>
+<xsl:key name="G_keyInterfacesByName" match="//interface[@name]" use="@name"/>
+
+<!--
+ xsltprocNewlineOutputHack - emits a single new line.
+
+ Hack Alert! This template helps xsltproc split up the output text elements
+ and avoid reallocating them into the MB range. Calls to this
+ template is made occationally while generating larger output
+ file. It's not necessary for small stuff like header.
+
+ The trick we're playing on xsltproc has to do with CDATA
+ and/or the escape setting of the xsl:text element. It forces
+ xsltproc to allocate a new output element, thus preventing
+ things from growing out of proportions and slowing us down.
+
+ This was successfully employed to reduce a 18+ seconds run to
+ around one second (possibly less due to kmk overhead).
+ -->
+<xsl:template name="xsltprocNewlineOutputHack">
+ <xsl:text disable-output-escaping="yes"><![CDATA[
+]]></xsl:text>
+</xsl:template>
+
+<xsl:template name="uppercase">
+ <xsl:param name="str" select="."/>
+ <xsl:value-of select="translate($str, 'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
+</xsl:template>
+
+<xsl:template name="capitalize">
+ <xsl:param name="str" select="."/>
+ <xsl:value-of select="
+ concat(translate(substring($str,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
+ substring($str,2))"/>
+</xsl:template>
+
+<xsl:template name="makeGetterName">
+ <xsl:param name="attrname" />
+ <xsl:variable name="capsname">
+ <xsl:call-template name="capitalize">
+ <xsl:with-param name="str" select="$attrname" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="concat('get', $capsname)" />
+</xsl:template>
+
+<xsl:template name="makeSetterName">
+ <xsl:param name="attrname" />
+ <xsl:variable name="capsname">
+ <xsl:call-template name="capitalize">
+ <xsl:with-param name="str" select="$attrname" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="concat('set', $capsname)" />
+</xsl:template>
+
+<xsl:template name="fileheader">
+ <xsl:param name="name" />
+ <xsl:text>/** @file
+</xsl:text>
+ <xsl:value-of select="concat(' * ',$name)"/>
+<xsl:text>
+ *
+ * DO NOT EDIT! This is a generated file.
+ * Generated from: src/VBox/Main/idl/VirtualBox.xidl (VirtualBox's interface definitions in XML)
+ * Generator: src/VBox/src/libs/xpcom18a4/java/tools/genjifaces.xsl
+ */
+
+/*
+ * Copyright (C) 2010-2022 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see &lt;https://www.gnu.org/licenses&gt;.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+</xsl:text>
+</xsl:template>
+
+<xsl:template name="startFile">
+ <xsl:param name="file" />
+
+ <xsl:value-of select="concat('&#10;// ##### BEGINFILE &quot;', $file, '&quot;&#10;&#10;')" />
+ <xsl:call-template name="fileheader">
+ <xsl:with-param name="name" select="$file" />
+ </xsl:call-template>
+
+ <xsl:value-of select=" 'package org.mozilla.interfaces;&#10;&#10;'" />
+</xsl:template>
+
+<xsl:template name="endFile">
+ <xsl:param name="file" />
+ <xsl:value-of select="concat('&#10;// ##### ENDFILE &quot;', $file, '&quot;&#10;')" />
+ <xsl:call-template name="xsltprocNewlineOutputHack"/>
+</xsl:template>
+
+
+<xsl:template name="emitHandwritten">
+
+ <xsl:call-template name="startFile">
+ <xsl:with-param name="file" select="'nsISupports.java'" />
+ </xsl:call-template>
+
+ <xsl:text><![CDATA[
+public interface nsISupports
+{
+ public static final String NS_ISUPPORTS_IID =
+ "{00000000-0000-0000-c000-000000000046}";
+
+ public nsISupports queryInterface(String arg1);
+}
+]]></xsl:text>
+
+ <xsl:call-template name="endFile">
+ <xsl:with-param name="file" select="'nsISupports.java'" />
+ </xsl:call-template>
+
+ <xsl:call-template name="startFile">
+ <xsl:with-param name="file" select="'nsIComponentManager.java'" />
+ </xsl:call-template>
+
+ <xsl:text><![CDATA[
+public interface nsIComponentManager extends nsISupports
+{
+ public static final String NS_ICOMPONENTMANAGER_IID =
+ "{a88e5a60-205a-4bb1-94e1-2628daf51eae}";
+
+ public nsISupports getClassObject(String arg1, String arg2);
+
+ public nsISupports getClassObjectByContractID(String arg1, String arg2);
+
+ public nsISupports createInstance(String arg1, nsISupports arg2, String arg3);
+
+ public nsISupports createInstanceByContractID(String arg1, nsISupports arg2, String arg3);
+}
+]]></xsl:text>
+
+ <xsl:call-template name="endFile">
+ <xsl:with-param name="file" select="'nsIComponentManager.java'" />
+ </xsl:call-template>
+
+ <xsl:call-template name="startFile">
+ <xsl:with-param name="file" select="'nsIServiceManager.java'" />
+ </xsl:call-template>
+
+ <xsl:text><![CDATA[
+public interface nsIServiceManager extends nsISupports
+{
+ public static final String NS_ISERVICEMANAGER_IID =
+ "{8bb35ed9-e332-462d-9155-4a002ab5c958}";
+
+ public nsISupports getService(String arg1, String arg2);
+
+ public nsISupports getServiceByContractID(String arg1, String arg2);
+
+ public boolean isServiceInstantiated(String arg1, String arg2);
+
+ public boolean isServiceInstantiatedByContractID(String arg1, String arg2);
+}
+]]></xsl:text>
+
+ <xsl:call-template name="endFile">
+ <xsl:with-param name="file" select="'nsIServiceManager.java'" />
+ </xsl:call-template>
+
+ <xsl:call-template name="startFile">
+ <xsl:with-param name="file" select="'nsIExceptionManager.java'" />
+ </xsl:call-template>
+
+ <xsl:text><![CDATA[
+public interface nsIExceptionManager extends nsISupports
+{
+ public static final String NS_IEXCEPTIONMANAGER_IID =
+ "{efc9d00b-231c-4feb-852c-ac017266a415}";
+
+ public nsIException getCurrentException();
+}
+]]></xsl:text>
+
+ <xsl:call-template name="endFile">
+ <xsl:with-param name="file" select="'nsISupports.java'" />
+ </xsl:call-template>
+
+ <xsl:call-template name="startFile">
+ <xsl:with-param name="file" select="'nsIExceptionService.java'" />
+ </xsl:call-template>
+
+ <xsl:text><![CDATA[
+public interface nsIExceptionService extends nsIExceptionManager
+{
+ public static final String NS_IEXCEPTIONSERVICE_IID =
+ "{35a88f54-f267-4414-92a7-191f6454ab52}";
+
+ public nsIExceptionManager getCurrentExceptionManager();
+}
+]]></xsl:text>
+
+ <xsl:call-template name="endFile">
+ <xsl:with-param name="file" select="'nsISupports.java'" />
+ </xsl:call-template>
+
+ <xsl:call-template name="startFile">
+ <xsl:with-param name="file" select="'nsIException.java'" />
+ </xsl:call-template>
+
+ <xsl:text><![CDATA[
+public interface nsIException extends nsISupports
+{
+ public static final String NS_IEXCEPTION_IID =
+ "{f3a8d3b4-c424-4edc-8bf6-8974c983ba78}";
+
+ // No methods - placeholder
+}
+]]></xsl:text>
+
+ <xsl:call-template name="endFile">
+ <xsl:with-param name="file" select="'nsISupports.java'" />
+ </xsl:call-template>
+
+ <xsl:call-template name="startFile">
+ <xsl:with-param name="file" select="'nsIComponentRegistrar.java'" />
+ </xsl:call-template>
+
+ <xsl:text><![CDATA[
+public interface nsIComponentRegistrar extends nsISupports
+{
+ public static final String NS_ICOMPONENTREGISTRAR_IID =
+ "{2417cbfe-65ad-48a6-b4b6-eb84db174392}";
+
+ // No methods - placeholder
+}
+]]></xsl:text>
+
+ <xsl:call-template name="endFile">
+ <xsl:with-param name="file" select="'nsIComponentRegistrar.java'" />
+ </xsl:call-template>
+
+
+ <xsl:call-template name="startFile">
+ <xsl:with-param name="file" select="'nsIFile.java'" />
+ </xsl:call-template>
+
+ <xsl:text><![CDATA[
+public interface nsIFile extends nsISupports
+{
+ public static final String NS_IFILE_IID =
+ "{c8c0a080-0868-11d3-915f-d9d889d48e3c}";
+
+ // No methods - placeholder
+}
+]]></xsl:text>
+
+ <xsl:call-template name="endFile">
+ <xsl:with-param name="file" select="'nsIFile.java'" />
+ </xsl:call-template>
+
+ <xsl:call-template name="startFile">
+ <xsl:with-param name="file" select="'nsILocalFile.java'" />
+ </xsl:call-template>
+
+ <xsl:text><![CDATA[
+public interface nsILocalFile extends nsIFile
+{
+ public static final String NS_ILOCALFILE_IID =
+ "{aa610f20-a889-11d3-8c81-000064657374}";
+
+ // No methods - placeholder
+}
+]]></xsl:text>
+
+ <xsl:call-template name="endFile">
+ <xsl:with-param name="file" select="'nsILocalFile.java'" />
+ </xsl:call-template>
+
+</xsl:template>
+
+<xsl:template name="genEnum">
+ <xsl:param name="enumname" />
+ <xsl:param name="filename" />
+
+ <xsl:call-template name="startFile">
+ <xsl:with-param name="file" select="$filename" />
+ </xsl:call-template>
+
+ <xsl:value-of select="concat('public interface ', $enumname, ' {&#10;&#10;')" />
+
+ <xsl:variable name="uppername">
+ <xsl:call-template name="uppercase">
+ <xsl:with-param name="str" select="$enumname" />
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:value-of select="concat(' public static final String ', $uppername, '_IID = &#10;',
+ ' &quot;{',@uuid, '}&quot;;&#10;&#10;')" />
+
+ <xsl:for-each select="const">
+ <xsl:variable name="enumconst" select="@name" />
+ <xsl:value-of select="concat(' public static final long ', @name, ' = ', @value, 'L;&#10;&#10;')" />
+ </xsl:for-each>
+
+ <xsl:value-of select="'}&#10;&#10;'" />
+
+ <xsl:call-template name="endFile">
+ <xsl:with-param name="file" select="$filename" />
+ </xsl:call-template>
+
+</xsl:template>
+
+<xsl:template name="typeIdl2Back">
+ <xsl:param name="type" />
+ <xsl:param name="safearray" />
+ <xsl:param name="forceelem" />
+
+ <xsl:variable name="needarray" select="($safearray='yes') and not($forceelem='yes')" />
+
+ <xsl:choose>
+ <xsl:when test="$type='unsigned long long'">
+ <!-- stupid, rewrite the bridge -->
+ <xsl:value-of select="'double'" />
+ </xsl:when>
+
+ <xsl:when test="$type='long long'">
+ <xsl:value-of select="'long'" />
+ </xsl:when>
+
+ <xsl:when test="$type='unsigned long'">
+ <xsl:value-of select="'long'" />
+ </xsl:when>
+
+ <xsl:when test="$type='long'">
+ <xsl:value-of select="'int'" />
+ </xsl:when>
+
+ <xsl:when test="$type='unsigned short'">
+ <xsl:value-of select="'int'" />
+ </xsl:when>
+
+ <xsl:when test="$type='short'">
+ <xsl:value-of select="'short'" />
+ </xsl:when>
+
+ <xsl:when test="$type='octet'">
+ <xsl:value-of select="'byte'" />
+ </xsl:when>
+
+ <xsl:when test="$type='boolean'">
+ <xsl:value-of select="'boolean'" />
+ </xsl:when>
+
+ <xsl:when test="$type='$unknown'">
+ <xsl:value-of select="'nsISupports'"/>
+ </xsl:when>
+
+ <xsl:when test="$type='wstring'">
+ <xsl:value-of select="'String'" />
+ </xsl:when>
+
+ <xsl:when test="$type='uuid'">
+ <xsl:value-of select="'String'" />
+ </xsl:when>
+
+ <xsl:when test="count(key('G_keyInterfacesByName', $type)) > 0">
+ <xsl:value-of select="$type" />
+ </xsl:when>
+
+ <xsl:when test="count(key('G_keyEnumsByName', $type)) > 0">
+ <xsl:value-of select="'long'" />
+ </xsl:when>
+
+ </xsl:choose>
+
+ <xsl:if test="$needarray">
+ <xsl:value-of select="'[]'" />
+ </xsl:if>
+
+</xsl:template>
+
+<xsl:template name="genIface">
+ <xsl:param name="ifname" />
+ <xsl:param name="filename" />
+
+ <xsl:call-template name="startFile">
+ <xsl:with-param name="file" select="$filename" />
+ </xsl:call-template>
+
+ <xsl:variable name="extendsidl" select="key('G_keyInterfacesByName', $ifname)/@extends" />
+
+ <xsl:variable name="extends">
+ <xsl:choose>
+ <xsl:when test="($extendsidl = '$unknown') or ($extendsidl = '$dispatched') or ($extendsidl = '$errorinfo')">
+ <xsl:value-of select="'nsISupports'" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$extendsidl" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:value-of select="concat('public interface ', $ifname, ' extends ', $extends, ' {&#10;&#10;')" />
+
+ <xsl:variable name="uppername">
+ <xsl:call-template name="uppercase">
+ <xsl:with-param name="str" select="$ifname" />
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:value-of select="concat(' public static final String ', $uppername, '_IID =&#10;',
+ ' &quot;{',@uuid, '}&quot;;&#10;&#10;')" />
+
+ <xsl:for-each select="attribute">
+ <xsl:variable name="attrname" select="@name" />
+ <xsl:variable name="attrtype" select="@type" />
+
+ <xsl:variable name="gettername">
+ <xsl:call-template name="makeGetterName">
+ <xsl:with-param name="attrname" select="$attrname" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="backtype">
+ <xsl:call-template name="typeIdl2Back">
+ <xsl:with-param name="type" select="$attrtype" />
+ <xsl:with-param name="safearray" select="@safearray" />
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="callparam">
+ <xsl:if test="@safearray='yes'">
+ <xsl:value-of select="concat(' long[] ', @name, 'Size')" />
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:value-of select="concat(' public ', $backtype, ' ', $gettername, '(',$callparam,');&#10;&#10;')" />
+
+ <xsl:if test="not(@readonly='yes')">
+ <xsl:variable name="settername">
+ <xsl:call-template name="makeSetterName">
+ <xsl:with-param name="attrname" select="$attrname" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="concat(' public void ', $settername, '(', $backtype, ' arg1);&#10;&#10;')" />
+ </xsl:if>
+
+ </xsl:for-each>
+
+ <xsl:for-each select="method">
+ <xsl:variable name="methodname" select="@name" />
+ <xsl:variable name="returnidltype" select="param[@dir='return']/@type" />
+ <xsl:variable name="returnidlsafearray" select="param[@dir='return']/@safearray" />
+
+ <xsl:variable name="returntype">
+ <xsl:choose>
+ <xsl:when test="$returnidltype">
+ <xsl:call-template name="typeIdl2Back">
+ <xsl:with-param name="type" select="$returnidltype" />
+ <xsl:with-param name="safearray" select="$returnidlsafearray" />
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>void</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:value-of select="concat(' public ', $returntype, ' ', $methodname, '(')" />
+ <xsl:for-each select="param">
+ <xsl:variable name="paramtype">
+ <xsl:call-template name="typeIdl2Back">
+ <xsl:with-param name="type" select="@type" />
+ <xsl:with-param name="safearray" select="@safearray" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="(@safearray='yes') and (@dir='return')">
+ <xsl:value-of select="concat('long[] ', @name)" />
+ </xsl:when>
+ <xsl:when test="(@safearray='yes') and (@dir='out')">
+ <xsl:value-of select="concat('long[] ', @name, 'Size, ', $paramtype, '[] ', @name)" />
+ </xsl:when>
+ <xsl:when test="(@safearray='yes') and (@dir='in') and (@type='octet')">
+ <xsl:value-of select="concat($paramtype, ' ', @name)" />
+ </xsl:when>
+ <xsl:when test="(@safearray='yes') and (@dir='in')">
+ <xsl:value-of select="concat('long ', @name, 'Size, ', $paramtype, ' ', @name)" />
+ </xsl:when>
+ <xsl:when test="@dir='out'">
+ <xsl:value-of select="concat($paramtype, '[] ', @name)" />
+ </xsl:when>
+ <xsl:when test="@dir='in'">
+ <xsl:value-of select="concat($paramtype, ' ', @name)" />
+ </xsl:when>
+ </xsl:choose>
+ <xsl:if test="not(position()=last()) and not(following-sibling::param[1]/@dir='return' and not(following-sibling::param[1]/@safearray='yes'))">
+ <xsl:value-of select="', '" />
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:value-of select=" ');&#10;&#10;'" />
+
+ </xsl:for-each>
+
+ <xsl:value-of select="'}&#10;&#10;'" />
+
+ <xsl:call-template name="endFile">
+ <xsl:with-param name="file" select="$filename" />
+ </xsl:call-template>
+
+</xsl:template>
+
+
+<xsl:template match="/">
+
+ <!-- Handwritten files -->
+ <xsl:call-template name="emitHandwritten"/>
+
+ <!-- Enums -->
+ <xsl:for-each select="//enum">
+ <xsl:call-template name="genEnum">
+ <xsl:with-param name="enumname" select="@name" />
+ <xsl:with-param name="filename" select="concat(@name, '.java')" />
+ </xsl:call-template>
+ </xsl:for-each>
+
+ <!-- Interfaces -->
+ <xsl:for-each select="//interface">
+ <xsl:variable name="self_target" select="current()/ancestor::if/@target"/>
+ <xsl:variable name="module" select="current()/ancestor::module/@name"/>
+
+ <!-- We don't need WSDL-specific nor MIDL-specific interfaces here -->
+ <xsl:if test="not($self_target='wsdl') and not($self_target='midl') and not($module)">
+ <xsl:call-template name="genIface">
+ <xsl:with-param name="ifname" select="@name" />
+ <xsl:with-param name="filename" select="concat(@name, '.java')" />
+ </xsl:call-template>
+ </xsl:if>
+
+ </xsl:for-each>
+
+</xsl:template>
+
+</xsl:stylesheet>