UnionPathIteratorpublic class UnionPathIterator extends LocPathIterator implements PathComponent, Cloneable, DTMIterator, SerializableThis class extends NodeSetDTM, which implements DTMIterator,
and fetches nodes one at a time in document order based on a XPath
UnionExpr.
As each node is iterated via nextNode(), the node is also stored
in the NodeVector, so that previousNode() can easily be done. |
Fields Summary |
---|
static final long | serialVersionUID | protected LocPathIterator[] | m_exprsThe location path iterators, one for each
location
path contained in the union expression. | protected DTMIterator[] | m_iteratorsThe location path iterators, one for each
location
path contained in the union expression. |
Constructors Summary |
---|
public UnionPathIterator()Constructor to create an instance which you can add location paths to.
super();
// m_mutable = false;
// m_cacheNodes = false;
m_iterators = null;
m_exprs = null;
| public UnionPathIterator(Compiler compiler, int opPos)Create a UnionPathIterator object, including creation
of location path iterators from the opcode list, and call back
into the Compiler to create predicate expressions.
super();
opPos = compiler.getFirstChildPos(opPos);
loadLocationPaths(compiler, opPos, 0);
|
Methods Summary |
---|
public void | addIterator(com.sun.org.apache.xml.internal.dtm.DTMIterator expr)Add an iterator to the union list.
// Increase array size by only 1 at a time. Fix this
// if it looks to be a problem.
if (null == m_iterators)
{
m_iterators = new DTMIterator[1];
m_iterators[0] = expr;
}
else
{
DTMIterator[] exprs = m_iterators;
int len = m_iterators.length;
m_iterators = new DTMIterator[len + 1];
System.arraycopy(exprs, 0, m_iterators, 0, len);
m_iterators[len] = expr;
}
expr.nextNode();
if(expr instanceof Expression)
((Expression)expr).exprSetParent(this);
| public void | callVisitors(com.sun.org.apache.xpath.internal.ExpressionOwner owner, com.sun.org.apache.xpath.internal.XPathVisitor visitor)
if(visitor.visitUnionPath(owner, this))
{
if(null != m_exprs)
{
int n = m_exprs.length;
for(int i = 0; i < n; i++)
{
m_exprs[i].callVisitors(new iterOwner(i), visitor);
}
}
}
| public java.lang.Object | clone()Get a cloned LocPathIterator that holds the same
position as this iterator.
UnionPathIterator clone = (UnionPathIterator) super.clone();
if (m_iterators != null)
{
int n = m_iterators.length;
clone.m_iterators = new DTMIterator[n];
for (int i = 0; i < n; i++)
{
clone.m_iterators[i] = (DTMIterator)m_iterators[i].clone();
}
}
return clone;
| protected com.sun.org.apache.xpath.internal.axes.LocPathIterator | createDTMIterator(com.sun.org.apache.xpath.internal.compiler.Compiler compiler, int opPos)Create a new location path iterator.
LocPathIterator lpi = (LocPathIterator)WalkerFactory.newDTMIterator(compiler, opPos,
(compiler.getLocationPathDepth() <= 0));
return lpi;
| public static com.sun.org.apache.xpath.internal.axes.LocPathIterator | createUnionIterator(com.sun.org.apache.xpath.internal.compiler.Compiler compiler, int opPos)This will return an iterator capable of handling the union of paths given.
// For the moment, I'm going to first create a full UnionPathIterator, and
// then see if I can reduce it to a UnionChildIterator. It would obviously
// be more effecient to just test for the conditions for a UnionChildIterator,
// and then create that directly.
UnionPathIterator upi = new UnionPathIterator(compiler, opPos);
int nPaths = upi.m_exprs.length;
boolean isAllChildIterators = true;
for(int i = 0; i < nPaths; i++)
{
LocPathIterator lpi = upi.m_exprs[i];
if(lpi.getAxis() != Axis.CHILD)
{
isAllChildIterators = false;
break;
}
else
{
// check for positional predicates or position function, which won't work.
if(HasPositionalPredChecker.check(lpi))
{
isAllChildIterators = false;
break;
}
}
}
if(isAllChildIterators)
{
UnionChildIterator uci = new UnionChildIterator();
for(int i = 0; i < nPaths; i++)
{
PredicatedNodeTest lpi = upi.m_exprs[i];
// I could strip the lpi down to a pure PredicatedNodeTest, but
// I don't think it's worth it. Note that the test can be used
// as a static object... so it doesn't have to be cloned.
uci.addNodeTest(lpi);
}
return uci;
}
else
return upi;
| public boolean | deepEquals(com.sun.org.apache.xpath.internal.Expression expr)
if (!super.deepEquals(expr))
return false;
UnionPathIterator upi = (UnionPathIterator) expr;
if (null != m_exprs)
{
int n = m_exprs.length;
if((null == upi.m_exprs) || (upi.m_exprs.length != n))
return false;
for (int i = 0; i < n; i++)
{
if(!m_exprs[i].deepEquals(upi.m_exprs[i]))
return false;
}
}
else if (null != upi.m_exprs)
{
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 && null != m_iterators){
int n = m_iterators.length;
for(int i = 0; i < n; i++)
{
m_iterators[i].detach();
}
m_iterators = null;
}
| public void | fixupVariables(java.util.Vector vars, int globalsSize)This function is used to fixup variables from QNames to stack frame
indexes at stylesheet build time.
for (int i = 0; i < m_exprs.length; i++)
{
m_exprs[i].fixupVariables(vars, globalsSize);
}
| public int | getAnalysisBits()Get the analysis bits for this walker, as defined in the WalkerFactory.
int bits = 0;
if (m_exprs != null)
{
int n = m_exprs.length;
for (int i = 0; i < n; i++)
{
int bit = m_exprs[i].getAnalysisBits();
bits |= bit;
}
}
return bits;
| public int | getAxis()Returns the axis being iterated, if it is known.
// Could be smarter.
return -1;
| protected void | loadLocationPaths(com.sun.org.apache.xpath.internal.compiler.Compiler compiler, int opPos, int count)Initialize the location path iterators. Recursive.
// TODO: Handle unwrapped FilterExpr
int steptype = compiler.getOp(opPos);
if (steptype == OpCodes.OP_LOCATIONPATH)
{
loadLocationPaths(compiler, compiler.getNextOpPos(opPos), count + 1);
m_exprs[count] = createDTMIterator(compiler, opPos);
m_exprs[count].exprSetParent(this);
}
else
{
// Have to check for unwrapped functions, which the LocPathIterator
// doesn't handle.
switch (steptype)
{
case OpCodes.OP_VARIABLE :
case OpCodes.OP_EXTFUNCTION :
case OpCodes.OP_FUNCTION :
case OpCodes.OP_GROUP :
loadLocationPaths(compiler, compiler.getNextOpPos(opPos), count + 1);
WalkingIterator iter =
new WalkingIterator(compiler.getNamespaceContext());
iter.exprSetParent(this);
if(compiler.getLocationPathDepth() <= 0)
iter.setIsTopLevel(true);
iter.m_firstWalker = new com.sun.org.apache.xpath.internal.axes.FilterExprWalker(iter);
iter.m_firstWalker.init(compiler, opPos, steptype);
m_exprs[count] = iter;
break;
default :
m_exprs = new LocPathIterator[count];
}
}
| public int | nextNode()Returns the next node in the set and advances the position of the
iterator in the set. After a DTMIterator is created, the first call
to nextNode() returns the first node in the set.
if(m_foundLast)
return DTM.NULL;
// Loop through the iterators getting the current fetched
// node, and get the earliest occuring in document order
int earliestNode = DTM.NULL;
if (null != m_iterators)
{
int n = m_iterators.length;
int iteratorUsed = -1;
for (int i = 0; i < n; i++)
{
int node = m_iterators[i].getCurrentNode();
if (DTM.NULL == node)
continue;
else if (DTM.NULL == earliestNode)
{
iteratorUsed = i;
earliestNode = node;
}
else
{
if (node == earliestNode)
{
// Found a duplicate, so skip past it.
m_iterators[i].nextNode();
}
else
{
DTM dtm = getDTM(node);
if (dtm.isNodeAfter(node, earliestNode))
{
iteratorUsed = i;
earliestNode = node;
}
}
}
}
if (DTM.NULL != earliestNode)
{
m_iterators[iteratorUsed].nextNode();
incrementCurrentPos();
}
else
m_foundLast = true;
}
m_lastFetched = earliestNode;
return earliestNode;
| private void | readObject(java.io.ObjectInputStream stream)Read the object from a serialization stream.
try
{
stream.defaultReadObject();
m_clones = new IteratorPool(this);
}
catch (ClassNotFoundException cnfe)
{
throw new javax.xml.transform.TransformerException(cnfe);
}
| public void | setRoot(int context, java.lang.Object environment)Initialize the context values for this expression
after it is cloned.
super.setRoot(context, environment);
try
{
if (null != m_exprs)
{
int n = m_exprs.length;
DTMIterator newIters[] = new DTMIterator[n];
for (int i = 0; i < n; i++)
{
DTMIterator iter = m_exprs[i].asIterator(m_execContext, context);
newIters[i] = iter;
iter.nextNode();
}
m_iterators = newIters;
}
}
catch(Exception e)
{
throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(e);
}
|
|