tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hor...@apache.org
Subject cvs commit: jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util Extension.java ExtensionValidator.java ManifestResource.java LocalStrings.properties
Date Sat, 24 Aug 2002 02:27:28 GMT
horwat      2002/08/23 19:27:28

  Modified:    catalina/src/share/org/apache/catalina/loader
                        StandardClassLoader.java WebappClassLoader.java
                        WebappLoader.java
               catalina/src/share/org/apache/catalina/startup
                        Bootstrap.java BootstrapService.java
                        ContextConfig.java Tool.java
               catalina/src/share/org/apache/catalina/core
                        StandardContext.java
               catalina/src/share/org/apache/catalina/util
                        LocalStrings.properties
  Added:       catalina/src/share/org/apache/catalina/util Extension.java
                        ExtensionValidator.java ManifestResource.java
  Removed:     catalina/src/share/org/apache/catalina/loader Extension.java
  Log:
  Implementation of extension version checking as defined by the Optional Package Versioning mechanism (http://java.sun.com/j2se/1.4/docs/guide/extensions).
  
  During deployment, declared dependencies in manifest entries of library JARs and WARs are now recognized. If these dependencies are not satisfied, the applicati on is rejected with an informative log message.
  
  Removed the broken dependency checking mechanism.
  
  Submitted by: Justyna Horwat and Greg Murray
  
  Revision  Changes    Path
  1.3       +4 -120    jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java
  
  Index: StandardClassLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- StandardClassLoader.java	7 Aug 2002 15:00:36 -0000	1.2
  +++ StandardClassLoader.java	24 Aug 2002 02:27:27 -0000	1.3
  @@ -249,15 +249,6 @@
   
   
       /**
  -     * The set of optional packages (formerly standard extensions) that
  -     * are available in the repositories associated with this class loader.
  -     * Each object in this list is of type
  -     * <code>org.apache.catalina.loader.Extension</code>.
  -     */
  -    protected ArrayList available = new ArrayList();
  -
  -
  -    /**
        * The debugging detail level of this component.
        */
       protected int debug = 0;
  @@ -282,15 +273,6 @@
   
   
       /**
  -     * The set of optional packages (formerly standard extensions) that
  -     * are required in the repositories associated with this class loader.
  -     * Each object in this list is of type
  -     * <code>org.apache.catalina.loader.Extension</code>.
  -     */
  -    protected ArrayList required = new ArrayList();
  -
  -
  -    /**
        * A list of read File and Jndi Permission's required if this loader
        * is for a web application context.
        */
  @@ -445,41 +427,6 @@
   
   
       /**
  -     * Return a list of "optional packages" (formerly "standard extensions")
  -     * that have been declared to be available in the repositories associated
  -     * with this class loader, plus any parent class loader implemented with
  -     * the same class.
  -     */
  -    public Extension[] findAvailable() {
  -
  -        // Initialize the results with our local available extensions
  -        ArrayList results = new ArrayList();
  -        Iterator available = this.available.iterator();
  -        while (available.hasNext())
  -            results.add(available.next());
  -
  -        // Trace our parentage tree and add declared extensions when possible
  -        ClassLoader loader = this;
  -        while (true) {
  -            loader = loader.getParent();
  -            if (loader == null)
  -                break;
  -            if (!(loader instanceof StandardClassLoader))
  -                continue;
  -            Extension extensions[] =
  -                ((StandardClassLoader) loader).findAvailable();
  -            for (int i = 0; i < extensions.length; i++)
  -                results.add(extensions[i]);
  -        }
  -
  -        // Return the results as an array
  -        Extension extensions[] = new Extension[results.size()];
  -        return ((Extension[]) results.toArray(extensions));
  -
  -    }
  -
  -
  -    /**
        * Return a String array of the current repositories for this class
        * loader.  If there are no repositories, a zero-length array is
        * returned.
  @@ -492,41 +439,6 @@
   
   
       /**
  -     * Return a list of "optional packages" (formerly "standard extensions")
  -     * that have been declared to be required in the repositories associated
  -     * with this class loader, plus any parent class loader implemented with
  -     * the same class.
  -     */
  -    public Extension[] findRequired() {
  -
  -        // Initialize the results with our local required extensions
  -        ArrayList results = new ArrayList();
  -        Iterator required = this.required.iterator();
  -        while (required.hasNext())
  -            results.add(required.next());
  -
  -        // Trace our parentage tree and add declared extensions when possible
  -        ClassLoader loader = this;
  -        while (true) {
  -            loader = loader.getParent();
  -            if (loader == null)
  -                break;
  -            if (!(loader instanceof StandardClassLoader))
  -                continue;
  -            Extension extensions[] =
  -                ((StandardClassLoader) loader).findRequired();
  -            for (int i = 0; i < extensions.length; i++)
  -                results.add(extensions[i]);
  -        }
  -
  -        // Return the results as an array
  -        Extension extensions[] = new Extension[results.size()];
  -        return ((Extension[]) results.toArray(extensions));
  -
  -    }
  -
  -
  -    /**
        * This class loader doesn't check for reloading.
        */
       public boolean modified() {
  @@ -542,13 +454,6 @@
       public String toString() {
   
           StringBuffer sb = new StringBuffer("StandardClassLoader\r\n");
  -        sb.append("  available:\r\n");
  -        Iterator available = this.available.iterator();
  -        while (available.hasNext()) {
  -            sb.append("    ");
  -            sb.append(available.next().toString());
  -            sb.append("\r\n");
  -        }
           sb.append("  delegate: ");
           sb.append(delegate);
           sb.append("\r\n");
  @@ -558,13 +463,6 @@
               sb.append(repositories[i]);
               sb.append("\r\n");
           }
  -        sb.append("  required:\r\n");
  -        Iterator required = this.required.iterator();
  -        while (required.hasNext()) {
  -            sb.append("    ");
  -            sb.append(required.next().toString());
  -            sb.append("\r\n");
  -        }
           if (this.parent != null) {
               sb.append("----------> Parent Classloader:\r\n");
               sb.append(this.parent.toString());
  @@ -1090,20 +988,6 @@
                       throw new IllegalArgumentException
                           ("addRepositoryInternal:  Invalid URL '" +
                            repository + "'");
  -                }
  -                if (!((manifest == null) && (jarFile == null))) {
  -                    if ((manifest == null) && (jarFile != null))
  -                        manifest = jarFile.getManifest();
  -                    if (manifest != null) {
  -                        Iterator extensions =
  -                            Extension.getAvailable(manifest).iterator();
  -                        while (extensions.hasNext())
  -                            available.add(extensions.next());
  -                        extensions =
  -                            Extension.getRequired(manifest).iterator();
  -                        while (extensions.hasNext())
  -                            required.add(extensions.next());
  -                    }
                   }
               } catch (Throwable t) {
                   t.printStackTrace();
  
  
  
  1.5       +4 -121    jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java
  
  Index: WebappClassLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- WebappClassLoader.java	14 Aug 2002 20:12:54 -0000	1.4
  +++ WebappClassLoader.java	24 Aug 2002 02:27:27 -0000	1.5
  @@ -248,15 +248,6 @@
   
   
       /**
  -     * The set of optional packages (formerly standard extensions) that
  -     * are available in the repositories associated with this class loader.
  -     * Each object in this list is of type
  -     * <code>org.apache.catalina.loader.Extension</code>.
  -     */
  -    protected ArrayList available = new ArrayList();
  -
  -
  -    /**
        * The cache of ResourceEntry for classes and resources we have loaded,
        * keyed by resource name.
        */
  @@ -343,15 +334,6 @@
   
   
       /**
  -     * The set of optional packages (formerly standard extensions) that
  -     * are required in the repositories associated with this class loader.
  -     * Each object in this list is of type
  -     * <code>org.apache.catalina.loader.Extension</code>.
  -     */
  -    protected ArrayList required = new ArrayList();
  -
  -
  -    /**
        * A list of read File and Jndi Permission's required if this loader
        * is for a web application context.
        */
  @@ -680,55 +662,6 @@
           }
           result4[jarRealFiles.length] = file;
           jarRealFiles = result4;
  -
  -        // Load manifest
  -        Manifest manifest = jarFile.getManifest();
  -        if (manifest != null) {
  -            Iterator extensions = Extension.getAvailable(manifest).iterator();
  -            while (extensions.hasNext()) {
  -                available.add(extensions.next());
  -            }
  -            extensions = Extension.getRequired(manifest).iterator();
  -            while (extensions.hasNext()) {
  -                required.add(extensions.next());
  -            }
  -        }
  -
  -    }
  -
  -
  -    /**
  -     * Return a list of "optional packages" (formerly "standard extensions")
  -     * that have been declared to be available in the repositories associated
  -     * with this class loader, plus any parent class loader implemented with
  -     * the same class.
  -     */
  -    public Extension[] findAvailable() {
  -
  -        // Initialize the results with our local available extensions
  -        ArrayList results = new ArrayList();
  -        Iterator available = this.available.iterator();
  -        while (available.hasNext())
  -            results.add(available.next());
  -
  -        // Trace our parentage tree and add declared extensions when possible
  -        ClassLoader loader = this;
  -        while (true) {
  -            loader = loader.getParent();
  -            if (loader == null)
  -                break;
  -            if (!(loader instanceof WebappClassLoader))
  -                continue;
  -            Extension extensions[] =
  -                ((WebappClassLoader) loader).findAvailable();
  -            for (int i = 0; i < extensions.length; i++)
  -                results.add(extensions[i]);
  -        }
  -
  -        // Return the results as an array
  -        Extension extensions[] = new Extension[results.size()];
  -        return ((Extension[]) results.toArray(extensions));
  -
       }
   
   
  @@ -745,41 +678,6 @@
   
   
       /**
  -     * Return a list of "optional packages" (formerly "standard extensions")
  -     * that have been declared to be required in the repositories associated
  -     * with this class loader, plus any parent class loader implemented with
  -     * the same class.
  -     */
  -    public Extension[] findRequired() {
  -
  -        // Initialize the results with our local required extensions
  -        ArrayList results = new ArrayList();
  -        Iterator required = this.required.iterator();
  -        while (required.hasNext())
  -            results.add(required.next());
  -
  -        // Trace our parentage tree and add declared extensions when possible
  -        ClassLoader loader = this;
  -        while (true) {
  -            loader = loader.getParent();
  -            if (loader == null)
  -                break;
  -            if (!(loader instanceof WebappClassLoader))
  -                continue;
  -            Extension extensions[] =
  -                ((WebappClassLoader) loader).findRequired();
  -            for (int i = 0; i < extensions.length; i++)
  -                results.add(extensions[i]);
  -        }
  -
  -        // Return the results as an array
  -        Extension extensions[] = new Extension[results.size()];
  -        return ((Extension[]) results.toArray(extensions));
  -
  -    }
  -
  -
  -    /**
        * Have one or more classes or resources been modified so that a reload
        * is appropriate?
        */
  @@ -878,13 +776,6 @@
       public String toString() {
   
           StringBuffer sb = new StringBuffer("WebappClassLoader\r\n");
  -        sb.append("  available:\r\n");
  -        Iterator available = this.available.iterator();
  -        while (available.hasNext()) {
  -            sb.append("    ");
  -            sb.append(available.next().toString());
  -            sb.append("\r\n");
  -        }
           sb.append("  delegate: ");
           sb.append(delegate);
           sb.append("\r\n");
  @@ -894,13 +785,6 @@
               sb.append(repositories[i]);
               sb.append("\r\n");
           }
  -        sb.append("  required:\r\n");
  -        Iterator required = this.required.iterator();
  -        while (required.hasNext()) {
  -            sb.append("    ");
  -            sb.append(required.next().toString());
  -            sb.append("\r\n");
  -        }
           if (this.parent != null) {
               sb.append("----------> Parent Classloader:\r\n");
               sb.append(this.parent.toString());
  @@ -1566,7 +1450,6 @@
           paths = new String[0];
           hasExternalRepositories = false;
   
  -        required.clear();
           permissionList.clear();
           loaderPC.clear();
   
  
  
  
  1.3       +4 -47     jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/loader/WebappLoader.java
  
  Index: WebappLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/loader/WebappLoader.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- WebappLoader.java	22 Aug 2002 17:02:12 -0000	1.2
  +++ WebappLoader.java	24 Aug 2002 02:27:27 -0000	1.3
  @@ -646,9 +646,6 @@
               throw new LifecycleException("start: ", t);
           }
   
  -        // Validate that all required packages are actually available
  -        validatePackages();
  -
           // Start our background thread if we are reloadable
           if (reloadable) {
               log.info(sm.getString("webappLoader.reloading"));
  @@ -1282,46 +1279,6 @@
           }
   
           thread = null;
  -
  -    }
  -
  -
  -    /**
  -     * Validate that the required optional packages for this application
  -     * are actually present.
  -     *
  -     * @exception LifecycleException if a required package is not available
  -     */
  -    private void validatePackages() throws LifecycleException {
  -
  -        ClassLoader classLoader = getClassLoader();
  -        if (classLoader instanceof WebappClassLoader) {
  -
  -            Extension available[] =
  -                ((WebappClassLoader) classLoader).findAvailable();
  -            Extension required[] =
  -                ((WebappClassLoader) classLoader).findRequired();
  -            if (log.isDebugEnabled())
  -                log.debug("Optional Packages:  available=" +
  -                    available.length + ", required=" +
  -                    required.length);
  -
  -            for (int i = 0; i < required.length; i++) {
  -                if (log.isDebugEnabled())
  -                    log.debug("Checking for required package " + required[i]);
  -                boolean found = false;
  -                for (int j = 0; j < available.length; j++) {
  -                    if (available[j].isCompatibleWith(required[i])) {
  -                        found = true;
  -                        break;
  -                    }
  -                }
  -                if (!found)
  -                    throw new LifecycleException
  -                        ("Missing optional package " + required[i]);
  -            }
  -
  -        }
   
       }
   
  
  
  
  1.2       +4 -5      jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/Bootstrap.java
  
  Index: Bootstrap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/Bootstrap.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Bootstrap.java	18 Jul 2002 16:47:47 -0000	1.1
  +++ Bootstrap.java	24 Aug 2002 02:27:27 -0000	1.2
  @@ -71,7 +71,6 @@
   import java.net.MalformedURLException;
   import java.net.URL;
   import java.util.ArrayList;
  -import org.apache.catalina.loader.Extension;
   import org.apache.catalina.loader.StandardClassLoader;
   
   
  
  
  
  1.2       +4 -5      jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/BootstrapService.java
  
  Index: BootstrapService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/BootstrapService.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BootstrapService.java	18 Jul 2002 16:47:48 -0000	1.1
  +++ BootstrapService.java	24 Aug 2002 02:27:27 -0000	1.2
  @@ -73,7 +73,6 @@
   import java.util.ArrayList;
   import org.apache.commons.daemon.Daemon;
   import org.apache.commons.daemon.DaemonContext;
  -import org.apache.catalina.loader.Extension;
   import org.apache.catalina.loader.StandardClassLoader;
   
   
  
  
  
  1.11      +4 -5      jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/ContextConfig.java
  
  Index: ContextConfig.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/ContextConfig.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- ContextConfig.java	21 Aug 2002 03:24:37 -0000	1.10
  +++ ContextConfig.java	24 Aug 2002 02:27:27 -0000	1.11
  @@ -122,7 +122,6 @@
   import org.apache.catalina.deploy.FilterMap;
   import org.apache.catalina.deploy.LoginConfig;
   import org.apache.catalina.deploy.SecurityConstraint;
  -import org.apache.catalina.loader.Extension;
   import org.apache.catalina.util.StringManager;
   import org.apache.catalina.util.SchemaResolver;
   import org.apache.catalina.valves.ValveBase;
  
  
  
  1.2       +4 -5      jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/Tool.java
  
  Index: Tool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/Tool.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Tool.java	18 Jul 2002 16:47:50 -0000	1.1
  +++ Tool.java	24 Aug 2002 02:27:27 -0000	1.2
  @@ -71,7 +71,6 @@
   import java.net.MalformedURLException;
   import java.net.URL;
   import java.util.ArrayList;
  -import org.apache.catalina.loader.Extension;
   import org.apache.catalina.loader.StandardClassLoader;
   
   
  
  
  
  1.7       +14 -4     jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContext.java
  
  Index: StandardContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContext.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- StandardContext.java	23 Aug 2002 14:54:48 -0000	1.6
  +++ StandardContext.java	24 Aug 2002 02:27:27 -0000	1.7
  @@ -142,6 +142,7 @@
   import org.apache.catalina.loader.WebappLoader;
   import org.apache.catalina.session.StandardManager;
   import org.apache.catalina.util.CharsetMapper;
  +import org.apache.catalina.util.ExtensionValidator;
   import org.apache.catalina.util.RequestUtil;
   
   
  @@ -3561,6 +3562,15 @@
   
           // Post work directory
           postWorkDirectory();
  +
  +        // Validate required extensions
  +        ExtensionValidator validator = ExtensionValidator.getInstance();
  +        boolean dependencyCheck = validator.validateApplication(
  +                                  getResources(), this);
  +        if (!dependencyCheck) {
  +            // do not make application available if depency check fails
  +            ok = false;
  +        }
   
           // Reading the "catalina.useNaming" environment variable
           String useNamingProperty = System.getProperty("catalina.useNaming");
  
  
  
  1.2       +4 -0      jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/LocalStrings.properties,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- LocalStrings.properties	18 Jul 2002 16:47:46 -0000	1.1
  +++ LocalStrings.properties	24 Aug 2002 02:27:28 -0000	1.2
  @@ -2,4 +2,8 @@
   resourceSet.locked=No modifications are allowed to a locked ResourceSet
   hexUtil.bad=Bad hexadecimal digit
   hexUtil.odd=Odd number of hexadecimal digits
  +#Default Messages Utilized by the ExtensionValidator
  +extensionValidator.web-application-manifest=Web Application Manifest
  +extensionValidator.extension-not-found-error=ExtensionValidator[{0}][{1}]: Required extension "{2}" not found.
  +extensionValidator.extension-validation-error=ExtensionValidator[{0}]: Failure to find {1} required extension(s).
   
  
  
  
  1.1                  jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/Extension.java
  
  Index: Extension.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/Extension.java,v 1.1 2002/08/24 02:27:28 horwat Exp $
   * $Revision: 1.1 $
   * $Date: 2002/08/24 02:27:28 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  
  package org.apache.catalina.util;
  
  
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.StringTokenizer;
  import java.util.jar.Attributes;
  import java.util.jar.Manifest;
  
  
  /**
   * Utility class that represents either an available "Optional Package"
   * (formerly known as "Standard Extension") as described in the manifest
   * of a JAR file, or the requirement for such an optional package.  It is
   * used to support the requirements of the Servlet Specification, version
   * 2.3, related to providing shared extensions to all webapps.
   * <p>
   * In addition, static utility methods are available to scan a manifest
   * and return an array of either available or required optional modules
   * documented in that manifest.
   * <p>
   * For more information about optional packages, see the document
   * <em>Optional Package Versioning</em> in the documentation bundle for your
   * Java2 Standard Edition package, in file
   * <code>guide/extensions/versioning.html</code>.
   *
   * @author Craig McClanahan
   * @author Justyna Horwat
   * @author Greg Murray
   * @version $Revision: 1.1 $ $Date: 2002/08/24 02:27:28 $
   */
  
  public final class Extension {
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * The name of the optional package being made available, or required.
       */
      private String extensionName = null;
      
  
      public String getExtensionName() {
          return (this.extensionName);
      }
  
      public void setExtensionName(String extensionName) {
          this.extensionName = extensionName;
      }
  
      /**
       * UniqueId created by combining the extension name and implementation
       * version. 
       */
      public String getUniqueId() {
          return this.extensionName + this.implementationVersion;
      }
  
      /**
       * The URL from which the most recent version of this optional package
       * can be obtained if it is not already installed.
       */
      private String implementationURL = null;
  
      public String getImplementationURL() {
          return (this.implementationURL);
      }
  
      public void setImplementationURL(String implementationURL) {
          this.implementationURL = implementationURL;
      }
  
  
      /**
       * The name of the company or organization that produced this
       * implementation of this optional package.
       */
      private String implementationVendor = null;
  
      public String getImplementationVendor() {
          return (this.implementationVendor);
      }
  
      public void setImplementationVendor(String implementationVendor) {
          this.implementationVendor = implementationVendor;
      }
  
  
      /**
       * The unique identifier of the company that produced the optional
       * package contained in this JAR file.
       */
      private String implementationVendorId = null;
  
      public String getImplementationVendorId() {
          return (this.implementationVendorId);
      }
  
      public void setImplementationVendorId(String implementationVendorId) {
          this.implementationVendorId = implementationVendorId;
      }
  
  
      /**
       * The version number (dotted decimal notation) for this implementation
       * of the optional package.
       */
      private String implementationVersion = null;
  
      public String getImplementationVersion() {
          return (this.implementationVersion);
      }
  
      public void setImplementationVersion(String implementationVersion) {
          this.implementationVersion = implementationVersion;
      }
  
  
      /**
       * The name of the company or organization that originated the
       * specification to which this optional package conforms.
       */
      private String specificationVendor = null;
  
      public String getSpecificationVendor() {
          return (this.specificationVendor);
      }
  
      public void setSpecificationVendor(String specificationVendor) {
          this.specificationVendor = specificationVendor;
      }
  
  
      /**
       * The version number (dotted decimal notation) of the specification
       * to which this optional package conforms.
       */
      private String specificationVersion = null;
  
      public String getSpecificationVersion() {
          return (this.specificationVersion);
      }
  
      public void setSpecificationVersion(String specificationVersion) {
          this.specificationVersion = specificationVersion;
      }
  
  
      /**
       * fulfilled is true if all the required extension dependencies have been
       * satisfied
       */
      private boolean fulfilled = false;
  
      public void setFulfilled(boolean fulfilled) {
          this.fulfilled = fulfilled;
      }
      
      public boolean isFulfilled() {
          return fulfilled;
      }
  
      // --------------------------------------------------------- Public Methods
  
      /**
       * Return <code>true</code> if the specified <code>Extension</code>
       * (which represents an optional package required by this application)
       * is satisfied by this <code>Extension</code> (which represents an
       * optional package that is already installed.  Otherwise, return
       * <code>false</code>.
       *
       * @param required Extension of the required optional package
       */
      public boolean isCompatibleWith(Extension required) {
  
          // Extension Name must match
          if (extensionName == null)
              return (false);
          if (!extensionName.equals(required.getExtensionName()))
              return (false);
  
          // Available specification version must be >= required
          if (!isNewer(specificationVersion, required.getSpecificationVersion()))
              return (false);
  
          // Implementation Vendor ID must match
          if (implementationVendorId == null)
              return (false);
          if (!implementationVendorId.equals(required.getImplementationVendorId()))
              return (false);
  
          // Implementation version must be >= required
          if (!isNewer(implementationVersion, required.getImplementationVersion()))
              return (false);
  
          // This available optional package satisfies the requirements
          return (true);
  
      }
  
      /**
       * Return a String representation of this object.
       */
      public String toString() {
  
          StringBuffer sb = new StringBuffer("Extension[");
          sb.append(extensionName);
          if (implementationURL != null) {
              sb.append(", implementationURL=");
              sb.append(implementationURL);
          }
          if (implementationVendor != null) {
              sb.append(", implementationVendor=");
              sb.append(implementationVendor);
          }
          if (implementationVendorId != null) {
              sb.append(", implementationVendorId=");
              sb.append(implementationVendorId);
          }
          if (implementationVersion != null) {
              sb.append(", implementationVersion=");
              sb.append(implementationVersion);
          }
          if (specificationVendor != null) {
              sb.append(", specificationVendor=");
              sb.append(specificationVendor);
          }
          if (specificationVersion != null) {
              sb.append(", specificationVersion=");
              sb.append(specificationVersion);
          }
          sb.append("]");
          return (sb.toString());
  
      }
  
  
      // -------------------------------------------------------- Private Methods
  
  
  
      /**
       * Return <code>true</code> if the first version number is greater than
       * or equal to the second; otherwise return <code>false</code>.
       *
       * @param first First version number (dotted decimal)
       * @param second Second version number (dotted decimal)
       *
       * @exception NumberFormatException on a malformed version number
       */
      private boolean isNewer(String first, String second)
          throws NumberFormatException {
  
          if ((first == null) || (second == null))
              return (false);
          if (first.equals(second))
              return (true);
  
          StringTokenizer fTok = new StringTokenizer(first, ".", true);
          StringTokenizer sTok = new StringTokenizer(second, ".", true);
          int fVersion = 0;
          int sVersion = 0;
          while (fTok.hasMoreTokens() || sTok.hasMoreTokens()) {
              if (fTok.hasMoreTokens())
                  fVersion = Integer.parseInt(fTok.nextToken());
              else
                  fVersion = 0;
              if (sTok.hasMoreTokens())
                  sVersion = Integer.parseInt(sTok.nextToken());
              else
                  sVersion = 0;
              if (fVersion < sVersion)
                  return (false);
              else if (fVersion > sVersion)
                  return (true);
              if (fTok.hasMoreTokens())   // Swallow the periods
                  fTok.nextToken();
              if (sTok.hasMoreTokens())
                  sTok.nextToken();
          }
  
          return (true);  // Exact match
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/ExtensionValidator.java
  
  Index: ExtensionValidator.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/ExtensionValidator.java,v 1.1 2002/08/24 02:27:28 horwat Exp $
   * $Revision: 1.1 $
   * $Date: 2002/08/24 02:27:28 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.catalina.util;
  
  import java.util.StringTokenizer;
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.HashMap;
  import java.util.ResourceBundle;
  import java.text.MessageFormat;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.InputStream;
  import java.util.jar.JarInputStream;
  import java.util.jar.Manifest;
  import java.util.jar.Attributes;
  
  import org.apache.catalina.core.StandardContext;
  import org.apache.catalina.Logger;
  import org.apache.naming.resources.BaseDirContext;
  import org.apache.naming.resources.Resource;
  
  // JNDI Imports
  import javax.naming.NamingEnumeration;
  import javax.naming.directory.DirContext;
  import javax.naming.Binding;
  
  
  /**
   *  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.1 $ $Date: 2002/08/24 02:27:28 $
   *
   */
  public final class ExtensionValidator {
  
      // ------------------------------------------------------------- Properties
  
      
      private static ExtensionValidator validator = null;
      private static HashMap containerAvailableExtensions = null;
      private static ArrayList containerManifestResources = null;
      private static ResourceBundle messages = null;
      
      /*
       *  Access to this class can only be made through the factory method
       *  getInstance()
       *
       *  This private constructor loads the container level extensions that are
       *  available to all web applications. This method scans all extension 
       *  directories available to via the "java.ext.dirs" System property. 
       *
       *  The System Class-Path is also scanned for jar files that may contain 
       *  available extensions. The system extensions are loaded only the 
       *  first time an instance of the ExtensionValidator is created.
       */
      private ExtensionValidator() {
         
          // load the container level extensions
          containerManifestResources = new ArrayList();
          // check for container level optional packages
          String systemClasspath = System.getProperties().
                                   getProperty("java.class.path");
  
          StringTokenizer strTok = new StringTokenizer(systemClasspath, 
                                                       File.pathSeparator);
          ArrayList items = new ArrayList();
          // build a list of jar files in the classpath
          while (strTok.hasMoreTokens()) {
              String classpathItem = strTok.nextToken();
              if (classpathItem.toLowerCase().endsWith(".jar")) {
                  items.add(classpathItem);
              }
          }
          // get the files in the extensions directory
          String extensionsDir = System.getProperties().
                                  getProperty("java.ext.dirs");
          StringTokenizer extensionsTok = null;
          if (extensionsDir != null) {
              extensionsTok = new StringTokenizer(extensionsDir, 
                                                   File.pathSeparator);
          }
          while ((extensionsTok != null) && extensionsTok.hasMoreTokens()) {
              String targetDir = extensionsTok.nextToken();
              // check if the directory exits
              if (((new File(targetDir)).exists()) && 
                  (new File(targetDir)).isDirectory()) {
                  // get a file list
                  File[] files = (new File(targetDir)).listFiles();
                  // see if any file is a jar file
                  for (int loop = 0; loop < files.length; loop++) {
                      if (files[loop].getName().toLowerCase().endsWith(".jar")) {
                          items.add(files[loop].getAbsolutePath());
                          Manifest manifest = getManifest(files[loop]);
                          if (manifest != null)  {
                              ManifestResource mre = new ManifestResource
                                  (files[loop].getAbsolutePath(), manifest, 
                                   ManifestResource.SYSTEM);
                              containerManifestResources.add(mre);
                          }
                      }
                  }
              }
          }
      }
  
      // --------------------------------------------------------- Public Methods
          
      /**
       *  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
       *
       */
      public static synchronized boolean validateApplication(
                                             DirContext dirContext, 
                                             StandardContext context) {
          String appName = context.getPath();
          Logger logger = context.getLogger();
          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 Mainfest for the Web Applicaiton
          try {
              NamingEnumeration  wne = null;
              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 inputStream = resource.streamContent();
                  Manifest manifest = new Manifest(inputStream);
                  ManifestResource mre = new ManifestResource
                      (getMessage("extensionValidator.web-application-manifest", 
                       logger), manifest, ManifestResource.WAR);
                  appManifestResources.add(mre);
              } 
          } catch (javax.naming.NamingException nex) {
              // Application does not contain a MANIFEST.MF file
          }  catch (java.io.IOException iox) {
              // Unable to load MANIFEST.MF file
          }
          // Locate the Manifests for all necessary Jar Files in the Application
          ArrayList jarEntries = new ArrayList();
          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")) {
                          Resource resource = (Resource)dirContext.lookup
                              ("/WEB-INF/lib/" + binding.getName());
                          try {
                              InputStream in = resource.streamContent();
                              JarInputStream jin = new JarInputStream(in);
                              Manifest jmanifest = jin.getManifest();
                              ManifestResource mre = new ManifestResource
                                  (binding.getName(), jmanifest, 
                                  ManifestResource.APPLICATION);
                              appManifestResources.add(mre);
                          } catch (java.io.IOException iox) {
                              // do not do anything... go to the next entry
                          }
                      }
                  }
          } catch (javax.naming.NamingException nex) {
              // Jump out of the check for this application because it 
              // has no resources
          }
          return validateManifestResources(appName,appManifestResources, logger);
      }
      
      /**
       *  Return an instance of the ExtensionValidator. 
       *  The ExtensionValidator is a singleton.
       */
      public static ExtensionValidator getInstance() {
          if (validator == null) {
            validator = new ExtensionValidator();
          }
          return validator;
      }
      
      // -------------------------------------------------------- Private Methods
  
      /**
       * Validates a <code>ArrayList</code> of <code>ManifestResource</code> 
       * objects. This method requires an application name (which is the 
       * context root of the application at runtime).  
       *
       * A <code>Logger</code> is required for the output of error messages. 
       * <code>false</false> is returned if the extension depeendencies
       * represented by any given <code>ManifestResource</code> objects 
       * is not met.
       *
       * 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 
       *                  to be validated.
       * @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;
          
          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++;
                      }
                  }
              }
          }
          if (!passes) {
              String[] args = {appName,failureCount + "" };
              logMessage("extensionValidator.extension-validation-error", 
                  args, logger);
          }
          return passes;
      }
      
     /* 
      * Build this list of available extensions so that we do not have to 
      * re-build this list every time we iterate through the list of required 
      * extensions. All available extensions in all of the 
      * <code>MainfestResource</code> objects will be added to a 
      * <code>HashMap</code>which is returned on the first dependency list
      * processing pass. 
      *
      * The key is the name + implementation version.
      *
      * 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
      *
      * @return HashMap Map of available extensions
      */
      private static HashMap buildAvailableExtensionsMap(ArrayList resources) {
          HashMap availableMap = new HashMap();
          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);
                      }
                  }
              }
          }
          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 {
              FileInputStream fis = new FileInputStream(file);
              JarInputStream jin = new JarInputStream(fis);
              return jin.getManifest();
          } catch (java.io.IOException iox) {
                 return null;
          }
      }
      
      /**
       *  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);
          if (args != null) {
              logger.log(MessageFormat.format(message, args));
          } else {
              logger.log(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 
       *               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) {
              try {
                  messages = ResourceBundle.getBundle(
                      "org.apache.catalina.util.LocalStrings");
              } catch (java.util.MissingResourceException mrx) {
                  logger.log(
                      "Unable to load localized resources for ExtensionValidator");
                  // jump out of method
                  return null;
              }
          }
          String message = null;
          try {
              return  messages.getString(messageId);
          } catch (java.util.MissingResourceException mrx) {
              logger.log("Unable to load resources for ExtensionValidator");
              return null;
          }
      }
  }
  
  
  
  
  
  1.1                  jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/ManifestResource.java
  
  Index: ManifestResource.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/ManifestResource.java,v 1.1 2002/08/24 02:27:28 horwat Exp $
   * $Revision: 1.1 $
   * $Date: 2002/08/24 02:27:28 $
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  package org.apache.catalina.util;
  
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.jar.Manifest;
  import java.util.jar.Attributes;
  import java.util.ArrayList;
  
  /**
   *  Representation of a Manifest file and its available extenstions and
   *  required extensions
   *  
   * @author Greg Murray
   * @author Justyna Horwat
   * @version $Revision: 1.1 $ $Date: 2002/08/24 02:27:28 $
   * 
   */
  public class ManifestResource {
      
      // ------------------------------------------------------------- Properties
  
      // These are the resource types for determining effect error messages
      public static final int SYSTEM = 1;
      public static final int WAR = 2;
      public static final int APPLICATION = 3;
      
      private HashMap availableExtensions = null;
      private ArrayList requiredExtensions = null;
      
      private String resourceName = null;
      private int resourceType = -1;
          
      public ManifestResource(String resourceName, Manifest manifest, 
                              int resourceType) {
          this.resourceName = resourceName;
          this.resourceType = resourceType;
          processManifest(manifest);
      }
      
      /**
       * return the name of the resource
       *
       * @return Strig the name of the resource
       */
      public String getResourceName() {
          return resourceName;
      }
  
      /**
       * Return the map of available extensions
       *
       * @return HashMap map of available extensions
       */
      public HashMap getAvailableExtensions() {
          return availableExtensions;
      }
      
      /**
       * Return the list of required extensions
       *
       * @return ArrayList list of required extensions
       */
      public ArrayList getRequiredExtensions() {
          return requiredExtensions;   
      }
      
      // --------------------------------------------------------- Public Methods
  
      /**
       * Return the number of available extensions
       *
       * @return int the number of available extensions
       */
      public int getAvailableExtensionCount() {
          if (availableExtensions == null) return 0;
          return availableExtensions.size();
      }
      
      /**
       * Return the number of required extensions
       *
       * @return int the number of required extensions
       */
      public int getRequiredExtensionCount() {
          if (requiredExtensions == null) return 0;
          return requiredExtensions.size();
      }
      
      /**
       * Convienience method to check if this <code>ManifestResource</code>
       * has an requires extensions.
       *
       * @return true if required extensions are present
       */
      public boolean requiresExtensions() {
          if (getRequiredExtensionCount() > 0) return true;
          else return false;
      }
      
      /**
       * Convienience method to check if this <code>ManifestResource</code>
       * has an extension available.
       *
       * @param key extension identifier
       *
       * @return true if extension available
       */
      public boolean containsExtension(String key) {
          return (availableExtensions.containsKey(key));
      }
      
      /**
       * 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
       */
      public boolean isFulfilled() {
          if ((requiredExtensions == null) ||
          requiredExtensions.size() ==0) {
              return false;
          }
          Iterator it = requiredExtensions.iterator();
          while (it.hasNext()) {
              Extension ext = (Extension)it.next();
              if (!ext.isFulfilled()) return false;            
          }
          return true;
      }
      
      public String toString() {
  
          StringBuffer sb = new StringBuffer("ManifestResource[");
          sb.append(resourceName);
  
          sb.append(", isFulfilled=");
          sb.append(isFulfilled() +"");
          sb.append(", requiredExtensionCount =");
          sb.append(getRequiredExtensionCount());
          sb.append(", availableExtensionCount=");
          sb.append(getAvailableExtensionCount());
          switch (resourceType) {
              case SYSTEM : sb.append(", resourceType=SYSTEM"); break;
              case WAR : sb.append(", resourceType=WAR"); break;
              case APPLICATION : sb.append(", resourceType=APPLICATION"); break;
          }
          sb.append("]");
          return (sb.toString());
      }
  
  
      // -------------------------------------------------------- Private Methods
  
      private void processManifest(Manifest manifest) {
          availableExtensions = getAvailableExtensions(manifest);
          requiredExtensions = getRequiredExtensions(manifest);
      }
      
      /**
       * 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.
       *
       * @param manifest Manifest to be parsed
       *
       * @return ArrayList list of required 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;
          names += " ";
  
          while (true) {
  
              int space = names.indexOf(' ');
              if (space < 0)
                  break;
              String name = names.substring(0, space).trim();
              names = names.substring(space + 1);
  
              String value =
                  attributes.getValue(name + "-Extension-Name");
              if (value == null)
                  continue;
              Extension extension = new Extension();
              extension.setExtensionName(value);
              extension.setImplementationURL
                  (attributes.getValue(name + "-Implementation-URL"));
              extension.setImplementationVendorId
                  (attributes.getValue(name + "-Implementation-Vendor-Id"));
              String version = attributes.getValue(name + "-Implementation-Version");
              extension.setImplementationVersion(version);
              extension.setSpecificationVersion
                  (attributes.getValue(name + "-Specification-Version"));
              extensionList.add(extension);
          }
          return extensionList;
      }
      
      /**
       * 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.
       *
       * @param manifest Manifest to be parsed
       *
       * @return HashMap Map of available 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);
          Extension extension = new Extension();
          extension.setExtensionName(name);
          extension.setImplementationURL
              (attributes.getValue("Implementation-URL"));
          extension.setImplementationVendor
              (attributes.getValue("Implementation-Vendor"));
          extension.setImplementationVendorId
              (attributes.getValue("Implementation-Vendor-Id"));
          String version = attributes.getValue("Implementation-Version");
          extension.setImplementationVersion(version);
          extension.setSpecificationVersion
              (attributes.getValue("Specification-Version"));
          // 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:   <mailto:tomcat-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:tomcat-dev-help@jakarta.apache.org>


Mime
View raw message