patrickl 2002/08/19 20:26:37 Modified: catalina/src/share/org/apache/catalina/startup Constants.java ContextConfig.java Added: catalina/src/share/org/apache/catalina/util SchemaResolver.java Log: This patch implements a new SAX's entity resolver that will re-direct any remote schema/dtd locally. The patch implements a workaround for the warning problem when using Xerces 2.0.1. It also supports the current Xerces nightly build. I was unable to find a workaround for the StackOverflowException when using Xerces 2.0.2. At least we have one Xerces released version that work (very slow, that's why I am going to start adding validation switch on/off :-)). Submitted by: Jean-Francois Arcand ([EMAIL PROTECTED]) Revision Changes Path 1.5 +9 -13 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/Constants.java Index: Constants.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/Constants.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- Constants.java 10 Aug 2002 22:42:34 -0000 1.4 +++ Constants.java 20 Aug 2002 03:26:36 -0000 1.5 @@ -83,49 +83,45 @@ public static final String TldDtdPublicId_11 = "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"; public static final String TldDtdResourcePath_11 = - // "conf/tld_11.dtd"; "/javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd"; public static final String TldDtdPublicId_12 = "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"; public static final String TldDtdResourcePath_12 = - // "conf/tld_12.dtd"; "/javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd"; public static final String TldSchemaPublicId_20 = - "http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd";; + "web-jsptaglibrary_2_0.xsd";; public static final String TldSchemaResourcePath_20 = "/javax/servlet/resources/web-jsptaglibrary_2_0.xsd"; public static final String WebDtdPublicId_22 = "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"; public static final String WebDtdResourcePath_22 = - // "conf/web_22.dtd"; "/javax/servlet/resources/web-app_2_2.dtd"; public static final String WebDtdPublicId_23 = "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"; public static final String WebDtdResourcePath_23 = - // "conf/web_23.dtd"; "/javax/servlet/resources/web-app_2_3.dtd"; public static final String WebSchemaPublicId_24 = - "http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd";; + "web-app_2_4.xsd";; public static final String WebSchemaResourcePath_24 = "/javax/servlet/resources/web-app_2_4.xsd"; public static final String J2eeSchemaPublicId_14 = - "http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd";; + "j2ee_1_4.xsd";; public static final String J2eeSchemaResourcePath_14 = "/javax/servlet/resources/j2ee_1_4.xsd"; public static final String W3cSchemaPublicId_10 = - "http://www.w3.org/2001/xml.xsd";; + "xml.xsd";; public static final String W3cSchemaResourcePath_10 = "/javax/servlet/resources/xml.xsd"; public static final String JspSchemaPublicId_20 = - "http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd";; + "jsp_2_0.xsd";; public static final String JspSchemaResourcePath_20 = "/javax/servlet/resources/jsp_2_0.xsd"; 1.9 +79 -59 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/ContextConfig.java Index: ContextConfig.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/ContextConfig.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- ContextConfig.java 10 Aug 2002 22:42:34 -0000 1.8 +++ ContextConfig.java 20 Aug 2002 03:26:36 -0000 1.9 @@ -124,9 +124,11 @@ import org.apache.catalina.deploy.SecurityConstraint; import org.apache.catalina.loader.Extension; import org.apache.catalina.util.StringManager; +import org.apache.catalina.util.SchemaResolver; import org.apache.catalina.valves.ValveBase; import org.apache.commons.digester.Digester; import org.xml.sax.InputSource; +import org.xml.sax.EntityResolver; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; import org.xml.sax.SAXParseException; @@ -275,12 +277,15 @@ try { URL url = servletContext.getResource(Constants.ApplicationWebXml); + InputSource is = new InputSource(url.toExternalForm()); is.setByteStream(stream); webDigester.setDebug(getDebug()); if (context instanceof StandardContext) { ((StandardContext) context).setReplaceWelcomeFiles(true); } + + webDigester.clear(); webDigester.push(context); webDigester.parse(is); @@ -482,25 +487,52 @@ Digester tldDigester = new Digester(); tldDigester.setNamespaceAware(true); tldDigester.setValidating(true); + + if (tldDigester.getFactory().getClass().getName().indexOf("xerces")!=-1) { + tldDigester = patchXerces(tldDigester); + } + + // Set the schemaLocation + url = ContextConfig.class.getResource(Constants.TldSchemaResourcePath_20); + SchemaResolver tldEntityResolver = new SchemaResolver(url.toString(), + tldDigester); + tldDigester.setSchema(url.toString()); + url = ContextConfig.class.getResource(Constants.TldDtdResourcePath_11); - tldDigester.register(Constants.TldDtdPublicId_11, - url.toString()); + tldEntityResolver.register(Constants.TldDtdPublicId_11, + url.toString()); + url = ContextConfig.class.getResource(Constants.TldDtdResourcePath_12); - tldDigester.register(Constants.TldDtdPublicId_12, - url.toString()); - - url = ContextConfig.class.getResource(Constants.TldSchemaResourcePath_20); - // to support servlet.jar that does not contains the schema - if (url != null){ - tldDigester.setSchema(url.toString()); - tldDigester = registerLocalSchema(tldDigester); - } - + tldEntityResolver.register(Constants.TldDtdPublicId_12, + url.toString()); + + tldEntityResolver = registerLocalSchema(tldEntityResolver); + + tldDigester.setEntityResolver(tldEntityResolver); tldDigester.addRuleSet(new TldRuleSet()); return (tldDigester); } + + private static Digester patchXerces(Digester digester){ + // This feature is needed for backward compatibility with old DDs + // which used Java encoding names such as ISO8859_1 etc. + // with Crimson (bug 4701993). By default, Xerces does not + // support ISO8859_1. + try{ + digester.setFeature( + "http://apache.org/xml/features/allow-java-encodings", true); + } catch(ParserConfigurationException e){ + // log("contextConfig.registerLocalSchema", e); + } catch(SAXNotRecognizedException e){ + // log("contextConfig.registerLocalSchema", e); + } catch(SAXNotSupportedException e){ + // log("contextConfig.registerLocalSchema", e); + } + return digester; + } + /** * Create (if necessary) and return a Digester configured to process the @@ -512,26 +544,29 @@ Digester webDigester = new Digester(); webDigester.setNamespaceAware(true); webDigester.setValidating(true); + + if (webDigester.getFactory().getClass().getName().indexOf("xerces")!=-1) { + webDigester = patchXerces(webDigester); + } + + url = ContextConfig.class.getResource(Constants.WebSchemaResourcePath_24); + SchemaResolver webEntityResolver = new SchemaResolver(url.toString(), + webDigester); + webDigester.setSchema(url.toString()); + url = ContextConfig.class.getResource(Constants.WebDtdResourcePath_22); - webDigester.register(Constants.WebDtdPublicId_22, - url.toString()); + webEntityResolver.register(Constants.WebDtdPublicId_22, + url.toString()); + url = ContextConfig.class.getResource(Constants.WebDtdResourcePath_23); - webDigester.register(Constants.WebDtdPublicId_23, - url.toString()); - - url = ContextConfig.class.getResource(Constants.WebSchemaResourcePath_24); - webDigester.register(Constants.WebSchemaPublicId_24, - url.toString()); + webEntityResolver.register(Constants.WebDtdPublicId_23, + url.toString()); - // to support servlet.jar that does not contains the schema - if (url != null){ - webDigester.setSchema(url.toString()); - webDigester = registerLocalSchema(webDigester); - } + webEntityResolver = registerLocalSchema(webEntityResolver); + webDigester.setEntityResolver(webEntityResolver); webDigester.addRuleSet(new WebRuleSet()); return (webDigester); - } @@ -566,6 +601,7 @@ stream = new FileInputStream(file); is.setByteStream(stream); webDigester.setDebug(getDebug()); + if (context instanceof StandardContext) ((StandardContext) context).setReplaceWelcomeFiles(true); webDigester.clear(); @@ -642,45 +678,29 @@ * @param digester The instance on which properties are set. * @return an instance ready to parse XML schema. */ - protected static Digester registerLocalSchema(Digester digester){ - - // This feature is needed for backward compatibility with old DDs - // which used Java encoding names such as ISO8859_1 etc. - // with Crimson (bug 4701993). By default, Xerces does not - // support ISO8859_1. - if (digester.getFactory().getClass().getName().indexOf("xerces")!=-1) { - try{ - digester.setFeature( - "http://apache.org/xml/features/allow-java-encodings", true); - } catch(ParserConfigurationException e){ - // log("contextConfig.registerLocalSchema", e); - } catch(SAXNotRecognizedException e){ - // log("contextConfig.registerLocalSchema", e); - } catch(SAXNotSupportedException e){ - // log("contextConfig.registerLocalSchema", e); - } - } + protected static SchemaResolver registerLocalSchema(SchemaResolver entityResolver){ URL url = ContextConfig.class.getResource(Constants.J2eeSchemaResourcePath_14); - digester.register(Constants.J2eeSchemaPublicId_14, - url.toString()); + entityResolver.register(Constants.J2eeSchemaPublicId_14, + url.toString()); url = ContextConfig.class.getResource(Constants.W3cSchemaResourcePath_10); - digester.register(Constants.W3cSchemaPublicId_10, - url.toString()); + entityResolver.register(Constants.W3cSchemaPublicId_10, + url.toString()); url = ContextConfig.class.getResource(Constants.JspSchemaResourcePath_20); - digester.register(Constants.JspSchemaPublicId_20, - url.toString()); + entityResolver.register(Constants.JspSchemaPublicId_20, + url.toString()); url = ContextConfig.class.getResource(Constants.TldSchemaResourcePath_20); - digester.register(Constants.TldSchemaPublicId_20, - url.toString()); + entityResolver.register(Constants.TldSchemaPublicId_20, + url.toString()); + url = ContextConfig.class.getResource(Constants.WebSchemaResourcePath_24); - digester.register(Constants.WebSchemaPublicId_24, - url.toString()); + entityResolver.register(Constants.WebSchemaPublicId_24, + url.toString()); - return digester; + return entityResolver; } 1.1 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/SchemaResolver.java Index: SchemaResolver.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/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.catalina.util; import java.util.HashMap; import org.apache.commons.digester.Digester; import org.xml.sax.InputSource; import org.xml.sax.EntityResolver; import org.xml.sax.SAXException; /** * This class implements a local SAX's <code>EntityResolver</code>. All * DTDs and schemas used to validate the web.xml file will re-directed * to a local file stored in the servlet-api.jar and jsp-api.jar. * * @author Jean-Francois Arcand */ public class SchemaResolver implements EntityResolver { /** * The disgester instance for which this class is the entity resolver. */ protected Digester digester; /** * The URLs of dtds and schemas that have been registered, keyed by the * public identifier that corresponds. */ protected HashMap entityValidator = new HashMap(); /** * The public identifier of the DTD we are currently parsing under * (if any). */ protected String publicId = null; /** * Extension to make the difference between DTD and Schema. */ protected String schemaExtension = "xsd"; /** * The XML schema to use for validating an XML instance. */ protected String schemaLocation = null; /** * Create a new <code>EntityResolver</code> that will redirect * all remote dtds and schema to a locat destination. * @param schemaLocation the XML Schema used to validate xml instance. */ public SchemaResolver(String schemaLocation, Digester digester) { this.schemaLocation = schemaLocation; this.digester = digester; } /** * Register the specified DTD/Schema URL for the specified public * identifier. This must be called before the first call to * <code>parse()</code>. * * When adding a schema file (*.xsd), only the name of the file * will get added. If two schemas with the same name are added, * only the last one will be stored. * * @param publicId Public identifier of the DTD to be resolved * @param entityURL The URL to use for reading this DTD */ public void register(String publicId, String entityURL) { String key = publicId; if (publicId.indexOf(schemaExtension) != -1) key = publicId.substring(publicId.lastIndexOf('/')+1); entityValidator.put(key, entityURL); } /** * Resolve the requested external entity. * * @param publicId The public identifier of the entity being referenced * @param systemId The system identifier of the entity being referenced * * @exception SAXException if a parsing exception occurs * */ public InputSource resolveEntity(String publicId, String systemId) throws SAXException { if (publicId != null) { this.publicId = publicId; digester.setPublicId(publicId); } // Has this system identifier been registered? String entityURL = null; if (publicId != null) { entityURL = (String) entityValidator.get(publicId); } // Redirect the schema location to a local destination String key = null; if (schemaLocation != null && entityURL == null && systemId != null) { key = systemId.substring(systemId.lastIndexOf('/')+1); entityURL = (String)entityValidator.get(key); } if (entityURL == null) { return (null); } try { return (new InputSource(entityURL)); } catch (Exception e) { throw new SAXException(e); } } }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>