KickJava   Java API By Example, From Geeks To Geeks.

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


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: FilterExprIteratorSimple.java,v 1.5 2004/02/17 04:32:08 minchau Exp $
18  */

19 package org.apache.xpath.axes;
20
21 import org.apache.xml.dtm.Axis;
22 import org.apache.xml.dtm.DTM;
23 import org.apache.xml.utils.PrefixResolver;
24 import org.apache.xpath.Expression;
25 import org.apache.xpath.ExpressionOwner;
26 import org.apache.xpath.VariableStack;
27 import org.apache.xpath.XPathContext;
28 import org.apache.xpath.XPathVisitor;
29 import org.apache.xpath.objects.XNodeSet;
30
31 /**
32  * Class to use for one-step iteration that doesn't have a predicate, and
33  * doesn't need to set the context.
34  */

35 public class FilterExprIteratorSimple extends LocPathIterator
36 {
37   /** The contained expression. Should be non-null.
38    * @serial */

39   private Expression m_expr;
40
41   /** The result of executing m_expr. Needs to be deep cloned on clone op. */
42   transient private XNodeSet m_exprObj;
43
44   private boolean m_mustHardReset = false;
45   private boolean m_canDetachNodeset = true;
46
47   /**
48    * Create a ChildTestIterator object.
49    *
50    * @param traverser Traverser that tells how the KeyIterator is to be handled.
51    *
52    * @throws javax.xml.transform.TransformerException
53    */

54   public FilterExprIteratorSimple()
55   {
56     super(null);
57   }
58   
59   /**
60    * Create a ChildTestIterator object.
61    *
62    * @param traverser Traverser that tells how the KeyIterator is to be handled.
63    *
64    * @throws javax.xml.transform.TransformerException
65    */

66   public FilterExprIteratorSimple(Expression expr)
67   {
68     super(null);
69     m_expr = expr;
70   }
71   
72   /**
73    * Initialize the context values for this expression
74    * after it is cloned.
75    *
76    * @param execContext The XPath runtime context for this
77    * transformation.
78    */

79   public void setRoot(int context, Object JavaDoc environment)
80   {
81     super.setRoot(context, environment);
82     m_exprObj = executeFilterExpr(context, m_execContext, getPrefixResolver(),
83                       getIsTopLevel(), m_stackFrame, m_expr);
84   }
85
86   /**
87    * Execute the expression. Meant for reuse by other FilterExpr iterators
88    * that are not derived from this object.
89    */

90   public static XNodeSet executeFilterExpr(int context, XPathContext xctxt,
91                                                 PrefixResolver prefixResolver,
92                                                 boolean isTopLevel,
93                                                 int stackFrame,
94                                                 Expression expr )
95     throws org.apache.xml.utils.WrappedRuntimeException
96   {
97     PrefixResolver savedResolver = xctxt.getNamespaceContext();
98     XNodeSet result = null;
99
100     try
101     {
102       xctxt.pushCurrentNode(context);
103       xctxt.setNamespaceContext(prefixResolver);
104
105       // The setRoot operation can take place with a reset operation,
106
// and so we may not be in the context of LocPathIterator#nextNode,
107
// so we have to set up the variable context, execute the expression,
108
// and then restore the variable context.
109

110       if (isTopLevel)
111       {
112         // System.out.println("calling m_expr.execute(getXPathContext())");
113
VariableStack vars = xctxt.getVarStack();
114
115         // These three statements need to be combined into one operation.
116
int savedStart = vars.getStackFrame();
117         vars.setStackFrame(stackFrame);
118
119         result = (org.apache.xpath.objects.XNodeSet) expr.execute(xctxt);
120         result.setShouldCacheNodes(true);
121
122         // These two statements need to be combined into one operation.
123
vars.setStackFrame(savedStart);
124       }
125       else
126           result = (org.apache.xpath.objects.XNodeSet) expr.execute(xctxt);
127
128     }
129     catch (javax.xml.transform.TransformerException JavaDoc se)
130     {
131
132       // TODO: Fix...
133
throw new org.apache.xml.utils.WrappedRuntimeException(se);
134     }
135     finally
136     {
137       xctxt.popCurrentNode();
138       xctxt.setNamespaceContext(savedResolver);
139     }
140     return result;
141   }
142   
143   /**
144    * Returns the next node in the set and advances the position of the
145    * iterator in the set. After a NodeIterator is created, the first call
146    * to nextNode() returns the first node in the set.
147    *
148    * @return The next <code>Node</code> in the set being iterated over, or
149    * <code>null</code> if there are no more members in that set.
150    */

151   public int nextNode()
152   {
153     if(m_foundLast)
154         return DTM.NULL;
155
156     int next;
157
158     if (null != m_exprObj)
159     {
160       m_lastFetched = next = m_exprObj.nextNode();
161     }
162     else
163       m_lastFetched = next = DTM.NULL;
164
165     // m_lastFetched = next;
166
if (DTM.NULL != next)
167     {
168       m_pos++;
169       return next;
170     }
171     else
172     {
173       m_foundLast = true;
174
175       return DTM.NULL;
176     }
177   }
178   
179   /**
180    * Detaches the walker from the set which it iterated over, releasing
181    * any computational resources and placing the iterator in the INVALID
182    * state.
183    */

184   public void detach()
185   {
186     if(m_allowDetach)
187     {
188         super.detach();
189         m_exprObj.detach();
190         m_exprObj = null;
191     }
192   }
193
194   /**
195    * This function is used to fixup variables from QNames to stack frame
196    * indexes at stylesheet build time.
197    * @param vars List of QNames that correspond to variables. This list
198    * should be searched backwards for the first qualified name that
199    * corresponds to the variable reference qname. The position of the
200    * QName in the vector from the start of the vector will be its position
201    * in the stack frame (but variables above the globalsTop value will need
202    * to be offset to the current stack frame).
203    */

204   public void fixupVariables(java.util.Vector JavaDoc vars, int globalsSize)
205   {
206     super.fixupVariables(vars, globalsSize);
207     m_expr.fixupVariables(vars, globalsSize);
208   }
209
210   /**
211    * Get the inner contained expression of this filter.
212    */

213   public Expression getInnerExpression()
214   {
215     return m_expr;
216   }
217
218   /**
219    * Set the inner contained expression of this filter.
220    */

221   public void setInnerExpression(Expression expr)
222   {
223     expr.exprSetParent(this);
224     m_expr = expr;
225   }
226
227   /**
228    * Get the analysis bits for this walker, as defined in the WalkerFactory.
229    * @return One of WalkerFactory#BIT_DESCENDANT, etc.
230    */

231   public int getAnalysisBits()
232   {
233     if (null != m_expr && m_expr instanceof PathComponent)
234     {
235       return ((PathComponent) m_expr).getAnalysisBits();
236     }
237     return WalkerFactory.BIT_FILTER;
238   }
239
240   /**
241    * Returns true if all the nodes in the iteration well be returned in document
242    * order.
243    * Warning: This can only be called after setRoot has been called!
244    *
245    * @return true as a default.
246    */

247   public boolean isDocOrdered()
248   {
249     return m_exprObj.isDocOrdered();
250   }
251
252   class filterExprOwner implements ExpressionOwner
253   {
254     /**
255     * @see ExpressionOwner#getExpression()
256     */

257     public Expression getExpression()
258     {
259       return m_expr;
260     }
261
262     /**
263      * @see ExpressionOwner#setExpression(Expression)
264      */

265     public void setExpression(Expression exp)
266     {
267       exp.exprSetParent(FilterExprIteratorSimple.this);
268       m_expr = exp;
269     }
270
271   }
272
273   /**
274    * This will traverse the heararchy, calling the visitor for
275    * each member. If the called visitor method returns
276    * false, the subtree should not be called.
277    *
278    * @param owner The owner of the visitor, where that path may be
279    * rewritten if needed.
280    * @param visitor The visitor whose appropriate method will be called.
281    */

282   public void callPredicateVisitors(XPathVisitor visitor)
283   {
284     m_expr.callVisitors(new filterExprOwner(), visitor);
285
286     super.callPredicateVisitors(visitor);
287   }
288
289   /**
290    * @see Expression#deepEquals(Expression)
291    */

292   public boolean deepEquals(Expression expr)
293   {
294     if (!super.deepEquals(expr))
295       return false;
296
297     FilterExprIteratorSimple fet = (FilterExprIteratorSimple) expr;
298     if (!m_expr.deepEquals(fet.m_expr))
299       return false;
300
301     return true;
302   }
303   
304   /**
305    * Returns the axis being iterated, if it is known.
306    *
307    * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple
308    * types.
309    */

310   public int getAxis()
311   {
312     if(null != m_exprObj)
313         return m_exprObj.getAxis();
314     else
315         return Axis.FILTEREDLIST;
316   }
317
318
319 }
320
321
Popular Tags