Author: jboynes
Date: Sat Nov 29 16:06:54 2014
New Revision: 1642442
URL: http://svn.apache.org/r1642442
Log:
Refactor and consolidate XML processing
Added:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XmlUtil.java
(with props)
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/util/UnclosableWriter.java
(with props)
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/util/UrlUtil.java
(with props)
Modified:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/ImportSupport.java
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/RedirectSupport.java
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/UrlSupport.java
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XalanUtil.java
tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/ExprSupportTest.java
tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/ForEachTagTest.java
tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/JSTLVariableStackTest.java
Modified:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/ImportSupport.java
URL:
http://svn.apache.org/viewvc/tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/ImportSupport.java?rev=1642442&r1=1642441&r2=1642442&view=diff
==============================================================================
---
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/ImportSupport.java
(original)
+++
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/ImportSupport.java
Sat Nov 29 16:06:54 2014
@@ -47,6 +47,7 @@ import javax.servlet.jsp.tagext.BodyTagS
import javax.servlet.jsp.tagext.TryCatchFinally;
import org.apache.taglibs.standard.resources.Resources;
+import org.apache.taglibs.standard.util.UrlUtil;
/**
* <p>Support for tag handlers for <import>, the general-purpose
@@ -63,23 +64,6 @@ public abstract class ImportSupport exte
// Public constants
/**
- * <p>Valid characters in a scheme.</p>
- * <p>RFC 1738 says the following:</p>
- * <blockquote>
- * Scheme names consist of a sequence of characters. The lower
- * case letters "a"--"z", digits, and the characters plus ("+"),
- * period ("."), and hyphen ("-") are allowed. For resiliency,
- * programs interpreting URLs should treat upper case letters as
- * equivalent to lower case in scheme names (e.g., allow "HTTP" as
- * well as "http").
- * </blockquote>
- * <p>We treat as absolute any URL that begins with such a scheme name,
- * followed by a colon.</p>
- */
- public static final String VALID_SCHEME_CHARS =
-
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+.-";
-
- /**
* Default character encoding for response.
*/
public static final String DEFAULT_ENCODING = "ISO-8859-1";
@@ -141,7 +125,7 @@ public abstract class ImportSupport exte
}
// Record whether our URL is absolute or relative
- isAbsoluteUrl = isAbsoluteUrl();
+ isAbsoluteUrl = UrlUtil.isAbsoluteUrl(url);
try {
// If we need to expose a Reader, we've got to do it right away
@@ -579,47 +563,11 @@ public abstract class ImportSupport exte
return urlWithParams;
}
- /**
- * Returns <tt>true</tt> if our current URL is absolute,
- * <tt>false</tt> otherwise.
- */
- private boolean isAbsoluteUrl() throws JspTagException {
- return isAbsoluteUrl(url);
- }
-
//*********************************************************************
// Public utility methods
/**
- * Returns <tt>true</tt> if our current URL is absolute,
- * <tt>false</tt> otherwise.
- */
- public static boolean isAbsoluteUrl(String url) {
- // a null URL is not absolute, by our definition
- if (url == null) {
- return false;
- }
-
- // do a fast, simple check first
- int colonPos;
- if ((colonPos = url.indexOf(":")) == -1) {
- return false;
- }
-
- // if we DO have a colon, make sure that every character
- // leading up to it is a valid scheme character
- for (int i = 0; i < colonPos; i++) {
- if (VALID_SCHEME_CHARS.indexOf(url.charAt(i)) == -1) {
- return false;
- }
- }
-
- // if so, we've got an absolute url
- return true;
- }
-
- /**
* Strips a servlet session ID from <tt>url</tt>. The session ID
* is encoded as a URL "path parameter" beginning with "jsessionid=".
* We thus remove anything we find between ";jsessionid=" (inclusive)
Modified:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/RedirectSupport.java
URL:
http://svn.apache.org/viewvc/tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/RedirectSupport.java?rev=1642442&r1=1642441&r2=1642442&view=diff
==============================================================================
---
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/RedirectSupport.java
(original)
+++
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/RedirectSupport.java
Sat Nov 29 16:06:54 2014
@@ -23,6 +23,8 @@ import javax.servlet.jsp.JspTagException
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;
+import org.apache.taglibs.standard.util.UrlUtil;
+
/**
* <p>Support for tag handlers for <redirect>, JSTL 1.0's tag
* for redirecting to a new URL (with optional query parameters).</p>
@@ -108,7 +110,7 @@ public abstract class RedirectSupport ex
// if the URL is relative, rewrite it with 'redirect' encoding rules
HttpServletResponse response =
((HttpServletResponse) pageContext.getResponse());
- if (!ImportSupport.isAbsoluteUrl(result)) {
+ if (!UrlUtil.isAbsoluteUrl(result)) {
result = response.encodeRedirectURL(result);
}
Modified:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/UrlSupport.java
URL:
http://svn.apache.org/viewvc/tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/UrlSupport.java?rev=1642442&r1=1642441&r2=1642442&view=diff
==============================================================================
---
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/UrlSupport.java
(original)
+++
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/core/UrlSupport.java
Sat Nov 29 16:06:54 2014
@@ -25,6 +25,7 @@ import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;
import org.apache.taglibs.standard.resources.Resources;
+import org.apache.taglibs.standard.util.UrlUtil;
/**
* <p>Support for tag handlers for <url>, the URL creation
@@ -110,7 +111,7 @@ public abstract class UrlSupport extends
result = params.aggregateParams(baseUrl);
// if the URL is relative, rewrite it
- if (!ImportSupport.isAbsoluteUrl(result)) {
+ if (!UrlUtil.isAbsoluteUrl(result)) {
HttpServletResponse response =
((HttpServletResponse) pageContext.getResponse());
result = response.encodeURL(result);
@@ -144,7 +145,7 @@ public abstract class UrlSupport extends
String url, String context, PageContext pageContext)
throws JspException {
// don't touch absolute URLs
- if (ImportSupport.isAbsoluteUrl(url)) {
+ if (UrlUtil.isAbsoluteUrl(url)) {
return url;
}
Modified:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java
URL:
http://svn.apache.org/viewvc/tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java?rev=1642442&r1=1642441&r2=1642442&view=diff
==============================================================================
---
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java
(original)
+++
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java
Sat Nov 29 16:06:54 2014
@@ -17,36 +17,26 @@
package org.apache.taglibs.standard.tag.common.xml;
-import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
-import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
-import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import org.apache.taglibs.standard.resources.Resources;
-import org.apache.taglibs.standard.tag.common.core.ImportSupport;
import org.apache.taglibs.standard.tag.common.core.Util;
import org.w3c.dom.Document;
-import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLFilter;
import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
/**
* <p>Support for tag handlers for <parse>, the XML parsing tag.</p>
@@ -69,12 +59,7 @@ public abstract class ParseSupport exten
private String varDom; // 'varDom' attribute
private int scope; // processed 'scope' attr
private int scopeDom; // processed 'scopeDom' attr
-
- // state in support of XML parsing...
- private DocumentBuilderFactory dbf;
- private DocumentBuilder db;
- private TransformerFactory tf;
- private TransformerHandler th;
+ private XmlUtil.JstlEntityResolver entityResolver;
//*********************************************************************
@@ -90,15 +75,10 @@ public abstract class ParseSupport exten
xml = null;
systemId = null;
filter = null;
- dbf = null;
- db = null;
- tf = null;
- th = null;
scope = PageContext.PAGE_SCOPE;
scopeDom = PageContext.PAGE_SCOPE;
}
-
//*********************************************************************
// Tag logic
@@ -106,68 +86,41 @@ public abstract class ParseSupport exten
@Override
public int doEndTag() throws JspException {
- try {
-
- // set up our DocumentBuilder
- if (dbf == null) {
- dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- dbf.setValidating(false);
- }
- db = dbf.newDocumentBuilder();
-
- // if we've gotten a filter, set up a transformer to support it
- if (filter != null) {
- if (tf == null) {
- tf = TransformerFactory.newInstance();
- }
- if (!tf.getFeature(SAXTransformerFactory.FEATURE)) {
- throw new JspTagException(
- Resources.getMessage("PARSE_NO_SAXTRANSFORMER"));
- }
- SAXTransformerFactory stf = (SAXTransformerFactory) tf;
- th = stf.newTransformerHandler();
- }
-
- // produce a Document by parsing whatever the attributes tell us
to use
- Document d;
- Object xmlText = this.xml;
- if (xmlText == null) {
- // if the attribute was specified, use the body as 'xml'
- if (bodyContent != null && bodyContent.getString() != null) {
- xmlText = bodyContent.getString().trim();
- } else {
- xmlText = "";
- }
- }
- if (xmlText instanceof String) {
- d = parseStringWithFilter((String) xmlText, filter);
- } else if (xmlText instanceof Reader) {
- d = parseReaderWithFilter((Reader) xmlText, filter);
+ // produce a Document by parsing whatever the attributes tell us to use
+ Object xmlText = this.xml;
+ if (xmlText == null) {
+ // if the attribute was specified, use the body as 'xml'
+ if (bodyContent != null && bodyContent.getString() != null) {
+ xmlText = bodyContent.getString().trim();
} else {
- throw new JspTagException(
- Resources.getMessage("PARSE_INVALID_SOURCE"));
+ xmlText = "";
}
+ }
+ if (xmlText instanceof String) {
+ xmlText = new StringReader((String) xmlText);
+ }
+ if (!(xmlText instanceof Reader)) {
+ throw new
JspTagException(Resources.getMessage("PARSE_INVALID_SOURCE"));
+ }
+ InputSource source = XmlUtil.newInputSource(((Reader) xmlText),
systemId);
- // we've got a Document object; store it out as appropriate
- // (let any exclusivity or other constraints be enforced by
TEI/TLV)
- if (var != null) {
- pageContext.setAttribute(var, d, scope);
- }
- if (varDom != null) {
- pageContext.setAttribute(varDom, d, scopeDom);
- }
+ Document d;
+ if (filter != null) {
+ d = parseInputSourceWithFilter(source, filter);
+ } else {
+ d = parseInputSource(source);
+ }
- return EVAL_PAGE;
- } catch (SAXException ex) {
- throw new JspException(ex);
- } catch (IOException ex) {
- throw new JspException(ex);
- } catch (ParserConfigurationException ex) {
- throw new JspException(ex);
- } catch (TransformerConfigurationException ex) {
- throw new JspException(ex);
+ // we've got a Document object; store it out as appropriate
+ // (let any exclusivity or other constraints be enforced by TEI/TLV)
+ if (var != null) {
+ pageContext.setAttribute(var, d, scope);
}
+ if (varDom != null) {
+ pageContext.setAttribute(varDom, d, scopeDom);
+ }
+
+ return EVAL_PAGE;
}
// Releases any resources we may have (or inherit)
@@ -184,151 +137,50 @@ public abstract class ParseSupport exten
/**
* Parses the given InputSource after, applying the given XMLFilter.
*/
- private Document parseInputSourceWithFilter(InputSource s, XMLFilter f)
- throws SAXException, IOException {
- if (f != null) {
- // prepare an output Document
- Document o = db.newDocument();
-
- // use TrAX to adapt SAX events to a Document object
- th.setResult(new DOMResult(o));
- XMLReader xr = XMLReaderFactory.createXMLReader();
- xr.setEntityResolver(new JstlEntityResolver(pageContext));
+ private Document parseInputSourceWithFilter(InputSource s, XMLFilter f)
throws JspException {
+ try {
+ XMLReader xr = XmlUtil.newXMLReader(entityResolver);
// (note that we overwrite the filter's parent. this seems
// to be expected usage. we could cache and reset the old
// parent, but you can't setParent(null), so this wouldn't
// be perfect.)
f.setParent(xr);
+
+ TransformerHandler th = XmlUtil.newTransformerHandler();
+ Document o = XmlUtil.newEmptyDocument();
+ th.setResult(new DOMResult(o));
f.setContentHandler(th);
+
f.parse(s);
return o;
- } else {
- return parseInputSource(s);
+ } catch (IOException e) {
+ throw new JspException(e);
+ } catch (SAXException e) {
+ throw new JspException(e);
+ } catch (TransformerConfigurationException e) {
+ throw new JspException(e);
}
}
/**
- * Parses the given Reader after applying the given XMLFilter.
- */
- private Document parseReaderWithFilter(Reader r, XMLFilter f)
- throws SAXException, IOException {
- return parseInputSourceWithFilter(new InputSource(r), f);
- }
-
- /**
- * Parses the given String after applying the given XMLFilter.
- */
- private Document parseStringWithFilter(String s, XMLFilter f)
- throws SAXException, IOException {
- StringReader r = new StringReader(s);
- return parseReaderWithFilter(r, f);
- }
-
- /**
- * Parses the given Reader after applying the given XMLFilter.
- */
- private Document parseURLWithFilter(String url, XMLFilter f)
- throws SAXException, IOException {
- return parseInputSourceWithFilter(new InputSource(url), f);
- }
-
- /**
* Parses the given InputSource into a Document.
*/
- private Document parseInputSource(InputSource s)
- throws SAXException, IOException {
- db.setEntityResolver(new JstlEntityResolver(pageContext));
-
- // normalize URIs so they can be processed consistently by resolver
- if (systemId == null) {
- s.setSystemId("jstl:");
- } else if (ImportSupport.isAbsoluteUrl(systemId)) {
- s.setSystemId(systemId);
- } else {
- s.setSystemId("jstl:" + systemId);
+ private Document parseInputSource(InputSource s) throws JspException {
+ try {
+ DocumentBuilder db = XmlUtil.newDocumentBuilder();
+ db.setEntityResolver(entityResolver);
+ return db.parse(s);
+ } catch (SAXException e) {
+ throw new JspException(e);
+ } catch (IOException e) {
+ throw new JspException(e);
}
- return db.parse(s);
}
- /**
- * Parses the given Reader into a Document.
- */
- private Document parseReader(Reader r) throws SAXException, IOException {
- return parseInputSource(new InputSource(r));
- }
-
- /**
- * Parses the given String into a Document.
- */
- private Document parseString(String s) throws SAXException, IOException {
- StringReader r = new StringReader(s);
- return parseReader(r);
- }
-
- /**
- * Parses the URL (passed as a String) into a Document.
- */
- private Document parseURL(String url) throws SAXException, IOException {
- return parseInputSource(new InputSource(url));
- }
-
- //*********************************************************************
- // JSTL-specific EntityResolver class
-
- /**
- * Lets us resolve relative external entities.
- */
- public static class JstlEntityResolver implements EntityResolver {
- private final PageContext ctx;
-
- public JstlEntityResolver(PageContext ctx) {
- this.ctx = ctx;
- }
-
- public InputSource resolveEntity(String publicId, String systemId)
- throws FileNotFoundException {
-
- // pass if we don't have a systemId
- if (systemId == null) {
- return null;
- }
-
- // strip leading "jstl:" off URL if applicable
- if (systemId.startsWith("jstl:")) {
- systemId = systemId.substring(5);
- }
-
- // we're only concerned with relative URLs
- if (ImportSupport.isAbsoluteUrl(systemId)) {
- return null;
- }
-
- // for relative URLs, load and wrap the resource.
- // don't bother checking for 'null' since we specifically want
- // the parser to fail if the resource doesn't exist
- InputStream s;
- if (systemId.startsWith("/")) {
- s = ctx.getServletContext().getResourceAsStream(systemId);
- if (s == null) {
- throw new FileNotFoundException(
- Resources.getMessage("UNABLE_TO_RESOLVE_ENTITY",
- systemId));
- }
- } else {
- String pagePath =
- ((HttpServletRequest)
ctx.getRequest()).getServletPath();
- String basePath =
- pagePath.substring(0, pagePath.lastIndexOf("/"));
- s = ctx.getServletContext().getResourceAsStream(
- basePath + "/" + systemId);
- if (s == null) {
- throw new FileNotFoundException(
- Resources.getMessage("UNABLE_TO_RESOLVE_ENTITY",
- systemId));
- }
- }
- return new InputSource(s);
- }
+ @Override
+ public void setPageContext(PageContext pageContext) {
+ super.setPageContext(pageContext);
+ entityResolver = pageContext == null ? null: new
XmlUtil.JstlEntityResolver(pageContext);
}
//*********************************************************************
Modified:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java
URL:
http://svn.apache.org/viewvc/tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java?rev=1642442&r1=1642441&r2=1642442&view=diff
==============================================================================
---
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java
(original)
+++
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java
Sat Nov 29 16:06:54 2014
@@ -17,43 +17,29 @@
package org.apache.taglibs.standard.tag.common.xml;
-import java.io.IOException;
-import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
-import java.io.Writer;
import java.util.List;
-import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
import org.apache.taglibs.standard.resources.Resources;
-import org.apache.taglibs.standard.tag.common.core.ImportSupport;
import org.apache.taglibs.standard.tag.common.core.Util;
+import org.apache.taglibs.standard.util.UnclosableWriter;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
-import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
/**
* <p>Support for tag handlers for <transform>, the XML transformation
@@ -79,24 +65,14 @@ public abstract class TransformSupport e
private String var; // 'var' attribute
private int scope; // processed 'scope' attr
private Transformer t; // actual Transformer
- private TransformerFactory tf; // reusable factory
- private DocumentBuilder db; // reusable factory
+ private XmlUtil.JstlEntityResolver entityResolver;
+ private XmlUtil.JstlUriResolver uriResolver;
//*********************************************************************
// Constructor and initialization
public TransformSupport() {
- try {
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- dbf.setValidating(false);
- db = dbf.newDocumentBuilder();
- tf = TransformerFactory.newInstance();
- } catch (ParserConfigurationException e) {
- throw (AssertionError) new AssertionError("Unable to create
DocumentBuilder").initCause(e);
- }
-
init();
}
@@ -106,7 +82,6 @@ public abstract class TransformSupport e
xmlSystemId = xsltSystemId = null;
var = null;
result = null;
- tf.setURIResolver(null);
scope = PageContext.PAGE_SCOPE;
}
@@ -117,36 +92,69 @@ public abstract class TransformSupport e
@Override
public int doStartTag() throws JspException {
// set up transformer in the start tag so that nested <param> tags can
set parameters directly
- t = getTransformer(xslt, xsltSystemId);
+ if (xslt == null) {
+ throw new
JspTagException(Resources.getMessage("TRANSFORM_XSLT_IS_NULL"));
+ }
+
+ Source source;
+ try {
+ if (xslt instanceof Source) {
+ source = (Source) xslt;
+ } else if (xslt instanceof String) {
+ String s = (String) xslt;
+ s = s.trim();
+ if (s.length() == 0) {
+ throw new
JspTagException(Resources.getMessage("TRANSFORM_XSLT_IS_EMPTY"));
+ }
+ source = XmlUtil.newSAXSource(new StringReader(s),
xsltSystemId, entityResolver);
+ } else if (xslt instanceof Reader) {
+ source = XmlUtil.newSAXSource((Reader) xslt, xsltSystemId,
entityResolver);
+ } else {
+ throw new
JspTagException(Resources.getMessage("TRANSFORM_XSLT_UNSUPPORTED_TYPE",
xslt.getClass()));
+ }
+ } catch (SAXException e) {
+ throw new JspException(e);
+ }
+
+ try {
+ t = XmlUtil.newTransformer(source);
+ t.setURIResolver(uriResolver);
+ } catch (TransformerConfigurationException e) {
+ throw new JspTagException(e);
+ } catch (RuntimeException e) {
+ throw e;
+ }
return EVAL_BODY_BUFFERED;
}
@Override
public int doEndTag() throws JspException {
- Source source = xmlSpecified ? getSourceFromXmlAttribute() :
getDocumentFromBodyContent();
try {
- //************************************
- // Conduct the transformation
+ Source source = xmlSpecified ? getSourceFromXmlAttribute() :
getSourceFromBodyContent();
- // we can assume at most one of 'var' or 'result' is specified
- if (result != null)
- // we can write directly to the Result
- {
- t.transform(source, result);
- } else if (var != null) {
- // we need a Document
- Document d = db.newDocument();
+ // Conduct the transformation
+ if (var != null) {
+ // Save the result to var.
+ Document d = XmlUtil.newEmptyDocument();
Result doc = new DOMResult(d);
t.transform(source, doc);
pageContext.setAttribute(var, d, scope);
} else {
- Result page = new StreamResult(new
SafeWriter(pageContext.getOut()));
- t.transform(source, page);
+ // Write to out if result is not specified.
+ Result out = result;
+ if (out == null) {
+ out = new StreamResult(new
UnclosableWriter(pageContext.getOut()));
+ }
+ t.transform(source, out);
}
return EVAL_PAGE;
} catch (TransformerException ex) {
throw new JspException(ex);
+ } catch (SAXException e) {
+ throw new JspException(e);
+ } finally {
+ t = null;
}
}
@@ -161,7 +169,8 @@ public abstract class TransformSupport e
@Override
public void setPageContext(PageContext pageContext) {
super.setPageContext(pageContext);
- tf.setURIResolver(pageContext == null ? null : new
JstlUriResolver(pageContext));
+ uriResolver = pageContext == null ? null : new
XmlUtil.JstlUriResolver(pageContext);
+ entityResolver = pageContext == null ? null : new
XmlUtil.JstlEntityResolver(pageContext);
}
@@ -180,64 +189,12 @@ public abstract class TransformSupport e
// Utility methods
/**
- * Wraps systemId with a "jstl:" prefix to prevent the parser from
- * thinking that the URI is truly relative and resolving it against
- * the current directory in the filesystem.
- */
- private static String wrapSystemId(String systemId) {
- if (systemId == null) {
- return "jstl:";
- } else if (ImportSupport.isAbsoluteUrl(systemId)) {
- return systemId;
- } else {
- return ("jstl:" + systemId);
- }
- }
-
- /**
- * Create a Transformer from the xslt attribute.
- *
- * @param xslt the xslt attribute
- * @param systemId the systemId for the transform
- * @return an XSLT transformer
- * @throws JspException if there was a problem creating the transformer
- */
- Transformer getTransformer(Object xslt, String systemId) throws
JspException {
- if (xslt == null) {
- throw new
JspTagException(Resources.getMessage("TRANSFORM_XSLT_IS_NULL"));
- }
- Source source;
- if (xslt instanceof Source) {
- source = (Source) xslt;
- } else {
- if (xslt instanceof String) {
- String s = (String) xslt;
- s = s.trim();
- if (s.length() == 0) {
- throw new
JspTagException(Resources.getMessage("TRANSFORM_XSLT_IS_EMPTY"));
- }
- xslt = new StringReader(s);
- }
- if (xslt instanceof Reader) {
- source = getSource((Reader) xslt, systemId);
- } else {
- throw new
JspTagException(Resources.getMessage("TRANSFORM_XSLT_UNSUPPORTED_TYPE",
xslt.getClass()));
- }
- }
- try {
- return tf.newTransformer(source);
- } catch (TransformerConfigurationException e) {
- throw new JspTagException(e);
- }
- }
-
- /**
* Return the Source for a document specified in the "doc" or "xml"
attribute.
*
* @return the document Source
* @throws JspTagException if there is a problem with the attribute
*/
- Source getSourceFromXmlAttribute() throws JspTagException {
+ Source getSourceFromXmlAttribute() throws JspTagException, SAXException {
Object xml = this.xml;
if (xml == null) {
throw new
JspTagException(Resources.getMessage("TRANSFORM_XML_IS_NULL"));
@@ -261,10 +218,10 @@ public abstract class TransformSupport e
if (s.length() == 0) {
throw new
JspTagException(Resources.getMessage("TRANSFORM_XML_IS_EMPTY"));
}
- return getSource(new StringReader(s), xmlSystemId);
+ return XmlUtil.newSAXSource(new StringReader(s), xmlSystemId,
entityResolver);
}
if (xml instanceof Reader) {
- return getSource((Reader) xml, xmlSystemId);
+ return XmlUtil.newSAXSource((Reader) xml, xmlSystemId,
entityResolver);
}
if (xml instanceof Node) {
return new DOMSource((Node) xml, xmlSystemId);
@@ -278,7 +235,7 @@ public abstract class TransformSupport e
* @return the document Source
* @throws JspTagException if there is a problem with the body content
*/
- Source getDocumentFromBodyContent() throws JspTagException {
+ Source getSourceFromBodyContent() throws JspTagException, SAXException {
if (bodyContent == null) {
throw new
JspTagException(Resources.getMessage("TRANSFORM_BODY_IS_NULL"));
}
@@ -290,31 +247,7 @@ public abstract class TransformSupport e
if (s.length() == 0) {
throw new
JspTagException(Resources.getMessage("TRANSFORM_BODY_IS_EMPTY"));
}
- return getSource(new StringReader(s), xmlSystemId);
- }
-
- /**
- * Create a Source from a Reader
- *
- * @param reader the Reader to read
- * @param systemId the systemId for the document
- * @return a SAX Source
- * @throws JspTagException if there is a problem creating the Source
- */
- Source getSource(Reader reader, String systemId) throws JspTagException {
- try {
- // explicitly go through SAX to maintain control
- // over how relative external entities resolve
- XMLReader xr = XMLReaderFactory.createXMLReader();
- xr.setEntityResolver(new
ParseSupport.JstlEntityResolver(pageContext));
- InputSource s = new InputSource(reader);
- s.setSystemId(wrapSystemId(systemId));
- Source source = new SAXSource(xr, s);
- source.setSystemId(wrapSystemId(systemId));
- return source;
- } catch (SAXException e) {
- throw new JspTagException(e);
- }
+ return XmlUtil.newSAXSource(new StringReader(s), xmlSystemId,
entityResolver);
}
@@ -328,109 +261,4 @@ public abstract class TransformSupport e
public void setScope(String scope) {
this.scope = Util.getScope(scope);
}
-
-
- //*********************************************************************
- // Private utility classes
-
- /**
- * A Writer based on a wrapped Writer but ignoring requests to
- * close() and flush() it. (Someone must have wrapped the
- * toilet in my office similarly...)
- */
- private static class SafeWriter extends Writer {
- // TODO: shouldn't we be delegating all methods?
- private Writer w;
-
- public SafeWriter(Writer w) {
- this.w = w;
- }
-
- @Override
- public void close() {
- }
-
- @Override
- public void flush() {
- }
-
- @Override
- public void write(char[] cbuf, int off, int len) throws IOException {
- w.write(cbuf, off, len);
- }
- }
-
- //*********************************************************************
- // JSTL-specific URIResolver class
-
- /**
- * Lets us resolve relative external entities.
- */
- private static class JstlUriResolver implements URIResolver {
- private final PageContext ctx;
-
- public JstlUriResolver(PageContext ctx) {
- this.ctx = ctx;
- }
-
- public Source resolve(String href, String base)
- throws TransformerException {
-
- // pass if we don't have a systemId
- if (href == null) {
- return null;
- }
-
- // remove "jstl" marker from 'base'
- // NOTE: how 'base' is determined varies among different Xalan
- // xsltc implementations
- int index;
- if (base != null && (index = base.indexOf("jstl:")) != -1) {
- base = base.substring(index + 5);
- }
-
- // we're only concerned with relative URLs
- if (ImportSupport.isAbsoluteUrl(href)
- || (base != null && ImportSupport.isAbsoluteUrl(base))) {
- return null;
- }
-
- // base is relative; remove everything after trailing '/'
- if (base == null || base.lastIndexOf("/") == -1) {
- base = "";
- } else {
- base = base.substring(0, base.lastIndexOf("/") + 1);
- }
-
- // concatenate to produce the real URL we're interested in
- String target = base + href;
-
- // for relative URLs, load and wrap the resource.
- // don't bother checking for 'null' since we specifically want
- // the parser to fail if the resource doesn't exist
- InputStream s;
- if (target.startsWith("/")) {
- s = ctx.getServletContext().getResourceAsStream(target);
- if (s == null) {
- throw new TransformerException(
- Resources.getMessage("UNABLE_TO_RESOLVE_ENTITY",
- href));
- }
- } else {
- String pagePath =
- ((HttpServletRequest)
ctx.getRequest()).getServletPath();
- String basePath =
- pagePath.substring(0, pagePath.lastIndexOf("/"));
- s = ctx.getServletContext().getResourceAsStream(
- basePath + "/" + target);
- if (s == null) {
- throw new TransformerException(
- Resources.getMessage("UNABLE_TO_RESOLVE_ENTITY",
- href));
- }
- }
- return new StreamSource(s);
- }
- }
-
}
Modified:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XalanUtil.java
URL:
http://svn.apache.org/viewvc/tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XalanUtil.java?rev=1642442&r1=1642441&r2=1642442&view=diff
==============================================================================
---
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XalanUtil.java
(original)
+++
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XalanUtil.java
Sat Nov 29 16:06:54 2014
@@ -19,9 +19,6 @@ package org.apache.taglibs.standard.tag.
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.apache.xpath.VariableStack;
@@ -31,21 +28,11 @@ import org.apache.xpath.objects.XNodeSet
import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XString;
-import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
/**
*/
public class XalanUtil {
- private static final DocumentBuilderFactory dbf;
-
- static {
- // from Java5 on DocumentBuilderFactory is thread safe and hence can
be cached
- dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- dbf.setValidating(false);
- }
-
/**
* Return the XPathContext to be used for evaluating expressions.
*
@@ -67,29 +54,12 @@ public class XalanUtil {
XPathContext context = new XPathContext(false);
VariableStack variableStack = new JSTLVariableStack(pageContext);
context.setVarStack(variableStack);
- int dtm = context.getDTMHandleFromNode(newEmptyDocument());
+ int dtm = context.getDTMHandleFromNode(XmlUtil.newEmptyDocument());
context.pushCurrentNodeAndExpression(dtm, dtm);
return context;
}
/**
- * Create a new empty document.
- *
- * This method always allocates a new document as its root node might be
- * exposed to other tags and potentially be mutated.
- *
- * @return a new empty document
- */
- private static Document newEmptyDocument() {
- try {
- DocumentBuilder db = dbf.newDocumentBuilder();
- return db.newDocument();
- } catch (ParserConfigurationException e) {
- throw new AssertionError();
- }
- }
-
- /**
* Return the Java value corresponding to an XPath result.
*
* @param xo the XPath type
Added:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XmlUtil.java
URL:
http://svn.apache.org/viewvc/tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XmlUtil.java?rev=1642442&view=auto
==============================================================================
---
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XmlUtil.java
(added)
+++
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XmlUtil.java
Sat Nov 29 16:06:54 2014
@@ -0,0 +1,279 @@
+/*
+ * 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.taglibs.standard.tag.common.xml;
+
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.Reader;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.PageContext;
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.taglibs.standard.resources.Resources;
+import org.apache.taglibs.standard.util.UrlUtil;
+import org.w3c.dom.Document;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * Utilities for working with JAXP and SAX.
+ */
+public class XmlUtil {
+ private static final DocumentBuilderFactory dbf;
+ private static final SAXTransformerFactory stf;
+
+ static {
+ // from Java5 on DocumentBuilderFactory is thread safe and hence can
be cached
+ dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ dbf.setValidating(false);
+ try {
+ dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ } catch (ParserConfigurationException e) {
+ throw new AssertionError("Parser does not support secure
processing");
+ }
+
+ TransformerFactory tf = TransformerFactory.newInstance();
+ if (!(tf instanceof SAXTransformerFactory)) {
+ throw new AssertionError("TransformerFactory does not support
SAX");
+ }
+ try {
+ tf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ } catch (TransformerConfigurationException e) {
+ throw new AssertionError("TransformerFactory does not support
secure processing");
+ }
+ stf = (SAXTransformerFactory) tf;
+ }
+
+
+ /**
+ * Create a new empty document.
+ *
+ * This method always allocates a new document as its root node might be
+ * exposed to other tags and potentially be mutated.
+ *
+ * @return a new empty document
+ */
+ static Document newEmptyDocument() {
+ return newDocumentBuilder().newDocument();
+ }
+
+ /**
+ * Create a new DocumentBuilder configured for namespaces but not
validating.
+ *
+ * @return a new, configured DocumentBuilder
+ */
+ static DocumentBuilder newDocumentBuilder() {
+ try {
+ return dbf.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Create a new TransformerHandler.
+ * @return a new TransformerHandler
+ */
+ static TransformerHandler newTransformerHandler() throws
TransformerConfigurationException {
+ return stf.newTransformerHandler();
+ }
+
+ static Transformer newTransformer(Source source) throws
TransformerConfigurationException {
+ Transformer transformer = stf.newTransformer(source);
+ if (transformer == null) {
+ throw new TransformerConfigurationException("newTransformer
returned null");
+ }
+ return transformer;
+ }
+
+ /**
+ * Create an InputSource from a Reader.
+ *
+ * The systemId will be wrapped for use with JSTL's EntityResolver and
UriResolver.
+ *
+ * @param reader the source of the XML
+ * @param systemId the system id
+ * @return a configured InputSource
+ */
+ static InputSource newInputSource(Reader reader, String systemId) {
+ InputSource source = new InputSource(reader);
+ source.setSystemId(wrapSystemId(systemId));
+ return source;
+ }
+
+ /**
+ * Create an XMLReader that resolves entities using JSTL semantics.
+ * @param entityResolver for resolving using JSTL semamtics
+ * @return a new XMLReader
+ * @throws SAXException if there was a problem creating the reader
+ */
+ static XMLReader newXMLReader(JstlEntityResolver entityResolver) throws
SAXException {
+ XMLReader xmlReader = XMLReaderFactory.createXMLReader();
+ xmlReader.setEntityResolver(entityResolver);
+ return xmlReader;
+ }
+
+ /**
+ * Create a SAXSource from a Reader. Any entities will be resolved using
JSTL semantics.
+ *
+ * @param reader the source of the XML
+ * @param systemId the system id
+ * @param entityResolver for resolving using JSTL semamtics
+ * @return a new SAXSource
+ * @throws SAXException if there was a problem creating the source
+ */
+ static SAXSource newSAXSource(Reader reader, String systemId,
JstlEntityResolver entityResolver) throws SAXException {
+ SAXSource source = new SAXSource(newXMLReader(entityResolver), new
InputSource(reader));
+ source.setSystemId(wrapSystemId(systemId));
+ return source;
+ }
+
+ /**
+ * Wraps systemId with a "jstl:" prefix to prevent the parser from
+ * thinking that the URI is truly relative and resolving it against
+ * the current directory in the filesystem.
+ */
+ private static String wrapSystemId(String systemId) {
+ if (systemId == null) {
+ return "jstl:";
+ } else if (UrlUtil.isAbsoluteUrl(systemId)) {
+ return systemId;
+ } else {
+ return ("jstl:" + systemId);
+ }
+ }
+
+ /**
+ * JSTL-specific implementation of EntityResolver.
+ */
+ static class JstlEntityResolver implements EntityResolver {
+ private final PageContext ctx;
+
+ public JstlEntityResolver(PageContext ctx) {
+ this.ctx = ctx;
+ }
+
+ public InputSource resolveEntity(String publicId, String systemId)
throws FileNotFoundException {
+
+ // pass if we don't have a systemId
+ if (systemId == null) {
+ return null;
+ }
+
+ // strip leading "jstl:" off URL if applicable
+ if (systemId.startsWith("jstl:")) {
+ systemId = systemId.substring(5);
+ }
+
+ // we're only concerned with relative URLs
+ if (UrlUtil.isAbsoluteUrl(systemId)) {
+ return null;
+ }
+
+ // for relative URLs, load and wrap the resource.
+ // don't bother checking for 'null' since we specifically want
+ // the parser to fail if the resource doesn't exist
+ String path = systemId;
+ if (!path.startsWith("/")) {
+ String pagePath = ((HttpServletRequest)
ctx.getRequest()).getServletPath();
+ String basePath = pagePath.substring(0,
pagePath.lastIndexOf("/"));
+ path = basePath + "/" + systemId;
+ }
+
+ InputStream s = ctx.getServletContext().getResourceAsStream(path);
+ if (s == null) {
+ throw new
FileNotFoundException(Resources.getMessage("UNABLE_TO_RESOLVE_ENTITY",
systemId));
+ }
+ return new InputSource(s);
+ }
+ }
+
+ /**
+ * JSTL-specific implementation of URIResolver.
+ */
+ static class JstlUriResolver implements URIResolver {
+ private final PageContext ctx;
+
+ public JstlUriResolver(PageContext ctx) {
+ this.ctx = ctx;
+ }
+
+ public Source resolve(String href, String base) throws
TransformerException {
+
+ // pass if we don't have a systemId
+ if (href == null) {
+ return null;
+ }
+
+ // remove "jstl" marker from 'base'
+ // NOTE: how 'base' is determined varies among different Xalan
+ // xsltc implementations
+ int index;
+ if (base != null && (index = base.indexOf("jstl:")) != -1) {
+ base = base.substring(index + 5);
+ }
+
+ // we're only concerned with relative URLs
+ if (UrlUtil.isAbsoluteUrl(href)
+ || (base != null && UrlUtil.isAbsoluteUrl(base))) {
+ return null;
+ }
+
+ // base is relative; remove everything after trailing '/'
+ if (base == null || base.lastIndexOf("/") == -1) {
+ base = "";
+ } else {
+ base = base.substring(0, base.lastIndexOf("/") + 1);
+ }
+
+ // concatenate to produce the real URL we're interested in
+ String target = base + href;
+
+ // for relative URLs, load and wrap the resource.
+ // don't bother checking for 'null' since we specifically want
+ // the parser to fail if the resource doesn't exist
+ if (!target.startsWith("/")) {
+ String pagePath = ((HttpServletRequest)
ctx.getRequest()).getServletPath();
+ String basePath = pagePath.substring(0,
pagePath.lastIndexOf("/"));
+ target = basePath + "/" + target;
+ }
+ InputStream s =
ctx.getServletContext().getResourceAsStream(target);
+ if (s == null) {
+ throw new
TransformerException(Resources.getMessage("UNABLE_TO_RESOLVE_ENTITY", href));
+ }
+ return new StreamSource(s);
+ }
+ }
+}
Propchange:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XmlUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/util/UnclosableWriter.java
URL:
http://svn.apache.org/viewvc/tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/util/UnclosableWriter.java?rev=1642442&view=auto
==============================================================================
---
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/util/UnclosableWriter.java
(added)
+++
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/util/UnclosableWriter.java
Sat Nov 29 16:06:54 2014
@@ -0,0 +1,47 @@
+/*
+ * 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.taglibs.standard.util;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * A Writer based on a wrapped Writer but ignoring requests to
+ * close() and flush() it. (Someone must have wrapped the
+ * toilet in my office similarly...)
+ */
+public class UnclosableWriter extends Writer {
+ // TODO: shouldn't we be delegating all methods?
+ private Writer w;
+
+ public UnclosableWriter(Writer w) {
+ this.w = w;
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ w.write(cbuf, off, len);
+ }
+}
Propchange:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/util/UnclosableWriter.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/util/UrlUtil.java
URL:
http://svn.apache.org/viewvc/tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/util/UrlUtil.java?rev=1642442&view=auto
==============================================================================
---
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/util/UrlUtil.java
(added)
+++
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/util/UrlUtil.java
Sat Nov 29 16:06:54 2014
@@ -0,0 +1,80 @@
+/*
+ * 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.taglibs.standard.util;
+
+import java.util.BitSet;
+
+/**
+ * Utilities for working with URLs.
+ */
+public class UrlUtil {
+ /**
+ * <p>Valid characters in a scheme.</p>
+ * <p>RFC 1738 says the following:</p>
+ * <blockquote>
+ * Scheme names consist of a sequence of characters. The lower
+ * case letters "a"--"z", digits, and the characters plus ("+"),
+ * period ("."), and hyphen ("-") are allowed. For resiliency,
+ * programs interpreting URLs should treat upper case letters as
+ * equivalent to lower case in scheme names (e.g., allow "HTTP" as
+ * well as "http").
+ * </blockquote>
+ * <p>We treat as absolute any URL that begins with such a scheme name,
+ * followed by a colon.</p>
+ */
+/*
+ private static final String VALID_SCHEME_CHARS =
+
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+.-";
+*/
+ private static final BitSet VALID_SCHEME_CHARS;
+ static {
+ VALID_SCHEME_CHARS = new BitSet(128);
+ VALID_SCHEME_CHARS.set('A', 'Z' + 1);
+ VALID_SCHEME_CHARS.set('a', 'z' + 1);
+ VALID_SCHEME_CHARS.set('0', '9' + 1);
+ VALID_SCHEME_CHARS.set('+');
+ VALID_SCHEME_CHARS.set('.');
+ VALID_SCHEME_CHARS.set('-');
+ }
+
+ /**
+ * Determine if a URL is absolute by JSTL's definition.
+ */
+ public static boolean isAbsoluteUrl(String url) {
+ // a null URL is not absolute, by our definition
+ if (url == null) {
+ return false;
+ }
+
+ // do a fast, simple check first
+ int colonPos = url.indexOf(":");
+ if (colonPos == -1) {
+ return false;
+ }
+
+ // if we DO have a colon, make sure that every character
+ // leading up to it is a valid scheme character
+ for (int i = 0; i < colonPos; i++) {
+ if (!VALID_SCHEME_CHARS.get(url.charAt(i))) {
+ return false;
+ }
+ }
+
+ // if so, we've got an absolute url
+ return true;
+ }
+}
Propchange:
tomcat/taglibs/standard/trunk/impl/src/main/java/org/apache/taglibs/standard/util/UrlUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/ExprSupportTest.java
URL:
http://svn.apache.org/viewvc/tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/ExprSupportTest.java?rev=1642442&r1=1642441&r2=1642442&view=diff
==============================================================================
---
tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/ExprSupportTest.java
(original)
+++
tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/ExprSupportTest.java
Sat Nov 29 16:06:54 2014
@@ -21,7 +21,6 @@ import java.io.InputStream;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -45,10 +44,7 @@ public class ExprSupportTest {
@BeforeClass
public static void loadXml() throws Exception {
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- dbf.setValidating(false);
- DocumentBuilder db = dbf.newDocumentBuilder();
+ DocumentBuilder db = XmlUtil.newDocumentBuilder();
InputStream is = ExprSupportTest.class.getResourceAsStream("test.xml");
try {
test = db.parse(is);
Modified:
tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/ForEachTagTest.java
URL:
http://svn.apache.org/viewvc/tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/ForEachTagTest.java?rev=1642442&r1=1642441&r2=1642442&view=diff
==============================================================================
---
tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/ForEachTagTest.java
(original)
+++
tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/ForEachTagTest.java
Sat Nov 29 16:06:54 2014
@@ -20,41 +20,33 @@ import java.io.InputStream;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.IterationTag;
-import javax.servlet.jsp.tagext.Tag;
import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.xpath.XPathConstants;
-import org.apache.xpath.XPath;
-import org.apache.xpath.XPathContext;
-import org.apache.xpath.objects.XObject;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import sun.security.krb5.internal.TGSRep;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
/**
*/
public class ForEachTagTest {
private static Document test;
- private static DocumentBuilderFactory dbf;
@BeforeClass
public static void loadXml() throws Exception {
- dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- dbf.setValidating(false);
- DocumentBuilder db = dbf.newDocumentBuilder();
+ DocumentBuilder db = XmlUtil.newDocumentBuilder();
InputStream is = ExprSupportTest.class.getResourceAsStream("test.xml");
try {
test = db.parse(is);
@@ -126,8 +118,7 @@ public class ForEachTagTest {
public void testIterationPerformance() throws Exception {
// create a large document
final int SIZE = 200000;
- DocumentBuilder db = dbf.newDocumentBuilder();
- test = db.newDocument();
+ test = XmlUtil.newEmptyDocument();
Element root = test.createElement("root");
test.appendChild(root);
for (int i = 0; i < SIZE; i++) {
Modified:
tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/JSTLVariableStackTest.java
URL:
http://svn.apache.org/viewvc/tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/JSTLVariableStackTest.java?rev=1642442&r1=1642441&r2=1642442&view=diff
==============================================================================
---
tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/JSTLVariableStackTest.java
(original)
+++
tomcat/taglibs/standard/trunk/impl/src/test/java/org/apache/taglibs/standard/tag/common/xml/JSTLVariableStackTest.java
Sat Nov 29 16:06:54 2014
@@ -20,11 +20,13 @@ import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.PageContext;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
import org.apache.xml.utils.QName;
import org.apache.xpath.XPathContext;
import org.apache.xpath.objects.XBoolean;
@@ -32,16 +34,12 @@ import org.apache.xpath.objects.XNodeSet
import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XObjectFactory;
import org.apache.xpath.objects.XString;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
/**
*/
@@ -156,11 +154,7 @@ public class JSTLVariableStackTest {
Assert.assertTrue(XObjectFactory.create(1234, xpathContext) instanceof
XNumber);
Assert.assertTrue(XObjectFactory.create("Hello", xpathContext)
instanceof XString);
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- dbf.setValidating(false);
- DocumentBuilder db = dbf.newDocumentBuilder();
- Document d = db.newDocument();
+ Document d = XmlUtil.newEmptyDocument();
Element root = d.createElement("root");
XNodeSetForDOM xo = (XNodeSetForDOM) XObjectFactory.create(root,
xpathContext);
Assert.assertEquals(root, xo.object());
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]