FileDocCategorySizeDatePackage
MatchPatternIterator.javaAPI DocJava SE 6 API9553Tue Jun 10 00:23:14 BST 2008com.sun.org.apache.xpath.internal.axes

MatchPatternIterator

public class MatchPatternIterator extends LocPathIterator
This class treats a LocationPath as a filtered iteration over the tree, evaluating each node in a super axis traversal against the LocationPath interpreted as a match pattern. This class is useful to find nodes in document order that are complex paths whose steps probably criss-cross each other.

Fields Summary
static final long
serialVersionUID
protected StepPattern
m_pattern
This is the select pattern, translated into a match pattern.
protected int
m_superAxis
The traversal axis from where the nodes will be filtered.
protected DTMAxisTraverser
m_traverser
The DTM inner traversal class, that corresponds to the super axis.
private static final boolean
DEBUG
DEBUG flag for diagnostic dumps.
Constructors Summary
MatchPatternIterator(Compiler compiler, int opPos, int analysis)
Create a LocPathIterator object, including creation of step walkers from the opcode list, and call back into the Compiler to create predicate expressions.

param
compiler The Compiler which is creating this expression.
param
opPos The position of this iterator in the opcode list from the compiler.
param
analysis Analysis bits that give general information about the LocationPath.
throws
javax.xml.transform.TransformerException

  
//  protected int m_nsElemBase = DTM.NULL;

                                                                 
       
           
  

    super(compiler, opPos, analysis, false);

    int firstStepPos = compiler.getFirstChildPos(opPos);

    m_pattern = WalkerFactory.loadSteps(this, compiler, firstStepPos, 0); 

    boolean fromRoot = false;
    boolean walkBack = false;
    boolean walkDescendants = false;
    boolean walkAttributes = false;

    if (0 != (analysis & (WalkerFactory.BIT_ROOT | 
                          WalkerFactory.BIT_ANY_DESCENDANT_FROM_ROOT)))
      fromRoot = true;
      
    if (0 != (analysis
              & (WalkerFactory.BIT_ANCESTOR
                 | WalkerFactory.BIT_ANCESTOR_OR_SELF
                 | WalkerFactory.BIT_PRECEDING
                 | WalkerFactory.BIT_PRECEDING_SIBLING 
                 | WalkerFactory.BIT_FOLLOWING
                 | WalkerFactory.BIT_FOLLOWING_SIBLING
                 | WalkerFactory.BIT_PARENT | WalkerFactory.BIT_FILTER)))
      walkBack = true;

    if (0 != (analysis
              & (WalkerFactory.BIT_DESCENDANT_OR_SELF
                 | WalkerFactory.BIT_DESCENDANT
                 | WalkerFactory.BIT_CHILD)))
      walkDescendants = true;

    if (0 != (analysis
              & (WalkerFactory.BIT_ATTRIBUTE | WalkerFactory.BIT_NAMESPACE)))
      walkAttributes = true;
      
    if(false || DEBUG)
    {
      System.out.print("analysis: "+Integer.toBinaryString(analysis));
      System.out.println(", "+WalkerFactory.getAnalysisString(analysis));
    }
      
    if(fromRoot || walkBack)
    {
      if(walkAttributes)
      {
        m_superAxis = Axis.ALL;
      }
      else
      {
        m_superAxis = Axis.DESCENDANTSFROMROOT;
      }
    }
    else if(walkDescendants)
    {
      if(walkAttributes)
      {
        m_superAxis = Axis.ALLFROMNODE;
      }
      else
      {
        m_superAxis = Axis.DESCENDANTORSELF;
      }
    }
    else
    {
      m_superAxis = Axis.ALL;
    }
    if(false || DEBUG)
    {
      System.out.println("axis: "+Axis.getNames(m_superAxis));
    }
    
  
Methods Summary
public shortacceptNode(int n, com.sun.org.apache.xpath.internal.XPathContext xctxt)
Test whether a specified node is visible in the logical view of a TreeWalker or NodeIterator. This function will be called by the implementation of TreeWalker and NodeIterator; it is not intended to be called directly from user code.

param
n The node to check to see if it passes the filter or not.
return
a constant to determine whether the node is accepted, rejected, or skipped, as defined above .


    try
    {
      xctxt.pushCurrentNode(n);
      xctxt.pushIteratorRoot(m_context);
      if(DEBUG)
      {
        System.out.println("traverser: "+m_traverser);
        System.out.print("node: "+n);
        System.out.println(", "+m_cdtm.getNodeName(n));
        // if(m_cdtm.getNodeName(n).equals("near-east"))
        System.out.println("pattern: "+m_pattern.toString());
        m_pattern.debugWhatToShow(m_pattern.getWhatToShow());
      }
      
      XObject score = m_pattern.execute(xctxt);
      
      if(DEBUG)
      {
        // System.out.println("analysis: "+Integer.toBinaryString(m_analysis));
        System.out.println("score: "+score);
        System.out.println("skip: "+(score == NodeTest.SCORE_NONE));
      }

      // System.out.println("\n::acceptNode - score: "+score.num()+"::");
      return (score == NodeTest.SCORE_NONE) ? DTMIterator.FILTER_SKIP 
                    : DTMIterator.FILTER_ACCEPT;
    }
    catch (javax.xml.transform.TransformerException se)
    {

      // TODO: Fix this.
      throw new RuntimeException(se.getMessage());
    }
    finally
    {
      xctxt.popCurrentNode();
      xctxt.popIteratorRoot();
    }

  
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)
    {
      m_traverser = null;
      
      // Always call the superclass detach last!
      super.detach();
    }
  
protected intgetNextNode()
Get the next node via getNextXXX. Bottlenecked for derived class override.

return
The next node on the axis, or DTM.NULL.

    m_lastFetched = (DTM.NULL == m_lastFetched)
                     ? m_traverser.first(m_context)
                     : m_traverser.next(m_context, m_lastFetched);
    return m_lastFetched;
  
public intnextNode()
Returns the next node in the set and advances the position of the iterator in the set. After a NodeIterator is created, the first call to nextNode() returns the first node in the set.

return
The next Node in the set being iterated over, or null if there are no more members in that set.

      
  	if(m_foundLast)
  		return DTM.NULL;

    int next;
    
    com.sun.org.apache.xpath.internal.VariableStack vars;
    int savedStart;
    if (-1 != m_stackFrame)
    {
      vars = m_execContext.getVarStack();

      // These three statements need to be combined into one operation.
      savedStart = vars.getStackFrame();

      vars.setStackFrame(m_stackFrame);
    }
    else
    {
      // Yuck.  Just to shut up the compiler!
      vars = null;
      savedStart = 0;
    }
    
    try
    {
      if(DEBUG)
        System.out.println("m_pattern"+m_pattern.toString());

      do
      {
        next = getNextNode();
  
        if (DTM.NULL != next)
        {
          if(DTMIterator.FILTER_ACCEPT == acceptNode(next, m_execContext))
            break;
          else
            continue;
        }
        else
          break;
      }
      while (next != DTM.NULL);
      
      if (DTM.NULL != next)
      {
        if(DEBUG)
        {
          System.out.println("next: "+next);
          System.out.println("name: "+m_cdtm.getNodeName(next));
        }
        incrementCurrentPos();
  
        return next;
      }
      else
      {
        m_foundLast = true;
  
        return DTM.NULL;
      }
    }
    finally
    {
      if (-1 != m_stackFrame)
      {
        // These two statements need to be combined into one operation.
        vars.setStackFrame(savedStart);
      }
    }

  
public voidsetRoot(int context, java.lang.Object environment)
Initialize the context values for this expression after it is cloned.

param
context The XPath runtime context for this transformation.

    super.setRoot(context, environment);
    m_traverser = m_cdtm.getAxisTraverser(m_superAxis);