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
22package com.sun.org.apache.xpath.internal.axes;
23
24import com.sun.org.apache.xml.internal.dtm.DTM;
25import com.sun.org.apache.xml.internal.dtm.DTMFilter;
26import com.sun.org.apache.xml.internal.dtm.DTMIterator;
27import com.sun.org.apache.xml.internal.utils.PrefixResolver;
28import com.sun.org.apache.xpath.internal.compiler.Compiler;
29import 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 */
36public 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   */
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   */
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   */
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   */
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   */
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   */
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   */
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