Greetings.
I wrote a custom class for this, as I found that the standard merges that I tried did
not work. The parser for the Web.xml file is Order-Sensitive for the elements. For
your convenience, I have
posted a copy of the class that I am using.
NOTE: This class triggers JBoss Patch#537795/Jetty Patch#573842.
-Steve
--
Java Developer
Looking for a new job opportunity
214-724-7741
/*
* MergeWebXML.java
*
* Created on March 15, 2002, 3:38 PM
*/
package com.hrnexus;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.jdom.Document;
import org.jdom.DocType;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import com.hrnexus.common.shared.ParameterProcessor;
/**
*
* @author Stephen Davidson
*/
public class MergeWebXML {
private final static boolean DEBUG = true;
protected static final SAXBuilder builder = new SAXBuilder();
protected static final ParameterProcessor proc = new ParameterProcessor("server");
protected static final XMLOutputter outputter;
private final static String IGNORE_SECTION_TOKEN = new String();
protected final JspFilter jspFilter;
private String jspBuildDir;
private String jspXmlFile;
static{
outputter = new XMLOutputter(" ", true); //Indent 3 spaces, Newlines = true;
outputter.setLineSeparator(System.getProperty("line.separator"));
outputter.setOmitEncoding(false);
outputter.setOmitDeclaration(false);
outputter.setTextTrim(true);
outputter.setTextNormalize(true);
}
/** Creates a new instance of MergeWebXML */
public MergeWebXML(final String[] args) {
for(int idx = 0; idx < args.length;idx++){
if (args[idx].equals("-b")){
jspBuildDir = args[++idx];
idx++;
}
if (args[idx].equals("-f")){
jspXmlFile = args[++idx];
//idx++; //If more parameters are added, uncomment this.
//Last Parameter should not increment, as for-loop does to prevent
//infinite looping.
}
}
if (jspXmlFile == null)
throw new NullPointerException("Must set parameter -f");
//initialize builder
jspFilter = new JspFilter("Importer");
}
private void execute(){
FileOutputStream outStream = null;
try{
//Load default web.xml file (Read/Write)
File fWebXml = new File(proc.get("SourceDirectory"), "loadbuild/web.xml");
if (DEBUG){
System.out.println(fWebXml.getAbsolutePath());
byte[] b = new byte[8196];
int read;
java.io.BufferedInputStream bStream = new
java.io.BufferedInputStream(new java.io.FileInputStream(fWebXml));
while ((read = bStream.read(b)) >= 0){
System.out.write(b, 0, read);
}
bStream.close();
}
final Document hrxWebXml = builder.build(fWebXml);
//Load generated webxml.xml file (Read Only)
final File fJspWebXml = new File(jspBuildDir, jspXmlFile);
final Document jspWebXML = builder.build(fJspWebXml);
//merge
//SPDBUG: The Web.XML file is ORDER SENSITIVE! The following is not
viable!
final Element rootHRX_XML = hrxWebXml.getRootElement();
final Element rootJspWebXML = jspWebXML.getRootElement();
// final List jspElements = rootJspWebXML.getChildren();
final Element rootWebXML = new Element("web-app");
//Add <servlet> section
final Iterator itHRX = rootHRX_XML.getChildren().iterator();
final Element firstServletMapping = loadXMLSection(itHRX, rootWebXML,
"servlet", null);
loadXMLSection(rootJspWebXML.getChildren("servlet").iterator(),
rootWebXML, "servlet", null); //This should return
null
//Add <servlet-mapping> section
final Element elementHandle = loadXMLSection(itHRX, rootWebXML,
"servlet-mapping", firstServletMapping);
loadXMLSection(rootJspWebXML.getChildren("servlet-mapping").iterator(),
rootWebXML, "servlet-mapping", null); //This should
return null
//Add rest of HRX web.xml
loadXMLSection(itHRX, rootWebXML, IGNORE_SECTION_TOKEN, elementHandle);
//save
if (DEBUG){
System.out.println("Merged XML File::::::");
outputter.output(rootWebXML, System.out);
}
final File outFile = new File(jspBuildDir, "web.xml");
outStream = new FileOutputStream(outFile);
DocType docType = hrxWebXml.getDocType();
if ( docType != null ){
docType = (DocType)docType.clone();
}
final Document webXml = new Document(rootWebXML, docType);
outputter.output(webXml, outStream);
}
catch (JDOMException e){
e.printStackTrace();
throw new RuntimeException();
}
catch(java.io.FileNotFoundException e){
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
catch(java.io.IOException e){
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
finally{
if (outStream != null){
try{
outStream.flush();
}catch(IOException e){e.printStackTrace();}
try{
outStream.close();
}catch(IOException e){e.printStackTrace();}
}
}
}
private Element loadXMLSection(final Iterator it, final Element rootElement,
final String elementName, final Element firstElement){
if ( (it == null) || (rootElement == null) || (elementName == null))
throw new IllegalArgumentException("Nulls not allowed! Iterator = " + it
+ " rootElement = " + rootElement + " String elementName = " +
elementName);
if (firstElement != null)
rootElement.addContent(firstElement);
Element lastElement = null;
try{
do{
final Element webElement = (Element) it.next();
//Make copy for new page
lastElement = (Element)webElement.clone();
if ( (elementName == IGNORE_SECTION_TOKEN)
|| elementName.equals(lastElement.getName())){
//Is Element "Proscribed?"
if (jspFilter.canAdd(lastElement)){
//Add to new page.
rootElement.addContent(lastElement);
}
}
else{
break;
}
} while(true);
}
catch(java.util.NoSuchElementException e){
//Overran list
}
//SPDBUG: JDom b8 is throwing this instead!
catch(IllegalStateException e){
//Overran list
}
return(lastElement);
}
public static void usage(){
System.out.println("Usage: com.hrnexus.MergeWebXML -d <jspBuildDir> -f
<jspWebXMLFile>");
}
public static void main(final String[] args){
if ((args == null) || (args.length < 1 )){
usage();
return;
}
//else
MergeWebXML merger = new MergeWebXML(args);
merger.execute();
}
//******************************************************************************
//Private Helper classes
//******************************************************************************
//The following class filters out all classes from the supplied directory.
//TODO: Enhance JspFilter to take a list of directories to exclude?
private class JspFilter extends org.jdom.filter.ElementFilter
{
final protected String jspName;
public JspFilter(final String jspName){
this.jspName = jspName;
};
public JspFilter(final String jspName, final String name){
super(name);
this.jspName = jspName;
};
public JspFilter(final String jspName, final String name, org.jdom.Namespace
namespace){
super(name, namespace);
this.jspName = jspName;
};
public boolean canAdd(final Object obj)
{
try{
final Element currentElement = (Element)obj;
final String servletName = currentElement.getChildText("servlet-name");
if ((servletName != null) && (servletName.startsWith(jspName))){
return(false);
}
} catch (ClassCastException e){}; //Not Element, so let super class handle
object
//default case
return(super.canAdd(obj));
}
}
}