Author: markt Date: Tue Jul 9 08:51:17 2013 New Revision: 1501139 URL: http://svn.apache.org/r1501139 Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=55217 Implement a common EntityResolver that can be used by Catalina and Jasper. Patch provided by Jeremy Boynes.
Added: tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java (with props) tomcat/trunk/java/org/apache/tomcat/util/descriptor/XmlIdentifiers.java (with props) tomcat/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java (with props) Added: tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java?rev=1501139&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java (added) +++ tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java Tue Jul 9 08:51:17 2013 @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat.util.descriptor; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Map; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.ext.EntityResolver2; + +/** + * A resolver for locally cached XML resources. + */ +public class LocalResolver implements EntityResolver2 { + + private final Class<?> base; + private final Map<String,String> publicIds; + private final Map<String,String> systemIds; + + + /** + * Constructor providing mappings of public and system identifiers to local + * resources. Each map contains a mapping from a well-known identifier to a + * resource path that will be further resolved using the base Class using + * Class#getResource(String). + * + * @param base the class to use to locate local copies + * @param publicIds mapping of public identifiers to local resources + * @param systemIds mapping of system identifiers to local resources + */ + public LocalResolver(Class<?> base, Map<String,String> publicIds, + Map<String,String> systemIds) { + this.base = base; + this.publicIds = publicIds; + this.systemIds = systemIds; + } + + + @Override + public InputSource resolveEntity(String publicId, String systemId) + throws SAXException, IOException { + return resolveEntity(null, publicId, null, systemId); + } + + + @Override + public InputSource resolveEntity(String name, String publicId, + String baseURI, String systemId) throws SAXException, IOException { + + String resolved = resolve(publicId, systemId, baseURI); + if (resolved == null) { + return null; + } + + URL url = base.getResource(resolved); + if (url != null) { + resolved = url.toExternalForm(); + } + InputSource is = new InputSource(resolved); + is.setPublicId(publicId); + return is; + } + + + @Override + public InputSource getExternalSubset(String name, String baseURI) + throws SAXException, IOException { + return null; + } + + + private String resolve(String publicId, String systemId, String baseURI) { + // try resolving using the publicId + String resolved = publicIds.get(publicId); + if (resolved != null) { + return resolved; + } + + // try resolving using the systemId + if (systemId == null) { + return null; + } + + systemId = resolve(baseURI, systemId); + resolved = systemIds.get(systemId); + if (resolved != null) { + return resolved; + } + + // fall back to the supplied systemId + return systemId; + } + + + private static String resolve(String baseURI, String systemId) { + try { + if (baseURI == null) { + return systemId; + } + URI systemUri = new URI(systemId); + if (systemUri.isAbsolute()) { + return systemId; + } + return new URI(baseURI).resolve(systemUri).toString(); + } catch (URISyntaxException e) { + return systemId; + } + } +} \ No newline at end of file Propchange: tomcat/trunk/java/org/apache/tomcat/util/descriptor/LocalResolver.java ------------------------------------------------------------------------------ svn:eol-style = native Added: tomcat/trunk/java/org/apache/tomcat/util/descriptor/XmlIdentifiers.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/descriptor/XmlIdentifiers.java?rev=1501139&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/descriptor/XmlIdentifiers.java (added) +++ tomcat/trunk/java/org/apache/tomcat/util/descriptor/XmlIdentifiers.java Tue Jul 9 08:51:17 2013 @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat.util.descriptor; + +/** + * Defines constants for well-known Public and System identifiers documented by + * the Servlet and JSP specifications. + */ +public final class XmlIdentifiers { + + // from W3C + public static final String XML_2001_XSD = "http://www.w3.org/2001/xml.xsd"; + public static final String DATATYPES_PUBLIC = "datatypes"; + public static final String XSD_10_PUBLIC = + "-//W3C//DTD XMLSCHEMA 200102//EN"; + + // from J2EE 1.2 + public static final String WEB_22_PUBLIC = + "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"; + public static final String WEB_22_SYSTEM = + "http://java.sun.com/dtd/web-app_2_2.dtd"; + public static final String TLD_11_PUBLIC = + "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"; + public static final String TLD_11_SYSTEM = + "http://java.sun.com/dtd/web-jsptaglibrary_1_1.dtd"; + + // from J2EE 1.3 + public static final String WEB_23_PUBLIC = + "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"; + public static final String WEB_23_SYSTEM = + "http://java.sun.com/dtd/web-app_2_3.dtd"; + public static final String TLD_12_PUBLIC = + "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"; + public static final String TLD_12_SYSTEM = + "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"; + + // from J2EE 1.4 + public static final String WEB_24_XSD = + "http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"; + public static final String TLD_20_XSD = + "http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"; + public static final String WEBSERVICES_11_XSD = + "http://www.ibm.com/webservices/xsd/j2ee_web_services_1_1.xsd"; + + // from JavaEE 5 + public static final String WEB_25_XSD = + "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"; + public static final String TLD_21_XSD = + "http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"; + public static final String WEBSERVICES_12_XSD = + "http://java.sun.com/xml/ns/javaee/javaee_web_services_1_2.xsd"; + + // from JavaEE 6 + public static final String WEB_30_XSD = + "http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"; + public static final String WEB_FRAGMENT_30_XSD = + "http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"; + public static final String WEBSERVICES_13_XSD = + "http://java.sun.com/xml/ns/javaee/javaee_web_services_1_3.xsd"; + + // from JavaEE 7 + public static final String WEB_31_XSD = + "http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"; + public static final String WEB_FRAGMENT_31_XSD = + "http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"; + public static final String WEBSERVICES_14_XSD = + "http://xmlns.jcp.org/xml/ns/javaee/javaee_web_services_1_4.xsd"; + + private XmlIdentifiers() { + } +} \ No newline at end of file Propchange: tomcat/trunk/java/org/apache/tomcat/util/descriptor/XmlIdentifiers.java ------------------------------------------------------------------------------ svn:eol-style = native Added: tomcat/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java?rev=1501139&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java (added) +++ tomcat/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java Tue Jul 9 08:51:17 2013 @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat.util.descriptor; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.ServletContext; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +public class TestLocalResolver { + + private final Map<String, String> publicIds = new HashMap<>(); + private final Map<String, String> systemIds = new HashMap<>(); + + private LocalResolver resolver = + new LocalResolver(ServletContext.class, publicIds, systemIds); + private String WEB_22_LOCAL; + private String WEB_31_LOCAL; + private String WEBCOMMON_31_LOCAL; + + @Before + public void init() { + publicIds.put(XmlIdentifiers.WEB_22_PUBLIC, + "/javax/servlet/resources/web-app_2_2.dtd"); + systemIds.put(XmlIdentifiers.WEB_31_XSD, + "/javax/servlet/resources/web-app_3_1.xsd"); + WEB_22_LOCAL = getClass().getResource( + "/javax/servlet/resources/web-app_2_2.dtd").toExternalForm(); + WEB_31_LOCAL = getClass().getResource( + "/javax/servlet/resources/web-app_3_1.xsd").toExternalForm(); + WEBCOMMON_31_LOCAL = getClass().getResource( + "/javax/servlet/resources/web-common_3_1.xsd").toExternalForm(); + } + + @Test + public void unknownNullIdIsNull() throws IOException, SAXException { + Assert.assertNull(resolver.resolveEntity(null, null)); + } + + @Test + public void unknownPublicIdIsNull() throws IOException, SAXException { + Assert.assertNull(resolver.resolveEntity("unknown", null)); + } + + @Test + public void unknownSystemIdIsReturned() throws IOException, SAXException { + InputSource source = resolver.resolveEntity(null, "unknown"); + Assert.assertEquals(null, source.getPublicId()); + Assert.assertEquals("unknown", source.getSystemId()); + } + + @Test + public void unknownSystemIdIsResolvedAgainstBaseURI() + throws IOException, SAXException { + InputSource source = resolver.resolveEntity( + null, null, "http://example.com/home.html", "unknown"); + Assert.assertEquals(null, source.getPublicId()); + Assert.assertEquals("http://example.com/unknown", source.getSystemId()); + } + + @Test + public void publicIdIsResolved() throws IOException, SAXException { + InputSource source = resolver.resolveEntity( + XmlIdentifiers.WEB_22_PUBLIC, XmlIdentifiers.WEB_22_SYSTEM); + Assert.assertEquals(XmlIdentifiers.WEB_22_PUBLIC, source.getPublicId()); + Assert.assertEquals(WEB_22_LOCAL, source.getSystemId()); + } + + @Test + public void systemIdIsIgnoredWhenPublicIdIsResolved() + throws IOException, SAXException { + InputSource source = resolver.resolveEntity( + XmlIdentifiers.WEB_22_PUBLIC, "unknown"); + Assert.assertEquals(XmlIdentifiers.WEB_22_PUBLIC, source.getPublicId()); + Assert.assertEquals(WEB_22_LOCAL, source.getSystemId()); + } + + @Test + public void systemIdIsResolved() throws IOException, SAXException { + InputSource source = + resolver.resolveEntity(null, XmlIdentifiers.WEB_31_XSD); + Assert.assertEquals(null, source.getPublicId()); + Assert.assertEquals(WEB_31_LOCAL, source.getSystemId()); + } + + @Test + public void relativeSystemIdIsResolvedAgainstBaseURI() + throws IOException, SAXException { + InputSource source = resolver.resolveEntity( + null, null, WEB_31_LOCAL, "web-common_3_1.xsd"); + Assert.assertEquals(null, source.getPublicId()); + Assert.assertEquals(WEBCOMMON_31_LOCAL, source.getSystemId()); + } + + @Test + public void absoluteSystemIdOverridesBaseURI() + throws IOException, SAXException { + InputSource source = resolver.resolveEntity(null, null, + "http://example.com/home.html", XmlIdentifiers.WEB_31_XSD); + Assert.assertEquals(null, source.getPublicId()); + Assert.assertEquals(WEB_31_LOCAL, source.getSystemId()); + } +} \ No newline at end of file Propchange: tomcat/trunk/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java ------------------------------------------------------------------------------ svn:eol-style = native --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org