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

PredicatedNodeTest

public abstract class PredicatedNodeTest extends NodeTest implements SubContextList

Fields Summary
static final long
serialVersionUID
protected int
m_predCount
protected transient boolean
m_foundLast
This is true if nextNode returns null.
protected LocPathIterator
m_lpi
The owning location path iterator.
transient int
m_predicateIndex
Which predicate we are executing.
private Expression[]
m_predicates
The list of predicate expressions. Is static and does not need to be deep cloned.
protected transient int[]
m_proximityPositions
An array of counts that correspond to the number of predicates the step contains.
static final boolean
DEBUG_PREDICATECOUNTING
If true, diagnostic messages about predicate execution will be posted.
Constructors Summary
PredicatedNodeTest(LocPathIterator locPathIterator)
Construct an AxesWalker using a LocPathIterator.

param
locPathIterator non-null reference to the parent iterator.


                   
   
  
    m_lpi = locPathIterator;
  
PredicatedNodeTest()
Construct an AxesWalker. The location path iterator will have to be set before use.

  
Methods Summary
public shortacceptNode(int n)
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 .


    XPathContext xctxt = m_lpi.getXPathContext();

    try
    {
      xctxt.pushCurrentNode(n);

      XObject score = execute(xctxt, n);

      // System.out.println("\n::acceptNode - score: "+score.num()+"::");
      if (score != NodeTest.SCORE_NONE)
      {
        if (getPredicateCount() > 0)
        {
          countProximityPosition(0);

          if (!executePredicates(n, xctxt))
            return DTMIterator.FILTER_SKIP;
        }

        return DTMIterator.FILTER_ACCEPT;
      }
    }
    catch (javax.xml.transform.TransformerException se)
    {

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

    return DTMIterator.FILTER_SKIP;
  
public voidcallPredicateVisitors(com.sun.org.apache.xpath.internal.XPathVisitor visitor)
This will traverse the heararchy, calling the visitor for each member. If the called visitor method returns false, the subtree should not be called.

param
visitor The visitor whose appropriate method will be called.

	  if (null != m_predicates)
	    {
	    int n = m_predicates.length;
	    for (int i = 0; i < n; i++)
	      {
	      ExpressionOwner predOwner = new PredOwner(i);
	      if (visitor.visitPredicate(predOwner, m_predicates[i]))
	        {
	        m_predicates[i].callVisitors(predOwner, visitor);
	      }
	
	    }
	  }
	
public booleancanTraverseOutsideSubtree()
Tell if this expression or it's subexpressions can traverse outside the current subtree.

return
true if traversal outside the context node's subtree can occur.

    int n = getPredicateCount();
    for (int i = 0; i < n; i++) 
    {
      if(getPredicate(i).canTraverseOutsideSubtree())
        return true;
    }
    return false;
   
public java.lang.Objectclone()
Get a cloned PrdicatedNodeTest.

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

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

    if ((null != this.m_proximityPositions)
            && (this.m_proximityPositions == clone.m_proximityPositions))
    {
      clone.m_proximityPositions = new int[this.m_proximityPositions.length];

      System.arraycopy(this.m_proximityPositions, 0,
                       clone.m_proximityPositions, 0,
                       this.m_proximityPositions.length);
    }
    
    if(clone.m_lpi == this)
      clone.m_lpi = (LocPathIterator)clone;

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

param
i The index into the m_proximityPositions array, where the increment will occur.

  	// Note that in the case of a UnionChildIterator, this may be a 
  	// static object and so m_proximityPositions may indeed be null!
  	int[] pp = m_proximityPositions;
    if ((null != pp) && (i < pp.length))
      pp[i]++;
  
public booleandeepEquals(com.sun.org.apache.xpath.internal.Expression expr)

see
Expression#deepEquals(Expression)

      if (!super.deepEquals(expr))
            return false;

      PredicatedNodeTest pnt = (PredicatedNodeTest) expr;
      if (null != m_predicates)
      {

        int n = m_predicates.length;
        if ((null == pnt.m_predicates) || (pnt.m_predicates.length != n))
              return false;
        for (int i = 0; i < n; i++)
        {
          if (!m_predicates[i].deepEquals(pnt.m_predicates[i]))
          	return false; 
        }
      }
      else if (null != pnt.m_predicates)
              return false; 
              
      return true; 
    
booleanexecutePredicates(int context, com.sun.org.apache.xpath.internal.XPathContext xctxt)
Process the predicates.

param
context The current context node.
param
xctxt The XPath runtime context.
return
the result of executing the predicate expressions.
throws
javax.xml.transform.TransformerException

    
    int nPredicates = getPredicateCount();
    // System.out.println("nPredicates: "+nPredicates);
    if (nPredicates == 0)
      return true;

    PrefixResolver savedResolver = xctxt.getNamespaceContext();

    try
    {
      m_predicateIndex = 0;
      xctxt.pushSubContextList(this);
      xctxt.pushNamespaceContext(m_lpi.getPrefixResolver());
      xctxt.pushCurrentNode(context);

      for (int i = 0; i < nPredicates; i++)
      {
        // System.out.println("Executing predicate expression - waiting count: "+m_lpi.getWaitingCount());
        XObject pred = m_predicates[i].execute(xctxt);
        // System.out.println("\nBack from executing predicate expression - waiting count: "+m_lpi.getWaitingCount());
        // System.out.println("pred.getType(): "+pred.getType());
        if (XObject.CLASS_NUMBER == pred.getType())
        {
          if (DEBUG_PREDICATECOUNTING)
          {
            System.out.flush();
            System.out.println("\n===== start predicate count ========");
            System.out.println("m_predicateIndex: " + m_predicateIndex);
            // System.out.println("getProximityPosition(m_predicateIndex): "
            //                   + getProximityPosition(m_predicateIndex));
            System.out.println("pred.num(): " + pred.num());
          }

          int proxPos = this.getProximityPosition(m_predicateIndex);
          int predIndex = (int) pred.num();
          if (proxPos != predIndex)
          {
            if (DEBUG_PREDICATECOUNTING)
            {
              System.out.println("\nnode context: "+nodeToString(context));
              System.out.println("index predicate is false: "+proxPos);
              System.out.println("\n===== end predicate count ========");
            }
            return false;
          }
          else if (DEBUG_PREDICATECOUNTING)
          {
            System.out.println("\nnode context: "+nodeToString(context));
            System.out.println("index predicate is true: "+proxPos);
            System.out.println("\n===== end predicate count ========");
          }
          
          // If there is a proximity index that will not change during the 
          // course of itteration, then we know there can be no more true 
          // occurances of this predicate, so flag that we're done after 
          // this.
          //
          // bugzilla 14365
          // We can't set m_foundLast = true unless we're sure that -all-
          // remaining parameters are stable, or else last() fails. Fixed so
          // only sets m_foundLast if on the last predicate
          if(m_predicates[i].isStableNumber() && i == nPredicates - 1)
          {
            m_foundLast = true;
          }
        }
        else if (!pred.bool())
          return false;

        countProximityPosition(++m_predicateIndex);
      }
    }
    finally
    {
      xctxt.popCurrentNode();
      xctxt.popNamespaceContext();
      xctxt.popSubContextList();
      m_predicateIndex = -1;
    }

    return true;
  
public voidfixupVariables(java.util.Vector vars, int globalsSize)
This function is used to fixup variables from QNames to stack frame indexes at stylesheet build time.

param
vars List of QNames that correspond to variables. This list should be searched backwards for the first qualified name that corresponds to the variable reference qname. The position of the QName in the vector from the start of the vector will be its position in the stack frame (but variables above the globalsTop value will need to be offset to the current stack frame).

    super.fixupVariables(vars, globalsSize);

    int nPredicates = getPredicateCount();

    for (int i = 0; i < nPredicates; i++)
    {
      m_predicates[i].fixupVariables(vars, globalsSize);
    }
  
public abstract intgetLastPos(com.sun.org.apache.xpath.internal.XPathContext xctxt)
Get the index of the last node that can be itterated to.

param
xctxt XPath runtime context.
return
the index of the last node that can be itterated to.

public com.sun.org.apache.xpath.internal.axes.LocPathIteratorgetLocPathIterator()
Get the owning location path iterator.

return
the owning location path iterator, which should not be null.

    return m_lpi;
  
public com.sun.org.apache.xpath.internal.ExpressiongetPredicate(int index)
Get a predicate expression at the given index.

param
index Index of the predicate.
return
A predicate expression.

    return m_predicates[index];
  
public intgetPredicateCount()
Get the number of predicates that this walker has.

return
the number of predicates that this walker has.


                       
    
  
    if(-1 == m_predCount)
      return (null == m_predicates) ? 0 : m_predicates.length;
    else
      return m_predCount;
  
public intgetPredicateIndex()
Get which predicate is executing.

return
The current predicate index, or -1 if no predicate is executing.

    return m_predicateIndex;
  
public intgetProximityPosition(com.sun.org.apache.xpath.internal.XPathContext xctxt)
Get the current sub-context position.

param
xctxt The XPath runtime context.
return
The node position of this walker in the sub-context node list.

    return getProximityPosition();
  
protected intgetProximityPosition(int predicateIndex)
Get the current sub-context position.

param
predicateIndex The index of the predicate where the proximity should be taken from.
return
The node position of this walker in the sub-context node list.

    return (predicateIndex >= 0) ? m_proximityPositions[predicateIndex] : 0;
  
public intgetProximityPosition()
Get the current sub-context position.

return
The node position of this walker in the sub-context node list.


    // System.out.println("getProximityPosition - m_predicateIndex: "+m_predicateIndex);
    return getProximityPosition(m_predicateIndex);
  
protected voidinitPredicateInfo(com.sun.org.apache.xpath.internal.compiler.Compiler compiler, int opPos)
Init predicate info.

param
compiler The Compiler object that has information about this walker in the op map.
param
opPos The op code position of this location step.
throws
javax.xml.transform.TransformerException


    int pos = compiler.getFirstPredicateOpPos(opPos);

    if(pos > 0)
    {
      m_predicates = compiler.getCompiledPredicates(pos);
      if(null != m_predicates)
      {
      	for(int i = 0; i < m_predicates.length; i++)
      	{
      		m_predicates[i].exprSetParent(this);
      	}
      }
    }
  
public voidinitProximityPosition(int i)
Init the proximity position to zero for a forward axes.

param
i The index into the m_proximityPositions array.
throws
javax.xml.transform.TransformerException

    m_proximityPositions[i] = 0;
  
public booleanisReverseAxes()
Tells if this is a reverse axes.

return
false, unless a derived class overrides.

    return false;
  
protected java.lang.StringnodeToString(int n)
Diagnostics.

param
n Node to give diagnostic information about, or null.
return
Informative string about the argument.

    if(DTM.NULL != n)
    {
      DTM dtm = m_lpi.getXPathContext().getDTM(n);
      return dtm.getNodeName(n) + "{" + (n+1) + "}";
    }
    else
    {
      return "null";
    }
  
private voidreadObject(java.io.ObjectInputStream stream)
Read the object from a serialization stream.

param
stream Input stream to read from
throws
java.io.IOException
throws
javax.xml.transform.TransformerException

    try
    {
      stream.defaultReadObject();
      m_predicateIndex = -1;
      resetProximityPositions();
    }
    catch (ClassNotFoundException cnfe)
    {
      throw new javax.xml.transform.TransformerException(cnfe);
    }
  
public voidresetProximityPositions()
Reset the proximity positions counts.

    int nPredicates = getPredicateCount();
    if (nPredicates > 0)
    {
      if (null == m_proximityPositions)
        m_proximityPositions = new int[nPredicates];

      for (int i = 0; i < nPredicates; i++)
      {
        try
        {
          initProximityPosition(i);
        }
        catch(Exception e)
        {
          // TODO: Fix this...
          throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(e);
        }
      }
    }
  
public voidsetLocPathIterator(com.sun.org.apache.xpath.internal.axes.LocPathIterator li)
Set the location path iterator owner for this walker. Besides initialization, this function is called during cloning operations.

param
li non-null reference to the owning location path iterator.

    m_lpi = li;
    if(this != li)
      li.exprSetParent(this);
  
public voidsetPredicateCount(int count)
Set the number of predicates that this walker has. This does more that one would think, as it creates a new predicate array of the size of the count argument, and copies count predicates into the new one from the old, and then reassigns the predicates value. All this to keep from having to have a predicate count value.

param
count The number of predicates, which must be equal or less than the existing count.

    if(count > 0)
    {
      Expression[] newPredicates = new Expression[count];
      for (int i = 0; i < count; i++) 
      {
        newPredicates[i] = m_predicates[i];
      }
      m_predicates = newPredicates;
    }
    else
      m_predicates = null;