KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xpath > axes > WalkingIterator


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: WalkingIterator.java,v 1.10 2004/02/17 04:32:08 minchau Exp $
18  */

19 package org.apache.xpath.axes;
20
21 import org.apache.xml.dtm.DTM;
22 import org.apache.xml.utils.PrefixResolver;
23 import org.apache.xpath.Expression;
24 import org.apache.xpath.ExpressionOwner;
25 import org.apache.xpath.VariableStack;
26 import org.apache.xpath.XPathVisitor;
27 import org.apache.xpath.compiler.Compiler;
28
29 /**
30  * Location path iterator that uses Walkers.
31  */

32
33 public class WalkingIterator extends LocPathIterator implements ExpressionOwner
34 {
35   /**
36    * Create a WalkingIterator iterator, including creation
37    * of step walkers from the opcode list, and call back
38    * into the Compiler to create predicate expressions.
39    *
40    * @param compiler The Compiler which is creating
41    * this expression.
42    * @param opPos The position of this iterator in the
43    * opcode list from the compiler.
44    * @param shouldLoadWalkers True if walkers should be
45    * loaded, or false if this is a derived iterator and
46    * it doesn't wish to load child walkers.
47    *
48    * @throws javax.xml.transform.TransformerException
49    */

50   WalkingIterator(
51           Compiler JavaDoc compiler, int opPos, int analysis, boolean shouldLoadWalkers)
52             throws javax.xml.transform.TransformerException JavaDoc
53   {
54     super(compiler, opPos, analysis, shouldLoadWalkers);
55     
56     int firstStepPos = compiler.getFirstChildPos(opPos);
57
58     if (shouldLoadWalkers)
59     {
60       m_firstWalker = WalkerFactory.loadWalkers(this, compiler, firstStepPos, 0);
61       m_lastUsedWalker = m_firstWalker;
62     }
63   }
64   
65   /**
66    * Create a WalkingIterator object.
67    *
68    * @param nscontext The namespace context for this iterator,
69    * should be OK if null.
70    */

71   public WalkingIterator(PrefixResolver nscontext)
72   {
73
74     super(nscontext);
75   }
76   
77   
78   /**
79    * Get the analysis bits for this walker, as defined in the WalkerFactory.
80    * @return One of WalkerFactory#BIT_DESCENDANT, etc.
81    */

82   public int getAnalysisBits()
83   {
84     int bits = 0;
85     if (null != m_firstWalker)
86     {
87       AxesWalker walker = m_firstWalker;
88
89       while (null != walker)
90       {
91         int bit = walker.getAnalysisBits();
92         bits |= bit;
93         walker = walker.getNextWalker();
94       }
95     }
96     return bits;
97   }
98   
99   /**
100    * Get a cloned WalkingIterator that holds the same
101    * position as this iterator.
102    *
103    * @return A clone of this iterator that holds the same node position.
104    *
105    * @throws CloneNotSupportedException
106    */

107   public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc
108   {
109
110     WalkingIterator clone = (WalkingIterator) super.clone();
111
112     // clone.m_varStackPos = this.m_varStackPos;
113
// clone.m_varStackContext = this.m_varStackContext;
114
if (null != m_firstWalker)
115     {
116       clone.m_firstWalker = m_firstWalker.cloneDeep(clone, null);
117     }
118
119     return clone;
120   }
121   
122   /**
123    * Reset the iterator.
124    */

125   public void reset()
126   {
127
128     super.reset();
129
130     if (null != m_firstWalker)
131     {
132       m_lastUsedWalker = m_firstWalker;
133
134       m_firstWalker.setRoot(m_context);
135     }
136
137   }
138   
139   /**
140    * Initialize the context values for this expression
141    * after it is cloned.
142    *
143    * @param execContext The XPath runtime context for this
144    * transformation.
145    */

146   public void setRoot(int context, Object JavaDoc environment)
147   {
148
149     super.setRoot(context, environment);
150     
151     if(null != m_firstWalker)
152     {
153       m_firstWalker.setRoot(context);
154       m_lastUsedWalker = m_firstWalker;
155     }
156   }
157   
158   /**
159    * Returns the next node in the set and advances the position of the
160    * iterator in the set. After a NodeIterator is created, the first call
161    * to nextNode() returns the first node in the set.
162    * @return The next <code>Node</code> in the set being iterated over, or
163    * <code>null</code> if there are no more members in that set.
164    */

165   public int nextNode()
166   {
167     if(m_foundLast)
168         return DTM.NULL;
169
170     // If the variable stack position is not -1, we'll have to
171
// set our position in the variable stack, so our variable access
172
// will be correct. Iterators that are at the top level of the
173
// expression need to reset the variable stack, while iterators
174
// in predicates do not need to, and should not, since their execution
175
// may be much later than top-level iterators.
176
// m_varStackPos is set in setRoot, which is called
177
// from the execute method.
178
if (-1 == m_stackFrame)
179     {
180       return returnNextNode(m_firstWalker.nextNode());
181     }
182     else
183     {
184       VariableStack vars = m_execContext.getVarStack();
185
186       // These three statements need to be combined into one operation.
187
int savedStart = vars.getStackFrame();
188
189       vars.setStackFrame(m_stackFrame);
190
191       int n = returnNextNode(m_firstWalker.nextNode());
192
193       // These two statements need to be combined into one operation.
194
vars.setStackFrame(savedStart);
195
196       return n;
197     }
198   }
199
200   
201   /**
202    * Get the head of the walker list.
203    *
204    * @return The head of the walker list, or null
205    * if this iterator does not implement walkers.
206    * @xsl.usage advanced
207    */

208   public final AxesWalker getFirstWalker()
209   {
210     return m_firstWalker;
211   }
212   
213   /**
214    * Set the head of the walker list.
215    *
216    * @param walker Should be a valid AxesWalker.
217    * @xsl.usage advanced
218    */

219   public final void setFirstWalker(AxesWalker walker)
220   {
221     m_firstWalker = walker;
222   }
223
224
225   /**
226    * Set the last used walker.
227    *
228    * @param walker The last used walker, or null.
229    * @xsl.usage advanced
230    */

231   public final void setLastUsedWalker(AxesWalker walker)
232   {
233     m_lastUsedWalker = walker;
234   }
235
236   /**
237    * Get the last used walker.
238    *
239    * @return The last used walker, or null.
240    * @xsl.usage advanced
241    */

242   public final AxesWalker getLastUsedWalker()
243   {
244     return m_lastUsedWalker;
245   }
246   
247   /**
248    * Detaches the iterator from the set which it iterated over, releasing
249    * any computational resources and placing the iterator in the INVALID
250    * state. After<code>detach</code> has been invoked, calls to
251    * <code>nextNode</code> or<code>previousNode</code> will raise the
252    * exception INVALID_STATE_ERR.
253    */

254   public void detach()
255   {
256     if(m_allowDetach)
257     {
258         AxesWalker walker = m_firstWalker;
259         while (null != walker)
260         {
261           walker.detach();
262           walker = walker.getNextWalker();
263         }
264     
265         m_lastUsedWalker = null;
266         
267         // Always call the superclass detach last!
268
super.detach();
269     }
270   }
271   
272   /**
273    * This function is used to fixup variables from QNames to stack frame
274    * indexes at stylesheet build time.
275    * @param vars List of QNames that correspond to variables. This list
276    * should be searched backwards for the first qualified name that
277    * corresponds to the variable reference qname. The position of the
278    * QName in the vector from the start of the vector will be its position
279    * in the stack frame (but variables above the globalsTop value will need
280    * to be offset to the current stack frame).
281    */

282   public void fixupVariables(java.util.Vector JavaDoc vars, int globalsSize)
283   {
284     m_predicateIndex = -1;
285
286     AxesWalker walker = m_firstWalker;
287
288     while (null != walker)
289     {
290       walker.fixupVariables(vars, globalsSize);
291       walker = walker.getNextWalker();
292     }
293   }
294   
295   /**
296    * @see org.apache.xpath.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
297    */

298   public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
299   {
300         if(visitor.visitLocationPath(owner, this))
301         {
302             if(null != m_firstWalker)
303             {
304                 m_firstWalker.callVisitors(this, visitor);
305             }
306         }
307   }
308
309   
310   /** The last used step walker in the walker list.
311    * @serial */

312   protected AxesWalker m_lastUsedWalker;
313
314   /** The head of the step walker list.
315    * @serial */

316   protected AxesWalker m_firstWalker;
317
318   /**
319    * @see ExpressionOwner#getExpression()
320    */

321   public Expression getExpression()
322   {
323     return m_firstWalker;
324   }
325
326   /**
327    * @see ExpressionOwner#setExpression(Expression)
328    */

329   public void setExpression(Expression exp)
330   {
331     exp.exprSetParent(this);
332     m_firstWalker = (AxesWalker)exp;
333   }
334   
335     /**
336      * @see Expression#deepEquals(Expression)
337      */

338     public boolean deepEquals(Expression expr)
339     {
340       if (!super.deepEquals(expr))
341                 return false;
342
343       AxesWalker walker1 = m_firstWalker;
344       AxesWalker walker2 = ((WalkingIterator)expr).m_firstWalker;
345       while ((null != walker1) && (null != walker2))
346       {
347         if(!walker1.deepEquals(walker2))
348             return false;
349         walker1 = walker1.getNextWalker();
350         walker2 = walker2.getNextWalker();
351       }
352       
353       if((null != walker1) || (null != walker2))
354         return false;
355
356       return true;
357     }
358
359 }
360
Popular Tags