1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /*
6  * Licensed to the Apache Software Foundation (ASF) under one or more
7  * contributor license agreements.  See the NOTICE file distributed with
8  * this work for additional information regarding copyright ownership.
9  * The ASF licenses this file to You under the Apache License, Version 2.0
10  * (the "License"); you may not use this file except in compliance with
11  * the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 package com.sun.org.apache.xpath.internal.axes;
23 
24 import com.sun.org.apache.xml.internal.dtm.DTM;
25 import com.sun.org.apache.xml.internal.dtm.DTMFilter;
26 import com.sun.org.apache.xml.internal.dtm.DTMIterator;
27 import com.sun.org.apache.xml.internal.utils.PrefixResolver;
28 import com.sun.org.apache.xpath.internal.compiler.Compiler;
29 import com.sun.org.apache.xpath.internal.compiler.OpMap;
30 
31 /**
32  * Base for iterators that handle predicates.  Does the basic next
33  * node logic, so all the derived iterator has to do is get the
34  * next node.
35  */
36 public abstract class BasicTestIterator extends LocPathIterator
37 {
38     static final long serialVersionUID = 3505378079378096623L;
39   /**
40    * Create a LocPathIterator object.
41    *
42    * @param nscontext The namespace context for this iterator,
43    * should be OK if null.
44    */
BasicTestIterator()45   protected BasicTestIterator()
46   {
47   }
48 
49 
50   /**
51    * Create a LocPathIterator object.
52    *
53    * @param nscontext The namespace context for this iterator,
54    * should be OK if null.
55    */
BasicTestIterator(PrefixResolver nscontext)56   protected BasicTestIterator(PrefixResolver nscontext)
57   {
58 
59     super(nscontext);
60   }
61 
62   /**
63    * Create a LocPathIterator object, including creation
64    * of step walkers from the opcode list, and call back
65    * into the Compiler to create predicate expressions.
66    *
67    * @param compiler The Compiler which is creating
68    * this expression.
69    * @param opPos The position of this iterator in the
70    * opcode list from the compiler.
71    *
72    * @throws javax.xml.transform.TransformerException
73    */
BasicTestIterator(Compiler compiler, int opPos, int analysis)74   protected BasicTestIterator(Compiler compiler, int opPos, int analysis)
75           throws javax.xml.transform.TransformerException
76   {
77     super(compiler, opPos, analysis, false);
78 
79     int firstStepPos = OpMap.getFirstChildPos(opPos);
80     int whatToShow = compiler.getWhatToShow(firstStepPos);
81 
82     if ((0 == (whatToShow
83                & (DTMFilter.SHOW_ATTRIBUTE
84                | DTMFilter.SHOW_NAMESPACE
85                | DTMFilter.SHOW_ELEMENT
86                | DTMFilter.SHOW_PROCESSING_INSTRUCTION)))
87                || (whatToShow == DTMFilter.SHOW_ALL))
88       initNodeTest(whatToShow);
89     else
90     {
91       initNodeTest(whatToShow, compiler.getStepNS(firstStepPos),
92                               compiler.getStepLocalName(firstStepPos));
93     }
94     initPredicateInfo(compiler, firstStepPos);
95   }
96 
97   /**
98    * Create a LocPathIterator object, including creation
99    * of step walkers from the opcode list, and call back
100    * into the Compiler to create predicate expressions.
101    *
102    * @param compiler The Compiler which is creating
103    * this expression.
104    * @param opPos The position of this iterator in the
105    * opcode list from the compiler.
106    * @param shouldLoadWalkers True if walkers should be
107    * loaded, or false if this is a derived iterator and
108    * it doesn't wish to load child walkers.
109    *
110    * @throws javax.xml.transform.TransformerException
111    */
BasicTestIterator( Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers)112   protected BasicTestIterator(
113           Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers)
114             throws javax.xml.transform.TransformerException
115   {
116     super(compiler, opPos, analysis, shouldLoadWalkers);
117   }
118 
119 
120   /**
121    * Get the next node via getNextXXX.  Bottlenecked for derived class override.
122    * @return The next node on the axis, or DTM.NULL.
123    */
getNextNode()124   protected abstract int getNextNode();
125 
126   /**
127    *  Returns the next node in the set and advances the position of the
128    * iterator in the set. After a NodeIterator is created, the first call
129    * to nextNode() returns the first node in the set.
130    *
131    * @return  The next <code>Node</code> in the set being iterated over, or
132    *   <code>null</code> if there are no more members in that set.
133    */
nextNode()134   public int nextNode()
135   {
136         if(m_foundLast)
137         {
138                 m_lastFetched = DTM.NULL;
139                 return DTM.NULL;
140         }
141 
142     if(DTM.NULL == m_lastFetched)
143     {
144       resetProximityPositions();
145     }
146 
147     int next;
148 
149     com.sun.org.apache.xpath.internal.VariableStack vars;
150     int savedStart;
151     if (-1 != m_stackFrame)
152     {
153       vars = m_execContext.getVarStack();
154 
155       // These three statements need to be combined into one operation.
156       savedStart = vars.getStackFrame();
157 
158       vars.setStackFrame(m_stackFrame);
159     }
160     else
161     {
162       // Yuck.  Just to shut up the compiler!
163       vars = null;
164       savedStart = 0;
165     }
166 
167     try
168     {
169       do
170       {
171         next = getNextNode();
172 
173         if (DTM.NULL != next)
174         {
175           if(DTMIterator.FILTER_ACCEPT == acceptNode(next))
176             break;
177           else
178             continue;
179         }
180         else
181           break;
182       }
183       while (next != DTM.NULL);
184 
185       if (DTM.NULL != next)
186       {
187         m_pos++;
188         return next;
189       }
190       else
191       {
192         m_foundLast = true;
193 
194         return DTM.NULL;
195       }
196     }
197     finally
198     {
199       if (-1 != m_stackFrame)
200       {
201         // These two statements need to be combined into one operation.
202         vars.setStackFrame(savedStart);
203       }
204     }
205   }
206 
207   /**
208    *  Get a cloned Iterator that is reset to the beginning
209    *  of the query.
210    *
211    *  @return A cloned NodeIterator set of the start of the query.
212    *
213    *  @throws CloneNotSupportedException
214    */
cloneWithReset()215   public DTMIterator cloneWithReset() throws CloneNotSupportedException
216   {
217 
218     ChildTestIterator clone = (ChildTestIterator) super.cloneWithReset();
219 
220     clone.resetProximityPositions();
221 
222     return clone;
223   }
224 
225 
226 }
227