You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cactus-dev@jakarta.apache.org by cm...@apache.org on 2003/05/14 12:43:37 UTC

cvs commit: jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment WebXmlIo.java WebXmlTag.java WebXmlVersion.java WebXmlMerger.java WebXml.java

cmlenz      2003/05/14 03:43:36

  Added:       integration/ant/src/java/org/apache/cactus/integration/ant/deployment
                        WebXmlIo.java WebXmlTag.java WebXmlVersion.java
                        WebXmlMerger.java WebXml.java
  Log:
  Multipart commit: Move classes from webxml into deployment package
  
  Revision  Changes    Path
  1.1                  jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/WebXmlIo.java
  
  Index: WebXmlIo.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 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", "Cactus" 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.cactus.integration.ant.deployment;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.util.jar.JarInputStream;
  
  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  import javax.xml.parsers.ParserConfigurationException;
  
  import org.apache.cactus.integration.ant.util.ResourceUtils;
  import org.apache.xml.serialize.OutputFormat;
  import org.apache.xml.serialize.XMLSerializer;
  import org.w3c.dom.Document;
  import org.w3c.dom.DocumentType;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  
  /**
   * Provides convenience methods for reading and writing web deployment
   * descriptors.
   *
   * @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
   *
   * @since Cactus 1.5
   * @version $Id: WebXmlIo.java,v 1.1 2003/05/14 10:43:36 cmlenz Exp $
   */
  public class WebXmlIo
  {
      
      // Inner Classes -----------------------------------------------------------
  
      /**
       * Implementation of the SAX EntityResolver interface that looks up the
       * web-app DTDs from the JAR. This resolver can also wrap around an existing
       * entity resolver, delegating to it when it couldn't resolve an entity
       * itself.
       */
      private static class WebXmlEntityResolver implements EntityResolver
      {
  
          /**
           * @see org.xml.sax.EntityResolver#resolveEntity
           */
          public InputSource resolveEntity(String thePublicId, String theSystemId)
              throws SAXException, IOException
          {
              WebXmlVersion version = WebXmlVersion.valueOf(thePublicId);
              if (version != null)
              {
                  String fileName = version.getSystemId().substring(
                      version.getSystemId().lastIndexOf('/'));
                  InputStream in = this.getClass().getResourceAsStream(
                      "/org/apache/cactus/integration/ant/webxml/resources"
                      + fileName);
                  if (in != null)
                  {
                      return new InputSource(in);
                  }
              }
              System.err.println("Resource for public ID " + thePublicId
                  + " not found");
              return null;
          }
  
      }
  
      // Public Methods ----------------------------------------------------------
  
      /**
       * Creates a new empty deployment descriptor.
       * 
       * @param theVersion The version of the descriptor to create
       * @return The new descriptor
       * @throws ParserConfigurationException If the XML parser was not correctly
       *          configured
       */
      public static WebXml newWebXml(WebXmlVersion theVersion)
          throws ParserConfigurationException
      {
          DocumentBuilderFactory factory =
              DocumentBuilderFactory.newInstance();
          factory.setValidating(false);
          factory.setNamespaceAware(false);
          DocumentBuilder builder = factory.newDocumentBuilder();
          DocumentType docType = null;
          if (theVersion != null)
          {
              docType =
                  builder.getDOMImplementation().createDocumentType("web-app",
                      theVersion.getPublicId(), theVersion.getSystemId());
          }
          Document doc = builder.getDOMImplementation().createDocument(
              "", "web-app", docType);
          return new WebXml(doc);
      }
  
      /**
       * Parses the deployment descriptor of a web-application archive (WAR).
       * 
       * @param theWar The web-app archive
       * @param theEntityResolver A SAX entity resolver, or <code>null</code> to
       *        use the default
       * @return The parsed descriptor, or <code>null</code> if no descriptor was
       *         found in the WAR
       * @throws SAXException If the descriptor could not be parsed
       * @throws ParserConfigurationException If the XML parser was not correctly
       *          configured
       * @throws IOException If an I/O error occurs
       */
      public static WebXml parseWebXmlFromWar(JarInputStream theWar,
          EntityResolver theEntityResolver)
          throws SAXException, ParserConfigurationException, IOException
      {
          InputStream in = null;
          try
          {
              in = ResourceUtils.getResource(theWar, "WEB-INF/web.xml");
              if (in == null)
              {
                  return null;
              }
              else
              {
                  return parseWebXml(in, theEntityResolver);
              }
          }
          finally
          {
              if (in != null)
              {
                  try
                  {
                      in.close();
                  }
                  catch (IOException ioe)
                  {
                      // we'll pass on the original IO error, so ignore this one
                  }
              }
          }
      }
      
      /**
       * Parses a deployment descriptor stored in a regular file.
       * 
       * @param theFile The file to parse
       * @param theEntityResolver A SAX entity resolver, or <code>null</code> to
       *        use the default
       * @return The parsed descriptor
       * @throws SAXException If the file could not be parsed
       * @throws ParserConfigurationException If the XML parser was not correctly
       *          configured
       * @throws IOException If an I/O error occurs
       */
      public static WebXml parseWebXmlFromFile(File theFile,
          EntityResolver theEntityResolver)
          throws SAXException, ParserConfigurationException, IOException
      {
          InputStream in = null;
          try
          {
              in = new FileInputStream(theFile);
              return parseWebXml(in, theEntityResolver);
          }
          finally
          {
              if (in != null)
              {
                  try
                  {
                      in.close();
                  }
                  catch (IOException ioe)
                  {
                      // we'll pass on the original IO error, so ignore this one
                  }
              }
          }
      }
      
      /**
       * Parses a deployment descriptor provided as input stream.
       * 
       * @param theInput The input stream
       * @param theEntityResolver A SAX entity resolver, or <code>null</code> to
       *        use the default
       * @return The parsed descriptor
       * @throws SAXException If the input could not be parsed
       * @throws ParserConfigurationException If the XML parser was not correctly
       *          configured
       * @throws IOException If an I/O error occurs
       */
      public static WebXml parseWebXml(InputStream theInput,
          EntityResolver theEntityResolver)
          throws SAXException, ParserConfigurationException, IOException
      {
          DocumentBuilderFactory factory =
              DocumentBuilderFactory.newInstance();
          factory.setValidating(false);
          factory.setNamespaceAware(false);
          DocumentBuilder builder = factory.newDocumentBuilder();
          if (theEntityResolver != null)
          {
              builder.setEntityResolver(theEntityResolver);
          }
          else
          {
              builder.setEntityResolver(new WebXmlEntityResolver());
          }
          return new WebXml(builder.parse(theInput));
      }
  
      /**
       * Writes the specified document to a file.
       * 
       * @param theWebXml The descriptor to serialize
       * @param theFile The file to write to
       * @throws IOException If an I/O error occurs
       */
      public static void writeWebXml(WebXml theWebXml, File theFile)
          throws IOException
      {
          writeWebXml(theWebXml, theFile, null, false);
      }
  
      /**
       * Writes the specified document to a file.
       * 
       * @param theWebXml The descriptor to serialize
       * @param theFile The file to write to
       * @param theEncoding The character encoding to use
       * @throws IOException If an I/O error occurs
       */
      public static void writeWebXml(WebXml theWebXml, File theFile,
          String theEncoding)
          throws IOException
      {
          writeWebXml(theWebXml, theFile, theEncoding, false);
      }
  
      /**
       * Writes the specified document to a file.
       * 
       * @param theWebXml The descriptor to serialize
       * @param theFile The file to write to
       * @param theEncoding The character encoding to use
       * @param isIndent Whether the written XML should be indented
       * @throws IOException If an I/O error occurs
       */
      public static void writeWebXml(WebXml theWebXml, File theFile,
          String theEncoding, boolean isIndent)
          throws IOException
      {
          OutputStream out = null;
          try
          {
              out = new FileOutputStream(theFile);
              writeWebXml(theWebXml, out, theEncoding, isIndent);
          }
          finally
          {
              if (out != null)
              {
                  try
                  {
                      out.close();
                  }
                  catch (IOException ioe)
                  {
                      // we'll pass on the original IO error, so ignore this one
                  }
              }
          }
      }
  
      /**
       * Writes the specified document to an output stream.
       * 
       * @param theWebXml The descriptor to serialize
       * @param theOutput The output stream to write to
       * @param theEncoding The character encoding to use
       * @param isIndent Whether the written XML should be indented
       * @throws IOException If an I/O error occurs
       */
      public static void writeWebXml(WebXml theWebXml, OutputStream theOutput,
          String theEncoding, boolean isIndent)
          throws IOException
      {
          OutputFormat outputFormat =
              new OutputFormat(theWebXml.getDocument());
          if (theEncoding != null)
          {
              outputFormat.setEncoding(theEncoding);
          }
          outputFormat.setIndenting(isIndent);
          outputFormat.setPreserveSpace(false);
          XMLSerializer serializer = new XMLSerializer(theOutput, outputFormat);
          serializer.serialize(theWebXml.getDocument());
      }
  
  }
  
  
  
  1.1                  jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/WebXmlTag.java
  
  Index: WebXmlTag.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 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", "Cactus" 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.cactus.integration.ant.deployment;
  
  /**
   * Represents the various top-level tags in a web deployment descriptor as a 
   * typesafe enumeration.
   * 
   * @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
   *
   * @since Cactus 1.5
   * @version $Id: WebXmlTag.java,v 1.1 2003/05/14 10:43:36 cmlenz Exp $
   */
  public class WebXmlTag
  {
      
      // Public Constants --------------------------------------------------------
      
      /**
       * Element name 'icon'.
       */
      public static final WebXmlTag ICON =
          new WebXmlTag("icon", false);
      
      /**
       * Element name 'display-name'.
       */
      public static final WebXmlTag DISPLAY_NAME =
          new WebXmlTag("display-name", false);
      
      /**
       * Element name 'description'.
       */
      public static final WebXmlTag DESCRIPTION =
          new WebXmlTag("description", false);
      
      /**
       * Element name 'distributable'.
       */
      public static final WebXmlTag DISTRIBUTABLE =
          new WebXmlTag("distributable", false);
      
      /**
       * Element name 'context-param'.
       */
      public static final WebXmlTag CONTEXT_PARAM =
          new WebXmlTag("context-param");
      
      /**
       * Element name 'param-name'.
       */
      public static final WebXmlTag PARAM_NAME =
          new WebXmlTag("param-name");
      
      /**
       * Element name 'param-value'.
       */
      public static final WebXmlTag PARAM_VALUE =
          new WebXmlTag("param-value");
      
      /**
       * Element name 'filter'.
       */
      public static final WebXmlTag FILTER =
          new WebXmlTag("filter");
      
      /**
       * Element name 'filter-name'.
       */
      public static final WebXmlTag FILTER_NAME =
          new WebXmlTag("filter-name");
      
      /**
       * Element name 'filter-class'.
       */
      public static final WebXmlTag FILTER_CLASS =
          new WebXmlTag("filter-class");
      
      /**
       * Element name 'filter-mapping'.
       */
      public static final WebXmlTag FILTER_MAPPING =
          new WebXmlTag("filter-mapping");
      
      /**
       * Element name 'init-param'.
       */
      public static final WebXmlTag INIT_PARAM =
          new WebXmlTag("init-param");
      
      /**
       * Element name 'listener'.
       */
      public static final WebXmlTag LISTENER =
          new WebXmlTag("listener");
      
      /**
       * Element name 'servlet',
       */
      public static final WebXmlTag SERVLET =
          new WebXmlTag("servlet");
      
      /**
       * Element name 'servlet-name',
       */
      public static final WebXmlTag SERVLET_NAME =
          new WebXmlTag("servlet-name");
      
      /**
       * Element name 'jsp-file'.
       */
      public static final WebXmlTag JSP_FILE =
          new WebXmlTag("jsp-file");
      
      /**
       * Element name 'servlet-class'.
       */
      public static final WebXmlTag SERVLET_CLASS =
          new WebXmlTag("servlet-class");
      
      /**
       * Element name 'servlet-mapping',
       */
      public static final WebXmlTag SERVLET_MAPPING =
          new WebXmlTag("servlet-mapping");
      
      /**
       * Element name 'url-pattern',
       */
      public static final WebXmlTag URL_PATTERN =
          new WebXmlTag("url-pattern");
      
      /**
       * Element name 'session-config',
       */
      public static final WebXmlTag SESSION_CONFIG =
          new WebXmlTag("session-config", false);
      
      /**
       * Element name 'mime-mapping',
       */
      public static final WebXmlTag MIME_MAPPING =
          new WebXmlTag("mime-mapping");
      
      /**
       * Element name 'welcome-file-list',
       */
      public static final WebXmlTag WELCOME_FILE_LIST =
          new WebXmlTag("welcome-file-list", false);
      
      /**
       * Element name 'error-page',
       */
      public static final WebXmlTag ERROR_PAGE =
          new WebXmlTag("error-page");
      
      /**
       * Element name 'taglib',
       */
      public static final WebXmlTag TAGLIB =
          new WebXmlTag("taglib");
      
      /**
       * Element name 'resource-env-ref',
       */
      public static final WebXmlTag RESOURCE_ENV_REF =
          new WebXmlTag("resource-env-ref");
      
      /**
       * Element name 'resource-ref',
       */
      public static final WebXmlTag RESOURCE_REF =
          new WebXmlTag("resource-ref");
      
      /**
       * Element name 'security-constraint',
       */
      public static final WebXmlTag SECURITY_CONSTRAINT =
          new WebXmlTag("security-constraint");
      
      /**
       * Element name 'login-config',
       */
      public static final WebXmlTag LOGIN_CONFIG =
          new WebXmlTag("login-config", false);
      
      /**
       * Element name 'security-role',
       */
      public static final WebXmlTag SECURITY_ROLE =
          new WebXmlTag("security-role");
      
      /**
       * Element name 'env-entry',
       */
      public static final WebXmlTag ENV_ENTRY =
          new WebXmlTag("env-entry");
      
      /**
       * Element name 'ejb-ref',
       */
      public static final WebXmlTag EJB_REF =
          new WebXmlTag("ejb-ref");
      
      /**
       * Element name 'ejb-local-ref',
       */
      public static final WebXmlTag EJB_LOCAL_REF =
          new WebXmlTag("ejb-local-ref");
      
      // Instance Variables ------------------------------------------------------
      
      /**
       * The tag name,
       */
      private String tagName;
      
      /**
       * Whether multiple occurrences of the tag in the descriptor are allowed.
       */
      private boolean multipleAllowed;
      
      // Constructors ------------------------------------------------------------
      
      /**
       * Constructor.
       * 
       * @param theTagName The tag name of the element
       * @param isMultipleAllowed Whether the element may occur multiple times in
       *         the descriptor
       */
      private WebXmlTag(String theTagName, boolean isMultipleAllowed)
      {
          this.tagName = theTagName;
          this.multipleAllowed = isMultipleAllowed;
      }
  
      /**
       * Constructor.
       * 
       * @param theTagName The tag name of the element
       */
      private WebXmlTag(String theTagName)
      {
          this(theTagName, true);
      }
  
      // Public Methods ----------------------------------------------------------
      
      /**
       * @see java.lang.Object#toString
       */
      public final boolean equals(Object theOther)
      {
          return super.equals(theOther);
      }
      
      /**
       * @see java.lang.Object#hashCode
       */
      public final int hashCode()
      {
          return super.hashCode();
      }
      
      /**
       * Returns the tag name.
       * 
       * @return The tag name
       */
      public final String getTagName()
      {
          return this.tagName;
      }
      
      /**
       * Returns whether the tag may occur multiple times in the descriptor.
       * 
       * @return Whether multiple occurrences are allowed
       */
      public final boolean isMultipleAllowed()
      {
          return this.multipleAllowed;
      }
      
      /**
       * @see java.lang.Object#toString
       */
      public final String toString()
      {
          return getTagName();
      }
      
  }
  
  
  
  1.1                  jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/WebXmlVersion.java
  
  Index: WebXmlVersion.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 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", "Cactus" 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.cactus.integration.ant.deployment;
  
  import org.w3c.dom.DocumentType;
  
  /**
   * Enumerated type that represents the version of the web deployment descriptor.
   * 
   * @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
   *
   * @since Cactus 1.5
   * @version $Id: WebXmlVersion.java,v 1.1 2003/05/14 10:43:36 cmlenz Exp $
   */
  public class WebXmlVersion implements Comparable
  {
  
      // Public Constants --------------------------------------------------------
  
      /**
       * Instance for version 2.2.
       */
      public static final WebXmlVersion V2_2 = new WebXmlVersion("2.2",
          "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",
          "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd");
  
      /**
       * Instance for version 2.3.
       */
      public static final WebXmlVersion V2_3 = new WebXmlVersion("2.3",
          "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",
          "http://java.sun.com/dtd/web-app_2_3.dtd");
  
      // Instance Variables ------------------------------------------------------
  
      /**
       * The version as strnig,
       */
      private String version;
  
      /**
       * The public ID of the corresponding document type.
       */
      private String publicId;
  
      /**
       * The system ID of the corresponding document type.
       */
      public String systemId;
  
      // Constructors ------------------------------------------------------------
      
      /**
       * Constructor.
       * 
       * @param theVersion The version as string
       * @param thePublicId The public ID of the correspondig document type
       * @param theSystemId The system ID of the correspondig document type
       */
      private WebXmlVersion(String theVersion, String thePublicId,
          String theSystemId)
      {
          this.version = theVersion;
          this.publicId = thePublicId;
          this.systemId = theSystemId;
      }
  
      // Public Methods ----------------------------------------------------------
      
      /**
       * @see java.lang.Comparable#compareTo
       */
      public int compareTo(Object theOther)
      {
          if (theOther == this)
          {
              return 0;
          }
          WebXmlVersion otherVersion = (WebXmlVersion) theOther;
          if (otherVersion == V2_3)
          {
              return -1;
          }
          return 1;
      }
      
      /**
       * @see java.lang.Object#toString
       */
      public final boolean equals(Object theOther)
      {
          return super.equals(theOther);
      }
      
      /**
       * @see java.lang.Object#hashCode
       */
      public final int hashCode()
      {
          return super.hashCode();
      }
      
      /**
       * Returns the tag name.
       * 
       * @return The tag name
       */
      public final String getVersion()
      {
          return this.version;
      }
      
      /**
       * Returns the public ID of the document type corresponding to the 
       * descriptor version.
       * 
       * @return The public ID
       */
      public String getPublicId()
      {
          return publicId;
      }
  
      /**
       * Returns the system ID of the document type corresponding to the 
       * descriptor version.
       * 
       * @return The system ID
       */
      public String getSystemId()
      {
          return systemId;
      }
  
      /**
       * @see java.lang.Object#toString
       */
      public final String toString()
      {
          return getVersion();
      }
  
      /**
       * Returns the version corresponding to the given document type.
       * 
       * @param theDocType The document type
       * @return The version that matches the document type, or <code>null</code>
       *         if the doctype is not recognized
       * @throws NullPointerException If the document type is <code>null</code>
       */
      public static WebXmlVersion valueOf(DocumentType theDocType)
      {
          return valueOf(theDocType.getPublicId());
      }
  
      /**
       * Returns the version corresponding to the given public ID.
       * 
       * @param thePublicId The public ID
       * @return The version that matches the public ID, or <code>null</code>
       *         if the ID is not recognized
       */
      public static WebXmlVersion valueOf(String thePublicId)
      {
          if (V2_2.getPublicId().equals(thePublicId))
          {
              return WebXmlVersion.V2_2;
          }
          else if (V2_3.getPublicId().equals(thePublicId))
          {
              return WebXmlVersion.V2_3;
          }
          return null;
      }
  
  }
  
  
  
  1.1                  jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/WebXmlMerger.java
  
  Index: WebXmlMerger.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 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", "Cactus" 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.cactus.integration.ant.deployment;
  
  import java.util.Iterator;
  
  import org.apache.cactus.integration.ant.util.AntLog;
  import org.apache.commons.logging.Log;
  import org.w3c.dom.Element;
  
  /**
   * Helper class that can merge two web deployment descriptors.
   *
   * @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
   *
   * @since Cactus 1.5
   * @version $Id: WebXmlMerger.java,v 1.1 2003/05/14 10:43:36 cmlenz Exp $
   */
  public class WebXmlMerger
  {
  
      // Instance Variables ------------------------------------------------------
  
      /**
       * The original, authorative descriptor onto which the merges are performed.
       */
      private WebXml webXml;
      
      /**
       * The log to use.
       */
      private Log log = AntLog.NULL;
  
      // Constructors ------------------------------------------------------------
  
      /**
       * Constructor.
       * 
       * @param theWebXml The original descriptor
       */
      public WebXmlMerger(WebXml theWebXml)
      {
          this.webXml = theWebXml;
      }
  
      // Public Methods ----------------------------------------------------------
  
      /**
       * Merges the merge descriptor with the original descriptor. 
       * 
       * @param theMergeWebXml The descriptor to merge in
       */
      public final void merge(WebXml theMergeWebXml)
      {
          checkServletVersions(theMergeWebXml);
          if (this.webXml.getVersion() == WebXmlVersion.V2_3)
          {
              mergeFilters(theMergeWebXml);
          }
          mergeServlets(theMergeWebXml);
          mergeSecurityConstraints(theMergeWebXml);
          mergeLoginConfig(theMergeWebXml);
          mergeSecurityRoles(theMergeWebXml);
      }
  
      /**
       * Sets the log to which events should be written. This method must be 
       * called before any of the other methods, because the class will rely on 
       * being able to log.
       * 
       * @param theLog The log to use
       */
      public final void setLog(Log theLog)
      {
          this.log = theLog;
      }
  
      // Protected Methods -------------------------------------------------------
  
      /**
       * Checks the versions of the servlet API in each descriptor, and logs
       * a warning if a mismatch might result in the loss of definitions.
       * 
       * @param theWebXml The descriptor that will be merged with the original
       */
      protected final void checkServletVersions(WebXml theWebXml)
      {
          if ((this.webXml.getVersion() != null)
           && (this.webXml.getVersion().compareTo(theWebXml.getVersion()) < 0))
          {
              this.log.warn(
                  "Merging elements from a version " + theWebXml.getVersion()
                  + " descriptor into a version " + this.webXml.getVersion() 
                  + ", some elements may be skipped");
          }
      }
  
      /**
       * Merges the servlet definitions from the specified descriptor into the 
       * original descriptor.
       * 
       * @param theWebXml The descriptor that contains the filter definitions
       *         that are to be merged into the original descriptor
       */
      protected final void mergeFilters(WebXml theWebXml)
      {
          Iterator filterNames = theWebXml.getFilterNames();
          int count = 0;
          while (filterNames.hasNext())
          {
              String filterName = (String) filterNames.next();
              if (!webXml.hasFilter(filterName))
              {
                  webXml.addFilter(theWebXml.getFilter(filterName));
              }
              else
              {
                  // merge the parameters
                  Iterator filterInitParamNames =
                      theWebXml.getFilterInitParamNames(filterName);
                  while (filterInitParamNames.hasNext())
                  {
                      String paramName = (String) filterInitParamNames.next();
                      String paramValue =
                          theWebXml.getFilterInitParam(filterName, paramName);
                      webXml.addFilterInitParam(
                          filterName, paramName, paramValue);
                  }
              }
              // merge the mappings
              Iterator filterMappings = theWebXml.getFilterMappings(filterName);
              while (filterMappings.hasNext())
              {
                  String urlPattern = (String) filterMappings.next();
                  webXml.addFilterMapping(filterName, urlPattern);
              }
              count++;
          }
          this.log.trace("Merged " + count + " filter definition"
              + (count != 1 ? "s " : " ") + "into the descriptor");
      }
  
      /**
       * Merges the servlet definitions from the specified descriptor into the 
       * original descriptor.
       * 
       * @param theWebXml The descriptor that contains the servlet definitions
       *         that are to be merged into the original descriptor
       */
      protected final void mergeServlets(WebXml theWebXml)
      {
          Iterator servletNames = theWebXml.getServletNames();
          int count = 0;
          while (servletNames.hasNext())
          {
              String servletName = (String) servletNames.next();
              if (!webXml.hasServlet(servletName))
              {
                  webXml.addServlet(theWebXml.getServlet(servletName));
              }
              else
              {
                  // merge the parameters
                  Iterator servletInitParamNames =
                      theWebXml.getServletInitParamNames(servletName);
                  while (servletInitParamNames.hasNext())
                  {
                      String paramName = (String) servletInitParamNames.next();
                      String paramValue =
                          theWebXml.getServletInitParam(servletName, paramName);
                      webXml.addServletInitParam(
                          servletName, paramName, paramValue);
                  }
              }
              // merge the mappings
              Iterator servletMappings =
                  theWebXml.getServletMappings(servletName);
              while (servletMappings.hasNext())
              {
                  String urlPattern = (String) servletMappings.next();
                  webXml.addServletMapping(servletName, urlPattern);
              }
              count++;
          }
          this.log.trace("Merged " + count + " servlet definition"
              + (count != 1 ? "s " : " ") + "into the descriptor");
      }
  
      /**
       * 
       * 
       * @param theWebXml The descriptor that contains the security constraints
       *         that are to be merged into the original descriptor
       */
      protected final void mergeSecurityConstraints(WebXml theWebXml)
      {
          Iterator securityConstraints =
              theWebXml.getElements(WebXmlTag.SECURITY_CONSTRAINT);
          int count = 0;
          while (securityConstraints.hasNext())
          {
              Element securityConstraint = (Element) securityConstraints.next();
              webXml.addElement(WebXmlTag.SECURITY_CONSTRAINT,
                  securityConstraint);
              count++;
          }
          this.log.trace("Merged " + count + " security constraint"
              + (count != 1 ? "s " : " ") + "into the descriptor");
      }
  
      /**
       * 
       * 
       * @param theWebXml The descriptor that contains the login config that
       *         is to be merged into the original descriptor
       */
      protected final void mergeLoginConfig(WebXml theWebXml)
      {
          Iterator loginConfigs = theWebXml.getElements(WebXmlTag.LOGIN_CONFIG);
          if (loginConfigs.hasNext())
          {
              webXml.replaceElement(WebXmlTag.LOGIN_CONFIG,
                  (Element) loginConfigs.next());
              this.log.trace(
                  "Merged the login configuration into the descriptor");
          }
      }
  
      /**
       * 
       * 
       * @param theWebXml The descriptor that contains the security roles that
       *         are to be merged into the original descriptor
       */
      protected final void mergeSecurityRoles(WebXml theWebXml)
      {
          Iterator securityRoles =
              theWebXml.getElements(WebXmlTag.SECURITY_ROLE);
          int count = 0;
          while (securityRoles.hasNext())
          {
              Element securityRole = (Element) securityRoles.next();
              webXml.addElement(WebXmlTag.SECURITY_ROLE,
                  securityRole);
              count++;
          }
          this.log.trace("Merged " + count + " security role"
              + (count != 1 ? "s " : " ") + "into the descriptor");
      }
  
  }
  
  
  
  1.1                  jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/WebXml.java
  
  Index: WebXml.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 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", "Cactus" 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.cactus.integration.ant.deployment;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  
  import org.w3c.dom.Document;
  import org.w3c.dom.DocumentType;
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  
  /**
   * Encapsulates the DOM representation of a web deployment descriptor 
   * <code>web.xml</code> to provide convenience methods for easy access and 
   * manipulation.
   *
   * @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
   * @author <a href="mailto:vmassol@apache.org">Vincent Massol</a>
   *
   * @since Cactus 1.5
   * @version $Id: WebXml.java,v 1.1 2003/05/14 10:43:36 cmlenz Exp $
   */
  public class WebXml
  {
      
      // Private Constants -------------------------------------------------------
      
      /**
       * Specifies the order in which the top-level elements must appear in the
       * descriptor, according to the DTD.
       */
      private static final WebXmlTag[] ELEMENT_ORDER = {
          WebXmlTag.ICON,
          WebXmlTag.DISPLAY_NAME,
          WebXmlTag.DESCRIPTION,
          WebXmlTag.DISTRIBUTABLE,
          WebXmlTag.FILTER,
          WebXmlTag.FILTER_MAPPING,
          WebXmlTag.LISTENER,
          WebXmlTag.SERVLET,
          WebXmlTag.SERVLET_MAPPING,
          WebXmlTag.SESSION_CONFIG,
          WebXmlTag.MIME_MAPPING,
          WebXmlTag.WELCOME_FILE_LIST,
          WebXmlTag.ERROR_PAGE,
          WebXmlTag.TAGLIB,
          WebXmlTag.RESOURCE_ENV_REF,
          WebXmlTag.RESOURCE_REF,
          WebXmlTag.SECURITY_CONSTRAINT,
          WebXmlTag.LOGIN_CONFIG,
          WebXmlTag.SECURITY_ROLE,
          WebXmlTag.ENV_ENTRY,
          WebXmlTag.EJB_REF,
          WebXmlTag.EJB_LOCAL_REF,
      };
      
      // Instance Variables ------------------------------------------------------
      
      /**
       * The DOM representation of the deployment descriptor.
       */
      private final Document document;
      
      /**
       * The root element of the descriptor.
       */
      private final Element rootElement;
      
      // Constructors ------------------------------------------------------------
      
      /**
       * Constructor.
       * 
       * @param theDocument The DOM document representing the parsed deployment
       *         descriptor
       */
      public WebXml(Document theDocument)
      {
          this.document = theDocument;
          this.rootElement = theDocument.getDocumentElement();
      }
      
      // Public Methods ----------------------------------------------------------
      
      /**
       * Returns the DOM document representing the deployment descriptor. The 
       * document will contain any modifications made through this instance.
       * 
       * @return The document representing the deploy descriptor
       */
      public final Document getDocument()
      {
          return this.document;
      }
      
      /**
       * Returns the servlet API version.
       * 
       * @return The version.
       */
      public final WebXmlVersion getVersion()
      {
          DocumentType docType = this.document.getDoctype();
          if (docType != null)
          {
              return WebXmlVersion.valueOf(docType);
          }
          return null;
      }
  
      /**
       * Adds a new servlet filter to the descriptor.
       * 
       * @param theFilterName The name of the filter to add
       * @param theFilterClass The name of the class implementing the filter
       */
      public final void addFilter(String theFilterName, String theFilterClass)
      {
          if (theFilterName == null)
          {
              throw new NullPointerException();
          }
          if (hasFilter(theFilterName))
          {
              throw new IllegalStateException("Filter '" + theFilterName
                  + "' already defined");
          }
          Element filterElement =
              this.document.createElement(WebXmlTag.FILTER.getTagName());
          filterElement.appendChild(
              createNestedText(WebXmlTag.FILTER_NAME, theFilterName));
          filterElement.appendChild(
              createNestedText(WebXmlTag.FILTER_CLASS, theFilterClass));
          addElement(WebXmlTag.FILTER, filterElement);
      }
      
      /**
       * Adds a new servlet filter to the descriptor.
       * 
       * @param theFilter The element representing the filter definition
       */
      public final void addFilter(Element theFilter)
      {
          checkElement(theFilter, WebXmlTag.FILTER);
          String filterName = getNestedText(theFilter, WebXmlTag.FILTER_NAME);
          if (filterName == null)
          {
              throw new IllegalArgumentException("Not a valid filter element");
          }
          if (hasFilter(filterName))
          {
              throw new IllegalStateException("Filter '" + filterName
                  + "' already defined");
          }
          addElement(WebXmlTag.FILTER, theFilter);
      }
      
      /**
       * Adds an initialization parameter to the specified filter.
       * 
       * @param theFilterName The name of the filter
       * @param theParamName The name of the parameter
       * @param theParamValue The parameter value
       */
      public final void addFilterInitParam(String theFilterName,
          String theParamName, String theParamValue)
      {
          Element filterElement = getFilter(theFilterName);
          if (filterElement == null)
          {
              throw new IllegalStateException("Filter '" + theFilterName
                  + "' not defined");
          }
          addInitParam(filterElement, theParamName, theParamValue);
      }
      
      /**
       * Adds a filter mapping to the descriptor.
       * 
       * @param theFilterName The name of the filter
       * @param theUrlPattern The URL pattern the filter should be mapped to
       */
      public final void addFilterMapping(String theFilterName,
          String theUrlPattern)
      {
          if (!hasFilter(theFilterName))
          {
              throw new IllegalStateException("Filter '" + theFilterName
                  + "' not defined");
          }
          Element filterMappingElement =
              this.document.createElement(WebXmlTag.FILTER_MAPPING.getTagName());
          filterMappingElement.appendChild(
              createNestedText(WebXmlTag.FILTER_NAME, theFilterName));
          filterMappingElement.appendChild(
              createNestedText(WebXmlTag.URL_PATTERN,  theUrlPattern));
          addElement(WebXmlTag.FILTER_MAPPING, filterMappingElement);
      }
      
      /**
       * Returns the element that contains the definition of a specific servlet
       * filter, or <code>null</code> if a filter of the specified name is not
       * defined in the descriptor.
       * 
       * @param theFilterName The name of the servlet filter
       * @return The DOM element representing the filter definition
       */
      public final Element getFilter(String theFilterName)
      {
          if (theFilterName == null)
          {
              throw new NullPointerException();
          }
          Iterator filterElements = getElements(WebXmlTag.FILTER);
          while (filterElements.hasNext())
          {
              Element filterElement = (Element) filterElements.next();
              if (theFilterName.equals(getNestedText(
                  filterElement, WebXmlTag.FILTER_NAME)))
              {
                  return filterElement;
              }
          }
          return null;
      }
      
      /**
       * Returns a list of names of filters that are mapped to the specified
       * class.
       * 
       * @param theClassName The fully qualified name of the filter class
       * @return An iterator over the names of the filters mapped to the class
       */
      public final Iterator getFilterNamesForClass(String theClassName)
      {
          if (theClassName == null)
          {
              throw new NullPointerException();
          }
          Iterator filterElements = getElements(WebXmlTag.FILTER);
          List filterNames = new ArrayList();
          while (filterElements.hasNext())
          {
              Element filterElement = (Element) filterElements.next();
              if (theClassName.equals(getNestedText(
                  filterElement, WebXmlTag.FILTER_CLASS)))
              {
                  filterNames.add(getNestedText(
                      filterElement, WebXmlTag.FILTER_NAME));
              }
          }
          return filterNames.iterator();
      }
      
      /**
       * Returns the value of an initialization parameter of the specified filter.
       * 
       * @param theFilterName The name of the servlet filter
       * @param theParamName The name of the initialization parameter
       * @return The parameter value
       */
      public final String getFilterInitParam(String theFilterName,
          String theParamName)
      {
          return getInitParam(getFilter(theFilterName), theParamName);
      }
      
      /**
       * Returns the names of the initialization parameters of the specified 
       * servlet filter.
       * 
       * @param theFilterName The name of the servlet filter of which the
       *         parameter names should be retrieved
       * @return An iterator over the ordered list of parameter names
       */
      public final Iterator getFilterInitParamNames(String theFilterName)
      {
          return getInitParamNames(getFilter(theFilterName));
      }
      
      /**
       * Returns the URL-patterns that the specified filter is mapped to in an
       * ordered list. If there are no mappings for the specified filter, an
       * iterator over an empty list is returned.
       * 
       * @param theFilterName The name of the servlet filter of which the 
       *         mappings should be retrieved
       * @return An iterator over the ordered list of URL-patterns
       */
      public final Iterator getFilterMappings(String theFilterName)
      {
          if (theFilterName == null)
          {
              throw new NullPointerException();
          }
          List filterMappings = new ArrayList();
          Iterator filterMappingElements = getElements(WebXmlTag.FILTER_MAPPING);
          while (filterMappingElements.hasNext())
          {
              Element filterMappingElement = (Element)
                  filterMappingElements.next();
              if (theFilterName.equals(getNestedText(
                  filterMappingElement, WebXmlTag.FILTER_NAME)))
              {
                  String urlPattern = getNestedText(
                      filterMappingElement, WebXmlTag.URL_PATTERN);
                  if (urlPattern != null)
                  {
                      filterMappings.add(urlPattern);
                  }
              }
          }
          return filterMappings.iterator();
      }
      
      /**
       * Returns the names of all filters defined in the deployment descriptor.
       * The names are returned as an iterator over an ordered list.
       * 
       * @return The filter names
       */
      public final Iterator getFilterNames()
      {
          List filterNames = new ArrayList();
          Iterator filterElements = getElements(WebXmlTag.FILTER);
          while (filterElements.hasNext())
          {
              Element filterElement = (Element) filterElements.next();
              String filterName =
                  getNestedText(filterElement, WebXmlTag.FILTER_NAME);
              if (filterName != null)
              {
                  filterNames.add(filterName);
              }
          }
          return filterNames.iterator();
      }
      
      /**
       * Returns whether a servlet filter by the specified name is defined in the 
       * deployment descriptor.
       * 
       * @param theFilterName The name of the filter
       * @return <code>true</code> if the filter is defined, <code>false</code>
       *          otherwise
       */
      public final boolean hasFilter(String theFilterName)
      {
          return (getFilter(theFilterName) != null);
      }
      
      /**
       * Adds a mapped JSP file to the descriptor.
       * 
       * @param theServletName The name of the servlet to add
       * @param theJspFile The path to the JSP file relative to the root of the
       *        web application
       */
      public final void addJspFile(String theServletName, String theJspFile)
      {
          if (theServletName == null)
          {
              throw new NullPointerException();
          }
          if (hasFilter(theServletName))
          {
              throw new IllegalStateException("Servlet '" + theServletName
                  + "' already defined");
          }
          Element servletElement =
              this.document.createElement(WebXmlTag.SERVLET.getTagName());
          servletElement.appendChild(
              createNestedText(WebXmlTag.SERVLET_NAME, theServletName));
          servletElement.appendChild(
              createNestedText(WebXmlTag.JSP_FILE, theJspFile));
          addElement(WebXmlTag.SERVLET, servletElement);
      }
      
      /**
       * Adds a new servlet to the descriptor.
       * 
       * @param theServletName The name of the servlet to add
       * @param theServletClass The name of the class implementing the servlet
       */
      public final void addServlet(String theServletName, String theServletClass)
      {
          if (theServletName == null)
          {
              throw new NullPointerException();
          }
          if (hasFilter(theServletName))
          {
              throw new IllegalStateException("Servlet '" + theServletName
                  + "' already defined");
          }
          Element servletElement =
              this.document.createElement(WebXmlTag.SERVLET.getTagName());
          servletElement.appendChild(
              createNestedText(WebXmlTag.SERVLET_NAME, theServletName));
          servletElement.appendChild(
              createNestedText(WebXmlTag.SERVLET_CLASS, theServletClass));
          addElement(WebXmlTag.SERVLET, servletElement);
      }
      
      /**
       * Adds a new servlet to the descriptor.
       * 
       * @param theServlet The element representing the servlet definition
       */
      public final void addServlet(Element theServlet)
      {
          checkElement(theServlet, WebXmlTag.SERVLET);
          String servletName = getNestedText(theServlet, WebXmlTag.SERVLET_NAME);
          if (servletName == null)
          {
              throw new IllegalArgumentException("Not a valid servlet element");
          }
          if (hasServlet(servletName))
          {
              throw new IllegalStateException("Servlet '" + servletName
                  + "' already defined");
          }
          addElement(WebXmlTag.SERVLET, theServlet);
      }
      
      /**
       * Adds an initialization parameter to the specified servlet.
       * 
       * @param theServletName The name of the filter
       * @param theParamName The name of the parameter
       * @param theParamValue The parameter value
       */
      public final void addServletInitParam(String theServletName,
          String theParamName, String theParamValue)
      {
          Element servletElement = getServlet(theServletName);
          if (servletElement == null)
          {
              throw new IllegalStateException("Servlet '" + theServletName
                  + "' not defined");
          }
          addInitParam(servletElement, theParamName, theParamValue);
      }
      
      /**
       * Adds a servlet mapping to the descriptor.
       * 
       * @param theServletName The name of the servlet
       * @param theUrlPattern The URL pattern the servlet should be mapped to
       */
      public final void addServletMapping(String theServletName,
          String theUrlPattern)
      {
          if (!hasServlet(theServletName))
          {
              throw new IllegalStateException("Servlet '" + theServletName
                  + "' not defined");
          }
          Element servletMappingElement =
              this.document.createElement(WebXmlTag.SERVLET_MAPPING.getTagName());
          servletMappingElement.appendChild(
              createNestedText(WebXmlTag.SERVLET_NAME, theServletName));
          servletMappingElement.appendChild(
              createNestedText(WebXmlTag.URL_PATTERN, theUrlPattern));
          addElement(WebXmlTag.SERVLET_MAPPING, servletMappingElement);
      }
      
      /**
       * Returns the element that contains the definition of a specific servlet, 
       * or <code>null</code> if a servlet of the specified name is not defined
       * in the descriptor.
       * 
       * @param theServletName The name of the servlet
       * @return The DOM element representing the servlet definition
       */
      public final Element getServlet(String theServletName)
      {
          if (theServletName == null)
          {
              throw new NullPointerException();
          }
          Iterator servletElements = getElements(WebXmlTag.SERVLET);
          while (servletElements.hasNext())
          {
              Element servletElement = (Element) servletElements.next();
              if (theServletName.equals(getNestedText(
                  servletElement, WebXmlTag.SERVLET_NAME)))
              {
                  return servletElement;
              }
          }
          return null;
      }
      
      /**
       * Returns the value of an initialization parameter of the specified
       * servlet.
       * 
       * @param theServletName The name of the servlet
       * @param theParamName The name of the initialization parameter
       * @return The parameter value
       */
      public final String getServletInitParam(String theServletName,
          String theParamName)
      {
          return getInitParam(getServlet(theServletName), theParamName);
      }
      
      /**
       * Returns the names of the initialization parameters of the specified 
       * servlet.
       * 
       * @param theServletName The name of the servlet of which the parameter
       *         names should be retrieved
       * @return An iterator over the ordered list of parameter names
       */
      public final Iterator getServletInitParamNames(String theServletName)
      {
          return getInitParamNames(getServlet(theServletName));
      }
      
      /**
       * Returns the URL-patterns that the specified servlet is mapped to in an
       * ordered list. If there are no mappings for the specified servlet, an
       * iterator over an empty list is returned.
       * 
       * @param theServletName The name of the servlet of which the mappings
       *         should be retrieved
       * @return An iterator over the ordered list of URL-patterns
       */
      public final Iterator getServletMappings(String theServletName)
      {
          if (theServletName == null)
          {
              throw new NullPointerException();
          }
          List servletMappings = new ArrayList();
          Iterator servletMappingElements =
              getElements(WebXmlTag.SERVLET_MAPPING);
          while (servletMappingElements.hasNext())
          {
              Element servletMappingElement = (Element)
                  servletMappingElements.next();
              if (theServletName.equals(getNestedText(
                  servletMappingElement, WebXmlTag.SERVLET_NAME)))
              {
                  String urlPattern = getNestedText(
                      servletMappingElement, WebXmlTag.URL_PATTERN);
                  if (urlPattern != null)
                  {
                      servletMappings.add(urlPattern);
                  }
              }
          }
          return servletMappings.iterator();
      }
      
      /**
       * Returns the names of all servlets defined in the deployment descriptor.
       * The names are returned as an iterator over an ordered list.
       * 
       * @return The servlet names
       */
      public final Iterator getServletNames()
      {
          List servletNames = new ArrayList();
          Iterator servletElements = getElements(WebXmlTag.SERVLET);
          while (servletElements.hasNext())
          {
              Element servletElement = (Element) servletElements.next();
              String servletName =
                  getNestedText(servletElement, WebXmlTag.SERVLET_NAME);
              if (servletName != null)
              {
                  servletNames.add(servletName);
              }
          }
          return servletNames.iterator();
      }
      
      /**
       * Returns a list of names of servlets that are mapped to the specified
       * class.
       * 
       * @param theClassName The fully qualified name of the servlet class
       * @return An iterator over the names of the servlets mapped to the class
       */
      public final Iterator getServletNamesForClass(String theClassName)
      {
          if (theClassName == null)
          {
              throw new NullPointerException();
          }
          Iterator servletElements = getElements(WebXmlTag.SERVLET);
          List servletNames = new ArrayList();
          while (servletElements.hasNext())
          {
              Element servletElement = (Element) servletElements.next();
              if (theClassName.equals(getNestedText(
                  servletElement, WebXmlTag.SERVLET_CLASS)))
              {
                  servletNames.add(getNestedText(
                      servletElement, WebXmlTag.SERVLET_NAME));
              }
          }
          return servletNames.iterator();
      }
      
      /**
       * Returns a list of names of servlets that are mapped to the specified
       * JSP file.
       * 
       * @param theJspFile The path to the JSP file, relative to the root of the
       *        web-application
       * @return An iterator over the names of the servlets mapped to the JSP file
       */
      public final Iterator getServletNamesForJspFile(String theJspFile)
      {
          if (theJspFile == null)
          {
              throw new NullPointerException();
          }
          Iterator servletElements = getElements(WebXmlTag.SERVLET);
          List servletNames = new ArrayList();
          while (servletElements.hasNext())
          {
              Element servletElement = (Element) servletElements.next();
              if (theJspFile.equals(getNestedText(
                  servletElement, WebXmlTag.JSP_FILE)))
              {
                  servletNames.add(getNestedText(
                      servletElement, WebXmlTag.SERVLET_NAME));
              }
          }
          return servletNames.iterator();
      }
      
      /**
       * Returns whether a servlet by the specified name is defined in the 
       * deployment descriptor.
       * 
       * @param theServletName The name of the servlet
       * @return <code>true</code> if the servlet is defined, <code>false</code>
       *          otherwise
       */
      public final boolean hasServlet(String theServletName)
      {
          return (getServlet(theServletName) != null);
      }
      
      /**
       * Returns an iterator over the elements that match the specified tag.
       * 
       * @param theTag The descriptor tag of which the elements should be
       *         returned
       * @return An iterator over the elements matching the tag, in the order 
       *          they occur in the descriptor
       */
      public final Iterator getElements(WebXmlTag theTag)
      {
          List elements = new ArrayList();
          NodeList nodeList =
              this.rootElement.getElementsByTagName(theTag.getTagName()); 
          for (int i = 0; i < nodeList.getLength(); i++)
          {
              elements.add(nodeList.item(i));
          }
          return elements.iterator();
      }
      
      /**
       * Adds an element of the specified tag to the descriptor.
       * 
       * @param theTag The descriptor tag
       * @param theElement The element to add
       */
      public final void addElement(WebXmlTag theTag, Element theElement)
      {
          checkElement(theElement, theTag);
          if (!theTag.isMultipleAllowed() && getElements(theTag).hasNext())
          {
              throw new IllegalStateException("The tag '" + theTag
                  + "' may not occur more than once in the descriptor");
          }
          Node importedNode = this.document.importNode(theElement, true);
          Node refNode = getInsertionPointFor(theTag);
          this.rootElement.insertBefore(importedNode, refNode);
      }
      
      /**
       * Replaces all elements of the specified tag with the provided element.
       * 
       * @param theTag The descriptor tag
       * @param theElement The element to replace the current elements with
       */
      public final void replaceElement(WebXmlTag theTag, Element theElement)
      {
          Iterator elements = getElements(theTag);
          while (elements.hasNext())
          {
              Element element = (Element) elements.next();
              element.getParentNode().removeChild(element);
          }
          addElement(theTag, theElement);
      }
      
      // Private Methods ---------------------------------------------------------
      
      /**
       * Adds an initialization parameter to the specified filter or servlet.
       * 
       * @param theElement The filter or servlet element to which the
       *         initialization parameter should be added
       * @param theParamName The name of the parameter
       * @param theParamValue The parameter value
       */
      private void addInitParam(Element theElement, String theParamName,
          String theParamValue)
      {
          Element initParamElement =
              this.document.createElement(WebXmlTag.INIT_PARAM.getTagName());
          initParamElement.appendChild(
              createNestedText(WebXmlTag.PARAM_NAME, theParamName));
          initParamElement.appendChild(
              createNestedText(WebXmlTag.PARAM_VALUE, theParamValue));
          theElement.appendChild(initParamElement);
      }
      
      /**
       * Checks an element whether its name matches the specified name.
       * 
       * @param theElement The element to check
       * @param theExpectedTag The expected tag name
       * @throws IllegalArgumentException If the element name doesn't match
       */
      private void checkElement(Element theElement, WebXmlTag theExpectedTag)
          throws IllegalArgumentException
      {
          if (!theExpectedTag.getTagName().equals(theElement.getNodeName()))
          {
              throw new IllegalArgumentException("Not a '" + theExpectedTag
                  + "' element");
          }
      }
      
      /**
       * Creates an element that contains nested text.
       * 
       * @param theTag The tag to create an instance of
       * @param theText The text that should be nested in the element
       * @return The created DOM element
       */
      private Element createNestedText(WebXmlTag theTag, String theText)
      {
          Element element = this.document.createElement(theTag.getTagName());
          element.appendChild(this.document.createTextNode(theText));
          return element;
      }
      
      /**
       * Returns the value of an initialization parameter of the specified filter
       * or servlet.
       * 
       * @param theElement The filter or servlet element that contains the
       *         initialization parameters
       * @param theParamName The name of the initialization parameter
       * @return The parameter value
       */
      private String getInitParam(Element theElement, String theParamName)
      {
          if (theElement != null)
          {
              NodeList initParamElements =
                  theElement.getElementsByTagName(
                      WebXmlTag.INIT_PARAM.getTagName());
              for (int i = 0; i < initParamElements.getLength(); i++)
              {
                  Element initParamElement = (Element) initParamElements.item(i);
                  String paramName = getNestedText(
                      initParamElement, WebXmlTag.PARAM_NAME);
                  if (theParamName.equals(paramName))
                  {
                      return getNestedText(
                          initParamElement, WebXmlTag.PARAM_VALUE);
                  }
              }
          }
          return null;
      }
      
      /**
       * Returns the names of the initialization parameters of the specified 
       * filter or servlet.
       * 
       * @param theElement The filter or servlet element that contains the
       *         initialization parameters
       * @return An iterator over the ordered list of parameter names
       */
      private Iterator getInitParamNames(Element theElement)
      {
          List initParamNames = new ArrayList();
          if (theElement != null)
          {
              NodeList initParamElements =
                  theElement.getElementsByTagName(
                      WebXmlTag.INIT_PARAM.getTagName());
              for (int i = 0; i < initParamElements.getLength(); i++)
              {
                  Element initParamElement = (Element) initParamElements.item(i);
                  String paramName = getNestedText(
                      initParamElement, WebXmlTag.PARAM_NAME);
                  if (paramName != null)
                  {
                      initParamNames.add(paramName);
                  }
              }
          }
          return initParamNames.iterator();
      }
      
      /**
       * Returns the node before which the specified tag should be inserted, or
       * <code>null</code> if the node should be inserted at the end of the 
       * descriptor.
       * 
       * @param theTag The tag that should be inserted
       * @return The node before which the tag can be inserted
       */
      private Node getInsertionPointFor(WebXmlTag theTag)
      {
          for (int i = 0; i < ELEMENT_ORDER.length; i++)
          {
              if (ELEMENT_ORDER[i] == theTag)
              {
                  for (int j = i + 1; j < ELEMENT_ORDER.length; j++)
                  {
                      NodeList elements =
                          this.rootElement.getElementsByTagName(
                              ELEMENT_ORDER[j].getTagName());
                      if (elements.getLength() > 0)
                      {
                          Node result = elements.item(0);
                          Node previous = result.getPreviousSibling();
                          while ((previous != null)
                              && ((previous.getNodeType() == Node.COMMENT_NODE)
                               || (previous.getNodeType() == Node.TEXT_NODE)))
                          {
                              result = previous;
                              previous = result.getPreviousSibling();
                          }
                          return result;
                      }
                  }
                  break;
              }
          }
          return null;
      }
      
      /**
       * Returns the text nested inside a child element of the specified element.
       * 
       * @param theElement The element of which the nested text should be
       *         returned
       * @param theTag The descriptor tag in which the text is nested
       * @return The text nested in the element
       */
      private String getNestedText(Element theElement,
          WebXmlTag theTag)
      {
          NodeList nestedElements =
              theElement.getElementsByTagName(theTag.getTagName());
          if (nestedElements.getLength() > 0)
          {
              Node nestedText = nestedElements.item(0).getFirstChild();
              if (nestedText != null)
              {
                  return nestedText.getNodeValue();
              }
          }
          return null;
      }
      
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: cactus-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: cactus-dev-help@jakarta.apache.org