14c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/* 24c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one 34c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * or more contributor license agreements. See the NOTICE file 44c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed with this work for additional information 54c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * regarding copyright ownership. The ASF licenses this file 64c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to you under the Apache License, Version 2.0 (the "License"); 74c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * you may not use this file except in compliance with the License. 84c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * You may obtain a copy of the License at 94c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Unless required by applicable law or agreed to in writing, software 134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * See the License for the specific language governing permissions and 164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * limitations under the License. 174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/* 194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * $Id: ElemApplyTemplates.java 468643 2006-10-28 06:56:03Z minchau $ 204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpackage org.apache.xalan.templates; 224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport java.util.Vector; 244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.transform.TransformerException; 264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xalan.transformer.TransformerImpl; 284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTM; 294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTMIterator; 304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.serializer.SerializationHandler; 314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.utils.IntStack; 324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.utils.QName; 334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.VariableStack; 344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.XPath; 354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.XPathContext; 364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.objects.XObject; 374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.xml.sax.SAXException; 384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/** 404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Implement xsl:apply-templates. 414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <pre> 424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * &!ELEMENT xsl:apply-templates (xsl:sort|xsl:with-param)*> 434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * &!ATTLIST xsl:apply-templates 444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * select %expr; "node()" 454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * mode %qname; #IMPLIED 464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * & 474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * </pre> 484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see <a href="http://www.w3.org/TR/xslt#section-Applying-Template-Rules">section-Applying-Template-Rules in XSLT Specification</a> 494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @xsl.usage advanced 504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpublic class ElemApplyTemplates extends ElemCallTemplate 524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson{ 534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson static final long serialVersionUID = 2903125371542621004L; 544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * mode %qname; #IMPLIED 574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @serial 584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private QName m_mode = null; 604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Set the mode attribute for this element. 634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>. 654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setMode(QName mode) 674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_mode = mode; 694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get the mode attribute for this element. 734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The mode attribute for this element 754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public QName getMode() 774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return m_mode; 794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Tells if this belongs to a default template, 834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * in which case it will act different with 844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * regard to processing modes. 854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see <a href="http://www.w3.org/TR/xslt#built-in-rule">built-in-rule in XSLT Specification</a> 864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @serial 874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private boolean m_isDefaultTemplate = false; 894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// /** 914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// * List of namespace/localname IDs, for identification of xsl:with-param to 924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// * xsl:params. Initialized in the compose() method. 934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// */ 944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// private int[] m_paramIDs; 954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Set if this belongs to a default template, 984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * in which case it will act different with 994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * regard to processing modes. 1004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see <a href="http://www.w3.org/TR/xslt#built-in-rule">built-in-rule in XSLT Specification</a> 1014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param b boolean value to set. 1034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setIsDefaultTemplate(boolean b) 1054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_isDefaultTemplate = b; 1074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Get an int constant identifying the type of element. 1114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see org.apache.xalan.templates.Constants 1124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return Token ID for this element types 1144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getXSLToken() 1164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return Constants.ELEMNAME_APPLY_TEMPLATES; 1184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * This function is called after everything else has been 1224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * recomposed, and allows the template to set remaining 1234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * values that may be based on some other property that 1244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * depends on recomposition. 1254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void compose(StylesheetRoot sroot) throws TransformerException 1274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super.compose(sroot); 1294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Return the node name. 1334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return Element name 1354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public String getNodeName() 1374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return Constants.ELEMNAME_APPLY_TEMPLATES_STRING; 1394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Apply the context node to the matching templates. 1434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @see <a href="http://www.w3.org/TR/xslt#section-Applying-Template-Rules">section-Applying-Template-Rules in XSLT Specification</a> 1444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param transformer non-null reference to the the current transform-time state. 1464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws TransformerException 1484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void execute(TransformerImpl transformer) throws TransformerException 1504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.pushCurrentTemplateRuleIsNull(false); 1534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson boolean pushMode = false; 1554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try 1574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // %REVIEW% Do we need this check?? 1594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // if (null != sourceNode) 1604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // { 1614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // boolean needToTurnOffInfiniteLoopCheck = false; 1624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson QName mode = transformer.getMode(); 1634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (!m_isDefaultTemplate) 1654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (((null == mode) && (null != m_mode)) 1674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson || ((null != mode) &&!mode.equals(m_mode))) 1684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson pushMode = true; 1704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.pushMode(m_mode); 1724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformSelectedNodes(transformer); 1764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson finally 1784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (pushMode) 1804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.popMode(); 1814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.popCurrentTemplateRuleIsNull(); 1834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Perform a query if needed, and call transformNode for each child. 1894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param transformer non-null reference to the the current transform-time state. 1914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws TransformerException Thrown in a variety of circumstances. 1934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @xsl.usage advanced 1944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void transformSelectedNodes(TransformerImpl transformer) 1964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws TransformerException 1974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson final XPathContext xctxt = transformer.getXPathContext(); 2004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson final int sourceNode = xctxt.getCurrentNode(); 2014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt, sourceNode); 2024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson VariableStack vars = xctxt.getVarStack(); 2034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int nParams = getParamElemCount(); 2044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int thisframe = vars.getStackFrame(); 2050b4ea6cb0176b34c7ac46800d51ce925683ef667Jesse Wilson 2064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson boolean pushContextNodeListFlag = false; 2074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try 2094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.pushCurrentNode(DTM.NULL); 2124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.pushCurrentExpressionNode(DTM.NULL); 2134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.pushSAXLocatorNull(); 2144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.pushElemTemplateElement(null); 2154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson final Vector keys = (m_sortElems == null) 2164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ? null 2174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson : transformer.processSortKeys(this, sourceNode); 2184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Sort if we need to. 2204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (null != keys) 2214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson sourceNodes = sortNodes(xctxt, keys, sourceNodes); 2224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson final SerializationHandler rth = transformer.getSerializationHandler(); 2244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// ContentHandler chandler = rth.getContentHandler(); 2254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson final StylesheetRoot sroot = transformer.getStylesheet(); 2264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson final TemplateList tl = sroot.getTemplateListComposed(); 2274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson final boolean quiet = transformer.getQuietConflictWarnings(); 2284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Should be able to get this from the iterator but there must be a bug. 2304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson DTM dtm = xctxt.getDTM(sourceNode); 2314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int argsFrame = -1; 2334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(nParams > 0) 2344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // This code will create a section on the stack that is all the 2364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // evaluated arguments. These will be copied into the real params 2374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // section of each called template. 2384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson argsFrame = vars.link(nParams); 2394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.setStackFrame(thisframe); 2404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for (int i = 0; i < nParams; i++) 2424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ElemWithParam ewp = m_paramElems[i]; 2444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XObject obj = ewp.getValue(transformer, sourceNode); 2450b4ea6cb0176b34c7ac46800d51ce925683ef667Jesse Wilson 2464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.setLocalVariable(i, obj, argsFrame); 2474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.setStackFrame(argsFrame); 2494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.pushContextNodeList(sourceNodes); 2524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson pushContextNodeListFlag = true; 2534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson IntStack currentNodes = xctxt.getCurrentNodeStack(); 2554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson IntStack currentExpressionNodes = xctxt.getCurrentExpressionNodeStack(); 2574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // pushParams(transformer, xctxt); 2594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int child; 2614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson while (DTM.NULL != (child = sourceNodes.nextNode())) 2624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson currentNodes.setTop(child); 2644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson currentExpressionNodes.setTop(child); 2654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(xctxt.getDTM(child) != dtm) 2674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson dtm = xctxt.getDTM(child); 2694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson final int exNodeType = dtm.getExpandedTypeID(child); 2724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson final int nodeType = dtm.getNodeType(child); 2744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson final QName mode = transformer.getMode(); 2764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ElemTemplate template = tl.getTemplateFast(xctxt, child, exNodeType, mode, 2784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson -1, quiet, dtm); 2794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // If that didn't locate a node, fall back to a default template rule. 2814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // See http://www.w3.org/TR/xslt#built-in-rule. 2824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (null == template) 2834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson switch (nodeType) 2854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 2864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson case DTM.DOCUMENT_FRAGMENT_NODE : 2874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson case DTM.ELEMENT_NODE : 2884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson template = sroot.getDefaultRule(); 2894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // %OPT% direct faster? 2904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson break; 2914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson case DTM.ATTRIBUTE_NODE : 2924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson case DTM.CDATA_SECTION_NODE : 2934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson case DTM.TEXT_NODE : 2944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // if(rth.m_elemIsPending || rth.m_docPending) 2954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // rth.flushPending(true); 2964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.pushPairCurrentMatched(sroot.getDefaultTextRule(), child); 2974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.setCurrentElement(sroot.getDefaultTextRule()); 2984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // dtm.dispatchCharactersEvents(child, chandler, false); 2994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson dtm.dispatchCharactersEvents(child, rth, false); 3004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.popCurrentMatched(); 3014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson continue; 3024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson case DTM.DOCUMENT_NODE : 3034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson template = sroot.getDefaultRootRule(); 3044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson break; 3054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson default : 3064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // No default rules for processing instructions and the like. 3084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson continue; 3094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson else 3124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.setCurrentElement(template); 3144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.pushPairCurrentMatched(template, child); 3174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int currentFrameBottom; // See comment with unlink, below 3194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(template.m_frameSize > 0) 3204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.pushRTFContext(); 3224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson currentFrameBottom = vars.getStackFrame(); // See comment with unlink, below 3234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.link(template.m_frameSize); 3244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // You can't do the check for nParams here, otherwise the 3254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // xsl:params might not be nulled. 3264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(/* nParams > 0 && */ template.m_inArgsSize > 0) 3274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int paramIndex = 0; 3294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for (ElemTemplateElement elem = template.getFirstChildElem(); 3304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson null != elem; elem = elem.getNextSiblingElem()) 3314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(Constants.ELEMNAME_PARAMVARIABLE == elem.getXSLToken()) 3334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ElemParam ep = (ElemParam)elem; 3354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int i; 3374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for (i = 0; i < nParams; i++) 3384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ElemWithParam ewp = m_paramElems[i]; 3404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(ewp.m_qnameID == ep.m_qnameID) 3414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XObject obj = vars.getLocalVariable(i, argsFrame); 3434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.setLocalVariable(paramIndex, obj); 3444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson break; 3454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(i == nParams) 3484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.setLocalVariable(paramIndex, null); 3494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson else 3514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson break; 3524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson paramIndex++; 3534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson else 3584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson currentFrameBottom = 0; 3594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // And execute the child templates. 3614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Loop through the children of the template, calling execute on 3624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // each of them. 3634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson for (ElemTemplateElement t = template.m_firstChild; 3644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson t != null; t = t.m_nextSibling) 3654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.setSAXLocator(t); 3674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try 3684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.pushElemTemplateElement(t); 3704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson t.execute(transformer); 3714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson finally 3734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.popElemTemplateElement(); 3754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(template.m_frameSize > 0) 3794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 3804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // See Frank Weiss bug around 03/19/2002 (no Bugzilla report yet). 3814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // While unlink will restore to the proper place, the real position 3824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // may have been changed for xsl:with-param, so that variables 3834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // can be accessed. 3844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // of right now. 3854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // More: 3864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // When we entered this function, the current 3874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // frame buffer (cfb) index in the variable stack may 3884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // have been manually set. If we just call 3894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // unlink(), however, it will restore the cfb to the 3904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // previous link index from the link stack, rather than 3914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // the manually set cfb. So, 3924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // the only safe solution is to restore it back 3934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // to the same position it was on entry, since we're 3944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // really not working in a stack context here. (Bug4218) 3954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.unlink(currentFrameBottom); 3964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.popRTFContext(); 3974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.popCurrentMatched(); 4004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } // end while (DTM.NULL != (child = sourceNodes.nextNode())) 4024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson catch (SAXException se) 4044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.getErrorListener().fatalError(new TransformerException(se)); 4064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson finally 4084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 4090b4ea6cb0176b34c7ac46800d51ce925683ef667Jesse Wilson // Unlink to the original stack frame 4104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(nParams > 0) 4114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.unlink(thisframe); 4124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.popSAXLocator(); 4134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (pushContextNodeListFlag) xctxt.popContextNodeList(); 4144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transformer.popElemTemplateElement(); 4154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.popCurrentExpressionNode(); 4164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xctxt.popCurrentNode(); 4174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson sourceNodes.detach(); 4184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson} 422