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: XUnresolvedVariable.java 468643 2006-10-28 06:56:03Z minchau $ 204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpackage org.apache.xalan.templates; 224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xalan.res.XSLTErrorResources; 244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xalan.transformer.TransformerImpl; 254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.VariableStack; 264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.XPathContext; 274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.objects.XObject; 284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/** 304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * An instance of this class holds unto a variable until 314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * it is executed. It is used at this time for global 324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * variables which must (we think) forward reference. 334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpublic class XUnresolvedVariable extends XObject 354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson{ 364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson static final long serialVersionUID = -256779804767950188L; 374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** The node context for execution. */ 384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transient private int m_context; 394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** The transformer context for execution. */ 414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transient private TransformerImpl m_transformer; 424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** An index to the point in the variable stack where we should 444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * begin variable searches for evaluation of expressions. 454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * This is -1 if m_isTopLevel is false. 464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson **/ 474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transient private int m_varStackPos = -1; 484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** An index into the variable stack where the variable context 504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * ends, i.e. at the point we should terminate the search. 514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson **/ 524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transient private int m_varStackContext; 534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** true if this variable or parameter is a global. 554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @serial */ 564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private boolean m_isGlobal; 574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** true if this variable or parameter is not currently being evaluated. */ 594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson transient private boolean m_doneEval = true; 604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Create an XUnresolvedVariable, that may be executed at a later time. 634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * This is primarily used so that forward referencing works with 644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * global variables. An XUnresolvedVariable is initially pushed 654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * into the global variable stack, and then replaced with the real 664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * thing when it is accessed. 674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param obj Must be a non-null reference to an ElemVariable. 694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param sourceNode The node context for execution. 704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param transformer The transformer execution context. 714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param varStackPos An index to the point in the variable stack where we should 724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * begin variable searches for evaluation of expressions. 734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param varStackContext An index into the variable stack where the variable context 744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * ends, i.e. at the point we should terminate the search. 754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param isGlobal true if this is a global variable. 764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public XUnresolvedVariable(ElemVariable obj, int sourceNode, 784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson TransformerImpl transformer, 794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int varStackPos, int varStackContext, 804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson boolean isGlobal) 814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson super(obj); 834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_context = sourceNode; 844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_transformer = transformer; 854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // For globals, this value will have to be updated once we 874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // have determined how many global variables have been pushed. 884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_varStackPos = varStackPos; 894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // For globals, this should zero. 914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_varStackContext = varStackContext; 924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_isGlobal = isGlobal; 944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * For support of literal objects in xpaths. 984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param xctxt The XPath execution context. 1004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return This object. 1024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws javax.xml.transform.TransformerException 1044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException 1064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if (!m_doneEval) 1084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.m_transformer.getMsgMgr().error 1104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson (xctxt.getSAXLocator(), XSLTErrorResources.ER_REFERENCING_ITSELF, 1114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[]{((ElemVariable)this.object()).getName().getLocalName()}); 1124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson VariableStack vars = xctxt.getVarStack(); 1144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // These three statements need to be combined into one operation. 1164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson int currentFrame = vars.getStackFrame(); 1174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson //// vars.setStackFrame(m_varStackPos); 1184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ElemVariable velem = (ElemVariable)m_obj; 1214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try 1224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_doneEval = false; 1244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(-1 != velem.m_frameSize) 1254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.link(velem.m_frameSize); 1264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XObject var = velem.getValue(m_transformer, m_context); 1274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_doneEval = true; 1284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return var; 1294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson finally 1314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // These two statements need to be combined into one operation. 1334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // vars.setStackFrame(currentFrame); 1344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(-1 != velem.m_frameSize) 1364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson vars.unlink(currentFrame); 1374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Set an index to the point in the variable stack where we should 1424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * begin variable searches for evaluation of expressions. 1434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * This is -1 if m_isTopLevel is false. 1444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param top A valid value that specifies where in the variable 1464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * stack the search should begin. 1474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setVarStackPos(int top) 1494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_varStackPos = top; 1514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Set an index into the variable stack where the variable context 1554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * ends, i.e. at the point we should terminate the search. 1564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param bottom The point at which the search should terminate, normally 1584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * zero for global variables. 1594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setVarStackContext(int bottom) 1614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson m_varStackContext = bottom; 1634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Tell what kind of class this is. 1674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return CLASS_UNRESOLVEDVARIABLE 1694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public int getType() 1714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return CLASS_UNRESOLVEDVARIABLE; 1734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Given a request type, return the equivalent string. 1774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * For diagnostic purposes. 1784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return An informational string. 1804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public String getTypeString() 1824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson { 1834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return "XUnresolvedVariable (" + object().getClass().getName() + ")"; 1844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson} 188