diff options
Diffstat (limited to 'src/com/sun/org/apache/xalan/internal/lib/ExsltDynamic.java')
-rw-r--r-- | src/com/sun/org/apache/xalan/internal/lib/ExsltDynamic.java | 616 |
1 files changed, 0 insertions, 616 deletions
diff --git a/src/com/sun/org/apache/xalan/internal/lib/ExsltDynamic.java b/src/com/sun/org/apache/xalan/internal/lib/ExsltDynamic.java deleted file mode 100644 index 7f55d89..0000000 --- a/src/com/sun/org/apache/xalan/internal/lib/ExsltDynamic.java +++ /dev/null @@ -1,616 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed 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. - */ -/* - * $Id: ExsltDynamic.java,v 1.1.2.1 2005/08/01 02:08:51 jeffsuttor Exp $ - */ -package com.sun.org.apache.xalan.internal.lib; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.TransformerException; - -import com.sun.org.apache.xalan.internal.extensions.ExpressionContext; -import com.sun.org.apache.xalan.internal.res.XSLMessages; -import com.sun.org.apache.xalan.internal.res.XSLTErrorResources; -import com.sun.org.apache.xpath.internal.NodeSet; -import com.sun.org.apache.xpath.internal.NodeSetDTM; -import com.sun.org.apache.xpath.internal.XPath; -import com.sun.org.apache.xpath.internal.XPathContext; -import com.sun.org.apache.xpath.internal.objects.XBoolean; -import com.sun.org.apache.xpath.internal.objects.XNodeSet; -import com.sun.org.apache.xpath.internal.objects.XNumber; -import com.sun.org.apache.xpath.internal.objects.XObject; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.Text; - -import org.xml.sax.SAXNotSupportedException; - -/** - * This class contains EXSLT dynamic extension functions. - * - * It is accessed by specifying a namespace URI as follows: - * <pre> - * xmlns:dyn="http://exslt.org/dynamic" - * </pre> - * The documentation for each function has been copied from the relevant - * EXSLT Implementer page. - * - * @see <a href="http://www.exslt.org/">EXSLT</a> - - * @xsl.usage general - */ -public class ExsltDynamic extends ExsltBase -{ - - public static final String EXSL_URI = "http://exslt.org/common"; - - /** - * The dyn:max function calculates the maximum value for the nodes passed as - * the first argument, where the value of each node is calculated dynamically - * using an XPath expression passed as a string as the second argument. - * <p> - * The expressions are evaluated relative to the nodes passed as the first argument. - * In other words, the value for each node is calculated by evaluating the XPath - * expression with all context information being the same as that for the call to - * the dyn:max function itself, except for the following: - * <p> - * <ul> - * <li>the context node is the node whose value is being calculated.</li> - * <li>the context position is the position of the node within the node set passed as - * the first argument to the dyn:max function, arranged in document order.</li> - * <li>the context size is the number of nodes passed as the first argument to the - * dyn:max function.</li> - * </ul> - * <p> - * The dyn:max function returns the maximum of these values, calculated in exactly - * the same way as for math:max. - * <p> - * If the expression string passed as the second argument is an invalid XPath - * expression (including an empty string), this function returns NaN. - * <p> - * This function must take a second argument. To calculate the maximum of a set of - * nodes based on their string values, you should use the math:max function. - * - * @param myContext The ExpressionContext passed by the extension processor - * @param nl The node set - * @param expr The expression string - * - * @return The maximum evaluation value - */ - public static double max(ExpressionContext myContext, NodeList nl, String expr) - throws SAXNotSupportedException - { - - XPathContext xctxt = null; - if (myContext instanceof XPathContext.XPathExpressionContext) - xctxt = ((XPathContext.XPathExpressionContext) myContext).getXPathContext(); - else - throw new SAXNotSupportedException(XSLMessages.createMessage(XSLTErrorResources.ER_INVALID_CONTEXT_PASSED, new Object[]{myContext })); - - if (expr == null || expr.length() == 0) - return Double.NaN; - - NodeSetDTM contextNodes = new NodeSetDTM(nl, xctxt); - xctxt.pushContextNodeList(contextNodes); - - double maxValue = - Double.MAX_VALUE; - for (int i = 0; i < contextNodes.getLength(); i++) - { - int contextNode = contextNodes.item(i); - xctxt.pushCurrentNode(contextNode); - - double result = 0; - try - { - XPath dynamicXPath = new XPath(expr, xctxt.getSAXLocator(), - xctxt.getNamespaceContext(), - XPath.SELECT); - result = dynamicXPath.execute(xctxt, contextNode, xctxt.getNamespaceContext()).num(); - } - catch (TransformerException e) - { - xctxt.popCurrentNode(); - xctxt.popContextNodeList(); - return Double.NaN; - } - - xctxt.popCurrentNode(); - - if (result > maxValue) - maxValue = result; - } - - xctxt.popContextNodeList(); - return maxValue; - - } - - /** - * The dyn:min function calculates the minimum value for the nodes passed as the - * first argument, where the value of each node is calculated dynamically using - * an XPath expression passed as a string as the second argument. - * <p> - * The expressions are evaluated relative to the nodes passed as the first argument. - * In other words, the value for each node is calculated by evaluating the XPath - * expression with all context information being the same as that for the call to - * the dyn:min function itself, except for the following: - * <p> - * <ul> - * <li>the context node is the node whose value is being calculated.</li> - * <li>the context position is the position of the node within the node set passed - * as the first argument to the dyn:min function, arranged in document order.</li> - * <li>the context size is the number of nodes passed as the first argument to the - * dyn:min function.</li> - * </ul> - * <p> - * The dyn:min function returns the minimum of these values, calculated in exactly - * the same way as for math:min. - * <p> - * If the expression string passed as the second argument is an invalid XPath expression - * (including an empty string), this function returns NaN. - * <p> - * This function must take a second argument. To calculate the minimum of a set of - * nodes based on their string values, you should use the math:min function. - * - * @param myContext The ExpressionContext passed by the extension processor - * @param nl The node set - * @param expr The expression string - * - * @return The minimum evaluation value - */ - public static double min(ExpressionContext myContext, NodeList nl, String expr) - throws SAXNotSupportedException - { - - XPathContext xctxt = null; - if (myContext instanceof XPathContext.XPathExpressionContext) - xctxt = ((XPathContext.XPathExpressionContext) myContext).getXPathContext(); - else - throw new SAXNotSupportedException(XSLMessages.createMessage(XSLTErrorResources.ER_INVALID_CONTEXT_PASSED, new Object[]{myContext })); - - if (expr == null || expr.length() == 0) - return Double.NaN; - - NodeSetDTM contextNodes = new NodeSetDTM(nl, xctxt); - xctxt.pushContextNodeList(contextNodes); - - double minValue = Double.MAX_VALUE; - for (int i = 0; i < nl.getLength(); i++) - { - int contextNode = contextNodes.item(i); - xctxt.pushCurrentNode(contextNode); - - double result = 0; - try - { - XPath dynamicXPath = new XPath(expr, xctxt.getSAXLocator(), - xctxt.getNamespaceContext(), - XPath.SELECT); - result = dynamicXPath.execute(xctxt, contextNode, xctxt.getNamespaceContext()).num(); - } - catch (TransformerException e) - { - xctxt.popCurrentNode(); - xctxt.popContextNodeList(); - return Double.NaN; - } - - xctxt.popCurrentNode(); - - if (result < minValue) - minValue = result; - } - - xctxt.popContextNodeList(); - return minValue; - - } - - /** - * The dyn:sum function calculates the sum for the nodes passed as the first argument, - * where the value of each node is calculated dynamically using an XPath expression - * passed as a string as the second argument. - * <p> - * The expressions are evaluated relative to the nodes passed as the first argument. - * In other words, the value for each node is calculated by evaluating the XPath - * expression with all context information being the same as that for the call to - * the dyn:sum function itself, except for the following: - * <p> - * <ul> - * <li>the context node is the node whose value is being calculated.</li> - * <li>the context position is the position of the node within the node set passed as - * the first argument to the dyn:sum function, arranged in document order.</li> - * <li>the context size is the number of nodes passed as the first argument to the - * dyn:sum function.</li> - * </ul> - * <p> - * The dyn:sum function returns the sumimum of these values, calculated in exactly - * the same way as for sum. - * <p> - * If the expression string passed as the second argument is an invalid XPath - * expression (including an empty string), this function returns NaN. - * <p> - * This function must take a second argument. To calculate the sumimum of a set of - * nodes based on their string values, you should use the sum function. - * - * @param myContext The ExpressionContext passed by the extension processor - * @param nl The node set - * @param expr The expression string - * - * @return The sum of the evaluation value on each node - */ - public static double sum(ExpressionContext myContext, NodeList nl, String expr) - throws SAXNotSupportedException - { - XPathContext xctxt = null; - if (myContext instanceof XPathContext.XPathExpressionContext) - xctxt = ((XPathContext.XPathExpressionContext) myContext).getXPathContext(); - else - throw new SAXNotSupportedException(XSLMessages.createMessage(XSLTErrorResources.ER_INVALID_CONTEXT_PASSED, new Object[]{myContext })); - - if (expr == null || expr.length() == 0) - return Double.NaN; - - NodeSetDTM contextNodes = new NodeSetDTM(nl, xctxt); - xctxt.pushContextNodeList(contextNodes); - - double sum = 0; - for (int i = 0; i < nl.getLength(); i++) - { - int contextNode = contextNodes.item(i); - xctxt.pushCurrentNode(contextNode); - - double result = 0; - try - { - XPath dynamicXPath = new XPath(expr, xctxt.getSAXLocator(), - xctxt.getNamespaceContext(), - XPath.SELECT); - result = dynamicXPath.execute(xctxt, contextNode, xctxt.getNamespaceContext()).num(); - } - catch (TransformerException e) - { - xctxt.popCurrentNode(); - xctxt.popContextNodeList(); - return Double.NaN; - } - - xctxt.popCurrentNode(); - - sum = sum + result; - - } - - xctxt.popContextNodeList(); - return sum; - } - - /** - * The dyn:map function evaluates the expression passed as the second argument for - * each of the nodes passed as the first argument, and returns a node set of those values. - * <p> - * The expressions are evaluated relative to the nodes passed as the first argument. - * In other words, the value for each node is calculated by evaluating the XPath - * expression with all context information being the same as that for the call to - * the dyn:map function itself, except for the following: - * <p> - * <ul> - * <li>The context node is the node whose value is being calculated.</li> - * <li>the context position is the position of the node within the node set passed - * as the first argument to the dyn:map function, arranged in document order.</li> - * <li>the context size is the number of nodes passed as the first argument to the - * dyn:map function.</li> - * </ul> - * <p> - * If the expression string passed as the second argument is an invalid XPath - * expression (including an empty string), this function returns an empty node set. - * <p> - * If the XPath expression evaluates as a node set, the dyn:map function returns - * the union of the node sets returned by evaluating the expression for each of the - * nodes in the first argument. Note that this may mean that the node set resulting - * from the call to the dyn:map function contains a different number of nodes from - * the number in the node set passed as the first argument to the function. - * <p> - * If the XPath expression evaluates as a number, the dyn:map function returns a - * node set containing one exsl:number element (namespace http://exslt.org/common) - * for each node in the node set passed as the first argument to the dyn:map function, - * in document order. The string value of each exsl:number element is the same as - * the result of converting the number resulting from evaluating the expression to - * a string as with the number function, with the exception that Infinity results - * in an exsl:number holding the highest number the implementation can store, and - * -Infinity results in an exsl:number holding the lowest number the implementation - * can store. - * <p> - * If the XPath expression evaluates as a boolean, the dyn:map function returns a - * node set containing one exsl:boolean element (namespace http://exslt.org/common) - * for each node in the node set passed as the first argument to the dyn:map function, - * in document order. The string value of each exsl:boolean element is 'true' if the - * expression evaluates as true for the node, and '' if the expression evaluates as - * false. - * <p> - * Otherwise, the dyn:map function returns a node set containing one exsl:string - * element (namespace http://exslt.org/common) for each node in the node set passed - * as the first argument to the dyn:map function, in document order. The string - * value of each exsl:string element is the same as the result of converting the - * result of evaluating the expression for the relevant node to a string as with - * the string function. - * - * @param myContext The ExpressionContext passed by the extension processor - * @param nl The node set - * @param expr The expression string - * - * @return The node set after evaluation - */ - public static NodeList map(ExpressionContext myContext, NodeList nl, String expr) - throws SAXNotSupportedException - { - XPathContext xctxt = null; - Document lDoc = null; - - if (myContext instanceof XPathContext.XPathExpressionContext) - xctxt = ((XPathContext.XPathExpressionContext) myContext).getXPathContext(); - else - throw new SAXNotSupportedException(XSLMessages.createMessage(XSLTErrorResources.ER_INVALID_CONTEXT_PASSED, new Object[]{myContext })); - - if (expr == null || expr.length() == 0) - return new NodeSet(); - - NodeSetDTM contextNodes = new NodeSetDTM(nl, xctxt); - xctxt.pushContextNodeList(contextNodes); - - NodeSet resultSet = new NodeSet(); - resultSet.setShouldCacheNodes(true); - - for (int i = 0; i < nl.getLength(); i++) - { - int contextNode = contextNodes.item(i); - xctxt.pushCurrentNode(contextNode); - - XObject object = null; - try - { - XPath dynamicXPath = new XPath(expr, xctxt.getSAXLocator(), - xctxt.getNamespaceContext(), - XPath.SELECT); - object = dynamicXPath.execute(xctxt, contextNode, xctxt.getNamespaceContext()); - - if (object instanceof XNodeSet) - { - NodeList nodelist = null; - nodelist = ((XNodeSet)object).nodelist(); - - for (int k = 0; k < nodelist.getLength(); k++) - { - Node n = nodelist.item(k); - if (!resultSet.contains(n)) - resultSet.addNode(n); - } - } - else - { - if (lDoc == null) - { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - lDoc = db.newDocument(); - } - - Element element = null; - if (object instanceof XNumber) - element = lDoc.createElementNS(EXSL_URI, "exsl:number"); - else if (object instanceof XBoolean) - element = lDoc.createElementNS(EXSL_URI, "exsl:boolean"); - else - element = lDoc.createElementNS(EXSL_URI, "exsl:string"); - - Text textNode = lDoc.createTextNode(object.str()); - element.appendChild(textNode); - resultSet.addNode(element); - } - } - catch (Exception e) - { - xctxt.popCurrentNode(); - xctxt.popContextNodeList(); - return new NodeSet(); - } - - xctxt.popCurrentNode(); - - } - - xctxt.popContextNodeList(); - return resultSet; - } - - /** - * The dyn:evaluate function evaluates a string as an XPath expression and returns - * the resulting value, which might be a boolean, number, string, node set, result - * tree fragment or external object. The sole argument is the string to be evaluated. - * <p> - * If the expression string passed as the second argument is an invalid XPath - * expression (including an empty string), this function returns an empty node set. - * <p> - * You should only use this function if the expression must be constructed dynamically, - * otherwise it is much more efficient to use the expression literally. - * - * @param myContext The ExpressionContext passed by the extension processor - * @param xpathExpr The XPath expression string - * - * @return The evaluation result - */ - public static XObject evaluate(ExpressionContext myContext, String xpathExpr) - throws SAXNotSupportedException - { - if (myContext instanceof XPathContext.XPathExpressionContext) - { - XPathContext xctxt = null; - try - { - xctxt = ((XPathContext.XPathExpressionContext) myContext).getXPathContext(); - XPath dynamicXPath = new XPath(xpathExpr, xctxt.getSAXLocator(), - xctxt.getNamespaceContext(), - XPath.SELECT); - - return dynamicXPath.execute(xctxt, myContext.getContextNode(), - xctxt.getNamespaceContext()); - } - catch (TransformerException e) - { - return new XNodeSet(xctxt.getDTMManager()); - } - } - else - throw new SAXNotSupportedException(XSLMessages.createMessage(XSLTErrorResources.ER_INVALID_CONTEXT_PASSED, new Object[]{myContext })); //"Invalid context passed to evaluate " - } - - /** - * The dyn:closure function creates a node set resulting from transitive closure of - * evaluating the expression passed as the second argument on each of the nodes passed - * as the first argument, then on the node set resulting from that and so on until no - * more nodes are found. For example: - * <pre> - * dyn:closure(., '*') - * </pre> - * returns all the descendant elements of the node (its element children, their - * children, their children's children and so on). - * <p> - * The expression is thus evaluated several times, each with a different node set - * acting as the context of the expression. The first time the expression is - * evaluated, the context node set is the first argument passed to the dyn:closure - * function. In other words, the node set for each node is calculated by evaluating - * the XPath expression with all context information being the same as that for - * the call to the dyn:closure function itself, except for the following: - * <p> - * <ul> - * <li>the context node is the node whose value is being calculated.</li> - * <li>the context position is the position of the node within the node set passed - * as the first argument to the dyn:closure function, arranged in document order.</li> - * <li>the context size is the number of nodes passed as the first argument to the - * dyn:closure function.</li> - * <li>the current node is the node whose value is being calculated.</li> - * </ul> - * <p> - * The result for a particular iteration is the union of the node sets resulting - * from evaluting the expression for each of the nodes in the source node set for - * that iteration. This result is then used as the source node set for the next - * iteration, and so on. The result of the function as a whole is the union of - * the node sets generated by each iteration. - * <p> - * If the expression string passed as the second argument is an invalid XPath - * expression (including an empty string) or an expression that does not return a - * node set, this function returns an empty node set. - * - * @param myContext The ExpressionContext passed by the extension processor - * @param nl The node set - * @param expr The expression string - * - * @return The node set after evaluation - */ - public static NodeList closure(ExpressionContext myContext, NodeList nl, String expr) - throws SAXNotSupportedException - { - XPathContext xctxt = null; - if (myContext instanceof XPathContext.XPathExpressionContext) - xctxt = ((XPathContext.XPathExpressionContext) myContext).getXPathContext(); - else - throw new SAXNotSupportedException(XSLMessages.createMessage(XSLTErrorResources.ER_INVALID_CONTEXT_PASSED, new Object[]{myContext })); - - if (expr == null || expr.length() == 0) - return new NodeSet(); - - NodeSet closureSet = new NodeSet(); - closureSet.setShouldCacheNodes(true); - - NodeList iterationList = nl; - do - { - - NodeSet iterationSet = new NodeSet(); - - NodeSetDTM contextNodes = new NodeSetDTM(iterationList, xctxt); - xctxt.pushContextNodeList(contextNodes); - - for (int i = 0; i < iterationList.getLength(); i++) - { - int contextNode = contextNodes.item(i); - xctxt.pushCurrentNode(contextNode); - - XObject object = null; - try - { - XPath dynamicXPath = new XPath(expr, xctxt.getSAXLocator(), - xctxt.getNamespaceContext(), - XPath.SELECT); - object = dynamicXPath.execute(xctxt, contextNode, xctxt.getNamespaceContext()); - - if (object instanceof XNodeSet) - { - NodeList nodelist = null; - nodelist = ((XNodeSet)object).nodelist(); - - for (int k = 0; k < nodelist.getLength(); k++) - { - Node n = nodelist.item(k); - if (!iterationSet.contains(n)) - iterationSet.addNode(n); - } - } - else - { - xctxt.popCurrentNode(); - xctxt.popContextNodeList(); - return new NodeSet(); - } - } - catch (TransformerException e) - { - xctxt.popCurrentNode(); - xctxt.popContextNodeList(); - return new NodeSet(); - } - - xctxt.popCurrentNode(); - - } - - xctxt.popContextNodeList(); - - iterationList = iterationSet; - - for (int i = 0; i < iterationList.getLength(); i++) - { - Node n = iterationList.item(i); - if (!closureSet.contains(n)) - closureSet.addNode(n); - } - - } while(iterationList.getLength() > 0); - - return closureSet; - - } - -} |