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)); } } }