Back to index

lightning-sunbird  0.9+nobinonly
Mozilla.java
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Java XPCOM Bindings.
00015  *
00016  * The Initial Developer of the Original Code is IBM Corporation.
00017  * Portions created by the Initial Developer are Copyright (C) 2006
00018  * IBM Corporation. All Rights Reserved.
00019  *
00020  * Contributor(s):
00021  *   Javier Pedemonte (jhpedemonte@gmail.com)
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 package org.mozilla.xpcom;
00038 
00039 import java.io.File;
00040 import java.io.FileNotFoundException;
00041 import java.io.IOException;
00042 import java.lang.reflect.Field;
00043 import java.lang.reflect.Method;
00044 import java.net.MalformedURLException;
00045 import java.net.URL;
00046 import java.net.URLClassLoader;
00047 import java.nio.charset.Charset;
00048 import java.util.ArrayList;
00049 import java.util.Enumeration;
00050 import java.util.Iterator;
00051 import java.util.Properties;
00052 
00053 import org.mozilla.interfaces.nsIComponentManager;
00054 import org.mozilla.interfaces.nsIComponentRegistrar;
00055 import org.mozilla.interfaces.nsILocalFile;
00056 import org.mozilla.interfaces.nsIServiceManager;
00057 import org.mozilla.interfaces.nsISupports;
00058 
00059 
00088 public class Mozilla implements IMozilla, IGRE, IXPCOM, IJavaXPCOMUtils,
00089 IXPCOMError {
00090 
00091   private static Mozilla mozillaInstance = new Mozilla();
00092 
00093   private static final String JAVAXPCOM_JAR = "javaxpcom.jar";
00094 
00095   private IMozilla mozilla = null;
00096   private IGRE gre = null;
00097   private IXPCOM xpcom = null;
00098   private IJavaXPCOMUtils jxutils = null;
00099 
00103   public static Mozilla getInstance() {
00104     return mozillaInstance;
00105   }
00106 
00110   private Mozilla() {
00111   }
00112 
00135   public static File getGREPathWithProperties(GREVersionRange[] aVersions,
00136           Properties aProperties) throws FileNotFoundException {
00137     File grePath = null;
00138 
00139     // if GRE_HOME is in the environment, use that GRE
00140     String env = System.getProperty("GRE_HOME");
00141     if (env != null) {
00142       try {
00143         grePath = new File(env).getCanonicalFile();
00144       } catch (IOException e) {
00145         throw new FileNotFoundException("cannot access GRE_HOME");
00146       }
00147       if (!grePath.exists()) {
00148         throw new FileNotFoundException("GRE_HOME doesn't exist");
00149       }
00150       return grePath;
00151     }
00152 
00153     // the Gecko bits that sit next to the application or in the PATH
00154     env = System.getProperty("USE_LOCAL_GRE");
00155     if (env != null) {
00156       return null;
00157     }
00158 
00159     // Search for GRE in platform specific locations.  We want a GRE that
00160     // supports Java, so we look for the "javaxpcom" property by default.
00161     if (aProperties == null) {
00162       aProperties = new Properties();
00163     }
00164     aProperties.setProperty("javaxpcom", "1");
00165 
00166     String osName = System.getProperty("os.name").toLowerCase();
00167     if (osName.startsWith("mac os x")) {
00168       grePath = getGREPathMacOSX(aVersions);
00169     } else if (osName.startsWith("windows")) {
00170       grePath = getGREPathWindows(aVersions, aProperties);
00171     } else {
00172       // assume everything else is Unix/Linux
00173       grePath = getGREPathUnix(aVersions, aProperties);
00174     }
00175 
00176     if (grePath == null) {
00177       throw new FileNotFoundException("GRE not found");
00178     }
00179 
00180     return grePath;
00181   }
00182 
00187   private static File getGREPathMacOSX(GREVersionRange[] aVersions) {
00188     /*
00189      * Check the application bundle first, for
00190      * <bundle>/Contents/Frameworks/XUL.framework/libxpcom.dylib.
00191      */
00192     File grePath = findGREBundleFramework();
00193     if (grePath != null) {
00194       return grePath;
00195     }
00196 
00197     // Check ~/Library/Frameworks/XUL.framework/Versions/<version>/libxpcom.dylib
00198     String home = System.getProperty("user.home");
00199     if (home != null) {
00200       grePath = findGREFramework(home, aVersions);
00201       if (grePath != null) {
00202         return grePath;
00203       }
00204     }
00205 
00206     // Check /Library/Frameworks/XUL.framework/Versions/<version>/libxpcom.dylib
00207     return findGREFramework("", aVersions);
00208   }
00209 
00213   private static File findGREBundleFramework() {
00214     /*
00215      * Use reflection to get Apple's NSBundle class, which can be used
00216      * to get the bundle's "Frameworks" directory.
00217      */
00218     try {
00219       URL[] urls = new URL[1];
00220       urls[0] = new File("/System/Library/Java/").toURL();
00221       ClassLoader loader = new URLClassLoader(urls);
00222       Class bundleClass = Class.forName("com.apple.cocoa.foundation.NSBundle",
00223                                         true, loader);
00224 
00225       // Get the bundle for this app.  If this is not executing from
00226       // a bundle, this will return null.
00227       Method mainBundleMethod = bundleClass.getMethod("mainBundle", null);
00228       Object bundle = mainBundleMethod.invoke(null, null);
00229 
00230       if (bundle != null) {
00231         // Get the path to the bundle's "Frameworks" directory
00232         Method fwPathMethod = bundleClass.getMethod("privateFrameworksPath",
00233                                                     null);
00234         String path = (String) fwPathMethod.invoke(bundle, null);
00235 
00236         // look for libxpcom.dylib
00237         if (path.length() != 0) {
00238           File xulDir = new File(path, "XUL.framework");
00239           if (xulDir.isDirectory()) {
00240             File xpcomLib = new File(xulDir, "libxpcom.dylib");
00241             if (xpcomLib.canRead()) {
00242               File grePath = xpcomLib.getCanonicalFile().getParentFile();
00243 
00244               // Since GRE Properties aren't supported on Mac OS X, we check
00245               // for the existence of the "javaxpcom.jar" file in the GRE.
00246               File jar = new File(grePath, JAVAXPCOM_JAR);
00247               if (jar.canRead()) {
00248                 // found GRE
00249                 return grePath;
00250               }
00251             }
00252           }
00253         }
00254       }
00255     } catch (Exception e) { }
00256 
00257     return null;
00258   }
00259 
00265   private static File findGREFramework(String aRootPath,
00266                                        GREVersionRange[] aVersions) {
00267     File frameworkDir = new File(aRootPath +
00268                                  "/Library/Frameworks/XUL.framework/Versions");
00269     if (!frameworkDir.exists())
00270       return null;
00271 
00272     File[] files = frameworkDir.listFiles();
00273     for (int i = 0; i < files.length; i++) {
00274       if (checkVersion(files[i].getName(), aVersions)) {
00275         File xpcomLib = new File(files[i], "libxpcom.dylib");
00276 
00277         // Since GRE Properties aren't supported on Mac OS X, we check
00278         // for the existence of the "javaxpcom.jar" file in the GRE.
00279         File jar = new File(files[i], JAVAXPCOM_JAR);
00280         if (xpcomLib.canRead() && jar.canRead()) {
00281           return files[i];
00282         }
00283       }
00284     }
00285 
00286     return null;
00287   }
00288 
00294   private static File getGREPathWindows(GREVersionRange[] aVersions,
00295                                         Properties aProperties) {
00296     /*
00297      * Note the usage of the "Software\\mozilla.org\\GRE" subkey - this allows
00298      * us to have multiple versions of GREs on the same machine by having
00299      * subkeys such as 1.0, 1.1, 2.0 etc. under it.
00300      *
00301      * Please see http://www.mozilla.org/projects/embedding/GRE.html for
00302      * more info.
00303      */
00304 
00305     final String greKey = "Software\\mozilla.org\\GRE";
00306 
00307     // See if there is a GRE registered for the current user.
00308     // If not, look for one on the system.
00309     String key = "HKEY_CURRENT_USER" + "\\" + greKey;
00310     File grePath = getGREPathFromRegKey(key, aVersions, aProperties);
00311     if (grePath == null) {
00312       key = "HKEY_LOCAL_MACHINE" + "\\" + greKey;
00313       grePath = getGREPathFromRegKey(key, aVersions, aProperties);
00314     }
00315 
00316     return grePath;
00317   }
00318 
00325   private static File getGREPathFromRegKey(String aRegKey,
00326           GREVersionRange[] aVersions, Properties aProperties) {
00327     // create a temp file for the registry export
00328     File tempFile;
00329     try {
00330       tempFile = File.createTempFile("jx_registry", null);
00331     } catch (IOException e) {
00332       // failed to create temp file.  ABORT
00333       return null;
00334     }
00335 
00336     Process proc;
00337     try {
00338       proc = Runtime.getRuntime().exec("regedit /e " + "\"" + tempFile.getPath()
00339               + "\" \"" + aRegKey + "\"");
00340       proc.waitFor();
00341     } catch (Exception e) {
00342       // Failed to run regedit.exe.  Length of temp file is zero, and that's
00343       // handled next.
00344     }
00345 
00346     // If there is a key by that name in the registry, then the file length
00347     // will not be zero.
00348     File grePath = null;
00349     if (tempFile.length() != 0) {
00350       grePath = getGREPathFromRegistryFile(tempFile.getPath(),
00351               aRegKey, aVersions, aProperties);
00352     }
00353 
00354     tempFile.delete();
00355     return grePath;
00356   }
00357 
00366   private static File getGREPathFromRegistryFile(String aFileName,
00367           String aKeyName, GREVersionRange[] aVersions,
00368           Properties aProperties) {
00369     INIParser parser;
00370     try {
00371       parser = new INIParser(aFileName, Charset.forName("UTF-16"));
00372     } catch (Exception e) {
00373       // Problem reading from file.  Bail out.
00374       return null;
00375     }
00376 
00377     Iterator sectionsIter = parser.getSections();
00378     while (sectionsIter.hasNext()) {
00379       // get 'section' name, which will be a registry key name
00380       String section = (String) sectionsIter.next();
00381 
00382       // Skip over GRE key ("<root>\Software\mozilla.org\GRE")
00383       int gre_len = aKeyName.length();
00384       if (section.length() <= gre_len) {
00385         continue;
00386       }
00387 
00388       // Get the GRE subkey;  that is, everything after
00389       // "<root>\Software\mozilla.org\GRE\"
00390       String subkeyName = section.substring(gre_len + 1);
00391 
00392       // We are only interested in _immediate_ subkeys.  We want
00393       // "<root>\Software\mozilla.org\GRE<version>" but not
00394       // "<root>\Software\mozilla.org\GRE<version><moretext>".
00395       if (subkeyName.indexOf('\\') != -1) {
00396         continue;
00397       }
00398 
00399       // See if this registry key has a "Version" value, and if so, compare
00400       // it to our desired versions.
00401       String version = parser.getString(section, "\"Version\"");
00402       if (version == null) {
00403         continue;
00404       }
00405       // remove quotes around string
00406       version = version.substring(1, version.length() - 1);
00407       if (!checkVersion(version, aVersions)) {
00408         continue;
00409       }
00410 
00411       // All properties must match, keeping in mind that the propery/value
00412       // pairs returned by regedit.exe have quotes around them.
00413       if (aProperties != null) {
00414         boolean ok = true;
00415         Enumeration e = aProperties.propertyNames();
00416         while (ok && e.hasMoreElements()) {
00417           String prop = (String) e.nextElement();
00418           String greValue = parser.getString(section, "\"" + prop + "\"");
00419           if (greValue == null) {
00420             // No such property is set for this GRE. Go on to next GRE.
00421             ok = false;
00422           } else  {
00423             // See if the value of the property for the GRE matches
00424             // the given value.
00425             String value = aProperties.getProperty(prop);
00426             if (!greValue.equals("\"" + value + "\"")) {
00427               ok = false;
00428             }
00429           }
00430         }
00431         if (!ok) {
00432           continue;
00433         }
00434       }
00435 
00436       String pathStr = parser.getString(section, "\"GreHome\"");
00437       if (pathStr != null) {
00438         // remove quotes around string
00439         pathStr = pathStr.substring(1, pathStr.length() - 1);
00440         File grePath = new File(pathStr);
00441         if (grePath.exists()) {
00442           File xpcomLib = new File(grePath, "xpcom.dll");
00443           if (xpcomLib.canRead()) {
00444             // found a good GRE
00445             return grePath;
00446           }
00447         }
00448       }
00449     }
00450 
00451     return null;
00452   }
00453 
00459   private static File getGREPathUnix(GREVersionRange[] aVersions,
00460                                      Properties aProperties) {
00461     File grePath = null;
00462 
00463     String env = System.getProperty("MOZ_GRE_CONF");
00464     if (env != null) {
00465       grePath = getPathFromConfigFile(env, aVersions, aProperties);
00466       if (grePath != null) {
00467         return grePath;
00468       }
00469     }
00470 
00471     final String greUserConfFile = ".gre.config";
00472     final String greUserConfDir = ".gre.d";
00473     final String greConfPath = "/etc/gre.conf";
00474     final String greConfDir = "/etc/gre.d";
00475 
00476     env = System.getProperty("user.home");
00477     if (env != null) {
00478       // Look in ~/.gre.config
00479       grePath = getPathFromConfigFile(env + File.separator + greUserConfFile,
00480                                       aVersions, aProperties);
00481       if (grePath != null) {
00482         return grePath;
00483       }
00484 
00485       // Look in ~/.gre.d/*.conf
00486       grePath = getPathFromConfigDir(env + File.separator + greUserConfDir,
00487                                      aVersions, aProperties);
00488       if (grePath != null) {
00489         return grePath;
00490       }
00491     }
00492 
00493     // Look for a global /etc/gre.conf file
00494     grePath = getPathFromConfigFile(greConfPath, aVersions, aProperties);
00495     if (grePath != null) {
00496       return grePath;
00497     }
00498 
00499     // Look for a group of config files in /etc/gre.d/
00500     grePath = getPathFromConfigDir(greConfDir, aVersions, aProperties);
00501     return grePath;
00502   }
00503 
00510   private static File getPathFromConfigFile(String aFileName,
00511           GREVersionRange[] aVersions, Properties aProperties) {
00512     INIParser parser;
00513     try {
00514       parser = new INIParser(aFileName);
00515     } catch (Exception e) {
00516       // Problem reading from file.  Bail out.
00517       return null;
00518     }
00519 
00520     Iterator sectionsIter = parser.getSections();
00521     while (sectionsIter.hasNext()) {
00522       // get 'section' name, which will be a version string
00523       String section = (String) sectionsIter.next();
00524 
00525       // if this isn't one of the versions we are looking for, move
00526       // on to next section
00527       if (!checkVersion(section, aVersions)) {
00528         continue;
00529       }
00530 
00531       // all properties must match
00532       if (aProperties != null) {
00533         boolean ok = true;
00534         Enumeration e = aProperties.propertyNames();
00535         while (ok && e.hasMoreElements()) {
00536           String prop = (String) e.nextElement();
00537           String greValue = parser.getString(section, prop);
00538           if (greValue == null) {
00539             // No such property is set for this GRE. Go on to next GRE.
00540             ok = false;
00541           } else  {
00542             // See if the value of the property for the GRE matches
00543             // the given value.
00544             if (!greValue.equals(aProperties.getProperty(prop))) {
00545               ok = false;
00546             }
00547           }
00548         }
00549         if (!ok) {
00550           continue;
00551         }
00552       }
00553 
00554       String pathStr = parser.getString(section, "GRE_PATH");
00555       if (pathStr != null) {
00556         File grePath = new File(pathStr);
00557         if (grePath.exists()) {
00558           File xpcomLib = new File(grePath, "libxpcom.so");
00559           if (xpcomLib.canRead()) {
00560             // found a good GRE
00561             return grePath;
00562           }
00563         }
00564       }
00565     }
00566 
00567     return null;
00568   }
00569 
00576   private static File getPathFromConfigDir(String aDirName,
00577           GREVersionRange[] aVersions, Properties aProperties) {
00578     /*
00579      * Open the directory provided and try to read any files in that
00580      * directory that end with .conf.  We look for an entry that might
00581      * point to the GRE that we're interested in.
00582      */
00583 
00584     File dir = new File(aDirName);
00585     if (!dir.isDirectory()) {
00586       return null;
00587     }
00588 
00589     File grePath = null;
00590     File[] files = dir.listFiles();
00591     for (int i = 0; i < files.length && grePath == null; i++) {
00592       // only look for files that end in '.conf'
00593       if (!files[i].getName().endsWith(".conf")) {
00594         continue;
00595       }
00596 
00597       grePath = getPathFromConfigFile(files[i].getPath(), aVersions,
00598                                       aProperties);
00599     }
00600 
00601     return grePath;
00602   }
00603 
00609   private static boolean checkVersion(String aVersionToCheck,
00610                                       GREVersionRange[] aVersions) {
00611     for (int i = 0; i < aVersions.length; i++) {
00612       if (aVersions[i].check(aVersionToCheck)) {
00613         return true;
00614       }
00615     }
00616     return false;
00617   }
00618 
00629   public void initialize(File aLibXULDirectory)
00630   throws XPCOMInitializationException {
00631     File jar = new File(aLibXULDirectory, JAVAXPCOM_JAR);
00632     if (!jar.exists()) {
00633       throw new XPCOMInitializationException("Could not find " + JAVAXPCOM_JAR +
00634           " in " + aLibXULDirectory);
00635     }
00636 
00637     URL[] urls = new URL[1];
00638     try {
00639       urls[0] = jar.toURL();
00640     } catch (MalformedURLException e) {
00641       throw new XPCOMInitializationException(e);
00642     }
00643     ClassLoader loader = new URLClassLoader(urls,
00644             this.getClass().getClassLoader());
00645 
00646     try {
00647       Class mozillaClass = Class.forName("org.mozilla.xpcom.internal.MozillaImpl",
00648           true, loader);
00649       mozilla  = (IMozilla) mozillaClass.newInstance();
00650 
00651       Class greClass = Class.forName("org.mozilla.xpcom.internal.GREImpl",
00652           true, loader);
00653       gre = (IGRE) greClass.newInstance();
00654 
00655       Class xpcomClass = Class.forName("org.mozilla.xpcom.internal.XPCOMImpl",
00656                                        true, loader);
00657       xpcom = (IXPCOM) xpcomClass.newInstance();
00658 
00659       Class javaXPCOMClass =
00660          Class.forName("org.mozilla.xpcom.internal.JavaXPCOMMethods",
00661                        true, loader);
00662       jxutils  = (IJavaXPCOMUtils) javaXPCOMClass.newInstance();
00663     } catch (Exception e) {
00664       throw new XPCOMInitializationException("Could not load " +
00665           "org.mozilla.xpcom.internal.* classes", e);
00666     }
00667     
00668     mozilla.initialize(aLibXULDirectory);
00669   }
00670 
00693   public void initEmbedding(File aLibXULDirectory, File aAppDirectory,
00694           IAppFileLocProvider aAppDirProvider) throws XPCOMException {
00695     try {
00696       gre.initEmbedding(aLibXULDirectory, aAppDirectory, aAppDirProvider);
00697     } catch (NullPointerException e) {
00698       throw new XPCOMInitializationException("Must call " +
00699           "Mozilla.getInstance().initialize() before using this method", e);
00700     }
00701   }
00702 
00712   public void termEmbedding() {
00713     try {
00714       gre.termEmbedding();
00715     } catch (NullPointerException e) {
00716       throw new XPCOMInitializationException("Must call " +
00717           "Mozilla.getInstance().initialize() before using this method", e);
00718     } finally {
00719       mozilla = null;
00720       gre = null;
00721       xpcom = null;
00722     }
00723   }
00724 
00740   public ProfileLock lockProfileDirectory(File aDirectory)
00741   throws XPCOMException {
00742          try {
00743      return gre.lockProfileDirectory(aDirectory);
00744     } catch (NullPointerException e) {
00745       throw new XPCOMInitializationException("Must call " +
00746           "Mozilla.getInstance().initialize() before using this method", e);      
00747     }
00748   }
00749 
00788   public void notifyProfile() {
00789     try {
00790       gre.notifyProfile();
00791     } catch (NullPointerException e) {
00792       throw new XPCOMInitializationException("Must call " +
00793           "Mozilla.getInstance().initialize() before using this method", e);
00794     }
00795   }
00796 
00822   public nsIServiceManager initXPCOM(File aMozBinDirectory,
00823           IAppFileLocProvider aAppFileLocProvider) throws XPCOMException {
00824     try {
00825       return xpcom.initXPCOM(aMozBinDirectory, aAppFileLocProvider);
00826     } catch (NullPointerException e) {
00827       throw new XPCOMInitializationException("Must call " +
00828           "Mozilla.getInstance().initialize() before using this method", e);
00829     }
00830   }
00831 
00843   public void shutdownXPCOM(nsIServiceManager aServMgr) throws XPCOMException {
00844     try {
00845       xpcom.shutdownXPCOM(aServMgr);
00846     } catch (NullPointerException e) {
00847       throw new XPCOMInitializationException("Must call " +
00848           "Mozilla.getInstance().initialize() before using this method", e);
00849     } finally {
00850       mozilla = null;
00851       gre = null;
00852       xpcom = null;
00853     }
00854   }
00855 
00865   public nsIServiceManager getServiceManager() throws XPCOMException {
00866     try {
00867       return xpcom.getServiceManager();
00868     } catch (NullPointerException e) {
00869       throw new XPCOMInitializationException("Must call " +
00870           "Mozilla.getInstance().initialize() before using this method", e);
00871     }
00872   }
00873 
00883   public nsIComponentManager getComponentManager() throws XPCOMException {
00884     try {
00885       return xpcom.getComponentManager();
00886     } catch (NullPointerException e) {
00887       throw new XPCOMInitializationException("Must call " +
00888           "Mozilla.getInstance().initialize() before using this method", e);
00889     }
00890   }
00891 
00901   public nsIComponentRegistrar getComponentRegistrar() throws XPCOMException {
00902     try {
00903       return xpcom.getComponentRegistrar();
00904     } catch (NullPointerException e) {
00905       throw new XPCOMInitializationException("Must call " +
00906           "Mozilla.getInstance().initialize() before using this method", e);
00907     }
00908   }
00909 
00930   public nsILocalFile newLocalFile(String aPath, boolean aFollowLinks)
00931           throws XPCOMException {
00932     try {
00933       return xpcom.newLocalFile(aPath, aFollowLinks);
00934     } catch (NullPointerException e) {
00935       throw new XPCOMInitializationException("Must call " +
00936           "Mozilla.getInstance().initialize() before using this method", e);
00937     }
00938   }
00939 
00959   public static nsISupports queryInterface(nsISupports aObject, String aIID) {
00960     ArrayList classes = new ArrayList();
00961     classes.add(aObject.getClass());
00962 
00963     while (!classes.isEmpty()) {
00964       Class clazz = (Class) classes.remove(0);
00965 
00966       // Skip over any class/interface in the "java.*" and "javax.*" domains.
00967       String className = clazz.getName();
00968       if (className.startsWith("java.") || className.startsWith("javax.")) {
00969         continue;
00970       }
00971 
00972       // If given IID matches that of the current interface, then we
00973       // know that aObject implements the interface specified by the given IID.
00974       if (clazz.isInterface() && className.startsWith("org.mozilla")) {
00975         String iid = Mozilla.getInterfaceIID(clazz);
00976         if (iid != null && aIID.equals(iid)) {
00977           return aObject;
00978         }
00979       }
00980 
00981       // clazz didn't match, so add the interfaces it implements
00982       Class[] interfaces = clazz.getInterfaces();
00983       for (int i = 0; i < interfaces.length; i++ ) {
00984         classes.add(interfaces[i]);
00985       }
00986 
00987       // Also add its superclass
00988       Class superclass = clazz.getSuperclass();
00989       if (superclass != null) {
00990         classes.add(superclass);
00991       }
00992     }
00993 
00994     return null;
00995   }
00996 
01005   public static String getInterfaceIID(Class aInterface) {
01006     // Get short class name (i.e. "bar", not "org.blah.foo.bar")
01007     StringBuffer iidName = new StringBuffer();
01008     String fullClassName = aInterface.getName();
01009     int index = fullClassName.lastIndexOf(".");
01010     String className = index > 0 ? fullClassName.substring(index + 1)
01011                                  : fullClassName;
01012 
01013     // Create iid field name
01014     if (className.startsWith("ns")) {
01015       iidName.append("NS_");
01016       iidName.append(className.substring(2).toUpperCase());
01017     } else {
01018       iidName.append(className.toUpperCase());
01019     }
01020     iidName.append("_IID");
01021 
01022     String iid;
01023     try {
01024       Field iidField = aInterface.getDeclaredField(iidName.toString());
01025       iid = (String) iidField.get(null);
01026     } catch (NoSuchFieldException e) {
01027       // Class may implement non-Mozilla interfaces, which would not have an
01028       // IID method.  In that case, just null.
01029       iid = null;
01030     } catch (IllegalAccessException e) {
01031       // Not allowed to access that field for some reason.  Write out an
01032       // error message, but don't fail.
01033       System.err.println("ERROR: Could not get field " + iidName.toString());
01034       iid = null;
01035     }
01036 
01037     return iid;
01038   }
01039 
01040   public long getNativeHandleFromAWT(Object widget) {
01041     try {
01042       return mozilla.getNativeHandleFromAWT(widget);
01043     } catch (NullPointerException e) {
01044       throw new XPCOMInitializationException("Must call " +
01045           "Mozilla.getInstance().initialize() before using this method", e);
01046     }
01047   }
01048 
01049        public long wrapJavaObject(Object aJavaObject, String aIID) {
01050               try {
01051                      return jxutils.wrapJavaObject(aJavaObject, aIID);
01052               } catch (NullPointerException e) {
01053                      throw new XPCOMInitializationException("Must call " +
01054                             "Mozilla.getInstance().initialize() before using this method", e);
01055               }
01056        }
01057        
01058        public Object wrapXPCOMObject(long aXPCOMObject, String aIID) {
01059               try {
01060                      return jxutils.wrapXPCOMObject(aXPCOMObject, aIID);
01061               } catch (NullPointerException e) {
01062                      throw new XPCOMInitializationException("Must call " +
01063                             "Mozilla.getInstance().initialize() before using this method", e);
01064               }
01065        }
01066 
01067 }