Save This Page
Home » cactus-1.8.0-src » org.apache.cactus.integration.ant.deployment.webapp » [javadoc | source]
    1   /* 
    2    * ========================================================================
    3    * 
    4    * Copyright 2003-2005 The Apache Software Foundation.
    5    *
    6    * Licensed under the Apache License, Version 2.0 (the "License");
    7    * you may not use this file except in compliance with the License.
    8    * You may obtain a copy of the License at
    9    * 
   10    *   http://www.apache.org/licenses/LICENSE-2.0
   11    * 
   12    * Unless required by applicable law or agreed to in writing, software
   13    * distributed under the License is distributed on an "AS IS" BASIS,
   14    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15    * See the License for the specific language governing permissions and
   16    * limitations under the License.
   17    * 
   18    * ========================================================================
   19    */
   20   package org.apache.cactus.integration.ant.deployment.webapp;
   21   
   22   import java.util.Iterator;
   23   
   24   import org.apache.cactus.integration.ant.util.AntLog;
   25   import org.apache.commons.logging.Log;
   26   import org.w3c.dom.Element;
   27   
   28   /**
   29    * Helper class that can merge two web deployment descriptors.
   30    *
   31    * @since Cactus 1.5
   32    * @version $Id: WebXmlMerger.java,v 1.2 2005/02/10 19:51:34 vmassol Exp $
   33    */
   34   public class WebXmlMerger
   35   {
   36       // Instance Variables ------------------------------------------------------
   37   
   38       /**
   39        * The original, authorative descriptor onto which the merges are performed.
   40        */
   41       private WebXml webXml;
   42       
   43       /**
   44        * The log to use.
   45        */
   46       private Log log = AntLog.NULL;
   47   
   48       // Constructors ------------------------------------------------------------
   49   
   50       /**
   51        * Constructor.
   52        * 
   53        * @param theWebXml The original descriptor
   54        */
   55       public WebXmlMerger(WebXml theWebXml)
   56       {
   57           this.webXml = theWebXml;
   58       }
   59   
   60       // Public Methods ----------------------------------------------------------
   61   
   62       /**
   63        * Merges the merge descriptor with the original descriptor. 
   64        * 
   65        * @param theMergeWebXml The descriptor to merge in
   66        */
   67       public final void merge(WebXml theMergeWebXml)
   68       {
   69           checkServletVersions(theMergeWebXml);
   70           mergeContextParams(theMergeWebXml);
   71           if (WebXmlVersion.V2_3.compareTo(this.webXml.getVersion()) <= 0)
   72           {
   73               mergeFilters(theMergeWebXml);
   74           }
   75           mergeServlets(theMergeWebXml);
   76           if (WebXmlVersion.V2_3.compareTo(this.webXml.getVersion()) <= 0)
   77           {
   78               mergeResourceEnvironmentReferences(theMergeWebXml);
   79           }
   80           mergeResourceReferences(theMergeWebXml);
   81           mergeSecurityConstraints(theMergeWebXml);
   82           mergeLoginConfig(theMergeWebXml);
   83           mergeSecurityRoles(theMergeWebXml);
   84           mergeEnvironmentEntries(theMergeWebXml);
   85           mergeEjbRefs(theMergeWebXml);
   86           if (WebXmlVersion.V2_3.compareTo(this.webXml.getVersion()) <= 0)
   87           {
   88               mergeEjbLocalRefs(theMergeWebXml);
   89           }
   90       }
   91   
   92       /**
   93        * Sets the log to which events should be written. This method must be 
   94        * called before any of the other methods, because the class will rely on 
   95        * being able to log.
   96        * 
   97        * @param theLog The log to use
   98        */
   99       public final void setLog(Log theLog)
  100       {
  101           this.log = theLog;
  102       }
  103   
  104       // Protected Methods -------------------------------------------------------
  105   
  106       /**
  107        * Checks the versions of the servlet API in each descriptor, and logs
  108        * a warning if a mismatch might result in the loss of definitions.
  109        * 
  110        * @param theWebXml The descriptor that will be merged with the original
  111        */
  112       protected final void checkServletVersions(WebXml theWebXml)
  113       {
  114           if ((this.webXml.getVersion() != null)
  115            && (this.webXml.getVersion().compareTo(theWebXml.getVersion()) < 0))
  116           {
  117               this.log.warn(
  118                   "Merging elements from a version " + theWebXml.getVersion()
  119                   + " descriptor into a version " + this.webXml.getVersion() 
  120                   + ", some elements may be skipped");
  121           }
  122       }
  123   
  124       /**
  125        * Merges the context-param definitions from the specified descriptor into 
  126        * the original descriptor.
  127        * 
  128        * @param theWebXml The descriptor that contains the context-params 
  129        *        definitions that are to be merged into the original descriptor
  130        */
  131       protected final void mergeContextParams(WebXml theWebXml)
  132       {
  133           Iterator contextParams = theWebXml.getElements(WebXmlTag.CONTEXT_PARAM);
  134           int count = 0;
  135           while (contextParams.hasNext())
  136           {
  137               String paramName = theWebXml.getContextParamName(
  138                   (Element) contextParams.next());
  139               if (!webXml.hasContextParam(paramName))
  140               {
  141                   webXml.addContextParam(theWebXml.getContextParam(paramName));
  142               }
  143               count++;            
  144           }
  145           this.log.trace("Merged " + count + " context-param definition"
  146               + (count != 1 ? "s " : " ") + "into the descriptor");
  147       }
  148       
  149       /**
  150        * Merges the servlet definitions from the specified descriptor into the 
  151        * original descriptor.
  152        * 
  153        * @param theWebXml The descriptor that contains the filter definitions
  154        *        that are to be merged into the original descriptor
  155        */
  156       protected final void mergeFilters(WebXml theWebXml)
  157       {
  158           Iterator filterNames = theWebXml.getFilterNames();
  159           int count = 0;
  160           while (filterNames.hasNext())
  161           {
  162               String filterName = (String) filterNames.next();
  163               if (!webXml.hasFilter(filterName))
  164               {
  165                   webXml.addFilter(theWebXml.getFilter(filterName));
  166               }
  167               else
  168               {
  169                   // merge the parameters
  170                   Iterator filterInitParamNames =
  171                       theWebXml.getFilterInitParamNames(filterName);
  172                   while (filterInitParamNames.hasNext())
  173                   {
  174                       String paramName = (String) filterInitParamNames.next();
  175                       String paramValue =
  176                           theWebXml.getFilterInitParam(filterName, paramName);
  177                       webXml.addFilterInitParam(
  178                           filterName, paramName, paramValue);
  179                   }
  180               }
  181               // merge the mappings
  182               Iterator filterMappings = theWebXml.getFilterMappings(filterName);
  183               while (filterMappings.hasNext())
  184               {
  185                   String urlPattern = (String) filterMappings.next();
  186                   webXml.addFilterMapping(filterName, urlPattern);
  187               }
  188               count++;
  189           }
  190           this.log.trace("Merged " + count + " filter definition"
  191               + (count != 1 ? "s " : " ") + "into the descriptor");
  192       }
  193   
  194       /**
  195        * Merges the servlet definitions from the specified descriptor into the 
  196        * original descriptor.
  197        * 
  198        * @param theWebXml The descriptor that contains the servlet definitions
  199        *        that are to be merged into the original descriptor
  200        */
  201       protected final void mergeServlets(WebXml theWebXml)
  202       {
  203           Iterator servletNames = theWebXml.getServletNames();
  204           int count = 0;
  205           while (servletNames.hasNext())
  206           {
  207               String servletName = (String) servletNames.next();
  208               if (!webXml.hasServlet(servletName))
  209               {
  210                   webXml.addServlet(theWebXml.getServlet(servletName));
  211               }
  212               else
  213               {
  214                   // merge the parameters
  215                   Iterator servletInitParamNames =
  216                       theWebXml.getServletInitParamNames(servletName);
  217                   while (servletInitParamNames.hasNext())
  218                   {
  219                       String paramName = (String) servletInitParamNames.next();
  220                       String paramValue =
  221                           theWebXml.getServletInitParam(servletName, paramName);
  222                       webXml.addServletInitParam(
  223                           servletName, paramName, paramValue);
  224                   }
  225                   String roleName = 
  226                       theWebXml.getServletRunAsRoleName(servletName);
  227                   if (roleName != null)
  228                   {
  229                       webXml.addServletRunAsRoleName(servletName, roleName);
  230                   }
  231               }
  232               // merge the mappings
  233               Iterator servletMappings =
  234                   theWebXml.getServletMappings(servletName);
  235               while (servletMappings.hasNext())
  236               {
  237                   String urlPattern = (String) servletMappings.next();
  238                   webXml.addServletMapping(servletName, urlPattern);
  239               }
  240               count++;
  241           }
  242           this.log.trace("Merged " + count + " servlet definition"
  243               + (count != 1 ? "s " : " ") + "into the descriptor");
  244       }
  245   
  246       /**
  247        * Merges the resource environment references from the provided descriptor
  248        * into the original descriptor.
  249        * 
  250        * @param theWebXml The descriptor that contains the references that are to
  251        *        be merged into the original descriptor
  252        */
  253       protected final void mergeResourceEnvironmentReferences(WebXml theWebXml)
  254       {
  255           int count = insertElements(theWebXml, WebXmlTag.RESOURCE_ENV_REF);
  256           if (count > 0)
  257           {
  258               this.log.trace("Merged " + count + " resource environment "
  259                   + "reference" + (count != 1 ? "s " : " ") + "into the "
  260                   + "descriptor");
  261           }
  262       }
  263   
  264       /**
  265        * Merges the resource references from the provided descriptor into the
  266        * original descriptor.
  267        * 
  268        * @param theWebXml The descriptor that contains the resource refs that
  269        *        are to be merged into the original descriptor
  270        */
  271       protected final void mergeResourceReferences(WebXml theWebXml)
  272       {
  273           int count = insertElements(theWebXml, WebXmlTag.RESOURCE_REF);
  274           if (count > 0)
  275           {
  276               this.log.trace("Merged " + count + " resource reference"
  277                   + (count != 1 ? "s " : " ") + "into the descriptor");
  278           }
  279       }
  280   
  281       /**
  282        * Merges the 
  283        * 
  284        * @param theWebXml The descriptor that contains the security constraints
  285        *        that are to be merged into the original descriptor
  286        */
  287       protected final void mergeSecurityConstraints(WebXml theWebXml)
  288       {
  289           int count = insertElements(theWebXml, WebXmlTag.SECURITY_CONSTRAINT);
  290           if (count > 0)
  291           {
  292               this.log.trace("Merged " + count + " security constraint"
  293                   + (count != 1 ? "s " : " ") + "into the descriptor");
  294           }
  295       }
  296   
  297       /**
  298        * Merges the login configuration from the provided descriptor into the
  299        * original descriptor, thereby eventually replacing the existing login 
  300        * config.
  301        * 
  302        * @param theWebXml The descriptor that contains the login config that
  303        *        is to be merged into the original descriptor
  304        */
  305       protected final void mergeLoginConfig(WebXml theWebXml)
  306       {
  307           boolean replaced = replaceElement(theWebXml, WebXmlTag.LOGIN_CONFIG);
  308           if (replaced)
  309           {
  310               this.log.trace(
  311                   "Merged the login configuration into the descriptor");
  312           }
  313       }
  314   
  315       /**
  316        * Merges the security roles from the provided descriptor into the original
  317        * descriptor.
  318        * 
  319        * @param theWebXml The descriptor that contains the security roles that
  320        *        are to be merged into the original descriptor
  321        */
  322       protected final void mergeSecurityRoles(WebXml theWebXml)
  323       {
  324           Iterator securityRoleNames = theWebXml.getSecurityRoleNames();
  325           int count = 0;
  326           while (securityRoleNames.hasNext())
  327           {
  328               String securityRoleName = (String) securityRoleNames.next();
  329               if (!this.webXml.hasSecurityRole(securityRoleName))
  330               {
  331                   this.webXml.addSecurityRole(securityRoleName);
  332               }
  333           }
  334           if (count > 0)
  335           {
  336               this.log.trace("Merged " + count + " security role"
  337                   + (count != 1 ? "s " : " ") + "into the descriptor");
  338           }
  339       }
  340   
  341       /**
  342        * Merges the environment entries from the provided descriptor into the
  343        * original descriptor.
  344        * 
  345        * @param theWebXml The descriptor that contains the environment entries
  346        *        that are to be merged into the original descriptor
  347        */
  348       protected final void mergeEnvironmentEntries(WebXml theWebXml)
  349       {
  350           int count = insertElements(theWebXml, WebXmlTag.ENV_ENTRY);
  351           if (count > 0)
  352           {
  353               this.log.trace("Merged " + count + " environment entr"
  354                   + (count != 1 ? "ies " : "y ") + "into the descriptor");
  355           }
  356       }
  357   
  358       /**
  359        * Merges the EJB references from the provided descriptor into the original
  360        * descriptor.
  361        * 
  362        * @param theWebXml The descriptor that contains the EJB refs that are to be
  363        *        merged into the original descriptor
  364        */
  365       protected final void mergeEjbRefs(WebXml theWebXml)
  366       {
  367           int count = insertElements(theWebXml, WebXmlTag.EJB_REF);
  368           if (count > 0)
  369           {
  370               this.log.trace("Merged " + count + " EJB reference"
  371                   + (count != 1 ? "s " : "y ") + "into the descriptor");
  372           }
  373       }
  374   
  375       /**
  376        * Merges the EJB local references from the provided descriptor into the
  377        * original descriptor.
  378        * 
  379        * @param theWebXml The descriptor that contains the EJB local refs that are
  380        *        to be merged into the original descriptor
  381        */
  382       protected final void mergeEjbLocalRefs(WebXml theWebXml)
  383       {
  384           int count = insertElements(theWebXml, WebXmlTag.EJB_LOCAL_REF);
  385           if (count > 0)
  386           {
  387               this.log.trace("Merged " + count + " EJB local reference"
  388                   + (count != 1 ? "s " : "y ") + "into the descriptor");
  389           }
  390       }
  391   
  392       // Private Methods ---------------------------------------------------------
  393   
  394       /**
  395        * Insert all elements of the specified tag from the given descriptor into
  396        * the original descriptor, and returns the number of elements that were
  397        * added.
  398        * 
  399        * @param theWebXml The descriptor that contains the elements that are to be
  400        *        merged into the original descriptor
  401        * @param theTag Defines which elements will get merged
  402        * @return The number of elements inserted into the original descriptor
  403        */
  404       private int insertElements(WebXml theWebXml, WebXmlTag theTag)
  405       {
  406           Iterator elements = theWebXml.getElements(theTag);
  407           int count = 0;
  408           while (elements.hasNext())
  409           {
  410               Element element = (Element) elements.next();
  411               webXml.addElement(theTag, element);
  412               count++;
  413           }
  414           return count;
  415       }
  416   
  417       /**
  418        * Replaces the element of the specified tag in the original descriptor with
  419        * the equivalent element in the specified descriptor.
  420        * 
  421        * @param theWebXml The descriptor that contains the element that is to be
  422        *        added to the original descriptor, replacing the original
  423        *        definition
  424        * @param theTag Defines which element will get replaced
  425        * @return Whether the element was replaced
  426        */
  427       private boolean replaceElement(WebXml theWebXml, WebXmlTag theTag)
  428       {
  429           Iterator elements = theWebXml.getElements(theTag);
  430           if (elements.hasNext())
  431           {
  432               webXml.replaceElement(theTag, (Element) elements.next());
  433               return true;
  434           }
  435           return false;
  436       }
  437   
  438   }

Save This Page
Home » cactus-1.8.0-src » org.apache.cactus.integration.ant.deployment.webapp » [javadoc | source]