cmlenz 2003/03/14 09:12:25
Added: integration/ant/src/java/org/apache/cactus/integration/ant/webxml
WebXmlMerger.java WebXmlElement.java WebXml.java
integration/ant/src/java/org/apache/cactus/integration/ant
WebXmlMergeTask.java
Log:
First cut of a <webxmlmerge> task, with very much the same goals as
Vincent's <webmerge> task. The good thing about this variant is that
it requires much more code to offer less features ;-)
But seriously: this task merges servlet and filter definitions from two
web deployment descriptors into a single descriptor. It takes the servlet
version into account, and will not add the same servlet/filter twice. It
can also merge the init-params of a servlet or filter that already exists
in the original descriptor, although uniqueness of parameters is
currently not checked.
The major increase in lines of code is because the task is more intelligent
about the descriptor, i.e. it knows the concepts of filters and servlets.
However, I really need to cut the code amount because there's currently
much duplication between the handling of filters and servlets.
This task uses the Ant <xmlcatalog> type to provide offline capabilities,
which I believe to be cleaner than the NoopResolver. It does not yet
merge stuff like <login-config> and <security-constraint>. I could go on,
but...
Revision Changes Path
1.1
jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/webxml/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 [EMAIL PROTECTED]
*
* 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.webxml;
import java.util.Iterator;
/**
* Helper class that can merge two web deployment descriptors.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Christopher Lenz</a>
*
* @version $Id: WebXmlMerger.java,v 1.1 2003/03/14 17:12:24 cmlenz Exp $
*/
public class WebXmlMerger
{
/**
* The original, authorative descriptor onto which the merges are performed.
*/
private WebXml webXml;
/**
* Constructor.
*
* @param theWebXml The original descriptor
*/
public WebXmlMerger(WebXml theWebXml)
{
this.webXml = theWebXml;
}
/**
* 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
* @return The number of filters merged into the original descriptor
*/
public int 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++;
}
return count;
}
/**
* 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
* @return The number of servlet merged into the original descriptor
*/
public int 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++;
}
return count;
}
}
1.1
jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/webxml/WebXmlElement.java
Index: WebXmlElement.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 [EMAIL PROTECTED]
*
* 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.webxml;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Class that knows about the names and order of the top-level elements in a web
* deployment descriptor.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Christopher Lenz</a>
*
* @version $Id: WebXmlElement.java,v 1.1 2003/03/14 17:12:24 cmlenz Exp $
*/
public class WebXmlElement
{
// Public Constants --------------------------------------------------------
/**
* Element name 'web-app'.
*/
public static final String WEB_APP = "web-app";
/**
* Element name 'icon'.
*/
public static final String ICON = "web-app";
/**
* Element name 'display-name'.
*/
public static final String DISPLAY_NAME = "display-name";
/**
* Element name 'description'.
*/
public static final String DESCRIPTION = "description";
/**
* Element name 'distributable'.
*/
public static final String DISTRIBUTABLE = "distributable";
/**
* Element name 'context-param'.
*/
public static final String CONTEXT_PARAM = "context-param";
/**
* Element name 'param-name'.
*/
public static final String PARAM_NAME = "param-name";
/**
* Element name 'param-value'.
*/
public static final String PARAM_VALUE = "param-value";
/**
* Element name 'filter'.
*/
public static final String FILTER = "filter";
/**
* Element name 'filter-name'.
*/
public static final String FILTER_NAME = "filter-name";
/**
* Element name 'filter-class'.
*/
public static final String FILTER_CLASS = "filter-class";
/**
* Element name 'filter-mapping'.
*/
public static final String FILTER_MAPPING = "filter-mapping";
/**
* Element name 'init-param'.
*/
public static final String INIT_PARAM = "init-param";
/**
* Element name 'listener'.
*/
public static final String LISTENER = "listener";
/**
* Element name 'servlet',
*/
public static final String SERVLET = "servlet";
/**
* Element name 'servlet-name',
*/
public static final String SERVLET_NAME = "servlet-name";
/**
* Element name 'jsp-file'.
*/
public static final String JSP_FILE = "jsp-file";
/**
* Element name 'servlet-class'.
*/
public static final String SERVLET_CLASS = "servlet-class";
/**
* Element name 'servlet-mapping',
*/
public static final String SERVLET_MAPPING = "servlet-mapping";
/**
* Element name 'url-pattern',
*/
public static final String URL_PATTERN = "url-pattern";
/**
* Element name 'session-config',
*/
public static final String SESSION_CONFIG = "session-config";
/**
* Element name 'mime-mapping',
*/
public static final String MIME_MAPPING = "mime-mapping";
/**
* Element name 'welcome-file-list',
*/
public static final String WELCOME_FILE_LIST = "welcome-file-list";
/**
* Element name 'error-page',
*/
public static final String ERROR_PAGE = "error-page";
/**
* Element name 'taglib',
*/
public static final String TAGLIB = "taglib";
/**
* Element name 'resource-env-ref',
*/
public static final String RESOURCE_ENV_REF = "resource-env-ref";
/**
* Element name 'resource-ref',
*/
public static final String RESOURCE_REF = "resource-ref";
/**
* Element name 'security-constraint',
*/
public static final String SECURITY_CONSTRAINT = "security-constraint";
/**
* Element name 'login-config',
*/
public static final String LOGIN_CONFIG = "login-config";
/**
* Element name 'security-role',
*/
public static final String SECURITY_ROLE = "security-role";
/**
* Element name 'env-entry',
*/
public static final String ENV_ENTRY = "env-entry";
/**
* Element name 'ejb-ref',
*/
public static final String EJB_REF = "ejb-ref";
/**
* Element name 'ejb-local-ref',
*/
public static final String EJB_LOCAL_REF = "ejb-local-ref";
// Private Constants -------------------------------------------------------
/**
* Specifies the order in which the top-level elements must appear in the
* descriptor, according to the DTD.
*/
private static final String[] ELEMENT_ORDER = {
WebXmlElement.ICON,
WebXmlElement.DISPLAY_NAME,
WebXmlElement.DESCRIPTION,
WebXmlElement.DISTRIBUTABLE,
WebXmlElement.FILTER,
WebXmlElement.FILTER_MAPPING,
WebXmlElement.LISTENER,
WebXmlElement.SERVLET,
WebXmlElement.SERVLET_MAPPING,
WebXmlElement.SESSION_CONFIG,
WebXmlElement.MIME_MAPPING,
WebXmlElement.WELCOME_FILE_LIST,
WebXmlElement.ERROR_PAGE,
WebXmlElement.TAGLIB,
WebXmlElement.RESOURCE_ENV_REF,
WebXmlElement.RESOURCE_REF,
WebXmlElement.SECURITY_CONSTRAINT,
WebXmlElement.LOGIN_CONFIG,
WebXmlElement.SECURITY_ROLE,
WebXmlElement.ENV_ENTRY,
WebXmlElement.EJB_REF,
WebXmlElement.EJB_LOCAL_REF,
};
// Public Static Methods ---------------------------------------------------
/**
* Creates a filter-mapping element initialized with the filter name and
* class.
*
* @param theDocument The document for which the element should be created
* @param theFilterName The name of the filter
* @param theUrlPattern The URL-pattern to map the filter to
* @return A DOM element representing the filter definition
*/
public static Element createFilterMapping(Document theDocument,
String theFilterName, String theUrlPattern)
{
Element filterMappingElement =
theDocument.createElement(WebXmlElement.FILTER_MAPPING);
filterMappingElement.appendChild(
createNestedText(theDocument, FILTER_NAME, theFilterName));
filterMappingElement.appendChild(
createNestedText(theDocument, URL_PATTERN, theUrlPattern));
return filterMappingElement;
}
/**
* Creates an init-param element initialized with the parameter name and
* value.
*
* @param theDocument The document for which the element should be created
* @param theParamName The name of the parameter
* @param theParamValue The parameter value
* @return A DOM element representing the parameter definition
*/
public static Element createInitParam(Document theDocument,
String theParamName, String theParamValue)
{
Element initParamElement =
theDocument.createElement(WebXmlElement.INIT_PARAM);
initParamElement.appendChild(
createNestedText(theDocument, PARAM_NAME, theParamName));
initParamElement.appendChild(
createNestedText(theDocument, PARAM_VALUE, theParamValue));
return initParamElement;
}
/**
* Creates a servlet-mapping element initialized with the servlet name and
* class.
*
* @param theDocument The document for which the element should be created
* @param theServletName The name of the servlet
* @param theUrlPattern The URL-pattern to map the servlet to
* @return A DOM element representing the servlet definition
*/
public static Element createServletMapping(Document theDocument,
String theServletName, String theUrlPattern)
{
Element servletMappingElement =
theDocument.createElement(WebXmlElement.SERVLET_MAPPING);
servletMappingElement.appendChild(
createNestedText(theDocument, SERVLET_NAME, theServletName));
servletMappingElement.appendChild(
createNestedText(theDocument, URL_PATTERN, theUrlPattern));
return servletMappingElement;
}
/**
* Finds and returns the node before which a new element of the specified
* name should be inserted.
*
* @param theDocument The DOM representation of the descriptor
* @param theTagName The name of the element that is to be inserted
* @return The node before which the element should be inserted, or
* <code>null</code> if the element should be appended to the end
*/
public static Node getNodeToInsertBefore(Document theDocument,
String theTagName)
{
Element root = theDocument.getDocumentElement();
for (int i = 0; i < ELEMENT_ORDER.length; i++)
{
if (ELEMENT_ORDER[i].equals(theTagName))
{
for (int j = i + 1; j < ELEMENT_ORDER.length; j++)
{
NodeList elements =
root.getElementsByTagName(ELEMENT_ORDER[j]);
if (elements.getLength() > 0)
{
return elements.item(0);
}
}
break;
}
}
return null;
}
// Private Static Methods --------------------------------------------------
/**
* Creates an element that contains nested text.
*
* @param theDocument The document for which the element should be created
* @param theTagName The name of the element to create
* @param theText The text that should be nested in the element
* @return The DOM element
*/
private static Element createNestedText(Document theDocument,
String theTagName, String theText)
{
Element element = theDocument.createElement(theTagName);
element.appendChild(theDocument.createTextNode(theText));
return element;
}
}
1.1
jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/webxml/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 [EMAIL PROTECTED]
*
* 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.webxml;
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:[EMAIL PROTECTED]">Christopher Lenz</a>
*
* @version $Id: WebXml.java,v 1.1 2003/03/14 17:12:24 cmlenz Exp $
*/
public class WebXml
{
// Public Constants --------------------------------------------------------
/**
* Servlet API version 2.2.
*/
public static final String SERVLET_VERSION_2_2 = "2.2";
/**
* Servlet API version 2.3.
*/
public static final String SERVLET_VERSION_2_3 = "2.3";
// Private Constants -------------------------------------------------------
/**
* Public ID of the web-app DTD of Servlet API version 2.2.
*/
private static final String WEB_APP_2_2_PUBLIC_ID =
"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN";
/**
* Public ID of the web-app DTD of Servlet API version 2.3.
*/
private static final String WEB_APP_2_3_PUBLIC_ID =
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN";
// 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 Document getDocument()
{
return document;
}
/**
* Returns the servlet API version, one of [EMAIL PROTECTED]
#SERVLET_VERSION_2_2} and
* [EMAIL PROTECTED] #SERVLET_VERSION_2_3}.
*
* @return The servlet API version.
*/
public String getVersion()
{
DocumentType docType = document.getDoctype();
if (docType != null)
{
String publicId = docType.getPublicId();
if (WEB_APP_2_2_PUBLIC_ID.equals(publicId))
{
return SERVLET_VERSION_2_2;
}
else if (WEB_APP_2_3_PUBLIC_ID.equals(publicId))
{
return SERVLET_VERSION_2_3;
}
}
return null;
}
/**
* Adds a new servlet filter to the descriptor.
*
* @param theFilterElement The element representing the filter definition
*/
public void addFilter(Element theFilterElement)
{
String filterName =
getNestedText(theFilterElement, WebXmlElement.FILTER_NAME);
if (filterName == null)
{
throw new IllegalArgumentException("Not a valid filter element");
}
if (hasFilter(filterName))
{
throw new IllegalStateException("Filter '" + filterName +
"' already defined");
}
Node importedNode = document.importNode(theFilterElement, true);
Node refNode = WebXmlElement.getNodeToInsertBefore(
document, WebXmlElement.FILTER);
rootElement.insertBefore(importedNode, refNode);
}
/**
* 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 void addFilterInitParam(String theFilterName, String theParamName,
String theParamValue)
{
Element filterElement = getFilter(theFilterName);
if (filterElement == null)
{
throw new IllegalStateException("Filter '" + theFilterName +
"' not defined");
}
Element initParamElement = WebXmlElement.createInitParam(
document, theParamName, theParamValue);
filterElement.appendChild(initParamElement);
}
/**
* 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 void addFilterMapping(String theFilterName, String theUrlPattern)
{
if (!hasFilter(theFilterName))
{
throw new IllegalStateException("Filter '" + theFilterName +
"' not defined");
}
Element filterMappingElement = WebXmlElement.createFilterMapping(
document, theFilterName, theUrlPattern);
Node refNode = WebXmlElement.getNodeToInsertBefore(
document, WebXmlElement.FILTER_MAPPING);
rootElement.insertBefore(filterMappingElement, refNode);
}
/**
* Removes a servlet filter from the descriptor.
*
* @param theFilterName The name of the filter to remove
* @return The removed element, or <code>null</code> if the specified filter
* was not defined
*/
public Element removeFilter(String theFilterName)
{
Element filterElement = getFilter(theFilterName);
if (filterElement != null)
{
filterElement.getParentNode().removeChild(filterElement);
}
return filterElement;
}
/**
* 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 Element getFilter(String theFilterName)
{
if (theFilterName == null)
{
throw new NullPointerException();
}
NodeList filterElements =
rootElement.getElementsByTagName(WebXmlElement.FILTER);
for (int i = 0; i < filterElements.getLength(); i++)
{
Element filterElement = (Element) filterElements.item(i);
if (theFilterName.equals(getNestedText(
filterElement, WebXmlElement.FILTER_NAME)))
{
return filterElement;
}
}
return null;
}
/**
* 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 String getFilterInitParam(String theFilterName, String theParamName)
{
Element filterElement = getFilter(theFilterName);
if (filterElement != null)
{
NodeList initParamElements =
filterElement.getElementsByTagName(WebXmlElement.INIT_PARAM);
for (int i = 0; i < initParamElements.getLength(); i++)
{
Element initParamElement = (Element) initParamElements.item(i);
String paramName = getNestedText(
initParamElement, WebXmlElement.PARAM_NAME);
if (theParamName.equals(paramName))
{
return getNestedText(
initParamElement, WebXmlElement.PARAM_VALUE);
}
}
}
return null;
}
/**
* 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 Iterator getFilterInitParamNames(String theFilterName)
{
List initParamNames = new ArrayList();
Element filterElement = getFilter(theFilterName);
if (filterElement != null)
{
NodeList initParamElements =
filterElement.getElementsByTagName(WebXmlElement.INIT_PARAM);
for (int i = 0; i < initParamElements.getLength(); i++)
{
Element initParamElement = (Element) initParamElements.item(i);
String paramName = getNestedText(
initParamElement, WebXmlElement.PARAM_NAME);
if (paramName != null)
{
initParamNames.add(paramName);
}
}
}
return initParamNames.iterator();
}
/**
* 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 Iterator getFilterMappings(String theFilterName)
{
if (theFilterName == null)
{
throw new NullPointerException();
}
List filterMappings = new ArrayList();
NodeList filterMappingElements =
rootElement.getElementsByTagName(WebXmlElement.FILTER_MAPPING);
for (int i = 0; i < filterMappingElements.getLength(); i++)
{
Element filterMappingElement = (Element)
filterMappingElements.item(i);
if (theFilterName.equals(getNestedText(
filterMappingElement, WebXmlElement.FILTER_NAME)))
{
String urlPattern = getNestedText(
filterMappingElement, WebXmlElement.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 Iterator getFilterNames()
{
List filterNames = new ArrayList();
NodeList filterElements =
rootElement.getElementsByTagName(WebXmlElement.FILTER);
for (int i = 0; i < filterElements.getLength(); i++)
{
Element filterElement = (Element) filterElements.item(i);
String filterName =
getNestedText(filterElement, WebXmlElement.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 boolean hasFilter(String theFilterName)
{
return (getFilter(theFilterName) != null);
}
/**
* Adds a new servlet to the descriptor.
*
* @param theServletElement The element representing the servlet definition
*/
public void addServlet(Element theServletElement)
{
String servletName =
getNestedText(theServletElement, WebXmlElement.SERVLET_NAME);
if (servletName == null)
{
throw new IllegalArgumentException("Not a valid servlet element");
}
if (hasServlet(servletName))
{
throw new IllegalStateException("Servlet '" + servletName +
"' already defined");
}
Node importedNode = document.importNode(theServletElement, true);
Node refNode = WebXmlElement.getNodeToInsertBefore(
document, WebXmlElement.SERVLET);
rootElement.insertBefore(importedNode, refNode);
}
/**
* 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 void addServletMapping(String theServletName, String theUrlPattern)
{
if (!hasServlet(theServletName))
{
throw new IllegalStateException("Servlet '" + theServletName +
"' not defined");
}
Element servletMappingElement = WebXmlElement.createServletMapping(
document, theServletName, theUrlPattern);
Node refNode = WebXmlElement.getNodeToInsertBefore(
document, WebXmlElement.SERVLET_MAPPING);
rootElement.insertBefore(servletMappingElement, refNode);
}
/**
* 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 void addServletInitParam(String theServletName, String theParamName,
String theParamValue)
{
Element servletElement = getServlet(theServletName);
if (servletElement == null)
{
throw new IllegalStateException("Servlet '" + theServletName +
"' not defined");
}
Element initParamElement = WebXmlElement.createInitParam(
document, theParamName, theParamValue);
servletElement.appendChild(initParamElement);
}
/**
* Removes a servlet from the descriptor.
*
* @param theServletName The name of the servlet to remove
* @return The removed element, or <code>null</code> if the servlet was not
* defined
*/
public Element removeServlet(String theServletName)
{
Element servletElement = getServlet(theServletName);
if (servletElement != null)
{
servletElement.getParentNode().removeChild(servletElement);
}
return servletElement;
}
/**
* 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 Element getServlet(String theServletName)
{
if (theServletName == null)
{
throw new NullPointerException();
}
NodeList servletElements =
rootElement.getElementsByTagName(WebXmlElement.SERVLET);
for (int i = 0; i < servletElements.getLength(); i++)
{
Element servletElement = (Element) servletElements.item(i);
if (theServletName.equals(getNestedText(
servletElement, WebXmlElement.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 String getServletInitParam(String theServletName,
String theParamName)
{
Element servletElement = getServlet(theServletName);
if (servletElement != null)
{
NodeList initParamElements =
servletElement.getElementsByTagName(WebXmlElement.INIT_PARAM);
for (int i = 0; i < initParamElements.getLength(); i++)
{
Element initParamElement = (Element) initParamElements.item(i);
String paramName = getNestedText(
initParamElement, WebXmlElement.PARAM_NAME);
if (theParamName.equals(paramName))
{
return getNestedText(
initParamElement, WebXmlElement.PARAM_VALUE);
}
}
}
return null;
}
/**
* 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 Iterator getServletInitParamNames(String theServletName)
{
List initParamNames = new ArrayList();
Element servletElement = getServlet(theServletName);
if (servletElement != null)
{
NodeList initParamElements =
servletElement.getElementsByTagName(WebXmlElement.INIT_PARAM);
for (int i = 0; i < initParamElements.getLength(); i++)
{
Element initParamElement = (Element) initParamElements.item(i);
String paramName = getNestedText(
initParamElement, WebXmlElement.PARAM_NAME);
if (paramName != null)
{
initParamNames.add(paramName);
}
}
}
return initParamNames.iterator();
}
/**
* 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 Iterator getServletMappings(String theServletName)
{
if (theServletName == null)
{
throw new NullPointerException();
}
List servletMappings = new ArrayList();
NodeList servletMappingElements =
rootElement.getElementsByTagName(WebXmlElement.SERVLET_MAPPING);
for (int i = 0; i < servletMappingElements.getLength(); i++)
{
Element servletMappingElement = (Element)
servletMappingElements.item(i);
if (theServletName.equals(getNestedText(
servletMappingElement, WebXmlElement.SERVLET_NAME)))
{
String urlPattern = getNestedText(
servletMappingElement, WebXmlElement.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 Iterator getServletNames()
{
List servletNames = new ArrayList();
NodeList servletElements =
rootElement.getElementsByTagName(WebXmlElement.SERVLET);
for (int i = 0; i < servletElements.getLength(); i++)
{
Element servletElement = (Element) servletElements.item(i);
String servletName =
getNestedText(servletElement, WebXmlElement.SERVLET_NAME);
if (servletName != null)
{
servletNames.add(servletName);
}
}
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 boolean hasServlet(String theServletName)
{
return (getServlet(theServletName) != null);
}
// Private Methods ---------------------------------------------------------
/**
*
* @param theElement The element of which the nested text should be
* returned
* @param theTagName The name of the child element that contains the text
* @return The text nested in the element
*/
private String getNestedText(Element theElement, String theTagName)
{
NodeList nestedElements = theElement.getElementsByTagName(theTagName);
if (nestedElements.getLength() > 0)
{
Node nestedText = nestedElements.item(0).getFirstChild();
if (nestedText != null)
{
return nestedText.getNodeValue();
}
}
return null;
}
}
1.1
jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/WebXmlMergeTask.java
Index: WebXmlMergeTask.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 [EMAIL PROTECTED]
*
* 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;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.cactus.integration.ant.webxml.WebXml;
import org.apache.cactus.integration.ant.webxml.WebXmlMerger;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.XMLCatalog;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.xml.sax.SAXException;
/**
* Ant task that can merge the definitions from two web deployment descriptors
* into one descriptor.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Christopher Lenz</a>
*
* @version $Id: WebXmlMergeTask.java,v 1.1 2003/03/14 17:12:25 cmlenz Exp $
*/
public class WebXmlMergeTask extends Task
{
// Instance Variables ------------------------------------------------------
/**
* Location of the original <code>web.xml</code>
*/
private File srcFile;
/**
* Location of the overriding <code>web.xml</code>
*/
private File mergeFile;
/**
* Location of the resulting <code>web.xml</code>
*/
private File destFile;
/**
* Whether the resulting XML file should be indented.
*/
private boolean indent = false;
/**
* The encoding of the resulting XML file.
*/
private String encoding;
/**
* For resolving entities such as DTDs.
*/
private XMLCatalog xmlCatalog = new XMLCatalog();
/**
* The factory for JAXP document builders.
*/
private DocumentBuilderFactory factory;
// Public Methods ----------------------------------------------------------
/**
* @see org.apache.tools.ant.Task#init()
*/
public void init() throws BuildException
{
this.factory = DocumentBuilderFactory.newInstance();
this.factory.setValidating(false);
this.factory.setNamespaceAware(false);
this.xmlCatalog.setProject(project);
}
/**
* @see Task#execute()
*/
public void execute() throws BuildException
{
if (this.srcFile == null)
{
throw new BuildException("The [srcfile] attribute is required");
}
if (this.destFile == null)
{
throw new BuildException("The [destfile] attribute is required");
}
// FIXME: Skip merge if destfile newer than srcfile and mergefile
try
{
WebXml srcWebXml = parseWebXml(this.srcFile);
if (this.mergeFile != null)
{
WebXml mergeWebXml = parseWebXml(this.mergeFile);
checkServletVersions(srcWebXml, mergeWebXml);
merge(srcWebXml, mergeWebXml);
}
writeWebXml(srcWebXml, this.destFile);
}
catch (ParserConfigurationException pce)
{
throw new BuildException("XML parser configuration problem", pce);
}
catch (IOException ioe)
{
throw new BuildException("An I/O error occurred", ioe);
}
}
/**
* Adds an XML catalog to the internal catalog.
*
* @param theXmlCatalog the XMLCatalog instance to use to look up DTDs
*/
public void addConfiguredXMLCatalog(XMLCatalog theXmlCatalog)
{
this.xmlCatalog.addConfiguredXMLCatalog(theXmlCatalog);
}
/**
* The original web deployment descriptor into which the new elements will
* be merged.
*
* @param theSrcFile the original <code>web.xml</code>
*/
public void setSrcFile(File theSrcFile)
{
this.srcFile = theSrcFile;
}
/**
* The descriptor to merge into the original file.
*
* @param theMergeFile the <code>web.xml</code> to merge
*/
public void setMergeFile(File theMergeFile)
{
this.mergeFile = theMergeFile;
}
/**
* The destination file where the result of the merge are stored.
*
* @param theDestFile the resulting <code>web.xml</code>
*/
public void setDestFile(File theDestFile)
{
this.destFile = theDestFile;
}
/**
* Sets the encoding of the resulting XML file. Default is 'UTF-8'.
*
* @param theEncoding The encoding to set
*/
public void setEncoding(String theEncoding)
{
this.encoding = theEncoding;
}
/**
* Whether the result XML file should be indented for better readability.
* Default is 'false'.
*
* @param theIndent Whether the result should be indented
*/
public void setIndent(boolean theIndent)
{
this.indent = theIndent;
}
// Private Methods ---------------------------------------------------------
/**
* Checks the versions of the servlet API in each descriptor, and logs
* warnings if a mismatch might result in loss of definitions.
*
* @param theSrcWebXml The source descriptor
* @param theMergeWebXml The descriptor to merge
* @throws BuildException If the versions are incompatible
*/
private void checkServletVersions(WebXml theSrcWebXml,
WebXml theMergeWebXml) throws BuildException
{
String srcVersion = theSrcWebXml.getVersion();
String mergeVersion = theMergeWebXml.getVersion();
if (srcVersion != mergeVersion)
{
if (WebXml.SERVLET_VERSION_2_2.equals(srcVersion) &&
WebXml.SERVLET_VERSION_2_3.equals(mergeVersion))
{
log("Merging elements from a version 2.3 into a version 2.2 "
+ "descriptor, some elements may be skipped");
}
}
}
/**
* Merges the merge descriptor with the original descriptor.
*
* @param theSrcWebXml The original descriptor
* @param theMergeWebXml The descriptor to merge in
* @throws BuildException If the operation fails
*/
private void merge(WebXml theSrcWebXml, WebXml theMergeWebXml)
{
WebXmlMerger merger = new WebXmlMerger(theSrcWebXml);
if (WebXml.SERVLET_VERSION_2_3.equals(theSrcWebXml.getVersion()))
{
int filtersMerged = merger.mergeFilters(theMergeWebXml);
if (filtersMerged > 0)
{
log("Merged " + filtersMerged + " filter definitions into the "
+ "descriptor", Project.MSG_INFO);
}
}
int servletsMerged = merger.mergeServlets(theMergeWebXml);
if (servletsMerged > 0)
{
log("Merged " + servletsMerged + " servlet definitions into the "
+ "descriptor", Project.MSG_INFO);
}
}
/**
* Parses a deployment descriptor.
*
* @param theFile The file to parse
* @return The parsed document
* @throws BuildException 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
*/
private WebXml parseWebXml(File theFile)
throws BuildException, ParserConfigurationException, IOException
{
FileInputStream in = null;
try
{
log("Parsing file [" + theFile + "]", Project.MSG_VERBOSE);
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(this.xmlCatalog);
in = new FileInputStream(theFile);
return new WebXml(builder.parse(in));
}
catch (SAXException saxe)
{
throw new BuildException("Error parsing file ["
+ theFile + "]: " + saxe.getMessage(), saxe);
}
finally
{
if (in != null)
{
try
{
in.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 theFile The file to write to
* @throws IOException If an I/O error occurs
*/
protected void writeWebXml(WebXml theWebXml, File theFile)
throws IOException
{
FileOutputStream out = null;
try
{
log("Writing to file [" + theFile + "]", Project.MSG_VERBOSE);
out = new FileOutputStream(theFile);
OutputFormat outputFormat =
new OutputFormat(theWebXml.getDocument());
if (this.encoding != null)
{
outputFormat.setEncoding(this.encoding);
}
outputFormat.setIndenting(this.indent);
outputFormat.setPreserveSpace(false);
XMLSerializer serializer = new XMLSerializer(out, outputFormat);
serializer.serialize(theWebXml.getDocument());
System.out.println();
}
finally
{
if (out != null)
{
try
{
out.close();
}
catch (IOException ioe)
{
// we'll pass on the original IO error, so ignore this one
}
}
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]