DescendantIteratorpublic class DescendantIterator extends LocPathIterator This class implements an optimized iterator for
descendant, descendant-or-self, or "//foo" patterns. |
Fields Summary |
---|
protected transient DTMAxisTraverser | m_traverserThe traverser to use to navigate over the descendants. | protected int | m_axisThe axis that we are traversing. | protected int | m_extendedTypeIDThe extended type ID, not set until setRoot. |
Constructors Summary |
---|
DescendantIterator(Compiler compiler, int opPos, int analysis)Create a DescendantIterator object.
super(compiler, opPos, analysis, false);
int firstStepPos = compiler.getFirstChildPos(opPos);
int stepType = compiler.getOp(firstStepPos);
boolean orSelf = (OpCodes.FROM_DESCENDANTS_OR_SELF == stepType);
boolean fromRoot = false;
if (OpCodes.FROM_SELF == stepType)
{
orSelf = true;
// firstStepPos += 8;
}
else if(OpCodes.FROM_ROOT == stepType)
{
fromRoot = true;
// Ugly code... will go away when AST work is done.
int nextStepPos = compiler.getNextStepPos(firstStepPos);
if(compiler.getOp(nextStepPos) == OpCodes.FROM_DESCENDANTS_OR_SELF)
orSelf = true;
// firstStepPos += 8;
}
// Find the position of the last step.
int nextStepPos = firstStepPos;
while(true)
{
nextStepPos = compiler.getNextStepPos(nextStepPos);
if(nextStepPos > 0)
{
int stepOp = compiler.getOp(nextStepPos);
if(OpCodes.ENDOP != stepOp)
firstStepPos = nextStepPos;
else
break;
}
else
break;
}
// Fix for http://nagoya.apache.org/bugzilla/show_bug.cgi?id=1336
if((analysis & WalkerFactory.BIT_CHILD) != 0)
orSelf = false;
if(fromRoot)
{
if(orSelf)
m_axis = Axis.DESCENDANTSORSELFFROMROOT;
else
m_axis = Axis.DESCENDANTSFROMROOT;
}
else if(orSelf)
m_axis = Axis.DESCENDANTORSELF;
else
m_axis = Axis.DESCENDANT;
int whatToShow = compiler.getWhatToShow(firstStepPos);
if ((0 == (whatToShow
& (DTMFilter.SHOW_ATTRIBUTE | DTMFilter.SHOW_ELEMENT
| DTMFilter.SHOW_PROCESSING_INSTRUCTION))) ||
(whatToShow == DTMFilter.SHOW_ALL))
initNodeTest(whatToShow);
else
{
initNodeTest(whatToShow, compiler.getStepNS(firstStepPos),
compiler.getStepLocalName(firstStepPos));
}
initPredicateInfo(compiler, firstStepPos);
| public DescendantIterator()Create a DescendantIterator object.
super(null);
m_axis = Axis.DESCENDANTSORSELFFROMROOT;
int whatToShow = DTMFilter.SHOW_ALL;
initNodeTest(whatToShow);
|
Methods Summary |
---|
public int | asNode(com.sun.org.apache.xpath.internal.XPathContext xctxt)Return the first node out of the nodeset, if this expression is
a nodeset expression. This is the default implementation for
nodesets.
WARNING: Do not mutate this class from this function!
if(getPredicateCount() > 0)
return super.asNode(xctxt);
int current = xctxt.getCurrentNode();
DTM dtm = xctxt.getDTM(current);
DTMAxisTraverser traverser = dtm.getAxisTraverser(m_axis);
String localName = getLocalName();
String namespace = getNamespace();
int what = m_whatToShow;
// System.out.print(" (DescendantIterator) ");
// System.out.println("what: ");
// NodeTest.debugWhatToShow(what);
if(DTMFilter.SHOW_ALL == what
|| localName == NodeTest.WILD
|| namespace == NodeTest.WILD)
{
return traverser.first(current);
}
else
{
int type = getNodeTypeTest(what);
int extendedType = dtm.getExpandedTypeID(namespace, localName, type);
return traverser.first(current, extendedType);
}
| public com.sun.org.apache.xml.internal.dtm.DTMIterator | cloneWithReset()Get a cloned Iterator that is reset to the beginning
of the query.
DescendantIterator clone = (DescendantIterator) super.cloneWithReset();
clone.m_traverser = m_traverser;
clone.resetProximityPositions();
return clone;
| public boolean | deepEquals(com.sun.org.apache.xpath.internal.Expression expr)
if(!super.deepEquals(expr))
return false;
if(m_axis != ((DescendantIterator)expr).m_axis)
return false;
return true;
| public void | detach()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;
m_extendedTypeID = 0;
// Always call the superclass detach last!
super.detach();
}
| public int | getAxis()Returns the axis being iterated, if it is known.
return m_axis;
| public int | nextNode()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.
if(m_foundLast)
return DTM.NULL;
if(DTM.NULL == m_lastFetched)
{
resetProximityPositions();
}
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
{
do
{
if(0 == m_extendedTypeID)
{
next = m_lastFetched = (DTM.NULL == m_lastFetched)
? m_traverser.first(m_context)
: m_traverser.next(m_context, m_lastFetched);
}
else
{
next = m_lastFetched = (DTM.NULL == m_lastFetched)
? m_traverser.first(m_context, m_extendedTypeID)
: m_traverser.next(m_context, m_lastFetched,
m_extendedTypeID);
}
if (DTM.NULL != next)
{
if(DTMIterator.FILTER_ACCEPT == acceptNode(next))
break;
else
continue;
}
else
break;
}
while (next != DTM.NULL);
if (DTM.NULL != next)
{
m_pos++;
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 void | setRoot(int context, java.lang.Object environment)Initialize the context values for this expression
after it is cloned.
super.setRoot(context, environment);
m_traverser = m_cdtm.getAxisTraverser(m_axis);
String localName = getLocalName();
String namespace = getNamespace();
int what = m_whatToShow;
// System.out.println("what: ");
// NodeTest.debugWhatToShow(what);
if(DTMFilter.SHOW_ALL == what
|| localName == NodeTest.WILD
|| namespace == NodeTest.WILD)
{
m_extendedTypeID = 0;
}
else
{
int type = getNodeTypeTest(what);
m_extendedTypeID = m_cdtm.getExpandedTypeID(namespace, localName, type);
}
|
|