diff --git a/extensions/java/xpcom/Makefile.in b/extensions/java/xpcom/Makefile.in index acd596e5f3fc..8b7ecaf3e220 100644 --- a/extensions/java/xpcom/Makefile.in +++ b/extensions/java/xpcom/Makefile.in @@ -42,52 +42,7 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -MODULE = javaxpcom -LIBRARY_NAME = javaxpcom -MOZILLA_INTERNAL_API = 1 - -# On Mac OS X, JNI libraries must end with a '.jnilib' extension -ifeq ($(OS_ARCH),Darwin) -DLL_SUFFIX = .jnilib -endif - -REQUIRES = xpcom \ - string \ - embed_base \ - $(NULL) - -DIRS = tools/genifaces build - -CPPSRCS = \ - nsAppFileLocProviderProxy.cpp \ - nsJavaInterfaces.cpp \ - nsJavaWrapper.cpp \ - nsJavaXPTCStub.cpp \ - nsJavaXPTCStubWeakRef.cpp \ - nsJavaXPCOMBindingUtils.cpp \ - $(NULL) - -LOCAL_INCLUDES = -I$(JAVA_INCLUDE_PATH) - -ifeq ($(OS_ARCH),WINNT) -LOCAL_INCLUDES += -I$(JAVA_INCLUDE_PATH)/win32 -else -LOCAL_INCLUDES += -I$(JAVA_INCLUDE_PATH)/linux -endif - -EXTRA_DSO_LIBS = \ - embed_base_s \ - $(NULL) - -EXTRA_DSO_LDOPTS = \ - $(LIBS_DIR) \ - $(EXTRA_DSO_LIBS) \ - $(MOZ_COMPONENT_LIBS) \ - $(NULL) +DIRS = tools/genifaces interfaces src include $(topsrcdir)/config/rules.mk -XPCOMError.java: $(topsrcdir)/xpcom/base/nsError.h gen-nsError.pl Makefile Makefile.in - $(PERL) $(srcdir)/gen-nsError.pl < $< > $@ - -export:: XPCOMError.java diff --git a/extensions/java/xpcom/XPCOMException.java b/extensions/java/xpcom/XPCOMException.java index 0a824f81f59a..44636d540a08 100644 --- a/extensions/java/xpcom/XPCOMException.java +++ b/extensions/java/xpcom/XPCOMException.java @@ -37,21 +37,21 @@ package org.mozilla.xpcom; -import java.lang.*; - /** * This exception is thrown whenever an internal XPCOM/Gecko error occurs. * You can query the error ID returned by XPCOM by checking * errorcode field. */ -public final class XPCOMException extends RuntimeException { +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. diff --git a/extensions/java/xpcom/XPCOMJavaProxy.java b/extensions/java/xpcom/XPCOMJavaProxy.java index c49e164a5180..f1ff446ebfc8 100644 --- a/extensions/java/xpcom/XPCOMJavaProxy.java +++ b/extensions/java/xpcom/XPCOMJavaProxy.java @@ -35,9 +35,10 @@ * * ***** END LICENSE BLOCK ***** */ -package org.mozilla.xpcom; +package org.mozilla.xpcom.internal; import java.lang.reflect.*; +import org.mozilla.xpcom.*; /** @@ -45,7 +46,7 @@ import java.lang.reflect.*; * java.lang.reflect.Proxy instance is created using the expected * interface, and all calls to the proxy are forwarded to the XPCOM object. */ -public final class XPCOMJavaProxy implements InvocationHandler { +public class XPCOMJavaProxy implements InvocationHandler { /** * Pointer to the XPCOM object for which we are a proxy. @@ -57,11 +58,22 @@ public final class XPCOMJavaProxy implements InvocationHandler { * * @param aXPCOMInstance address of XPCOM object as a long */ - public XPCOMJavaProxy(long aXPCOMInstance) - { + public XPCOMJavaProxy(long aXPCOMInstance) { nativeXPCOMPtr = aXPCOMInstance; } + /** + * Returns the XPCOM object that the given proxy references. + * + * @param aProxy Proxy created by createProxy + * + * @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. * @@ -70,12 +82,10 @@ public final class XPCOMJavaProxy implements InvocationHandler { * * @return Proxy of given XPCOM object */ - protected static Object createProxy(Class aInterface, long aXPCOMInstance) - { + protected static Object createProxy(Class aInterface, long aXPCOMInstance) { return Proxy.newProxyInstance(aInterface.getClassLoader(), - new Class[] { aInterface, - XPCOMJavaProxyBase.class }, - new XPCOMJavaProxy(aXPCOMInstance)); + new Class[] { aInterface, XPCOMJavaProxyBase.class }, + new XPCOMJavaProxy(aXPCOMInstance)); } /** @@ -90,8 +100,7 @@ public final class XPCOMJavaProxy implements InvocationHandler { * @return return value as defined by given aMethod */ public Object invoke(Object aProxy, Method aMethod, Object[] aParams) - throws Throwable - { + throws Throwable { String methodName = aMethod.getName(); // Handle the three java.lang.Object methods that are passed to us. @@ -134,8 +143,7 @@ public final class XPCOMJavaProxy implements InvocationHandler { * * @see Object#hashCode() */ - protected static Integer proxyHashCode(Object aProxy) - { + protected static Integer proxyHashCode(Object aProxy) { return new Integer(System.identityHashCode(aProxy)); } @@ -150,11 +158,28 @@ public final class XPCOMJavaProxy implements InvocationHandler { * * @see Object#equals(Object) */ - protected static Boolean proxyEquals(Object aProxy, Object aOther) - { + protected static Boolean proxyEquals(Object aProxy, Object aOther) { return (aProxy == aOther ? Boolean.TRUE : Boolean.FALSE); } + /** + * Indicates whether the given object is an XPCOMJavaProxy. + * + * @param aObject object to check + * + * @return true if the given object is an XPCOMJavaProxy; + * false otherwise + */ + protected static boolean isXPCOMJavaProxy(Object aObject) { + if (Proxy.isProxyClass(aObject.getClass())) { + InvocationHandler h = Proxy.getInvocationHandler(aObject); + if (h instanceof XPCOMJavaProxy) { + return true; + } + } + return false; + } + /** * Handles method calls of java.lang.Object.toString * @@ -164,44 +189,23 @@ public final class XPCOMJavaProxy implements InvocationHandler { * * @see Object#toString() */ - protected static String proxyToString(Object aProxy) - { + protected static String proxyToString(Object aProxy) { return aProxy.getClass().getInterfaces()[0].getName() + '@' + Integer.toHexString(aProxy.hashCode()); } /** - * Indicates whether the given object is an XPCOMJavaProxy. + * Called when the proxy is garbage collected by the JVM. Allows us to clean + * up any references to the XPCOM object. * - * @param aObject object to check - * - * @return true if the given object is an XPCOMJavaProxy; - * false otherwise + * @param aProxy reference to Proxy that is being garbage collected */ - protected static boolean isXPCOMJavaProxy(Object aObject) - { - Class objectClass = aObject.getClass(); - if (Proxy.isProxyClass(objectClass)) { - Class[] interfaces = objectClass.getInterfaces(); - if (interfaces[interfaces.length-1] == XPCOMJavaProxyBase.class) { - return true; - } - } - return false; + protected void finalizeProxy(Object aProxy) throws Throwable { + finalizeProxyNative(aProxy); + super.finalize(); } - /** - * Returns the XPCOM object that the given proxy references. - * - * @param aProxy Proxy created by createProxy - * - * @return address of XPCOM object as a long - */ - protected static long getNativeXPCOMInstance(Object aProxy) - { - XPCOMJavaProxy proxy = (XPCOMJavaProxy) Proxy.getInvocationHandler(aProxy); - return proxy.nativeXPCOMPtr; - } + protected static native void finalizeProxyNative(Object aProxy); /** * Calls the XPCOM object referenced by the proxy with the given method. @@ -215,16 +219,8 @@ public final class XPCOMJavaProxy implements InvocationHandler { * @exception XPCOMException if XPCOM method failed. Values of XPCOMException * are defined by the method called. */ - protected static native - Object callXPCOMMethod(Object aProxy, String aMethodName, Object[] aParams); - - /** - * Called when the proxy is garbage collected by the JVM. Allows us to clean - * up any references to the XPCOM object. - * - * @param aProxy reference to Proxy that is being garbage collected - */ - protected static native - void finalizeProxy(Object aProxy); + protected static native Object callXPCOMMethod(Object aProxy, + String aMethodName, Object[] aParams); } + diff --git a/extensions/java/xpcom/gen-nsError.pl b/extensions/java/xpcom/gen-nsError.pl index da866b83be36..a7e3692d01e4 100644 --- a/extensions/java/xpcom/gen-nsError.pl +++ b/extensions/java/xpcom/gen-nsError.pl @@ -37,9 +37,9 @@ # # ***** END LICENSE BLOCK ***** -# Generates XPCOMError.java from xpcom/base/nsError.h +# Generates IXPCOMError.java from xpcom/base/nsError.h # -# usage: perl gen-nsErrors.pl < /xpcom/base/nsError.h > XPCOMError.java +# usage: perl gen-nsErrors.pl < /xpcom/base/nsError.h > IXPCOMError.java print "/* ***** BEGIN LICENSE BLOCK *****\n"; @@ -83,12 +83,12 @@ print "package org.mozilla.xpcom;\n"; print "\n\n"; print "/**\n"; -print " * Mozilla error codes.\n"; -print " *\n"; +print " * Mozilla XPCOM 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"; +print "public interface IXPCOMError {\n"; while () { $line = $_; diff --git a/extensions/java/xpcom/interfaces/GREVersionRange.java b/extensions/java/xpcom/interfaces/GREVersionRange.java new file mode 100644 index 000000000000..ede1a52322db --- /dev/null +++ b/extensions/java/xpcom/interfaces/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/extensions/java/xpcom/AppFileLocProvider.java b/extensions/java/xpcom/interfaces/IAppFileLocProvider.java similarity index 87% rename from extensions/java/xpcom/AppFileLocProvider.java rename to extensions/java/xpcom/interfaces/IAppFileLocProvider.java index 721aaa509629..be13c1ba4a2e 100644 --- a/extensions/java/xpcom/AppFileLocProvider.java +++ b/extensions/java/xpcom/interfaces/IAppFileLocProvider.java @@ -48,18 +48,20 @@ import java.io.*; * java.io.File instead of nsIFile. *

* - * @see GeckoEmbed#initEmbedding - * @see XPCOM#initXPCOM - * @see + * @see Mozilla#initEmbedding + * @see Mozilla#initXPCOM + * @see * nsIDirectoryServiceProvider - * @see + * @see * Directory Service property names */ -public interface AppFileLocProvider { +public interface IAppFileLocProvider { /** * Directory Service calls this when it gets the first request for - * a prop or on every request if the prop is not persistent. + * 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: @@ -78,12 +80,13 @@ public interface AppFileLocProvider { /** * Directory Service calls this when it gets a request for - * a prop and the requested type is nsISimpleEnumerator. + * a property and the requested type is nsISimpleEnumerator. * * @param prop the symbolic name of the file list * - * @return an array for a list of file locations + * @return an array of file locations */ public File[] getFiles(String prop); } + diff --git a/extensions/java/xpcom/GeckoEmbed.java b/extensions/java/xpcom/interfaces/IGRE.java similarity index 54% rename from extensions/java/xpcom/GeckoEmbed.java rename to extensions/java/xpcom/interfaces/IGRE.java index 0900e628efca..fd956c81dc65 100644 --- a/extensions/java/xpcom/GeckoEmbed.java +++ b/extensions/java/xpcom/interfaces/IGRE.java @@ -39,44 +39,42 @@ package org.mozilla.xpcom; import java.io.*; -/** - * Provides access to functions that are used to embed Mozilla's Gecko layer. - */ -public final class GeckoEmbed { + +public interface IGRE { /** - * Initializes the Gecko embedding layer. You must - * call this method before proceeding to use Gecko. This function ensures - * XPCOM is started, creates the component registry if necessary and - * starts global services. - * - * @param aMozBinDirectory The Gecko directory containing the component - * registry and runtime libraries; - * or use null 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 - * null for the default behaviour. - * - * @exception XPCOMException if a failure occurred during initialization - */ - public static native - void initEmbedding(File aMozBinDirectory, - AppFileLocProvider aAppFileLocProvider); - - /** - * Terminates the Gecko embedding layer. Call this function during shutdown to - * ensure that global services are unloaded, files are closed and - * XPCOM is shutdown. + * Initializes libXUL for embedding purposes. *

- * NOTE: Release any XPCOM objects within Gecko that you may be holding a - * reference to before calling this function. - *

+ * NOTE: This function must be called from the "main" thread. + *

+ * NOTE: At the present time, this function may only be called once in + * a given process. Use termEmbedding to clean up and free + * resources allocated by initEmbedding. * - * @exception XPCOMException if a failure occurred during termination + * @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 */ - public static native - void termEmbedding(); + public void initEmbedding(File aLibXULDirectory, File aAppDirectory, + IAppFileLocProvider aAppDirProvider) throws XPCOMException; + + /** + * Terminates libXUL embedding. + *

+ * NOTE: Release any references to XPCOM objects that you may be holding + * before calling this function. + * + * @throws XPCOMException if a failure occurred during initialization + */ + public void termEmbedding() throws XPCOMException; } + + diff --git a/extensions/java/xpcom/interfaces/INIParser.java b/extensions/java/xpcom/interfaces/INIParser.java new file mode 100644 index 000000000000..f28aaaca3266 --- /dev/null +++ b/extensions/java/xpcom/interfaces/INIParser.java @@ -0,0 +1,235 @@ +/* ***** 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.*; +import java.nio.charset.Charset; +import java.util.*; + + +/** + * A simple parser for INI files. + */ +public class INIParser { + + private HashMap mSections; + + /** + * Creates a new INIParser instance from the INI file at the + * given path. aCharset specifies the character encoding of + * the file. + * + * @param aFilename path of INI file to parse + * @param aCharset character encoding of file + * @throws FileNotFoundException if aFilename 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 INIParser instance from the INI file at the + * given path, which is assumed to be in the UTF-8 charset. + * + * @param aFilename path of INI file to parse + * @throws FileNotFoundException if aFilename 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 INIParser instance from the given file. + * aCharset specifies the character encoding of the file. + * + * @param aFile INI file to parse + * @param aCharset character encoding of file + * @throws FileNotFoundException if aFile 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 INIParser instance from the given file, + * which is assumed to be in the UTF-8 charset. + * + * @param aFile INI file to parse + * @throws FileNotFoundException if aFile 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 aFile 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 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 = (Properties) 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 null 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 = (Properties) 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 = (Properties) mSections.get(aSection); + if (props == null) { + return null; + } + + return props.getProperty(aKey); + } + +} + diff --git a/extensions/java/xpcom/XPCOM.java b/extensions/java/xpcom/interfaces/IXPCOM.java similarity index 52% rename from extensions/java/xpcom/XPCOM.java rename to extensions/java/xpcom/interfaces/IXPCOM.java index 1519e6e14e0c..fd3fbb4eb0ec 100644 --- a/extensions/java/xpcom/XPCOM.java +++ b/extensions/java/xpcom/interfaces/IXPCOM.java @@ -15,7 +15,7 @@ * * The Initial Developer of the Original Code is * IBM Corporation. - * Portions created by the Initial Developer are Copyright (C) 2005 + * Portions created by the Initial Developer are Copyright (C) 2004 * IBM Corporation. All Rights Reserved. * * Contributor(s): @@ -37,16 +37,10 @@ package org.mozilla.xpcom; -import java.lang.reflect.*; import java.io.*; -import java.util.*; -/** - * Provides access to methods for initializing XPCOM, as well as helper methods - * for working with XPCOM classes. - */ -public final class XPCOM implements XPCOMError { +public interface IXPCOM { /** * Initializes XPCOM. You must call this method before proceeding @@ -71,9 +65,8 @@ public final class XPCOM implements XPCOMError { *

  • Other error codes indicate a failure during initialisation.
  • * */ - public static native - nsIServiceManager initXPCOM(File aMozBinDirectory, - AppFileLocProvider aAppFileLocProvider); + public nsIServiceManager initXPCOM(File aMozBinDirectory, + IAppFileLocProvider aAppFileLocProvider) throws XPCOMException; /** * Shutdown XPCOM. You must call this method after you are finished @@ -84,8 +77,7 @@ public final class XPCOM implements XPCOMError { * * @exception XPCOMException if a failure occurred during termination */ - public static native - void shutdownXPCOM(nsIServiceManager aServMgr); + public void shutdownXPCOM(nsIServiceManager aServMgr) throws XPCOMException; /** * Public Method to access to the service manager. @@ -94,8 +86,7 @@ public final class XPCOM implements XPCOMError { * * @exception XPCOMException */ - public static native - nsIServiceManager getServiceManager(); + public nsIServiceManager getServiceManager() throws XPCOMException; /** * Public Method to access to the component manager. @@ -104,8 +95,7 @@ public final class XPCOM implements XPCOMError { * * @exception XPCOMException */ - public static native - nsIComponentManager getComponentManager(); + public nsIComponentManager getComponentManager() throws XPCOMException; /** * Public Method to access to the component registration manager. @@ -114,8 +104,7 @@ public final class XPCOM implements XPCOMError { * * @exception XPCOMException */ - public static native - nsIComponentRegistrar getComponentRegistrar(); + public nsIComponentRegistrar getComponentRegistrar() throws XPCOMException; /** * Public Method to create an instance of a nsILocalFile. @@ -135,108 +124,8 @@ public final class XPCOM implements XPCOMError { * or relative paths (must supply full file path) * */ - public static native - nsILocalFile newLocalFile(String aPath, boolean aFollowLinks); - - - /** - * If you create a class that implements nsISupports, you will need to provide - * an implementation of the queryInterface method. This helper - * function provides a simple implementation. Therefore, if your class does - * not need to do anything special with queryInterface, your - * implementation would look like: - *
    -   *      public nsISupports queryInterface(String aIID) {
    -   *        return XPCOM.queryInterface(this, aIID);
    -   *      }
    -   * 
    - * - * @param aObject object to query - * @param aIID requested interface IID - * - * @return aObject if the given object supports that - * interface; - * null otherwise. - */ - public static nsISupports queryInterface(nsISupports aObject, String aIID) - { - ArrayList classes = new ArrayList(); - classes.add(aObject.getClass()); - - while (!classes.isEmpty()) { - Class clazz = (Class) classes.remove(0); - - // Skip over any class/interface in the "java.*" and "javax.*" domains. - if (clazz.getName().startsWith("java")) { - continue; - } - - // If given IID matches that of the current class/interface, then we - // know that aObject implements the interface specified by the given IID. - String iid = XPCOM.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 nsILocalFile newLocalFile(String aPath, boolean aFollowLinks) + throws XPCOMException; } diff --git a/extensions/java/xpcom/interfaces/Makefile.in b/extensions/java/xpcom/interfaces/Makefile.in new file mode 100644 index 000000000000..f40739b143e0 --- /dev/null +++ b/extensions/java/xpcom/interfaces/Makefile.in @@ -0,0 +1,115 @@ +# ***** 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 ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ ; @srcdir@/.. + +include $(DEPTH)/config/autoconf.mk + +JARFILE = MozillaInterfaces.jar +JARFILE_SRC = $(patsubst %.jar,%-src.jar,$(JARFILE)) + +JAVA_SRCS = \ + $(srcdir)/Mozilla.java \ + $(srcdir)/GREVersionRange.java \ + $(srcdir)/IGRE.java \ + $(srcdir)/IXPCOM.java \ + $(srcdir)/../XPCOMException.java \ + $(srcdir)/IAppFileLocProvider.java \ + $(srcdir)/INIParser.java \ + $(srcdir)/VersionComparator.java \ + $(srcdir)/../XPCOMJavaProxyBase.java \ + $(NULL) + +GEN_JAVA_SRCS = \ + IXPCOMError.java \ + $(NULL) + +# install jars into SDK +SDK_LIBRARY = $(JARFILE) $(JARFILE_SRC) + +GARBAGE += $(JARFILE) $(JARFILE_SRC) $(GEN_JAVA_SRCS) +GARBAGE_DIRS += _javagen org + +include $(topsrcdir)/config/rules.mk + +ifdef MOZ_DEBUG +JAVAC_FLAGS = -g +endif + +ifeq ($(OS_ARCH),WINNT) +RUN = +OUTPUT_DIR = $(shell cygpath -w $(CURDIR)/_javagen/org/mozilla/xpcom) +else +RUN = $(DIST)/bin/run-mozilla.sh +OUTPUT_DIR = $(CURDIR)/_javagen/org/mozilla/xpcom +endif + +_javagen/org/mozilla/xpcom/.iface_done: $(JAVA_SRCS) + @if test ! -d _javagen/org/mozilla/xpcom; then \ + touch .done; \ + $(INSTALL) -m 644 .done _javagen/org/mozilla/xpcom; \ + fi + @echo Copying Java source files + @$(INSTALL) -m 644 $(JAVA_SRCS) \ + _javagen/org/mozilla/xpcom + @$(INSTALL) -m 644 $(GEN_JAVA_SRCS) _javagen/org/mozilla/xpcom + @echo Generating Java interface files + $(RUN) $(DIST)/bin/GenerateJavaInterfaces$(BIN_SUFFIX) -d $(OUTPUT_DIR) + @touch $@ + +# Use find and xargs for passing list of Java files to JAVAC. This avoids the +# "argument list too long" error on Windows when using *.java +org/mozilla/xpcom/.class_done: _javagen/org/mozilla/xpcom/.iface_done + @echo Compiling Java interface classes + find _javagen -name "*.java" | xargs $(JAVAC) $(JAVAC_FLAGS) -classpath . \ + -d . -sourcepath _javagen + @touch $@ + +$(JARFILE): org/mozilla/xpcom/.class_done Makefile + $(JAR) cf $@ org + +$(JARFILE_SRC): $(JARFILE) + $(JAR) cf $@ -C _javagen org + +IXPCOMError.java: $(topsrcdir)/xpcom/base/nsError.h gen-nsError.pl Makefile Makefile.in + $(PERL) $(srcdir)/../gen-nsError.pl < $< > $@ + +export:: IXPCOMError.java + diff --git a/extensions/java/xpcom/interfaces/Mozilla.java b/extensions/java/xpcom/interfaces/Mozilla.java new file mode 100644 index 000000000000..053fcd64c0e9 --- /dev/null +++ b/extensions/java/xpcom/interfaces/Mozilla.java @@ -0,0 +1,871 @@ +/* ***** 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.*; +import java.lang.reflect.*; +import java.net.*; +import java.nio.charset.Charset; +import java.util.*; + + +/** + * @see http://www.mozilla.org/projects/embedding/GRE.html + */ +public class Mozilla implements IGRE, IXPCOM, IXPCOMError { + + private static Mozilla mozillaInstance = new Mozilla(); + + private static final String JAVACONNECT_JAR = "javaconnect.jar"; + + private IGRE gre = null; + + private IXPCOM xpcom = 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 "javaconnect.jar"). + *

    + * 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 + * null. + * + * @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 + 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 + * /Contents/Frameworks/XUL.framework/libxpcom.dylib. + */ + File grePath = findGREBundleFramework(); + if (grePath != null) { + return grePath; + } + + // Check ~/Library/Frameworks/XUL.framework/Versions//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//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/").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", null); + Object bundle = mainBundleMethod.invoke(null, null); + + if (bundle != null) { + // Get the path to the bundle's "Frameworks" directory + Method fwPathMethod = bundleClass.getMethod("privateFrameworksPath", + null); + String path = (String) fwPathMethod.invoke(bundle, 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(); + File jar = new File(grePath, JAVACONNECT_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"); + File jar = new File(files[i], JAVACONNECT_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(); + + // Get the GRE subkey; that is, everything after + // "\Software\mozilla.org\GRE\" + String subkeyName = section.substring(aKeyName.length() + 1); + + // We are only interested in _immediate_ subkeys. We want + // "\Software\mozilla.org\GRE\" but not + // "\Software\mozilla.org\GRE\\". + 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"); + File jar = new File(grePath, JAVACONNECT_JAR); + if (xpcomLib.canRead() && jar.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"); + File jar = new File(grePath, JAVACONNECT_JAR); + if (xpcomLib.canRead() && jar.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; + } + + /** + * Initializes libXUL for embedding purposes. + *

    + * NOTE: This function must be called from the "main" thread. + *

    + * NOTE: At the present time, this function may only be called once in + * a given process. Use termEmbedding to clean up and free + * resources allocated by initEmbedding. + * + * @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 IllegalArgumentException if aLibXULDirectory is not + * a valid path + * @throws XPCOMException if a failure occurred during initialization + */ + public void initEmbedding(File aLibXULDirectory, File aAppDirectory, + IAppFileLocProvider aAppDirProvider) throws XPCOMException { + loadJavaconnect(aLibXULDirectory, true); + gre.initEmbedding(aLibXULDirectory, aAppDirectory, aAppDirProvider); + } + + /** + * @param aLibXULDirectory + * @param aLoadGREImpl + * @throws XPCOMException + */ + private void loadJavaconnect(File aLibXULDirectory, boolean aLoadGREImpl) + throws XPCOMException { + File jar = new File(aLibXULDirectory, JAVACONNECT_JAR); + if (!jar.exists()) { + throw new XPCOMException(NS_ERROR_FILE_INVALID_PATH); + } + + URL[] urls = new URL[1]; + try { + urls[0] = jar.toURL(); + } catch (MalformedURLException e) { + throw new XPCOMException(NS_ERROR_FILE_INVALID_PATH); + } + ClassLoader loader = new URLClassLoader(urls, + this.getClass().getClassLoader()); + + try { + if (aLoadGREImpl) { + 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(); + } catch (Exception e) { + throw new XPCOMException(NS_ERROR_FAILURE, + "failure creating org.mozilla.xpcom.internal.*"); + } + } + + /** + * Terminates libXUL embedding. + *

    + * NOTE: Release any references to XPCOM objects that you may be holding + * before calling this function. + */ + public void termEmbedding() throws XPCOMException { + try { + gre.termEmbedding(); + } catch (NullPointerException e) { + throw new XPCOMException(Mozilla.NS_ERROR_NULL_POINTER, + "Attempt to use unitialized GRE object"); + } finally { + gre = null; + xpcom = null; + } + } + + /** + * 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 null 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 + * null for the default behaviour. + * + * @return the service manager + * + * @exception XPCOMException

    + */ + public nsIServiceManager initXPCOM(File aMozBinDirectory, + IAppFileLocProvider aAppFileLocProvider) throws XPCOMException { + loadJavaconnect(aMozBinDirectory, false); + return xpcom.initXPCOM(aMozBinDirectory, aAppFileLocProvider); + } + + /** + * 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. + * + * @exception XPCOMException if a failure occurred during termination + */ + public void shutdownXPCOM(nsIServiceManager aServMgr) throws XPCOMException { + try { + xpcom.shutdownXPCOM(aServMgr); + } catch (NullPointerException e) { + throw new XPCOMException(Mozilla.NS_ERROR_NULL_POINTER, + "Attempt to use unitialized XPCOM object"); + } finally { + xpcom = null; + } + } + + /** + * Public Method to access to the service manager. + * + * @return the service manager + * + * @exception XPCOMException + */ + public nsIServiceManager getServiceManager() throws XPCOMException { + try { + return xpcom.getServiceManager(); + } catch (NullPointerException e) { + throw new XPCOMException(Mozilla.NS_ERROR_NULL_POINTER, + "Attempt to use unitialized XPCOM object"); + } + } + + /** + * Public Method to access to the component manager. + * + * @return the component manager + * + * @exception XPCOMException + */ + public nsIComponentManager getComponentManager() throws XPCOMException { + try { + return xpcom.getComponentManager(); + } catch (NullPointerException e) { + throw new XPCOMException(Mozilla.NS_ERROR_NULL_POINTER, + "Attempt to use unitialized XPCOM object"); + } + } + + /** + * Public Method to access to the component registration manager. + * + * @return the component registration manager + * + * @exception XPCOMException + */ + public nsIComponentRegistrar getComponentRegistrar() throws XPCOMException { + try { + return xpcom.getComponentRegistrar(); + } catch (NullPointerException e) { + throw new XPCOMException(Mozilla.NS_ERROR_NULL_POINTER, + "Attempt to use unitialized XPCOM object"); + } + } + + /** + * 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 + * + * @exception XPCOMException + */ + public nsILocalFile newLocalFile(String aPath, boolean aFollowLinks) + throws XPCOMException { + try { + return xpcom.newLocalFile(aPath, aFollowLinks); + } catch (NullPointerException e) { + throw new XPCOMException(Mozilla.NS_ERROR_NULL_POINTER, + "Attempt to use unitialized XPCOM object"); + } + } + + /** + * If you create a class that implements nsISupports, you will need to provide + * an implementation of the queryInterface method. This helper + * function provides a simple implementation. Therefore, if your class does + * not need to do anything special with queryInterface, your + * implementation would look like: + *
    +   *      public nsISupports queryInterface(String aIID) {
    +   *        return XPCOM.queryInterface(this, aIID);
    +   *      }
    +   * 
    + * + * @param aObject object to query + * @param aIID requested interface IID + * + * @return aObject if the given object supports that + * interface; + * null otherwise. + */ + public static nsISupports queryInterface(nsISupports aObject, String aIID) { + ArrayList classes = new ArrayList(); + classes.add(aObject.getClass()); + + while (!classes.isEmpty()) { + Class clazz = (Class) 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; + } + +} + diff --git a/extensions/java/xpcom/interfaces/VersionComparator.java b/extensions/java/xpcom/interfaces/VersionComparator.java new file mode 100644 index 000000000000..c4438f49c96e --- /dev/null +++ b/extensions/java/xpcom/interfaces/VersionComparator.java @@ -0,0 +1,269 @@ +/* ***** 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.*; + + +/** + * Version strings are dot-separated sequences of version-parts. + *

    + * A version-part consists of up to four parts, all of which are optional: + *
    + * <number-a><string-b><number-c> + * <string-d (everything else)> + *

    + * A version-part may also consist of a single asterisk "*" which indicates + * "infinity". + *

    + * Numbers are base-10, and are zero if left out. + * Strings are compared bytewise. + *

    + * For additional backwards compatibility, if "string-b" is "+" then + * "number-a" is incremented by 1 and "string-b" becomes "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
    + * 
    + * 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 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 "+" + if (str.charAt(0) == '+') { + result.numA++; + result.strB = "pre"; + } else { + // else if part is of type "..." + 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: + * <number-a><string-b><number-c> + * <string-d (everything else)>. + */ +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 <string-d (everything else)> + * section of a version string. + * + * @return remaining version string + */ + public String getRemainder() { + return part; + } + +} + diff --git a/extensions/java/xpcom/nsJavaInterfaces.cpp b/extensions/java/xpcom/nsJavaInterfaces.cpp index 2b0e86f5ef29..787b46f46f41 100644 --- a/extensions/java/xpcom/nsJavaInterfaces.cpp +++ b/extensions/java/xpcom/nsJavaInterfaces.cpp @@ -38,7 +38,6 @@ #include "nsJavaWrapper.h" #include "nsJavaXPCOMBindingUtils.h" #include "nsJavaXPTCStub.h" -#include "nsEmbedAPI.h" #include "nsIComponentRegistrar.h" #include "nsString.h" #include "nsISimpleEnumerator.h" @@ -48,52 +47,54 @@ #include "nsArray.h" #include "nsAppFileLocProviderProxy.h" #include "nsIEventQueueService.h" +#include "nsXULAppAPI.h" +#include "nsILocalFile.h" -#define GECKO_NATIVE(func) Java_org_mozilla_xpcom_GeckoEmbed_##func -#define XPCOM_NATIVE(func) Java_org_mozilla_xpcom_XPCOM_##func +#define GRE_NATIVE(func) Java_org_mozilla_xpcom_internal_GREImpl_##func +#define XPCOM_NATIVE(func) Java_org_mozilla_xpcom_internal_XPCOMImpl_##func nsresult -InitEmbedding_Impl(JNIEnv* env, jobject aMozBinDirectory, - jobject aAppFileLocProvider) +InitEmbedding_Impl(JNIEnv* env, jobject aLibXULDirectory, + jobject aAppDirectory, jobject aAppDirProvider) { nsresult rv; if (!InitializeJavaGlobals(env)) return NS_ERROR_FAILURE; // create an nsILocalFile from given java.io.File - nsCOMPtr directory; - if (aMozBinDirectory) { - rv = File_to_nsILocalFile(env, aMozBinDirectory, getter_AddRefs(directory)); + nsCOMPtr libXULDir; + if (aLibXULDirectory) { + rv = File_to_nsILocalFile(env, aLibXULDirectory, getter_AddRefs(libXULDir)); + NS_ENSURE_SUCCESS(rv, rv); + } + nsCOMPtr appDir; + if (aAppDirectory) { + rv = File_to_nsILocalFile(env, aAppDirectory, getter_AddRefs(appDir)); NS_ENSURE_SUCCESS(rv, rv); } // create nsAppFileLocProviderProxy from given Java object nsCOMPtr provider; - if (aAppFileLocProvider) { - rv = NS_NewAppFileLocProviderProxy(aAppFileLocProvider, + if (aAppDirProvider) { + rv = NS_NewAppFileLocProviderProxy(aAppDirProvider, getter_AddRefs(provider)); NS_ENSURE_SUCCESS(rv, rv); } - // init Gecko - rv = NS_InitEmbedding(directory, provider); + // init libXUL + rv = XRE_InitEmbedding(libXULDir, appDir, provider); NS_ENSURE_SUCCESS(rv, rv); - // init Event Queue - nsCOMPtr - eventQService(do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv)); - NS_ENSURE_SUCCESS(rv, rv); - rv = eventQService->CreateThreadEventQueue(); - return rv; } extern "C" JX_EXPORT void JNICALL -GECKO_NATIVE(initEmbedding) (JNIEnv* env, jclass, jobject aMozBinDirectory, - jobject aAppFileLocProvider) +GRE_NATIVE(initEmbeddingNative) (JNIEnv* env, jobject, jobject aLibXULDirectory, + jobject aAppDirectory, jobject aAppDirProvider) { - nsresult rv = InitEmbedding_Impl(env, aMozBinDirectory, aAppFileLocProvider); + nsresult rv = InitEmbedding_Impl(env, aLibXULDirectory, aAppDirectory, + aAppDirProvider); if (NS_FAILED(rv)) { ThrowException(env, rv, "Failure in initEmbedding"); @@ -102,15 +103,13 @@ GECKO_NATIVE(initEmbedding) (JNIEnv* env, jclass, jobject aMozBinDirectory, } extern "C" JX_EXPORT void JNICALL -GECKO_NATIVE(termEmbedding) (JNIEnv *env, jclass) +GRE_NATIVE(termEmbedding) (JNIEnv *env, jobject) { - // Free globals before calling NS_TermEmbedding(), since we need some + // Free globals before calling XRE_TermEmbedding(), since we need some // XPCOM services. FreeJavaGlobals(env); - nsresult rv = NS_TermEmbedding(); - if (NS_FAILED(rv)) - ThrowException(env, rv, "NS_TermEmbedding failed"); + XRE_TermEmbedding(); } nsresult @@ -160,7 +159,7 @@ InitXPCOM_Impl(JNIEnv* env, jobject aMozBinDirectory, } extern "C" JX_EXPORT jobject JNICALL -XPCOM_NATIVE(initXPCOM) (JNIEnv* env, jclass, jobject aMozBinDirectory, +XPCOM_NATIVE(initXPCOM) (JNIEnv* env, jobject, jobject aMozBinDirectory, jobject aAppFileLocProvider) { jobject servMan; @@ -175,7 +174,7 @@ XPCOM_NATIVE(initXPCOM) (JNIEnv* env, jclass, jobject aMozBinDirectory, } extern "C" JX_EXPORT void JNICALL -XPCOM_NATIVE(shutdownXPCOM) (JNIEnv *env, jclass, jobject aServMgr) +XPCOM_NATIVE(shutdownXPCOM) (JNIEnv *env, jobject, jobject aServMgr) { nsresult rv; nsCOMPtr servMgr; @@ -204,7 +203,7 @@ XPCOM_NATIVE(shutdownXPCOM) (JNIEnv *env, jclass, jobject aServMgr) } extern "C" JX_EXPORT jobject JNICALL -XPCOM_NATIVE(newLocalFile) (JNIEnv *env, jclass, jstring aPath, +XPCOM_NATIVE(newLocalFile) (JNIEnv *env, jobject, jstring aPath, jboolean aFollowLinks) { // Create a Mozilla string from the jstring @@ -235,7 +234,7 @@ XPCOM_NATIVE(newLocalFile) (JNIEnv *env, jclass, jstring aPath, } extern "C" JX_EXPORT jobject JNICALL -XPCOM_NATIVE(getComponentManager) (JNIEnv *env, jclass) +XPCOM_NATIVE(getComponentManager) (JNIEnv *env, jobject) { // Call XPCOM method nsIComponentManager* cm = nsnull; @@ -254,7 +253,7 @@ XPCOM_NATIVE(getComponentManager) (JNIEnv *env, jclass) } extern "C" JX_EXPORT jobject JNICALL -XPCOM_NATIVE(getComponentRegistrar) (JNIEnv *env, jclass) +XPCOM_NATIVE(getComponentRegistrar) (JNIEnv *env, jobject) { // Call XPCOM method nsIComponentRegistrar* cr = nsnull; @@ -273,7 +272,7 @@ XPCOM_NATIVE(getComponentRegistrar) (JNIEnv *env, jclass) } extern "C" JX_EXPORT jobject JNICALL -XPCOM_NATIVE(getServiceManager) (JNIEnv *env, jclass) +XPCOM_NATIVE(getServiceManager) (JNIEnv *env, jobject) { // Call XPCOM method nsIServiceManager* sm = nsnull; diff --git a/extensions/java/xpcom/nsJavaWrapper.cpp b/extensions/java/xpcom/nsJavaWrapper.cpp index 18d8d09f9657..29657e9066e3 100644 --- a/extensions/java/xpcom/nsJavaWrapper.cpp +++ b/extensions/java/xpcom/nsJavaWrapper.cpp @@ -45,7 +45,8 @@ #include "nsCRT.h" #include "prmem.h" -#define JAVAPROXY_NATIVE(func) Java_org_mozilla_xpcom_XPCOMJavaProxy_##func +#define JAVAPROXY_NATIVE(func) \ + Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_##func static nsID nullID = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}; @@ -1379,7 +1380,7 @@ QueryMethodInfo(nsIInterfaceInfo* aIInfo, const char* aMethodName, } /** - * org.mozilla.xpcom.XPCOMJavaProxy.callXPCOMMethod + * org.mozilla.xpcom.XPCOMJavaProxy.internal.callXPCOMMethod */ extern "C" JX_EXPORT jobject JNICALL JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy, @@ -1709,10 +1710,11 @@ GetXPCOMInstFromProxy(JNIEnv* env, jobject aJavaObject, void** aResult) } /** - * org.mozilla.xpcom.XPCOMJavaProxy.finalizeProxy + * org.mozilla.xpcom.internal.XPCOMJavaProxy.finalizeProxyNative */ extern "C" JX_EXPORT void JNICALL -JAVAPROXY_NATIVE(finalizeProxy) (JNIEnv *env, jclass that, jobject aJavaProxy) +JAVAPROXY_NATIVE(finalizeProxyNative) (JNIEnv *env, jclass that, + jobject aJavaProxy) { #ifdef DEBUG_JAVAXPCOM PRUint32 xpcom_addr = 0; diff --git a/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp b/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp index e0809902a460..46b2dbaf846c 100644 --- a/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp +++ b/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp @@ -224,7 +224,7 @@ InitializeJavaGlobals(JNIEnv *env) goto init_error; } - if (!(clazz = env->FindClass("org/mozilla/xpcom/XPCOMJavaProxy")) || + 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;")) || @@ -234,7 +234,7 @@ InitializeJavaGlobals(JNIEnv *env) "getNativeXPCOMInstance", "(Ljava/lang/Object;)J"))) { - NS_WARNING("Problem creating org.mozilla.xpcom.XPCOMJavaProxy globals"); + NS_WARNING("Problem creating org.mozilla.xpcom.internal.XPCOMJavaProxy globals"); goto init_error; } @@ -283,11 +283,14 @@ init_error: void FreeJavaGlobals(JNIEnv* env) { - PR_Lock(gJavaXPCOMLock); + PRLock* tempLock = nsnull; + if (gJavaXPCOMLock) { + PR_Lock(gJavaXPCOMLock); - // null out global lock so no one else can use it - PRLock* tempLock = gJavaXPCOMLock; - gJavaXPCOMLock = nsnull; + // null out global lock so no one else can use it + tempLock = gJavaXPCOMLock; + gJavaXPCOMLock = nsnull; + } gJavaXPCOMInitialized = PR_FALSE; @@ -354,8 +357,10 @@ FreeJavaGlobals(JNIEnv* env) xpcomJavaProxyClass = nsnull; } - PR_Unlock(tempLock); - PR_DestroyLock(tempLock); + if (tempLock) { + PR_Unlock(tempLock); + PR_DestroyLock(tempLock); + } } diff --git a/extensions/java/xpcom/src/GREImpl.java b/extensions/java/xpcom/src/GREImpl.java new file mode 100644 index 000000000000..83fc74c67347 --- /dev/null +++ b/extensions/java/xpcom/src/GREImpl.java @@ -0,0 +1,85 @@ +/* ***** 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.io.*; +import org.mozilla.xpcom.*; + + +public class GREImpl implements IGRE { + + public void initEmbedding(File aLibXULDirectory, File aAppDirectory, + IAppFileLocProvider aAppDirProvider) { + loadDependentLibraries(aLibXULDirectory); + initEmbeddingNative(aLibXULDirectory, aAppDirectory, aAppDirProvider); + } + + private void loadDependentLibraries(File binPath) { + String path = ""; + if (binPath != null) { + path = binPath + File.separator; + } + + System.load(path + System.mapLibraryName("nspr4")); + System.load(path + System.mapLibraryName("plds4")); + System.load(path + System.mapLibraryName("plc4")); + try { + /* try loading Win32 DLL */ + System.load(path + System.mapLibraryName("js3250")); + } catch (UnsatisfiedLinkError e) { } + try { + /* try loading Linux DLL */ + System.load(path + System.mapLibraryName("mozjs")); + } catch (UnsatisfiedLinkError e) { } + System.load(path + System.mapLibraryName("softokn3")); + System.load(path + System.mapLibraryName("nss3")); + System.load(path + System.mapLibraryName("smime3")); + System.load(path + System.mapLibraryName("ssl3")); + System.load(path + System.mapLibraryName("xul")); + System.load(path + System.mapLibraryName("xpcom")); + + System.load(path + System.mapLibraryName("javaxpcom")); + } + + public native void initEmbeddingNative(File aLibXULDirectory, + File aAppDirectory, IAppFileLocProvider aAppDirProvider); + + public native void termEmbedding(); + +} + diff --git a/extensions/java/xpcom/src/Makefile.in b/extensions/java/xpcom/src/Makefile.in new file mode 100755 index 000000000000..260cd4c40755 --- /dev/null +++ b/extensions/java/xpcom/src/Makefile.in @@ -0,0 +1,136 @@ +# ***** 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 ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ ; @srcdir@/.. + +include $(DEPTH)/config/autoconf.mk + +MODULE = javaxpcom +LIBRARY_NAME = javaxpcom +MOZILLA_INTERNAL_API = 1 + +# On Mac OS X, JNI libraries must end with a '.jnilib' extension +ifeq ($(OS_ARCH),Darwin) +DLL_SUFFIX = .jnilib +endif + +REQUIRES = xpcom \ + string \ + embed_base \ + xulapp \ + $(NULL) + +CPPSRCS = \ + nsAppFileLocProviderProxy.cpp \ + nsJavaInterfaces.cpp \ + nsJavaWrapper.cpp \ + nsJavaXPTCStub.cpp \ + nsJavaXPTCStubWeakRef.cpp \ + nsJavaXPCOMBindingUtils.cpp \ + $(NULL) + +JARFILE = javaconnect.jar +JARFILE_SRC = $(patsubst %.jar,%-src.jar,$(JARFILE)) + +JAVA_SRCS = \ + $(srcdir)/../XPCOMJavaProxy.java \ + $(srcdir)/GREImpl.java \ + $(srcdir)/XPCOMImpl.java \ + $(NULL) + +LOCAL_INCLUDES = -I$(JAVA_INCLUDE_PATH) + +ifeq ($(OS_ARCH),WINNT) +LOCAL_INCLUDES += -I$(JAVA_INCLUDE_PATH)/win32 +else +LOCAL_INCLUDES += -I$(JAVA_INCLUDE_PATH)/linux +endif + +EXTRA_DSO_LDOPTS = \ + $(LIBS_DIR) \ + $(EXTRA_DSO_LIBS) \ + $(MOZ_COMPONENT_LIBS) \ + $(NULL) + +GARBAGE += $(JARFILE) $(JARFILE_SRC) +GARBAGE_DIRS += _javagen org + +include $(topsrcdir)/config/rules.mk + +ifdef MOZ_DEBUG +JAVAC_FLAGS = -g +endif + +ifeq ($(OS_ARCH),WINNT) +RUN = +SEP = ; +else +RUN = $(DIST)/bin/run-mozilla.sh +SEP = : +endif + +_javagen/org/mozilla/xpcom/internal/.iface_done: $(JAVA_SRCS) + @if test ! -d _javagen/org/mozilla/xpcom/internal; then \ + touch .done; \ + $(INSTALL) -m 644 .done _javagen/org/mozilla/xpcom/internal; \ + fi + @echo Copying Java source files + @$(INSTALL) -m 644 $(JAVA_SRCS) \ + _javagen/org/mozilla/xpcom/internal + @touch $@ + +# Use find and xargs for passing list of Java files to JAVAC. This avoids the +# "argument list too long" error on Windows when using *.java +org/mozilla/xpcom/internal/.class_done: _javagen/org/mozilla/xpcom/internal/.iface_done + @echo Compiling Java interface classes + find _javagen -name "*.java" | xargs $(JAVAC) $(JAVAC_FLAGS) \ + -classpath ".$(SEP)../interfaces/MozillaInterfaces.jar" \ + -d . -sourcepath _javagen + @touch $@ + +$(JARFILE): org/mozilla/xpcom/internal/.class_done Makefile + $(JAR) cf $@ org + +$(JARFILE_SRC): $(JARFILE) + $(JAR) cf $@ -C _javagen org + +libs:: $(JARFILE) + $(INSTALL) $(IFLAGS1) $^ $(DIST)/bin + diff --git a/extensions/java/xpcom/src/XPCOMImpl.java b/extensions/java/xpcom/src/XPCOMImpl.java new file mode 100644 index 000000000000..bdaad106db16 --- /dev/null +++ b/extensions/java/xpcom/src/XPCOMImpl.java @@ -0,0 +1,60 @@ +/* ***** 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.io.*; +import org.mozilla.xpcom.*; + + +public class XPCOMImpl implements IXPCOM { + + public native nsIComponentManager getComponentManager(); + + public native nsIComponentRegistrar getComponentRegistrar(); + + public native nsIServiceManager getServiceManager(); + + public native nsIServiceManager initXPCOM(File aMozBinDirectory, + IAppFileLocProvider aAppFileLocProvider); + + public native nsILocalFile newLocalFile(String aPath, boolean aFollowLinks); + + public native void shutdownXPCOM(nsIServiceManager aServMgr); + +} + diff --git a/extensions/java/xpcom/tests/TestINIParser.java b/extensions/java/xpcom/tests/TestINIParser.java new file mode 100644 index 000000000000..0f718608ff46 --- /dev/null +++ b/extensions/java/xpcom/tests/TestINIParser.java @@ -0,0 +1,124 @@ +/* ***** 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 ***** */ + +import java.io.*; +import java.util.*; + +import org.mozilla.xpcom.INIParser; + + +public class TestINIParser { + + /** + * @param args path of INI file to parse, or null to parse + * a sample file + * @throws IOException + * @throws FileNotFoundException + */ + public static void main(String[] args) throws FileNotFoundException, + IOException { + if (args.length > 1) { + System.err.println("TestINIParser [file]"); + return; + } + + INIParser parser = null; + File iniFile = null; + File tempFile = null; + + try { + if (args.length == 1) { + iniFile = new File(args[0]); + parser = new INIParser(iniFile); + } else { + tempFile = File.createTempFile("testiniparser", null); + createSampleINIFile(tempFile); + parser = new INIParser(tempFile); + } + + printValidSections(parser); + } finally { + if (tempFile != null) { + tempFile.delete(); + } + } + } + + private static void createSampleINIFile(File aFile) throws IOException { + BufferedWriter out = new BufferedWriter(new FileWriter(aFile)); + out.write("; first comment\n"); + out.write("; second comment\n"); + out.newLine(); + out.write("[good section 1]\n"); + out.write("param1=value1\n"); + out.write("param2=value2\n"); + out.newLine(); + out.write("[invalid section] 1\n"); + out.write("blah=blippity-blah\n"); + out.newLine(); + out.write("[good section 2] \n"); + out.write("param3=value3\n"); + out.write("param4=value4\n"); + out.newLine(); + out.write("param5=value5\n"); + out.newLine(); + out.write("invalid pair\n"); + out.write("this shouldn't appear\n"); + out.write(" ; another comment\n"); + + out.close(); + } + + private static void printValidSections(INIParser aParser) { + Iterator sectionsIter = aParser.getSections(); + while (sectionsIter.hasNext()) { + String sectionName = (String) sectionsIter.next(); + System.out.println("[" + sectionName + "]"); + + Iterator keysIter = aParser.getKeys(sectionName); + while (keysIter.hasNext()) { + String key = (String) keysIter.next(); + String value = aParser.getString(sectionName, key); + System.out.println(key + " = " + value); + } + + System.out.println(); + } + } + +} + diff --git a/extensions/java/xpcom/tests/TestVersionComparator.java b/extensions/java/xpcom/tests/TestVersionComparator.java new file mode 100644 index 000000000000..d9e9ec9aa2f3 --- /dev/null +++ b/extensions/java/xpcom/tests/TestVersionComparator.java @@ -0,0 +1,102 @@ +/* ***** 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 ***** */ + +import org.mozilla.xpcom.VersionComparator; + +public class TestVersionComparator { + + public static void main(String[] args) { + String[] comparisons = { + "0.9", + "0.9.1", + "1.0pre1", + "1.0pre2", + "1.0", + "1.1pre", + "1.1pre1a", + "1.1pre1", + "1.1pre10a", + "1.1pre10", + "1.1", + "1.1.0.1", + "1.1.1", + "1.1.*", + "1.*", + "2.0", + "2.1", + "3.0.-1", + "3.0" + }; + + String[] equality = { + "1.1pre", + "1.1pre0", + "1.0+" + }; + + VersionComparator comp = new VersionComparator(); + + // test comparisons in both directions + for (int i = 0; i < comparisons.length - 1; i++) { + int res = comp.compare(comparisons[i], comparisons[i + 1]); + _assert(res < 0); + + res = comp.compare(comparisons[i + 1], comparisons[i]); + _assert(res > 0); + } + + // test equality in both directions + for (int i = 0; i < equality.length - 1; i++) { + int res = comp.compare(equality[i], equality[i + 1]); + _assert(res == 0); + + res = comp.compare(equality[i + 1], equality[i]); + _assert(res == 0); + } + + System.out.println("-- passed"); + } + + private static void _assert(boolean expression) { + if (!expression) { + Throwable t = new Throwable(); + t.printStackTrace(); + System.exit(1); + } + } +} +