/* * <p> * An required extension is missing, if an ExtensionInstallationProvider is * registered, delegate the installation of that particular extension to it. * </p> * * @param reqInfo Missing extension information * @param instInfo Older installed version information * * @return true if the installation is successful */ protected boolean installExtension(ExtensionInfo reqInfo, ExtensionInfo instInfo) throws ExtensionInstallationException { Vector currentProviders; synchronized (providers) { currentProviders = (Vector) providers.clone(); } for (Enumeration e = currentProviders.elements(); e.hasMoreElements(); ) { ExtensionInstallationProvider eip = (ExtensionInstallationProvider) e.nextElement(); if (eip != null) { // delegate the installation to the provider if (eip.installExtension(reqInfo, instInfo)) { debug(reqInfo.name + " installation successful"); Launcher.ExtClassLoader cl = (Launcher.ExtClassLoader) Launcher.getLauncher().getClassLoader().getParent(); addNewExtensionsToClassLoader(cl); return true; } } } // We have tried all of our providers, noone could install this // extension, we just return failure at this point debug(reqInfo.name + " installation failed"); return false; }
/* * <p> * Check that a particular dependency on an extension is satisfied. * </p> * @param extensionName is the key used for the attributes in the manifest * @param attr is the attributes of the manifest file * * @return true if the dependency is satisfied by the installed extensions */ protected boolean checkExtension(final String extensionName, final Attributes attr) throws ExtensionInstallationException { debug("Checking extension " + extensionName); if (checkExtensionAgainstInstalled(extensionName, attr)) return true; debug("Extension not currently installed "); ExtensionInfo reqInfo = new ExtensionInfo(extensionName, attr); return installExtension(reqInfo, null); }
/* * Check for all declared required extensions in the jar file * manifest. */ protected boolean checkExtensions(JarFile jar) throws ExtensionInstallationException { Manifest man; try { man = jar.getManifest(); } catch (IOException e) { return false; } if (man == null) { // The applet does not define a manifest file, so // we just assume all dependencies are satisfied. return true; } boolean result = true; Attributes attr = man.getMainAttributes(); if (attr != null) { // Let's get the list of declared dependencies String value = attr.getValue(Name.EXTENSION_LIST); if (value != null) { StringTokenizer st = new StringTokenizer(value); // Iterate over all declared dependencies while (st.hasMoreTokens()) { String extensionName = st.nextToken(); debug("The file " + jar.getName() + " appears to depend on " + extensionName); // Sanity Check String extName = extensionName + "-" + Name.EXTENSION_NAME.toString(); if (attr.getValue(extName) == null) { debug( "The jar file " + jar.getName() + " appers to depend on " + extensionName + " but does not define the " + extName + " attribute in its manifest "); } else { if (!checkExtension(extensionName, attr)) { debug("Failed installing " + extensionName); result = false; } } } } else { debug("No dependencies for " + jar.getName()); } } return result; }
/* * <p> * Scan the directories and return all files installed in those * </p> * @param dirs list of directories to scan * * @return the list of files installed in all the directories */ private static File[] getExtFiles(File[] dirs) throws IOException { Vector urls = new Vector(); for (int i = 0; i < dirs.length; i++) { String[] files = dirs[i].list(new JarFilter()); debug("getExtFiles files.length " + files.length); if (files != null) { for (int j = 0; j < files.length; j++) { File f = new File(dirs[i], files[j]); urls.add(f); debug("getExtFiles f[" + j + "] " + f); } } } File[] ua = new File[urls.size()]; urls.copyInto(ua); debug("getExtFiles ua.length " + ua.length); return ua; }
/* * <p> * Add the newly installed jar file to the extension class loader. * </p> * * @param cl the current installed extension class loader * * @return true if successful */ private Boolean addNewExtensionsToClassLoader(Launcher.ExtClassLoader cl) { try { File[] installedExts = getInstalledExtensions(); for (int i = 0; i < installedExts.length; i++) { final File instFile = installedExts[i]; URL instURL = (URL) AccessController.doPrivileged( new PrivilegedAction() { public Object run() { try { return (URL) ParseUtil.fileToEncodedURL(instFile); } catch (MalformedURLException e) { debugException(e); return null; } } }); if (instURL != null) { URL[] urls = cl.getURLs(); boolean found = false; for (int j = 0; j < urls.length; j++) { debug("URL[" + j + "] is " + urls[j] + " looking for " + instURL); if (urls[j].toString().compareToIgnoreCase(instURL.toString()) == 0) { found = true; debug("Found !"); } } if (!found) { debug("Not Found ! adding to the classloader " + instURL); cl.addExtURL(instURL); } } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); // let's continue with the next installed extension } return Boolean.TRUE; }
/** @return the java.ext.dirs property as a list of directory */ private static File[] getExtDirs() { String s = (String) java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("java.ext.dirs")); File[] dirs; if (s != null) { StringTokenizer st = new StringTokenizer(s, File.pathSeparator); int count = st.countTokens(); debug("getExtDirs count " + count); dirs = new File[count]; for (int i = 0; i < count; i++) { dirs[i] = new File(st.nextToken()); debug("getExtDirs dirs[" + i + "] " + dirs[i]); } } else { dirs = new File[0]; debug("getExtDirs dirs " + dirs); } debug("getExtDirs dirs.length " + dirs.length); return dirs; }
/** * Checks the dependencies of the jar file on installed extension. * * @param jarFile containing the attriutes declaring the dependencies */ public static synchronized boolean checkExtensionsDependencies(JarFile jar) { if (providers == null) { // no need to bother, nobody is registered to install missing // extensions return true; } try { ExtensionDependency extDep = new ExtensionDependency(); return extDep.checkExtensions(jar); } catch (ExtensionInstallationException e) { debug(e.getMessage()); } return false; }
/* * <p> * Check if the requested extension described by the attributes * in the manifest under the key extensionName is compatible with * the jar file. * </p> * * @param extensionName key in the attibute list * @param attr manifest file attributes * @param file installed extension jar file to compare the requested * extension against. */ protected boolean checkExtensionAgainst(String extensionName, Attributes attr, final File file) throws IOException, FileNotFoundException, ExtensionInstallationException { debug("Checking extension " + extensionName + " against " + file.getName()); // Load the jar file ... Manifest man; try { man = (Manifest) AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws IOException, FileNotFoundException { if (!file.exists()) throw new FileNotFoundException(file.getName()); JarFile jarFile = new JarFile(file); return jarFile.getManifest(); } }); } catch (PrivilegedActionException e) { if (e.getException() instanceof FileNotFoundException) throw (FileNotFoundException) e.getException(); throw (IOException) e.getException(); } // Construct the extension information object ExtensionInfo reqInfo = new ExtensionInfo(extensionName, attr); debug("Requested Extension : " + reqInfo); int isCompatible = ExtensionInfo.INCOMPATIBLE; ExtensionInfo instInfo = null; if (man != null) { Attributes instAttr = man.getMainAttributes(); if (instAttr != null) { instInfo = new ExtensionInfo(null, instAttr); debug("Extension Installed " + instInfo); isCompatible = instInfo.isCompatibleWith(reqInfo); switch (isCompatible) { case ExtensionInfo.COMPATIBLE: debug("Extensions are compatible"); return true; case ExtensionInfo.INCOMPATIBLE: debug("Extensions are incompatible"); return false; default: // everything else debug("Extensions require an upgrade or vendor switch"); return installExtension(reqInfo, instInfo); } } } return true; }