junit
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ExprSupport.java (revision 1817516)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ExprSupport.java (working copy)
@@ -22,52 +22,52 @@
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.TagSupport;
-import javax.xml.transform.TransformerException;
import org.apache.taglibs.standard.util.EscapeXML;
-import org.apache.xpath.XPath;
-import org.apache.xpath.XPathContext;
+import org.apache.taglibs.standard.xpath.JSTLXPathCompiler;
+import org.apache.taglibs.standard.xpath.JSTLXPathExpression;
+import org.apache.taglibs.standard.xpath.JSTLXPathFactory;
/**
- * Tag handler for <out> in JSTL's XML library.
- * TODO: should we rename this to OutSupport to match the tag name?
+ * Tag handler for <out> in JSTL's XML library. TODO: should we rename
+ * this to OutSupport to match the tag name?
*
* @author Shawn Bayern
*/
public abstract class ExprSupport extends TagSupport {
- private XPath select;
- protected boolean escapeXml = true; // tag attribute
+ private JSTLXPathCompiler compiler;
+ private JSTLXPathExpression select;
+ protected boolean escapeXml = true; // tag attribute
- @Override
- public void release() {
- super.release();
- select = null;
- }
+ public ExprSupport() {
+ JSTLXPathFactory xpf = JSTLXPathFactory.getFactory();
+ compiler = xpf.newCompiler();
+ }
- //*********************************************************************
- // Tag logic
+ @Override
+ public void release() {
+ super.release();
+ compiler = null;
+ select = null;
+ }
- // applies XPath expression from 'select' and prints the result
- @Override
- public int doStartTag() throws JspException {
- try {
- XPathContext context = XalanUtil.getContext(this, pageContext);
- String result = select.execute(context, context.getCurrentNode(), null).str();
- EscapeXML.emit(result, escapeXml, pageContext.getOut());
- return SKIP_BODY;
- } catch (IOException ex) {
- throw new JspTagException(ex.toString(), ex);
- } catch (TransformerException e) {
- throw new JspTagException(e);
- }
- }
+ // *********************************************************************
+ // Tag logic
- public void setSelect(String select) {
- try {
- this.select = new XPath(select, null, null, XPath.SELECT);
- } catch (TransformerException e) {
- throw new AssertionError();
- }
- }
+ // applies XPath expression from 'select' and prints the result
+ @Override
+ public int doStartTag() throws JspException {
+ try {
+ String result = select.evaluateString(ForEachTag.getContext(this), pageContext);
+ EscapeXML.emit(result, escapeXml, pageContext.getOut());
+ return SKIP_BODY;
+ } catch (IOException ex) {
+ throw new JspTagException(ex.toString(), ex);
+ }
+ }
+
+ public void setSelect(String select) {
+ this.select = compiler.compile(select);
+ }
}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ForEachTag.java (revision 1817516)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ForEachTag.java (working copy)
@@ -17,15 +17,15 @@
package org.apache.taglibs.standard.tag.common.xml;
-import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.jstl.core.LoopTagSupport;
-import javax.xml.transform.TransformerException;
+import javax.servlet.jsp.tagext.Tag;
+import javax.servlet.jsp.tagext.TagSupport;
-import org.apache.xml.dtm.DTMIterator;
-import org.apache.xpath.XPath;
-import org.apache.xpath.XPathContext;
-import org.apache.xpath.objects.XObject;
+import org.apache.taglibs.standard.xpath.JSTLXPathCompiler;
+import org.apache.taglibs.standard.xpath.JSTLXPathContext;
+import org.apache.taglibs.standard.xpath.JSTLXPathExpression;
+import org.apache.taglibs.standard.xpath.JSTLXPathFactory;
/**
* Implementation of <x:forEach> tag using low-level Xalan API.
@@ -35,95 +35,67 @@
*/
public class ForEachTag extends LoopTagSupport {
- private XPath select;
- private XPathContext context;
+ private JSTLXPathCompiler compiler;
+ private JSTLXPathExpression select;
+ private JSTLXPathContext context;
- @Override
- public void release() {
- super.release();
- select = null;
- context = null;
- }
+ public ForEachTag() {
+ JSTLXPathFactory xpf = JSTLXPathFactory.getFactory();
+ compiler = xpf.newCompiler();
+ }
- @Override
- protected void prepare() throws JspTagException {
- context = XalanUtil.getContext(this, pageContext);
- try {
- XObject nodes = select.execute(context, context.getCurrentNode(), null);
+ @Override
+ public void release() {
+ super.release();
+ compiler = null;
+ select = null;
+ context = null;
+ }
- // create an iterator over the returned nodes and push into the context
- DTMIterator iterator = nodes.iter();
- context.pushContextNodeList(iterator);
- } catch (TransformerException e) {
- throw new JspTagException(e);
- }
- }
+ @Override
+ protected void prepare() throws JspTagException {
+ context = select.iterate(getContext(this), pageContext);
+ }
- @Override
- protected boolean hasNext() throws JspTagException {
- DTMIterator iterator = context.getContextNodeList();
- return iterator.getCurrentPos() < iterator.getLength();
- }
+ @Override
+ protected boolean hasNext() throws JspTagException {
+ return context.hasNext();
+ }
- @Override
- protected Object next() throws JspTagException {
- DTMIterator iterator = context.getContextNodeList();
- int next = iterator.nextNode();
- context.pushCurrentNode(next);
- return iterator.getDTM(next).getNode(next);
- }
+ @Override
+ protected Object next() throws JspTagException {
+ return context.next();
+ }
- @Override
- public int doAfterBody() throws JspException {
- // pop the context node after executing the body
- context.popCurrentNode();
- return super.doAfterBody();
- }
+ public void setSelect(String select) {
+ this.select = compiler.compile(select);
+ }
- @Override
- public void doFinally() {
- // context might be null as prepare is not called if end < begin
- if (context != null) {
- // pop the list of nodes being iterated
- context.popContextNodeList();
- context = null;
- }
- super.doFinally();
- }
+ public void setBegin(int begin) throws JspTagException {
+ this.beginSpecified = true;
+ this.begin = begin;
+ validateBegin();
+ }
- public void setSelect(String select) {
- try {
- this.select = new XPath(select, null, null, XPath.SELECT);
- } catch (TransformerException e) {
- throw new AssertionError();
- }
- }
+ public void setEnd(int end) throws JspTagException {
+ this.endSpecified = true;
+ this.end = end;
+ validateEnd();
+ }
- public void setBegin(int begin) throws JspTagException {
- this.beginSpecified = true;
- this.begin = begin;
- validateBegin();
- }
+ public void setStep(int step) throws JspTagException {
+ this.stepSpecified = true;
+ this.step = step;
+ validateStep();
+ }
- public void setEnd(int end) throws JspTagException {
- this.endSpecified = true;
- this.end = end;
- validateEnd();
- }
-
- public void setStep(int step) throws JspTagException {
- this.stepSpecified = true;
- this.step = step;
- validateStep();
- }
-
- /**
- * Return the current XPath context to support expression evaluation in nested tags.
- *
- * @return the current XPath context
- */
- XPathContext getContext() {
- return context;
- }
+ /* Retrieves the current context. */
+ public static JSTLXPathContext getContext(Tag child) {
+ ForEachTag forEachTag = (ForEachTag) TagSupport.findAncestorWithClass(child, ForEachTag.class);
+ if (forEachTag == null) {
+ return null;
+ } else {
+ return forEachTag.context;
+ }
+ }
}
-
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/IfTag.java (revision 1817516)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/IfTag.java (working copy)
@@ -19,13 +19,15 @@
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.jstl.core.ConditionalTagSupport;
-import javax.xml.transform.TransformerException;
-import org.apache.xpath.XPath;
-import org.apache.xpath.XPathContext;
+import org.apache.taglibs.standard.xpath.JSTLXPathCompiler;
+import org.apache.taglibs.standard.xpath.JSTLXPathExpression;
+import org.apache.taglibs.standard.xpath.JSTLXPathFactory;
/**
- * Tag handler for <if> in JSTL's XML library.
+ *
+ * Tag handler for <if> in JSTL's XML library.
+ *
*
* @author Shawn Bayern
*/
@@ -32,30 +34,27 @@
public class IfTag extends ConditionalTagSupport {
- private XPath select;
+ private JSTLXPathCompiler compiler;
+ private JSTLXPathExpression select;
+ public IfTag() {
+ JSTLXPathFactory xpf = JSTLXPathFactory.getFactory();
+ compiler = xpf.newCompiler();
+ }
- @Override
- public void release() {
- super.release();
- select = null;
- }
+ @Override
+ public void release() {
+ super.release();
+ compiler = null;
+ select = null;
+ }
- @Override
- protected boolean condition() throws JspTagException {
- XPathContext context = XalanUtil.getContext(this, pageContext);
- try {
- return select.bool(context, context.getCurrentNode(), null);
- } catch (TransformerException e) {
- throw new JspTagException(e);
- }
- }
+ @Override
+ protected boolean condition() throws JspTagException {
+ return select.evaluateBoolean(ForEachTag.getContext(this), pageContext);
+ }
- public void setSelect(String select) {
- try {
- this.select = new XPath(select, null, null, XPath.SELECT);
- } catch (TransformerException e) {
- throw new AssertionError();
- }
- }
+ public void setSelect(String select) {
+ this.select = compiler.compile(select);
+ }
}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/SetTag.java (revision 1817516)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/SetTag.java (working copy)
@@ -18,70 +18,73 @@
package org.apache.taglibs.standard.tag.common.xml;
import javax.servlet.jsp.JspException;
-import javax.servlet.jsp.JspTagException;
+//import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;
-import javax.xml.transform.TransformerException;
+//import javax.xml.transform.TransformerException;
import org.apache.taglibs.standard.tag.common.core.Util;
-import org.apache.xpath.XPath;
-import org.apache.xpath.XPathContext;
-import org.apache.xpath.objects.XObject;
+import org.apache.taglibs.standard.xpath.JSTLXPathCompiler;
+import org.apache.taglibs.standard.xpath.JSTLXPathExpression;
+import org.apache.taglibs.standard.xpath.JSTLXPathFactory;
+//import org.apache.xpath.XPath;
+//import org.apache.xpath.XPathContext;
+//import org.apache.xpath.objects.XObject;
/**
- * Tag handler for <set> in JSTL's XML library.
+ *
+ * Tag handler for <set> in JSTL's XML library.
+ *
*
* @author Shawn Bayern
*/
public class SetTag extends TagSupport {
- private XPath select;
- private String var;
- private int scope = PageContext.PAGE_SCOPE;
+ private JSTLXPathCompiler compiler;
+ private JSTLXPathExpression select;
+ private String var;
+ private int scope = PageContext.PAGE_SCOPE;
- //*********************************************************************
- // Construction and initialization
+ // *********************************************************************
+ // Construction and initialization
- @Override
- public void release() {
- super.release();
- select = null;
- var = null;
- }
+ public SetTag() {
+ JSTLXPathFactory xpf = JSTLXPathFactory.getFactory();
+ compiler = xpf.newCompiler();
+ }
- //*********************************************************************
- // Tag logic
+ @Override
+ public void release() {
+ super.release();
+ compiler = null;
+ select = null;
+ var = null;
+ }
- // applies XPath expression from 'select' and stores the result in 'var'
+ // *********************************************************************
+ // Tag logic
- @Override
- public int doStartTag() throws JspException {
- try {
- XPathContext context = XalanUtil.getContext(this, pageContext);
- XObject result = select.execute(context, context.getCurrentNode(), null);
- pageContext.setAttribute(var, XalanUtil.coerceToJava(result), scope);
- return SKIP_BODY;
- } catch (TransformerException e) {
- throw new JspTagException(e);
- }
- }
+ // applies XPath expression from 'select' and stores the result in 'var'
- //*********************************************************************
- // Attribute accessors
+ @Override
+ public int doStartTag() throws JspException {
+ Object result = select.evaluateObject(ForEachTag.getContext(this), pageContext);
+ pageContext.setAttribute(var, result, scope);
+ return SKIP_BODY;
+ }
- public void setSelect(String select) {
- try {
- this.select = new XPath(select, null, null, XPath.SELECT);
- } catch (TransformerException e) {
- throw new AssertionError();
- }
- }
+ // *********************************************************************
+ // Attribute accessors
- public void setVar(String var) {
- this.var = var;
- }
+ public void setSelect(String select) {
+ this.select = compiler.compile(select);
+ }
- public void setScope(String scope) {
- this.scope = Util.getScope(scope);
- }
+ public void setVar(String var) {
+ this.var = var;
+ }
+
+ public void setScope(String scope) {
+ this.scope = Util.getScope(scope);
+ }
}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/WhenTag.java (revision 1817516)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/WhenTag.java (working copy)
@@ -18,14 +18,16 @@
package org.apache.taglibs.standard.tag.common.xml;
import javax.servlet.jsp.JspTagException;
-import javax.xml.transform.TransformerException;
import org.apache.taglibs.standard.tag.common.core.WhenTagSupport;
-import org.apache.xpath.XPath;
-import org.apache.xpath.XPathContext;
+import org.apache.taglibs.standard.xpath.JSTLXPathCompiler;
+import org.apache.taglibs.standard.xpath.JSTLXPathExpression;
+import org.apache.taglibs.standard.xpath.JSTLXPathFactory;
/**
- * Tag handler for <if> in JSTL's XML library.
+ *
+ * Tag handler for <if> in JSTL's XML library.
+ *
*
* @author Shawn Bayern
*/
@@ -32,29 +34,27 @@
public class WhenTag extends WhenTagSupport {
- private XPath select;
+ private JSTLXPathCompiler compiler;
+ private JSTLXPathExpression select;
- @Override
- public void release() {
- super.release();
- select = null;
- }
+ public WhenTag() {
+ JSTLXPathFactory xpf = JSTLXPathFactory.getFactory();
+ compiler = xpf.newCompiler();
+ }
- @Override
- protected boolean condition() throws JspTagException {
- XPathContext context = XalanUtil.getContext(this, pageContext);
- try {
- return select.bool(context, context.getCurrentNode(), null);
- } catch (TransformerException e) {
- throw new JspTagException(e);
- }
- }
+ @Override
+ public void release() {
+ super.release();
+ compiler = null;
+ select = null;
+ }
- public void setSelect(String select) {
- try {
- this.select = new XPath(select, null, null, XPath.SELECT);
- } catch (TransformerException e) {
- throw new AssertionError();
- }
- }
+ @Override
+ protected boolean condition() throws JspTagException {
+ return select.evaluateBoolean(ForEachTag.getContext(this), pageContext);
+ }
+
+ public void setSelect(String select) {
+ this.select = compiler.compile(select);
+ }
}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/InvalidXPathException.java (nonexistent)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/InvalidXPathException.java (working copy)
@@ -0,0 +1,36 @@
+/*
+ * 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.xpath;
+
+/**
+ */
+public class InvalidXPathException extends RuntimeException {
+ public InvalidXPathException() {
+ }
+
+ public InvalidXPathException(String s) {
+ super(s);
+ }
+
+ public InvalidXPathException(String s, Throwable throwable) {
+ super(s, throwable);
+ }
+
+ public InvalidXPathException(Throwable throwable) {
+ super(throwable);
+ }
+}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/JSTLVariableResolver.java (nonexistent)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/JSTLVariableResolver.java (working copy)
@@ -0,0 +1,154 @@
+/*
+ * 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.xpath;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.PageContext;
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPathVariableResolver;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ */
+public class JSTLVariableResolver implements XPathVariableResolver, NamespaceContext {
+
+ private static enum Scope {
+ JSP, PARAM, HEADER, COOKIE, INITPARAM, PAGE, REQUEST, SESSION, APPLICATION
+ }
+
+ // Namespace URIs for JSTL implicit variables
+ private static final String PARAM_NS_URL = "http://java.sun.com/jstl/xpath/param";
+ private static final String HEADER_NS_URL = "http://java.sun.com/jstl/xpath/header";
+ private static final String COOKIE_NS_URL = "http://java.sun.com/jstl/xpath/cookie";
+ private static final String INITPARAM_NS_URL = "http://java.sun.com/jstl/xpath/initParam";
+ private static final String PAGE_NS_URL = "http://java.sun.com/jstl/xpath/page";
+ private static final String REQUEST_NS_URL = "http://java.sun.com/jstl/xpath/request";
+ private static final String SESSION_NS_URL = "http://java.sun.com/jstl/xpath/session";
+ private static final String APP_NS_URL = "http://java.sun.com/jstl/xpath/app";
+
+ // Prefixes for JSTL implicit variables
+ private static final String PARAM_PREFIX = "param";
+ private static final String HEADER_PREFIX = "header";
+ private static final String COOKIE_PREFIX = "cookie";
+ private static final String INITPARAM_PREFIX = "initParam";
+ private static final String PAGE_PREFIX = "pageScope";
+ private static final String REQUEST_PREFIX = "requestScope";
+ private static final String SESSION_PREFIX = "sessionScope";
+ private static final String APP_PREFIX = "applicationScope";
+
+ // map prefixes to namespaces
+ private static final Map NAMESPACES;
+
+ static {
+ NAMESPACES = new HashMap(8);
+ NAMESPACES.put(XMLConstants.DEFAULT_NS_PREFIX, XMLConstants.NULL_NS_URI);
+ NAMESPACES.put(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI);
+ NAMESPACES.put(XMLConstants.XMLNS_ATTRIBUTE, XMLConstants.XMLNS_ATTRIBUTE_NS_URI);
+ NAMESPACES.put(PARAM_PREFIX, PARAM_NS_URL);
+ NAMESPACES.put(HEADER_PREFIX, HEADER_NS_URL);
+ NAMESPACES.put(COOKIE_PREFIX, COOKIE_NS_URL);
+ NAMESPACES.put(INITPARAM_PREFIX, INITPARAM_NS_URL);
+ NAMESPACES.put(PAGE_PREFIX, PAGE_NS_URL);
+ NAMESPACES.put(REQUEST_PREFIX, REQUEST_NS_URL);
+ NAMESPACES.put(SESSION_PREFIX, SESSION_NS_URL);
+ NAMESPACES.put(APP_PREFIX, APP_NS_URL);
+ }
+
+ // map namespaces to scopes
+ private static final Map SCOPES;
+
+ static {
+ SCOPES = new HashMap(8);
+ SCOPES.put(XMLConstants.NULL_NS_URI, Scope.JSP);
+ SCOPES.put(PARAM_NS_URL, Scope.PARAM);
+ SCOPES.put(HEADER_NS_URL, Scope.HEADER);
+ SCOPES.put(COOKIE_NS_URL, Scope.COOKIE);
+ SCOPES.put(INITPARAM_NS_URL, Scope.INITPARAM);
+ SCOPES.put(PAGE_NS_URL, Scope.PAGE);
+ SCOPES.put(REQUEST_NS_URL, Scope.REQUEST);
+ SCOPES.put(SESSION_NS_URL, Scope.SESSION);
+ SCOPES.put(APP_NS_URL, Scope.APPLICATION);
+ }
+
+ private PageContext pageContext;
+
+ public void setPageContext(PageContext pageContext) {
+ this.pageContext = pageContext;
+ }
+
+ public Object resolveVariable(QName variableName) {
+ String name = variableName.getLocalPart();
+ Scope scope = SCOPES.get(variableName.getNamespaceURI());
+ if (scope == null) {
+ return null;
+ }
+ switch (scope) {
+ case JSP:
+ return pageContext.findAttribute(name);
+ case PARAM:
+ return pageContext.getRequest().getParameter(name);
+ case HEADER:
+ return ((HttpServletRequest) pageContext.getRequest()).getHeader(name);
+ case COOKIE:
+ Cookie[] cookies = ((HttpServletRequest) pageContext.getRequest()).getCookies();
+ if (cookies != null) {
+ for (Cookie cookie : cookies) {
+ if (cookie.getName().equals(name)) {
+ return cookie.getValue();
+ }
+ }
+ }
+ return null;
+ case INITPARAM:
+ return pageContext.getServletContext().getInitParameter(name);
+ case PAGE:
+ return pageContext.getAttribute(name, PageContext.PAGE_SCOPE);
+ case REQUEST:
+ return pageContext.getAttribute(name, PageContext.REQUEST_SCOPE);
+ case SESSION:
+ return pageContext.getAttribute(name, PageContext.SESSION_SCOPE);
+ case APPLICATION:
+ return pageContext.getAttribute(name, PageContext.APPLICATION_SCOPE);
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ public String getNamespaceURI(String prefix) {
+ if (prefix == null) {
+ throw new IllegalArgumentException("prefix is null");
+ }
+ String uri = NAMESPACES.get(prefix);
+ if (uri != null) {
+ return uri;
+ }
+ return XMLConstants.NULL_NS_URI;
+ }
+
+ public String getPrefix(String namespaceURI) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Iterator getPrefixes(String namespaceURI) {
+ throw new UnsupportedOperationException();
+ }
+}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/JSTLXPathCompiler.java (nonexistent)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/JSTLXPathCompiler.java (working copy)
@@ -0,0 +1,33 @@
+/*
+ * 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.xpath;
+
+/**
+ */
+public interface JSTLXPathCompiler {
+
+ /**
+ * Pre-compiles an XPath expression for future evaluation;
+ *
+ * @param xpath
+ * the xpath to compile
+ * @return an JSTLXPathExpression that can be used to evaluate the XPath
+ * @throws InvalidXPathException
+ * if the supplied XPath is not valid
+ */
+ JSTLXPathExpression compile(String xpath) throws InvalidXPathException;
+}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/JSTLXPathContext.java (nonexistent)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/JSTLXPathContext.java (working copy)
@@ -0,0 +1,25 @@
+/*
+ * 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.xpath;
+
+/**
+ */
+public interface JSTLXPathContext {
+ boolean hasNext();
+
+ Object next();
+}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/JSTLXPathExpression.java (nonexistent)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/JSTLXPathExpression.java (working copy)
@@ -0,0 +1,33 @@
+/*
+ * 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.xpath;
+
+import javax.servlet.jsp.JspTagException;
+import javax.servlet.jsp.PageContext;
+
+/**
+ */
+public interface JSTLXPathExpression {
+
+ boolean evaluateBoolean(JSTLXPathContext context, PageContext pageContext) throws JspTagException;
+
+ String evaluateString(JSTLXPathContext context, PageContext pageContext) throws JspTagException;
+
+ Object evaluateObject(JSTLXPathContext context, PageContext pageContext) throws JspTagException;
+
+ JSTLXPathContext iterate(JSTLXPathContext context, PageContext pageContext) throws JspTagException;
+}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/JSTLXPathFactory.java (nonexistent)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/JSTLXPathFactory.java (working copy)
@@ -0,0 +1,32 @@
+/*
+ * 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.xpath;
+
+import org.apache.taglibs.standard.xpath.jaxp.JAXPXPathFactory;
+
+/**
+ */
+public abstract class JSTLXPathFactory {
+
+ private static final JAXPXPathFactory factory = new JAXPXPathFactory();
+
+ public static JSTLXPathFactory getFactory() {
+ return factory;
+ }
+
+ public abstract JSTLXPathCompiler newCompiler();
+}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/jaxp/JAXPXPathCompiler.java (nonexistent)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/jaxp/JAXPXPathCompiler.java (working copy)
@@ -0,0 +1,44 @@
+/*
+ * 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.xpath.jaxp;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpressionException;
+
+import org.apache.taglibs.standard.xpath.InvalidXPathException;
+import org.apache.taglibs.standard.xpath.JSTLVariableResolver;
+import org.apache.taglibs.standard.xpath.JSTLXPathCompiler;
+import org.apache.taglibs.standard.xpath.JSTLXPathExpression;
+
+/**
+ */
+public class JAXPXPathCompiler implements JSTLXPathCompiler {
+ private final XPath xpath;
+
+ public JAXPXPathCompiler(XPath xpath) {
+ this.xpath = xpath;
+ }
+
+ public JSTLXPathExpression compile(String select) {
+ try {
+ JSTLVariableResolver resolver = (JSTLVariableResolver) xpath.getXPathVariableResolver();
+ return new JAXPXPathExpression(xpath.compile(select), resolver);
+ } catch (XPathExpressionException e) {
+ throw new InvalidXPathException(e);
+ }
+ }
+}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/jaxp/JAXPXPathContext.java (nonexistent)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/jaxp/JAXPXPathContext.java (working copy)
@@ -0,0 +1,44 @@
+/*
+ * 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.xpath.jaxp;
+
+import org.apache.taglibs.standard.xpath.JSTLXPathContext;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ */
+public class JAXPXPathContext implements JSTLXPathContext {
+ private final NodeList nodes;
+ private int index;
+
+ public JAXPXPathContext(NodeList nodes) {
+ this.nodes = nodes;
+ }
+
+ public boolean hasNext() {
+ return index < nodes.getLength();
+ }
+
+ public Object next() {
+ return nodes.item(index++);
+ }
+
+ Node current() {
+ return nodes.item(index);
+ }
+}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/jaxp/JAXPXPathExpression.java (nonexistent)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/jaxp/JAXPXPathExpression.java (working copy)
@@ -0,0 +1,70 @@
+/*
+ * 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.xpath.jaxp;
+
+import javax.servlet.jsp.JspTagException;
+import javax.servlet.jsp.PageContext;
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import org.apache.taglibs.standard.xpath.JSTLVariableResolver;
+import org.apache.taglibs.standard.xpath.JSTLXPathContext;
+import org.apache.taglibs.standard.xpath.JSTLXPathExpression;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ */
+public class JAXPXPathExpression implements JSTLXPathExpression {
+ private final XPathExpression expr;
+ private final JSTLVariableResolver resolver;
+
+ public JAXPXPathExpression(XPathExpression expr, JSTLVariableResolver resolver) {
+ this.expr = expr;
+ this.resolver = resolver;
+ }
+
+ public boolean evaluateBoolean(JSTLXPathContext context, PageContext pageContext) throws JspTagException {
+ return (Boolean) evaluate(context, pageContext, XPathConstants.BOOLEAN);
+ }
+
+ public String evaluateString(JSTLXPathContext context, PageContext pageContext) throws JspTagException {
+ return (String) evaluate(context, pageContext, XPathConstants.STRING);
+ }
+
+ public Object evaluateObject(JSTLXPathContext context, PageContext pageContext) throws JspTagException {
+ return evaluate(context, pageContext, XPathConstants.NODE);
+ }
+
+ public JSTLXPathContext iterate(JSTLXPathContext context, PageContext pageContext) throws JspTagException {
+ NodeList nodes = (NodeList) evaluate(context, pageContext, XPathConstants.NODESET);
+ return new JAXPXPathContext(nodes);
+ }
+
+ private Object evaluate(JSTLXPathContext context, PageContext pageContext, QName resultType)
+ throws JspTagException {
+ resolver.setPageContext(pageContext);
+ Node contextNode = (context == null) ? null : ((JAXPXPathContext) context).current();
+ try {
+ return expr.evaluate(contextNode, resultType);
+ } catch (XPathExpressionException e) {
+ throw new JspTagException(e);
+ }
+ }
+}
--- apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/jaxp/JAXPXPathFactory.java (nonexistent)
+++ apache-taglibs-trunk/impl/src/main/java/org/apache/taglibs/standard/xpath/jaxp/JAXPXPathFactory.java (working copy)
@@ -0,0 +1,42 @@
+/*
+ * 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.xpath.jaxp;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.taglibs.standard.xpath.JSTLVariableResolver;
+import org.apache.taglibs.standard.xpath.JSTLXPathCompiler;
+import org.apache.taglibs.standard.xpath.JSTLXPathFactory;
+
+/**
+ */
+public class JAXPXPathFactory extends JSTLXPathFactory {
+ private static final XPathFactory xpf = XPathFactory.newInstance();
+
+ @Override
+ public JSTLXPathCompiler newCompiler() {
+ XPath xpath;
+ synchronized (xpf) {
+ xpath = xpf.newXPath();
+ }
+ JSTLVariableResolver resolver = new JSTLVariableResolver();
+ xpath.setXPathVariableResolver(resolver);
+ xpath.setNamespaceContext(resolver);
+ return new JAXPXPathCompiler(xpath);
+ }
+}