craigmcc 01/02/15 23:14:34 Modified: . build.bat jasper/src/share/org/apache/jasper/compiler TldLocationsCache.java Added: jasper/src/share/org/apache/jasper/parser ParserUtils.java TreeNode.java Log: Stage 1 in making Jasper not require an XML parser in the shared class loader: * Create a separate class ParserUtils that isolates all references to the JAXP APIs. Ultimately, this class will be loaded by a separate classloader (child of the webapp classloader) that will effectively isolate the parser itself. * Create a TreeNode class to represent a DOM element, its associated attributes, and the corresponding child elements. * Modify the parsing routines for web.xml and TLD scanning (for <uri> elements) to use the new parsing utillities. Stage 2 will be modifying org.apache.jasper.compiler.TagLibraryInfoImpl to use the new parsing mechanism as well, as it processes TLD files. Stage 3 (the hardest) will be to deal with parsing JSP files that are using the XML syntax. Revision Changes Path 1.15 +175 -175 jakarta-tomcat-4.0/build.bat Index: build.bat =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/build.bat,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- build.bat 2001/02/01 16:52:53 1.14 +++ build.bat 2001/02/16 07:14:32 1.15 @@ -1,175 +1,175 @@ -@echo off -rem -------------------------------------------------------------------------- -rem build.bat - Build Script for Tomcat -rem -rem Environment Variable Prerequisites: -rem -rem JAVA_HOME Must point at your Java Development Kit [REQUIRED] -rem -rem JAXP_HOME Points at a JAXP compliant XML parser -rem installation directory [NONE] -rem JAXP_PARSER_JAR The jar filename of the JAXP compliant -rem 'XML parser' [crimson.jar] -rem -rem ANT_HOME Must point at your Ant installation [../jakarta-ant] -rem -rem ANT_OPTS Command line options to the Java runtime -rem that executes Ant [NONE] -rem ANT_XML_CLASSPATH -rem Jar files added to the classpath for the XML parsing -rem requirements of ant -rem [%JAXP_HOME%\%JAXP_PARSER_JAR%;%JAXP_HOME%\jaxp.jar] -rem -rem JMX_HOME Must point at your JMX installation [REQUIRED] -rem -rem JNDI_HOME Must point at your JNDI installation [REQUIRED] -rem -rem JSSE_HOME Must point at your JSSE installation [REQUIRED] -rem -rem REGEXP_HOME Must point at your Regexp installation [REQUIRED] -rem -rem SERVLETAPI_HOME Must point at your "jakarta-servletapi" installation. -rem [REQUIRED] -rem -rem CATALINA_JAXP_HOME -rem JAXP 1.0 compliant XML parser installation directory -rem used for catalina [JAXP_HOME] -rem CATALINA_JAXP_PARSER_JAR -rem The jar filename of the JAXP compliant XML parser -rem used for catalina [JAXP_PARSER_JAR] -rem -rem JASPER_JAXP_HOME -rem JAXP 1.1 compliant XML parser installation directory -rem used for jasper [JAXP_HOME] -rem JASPER_JAXP_PARSER_JAR -rem The jar filename of the JAXP compliant XML parser -rem used for jasper [JAXP_PARSER_JAR] -rem -rem $Id: build.bat,v 1.14 2001/02/01 16:52:53 craigmcc Exp $ -rem --------------------------------------------------------------------------- - - -rem ----- Save Environment Variables ------------------------------------------ - -set _CLASSPATH=%CLASSPATH% -set _JAXP_PARSER_JAR=%JAXP_PARSER_JAR% -set _ANT_HOME=%ANT_HOME% -set _ANT_XML_CLASSPATH=%ANT_XML_CLASSPATH% -set _CATALINA_JAXP_HOME=%CATALINA_JAXP_HOME% -set _CATALINA_JAXP_PARSER_JAR=%CATALINA_JAXP_PARSER_JAR% -set _JASPER_JAXP_HOME=%JASPER_JAXP_HOME% -set _JASPER_JAXP_PARSER_JAR=%JASPER_JAXP_PARSER_JAR% - - -rem ----- Verify and Set Required Environment Variables ----------------------- - -if not "%JAVA_HOME%" == "" goto gotJavaHome -echo You must set JAVA_HOME to point at your Java Development Kit installation -goto cleanup -:gotJavaHome - -if not "%JAXP_PARSER_JAR%" == "" goto gotJaxpParserJar -set JAXP_PARSER_JAR=crimson.jar -:gotJaxpParserJar - -if not "%ANT_XML_CLASSPATH%" == "" goto gotAntXmlClasspath -if "%JAXP_HOME%" == "" goto jaxpHome -set ANT_XML_CLASSPATH=%JAXP_HOME%\%JAXP_PARSER_JAR%;%JAXP_HOME%\jaxp.jar -:gotAntXmlClasspath - -if not "%CATALINA_JAXP_HOME%" == "" goto gotCatalinaJaxpHome -if "%JAXP_HOME%" == "" goto jaxpHome -set CATALINA_JAXP_HOME=%JAXP_HOME% -:gotCatalinaJaxpHome - -if not "%CATALINA_JAXP_PARSER_JAR%" == "" goto gotCatalinaJaxpParserJar -set CATALINA_JAXP_PARSER_JAR=%JAXP_PARSER_JAR% -:gotCatalinaJaxpParserJar - -if not "%JASPER_JAXP_HOME%" == "" goto gotJasperJaxpHome -if "%JAXP_HOME%" == "" goto jaxpHome -set JASPER_JAXP_HOME=%JAXP_HOME% -:gotJasperJaxpHome - -if not "%JASPER_JAXP_PARSER_JAR%" == "" goto gotJasperJaxpParserJar -set JASPER_JAXP_PARSER_JAR=%JAXP_PARSER_JAR% -:gotJasperJaxpParserJar - -goto gotJaxpHome - -:jaxpHome -echo You must set JAXP_HOME to point at your XML Parser install directory. -echo By default, ant, catalina, and jasper will use jaxp.jar and crimson.jar from -echo that directory. -echo - A different parser jar file can be specified globally for all -echo components via environment variable JAXP_PARSER_JAR (e.g. xerces.jar). -echo - XML requirements for each component can also be set individually via -echo the following environment variables: -echo ANT_XML_CLASSPATH -echo CATALINA_JAXP_HOME CATALINA_JAXP_PARSER_JAR -echo JASPER_JAXP_HOME JASPER_JAXP_PARSER_JAR -goto cleanup -:gotJaxpHome - -if not "%ANT_HOME%" == "" goto gotAntHome -set ANT_HOME=../jakarta-ant -:gotAntHome - -if not "%JMX_HOME%" == "" goto gotJmxHome -echo You must set JMX_HOME to point at your Java Management Extensions install -goto cleanup -:gotJmxHome - -if not "%JNDI_HOME%" == "" goto gotJndiHome -echo You must set JNDI_HOME to point at your Java Naming and Directory Interface install -goto cleanup -:gotJndiHome - -if not "%JSSE_HOME%" == "" goto gotJsseHome -echo You must set JSSE_HOME to point at your Java Security Extensions install -goto cleanup -:gotJsseHome - -if not "%REGEXP_HOME%" == "" goto gotRegexpHome -echo You must set REGEXP_HOME to point at your Regular Expressions distribution install -goto cleanup -:gotRegexpHome - -if not "%SERVLETAPI_HOME%" == "" goto gotServletapiHome -echo You must set SERVLETAPI_HOME to your Servlet API distribution that includes the Servlet 2.3 and JSP 1.2 API classes. -goto cleanup -:gotServletapiHome - - -rem ----- Set Up The Runtime Classpath ---------------------------------------- - -if not "%CLASSPATH%" == "" set CLASSPATH=%CLASSPATH%; -set CLASSPATH=%CLASSPATH%;%ANT_HOME%\lib\ant.jar;%JAVA_HOME%\lib\tools.jar;%ANT_XML_CLASSPATH% -rem @@@ %JMX_HOME%\lib\jmxri.jar - - -rem ----- Execute The Requested Build ----------------------------------------- - -%JAVA_HOME%\bin\java %ANT_OPTS% org.apache.tools.ant.Main -Dant.home=%ANT_HOME% -Dcatalina.jaxp.home="%CATALINA_JAXP_HOME%" -Dcatalina.jaxp.parser.jar="%CATALINA_JAXP_PARSER_JAR%" -Djasper.jaxp.home="%JASPER_JAXP_HOME%" -Djasper.jaxp.parser.jar="%JASPER_JAXP_PARSER_JAR%" -Djsse.home="%JSSE_HOME%" -Djmx.home="%JMX_HOME%" -Djndi.home="%JNDI_HOME%" -Dregexp.home="%REGEXP_HOME%" -Dservletapi.home="%SERVLETAPI_HOME%" -Djava.home="%JAVA_HOME%" %1 %2 %3 %4 %5 %6 %7 %8 %9 - - -rem ----- Restore Environment Variables --------------------------------------- -:cleanup -set CLASSPATH=%_CLASSPATH% -set _CLASSPATH= -set JAXP_PARSER_JAR=%_JAXP_PARSER_JAR% -set _JAXP_PARSER_JAR= -set ANT_HOME=%_ANT_HOME% -set _ANT_HOME= -set ANT_XML_CLASSPATH=%_ANT_XML_CLASSPATH% -set _ANT_XML_CLASSPATH= -set CATALINA_JAXP_HOME=%_CATALINA_JAXP_HOME% -set _CATALINA_JAXP_HOME= -set CATALINA_JAXP_PARSER_JAR=%_CATALINA_JAXP_PARSER_JAR% -set _CATALINA_JAXP_PARSER_JAR= -set JASPER_JAXP_HOME=%_JASPER_JAXP_HOME% -set _JASPER_JAXP_HOME= -set JASPER_JAXP_PARSER_JAR=%_JASPER_JAXP_PARSER_JAR% -set _JASPER_JAXP_PARSER_JAR= -:finish - +@echo off +rem -------------------------------------------------------------------------- +rem build.bat - Build Script for Tomcat +rem +rem Environment Variable Prerequisites: +rem +rem JAVA_HOME Must point at your Java Development Kit [REQUIRED] +rem +rem JAXP_HOME Points at a JAXP compliant XML parser +rem installation directory [NONE] +rem JAXP_PARSER_JAR The jar filename of the JAXP compliant +rem 'XML parser' [crimson.jar] +rem +rem ANT_HOME Must point at your Ant installation [../jakarta-ant] +rem +rem ANT_OPTS Command line options to the Java runtime +rem that executes Ant [NONE] +rem ANT_XML_CLASSPATH +rem Jar files added to the classpath for the XML parsing +rem requirements of ant +rem [%JAXP_HOME%\%JAXP_PARSER_JAR%;%JAXP_HOME%\jaxp.jar] +rem +rem JMX_HOME Must point at your JMX installation [REQUIRED] +rem +rem JNDI_HOME Must point at your JNDI installation [REQUIRED] +rem +rem JSSE_HOME Must point at your JSSE installation [REQUIRED] +rem +rem REGEXP_HOME Must point at your Regexp installation [REQUIRED] +rem +rem SERVLETAPI_HOME Must point at your "jakarta-servletapi" installation. +rem [REQUIRED] +rem +rem CATALINA_JAXP_HOME +rem JAXP 1.0 compliant XML parser installation directory +rem used for catalina [JAXP_HOME] +rem CATALINA_JAXP_PARSER_JAR +rem The jar filename of the JAXP compliant XML parser +rem used for catalina [JAXP_PARSER_JAR] +rem +rem JASPER_JAXP_HOME +rem JAXP 1.1 compliant XML parser installation directory +rem used for jasper [JAXP_HOME] +rem JASPER_JAXP_PARSER_JAR +rem The jar filename of the JAXP compliant XML parser +rem used for jasper [JAXP_PARSER_JAR] +rem +rem $Id: build.bat,v 1.15 2001/02/16 07:14:32 craigmcc Exp $ +rem --------------------------------------------------------------------------- + + +rem ----- Save Environment Variables ------------------------------------------ + +set _CLASSPATH=%CLASSPATH% +set _JAXP_PARSER_JAR=%JAXP_PARSER_JAR% +set _ANT_HOME=%ANT_HOME% +set _ANT_XML_CLASSPATH=%ANT_XML_CLASSPATH% +set _CATALINA_JAXP_HOME=%CATALINA_JAXP_HOME% +set _CATALINA_JAXP_PARSER_JAR=%CATALINA_JAXP_PARSER_JAR% +set _JASPER_JAXP_HOME=%JASPER_JAXP_HOME% +set _JASPER_JAXP_PARSER_JAR=%JASPER_JAXP_PARSER_JAR% + + +rem ----- Verify and Set Required Environment Variables ----------------------- + +if not "%JAVA_HOME%" == "" goto gotJavaHome +echo You must set JAVA_HOME to point at your Java Development Kit installation +goto cleanup +:gotJavaHome + +if not "%JAXP_PARSER_JAR%" == "" goto gotJaxpParserJar +set JAXP_PARSER_JAR=crimson.jar +:gotJaxpParserJar + +if not "%ANT_XML_CLASSPATH%" == "" goto gotAntXmlClasspath +if "%JAXP_HOME%" == "" goto jaxpHome +set ANT_XML_CLASSPATH=%JAXP_HOME%\%JAXP_PARSER_JAR%;%JAXP_HOME%\jaxp.jar +:gotAntXmlClasspath + +if not "%CATALINA_JAXP_HOME%" == "" goto gotCatalinaJaxpHome +if "%JAXP_HOME%" == "" goto jaxpHome +set CATALINA_JAXP_HOME=%JAXP_HOME% +:gotCatalinaJaxpHome + +if not "%CATALINA_JAXP_PARSER_JAR%" == "" goto gotCatalinaJaxpParserJar +set CATALINA_JAXP_PARSER_JAR=%JAXP_PARSER_JAR% +:gotCatalinaJaxpParserJar + +if not "%JASPER_JAXP_HOME%" == "" goto gotJasperJaxpHome +if "%JAXP_HOME%" == "" goto jaxpHome +set JASPER_JAXP_HOME=%JAXP_HOME% +:gotJasperJaxpHome + +if not "%JASPER_JAXP_PARSER_JAR%" == "" goto gotJasperJaxpParserJar +set JASPER_JAXP_PARSER_JAR=%JAXP_PARSER_JAR% +:gotJasperJaxpParserJar + +goto gotJaxpHome + +:jaxpHome +echo You must set JAXP_HOME to point at your XML Parser install directory. +echo By default, ant, catalina, and jasper will use jaxp.jar and crimson.jar from +echo that directory. +echo - A different parser jar file can be specified globally for all +echo components via environment variable JAXP_PARSER_JAR (e.g. xerces.jar). +echo - XML requirements for each component can also be set individually via +echo the following environment variables: +echo ANT_XML_CLASSPATH +echo CATALINA_JAXP_HOME CATALINA_JAXP_PARSER_JAR +echo JASPER_JAXP_HOME JASPER_JAXP_PARSER_JAR +goto cleanup +:gotJaxpHome + +if not "%ANT_HOME%" == "" goto gotAntHome +set ANT_HOME=../jakarta-ant +:gotAntHome + +if not "%JMX_HOME%" == "" goto gotJmxHome +echo You must set JMX_HOME to point at your Java Management Extensions install +goto cleanup +:gotJmxHome + +if not "%JNDI_HOME%" == "" goto gotJndiHome +echo You must set JNDI_HOME to point at your Java Naming and Directory Interface install +goto cleanup +:gotJndiHome + +if not "%JSSE_HOME%" == "" goto gotJsseHome +echo You must set JSSE_HOME to point at your Java Security Extensions install +goto cleanup +:gotJsseHome + +if not "%REGEXP_HOME%" == "" goto gotRegexpHome +echo You must set REGEXP_HOME to point at your Regular Expressions distribution install +goto cleanup +:gotRegexpHome + +if not "%SERVLETAPI_HOME%" == "" goto gotServletapiHome +echo You must set SERVLETAPI_HOME to your Servlet API distribution that includes the Servlet 2.3 and JSP 1.2 API classes. +goto cleanup +:gotServletapiHome + + +rem ----- Set Up The Runtime Classpath ---------------------------------------- + +if not "%CLASSPATH%" == "" set CLASSPATH=%CLASSPATH%; +set CLASSPATH=%CLASSPATH%;%ANT_HOME%\lib\ant.jar;%JAVA_HOME%\lib\tools.jar;%ANT_XML_CLASSPATH% +rem @@@ %JMX_HOME%\lib\jmxri.jar + + +rem ----- Execute The Requested Build ----------------------------------------- + +%JAVA_HOME%\bin\java %ANT_OPTS% org.apache.tools.ant.Main -Dant.home=%ANT_HOME% -Dcatalina.jaxp.home="%CATALINA_JAXP_HOME%" -Dcatalina.jaxp.parser.jar="%CATALINA_JAXP_PARSER_JAR%" -Djasper.jaxp.home="%JASPER_JAXP_HOME%" -Djasper.jaxp.parser.jar="%JASPER_JAXP_PARSER_JAR%" -Djsse.home="%JSSE_HOME%" -Djmx.home="%JMX_HOME%" -Djndi.home="%JNDI_HOME%" -Dregexp.home="%REGEXP_HOME%" -Dservletapi.home="%SERVLETAPI_HOME%" -Djava.home="%JAVA_HOME%" %1 %2 %3 %4 %5 %6 %7 %8 %9 + + +rem ----- Restore Environment Variables --------------------------------------- +:cleanup +set CLASSPATH=%_CLASSPATH% +set _CLASSPATH= +set JAXP_PARSER_JAR=%_JAXP_PARSER_JAR% +set _JAXP_PARSER_JAR= +set ANT_HOME=%_ANT_HOME% +set _ANT_HOME= +set ANT_XML_CLASSPATH=%_ANT_XML_CLASSPATH% +set _ANT_XML_CLASSPATH= +set CATALINA_JAXP_HOME=%_CATALINA_JAXP_HOME% +set _CATALINA_JAXP_HOME= +set CATALINA_JAXP_PARSER_JAR=%_CATALINA_JAXP_PARSER_JAR% +set _CATALINA_JAXP_PARSER_JAR= +set JASPER_JAXP_HOME=%_JASPER_JAXP_HOME% +set _JASPER_JAXP_HOME= +set JASPER_JAXP_PARSER_JAR=%_JASPER_JAXP_PARSER_JAR% +set _JASPER_JAXP_PARSER_JAR= +:finish + 1.4 +62 -60 jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/compiler/TldLocationsCache.java Index: TldLocationsCache.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/compiler/TldLocationsCache.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- TldLocationsCache.java 2000/12/07 19:33:08 1.3 +++ TldLocationsCache.java 2001/02/16 07:14:33 1.4 @@ -60,6 +60,7 @@ import java.io.IOException; import java.util.Hashtable; import java.util.Enumeration; +import java.util.Iterator; import java.util.jar.*; import java.net.JarURLConnection; import java.net.*; @@ -69,12 +70,11 @@ import javax.servlet.jsp.tagext.TagInfo; import javax.servlet.jsp.tagext.Tag; -import org.w3c.dom.*; -import org.xml.sax.*; - import org.apache.jasper.Constants; import org.apache.jasper.JasperException; import org.apache.jasper.logging.Logger; +import org.apache.jasper.parser.ParserUtils; +import org.apache.jasper.parser.TreeNode; /** * A container for all tag libraries that are defined "globally" @@ -144,49 +144,51 @@ private void processWebDotXml(ServletContext ctxt) throws JasperException { - // Parse web.xml - InputStream is = ctxt.getResourceAsStream(WEB_XML); + // Acquire an input stream to the web application deployment descriptor + InputStream is = ctxt.getResourceAsStream(WEB_XML); if (is == null) { - Constants.message("jsp.error.internal.filenotfound", - new Object[]{WEB_XML}, + Constants.message("jsp.error.internal.filenotfound", + new Object[] {WEB_XML}, Logger.WARNING); return; } - Document webtld = - JspUtil.parseXMLDoc(WEB_XML, is); - NodeList nList = webtld.getElementsByTagName("taglib"); - if (nList.getLength() != 0) { - for(int i=0; i<nList.getLength(); i++) { - String tagUri = null; - String tagLoc = null; - Element e = (Element)nList.item(i); - - NodeList uriList = e.getElementsByTagName("taglib-uri"); - Element uriElem = (Element)uriList.item(0); - tagUri = JspUtil.getElementChildTextData(uriElem); - if (tagUri == null) continue; - - NodeList locList = - e.getElementsByTagName("taglib-location"); - Element locElem = (Element)locList.item(0); - tagLoc = JspUtil.getElementChildTextData(locElem); - if (tagLoc == null) continue; - - if (uriType(tagLoc) == NOROOT_REL_URI) { - // relative to web.xml location - tagLoc = "/WEB-INF/" + tagLoc; - } - String loc2 = null; - if (tagLoc.endsWith(".jar")) { - loc2 = "META-INF/taglib.tld"; - } - mappings.put(tagUri, new String[] {tagLoc, loc2}); - //p("added web.xml mapping: " + tagUri + " -> " + - // tagLoc + " " + loc2); - } + // Parse the web application deployment descriptor + ParserUtils pu = new ParserUtils(); + TreeNode webtld = pu.parseXMLDocument(WEB_XML, is); + Iterator taglibs = webtld.findChildren("taglib"); + while (taglibs.hasNext()) { + + // Parse the next <taglib> element + TreeNode taglib = (TreeNode) taglibs.next(); + String tagUri = null; + Iterator uris = taglib.findChildren("taglib-uri"); + while (uris.hasNext()) { + TreeNode uri = (TreeNode) uris.next(); + if (tagUri == null) + tagUri = uri.getBody(); + } + String tagLoc = null; + Iterator locs = taglib.findChildren("taglib-location"); + while (locs.hasNext()) { + TreeNode loc = (TreeNode) locs.next(); + if (tagLoc == null) + tagLoc = loc.getBody(); + } + + // Save this location if appropriate + if (tagLoc == null) + continue; + if (uriType(tagLoc) == NOROOT_REL_URI) + tagLoc = "/WEB-INF/" + tagLoc; + String tagLoc2 = null; + if (tagLoc.endsWith(".jar")) + tagLoc2 = "META-INF/taglib.tld"; + mappings.put(tagUri, new String[] {tagLoc, tagLoc2}); + } + } /** @@ -274,29 +276,29 @@ private String parseTldForUri(String resourcePath, InputStream in) throws JasperException { - Document tld = JspUtil.parseXMLDoc(resourcePath, in); - NodeList list = tld.getElementsByTagName("taglib"); - if (list.getLength() != 1) { - Constants.message("jsp.error.more.than.one.taglib", - new Object[]{resourcePath}, - Logger.ERROR); - return null; - } - - Element elem = (Element)list.item(0); - list = elem.getChildNodes(); - - for(int i = 0; i < list.getLength(); i++) { - Node tmp = list.item(i); - if (! (tmp instanceof Element)) continue; - Element e = (Element) tmp; - String tname = e.getTagName(); - if (tname.equals("uri")) { - return JspUtil.getElementChildTextData(e); + + // Parse the tag library descriptor at the specified resource path + ParserUtils pu = new ParserUtils(); + TreeNode tld = pu.parseXMLDocument(resourcePath, in); + Iterator taglibs = tld.findChildren("taglib"); + int n = 0; + while (taglibs.hasNext()) { + n++; + if (n > 1) { + Constants.message("jsp.error.more.than.one.taglib", + new Object[] {resourcePath}, + Logger.ERROR); + return null; + } + TreeNode taglib = (TreeNode) taglibs.next(); + Iterator uris = taglib.findChildren("uri"); + while (uris.hasNext()) { + TreeNode uri = (TreeNode) uris.next(); + return uri.getBody(); } } - //p("No URI defined for this tag library: " + resourcePath); - return null; + return null; // No <uri> element is present + } //********************************************************************* 1.1 jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/parser/ParserUtils.java Index: ParserUtils.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 1999 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", "Tomcat", 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.jasper.parser; import java.io.InputStream; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.jasper.Constants; import org.apache.jasper.JasperException; import org.w3c.dom.Comment; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; /** * XML parsing utilities for processing web application deployment * descriptor and tag library descriptor files. FIXME - make these * use a separate class loader for the parser to be used. * * @author Craig R. McClanahan * @version $Revision: 1.1 $ $Date: 2001/02/16 07:14:34 $ */ public class ParserUtils { // ------------------------------------------------------ Unit Test Program /** * Usage: java org.apache.jasper.parser.ParserUtils {pathname} */ public static void main(String args[]) { if (args.length < 1) { System.out.println("usage: java ParserUtils {filename}"); System.exit(1); } try { ParserUtils pu = new ParserUtils(); System.out.println("Opening " + args[0]); java.io.FileInputStream fis = new java.io.FileInputStream(args[0]); System.out.println("Execute the parse"); TreeNode tree = pu.parseXMLDocument(args[0], fis); System.out.println("Dump results"); System.out.println(tree); } catch (Throwable t) { System.out.println("Exception: " + t.toString()); t.printStackTrace(System.out); } } // ----------------------------------------------------- Instance Variables /** * An error handler for use when parsing XML documents. */ protected ErrorHandler errorHandler = new MyErrorHandler(); /** * An entity resolver for use when parsing XML documents. */ protected EntityResolver entityResolver = new MyEntityResolver(); // --------------------------------------------------------- Public Methods /** * Parse the specified XML document, and return a <code>TreeNode</code> * that corresponds to the root node of the document tree. * * @param uri URI of the XML document being parsed * @param is Input stream containing the deployment descriptor * * @exception JasperException if an input/output error occurs * @exception JasperException if a parsing error occurs */ public TreeNode parseXMLDocument(String uri, InputStream is) throws JasperException { Document document = null; // Perform an XML parse of this document, via JAXP try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); factory.setValidating(true); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setEntityResolver(entityResolver); builder.setErrorHandler(errorHandler); document = builder.parse(is); } catch (ParserConfigurationException ex) { throw new JasperException (Constants.getString("jsp.error.parse.xml", new Object[]{uri, ex.getMessage()})); } catch (SAXParseException ex) { throw new JasperException (Constants.getString ("jsp.error.parse.xml.line", new Object[]{uri, new Integer(ex.getLineNumber()), new Integer(ex.getColumnNumber()), ex.getMessage()})); } catch (SAXException sx) { throw new JasperException (Constants.getString("jsp.error.parse.xml", new Object[]{uri, sx.getMessage()})); } catch (IOException io) { throw new JasperException (Constants.getString("jsp.error.parse.xml", new Object[]{uri, io.toString()})); } // Convert the resulting document to a graph of TreeNodes return (convert(null, document.getDocumentElement())); } // ------------------------------------------------------ Protected Methods /** * Create and return a TreeNode that corresponds to the specified Node, * including processing all of the attributes and children nodes. * * @param parent The parent TreeNode (if any) for the new TreeNode * @param node The XML document Node to be converted */ protected TreeNode convert(TreeNode parent, Node node) { // Construct a new TreeNode for this node TreeNode treeNode = new TreeNode(node.getNodeName(), parent); // Convert all attributes of this node NamedNodeMap attributes = node.getAttributes(); if (attributes != null) { int n = attributes.getLength(); for (int i = 0; i < n; i++) { Node attribute = attributes.item(i); treeNode.addAttribute(attribute.getNodeName(), attribute.getNodeValue()); } } // Create and attach all children of this node NodeList children = node.getChildNodes(); if (children != null) { int n = children.getLength(); for (int i = 0; i < n; i++) { Node child = children.item(i); if (child instanceof Comment) continue; if (child instanceof Text) { String body = ((Text) child).getData(); if (body != null) { body = body.trim(); if (body.length() > 0) treeNode.setBody(body); } } else { TreeNode treeChild = convert(treeNode, child); } } } // Return the completed TreeNode graph return (treeNode); } } // ------------------------------------------------------------ Private Classes class MyEntityResolver implements EntityResolver { public InputSource resolveEntity(String publicId, String systemId) throws SAXException { for (int i=0; i<Constants.CACHED_DTD_PUBLIC_IDS.length; i++) { String cachedDtdPublicId = Constants.CACHED_DTD_PUBLIC_IDS[i]; if (cachedDtdPublicId.equals(publicId)) { String resourcePath = Constants.CACHED_DTD_RESOURCE_PATHS[i]; InputStream input = this.getClass().getResourceAsStream(resourcePath); if (input == null) { throw new SAXException( Constants.getString("jsp.error.internal.filenotfound", new Object[]{resourcePath})); } InputSource isrc = new InputSource(input); return isrc; } } throw new SAXException( Constants.getString("jsp.error.parse.xml.invalidPublicId", new Object[]{publicId})); } } class MyErrorHandler implements ErrorHandler { public void warning(SAXParseException ex) throws SAXException { // We ignore warnings } public void error(SAXParseException ex) throws SAXException { throw ex; } public void fatalError(SAXParseException ex) throws SAXException { throw ex; } } 1.1 jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/parser/TreeNode.java Index: TreeNode.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 1999 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", "Tomcat", 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.jasper.parser; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; /** * Simplified implementation of a Node from a Document Object Model (DOM) * parse of an XML document. This class is used to represent a DOM tree * so that the XML parser's implementation of <code>org.w3c.dom</code> need * not be visible to the remainder of Jasper. * <p> * <strong>WARNING</strong> - Construction of a new tree, or modifications * to an existing one, are not thread-safe and such accesses must be * synchronized. * * @author Craig R. McClanahan * @version $Revision: 1.1 $ $Date: 2001/02/16 07:14:34 $ */ public class TreeNode { // ----------------------------------------------------------- Constructors /** * Construct a new node with no parent. * * @param name The name of this node */ public TreeNode(String name) { this(name, null); } /** * Construct a new node with the specified parent. * * @param name The name of this node * @param parent The node that is the parent of this node */ public TreeNode(String name, TreeNode parent) { super(); this.name = name; this.parent = parent; if (this.parent != null) this.parent.addChild(this); } // ----------------------------------------------------- Instance Variables /** * The attributes of this node, keyed by attribute name, * Instantiated only if required. */ protected HashMap attributes = null; /** * The body text associated with this node (if any). */ protected String body = null; /** * The children of this node, instantiated only if required. */ protected ArrayList children = null; /** * The name of this node. */ protected String name = null; /** * The parent node of this node. */ protected TreeNode parent = null; // --------------------------------------------------------- Public Methods /** * Add an attribute to this node, replacing any existing attribute * with the same name. * * @param name The attribute name to add * @param value The new attribute value */ public void addAttribute(String name, String value) { if (attributes == null) attributes = new HashMap(); attributes.put(name, value); } /** * Add a new child node to this node. * * @param node The new child node */ public void addChild(TreeNode node) { if (children == null) children = new ArrayList(); children.add(node); } /** * Return the value of the specified node attribute if it exists, or * <code>null</code> otherwise. * * @param name Name of the requested attribute */ public String findAttribute(String name) { if (attributes == null) return (null); else return ((String) attributes.get(name)); } /** * Return an Iterator of the attribute names of this node. If there are * no attributes, an empty Iterator is returned. */ public Iterator findAttributes() { if (attributes == null) return (Collections.EMPTY_LIST.iterator()); else return (attributes.keySet().iterator()); } /** * Return an Iterator of all children of this node. If there are no * children, an empty Iterator is returned. */ public Iterator findChildren() { if (children == null) return (Collections.EMPTY_LIST.iterator()); else return (children.iterator()); } /** * Return an Iterator over all children of this node that have the * specified name. If there are no such children, an empty Iterator * is returned. * * @param name Name used to select children */ public Iterator findChildren(String name) { if (children == null) return (Collections.EMPTY_LIST.iterator()); ArrayList results = new ArrayList(); Iterator items = children.iterator(); while (items.hasNext()) { TreeNode item = (TreeNode) items.next(); if (name.equals(item.getName())) results.add(item); } return (results.iterator()); } /** * Return the body text associated with this node (if any). */ public String getBody() { return (this.body); } /** * Return the name of this node. */ public String getName() { return (this.name); } /** * Remove any existing value for the specified attribute name. * * @param name The attribute name to remove */ public void removeAttribute(String name) { if (attributes != null) attributes.remove(name); } /** * Remove a child node from this node, if it is one. * * @param node The child node to remove */ public void removeNode(TreeNode node) { if (children != null) children.remove(node); } /** * Set the body text associated with this node (if any). * * @param body The body text (if any) */ public void setBody(String body) { this.body = body; } /** * Return a String representation of this TreeNode. */ public String toString() { StringBuffer sb = new StringBuffer(); toString(sb, 0, this); return (sb.toString()); } // ------------------------------------------------------ Protected Methods /** * Append to the specified StringBuffer a character representation of * this node, with the specified amount of indentation. * * @param sb The StringBuffer to append to * @param indent Number of characters of indentation * @param node The TreeNode to be printed */ protected void toString(StringBuffer sb, int indent, TreeNode node) { int indent2 = indent + 2; // Reconstruct an opening node for (int i = 0; i < indent; i++) sb.append(' '); sb.append('<'); sb.append(node.getName()); Iterator names = node.findAttributes(); while (names.hasNext()) { sb.append(' '); String name = (String) names.next(); sb.append(name); sb.append("=\""); String value = node.findAttribute(name); sb.append(value); sb.append("\""); } sb.append(">\n"); // Reconstruct the body text of this node (if any) String body = node.getBody(); if ((body != null) && (body.length() > 0)) { for (int i = 0; i < indent2; i++) sb.append(' '); sb.append(body); sb.append("\n"); } // Reconstruct child nodes with extra indentation Iterator children = node.findChildren(); while (children.hasNext()) { TreeNode child = (TreeNode) children.next(); toString(sb, indent2, child); } // Reconstruct a closing node marker for (int i = 0; i < indent; i++) sb.append(' '); sb.append("</"); sb.append(node.getName()); sb.append(">\n"); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]