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