Author: pete Date: Sat Nov 13 12:19:30 2010 New Revision: 1034744 URL: http://svn.apache.org/viewvc?rev=1034744&view=rev Log: WICKET-3163: support offline builds of wicket (avoid hitting java.sun.com for lookup of web.xml 2.3 DTD)
Added: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/xml/ wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/xml/CustomEntityResolver.java Modified: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/WebXmlFile.java Modified: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/WebXmlFile.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/WebXmlFile.java?rev=1034744&r1=1034743&r2=1034744&view=diff ============================================================================== --- wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/WebXmlFile.java (original) +++ wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/file/WebXmlFile.java Sat Nov 13 12:19:30 2010 @@ -25,6 +25,7 @@ import javax.xml.parsers.DocumentBuilder import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import org.apache.wicket.util.xml.CustomEntityResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -34,7 +35,7 @@ import org.xml.sax.SAXException; /** * A utility class providing helper methods in dealing with web.xml - * + * * @author jcompagner * @author Juergen Donnerstag */ @@ -51,7 +52,7 @@ public class WebXmlFile /** * Gets Wicket filter path via FilterConfig - * + * * @param isServlet * true if Servlet, false if Filter * @param filterConfig @@ -65,7 +66,7 @@ public class WebXmlFile /** * Gets Wicket filter path via ServletContext and the filter name - * + * * @param isServlet * true if Servlet, false if Filter * @param servletContext @@ -109,7 +110,7 @@ public class WebXmlFile * web.xml file. * <p> * A typical Wicket web.xml entry looks like: - * + * * <pre> * <code> * <filter> @@ -120,7 +121,7 @@ public class WebXmlFile * <param-value>org.apache.wicket.examples.helloworld.HelloWorldApplication</param-value> * </init-param> * </filter> - * + * * <filter-mapping> * <filter-name>HelloWorldApplication</filter-name> * <url-pattern>/helloworld/*</url-pattern> @@ -129,7 +130,7 @@ public class WebXmlFile * </filter-mapping> * </code> * </pre> - * + * * @param isServlet * true if Servlet, false if Filter * @param filterName @@ -145,6 +146,7 @@ public class WebXmlFile { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); + builder.setEntityResolver(CustomEntityResolver.getPreloaded()); // try to pull DTD from local set of entities Document document = builder.parse(is); String tag = (isServlet ? "servlet" : "filter"); @@ -173,7 +175,7 @@ public class WebXmlFile /** * Iterate through all children of 'node' and search for a node with name "filterName". Return * the value of node "url-pattern" if "filterName" was found. - * + * * @param filterName * @param name * @param node @@ -215,7 +217,7 @@ public class WebXmlFile /** * Find a node with name 'mapping' within 'nodeList' and if found continue to search amongst its * children for a node with 'filterName' and "url-pattern' - * + * * @param filterName * @param mapping * @param name Added: wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/xml/CustomEntityResolver.java URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/xml/CustomEntityResolver.java?rev=1034744&view=auto ============================================================================== --- wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/xml/CustomEntityResolver.java (added) +++ wicket/trunk/wicket-util/src/main/java/org/apache/wicket/util/xml/CustomEntityResolver.java Sat Nov 13 12:19:30 2010 @@ -0,0 +1,157 @@ +/* + * 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.wicket.util.xml; + +import org.apache.wicket.util.lang.Args; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import javax.servlet.Filter; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +/** + * entity resolver that tries to locate a document type definition (DTD) using a set of custom entity resolvers + * + * @author pete + */ +public class CustomEntityResolver implements EntityResolver +{ + private final Map<EntityKey, EntityLocator> entities = new HashMap<EntityKey, EntityLocator>(3); + + /** + * get default instances of custom entity resolver with preloaded well-known entities + * + * @return instance of resolver + */ + public static CustomEntityResolver getPreloaded() + { + CustomEntityResolver resolver = new CustomEntityResolver(); + + resolver.put(new EntityKey("-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN", + "http://java.sun.com/dtd/web-app_2_3.dtd"), + new ServletApiEntityLocator("web-app_2_3.dtd")); + + return resolver; + } + + /** + * add custom entity resolver + * + * @param key key for lookup (contains id and url) + * @param locator locator for looking up entity + */ + public void put(EntityKey key, EntityLocator locator) + { + Args.notNull(key, "key"); + Args.notNull(locator, "locator"); + entities.put(key, locator); + } + + public InputSource resolveEntity(String id, String url) throws SAXException, IOException + { + for (Map.Entry<EntityKey, EntityLocator> entry : entities.entrySet()) + if (entry.getKey().id.equals(id) || entry.getKey().url.equals(url)) + return entry.getValue().locateInputSource(); + + return null; + } + + /** + * key for entity + * <p/> + * consists of id + url + */ + public static class EntityKey + { + private final String id; + private final String url; + + private EntityKey(String id, String url) + { + Args.notEmpty(id, "id"); + Args.notEmpty(url, "url"); + this.id = id; + this.url = url; + } + + @Override + public boolean equals(Object o) + { + if (this == o) + return true; + if (!(o instanceof EntityKey)) + return false; + + EntityKey key = (EntityKey) o; + + if (!id.equals(key.id)) + return false; + + return url.equals(key.url); + } + + @Override + public int hashCode() + { + int result = id.hashCode(); + result = 31 * result + url.hashCode(); + return result; + } + } + + /** + * entity locator + * <p/> + * manages locating an entity + */ + public static interface EntityLocator + { + InputSource locateInputSource() throws SAXException, IOException; + } + + /** + * entity locator for resources inside servlet-api.jar + */ + public static class ServletApiEntityLocator implements EntityLocator + { + private final String name; + + private ServletApiEntityLocator(String name) + { + this.name = name; + } + + /** + * resolve servlet api resource, where e.g. 'web-app_2_3.dtd' is located + * + * @return input source + */ + public InputSource locateInputSource() + { + InputStream stream = Filter.class.getResourceAsStream("resources/" + name); + + if (stream == null) + return null; + + return new InputSource(stream); + } + } +}