luehe 2003/07/30 11:48:18 Modified: catalina/src/share/org/apache/catalina/util ExtensionValidator.java ManifestResource.java Log: Fixed NPE. Available and required extensions are now consistently NULL if not present. Previous code was inconsistent, assuming empty HashMap/ArrayList if no available/required extensions were present, but actually never allocating a HashMap/ArrayList in that case. Allocate HashMap/ArrayList objects only when needed. Revision Changes Path 1.4 +113 -104 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/ExtensionValidator.java Index: ExtensionValidator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/ExtensionValidator.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ExtensionValidator.java 30 Aug 2002 18:41:26 -0000 1.3 +++ ExtensionValidator.java 30 Jul 2003 18:48:18 -0000 1.4 @@ -176,22 +176,21 @@ // --------------------------------------------------------- Public Methods /** - * Runtime validation of a Web Applicaiton. + * Runtime validation of a Web Applicaiton. * - * This method uses JNDI to look up the resources located under a - * <code>DirContext</code>. 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 <code>ArrayList</code> of - * <code>ManifestResorce<code> objects. These objects are then passed - * to the validateManifestResources method for validation. - * - * @param DirContext The JNDI root of the Web Application - * @param StandardContext The context from which the Logger and path - * to the application - * - * @return true if all required extensions satisfied + * This method uses JNDI to look up the resources located under a + * <code>DirContext</code>. 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 <code>ArrayList</code> of + * <code>ManifestResorce<code> 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 */ public static synchronized boolean validateApplication( DirContext dirContext, @@ -203,7 +202,7 @@ // If the application context is null it does not exist and // therefore is not valid if (dirContext == null) return false; - // Find the Mainfest for the Web Applicaiton + // Find the Manifest for the Web Applicaiton try { NamingEnumeration wne = null; wne = dirContext.listBindings("/META-INF/"); @@ -254,12 +253,13 @@ // Jump out of the check for this application because it // has no resources } - return validateManifestResources(appName,appManifestResources, logger); + return validateManifestResources(appName, appManifestResources, + logger); } /** - * Return an instance of the ExtensionValidator. - * The ExtensionValidator is a singleton. + * Return an instance of the ExtensionValidator. + * The ExtensionValidator is a singleton. */ public static ExtensionValidator getInstance() { if (validator == null) { @@ -283,86 +283,90 @@ * This method should also provide static validation of a Web Applicaiton * if provided with the necessary parameters. * - * @param String The name of the Application that will appear in the - * error messages - * @param ArrayList A list of <code>ManifestResource</code> objects + * @param appName The name of the Application that will appear in the + * error messages + * @param resources A list of <code>ManifestResource</code> objects * to be validated. - * @param Logger A logger to which failure messages are logged. + * @param logger A logger to which failure messages are logged. * * @return true if manifest resource file requirements are met - * */ private static boolean validateManifestResources(String appName, ArrayList resources, Logger logger) { boolean passes = true; - int failureCount = 0; - + int failureCount = 0; HashMap availableExtensions = null; + Iterator it = resources.iterator(); - // iterate through the list while (it.hasNext()) { ManifestResource mre = (ManifestResource)it.next(); - // check if the resource requires extensions - if (mre.requiresExtensions()) { - // 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); - } - // get a list of the required extensions - ArrayList requiredList = mre.getRequiredExtensions(); - Iterator rit = requiredList.iterator(); - // iterate through the list of required extensions - while (rit.hasNext()) { - Extension requiredExtension = (Extension)rit.next(); - String key = requiredExtension.getUniqueId(); - // check in the applicaion first for the extension - if (availableExtensions.containsKey(key)) { - // check if the desired extension is compatible - // with the required extension - Extension targetExtension = (Extension) - ((ManifestResource)availableExtensions.get(key)). - getAvailableExtensions().get(key); - // check if the desired extension is valid - if (targetExtension.isCompatibleWith(requiredExtension)) { - // extension requirements have passed - requiredExtension.setFulfilled(true); - } - // check the container level list for the extension - } else if (containerAvailableExtensions.containsKey(key)) { - // check if the desired extension is compatible - // with the required extension - Extension targetExtension = (Extension) - ((ManifestResource)containerAvailableExtensions. - get(key)).getAvailableExtensions().get(key); - // check if the desired extension is valid - if (targetExtension.isCompatibleWith(requiredExtension)) { - // extension requirements have passed - requiredExtension.setFulfilled(true); - } - } else { - // FAILURE has occured - String[] args = {appName, mre.getResourceName(), - requiredExtension.getExtensionName() }; - logMessage("extensionValidator.extension-not-found-error", - args, logger); - passes = false; - failureCount++; - } + 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 requiredExtension = (Extension)rit.next(); + String key = requiredExtension.getUniqueId(); + // check in the applicaion first for the extension + if (availableExtensions != null + && availableExtensions.containsKey(key)) { + // check if the desired extension is compatible + // with the required extension + Extension targetExtension = (Extension) + ((ManifestResource)availableExtensions.get(key)). + getAvailableExtensions().get(key); + // check if the desired extension is valid + if (targetExtension.isCompatibleWith(requiredExtension)) { + // extension requirements have passed + requiredExtension.setFulfilled(true); + } + // check the container level list for the extension + } else if (containerAvailableExtensions != null + && containerAvailableExtensions.containsKey(key)) { + // check if the desired extension is compatible + // with the required extension + Extension targetExtension = (Extension) + ((ManifestResource)containerAvailableExtensions. + get(key)).getAvailableExtensions().get(key); + // check if the desired extension is valid + if (targetExtension.isCompatibleWith(requiredExtension)) { + // extension requirements have passed + requiredExtension.setFulfilled(true); + } + } else { + // FAILURE has occured + String[] args = {appName, mre.getResourceName(), + requiredExtension.getExtensionName() }; + logMessage("extensionValidator.extension-not-found-error", + args, logger); + passes = false; + failureCount++; } } } + if (!passes) { String[] args = {appName,failureCount + "" }; logMessage("extensionValidator.extension-validation-error", args, logger); } + return passes; } @@ -379,39 +383,45 @@ * NOTE: A list is built only if there is a dependency that needs * to be checked (performace optimization). * - * @param ArrayList A list of <code>ManifestResource</code> objects + * @param resources A list of <code>ManifestResource</code> objects * * @return HashMap Map of available extensions */ private static HashMap buildAvailableExtensionsMap(ArrayList resources) { - HashMap availableMap = new HashMap(); + + HashMap availableMap = null; + Iterator it = resources.iterator(); - // iterate through the list while (it.hasNext()) { ManifestResource mre = (ManifestResource)it.next(); if (mre.requiresExtensions()) { HashMap map = mre.getAvailableExtensions(); - Iterator kit = map.keySet().iterator(); - while (kit.hasNext()) { - String key = (String)kit.next(); - Extension ext = (Extension)map.get(key); - // mre is needed for error reporting if a match is not made - // it has access to the extensions - if (!availableMap.containsKey(key)) { - availableMap.put(ext.getUniqueId(), mre); + if (map != null) { + Iterator kit = map.keySet().iterator(); + while (kit.hasNext()) { + String key = (String)kit.next(); + Extension ext = (Extension)map.get(key); + // mre is needed for error reporting if a match is not + // made. it has access to the extensions + if (availableMap == null) { + availableMap = new HashMap(); + availableMap.put(ext.getUniqueId(), mre); + } else if (!availableMap.containsKey(key)) { + availableMap.put(ext.getUniqueId(), mre); + } } } } } + return availableMap; } - /** + /** * Return the Manifest from a jar file or war file * * @param File is a war file or a jar file * @return java.util.jar.Manifest - * */ private static Manifest getManifest(File file) { try { @@ -424,17 +434,17 @@ } /** - * Standardized method of logging localized messages by the - * ExtensionValidator. + * Standardized method of logging localized messages by the + * ExtensionValidator. * * @param String The key of the message in the ResourceBundle * @param String[] The Arguments to be applied to the messages * if any (null) if none * @param Logger The logger to which the messages will be logged - * */ - private static void logMessage(String messageId, String[] args, Logger logger) { - String message = getMessage(messageId, logger); + private static void logMessage(String messageId, String[] args, + Logger logger) { + String message = getMessage(messageId, logger); if (args != null) { logger.log(MessageFormat.format(message, args)); } else { @@ -443,15 +453,14 @@ } /** - * Standardized method of obtaining a localized message. + * Standardized method of obtaining a localized message. * - * @param String The key of the message in the ResourceBundle - * @param Logger The logger to which error messages encounter looking + * @param messageId The key of the message in the ResourceBundle + * @param logger The logger to which error messages encounter looking * up resources will be logged * * @return String message string */ - private static String getMessage(String messageId, Logger logger) { // load localized messages if necessary if (messages == null) { 1.2 +38 -35 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/ManifestResource.java Index: ManifestResource.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/ManifestResource.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ManifestResource.java 24 Aug 2002 02:27:28 -0000 1.1 +++ ManifestResource.java 30 Jul 2003 18:48:18 -0000 1.2 @@ -97,27 +97,27 @@ } /** - * return the name of the resource + * Gets the name of the resource * - * @return Strig the name of the resource + * @return The name of the resource */ public String getResourceName() { return resourceName; } /** - * Return the map of available extensions + * Gets the map of available extensions * - * @return HashMap map of available extensions + * @return Map of available extensions */ public HashMap getAvailableExtensions() { return availableExtensions; } /** - * Return the list of required extensions + * Gets the list of required extensions * - * @return ArrayList list of required extensions + * @return List of required extensions */ public ArrayList getRequiredExtensions() { return requiredExtensions; @@ -126,23 +126,21 @@ // --------------------------------------------------------- Public Methods /** - * Return the number of available extensions + * Gets the number of available extensions * - * @return int the number of available extensions + * @return The number of available extensions */ public int getAvailableExtensionCount() { - if (availableExtensions == null) return 0; - return availableExtensions.size(); + return (availableExtensions != null) ? availableExtensions.size() : 0; } /** - * Return the number of required extensions + * Gets the number of required extensions * - * @return int the number of required extensions + * @return The number of required extensions */ public int getRequiredExtensionCount() { - if (requiredExtensions == null) return 0; - return requiredExtensions.size(); + return (requiredExtensions != null) ? requiredExtensions.size() : 0; } /** @@ -152,8 +150,7 @@ * @return true if required extensions are present */ public boolean requiresExtensions() { - if (getRequiredExtensionCount() > 0) return true; - else return false; + return (requiredExtensions != null) ? true : false; } /** @@ -165,18 +162,18 @@ * @return true if extension available */ public boolean containsExtension(String key) { - return (availableExtensions.containsKey(key)); + return (availableExtensions != null) ? + availableExtensions.containsKey(key) : false; } /** - * Returns <code>true</code> if all required extension dependencies + * Returns <code>true</code> if all required extension dependencies * have been meet for this <code>ManifestResource</code> object. * - * @return boolean true if extension dependencies satisfied + * @return boolean true if all extension dependencies have been satisfied */ public boolean isFulfilled() { - if ((requiredExtensions == null) || - requiredExtensions.size() ==0) { + if (requiredExtensions == null) { return false; } Iterator it = requiredExtensions.iterator(); @@ -217,20 +214,22 @@ /** * Return the set of <code>Extension</code> objects representing optional - * packages that are required by the application contained in the JAR or WAR - * file associated with the specified <code>Manifest</code>. If there - * are no such optional packages, null is returned. + * packages that are required by the application associated with the + * specified <code>Manifest</code>. * * @param manifest Manifest to be parsed * - * @return ArrayList list of required extensions + * @return List of required extensions, or null if the application + * does not require any extensions */ private ArrayList getRequiredExtensions(Manifest manifest) { - ArrayList extensionList = new ArrayList(); + Attributes attributes = manifest.getMainAttributes(); String names = attributes.getValue("Extension-List"); if (names == null) return null; + + ArrayList extensionList = new ArrayList(); names += " "; while (true) { @@ -262,20 +261,23 @@ /** * Return the set of <code>Extension</code> objects representing optional - * packages that are avaiable by the application contained in the JAR - * file associated with the specified <code>Manifest</code>. If there - * are no such optional packages, a zero-length list is returned. + * packages that are bundled with the application associated with the + * specified <code>Manifest</code>. * * @param manifest Manifest to be parsed * - * @return HashMap Map of available extensions + * @return Map of available extensions, or null if the web application + * does not bundle any extensions */ private HashMap getAvailableExtensions(Manifest manifest) { - HashMap extensionMap = new HashMap(); + Attributes attributes = manifest.getMainAttributes(); String name = attributes.getValue("Extension-Name"); if (name == null) return (null); + + HashMap extensionMap = new HashMap(); + Extension extension = new Extension(); extension.setExtensionName(name); extension.setImplementationURL @@ -291,6 +293,7 @@ // creating a unique extension identifier with the key and value pair if (!extensionMap.containsKey(name + version)) extensionMap.put(name + version, extension); + return extensionMap; }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]