ExtensionDependency.java revision 2362
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* <p>
* This class checks dependent extensions a particular jar file may have
* declared through its manifest attributes.
* </p>
* Jar file declared dependent extensions through the extension-list
* attribute. The extension-list contains a list of keys used to
* fetch the other attributes describing the required extension.
* If key is the extension key declared in the extension-list
* attribute, the following describing attribute can be found in
* the manifest :
* key-Extension-Name: (Specification package name)
* key-Specification-Version: (Specification-Version)
* key-Implementation-Version: (Implementation-Version)
* key-Implementation-Vendor-Id: (Imlementation-Vendor-Id)
* key-Implementation-Version: (Implementation version)
* key-Implementation-URL: (URL to download the requested extension)
* <p>
* This class also maintain versioning consistency of installed
* extensions dependencies declared in jar file manifest.
* </p>
* @author Jerome Dochez
*/
public class ExtensionDependency {
/* Callbak interfaces to delegate installation of missing extensions */
/**
* <p>
* Register an ExtensionInstallationProvider. The provider is responsible
* for handling the installation (upgrade) of any missing extensions.
* </p>
* @param eip ExtensionInstallationProvider implementation
*/
public synchronized static void addExtensionInstallationProvider
{
}
}
/**
* <p>
* Unregister a previously installed installation provider
* </p>
*/
public synchronized static void removeExtensionInstallationProvider
{
}
/**
* <p>
* Checks the dependencies of the jar file on installed extension.
* </p>
* @param jarFile containing the attriutes declaring the dependencies
*/
{
// no need to bother, nobody is registered to install missing
// extensions
return true;
}
try {
} catch (ExtensionInstallationException e) {
debug(e.getMessage());
}
return false;
}
/*
* Check for all declared required extensions in the jar file
* manifest.
*/
{
try {
} catch (IOException e) {
return false;
}
// The applet does not define a manifest file, so
// we just assume all dependencies are satisfied.
return true;
}
boolean result = true;
// Let's get the list of declared dependencies
// Iterate over all declared dependencies
while (st.hasMoreTokens()) {
" appears to depend on " + extensionName);
// Sanity Check
" appers to depend on "
+ extensionName + " but does not define the " +
extName + " attribute in its manifest ");
} else {
result = false;
}
}
}
} else {
}
}
return result;
}
/*
* <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
*/
final Attributes attr)
{
return true;
debug("Extension not currently installed ");
}
/*
* <p>
* Check if a particular extension is part of the currently installed
* extensions.
* </p>
* @param extensionName is the key for the attributes in the manifest
* @param attr is the attributes of the manifest
*
* @return true if the requested extension is already installed
*/
{
if (fExtension != null) {
// Extension already installed, just check against this one
try {
return true;
} catch (FileNotFoundException e) {
debugException(e);
} catch (IOException e) {
debugException(e);
}
return false;
} else {
// Not sure if extension is already installed, so check all the
// installed extension jar files to see if we get a match
try {
// Get the list of installed extension jar files so we can
// compare the installed versus the requested extension
} catch(IOException e) {
debugException(e);
return false;
}
try {
return true;
} catch (FileNotFoundException e) {
debugException(e);
} catch (IOException e) {
debugException(e);
// let's continue with the next installed extension
}
}
}
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.
*/
throws IOException,
{
// Load the jar file ...
try {
new PrivilegedExceptionAction<Manifest>() {
throws IOException, FileNotFoundException {
return jarFile.getManifest();
}
});
} catch(PrivilegedActionException e) {
if (e.getException() instanceof FileNotFoundException)
throw (FileNotFoundException) e.getException();
throw (IOException) e.getException();
}
// Construct the extension information object
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 false;
}
/*
* <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
*/
{
synchronized(providers) {
}
// delegate the installation to the provider
return true;
}
}
}
// We have tried all of our providers, noone could install this
// extension, we just return failure at this point
return false;
}
/**
* <p>
* Checks if the extension, that is specified in the extension-list in
* the applet jar manifest, is already installed (i.e. exists in the
* extension directory).
* </p>
*
* @param extensionName extension name in the extension-list
*
* @return the extension if it exists in the extension directory
*/
// Function added to fix bug 4504166
return AccessController.doPrivileged(
new PrivilegedAction<File>() {
try {
// Search the extension directories for the extension that is specified
// in the attribute extension-list in the applet jar manifest
} else {
}
if (fExtension.exists()) {
return fExtension;
}
}
}
return null;
} catch(Exception e) {
debugException(e);
return null;
}
}
});
}
/**
* <p>
* @return the java.ext.dirs property as a list of directory
* </p>
*/
private static File[] getExtDirs() {
if (s != null) {
for (int i = 0; i < count; i++) {
}
} else {
}
return dirs;
}
/*
* <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
*/
}
}
}
return ua;
}
/*
* <p>
* @return the list of installed extensions jar files
* </p>
*/
return AccessController.doPrivileged(
new PrivilegedAction<File[]>() {
try {
return getExtFiles(getExtDirs());
} catch(IOException e) {
debug("Cannot get list of installed extensions");
debugException(e);
return new File[0];
}
}
});
}
/*
* <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
*/
try {
new PrivilegedAction<URL>() {
try {
} catch (MalformedURLException e) {
debugException(e);
return null;
}
}
});
boolean found=false;
instURL);
found=true;
debug("Found !");
}
}
if (!found) {
debug("Not Found ! adding to the classloader " +
instURL);
}
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
// let's continue with the next installed extension
}
}
// True to display all debug and trace messages
static final boolean DEBUG = false;
if (DEBUG) {
}
}
private void debugException(Throwable e) {
if (DEBUG) {
e.printStackTrace();
}
}
}