FileDocCategorySizeDatePackage
ExtensionValidator.javaAPI DocGlassfish v2 API16973Fri May 04 22:32:30 BST 2007org.apache.catalina.util

ExtensionValidator

public final class ExtensionValidator extends Object
Ensures that all extension dependies are resolved for a WEB application are met. This class builds a master list of extensions available to an applicaiton and then validates those extensions. See http://java.sun.com/j2se/1.4/docs/guide/extensions/spec.html for a detailed explanation of the extension mechanism in Java.
author
Greg Murray
author
Justyna Horwat
version
$Revision: 1.4 $ $Date: 2007/05/05 05:32:30 $

Fields Summary
private static com.sun.org.apache.commons.logging.Log
log
private static StringManager
sm
The string resources for this package.
private static HashMap
containerAvailableExtensions
private static ArrayList
containerManifestResources
private static ResourceBundle
messages
Constructors Summary
Methods Summary
private static voidaddSystemResource(java.io.File jarFile)


        Manifest manifest = getManifest(new FileInputStream(jarFile));
        if (manifest != null)  {
            ManifestResource mre
                = new ManifestResource(jarFile.getAbsolutePath(),
                                       manifest,
                                       ManifestResource.SYSTEM);
            containerManifestResources.add(mre);
        }
    
private static java.util.HashMapbuildAvailableExtensionsMap(java.util.ArrayList resources)


        HashMap availableMap = null;

        Iterator it = resources.iterator();
        while (it.hasNext()) {
            ManifestResource mre = (ManifestResource)it.next();
            HashMap map = mre.getAvailableExtensions();
            if (map != null) {
                Iterator values = map.values().iterator();
                while (values.hasNext()) {
                    Extension ext = (Extension) values.next();
                    if (availableMap == null) {
                        availableMap = new HashMap();
                        availableMap.put(ext.getUniqueId(), ext);
                    } else if (!availableMap.containsKey(ext.getUniqueId())) {
                        availableMap.put(ext.getUniqueId(), ext);
                    }
                }
            }
        }

        return availableMap;
    
private static java.util.jar.ManifestgetManifest(java.io.InputStream inStream)
Return the Manifest from a jar file or war file

param
inStream Input stream to a WAR or JAR file
return
The WAR's or JAR's manifest


        Manifest manifest = null;
        JarInputStream jin = null;

        try {
            jin = new JarInputStream(inStream);
            manifest = jin.getManifest();
            jin.close();
            jin = null;
        } finally {
            if (jin != null) {
                try {
                    jin.close();
                } catch (Throwable t) {
                    // Ignore
                }
            }
        }

        return manifest;
    
public static synchronized booleanvalidateApplication(javax.naming.directory.DirContext dirContext, org.apache.catalina.core.StandardContext context)
Runtime validation of a Web Applicaiton. This method uses JNDI to look up the resources located under a DirContext. It locates Web Application MANIFEST.MF file in the /META-INF/ directory of the application and all MANIFEST.MF files in each JAR file located in the WEB-INF/lib directory and creates an ArrayList of ManifestResorce objects. These objects are then passed to the validateManifestResources method for validation.

param
dirContext The JNDI root of the Web Application
param
context The context from which the Logger and path to the application
return
true if all required extensions satisfied



    // ----------------------------------------------------- Static Initializer


                                                          
     

        // check for container level optional packages
        String systemClasspath = System.getProperty("java.class.path");

        StringTokenizer strTok = new StringTokenizer(systemClasspath, 
                                                     File.pathSeparator);

        // build a list of jar files in the classpath
        while (strTok.hasMoreTokens()) {
            String classpathItem = strTok.nextToken();
            if (classpathItem.toLowerCase().endsWith(".jar")) {
                File item = new File(classpathItem);
                if (item.exists()) {
                    try {
                        addSystemResource(item);
                    } catch (IOException e) {
                        log.error(sm.getString
                                  ("extensionValidator.failload", item), e);
                    }
                }
            }
        }

        // get the files in the extensions directory
        String extensionsDir = System.getProperty("java.ext.dirs");
        if (extensionsDir != null) {
            StringTokenizer extensionsTok
                = new StringTokenizer(extensionsDir, File.pathSeparator);
            while (extensionsTok.hasMoreTokens()) {
                File targetDir = new File(extensionsTok.nextToken());
                if (!targetDir.exists() || !targetDir.isDirectory()) {
                    continue;
                }
                File[] files = targetDir.listFiles();
                for (int i = 0; i < files.length; i++) {
                    if (files[i].getName().toLowerCase().endsWith(".jar")) {
                        try {
                            addSystemResource(files[i]);
                        } catch (IOException e) {
                            log.error
                                (sm.getString
                                 ("extensionValidator.failload", files[i]), e);
                        }
                    }
                }
            }
        }

    

        String appName = context.getPath();
        ArrayList appManifestResources = new ArrayList();
        ManifestResource appManifestResource = null;
        // If the application context is null it does not exist and 
        // therefore is not valid
        if (dirContext == null) return false;
        // Find the Manifest for the Web Applicaiton
        InputStream inputStream = null;
        try {
            NamingEnumeration wne = dirContext.listBindings("/META-INF/");
            Binding binding = (Binding) wne.nextElement();
            if (binding.getName().toUpperCase().equals("MANIFEST.MF")) {
                Resource resource = (Resource)dirContext.lookup
                                    ("/META-INF/" + binding.getName());
                inputStream = resource.streamContent();
                Manifest manifest = new Manifest(inputStream);
                inputStream.close();
                inputStream = null;
                ManifestResource mre = new ManifestResource
                    (sm.getString("extensionValidator.web-application-manifest"),
                    manifest, ManifestResource.WAR);
                appManifestResources.add(mre);
            } 
        } catch (NamingException nex) {
            // Application does not contain a MANIFEST.MF file
        } catch (NoSuchElementException nse) {
            // Application does not contain a MANIFEST.MF file
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Throwable t) {
                    // Ignore
                }
            }
        }

        // Locate the Manifests for all bundled JARs
        NamingEnumeration ne = null;
        try {
            if (dirContext != null) {
                ne = dirContext.listBindings("WEB-INF/lib/");
            }
            while ((ne != null) && ne.hasMoreElements()) {
                Binding binding = (Binding)ne.nextElement();
                if (!binding.getName().toLowerCase().endsWith(".jar")) {
                    continue;
                }
                Resource resource = (Resource)dirContext.lookup
                                        ("/WEB-INF/lib/" + binding.getName());
                Manifest jmanifest = getManifest(resource.streamContent());
                if (jmanifest != null) {
                    ManifestResource mre = new ManifestResource(
                                                binding.getName(),
                                                jmanifest, 
                                                ManifestResource.APPLICATION);
                    appManifestResources.add(mre);
                }
            }
        } catch (NamingException nex) {
            // Jump out of the check for this application because it 
            // has no resources
        }

        return validateManifestResources(appName, appManifestResources);
    
private static booleanvalidateManifestResources(java.lang.String appName, java.util.ArrayList resources)
Validates a ArrayList of ManifestResource objects. This method requires an application name (which is the context root of the application at runtime). false is returned if the extension dependencies represented by any given ManifestResource objects is not met. This method should also provide static validation of a Web Applicaiton if provided with the necessary parameters.

param
appName The name of the Application that will appear in the error messages
param
resources A list of ManifestResource objects to be validated.
return
true if manifest resource file requirements are met

        boolean passes = true;
        int failureCount = 0;        
        HashMap availableExtensions = null;

        Iterator it = resources.iterator();
        while (it.hasNext()) {
            ManifestResource mre = (ManifestResource)it.next();
            ArrayList requiredList = mre.getRequiredExtensions();
            if (requiredList == null) {
                continue;
            }

            // build the list of available extensions if necessary
            if (availableExtensions == null) {
                availableExtensions = buildAvailableExtensionsMap(resources);
            }

            // load the container level resource map if it has not been built
            // yet
            if (containerAvailableExtensions == null) {
                containerAvailableExtensions
                    = buildAvailableExtensionsMap(containerManifestResources);
            }

            // iterate through the list of required extensions
            Iterator rit = requiredList.iterator();
            while (rit.hasNext()) {
                Extension requiredExt = (Extension)rit.next();
                String extId = requiredExt.getUniqueId();
                // check the applicaion itself for the extension
                if (availableExtensions != null
                                && availableExtensions.containsKey(extId)) {
                   Extension targetExt = (Extension)
                       availableExtensions.get(extId);
                   if (targetExt.isCompatibleWith(requiredExt)) {
                       requiredExt.setFulfilled(true);
                   }
                // check the container level list for the extension
                } else if (containerAvailableExtensions != null
                        && containerAvailableExtensions.containsKey(extId)) {
                   Extension targetExt = (Extension)
                       containerAvailableExtensions.get(extId);
                   if (targetExt.isCompatibleWith(requiredExt)) {
                       requiredExt.setFulfilled(true);
                   }
                } else {
                    // Failure
                    log.info(sm.getString(
                        "extensionValidator.extension-not-found-error",
                        appName, mre.getResourceName(),
                        requiredExt.getExtensionName()));
                    passes = false;
                    failureCount++;
                }
            }
        }

        if (!passes) {
            log.info(sm.getString(
                     "extensionValidator.extension-validation-error", appName,
                     failureCount + ""));
        }

        return passes;