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

Reply via email to