FileDocCategorySizeDatePackage
OneStepIterator.javaAPI DocJava SE 5 API9021Fri Aug 26 14:56:06 BST 2005com.sun.org.apache.xpath.internal.axes

OneStepIterator

public class OneStepIterator extends ChildTestIterator
This class implements a general iterator for those LocationSteps with only one step, and perhaps a predicate.
see
com.sun.org.apache.xpath.internal.axes#LocPathIterator
xsl.usage
advanced

Fields Summary
protected int
m_axis
The traversal axis from where the nodes will be filtered.
protected DTMAxisIterator
m_iterator
The DTM inner traversal class, that corresponds to the super axis.
Constructors Summary
OneStepIterator(Compiler compiler, int opPos, int analysis)
Create a OneStepIterator object.

param
compiler A reference to the Compiler that contains the op map.
param
opPos The position within the op map, which contains the location path expression for this itterator.
throws
javax.xml.transform.TransformerException


                                        
       
           
  
    super(compiler, opPos, analysis);
    int firstStepPos = compiler.getFirstChildPos(opPos);
    
    m_axis = WalkerFactory.getAxisFromStep(compiler, firstStepPos);
    
  
public OneStepIterator(DTMAxisIterator iterator, int axis)
Create a OneStepIterator object.

param
iterator The DTM iterator which this iterator will use.
param
axis One of Axis.Child, etc., or -1 if the axis is unknown.
throws
javax.xml.transform.TransformerException

    super(null);
    
    m_iterator = iterator;
    m_axis = axis;
    int whatToShow = DTMFilter.SHOW_ALL;
    initNodeTest(whatToShow);
  
Methods Summary
public java.lang.Objectclone()
Get a cloned iterator.

return
A new iterator that can be used without mutating this one.
throws
CloneNotSupportedException

    // Do not access the location path itterator during this operation!
    
    OneStepIterator clone = (OneStepIterator) super.clone();

    if(m_iterator != null)
    {
      clone.m_iterator = m_iterator.cloneIterator();
    }
    return clone;
  
public com.sun.org.apache.xml.internal.dtm.DTMIteratorcloneWithReset()
Get a cloned Iterator that is reset to the beginning of the query.

return
A cloned NodeIterator set of the start of the query.
throws
CloneNotSupportedException


    OneStepIterator clone = (OneStepIterator) super.cloneWithReset();
    clone.m_iterator = m_iterator;

    return clone;
  
protected voidcountProximityPosition(int i)
Count backwards one proximity position.

param
i The predicate index.

    if(!isReverseAxes())
      super.countProximityPosition(i);
    else if (i < m_proximityPositions.length)
      m_proximityPositions[i]--;
  
public booleandeepEquals(com.sun.org.apache.xpath.internal.Expression expr)

see
Expression#deepEquals(Expression)

  	if(!super.deepEquals(expr))
  		return false;
  		
  	if(m_axis != ((OneStepIterator)expr).m_axis)
  		return false;
  		
  	return true;
  
public voiddetach()
Detaches the iterator from the set which it iterated over, releasing any computational resources and placing the iterator in the INVALID state. Afterdetach has been invoked, calls to nextNode orpreviousNode will raise the exception INVALID_STATE_ERR.

    
    if(m_allowDetach)
    {
      if(m_axis > -1)
        m_iterator = null;
      
      // Always call the superclass detach last!
      super.detach();
    }
  
public intgetAxis()
Returns the axis being iterated, if it is known.

return
Axis.CHILD, etc., or -1 if the axis is not known or is of multiple types.

    return m_axis;
  
public intgetLength()
The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.

return
The number of nodes in the list, always greater or equal to zero.

    if(!isReverseAxes())
      return super.getLength();
      
    // Tell if this is being called from within a predicate.
    boolean isPredicateTest = (this == m_execContext.getSubContextList());

    // And get how many total predicates are part of this step.
    int predCount = getPredicateCount();
   
    // If we have already calculated the length, and the current predicate 
    // is the first predicate, then return the length.  We don't cache 
    // the anything but the length of the list to the first predicate.
    if (-1 != m_length && isPredicateTest && m_predicateIndex < 1)
       return m_length;      

    int count = 0;
    
    XPathContext xctxt = getXPathContext();
    try
    {
      OneStepIterator clone = (OneStepIterator) this.cloneWithReset();
      
      int root = getRoot();
      xctxt.pushCurrentNode(root);
      clone.setRoot(root, xctxt);
 
      clone.m_predCount = m_predicateIndex;

      int next;

      while (DTM.NULL != (next = clone.nextNode()))
      {
        count++;
      }
    }
    catch (CloneNotSupportedException cnse)
    {
       // can't happen
    }
    finally
    {
      xctxt.popCurrentNode();
    }
    if (isPredicateTest && m_predicateIndex < 1)
      m_length = count;    
      
    return count;
  
protected intgetNextNode()
Get the next node via getFirstAttribute && getNextAttribute.

    return m_lastFetched = m_iterator.next();
  
protected intgetProximityPosition(int predicateIndex)
Get the current sub-context position. In order to do the reverse axes count, for the moment this re-searches the axes up to the predicate. An optimization on this is to cache the nodes searched, but, for the moment, this case is probably rare enough that the added complexity isn't worth it.

param
predicateIndex The predicate index of the proximity position.
return
The pridicate index, or -1.

    if(!isReverseAxes())
      return super.getProximityPosition(predicateIndex);
      
    // A negative predicate index seems to occur with
    // (preceding-sibling::*|following-sibling::*)/ancestor::*[position()]/*[position()]
    // -sb
    if(predicateIndex < 0)
      return -1;
      
    if (m_proximityPositions[predicateIndex] <= 0)
    {
      XPathContext xctxt = getXPathContext();
      try
      {
        OneStepIterator clone = (OneStepIterator) this.clone();
        
        int root = getRoot();
        xctxt.pushCurrentNode(root);
        clone.setRoot(root, xctxt);

        // clone.setPredicateCount(predicateIndex);
        clone.m_predCount = predicateIndex;

        // Count 'em all
        int count = 1;
        int next;

        while (DTM.NULL != (next = clone.nextNode()))
        {
          count++;
        }

        m_proximityPositions[predicateIndex] += count;
      }
      catch (CloneNotSupportedException cnse)
      {

        // can't happen
      }
      finally
      {
        xctxt.popCurrentNode();
      }
    }

    return m_proximityPositions[predicateIndex];
  
public booleanisReverseAxes()
Tells if this is a reverse axes. Overrides AxesWalker#isReverseAxes.

return
true for this class.

    return m_iterator.isReverse();
  
public voidreset()
Reset the iterator.


    super.reset();
    if(null != m_iterator)
      m_iterator.reset();
  
public voidsetRoot(int context, java.lang.Object environment)
Initialize the context values for this expression after it is cloned.

param
execContext The XPath runtime context for this transformation.

    super.setRoot(context, environment);
    if(m_axis > -1)
      m_iterator = m_cdtm.getAxisIterator(m_axis);
    m_iterator.setStartNode(m_context);