KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xpath > internal > axes > FilterExprWalker


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

19 package com.sun.org.apache.xpath.internal.axes;
20
21 import com.sun.org.apache.xml.internal.dtm.Axis;
22 import com.sun.org.apache.xml.internal.dtm.DTM;
23 import com.sun.org.apache.xml.internal.dtm.DTMIterator;
24 import com.sun.org.apache.xpath.internal.Expression;
25 import com.sun.org.apache.xpath.internal.ExpressionOwner;
26 import com.sun.org.apache.xpath.internal.XPathContext;
27 import com.sun.org.apache.xpath.internal.XPathVisitor;
28 import com.sun.org.apache.xpath.internal.compiler.Compiler;
29 import com.sun.org.apache.xpath.internal.compiler.OpCodes;
30 import com.sun.org.apache.xpath.internal.objects.XNodeSet;
31
32 /**
33  * Walker for the OP_VARIABLE, or OP_EXTFUNCTION, or OP_FUNCTION, or OP_GROUP,
34  * op codes.
35  * @see <a HREF="http://www.w3.org/TR/xpath#NT-FilterExpr">XPath FilterExpr descriptions</a>
36  */

37 public class FilterExprWalker extends AxesWalker
38 {
39
40   /**
41    * Construct a FilterExprWalker using a LocPathIterator.
42    *
43    * @param locPathIterator non-null reference to the parent iterator.
44    */

45   public FilterExprWalker(WalkingIterator locPathIterator)
46   {
47     super(locPathIterator, Axis.FILTEREDLIST);
48   }
49
50   /**
51    * Init a FilterExprWalker.
52    *
53    * @param compiler non-null reference to the Compiler that is constructing.
54    * @param opPos positive opcode position for this step.
55    * @param stepType The type of step.
56    *
57    * @throws javax.xml.transform.TransformerException
58    */

59   public void init(Compiler JavaDoc compiler, int opPos, int stepType)
60           throws javax.xml.transform.TransformerException JavaDoc
61   {
62
63     super.init(compiler, opPos, stepType);
64
65     // Smooth over an anomily in the opcode map...
66
switch (stepType)
67     {
68     case OpCodes.OP_FUNCTION :
69     case OpCodes.OP_EXTFUNCTION :
70         m_mustHardReset = true;
71     case OpCodes.OP_GROUP :
72     case OpCodes.OP_VARIABLE :
73       m_expr = compiler.compile(opPos);
74       m_expr.exprSetParent(this);
75       //if((OpCodes.OP_FUNCTION == stepType) && (m_expr instanceof com.sun.org.apache.xalan.internal.templates.FuncKey))
76
if(m_expr instanceof com.sun.org.apache.xpath.internal.operations.Variable)
77       {
78         // hack/temp workaround
79
m_canDetachNodeset = false;
80       }
81       break;
82     default :
83       m_expr = compiler.compile(opPos + 2);
84       m_expr.exprSetParent(this);
85     }
86 // if(m_expr instanceof WalkingIterator)
87
// {
88
// WalkingIterator wi = (WalkingIterator)m_expr;
89
// if(wi.getFirstWalker() instanceof FilterExprWalker)
90
// {
91
// FilterExprWalker fw = (FilterExprWalker)wi.getFirstWalker();
92
// if(null == fw.getNextWalker())
93
// {
94
// m_expr = fw.m_expr;
95
// m_expr.exprSetParent(this);
96
// }
97
// }
98
//
99
// }
100
}
101   
102   /**
103    * Detaches the walker from the set which it iterated over, releasing
104    * any computational resources and placing the iterator in the INVALID
105    * state.
106    */

107   public void detach()
108   {
109     super.detach();
110     if (m_canDetachNodeset)
111     {
112       m_exprObj.detach();
113     }
114     m_exprObj = null;
115   }
116
117   /**
118    * Set the root node of the TreeWalker.
119    *
120    * @param root non-null reference to the root, or starting point of
121    * the query.
122    */

123   public void setRoot(int root)
124   {
125
126     super.setRoot(root);
127
128     m_exprObj = FilterExprIteratorSimple.executeFilterExpr(root,
129                       m_lpi.getXPathContext(), m_lpi.getPrefixResolver(),
130                       m_lpi.getIsTopLevel(), m_lpi.m_stackFrame, m_expr);
131
132   }
133
134   /**
135    * Get a cloned FilterExprWalker.
136    *
137    * @return A new FilterExprWalker that can be used without mutating this one.
138    *
139    * @throws CloneNotSupportedException
140    */

141   public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc
142   {
143
144     FilterExprWalker clone = (FilterExprWalker) super.clone();
145
146     // clone.m_expr = (Expression)((Expression)m_expr).clone();
147
if (null != m_exprObj)
148       clone.m_exprObj = (XNodeSet) m_exprObj.clone();
149
150     return clone;
151   }
152   
153   /**
154    * This method needs to override AxesWalker.acceptNode because FilterExprWalkers
155    * don't need to, and shouldn't, do a node test.
156    * @param n The node to check to see if it passes the filter or not.
157    * @return a constant to determine whether the node is accepted,
158    * rejected, or skipped, as defined above .
159    */

160   public short acceptNode(int n)
161   {
162
163     try
164     {
165       if (getPredicateCount() > 0)
166       {
167         countProximityPosition(0);
168
169         if (!executePredicates(n, m_lpi.getXPathContext()))
170           return DTMIterator.FILTER_SKIP;
171       }
172
173       return DTMIterator.FILTER_ACCEPT;
174     }
175     catch (javax.xml.transform.TransformerException JavaDoc se)
176     {
177       throw new RuntimeException JavaDoc(se.getMessage());
178     }
179   }
180
181   /**
182    * Moves the <code>TreeWalker</code> to the next visible node in document
183    * order relative to the current node, and returns the new node. If the
184    * current node has no next node, or if the search for nextNode attempts
185    * to step upward from the TreeWalker's root node, returns
186    * <code>null</code> , and retains the current node.
187    * @return The new node, or <code>null</code> if the current node has no
188    * next node in the TreeWalker's logical view.
189    */

190   public int getNextNode()
191   {
192
193     if (null != m_exprObj)
194     {
195        int next = m_exprObj.nextNode();
196        return next;
197     }
198     else
199       return DTM.NULL;
200   }
201   
202   /**
203    * Get the index of the last node that can be itterated to.
204    *
205    *
206    * @param xctxt XPath runtime context.
207    *
208    * @return the index of the last node that can be itterated to.
209    */

210   public int getLastPos(XPathContext xctxt)
211   {
212     return m_exprObj.getLength();
213   }
214   
215   /** The contained expression. Should be non-null.
216    * @serial */

217   private Expression m_expr;
218
219   /** The result of executing m_expr. Needs to be deep cloned on clone op. */
220   transient private XNodeSet m_exprObj;
221   
222   private boolean m_mustHardReset = false;
223   private boolean m_canDetachNodeset = true;
224
225   /**
226    * This function is used to fixup variables from QNames to stack frame
227    * indexes at stylesheet build time.
228    * @param vars List of QNames that correspond to variables. This list
229    * should be searched backwards for the first qualified name that
230    * corresponds to the variable reference qname. The position of the
231    * QName in the vector from the start of the vector will be its position
232    * in the stack frame (but variables above the globalsTop value will need
233    * to be offset to the current stack frame).
234    */

235   public void fixupVariables(java.util.Vector JavaDoc vars, int globalsSize)
236   {
237     super.fixupVariables(vars, globalsSize);
238     m_expr.fixupVariables(vars, globalsSize);
239   }
240   
241   /**
242    * Get the inner contained expression of this filter.
243    */

244   public Expression getInnerExpression()
245   {
246     return m_expr;
247   }
248   
249   /**
250    * Set the inner contained expression of this filter.
251    */

252   public void setInnerExpression(Expression expr)
253   {
254     expr.exprSetParent(this);
255     m_expr = expr;
256   }
257
258   
259   /**
260    * Get the analysis bits for this walker, as defined in the WalkerFactory.
261    * @return One of WalkerFactory#BIT_DESCENDANT, etc.
262    */

263   public int getAnalysisBits()
264   {
265       if (null != m_expr && m_expr instanceof PathComponent)
266       {
267         return ((PathComponent) m_expr).getAnalysisBits();
268       }
269       return WalkerFactory.BIT_FILTER;
270   }
271   
272   /**
273    * Returns true if all the nodes in the iteration well be returned in document
274    * order.
275    * Warning: This can only be called after setRoot has been called!
276    *
277    * @return true as a default.
278    */

279   public boolean isDocOrdered()
280   {
281     return m_exprObj.isDocOrdered();
282   }
283   
284   /**
285    * Returns the axis being iterated, if it is known.
286    *
287    * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple
288    * types.
289    */

290   public int getAxis()
291   {
292     return m_exprObj.getAxis();
293   }
294   
295   class filterExprOwner implements ExpressionOwner
296   {
297       /**
298      * @see ExpressionOwner#getExpression()
299      */

300     public Expression getExpression()
301     {
302       return m_expr;
303     }
304
305     /**
306      * @see ExpressionOwner#setExpression(Expression)
307      */

308     public void setExpression(Expression exp)
309     {
310         exp.exprSetParent(FilterExprWalker.this);
311         m_expr = exp;
312     }
313   }
314   
315     /**
316      * This will traverse the heararchy, calling the visitor for
317      * each member. If the called visitor method returns
318      * false, the subtree should not be called.
319      *
320      * @param owner The owner of the visitor, where that path may be
321      * rewritten if needed.
322      * @param visitor The visitor whose appropriate method will be called.
323      */

324     public void callPredicateVisitors(XPathVisitor visitor)
325     {
326       m_expr.callVisitors(new filterExprOwner(), visitor);
327       
328       super.callPredicateVisitors(visitor);
329     }
330
331
332     /**
333      * @see Expression#deepEquals(Expression)
334      */

335     public boolean deepEquals(Expression expr)
336     {
337       if (!super.deepEquals(expr))
338                 return false;
339
340       FilterExprWalker walker = (FilterExprWalker)expr;
341       if(!m_expr.deepEquals(walker.m_expr))
342         return false;
343
344       return true;
345     }
346
347     
348
349 }
350
Popular Tags