Author: cbrisson Date: Sat Jul 7 15:38:57 2018 New Revision: 1835318 URL: http://svn.apache.org/viewvc?rev=1835318&view=rev Log: [tools] Enable XInclude support - have FileFactoryConfiguration convey URL rather than InputStream"
Modified: velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/main/webapp/WEB-INF/tools.xml velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/main/webapp/WEB-INF/web.xml velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/test/java/org/apache/velocity/examples/showcase/ViewToolsIT.java velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/ConfigurationUtils.java velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/FileFactoryConfiguration.java velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/PropertiesFactoryConfiguration.java velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/XmlFactoryConfiguration.java velocity/tools/trunk/velocity-tools-view/src/main/java/org/apache/velocity/tools/view/ServletUtils.java velocity/tools/trunk/velocity-tools-view/src/test/java/org/apache/velocity/tools/view/VelocityViewTest.java Modified: velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/main/webapp/WEB-INF/tools.xml URL: http://svn.apache.org/viewvc/velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/main/webapp/WEB-INF/tools.xml?rev=1835318&r1=1835317&r2=1835318&view=diff ============================================================================== --- velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/main/webapp/WEB-INF/tools.xml (original) +++ velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/main/webapp/WEB-INF/tools.xml Sat Jul 7 15:38:57 2018 @@ -19,7 +19,7 @@ under the License. --> -<tools> +<tools xmlns:xi="http://www.w3.org/2001/XInclude"> <data key="author">Nathan Bubna</data> <toolbox scope="request"> <tool class="org.apache.velocity.tools.examples.showcase.tool.LayoutLinkTool"/> @@ -39,4 +39,12 @@ <tool key="number" format="#0.0"/> <tool key="xml" file="file.xml" safeMode="false"/> </toolbox> + + <!-- xi:include tests --> + <!-- cbrisson: I'm a bit polluting the showcase example webapp with XInclude testcases + but those testcases have an example value in the source code as well + --> + <xi:include href="included/test-xinclude1.xml"/> + <xi:include href="included/test-xinclude2.xml" xpointer="element(/1/1)"/> <!-- xpointer() scheme is not supported by xerces --> + <data key="xinclude_3"><xi:include href="included/test-xinclude3.txt" parse="text"/></data> </tools> Modified: velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/main/webapp/WEB-INF/web.xml URL: http://svn.apache.org/viewvc/velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/main/webapp/WEB-INF/web.xml?rev=1835318&r1=1835317&r2=1835318&view=diff ============================================================================== --- velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/main/webapp/WEB-INF/web.xml (original) +++ velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/main/webapp/WEB-INF/web.xml Sat Jul 7 15:38:57 2018 @@ -23,29 +23,42 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3.0.xsd" version="3.0"> + <!-- servlets --> <servlet> <servlet-name>velocity</servlet-name> <servlet-class>org.apache.velocity.tools.examples.showcase.ShowcaseLayoutServlet</servlet-class> - <init-param> - <param-name>org.apache.velocity.tools.loadDefaults</param-name> - <param-value>true</param-value> - </init-param> - <init-param> - <param-name>org.apache.velocity.tools.cleanConfiguration</param-name> - <param-value>true</param-value> - </init-param> - <init-param> - <param-name>org.apache.velocity.tools.userCanOverwriteTools</param-name> - <param-value>false</param-value> - </init-param> </servlet> + <servlet> + <servlet-name>velocity-standard</servlet-name> + <servlet-class>org.apache.velocity.tools.view.VelocityViewServlet</servlet-class> + </servlet> + <!-- servlet mappings --> + <servlet-mapping> + <servlet-name>velocity-standard</servlet-name> + <url-pattern>nolayout/*</url-pattern> + </servlet-mapping> <servlet-mapping> <servlet-name>velocity</servlet-name> <url-pattern>*.vm</url-pattern> </servlet-mapping> + <!-- context params --> + <context-param> + <param-name>org.apache.velocity.tools.loadDefaults</param-name> + <param-value>true</param-value> + </context-param> + <context-param> + <param-name>org.apache.velocity.tools.cleanConfiguration</param-name> + <param-value>true</param-value> + </context-param> + <context-param> + <param-name>org.apache.velocity.tools.userCanOverwriteTools</param-name> + <param-value>false</param-value> + </context-param> + <!-- welcome file --> <welcome-file-list> <welcome-file>index.vm</welcome-file> </welcome-file-list> + <!-- listeners --> <listener> <listener-class>org.apache.velocity.tools.examples.showcase.sample.SampleListInitializer</listener-class> </listener> Modified: velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/test/java/org/apache/velocity/examples/showcase/ViewToolsIT.java URL: http://svn.apache.org/viewvc/velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/test/java/org/apache/velocity/examples/showcase/ViewToolsIT.java?rev=1835318&r1=1835317&r2=1835318&view=diff ============================================================================== --- velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/test/java/org/apache/velocity/examples/showcase/ViewToolsIT.java (original) +++ velocity/tools/trunk/velocity-tools-examples/velocity-tools-examples-showcase/src/test/java/org/apache/velocity/examples/showcase/ViewToolsIT.java Sat Jul 7 15:38:57 2018 @@ -208,7 +208,7 @@ public class ViewToolsIT { checkTextStart(resp, "get(java.lang.Object)", "org.apache.velocity.tools.view.ViewContextTool"); /* check keys (the only expected uppercase is in 'velocityCount') */ - checkTextRegex(resp, "getKeys()", "^\\[[a-z_A-Z]+(?:,\\s*[a-z_A-Z]+)*\\]$"); + checkTextRegex(resp, "getKeys()", "^\\[[a-z_A-Z][a-z_A-Z0-9]*(?:,\\s*[a-z_A-Z][a-z_A-Z0-9]*)*\\]$"); /* check toolbox */ checkTextRegex(resp,"getToolbox()","^\\{[a-z_A-Z]+=.*(?:,\\s*[a-z_A-Z]+=.*)*\\}$"); @@ -336,4 +336,11 @@ public class ViewToolsIT { checkText(resp, "foo", "bar"); } + public @Test void testXInclude() throws Exception + { + WebConversation conv = new WebConversation(); + WebRequest req = new GetMethodWebRequest(ROOT_URL+"nolayout/xinclude.txt"); + WebResponse resp = conv.getResponse(req); + assertEquals("success success success", resp.getText().trim()); + } } Modified: velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/ConfigurationUtils.java URL: http://svn.apache.org/viewvc/velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/ConfigurationUtils.java?rev=1835318&r1=1835317&r2=1835318&view=diff ============================================================================== --- velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/ConfigurationUtils.java (original) +++ velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/ConfigurationUtils.java Sat Jul 7 15:38:57 2018 @@ -331,30 +331,14 @@ public class ConfigurationUtils } // now, try to read the file - InputStream inputStream = null; try { - inputStream = url.openStream(); - config.read(inputStream); + config.read(url); } - catch (IOException ioe) + catch (Exception e) { return null; } - finally - { - if (inputStream != null) - { - try - { - inputStream.close(); - } - catch (IOException ioe) - { - throw new RuntimeException("Could not close input stream for "+path, ioe); - } - } - } return config; } Modified: velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/FileFactoryConfiguration.java URL: http://svn.apache.org/viewvc/velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/FileFactoryConfiguration.java?rev=1835318&r1=1835317&r2=1835318&view=diff ============================================================================== --- velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/FileFactoryConfiguration.java (original) +++ velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/FileFactoryConfiguration.java Sat Jul 7 15:38:57 2018 @@ -19,7 +19,6 @@ package org.apache.velocity.tools.config * under the License. */ -import java.io.InputStream; import java.io.IOException; import java.net.URL; @@ -29,8 +28,7 @@ import org.apache.velocity.exception.Res import org.apache.velocity.tools.ConversionUtils; /** - * Provides support for reading a configuration file from a specified path, - * This frees the user from having to obtain an InputStream themselves. + * Provides support for reading a configuration file from a specified path. * * @author Nathan Bubna * @version $Id: XmlFactoryConfiguration.java 511959 2007-02-26 19:24:39Z nbubna $ @@ -43,11 +41,11 @@ public abstract class FileFactoryConfigu } /** - * <p>Reads an configuration from an {@link InputStream}.</p> + * <p>Reads an configuration from an {@link URL}.</p> * - * @param input the InputStream to read from + * @param url the InputStream to read from */ - public abstract void read(InputStream input) throws IOException; + protected abstract void readImpl(URL url) throws IOException; /** * <p>Reads a configuration file from the specified file path @@ -115,7 +113,7 @@ public abstract class FileFactoryConfigu { try { - read(url, url.openStream(), required, log); + readImpl(url); // only add the sources which can be read addSource(" .read("+url.toString()+")"); } @@ -132,44 +130,4 @@ public abstract class FileFactoryConfigu } } } - - - protected void read(Object source, InputStream inputStream, - boolean required, Logger log) - { - try - { - read(inputStream); - } - catch (IOException ioe) - { - String msg = "InputStream could not be read from: "+source; - if (log != null) - { - log.debug(msg, ioe); - } - if (required) - { - throw new RuntimeException(msg, ioe); - } - } - finally - { - try - { - if (inputStream != null) - { - inputStream.close(); - } - } - catch (IOException ioe) - { - if (log != null) - { - log.error("Failed to close input stream for {}", source, ioe); - } - } - } - } - } Modified: velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/PropertiesFactoryConfiguration.java URL: http://svn.apache.org/viewvc/velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/PropertiesFactoryConfiguration.java?rev=1835318&r1=1835317&r2=1835318&view=diff ============================================================================== --- velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/PropertiesFactoryConfiguration.java (original) +++ velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/PropertiesFactoryConfiguration.java Sat Jul 7 15:38:57 2018 @@ -21,6 +21,7 @@ package org.apache.velocity.tools.config import java.io.InputStream; import java.io.IOException; +import java.net.URL; import java.util.Iterator; import org.apache.commons.beanutils.BeanUtils; import org.apache.velocity.util.ExtProperties; @@ -83,12 +84,12 @@ public class PropertiesFactoryConfigurat * <p>Reads an properties file from an {@link InputStream} * and uses it to configure this {@link FactoryConfiguration}.</p> * - * @param input the InputStream to read from + * @param url the URL to read from */ - public void read(InputStream input) throws IOException + protected void readImpl(URL url) throws IOException { ExtProperties props = new ExtProperties(); - props.load(input); + props.load(url.openStream()); // all factory settings should be prefixed with "tools" read(props.subset("tools")); Modified: velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/XmlFactoryConfiguration.java URL: http://svn.apache.org/viewvc/velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/XmlFactoryConfiguration.java?rev=1835318&r1=1835317&r2=1835318&view=diff ============================================================================== --- velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/XmlFactoryConfiguration.java (original) +++ velocity/tools/trunk/velocity-tools-generic/src/main/java/org/apache/velocity/tools/config/XmlFactoryConfiguration.java Sat Jul 7 15:38:57 2018 @@ -19,8 +19,8 @@ package org.apache.velocity.tools.config * under the License. */ -import java.io.InputStream; import java.io.IOException; +import java.net.URL; import org.xml.sax.SAXException; import org.apache.commons.digester3.Digester; import org.apache.commons.digester3.RuleSet; @@ -47,6 +47,11 @@ public class XmlFactoryConfiguration ext { private RuleSet ruleSet; + /** + * Creates an instance + * + * @see FactoryConfiguration#setSource(String) + */ public XmlFactoryConfiguration() { this(""); @@ -54,7 +59,7 @@ public class XmlFactoryConfiguration ext /** * Creates an instance using the specified string - * as an identifier to distinguish this instance when debugging. + * as an identifier to distinguish this instance when debugging * * @param id the name of the "source" of this instance * @see FactoryConfiguration#setSource(String) @@ -85,21 +90,23 @@ public class XmlFactoryConfiguration ext /** - * <p>Reads an XML document from an {@link InputStream} + * <p>Reads an XML document from an {@link URL} * and uses it to configure this {@link FactoryConfiguration}.</p> * - * @param input the InputStream to read from + * @param url the URL to read from */ - public void read(InputStream input) throws IOException + protected void readImpl(URL url) throws IOException { Digester digester = new Digester(); + digester.setNamespaceAware(true); + digester.setXIncludeAware(true); digester.setValidating(false); digester.setUseContextClassLoader(true); digester.push(this); digester.addRuleSet(getRuleSet()); try { - digester.parse(input); + digester.parse(url); } catch (SAXException saxe) { Modified: velocity/tools/trunk/velocity-tools-view/src/main/java/org/apache/velocity/tools/view/ServletUtils.java URL: http://svn.apache.org/viewvc/velocity/tools/trunk/velocity-tools-view/src/main/java/org/apache/velocity/tools/view/ServletUtils.java?rev=1835318&r1=1835317&r2=1835318&view=diff ============================================================================== --- velocity/tools/trunk/velocity-tools-view/src/main/java/org/apache/velocity/tools/view/ServletUtils.java (original) +++ velocity/tools/trunk/velocity-tools-view/src/main/java/org/apache/velocity/tools/view/ServletUtils.java Sat Jul 7 15:38:57 2018 @@ -25,6 +25,8 @@ import java.io.FileNotFoundException; import java.io.InputStream; import java.io.IOException; import java.lang.reflect.Constructor; +import java.net.MalformedURLException; +import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; import javax.servlet.FilterConfig; @@ -297,11 +299,15 @@ public class ServletUtils return null; } + protected static boolean isWebappResource(String path) + { + return path != null && (path.startsWith("WEB-INF") || path.startsWith("/WEB-INF")); + } + public static InputStream getInputStream(final String path, final ServletContext application) { InputStream inputStream = null; - boolean webappResource = path != null && (path.startsWith("WEB-INF") || path.startsWith("/WEB-INF")); - if (!webappResource) + if (!isWebappResource(path)) { // search classpath except for WEB-INF/* inputStream = ClassUtils.getResourceAsStream(path, ServletUtils.class); @@ -330,6 +336,48 @@ public class ServletUtils return inputStream; } + public static URL getURL(final String path, final ServletContext application) + { + URL url = null; + if (!isWebappResource(path)) + { + // search classpath except for WEB-INF/* + url = ClassUtils.getResource(path, ServletUtils.class); + } + else + { + // then webapp only for WEB-INF/* + if (System.getSecurityManager() != null) + { + url = AccessController.doPrivileged( + new PrivilegedAction<URL>() + { + @Override + public URL run() + { + try + { + return application.getResource(path); + } + catch (MalformedURLException mue) + { + return null; + } + } + }); + } + else + { + try + { + url = application.getResource(path); + } + catch (MalformedURLException mue) {} + } + } + return url; + } + public static FactoryConfiguration getConfiguration(ServletContext application) { Object obj = application.getAttribute(CONFIGURATION_KEY); @@ -348,11 +396,11 @@ public class ServletUtils return null; } - public static FactoryConfiguration getConfiguration(String path, ServletContext application) + public static FactoryConfiguration getConfiguration(final String path, final ServletContext application) { // first make sure we can even get such a file - InputStream inputStream = getInputStream(path, application); - if (inputStream == null) + URL url = getURL(path, application); + if (url == null) { return null; } @@ -378,25 +426,11 @@ public class ServletUtils // now, try to read the file try { - config.read(inputStream); + config.read(url); } - catch (IOException ioe) - { - throw new RuntimeException("Failed to load configuration at: "+path, ioe); - } - finally + catch (Exception e) { - try - { - if (inputStream != null) - { - inputStream.close(); - } - } - catch (IOException ioe) - { - throw new RuntimeException("Failed to close input stream for "+path, ioe); - } + throw new RuntimeException("Failed to load configuration at: "+path, e); } return config; } Modified: velocity/tools/trunk/velocity-tools-view/src/test/java/org/apache/velocity/tools/view/VelocityViewTest.java URL: http://svn.apache.org/viewvc/velocity/tools/trunk/velocity-tools-view/src/test/java/org/apache/velocity/tools/view/VelocityViewTest.java?rev=1835318&r1=1835317&r2=1835318&view=diff ============================================================================== --- velocity/tools/trunk/velocity-tools-view/src/test/java/org/apache/velocity/tools/view/VelocityViewTest.java (original) +++ velocity/tools/trunk/velocity-tools-view/src/test/java/org/apache/velocity/tools/view/VelocityViewTest.java Sat Jul 7 15:38:57 2018 @@ -26,6 +26,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; +import java.net.URL; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -114,7 +115,7 @@ public class VelocityViewTest expect(servletContext.getInitParameter(VelocityView.TOOLS_KEY)).andAnswer(eval((String)null)); expect(config.getInitParameter(VelocityView.TOOLS_KEY)).andAnswer(eval((String)null)); expect(servletContext.getAttribute(ServletUtils.CONFIGURATION_KEY)).andAnswer(eval((String)null)); - expect(servletContext.getResourceAsStream(VelocityView.USER_TOOLS_PATH)).andAnswer(eval((InputStream)null)); + expect(servletContext.getResource(VelocityView.USER_TOOLS_PATH)).andAnswer(eval((URL)null)); expect(request.getAttribute("javax.servlet.include.servlet_path")).andAnswer(eval("/charset-test.vm")); expect(request.getAttribute("javax.servlet.include.path_info")).andAnswer(eval((String)null));