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: [email protected]
For additional commands, e-mail: [email protected]