• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 /*
19  * $Id: XUnresolvedVariable.java 468643 2006-10-28 06:56:03Z minchau $
20  */
21 package org.apache.xalan.templates;
22 
23 import org.apache.xalan.res.XSLTErrorResources;
24 import org.apache.xalan.transformer.TransformerImpl;
25 import org.apache.xpath.VariableStack;
26 import org.apache.xpath.XPathContext;
27 import org.apache.xpath.objects.XObject;
28 
29 /**
30  * An instance of this class holds unto a variable until
31  * it is executed.  It is used at this time for global
32  * variables which must (we think) forward reference.
33  */
34 public class XUnresolvedVariable extends XObject
35 {
36     static final long serialVersionUID = -256779804767950188L;
37   /** The node context for execution. */
38   transient private int m_context;
39 
40   /** The transformer context for execution. */
41   transient private TransformerImpl m_transformer;
42 
43   /** An index to the point in the variable stack where we should
44    * begin variable searches for evaluation of expressions.
45    * This is -1 if m_isTopLevel is false.
46    **/
47   transient private int m_varStackPos = -1;
48 
49   /** An index into the variable stack where the variable context
50    * ends, i.e. at the point we should terminate the search.
51    **/
52   transient private int m_varStackContext;
53 
54   /** true if this variable or parameter is a global.
55    *  @serial */
56   private boolean m_isGlobal;
57 
58   /** true if this variable or parameter is not currently being evaluated. */
59   transient private boolean m_doneEval = true;
60 
61   /**
62    * Create an XUnresolvedVariable, that may be executed at a later time.
63    * This is primarily used so that forward referencing works with
64    * global variables.  An XUnresolvedVariable is initially pushed
65    * into the global variable stack, and then replaced with the real
66    * thing when it is accessed.
67    *
68    * @param obj Must be a non-null reference to an ElemVariable.
69    * @param sourceNode The node context for execution.
70    * @param transformer The transformer execution context.
71    * @param varStackPos An index to the point in the variable stack where we should
72    * begin variable searches for evaluation of expressions.
73    * @param varStackContext An index into the variable stack where the variable context
74    * ends, i.e. at the point we should terminate the search.
75    * @param isGlobal true if this is a global variable.
76    */
XUnresolvedVariable(ElemVariable obj, int sourceNode, TransformerImpl transformer, int varStackPos, int varStackContext, boolean isGlobal)77   public XUnresolvedVariable(ElemVariable obj, int sourceNode,
78                              TransformerImpl transformer,
79                              int varStackPos, int varStackContext,
80                              boolean isGlobal)
81   {
82     super(obj);
83     m_context = sourceNode;
84     m_transformer = transformer;
85 
86     // For globals, this value will have to be updated once we
87     // have determined how many global variables have been pushed.
88     m_varStackPos = varStackPos;
89 
90     // For globals, this should zero.
91     m_varStackContext = varStackContext;
92 
93     m_isGlobal = isGlobal;
94   }
95 
96   /**
97    * For support of literal objects in xpaths.
98    *
99    * @param xctxt The XPath execution context.
100    *
101    * @return This object.
102    *
103    * @throws javax.xml.transform.TransformerException
104    */
execute(XPathContext xctxt)105   public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
106   {
107     if (!m_doneEval)
108     {
109       this.m_transformer.getMsgMgr().error
110         (xctxt.getSAXLocator(), XSLTErrorResources.ER_REFERENCING_ITSELF,
111           new Object[]{((ElemVariable)this.object()).getName().getLocalName()});
112     }
113     VariableStack vars = xctxt.getVarStack();
114 
115     // These three statements need to be combined into one operation.
116     int currentFrame = vars.getStackFrame();
117     //// vars.setStackFrame(m_varStackPos);
118 
119 
120     ElemVariable velem = (ElemVariable)m_obj;
121     try
122     {
123       m_doneEval = false;
124       if(-1 != velem.m_frameSize)
125       	vars.link(velem.m_frameSize);
126       XObject var = velem.getValue(m_transformer, m_context);
127       m_doneEval = true;
128       return var;
129     }
130     finally
131     {
132       // These two statements need to be combined into one operation.
133       // vars.setStackFrame(currentFrame);
134 
135       if(-1 != velem.m_frameSize)
136 	  	vars.unlink(currentFrame);
137     }
138   }
139 
140   /**
141    * Set an index to the point in the variable stack where we should
142    * begin variable searches for evaluation of expressions.
143    * This is -1 if m_isTopLevel is false.
144    *
145    * @param top A valid value that specifies where in the variable
146    * stack the search should begin.
147    */
setVarStackPos(int top)148   public void setVarStackPos(int top)
149   {
150     m_varStackPos = top;
151   }
152 
153   /**
154    * Set an index into the variable stack where the variable context
155    * ends, i.e. at the point we should terminate the search.
156    *
157    * @param bottom The point at which the search should terminate, normally
158    * zero for global variables.
159    */
setVarStackContext(int bottom)160   public void setVarStackContext(int bottom)
161   {
162     m_varStackContext = bottom;
163   }
164 
165   /**
166    * Tell what kind of class this is.
167    *
168    * @return CLASS_UNRESOLVEDVARIABLE
169    */
getType()170   public int getType()
171   {
172     return CLASS_UNRESOLVEDVARIABLE;
173   }
174 
175   /**
176    * Given a request type, return the equivalent string.
177    * For diagnostic purposes.
178    *
179    * @return An informational string.
180    */
getTypeString()181   public String getTypeString()
182   {
183     return "XUnresolvedVariable (" + object().getClass().getName() + ")";
184   }
185 
186 
187 }
188