You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sb...@locus.apache.org on 2000/12/27 23:24:18 UTC
cvs commit: xml-xalan/java/src/org/apache/xpath/axes RootWalkerMultiStep.java AttributeIterator.java AxesWalker.java ChildIterator.java ChildTestIterator.java DescendantIterator.java FilterExprWalker.java LocPathIterator.java PredicatedNodeTest.java ReverseAxesWalker.java RootWalker.java WalkerFactory.java
sboag 00/12/27 14:24:18
Modified: java/src/org/apache/xpath/axes AttributeIterator.java
AxesWalker.java ChildIterator.java
ChildTestIterator.java DescendantIterator.java
FilterExprWalker.java LocPathIterator.java
PredicatedNodeTest.java ReverseAxesWalker.java
RootWalker.java WalkerFactory.java
Added: java/src/org/apache/xpath/axes RootWalkerMultiStep.java
Log:
Optimize for "/foo/baz" patterns. Add canTraverseOutsideSubtree support.
Revision Changes Path
1.5 +2 -2 xml-xalan/java/src/org/apache/xpath/axes/AttributeIterator.java
Index: AttributeIterator.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/AttributeIterator.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- AttributeIterator.java 2000/12/21 22:32:49 1.4
+++ AttributeIterator.java 2000/12/27 22:24:11 1.5
@@ -87,11 +87,11 @@
*
* @throws javax.xml.transform.TransformerException
*/
- public AttributeIterator(Compiler compiler, int opPos)
+ public AttributeIterator(Compiler compiler, int opPos, int analysis)
throws javax.xml.transform.TransformerException
{
- super(compiler, opPos, false);
+ super(compiler, opPos, analysis, false);
int firstStepPos = compiler.getFirstChildPos(opPos);
int whatToShow = compiler.getWhatToShow(firstStepPos);
1.17 +88 -99 xml-xalan/java/src/org/apache/xpath/axes/AxesWalker.java
Index: AxesWalker.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/AxesWalker.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- AxesWalker.java 2000/12/18 08:48:20 1.16
+++ AxesWalker.java 2000/12/27 22:24:11 1.17
@@ -87,36 +87,7 @@
public abstract class AxesWalker extends PredicatedNodeTest
implements Cloneable, TreeWalker, NodeFilter
{
-
- // These are useful to enable if you want to turn diagnostics messages
- // on or off temporarily from another module.
- // public static boolean DEBUG = true;
- // public static boolean DEBUG_WAITING = true;
- // public static boolean DEBUG_TRAVERSAL = true;
- // public static boolean DEBUG_LOCATED = true;
- // public static boolean DEBUG_PREDICATECOUNTING = false;
- /** General static debug flag. Setting this to false will suppress some
- * of the output messages caused by the other debug categories. */
- static final boolean DEBUG = false;
-
- /** If true, diagnostic messages about the waiting queue will be posted. */
- static final boolean DEBUG_WAITING = false;
-
- /** For diagnostic purposes, tells if we already did a subtree dump. */
- static boolean m_didDumpAll = false;
-
- /** If true, diagnostic messages about the tree traversal will be posted. */
- static final boolean DEBUG_TRAVERSAL = false;
-
- /** If true, diagnostic messages about the nodes that have
- * been 'located' will be posted. */
- static final boolean DEBUG_LOCATED = false;
-
- /** String passed to {@link org.w3c.dom.Node#isSupported} to see if it implements
- * a {@link org.apache.xpath.patterns.NodeTestFilter} interface. */
- public static final String FEATURE_NODETESTFILTER = "NodeTestFilter";
-
/**
* Construct an AxesWalker using a LocPathIterator.
*
@@ -254,9 +225,19 @@
}
/**
- * The step type of the XPath step. Does not change after the constructor.
+ * 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.
*/
- private int m_stepType;
+ public boolean canTraverseOutsideSubtree()
+ {
+ if(super.canTraverseOutsideSubtree())
+ return true;
+ if(null != m_nextWalker)
+ return m_nextWalker.canTraverseOutsideSubtree();
+ return false;
+ }
/**
* The the step type op code.
@@ -271,12 +252,6 @@
}
/**
- * The arg length of the XPath step. Does not change after the constructor.
- * TODO: Can this be removed since it is only valuable at compile time?
- */
- private int m_argLen;
-
- /**
* Get the argument length of the location step in the opcode map.
* TODO: Can this be removed since it is only valuable at compile time?
*
@@ -288,36 +263,6 @@
}
/**
- * The analysis pattern built by the WalkerFactory.
- * TODO: Move to LocPathIterator.
- * @see org.apache.xpath.axes.WalkerFactory
- */
- protected int m_analysis = 0x00000000;
-
- /**
- * Get the analysis pattern built by the WalkerFactory.
- * TODO: Move to LocPathIterator.
- *
- * @return The analysis pattern built by the WalkerFactory.
- */
- int getAnalysis()
- {
- return m_analysis;
- }
-
- /**
- * Set the analysis pattern built by the WalkerFactory.
- * TODO: Move to LocPathIterator.
- *
- * @param a The analysis pattern built by the WalkerFactory.
- */
- void setAnalysis(int a)
- {
- m_analysis = a;
- }
-
-
- /**
* Tell if the given node is a parent of the
* step context, or the step context node itself.
*
@@ -343,11 +288,6 @@
//=============== TreeWalker Implementation ===============
/**
- * The root node of the TreeWalker, as specified when it was created.
- */
- transient Node m_root;
-
- /**
* The root node of the TreeWalker, as specified in setRoot(Node root).
* Note that this may actually be below the current node.
*
@@ -358,9 +298,6 @@
return m_root;
}
- /** True if an itteration has not begun. */
- boolean m_isFresh;
-
/**
* Set the root node of the TreeWalker.
* (Not part of the DOM2 TreeWalker interface).
@@ -386,11 +323,6 @@
}
/**
- * The node at which the TreeWalker is currently positioned.
- */
- transient Node m_currentNode;
-
- /**
* The node at which the TreeWalker is currently positioned.
* <br> The value must not be null. Alterations to the DOM tree may cause
* the current node to no longer be accepted by the TreeWalker's
@@ -550,9 +482,6 @@
throw new RuntimeException("previousNode not supported!");
}
- /** The next walker in the location step chain. */
- protected AxesWalker m_nextWalker;
-
/**
* Set the next walker in the location step chain.
*
@@ -575,9 +504,6 @@
return m_nextWalker;
}
- /** The previous walker in the location step chain, or null. */
- AxesWalker m_prevWalker;
-
/**
* Set or clear the previous walker reference in the location step chain.
*
@@ -843,10 +769,6 @@
return 0;
}
- /** An estimation of the next level that this walker will traverse to. Not
- * always accurate. */
- protected int m_nextLevelAmount;
-
/**
* Tell what's the next level this axes can descend to.
*
@@ -932,9 +854,6 @@
return ok;
}
- /** Fairly short lived flag to tell if we switched to a waiting walker. */
- private boolean m_didSwitch = false;
-
/**
* Check if any walkers need to fire before the given walker. If they
* do, then the given walker will be put on the waiting list, and the
@@ -1116,9 +1035,6 @@
return walker;
}
- /** True if this walker has found it's last node. */
- boolean m_isDone = false;
-
/**
* Get the next node in document order on the axes.
*
@@ -1156,9 +1072,6 @@
return next;
}
- /** The node last returned from nextNode(). */
- transient Node m_prevReturned;
-
/**
* Moves the <code>TreeWalker</code> to the next visible node in document
* order relative to the current node, and returns the new node. If the
@@ -1400,4 +1313,80 @@
return false;
}
+ //============= Static Data =============
+
+ // These are useful to enable if you want to turn diagnostics messages
+ // on or off temporarily from another module.
+ // public static boolean DEBUG = true;
+ // public static boolean DEBUG_WAITING = true;
+ // public static boolean DEBUG_TRAVERSAL = true;
+ // public static boolean DEBUG_LOCATED = true;
+ // public static boolean DEBUG_PREDICATECOUNTING = false;
+
+ /** General static debug flag. Setting this to false will suppress some
+ * of the output messages caused by the other debug categories. */
+ static final boolean DEBUG = false;
+
+ /** If true, diagnostic messages about the waiting queue will be posted. */
+ static final boolean DEBUG_WAITING = false;
+
+ /** For diagnostic purposes, tells if we already did a subtree dump. */
+ static boolean m_didDumpAll = false;
+
+ /** If true, diagnostic messages about the tree traversal will be posted. */
+ static final boolean DEBUG_TRAVERSAL = false;
+
+ /** If true, diagnostic messages about the nodes that have
+ * been 'located' will be posted. */
+ static final boolean DEBUG_LOCATED = false;
+
+ /** String passed to {@link org.w3c.dom.Node#isSupported} to see if it implements
+ * a {@link org.apache.xpath.patterns.NodeTestFilter} interface. */
+ public static final String FEATURE_NODETESTFILTER = "NodeTestFilter";
+
+ //============= State Data =============
+
+ /**
+ * The root node of the TreeWalker, as specified when it was created.
+ */
+ transient Node m_root;
+
+ /**
+ * The node at which the TreeWalker is currently positioned.
+ */
+ transient Node m_currentNode;
+
+ /** The node last returned from nextNode(). */
+ transient Node m_prevReturned;
+
+ /**
+ * The arg length of the XPath step. Does not change after the constructor.
+ * TODO: Can this be removed since it is only valuable at compile time?
+ */
+ private int m_argLen;
+
+ /**
+ * The step type of the XPath step. Does not change after the constructor.
+ */
+ private int m_stepType;
+
+ /** Fairly short lived flag to tell if we switched to a waiting walker. */
+ private boolean m_didSwitch = false;
+
+ /** True if this walker has found it's last node. */
+ boolean m_isDone = false;
+
+ /** True if an itteration has not begun. */
+ boolean m_isFresh;
+
+ /** An estimation of the next level that this walker will traverse to. Not
+ * always accurate. */
+ protected int m_nextLevelAmount;
+
+ /** The next walker in the location step chain. */
+ protected AxesWalker m_nextWalker;
+
+ /** The previous walker in the location step chain, or null. */
+ AxesWalker m_prevWalker;
+
}
1.4 +2 -2 xml-xalan/java/src/org/apache/xpath/axes/ChildIterator.java
Index: ChildIterator.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/ChildIterator.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ChildIterator.java 2000/12/21 22:32:51 1.3
+++ ChildIterator.java 2000/12/27 22:24:11 1.4
@@ -82,10 +82,10 @@
*
* @throws javax.xml.transform.TransformerException
*/
- public ChildIterator(Compiler compiler, int opPos)
+ public ChildIterator(Compiler compiler, int opPos, int analysis)
throws javax.xml.transform.TransformerException
{
- super(compiler, opPos, false);
+ super(compiler, opPos, analysis, false);
}
/**
1.6 +2 -2 xml-xalan/java/src/org/apache/xpath/axes/ChildTestIterator.java
Index: ChildTestIterator.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/ChildTestIterator.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ChildTestIterator.java 2000/12/21 22:32:51 1.5
+++ ChildTestIterator.java 2000/12/27 22:24:11 1.6
@@ -85,11 +85,11 @@
*
* @throws javax.xml.transform.TransformerException
*/
- public ChildTestIterator(Compiler compiler, int opPos)
+ public ChildTestIterator(Compiler compiler, int opPos, int analysis)
throws javax.xml.transform.TransformerException
{
- super(compiler, opPos, false);
+ super(compiler, opPos, analysis, false);
int firstStepPos = compiler.getFirstChildPos(opPos);
int whatToShow = compiler.getWhatToShow(firstStepPos);
1.5 +7 -2 xml-xalan/java/src/org/apache/xpath/axes/DescendantIterator.java
Index: DescendantIterator.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/DescendantIterator.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DescendantIterator.java 2000/12/21 22:32:51 1.4
+++ DescendantIterator.java 2000/12/27 22:24:11 1.5
@@ -87,11 +87,11 @@
*
* @throws javax.xml.transform.TransformerException
*/
- public DescendantIterator(Compiler compiler, int opPos)
+ public DescendantIterator(Compiler compiler, int opPos, int analysis)
throws javax.xml.transform.TransformerException
{
- super(compiler, opPos, false);
+ super(compiler, opPos, analysis, false);
int ops[] = compiler.getOpMap();
int firstStepPos = compiler.getFirstChildPos(opPos);
@@ -99,6 +99,11 @@
if (OpCodes.FROM_DESCENDANTS_OR_SELF == stepType)
m_orSelf = true;
+ if (OpCodes.FROM_SELF == stepType)
+ {
+ m_orSelf = true;
+ firstStepPos += 8;
+ }
else if(OpCodes.FROM_ROOT == stepType)
{
m_fromRoot = true;
1.12 +1 -1 xml-xalan/java/src/org/apache/xpath/axes/FilterExprWalker.java
Index: FilterExprWalker.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/FilterExprWalker.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- FilterExprWalker.java 2000/12/17 06:18:19 1.11
+++ FilterExprWalker.java 2000/12/27 22:24:11 1.12
@@ -209,7 +209,7 @@
try
{
- if (m_predicateCount > 0)
+ if (getPredicateCount() > 0)
{
countProximityPosition(0);
1.22 +151 -99 xml-xalan/java/src/org/apache/xpath/axes/LocPathIterator.java
Index: LocPathIterator.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/LocPathIterator.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- LocPathIterator.java 2000/12/18 08:48:20 1.21
+++ LocPathIterator.java 2000/12/27 22:24:11 1.22
@@ -105,76 +105,7 @@
java.io.Serializable
{
- /* The pool for cloned iterators. Iterators need to be cloned
- * because the hold running state, and thus the original iterator
- * expression from the stylesheet pool can not be used. */
-
- // ObjectPool m_pool = new ObjectPool(this.getClass());
-
- /** The last node that was fetched, usually by nextNode. */
- transient public Node m_lastFetched;
-
/**
- * If this iterator needs to cache nodes that are fetched, they
- * are stored here.
- */
- transient NodeSet m_cachedNodes;
-
- /** The last used step walker in the walker list. */
- protected AxesWalker m_lastUsedWalker;
-
- /** The head of the step walker list. */
- protected AxesWalker m_firstWalker;
-
- /** This is true if nextNode returns null. */
- protected boolean m_foundLast = false;
-
- /**
- * Quicker access to the DOM helper than going through the
- * XPathContext object.
- */
- transient protected DOMHelper m_dhelper;
-
- /**
- * The context node for this iterator, which doesn't change through
- * the course of the iteration.
- */
- transient protected Node m_context;
-
- /**
- * The node context from where the expression is being
- * executed from (i.e. for current() support). Different
- * from m_context in that this is the context for the entire
- * expression, rather than the context for the subexpression.
- */
- transient protected Node m_currentContextNode;
-
- /**
- * Fast access to the current prefix resolver. It isn't really
- * clear that this is needed.
- */
- protected PrefixResolver m_prefixResolver;
-
- /**
- * The XPathContext reference, needed for execution of many
- * operations.
- */
- transient protected XPathContext m_execContext;
-
- /**
- * The index of the next node to be fetched. Useful if this
- * is a cached iterator, and is being used as random access
- * NodeList.
- */
- protected int m_next = 0;
-
- /**
- * The list of "waiting" step walkers.
- * @see org.apache.xpath.axes.AxesWalker
- */
- private Vector m_waiting = null;
-
- /**
* Get the waiting walker at the given index.
*
*
@@ -203,34 +134,7 @@
return m_waiting.size() - m_waitingBottom;
}
- /** The starting point in m_waiting where the waiting step walkers are. */
- int m_waitingBottom = 0;
-
- /**
- * An index to the point in the variable stack where we should
- * begin variable searches for this iterator.
- * This is -1 if m_isTopLevel is false.
- */
- int m_varStackPos = -1;
-
/**
- * An index into the variable stack where the variable context
- * ends, i.e. at the point we should terminate the search and
- * go looking for global variables.
- */
- int m_varStackContext;
-
- /**
- * Value determined at compile time, indicates that this is an
- * iterator at the top level of the expression, rather than inside
- * a predicate.
- */
- private boolean m_isTopLevel = false;
-
- /** The index of the last node in the iteration. */
- private int m_last = 0;
-
- /**
* Create a LocPathIterator object.
*
* @param nscontext The namespace context for this iterator,
@@ -256,10 +160,10 @@
*
* @throws javax.xml.transform.TransformerException
*/
- public LocPathIterator(Compiler compiler, int opPos)
+ public LocPathIterator(Compiler compiler, int opPos, int analysis)
throws javax.xml.transform.TransformerException
{
- this(compiler, opPos, true);
+ this(compiler, opPos, analysis, true);
}
/**
@@ -278,9 +182,10 @@
* @throws javax.xml.transform.TransformerException
*/
public LocPathIterator(
- Compiler compiler, int opPos, boolean shouldLoadWalkers)
+ Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers)
throws javax.xml.transform.TransformerException
{
+ m_analysis = analysis;
setLocPathIterator(this);
@@ -1044,4 +949,151 @@
// System.out.println("pos: "+pos);
return pos;
}
+
+ /**
+ * Get the analysis pattern built by the WalkerFactory.
+ *
+ * @return The analysis pattern built by the WalkerFactory.
+ */
+ int getAnalysis()
+ {
+ return m_analysis;
+ }
+
+ /**
+ * Set the analysis pattern built by the WalkerFactory.
+ *
+ * @param a The analysis pattern built by the WalkerFactory.
+ */
+ void setAnalysis(int a)
+ {
+ m_analysis = a;
+ }
+
+ /**
+ * 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.
+ */
+ public boolean canTraverseOutsideSubtree()
+ {
+ if((m_analysis & WalkerFactory.BITMASK_TRAVERSES_OUTSIDE_SUBTREE) != 0)
+ {
+ return true;
+ }
+ // We have to ask subwalkers about their predicates.
+ if(null != m_firstWalker)
+ {
+ if(m_firstWalker.canTraverseOutsideSubtree())
+ return true;
+ }
+ return super.canTraverseOutsideSubtree();
+ }
+
+
+ //============= State Data =============
+
+ /** The starting point in m_waiting where the waiting step walkers are. */
+ int m_waitingBottom = 0;
+
+ /**
+ * An index to the point in the variable stack where we should
+ * begin variable searches for this iterator.
+ * This is -1 if m_isTopLevel is false.
+ */
+ int m_varStackPos = -1;
+
+ /**
+ * An index into the variable stack where the variable context
+ * ends, i.e. at the point we should terminate the search and
+ * go looking for global variables.
+ */
+ int m_varStackContext;
+
+ /**
+ * Value determined at compile time, indicates that this is an
+ * iterator at the top level of the expression, rather than inside
+ * a predicate.
+ */
+ private boolean m_isTopLevel = false;
+
+ /** The index of the last node in the iteration. */
+ private int m_last = 0;
+
+ /* The pool for cloned iterators. Iterators need to be cloned
+ * because the hold running state, and thus the original iterator
+ * expression from the stylesheet pool can not be used. */
+
+ // ObjectPool m_pool = new ObjectPool(this.getClass());
+
+ /** The last node that was fetched, usually by nextNode. */
+ transient public Node m_lastFetched;
+
+ /**
+ * If this iterator needs to cache nodes that are fetched, they
+ * are stored here.
+ */
+ transient NodeSet m_cachedNodes;
+
+ /** The last used step walker in the walker list. */
+ protected AxesWalker m_lastUsedWalker;
+
+ /** The head of the step walker list. */
+ protected AxesWalker m_firstWalker;
+
+ /** This is true if nextNode returns null. */
+ protected boolean m_foundLast = false;
+
+ /**
+ * Quicker access to the DOM helper than going through the
+ * XPathContext object.
+ */
+ transient protected DOMHelper m_dhelper;
+
+ /**
+ * The context node for this iterator, which doesn't change through
+ * the course of the iteration.
+ */
+ transient protected Node m_context;
+
+ /**
+ * The node context from where the expression is being
+ * executed from (i.e. for current() support). Different
+ * from m_context in that this is the context for the entire
+ * expression, rather than the context for the subexpression.
+ */
+ transient protected Node m_currentContextNode;
+
+ /**
+ * Fast access to the current prefix resolver. It isn't really
+ * clear that this is needed.
+ */
+ protected PrefixResolver m_prefixResolver;
+
+ /**
+ * The XPathContext reference, needed for execution of many
+ * operations.
+ */
+ transient protected XPathContext m_execContext;
+
+ /**
+ * The index of the next node to be fetched. Useful if this
+ * is a cached iterator, and is being used as random access
+ * NodeList.
+ */
+ protected int m_next = 0;
+
+ /**
+ * The list of "waiting" step walkers.
+ * @see org.apache.xpath.axes.AxesWalker
+ */
+ private Vector m_waiting = null;
+
+ /**
+ * The analysis pattern built by the WalkerFactory.
+ * TODO: Move to LocPathIterator.
+ * @see org.apache.xpath.axes.WalkerFactory
+ */
+ protected int m_analysis = 0x00000000;
}
1.2 +42 -15 xml-xalan/java/src/org/apache/xpath/axes/PredicatedNodeTest.java
Index: PredicatedNodeTest.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/PredicatedNodeTest.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- PredicatedNodeTest.java 2000/12/18 08:48:20 1.1
+++ PredicatedNodeTest.java 2000/12/27 22:24:11 1.2
@@ -70,17 +70,33 @@
*/
public int getPredicateCount()
{
- return m_predicateCount;
+ return (null == m_predicates) ? 0 : m_predicates.length;
}
/**
- * Set the number of predicates that this walker has.
+ * 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.
+ * @param count The number of predicates, which must be equal or less
+ * than the existing count.
*/
public void setPredicateCount(int count)
{
- m_predicateCount = 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;
+
}
/**
@@ -99,7 +115,6 @@
int pos = compiler.getFirstPredicateOpPos(opPos);
m_predicates = compiler.getCompiledPredicates(pos);
- m_predicateCount = (null == m_predicates) ? 0 : m_predicates.length;
}
/**
@@ -169,13 +184,13 @@
*/
public void resetProximityPositions()
{
-
- if (m_predicateCount > 0)
+ int nPredicates = getPredicateCount();
+ if (nPredicates > 0)
{
if (null == m_proximityPositions)
- m_proximityPositions = new int[m_predicateCount];
+ m_proximityPositions = new int[nPredicates];
- for (int i = 0; i < m_predicateCount; i++)
+ for (int i = 0; i < nPredicates; i++)
{
try
{
@@ -250,7 +265,7 @@
m_predicateIndex = 0;
- int nPredicates = m_predicateCount;
+ int nPredicates = getPredicateCount();
// System.out.println("nPredicates: "+nPredicates);
if (nPredicates == 0)
return true;
@@ -377,7 +392,7 @@
// System.out.println("\n::acceptNode - score: "+score.num()+"::");
if (score != NodeTest.SCORE_NONE)
{
- if (m_predicateCount > 0)
+ if (getPredicateCount() > 0)
{
countProximityPosition(0);
@@ -425,10 +440,22 @@
}
/**
- * Number of predicates (in effect).
- */
- protected int m_predicateCount;
-
+ * 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.
+ */
+ public boolean canTraverseOutsideSubtree()
+ {
+ int n = getPredicateCount();
+ for (int i = 0; i < n; i++)
+ {
+ if(getPredicate(i).canTraverseOutsideSubtree())
+ return true;
+ }
+ return false;
+ }
+
/** The owning location path iterator. */
protected LocPathIterator m_lpi;
1.6 +2 -2 xml-xalan/java/src/org/apache/xpath/axes/ReverseAxesWalker.java
Index: ReverseAxesWalker.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/ReverseAxesWalker.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ReverseAxesWalker.java 2000/12/17 17:40:01 1.5
+++ ReverseAxesWalker.java 2000/12/27 22:24:11 1.6
@@ -135,7 +135,7 @@
clone.setRoot(this.getRoot());
- clone.m_predicateCount = predicateIndex;
+ clone.setPredicateCount(predicateIndex);
clone.setPrevWalker(null);
clone.setNextWalker(null);
@@ -198,7 +198,7 @@
clone.setRoot(this.getRoot());
- clone.m_predicateCount = this.m_predicateCount - 1;
+ clone.setPredicateCount(this.getPredicateCount() - 1);
clone.setPrevWalker(null);
clone.setNextWalker(null);
1.5 +6 -11 xml-xalan/java/src/org/apache/xpath/axes/RootWalker.java
Index: RootWalker.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/RootWalker.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- RootWalker.java 2000/12/17 17:40:01 1.4
+++ RootWalker.java 2000/12/27 22:24:11 1.5
@@ -85,20 +85,15 @@
}
/**
- * Get a cloned RootWalker.
+ * Set the root node of the TreeWalker.
*
- * @return a new RootWalker ready to be used.
- *
- * @throws CloneNotSupportedException
+ * @param root The context node of this step.
*/
- public Object clone() throws CloneNotSupportedException
- {
-
- RootWalker clone = (RootWalker) super.clone();
-
- clone.m_processedRoot = false;
+ public void setRoot(Node root)
+ {
- return clone;
+ super.setRoot(root);
+ m_processedRoot = false;
}
/**
1.11 +130 -31 xml-xalan/java/src/org/apache/xpath/axes/WalkerFactory.java
Index: WalkerFactory.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/axes/WalkerFactory.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- WalkerFactory.java 2000/12/18 08:48:20 1.10
+++ WalkerFactory.java 2000/12/27 22:24:11 1.11
@@ -140,7 +140,7 @@
walker = createDefaultWalker(compiler, stepOpCodePos, lpi, analysis);
walker.init(compiler, stepOpCodePos, stepType);
- walker.setAnalysis(analysis);
+ // walker.setAnalysis(analysis);
if (null == firstWalker)
{
@@ -183,39 +183,43 @@
int analysis = analyze(compiler, firstStepPos, 0);
- if (DEBUG_ITERATOR_CREATION)
- System.out.println("analysis -- newLocPathIterator: "
- + Integer.toBinaryString(analysis) + ", "
- + compiler.toString());
-
-// // Can't have optimized iterators at this time that have predicates.
-// if (BIT_PREDICATE == (analysis & BIT_PREDICATE))
-// return new LocPathIterator(compiler, opPos, true);
-
+ // Is the iteration exactly one child step?
if ((BIT_CHILD | 0x00000001) == (analysis & (BIT_CHILD | BITS_COUNT)))
{
+ // Does the pattern specify *any* child with no predicate? (i.e. select="child::node()".
if (BIT_CHILD == (analysis & BIT_NODETEST_ANY) && !(BIT_PREDICATE == (analysis & BIT_PREDICATE)))
{
if (DEBUG_ITERATOR_CREATION)
- System.out.println("ChildIterator!");
+ System.out.println("new iterator: ChildIterator: "
+ + Integer.toBinaryString(analysis) + ", "
+ + compiler.toString());
- return new ChildIterator(compiler, opPos);
+ // Use simple child iteration without any test.
+ return new ChildIterator(compiler, opPos, analysis);
}
else
{
if (DEBUG_ITERATOR_CREATION)
- System.out.println("ChildTestIterator!");
+ System.out.println("new iterator: ChildTestIterator: "
+ + Integer.toBinaryString(analysis) + ", "
+ + compiler.toString());
- return new ChildTestIterator(compiler, opPos);
+ // Else use simple node test iteration with predicate test.
+ return new ChildTestIterator(compiler, opPos, analysis);
}
}
+ // Is the iteration a one-step attribute pattern (i.e. select="@foo")?
else if ((BIT_ATTRIBUTE | 0x00000001)
== (analysis & (BIT_ATTRIBUTE | BITS_COUNT)))
{
if (DEBUG_ITERATOR_CREATION)
- System.out.println("AttributeIterator!");
-
- return new AttributeIterator(compiler, opPos);
+ System.out.println("new iterator: AttributeIterator: "
+ + Integer.toBinaryString(analysis) + ", "
+ + compiler.toString());
+
+ // Then use a simple iteration of the attributes, with node test
+ // and predicate testing.
+ return new AttributeIterator(compiler, opPos, analysis);
}
// Analysis of "//center":
// bits: 1001000000001010000000000000011
@@ -229,21 +233,36 @@
== (analysis
& (BIT_DESCENDANT | BIT_DESCENDANT_OR_SELF | BITS_COUNT))) ||
((BIT_DESCENDANT_OR_SELF | BIT_SELF | 0x00000002)
+ == (analysis
+ & (BIT_DESCENDANT_OR_SELF | BIT_SELF | BITS_COUNT)))
+
+ /* ".//center" -- 1000010000001010000000000000011 */
+ || ((BIT_DESCENDANT_OR_SELF | BIT_SELF | BIT_CHILD | BIT_NODETEST_ANY | 0x00000003)
== (analysis
- & (BIT_DESCENDANT_OR_SELF | BIT_SELF | BITS_COUNT))) ||
- ((BIT_DESCENDANT_OR_SELF | BIT_ROOT | BIT_CHILD | BIT_NODETEST_ANY | BIT_ANY_DESCENDANT_FROM_ROOT | 0x00000003)
+ & (BIT_DESCENDANT_OR_SELF | BIT_SELF | BIT_CHILD | BIT_NODETEST_ANY | BITS_COUNT)))
+
+ /* "//center" -- 1001000000001010000000000000011 */
+ || ((BIT_DESCENDANT_OR_SELF | BIT_ROOT | BIT_CHILD | BIT_NODETEST_ANY |
+ BIT_ANY_DESCENDANT_FROM_ROOT | 0x00000003)
== (analysis
- & (BIT_DESCENDANT_OR_SELF | BIT_ROOT | BIT_CHILD | BIT_NODETEST_ANY | BIT_ANY_DESCENDANT_FROM_ROOT | BITS_COUNT)))
+ & (BIT_DESCENDANT_OR_SELF | BIT_ROOT | BIT_CHILD |
+ BIT_NODETEST_ANY | BIT_ANY_DESCENDANT_FROM_ROOT | BITS_COUNT)))
)
{
if (DEBUG_ITERATOR_CREATION)
- System.out.println("DescendantIterator!");
+ System.out.println("new iterator: DescendantIterator: "
+ + Integer.toBinaryString(analysis) + ", "
+ + compiler.toString());
- return new DescendantIterator(compiler, opPos);
+ return new DescendantIterator(compiler, opPos, analysis);
}
else
{
- return new LocPathIterator(compiler, opPos, true);
+ if (DEBUG_ITERATOR_CREATION)
+ System.out.println("new iterator: LocPathIterator: "
+ + Integer.toBinaryString(analysis) + ", "
+ + compiler.toString());
+ return new LocPathIterator(compiler, opPos, analysis, true);
}
}
@@ -448,25 +467,49 @@
case OpCodes.OP_FUNCTION :
case OpCodes.OP_GROUP :
prevIsOneStepDown = false;
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: FilterExprWalker: " + analysis
+ + ", " + compiler.toString());
ai = new FilterExprWalker(lpi);
simpleInit = true;
break;
case OpCodes.FROM_ROOT :
- ai = new RootWalker(lpi);
+ if (0 == (analysis & ~(BIT_ROOT | BIT_CHILD | BIT_ATTRIBUTE |
+ BIT_NAMESPACE | BIT_PREDICATE | BITS_COUNT)))
+ {
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: RootWalkerMultiStep: " + analysis
+ + ", " + compiler.toString());
+
+ ai = new RootWalkerMultiStep(lpi);
+ }
+ else
+ {
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: RootWalker: " + analysis
+ + ", " + compiler.toString());
+ ai = new RootWalker(lpi);
+ }
break;
case OpCodes.FROM_ANCESTORS :
prevIsOneStepDown = false;
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: AncestorWalker: " + analysis
+ + ", " + compiler.toString());
ai = new AncestorWalker(lpi);
break;
case OpCodes.FROM_ANCESTORS_OR_SELF :
prevIsOneStepDown = false;
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: AncestorOrSelfWalker: " + analysis
+ + ", " + compiler.toString());
ai = new AncestorOrSelfWalker(lpi);
break;
case OpCodes.FROM_ATTRIBUTES :
if (1 == totalNumberWalkers)
{
if (DEBUG_WALKER_CREATION)
- System.out.println("analysis -- AttributeWalkerOneStep: " + analysis
+ System.out.println("new walker: AttributeWalkerOneStep: " + analysis
+ ", " + compiler.toString());
// TODO: We should be able to do this as long as this is
@@ -476,89 +519,130 @@
else
{
if (DEBUG_WALKER_CREATION)
- System.out.println("analysis -- AttributeWalker: " + analysis
+ System.out.println("new walker: AttributeWalker: " + analysis
+ ", " + compiler.toString());
ai = new AttributeWalker(lpi);
}
break;
case OpCodes.FROM_NAMESPACE :
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: NamespaceWalker: " + analysis
+ + ", " + compiler.toString());
ai = new NamespaceWalker(lpi);
break;
case OpCodes.FROM_CHILDREN :
if (1 == totalNumberWalkers)
{
+ // I don't think this will ever happen any more. -sb
if (DEBUG_WALKER_CREATION)
- System.out.println("analysis -- onestep child: " + analysis + ", "
+ System.out.println("new walker: ChildWalkerOneStep: " + analysis + ", "
+ compiler.toString());
ai = new ChildWalkerOneStep(lpi);
}
else
{
- if (0 == (analysis & ~(BIT_CHILD | BIT_ATTRIBUTE | BIT_NAMESPACE | BIT_PREDICATE | BITS_COUNT)))
+ if (0 == (analysis & ~(BIT_ROOT | BIT_CHILD | BIT_ATTRIBUTE |
+ BIT_NAMESPACE | BIT_PREDICATE | BITS_COUNT)))
{
if (DEBUG_WALKER_CREATION)
- System.out.println("analysis -- multi-step child: " + analysis
+ System.out.println("new walker: ChildWalkerMultiStep: " + analysis
+ ", " + compiler.toString());
ai = new ChildWalkerMultiStep(lpi);
}
else
{
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: ChildWalker: " + analysis
+ + ", " + compiler.toString());
ai = new ChildWalker(lpi);
}
}
break;
case OpCodes.FROM_DESCENDANTS :
prevIsOneStepDown = false;
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: DescendantWalker: " + analysis
+ + ", " + compiler.toString());
ai = new DescendantWalker(lpi);
break;
case OpCodes.FROM_DESCENDANTS_OR_SELF :
prevIsOneStepDown = false;
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: DescendantOrSelfWalker: " + analysis
+ + ", " + compiler.toString());
ai = new DescendantOrSelfWalker(lpi);
break;
case OpCodes.FROM_FOLLOWING :
prevIsOneStepDown = false;
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: FollowingWalker: " + analysis
+ + ", " + compiler.toString());
ai = new FollowingWalker(lpi);
break;
case OpCodes.FROM_FOLLOWING_SIBLINGS :
prevIsOneStepDown = false;
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: FollowingSiblingWalker: " + analysis
+ + ", " + compiler.toString());
ai = new FollowingSiblingWalker(lpi);
break;
case OpCodes.FROM_PRECEDING :
prevIsOneStepDown = false;
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: PrecedingWalker: " + analysis
+ + ", " + compiler.toString());
ai = new PrecedingWalker(lpi);
break;
case OpCodes.FROM_PRECEDING_SIBLINGS :
prevIsOneStepDown = false;
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: PrecedingSiblingWalker: " + analysis
+ + ", " + compiler.toString());
ai = new PrecedingSiblingWalker(lpi);
break;
case OpCodes.FROM_PARENT :
prevIsOneStepDown = false;
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: ParentWalker: " + analysis
+ + ", " + compiler.toString());
ai = new ParentWalker(lpi);
break;
case OpCodes.FROM_SELF :
if (1 == totalNumberWalkers)
{
if (DEBUG_WALKER_CREATION)
- System.out.println("analysis -- SelfWalkerOneStep: " + analysis
+ System.out.println("new walker: SelfWalkerOneStep: " + analysis
+ ", " + compiler.toString());
ai = new SelfWalkerOneStep(lpi);
}
else
{
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: SelfWalker: " + analysis
+ + ", " + compiler.toString());
ai = new SelfWalker(lpi);
}
break;
case OpCodes.MATCH_ATTRIBUTE :
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: AttributeWalker(MATCH_ATTRIBUTE): " + analysis
+ + ", " + compiler.toString());
ai = new AttributeWalker(lpi);
break;
case OpCodes.MATCH_ANY_ANCESTOR :
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: ChildWalker(MATCH_ANY_ANCESTOR): " + analysis
+ + ", " + compiler.toString());
ai = new ChildWalker(lpi);
break;
case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
+ if (DEBUG_WALKER_CREATION)
+ System.out.println("new walker: ChildWalker(MATCH_IMMEDIATE_ANCESTOR): " + analysis
+ + ", " + compiler.toString());
ai = new ChildWalker(lpi);
break;
default :
@@ -660,6 +744,20 @@
/** Bit is on if any of the walkers contain a root step. */
public static final int BIT_ROOT = (0x00001000 << 15);
+
+ /** If any of these bits are on, the expression may likely traverse outside
+ * the given subtree. */
+ public static final int BITMASK_TRAVERSES_OUTSIDE_SUBTREE
+ = (BIT_NAMESPACE // ??
+ | BIT_PRECEDING_SIBLING
+ | BIT_PRECEDING
+ | BIT_FOLLOWING_SIBLING
+ | BIT_FOLLOWING
+ | BIT_PARENT // except parent of attrs.
+ | BIT_ANCESTOR_OR_SELF
+ | BIT_ANCESTOR
+ | BIT_FILTER
+ | BIT_ROOT);
/**
* Bit is on if any of the walkers can go backwards in document
@@ -675,9 +773,10 @@
* really only useful if the count is 1.
*/
public static final int BIT_NODETEST_ANY = (0x00001000 << 18);
+
+ // can't go higher than 18!
/** Bit is on if the expression is a match pattern. */
public static final int BIT_MATCH_PATTERN = (0x00001000 << 19);
- // can't go higher than 19!
}
1.1 xml-xalan/java/src/org/apache/xpath/axes/RootWalkerMultiStep.java
Index: RootWalkerMultiStep.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xpath.axes;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeFilter;
import org.apache.xpath.patterns.NodeTestFilter;
/**
* This class extends ChildWalkerMultiStep to handle the root step of
* patterns such as "/foo/baz" where the first step is the root, and the
* rest of the steps are simple child steps.
*/
public class RootWalkerMultiStep extends ChildWalkerMultiStep
{
/**
* Construct an ChildWalkerMultiStep using a LocPathIterator.
*
* @param locPathIterator
*/
public RootWalkerMultiStep(LocPathIterator locPathIterator)
{
super(locPathIterator);
}
/**
* Set the root node of the TreeWalker.
*
* @param root The context node of this step.
*/
public void setRoot(Node root)
{
super.setRoot(root);
m_processedRoot = false;
}
/**
* Get the next node in document order on the axes.
*
* @return the next valid child node.
*/
protected Node getNextNode()
{
if (m_isFresh)
m_isFresh = false;
Node current = this.getCurrentNode();
if (current.isSupported(FEATURE_NODETESTFILTER, "1.0"))
((NodeTestFilter) current).setNodeTest(this);
Node next;
if (!m_processedRoot)
{
m_processedRoot = true;
next = m_lpi.getDOMHelper().getRootNode(m_currentNode);
}
else
next = null;
if (null != next)
{
m_currentNode = next;
// doesn't seem like we need to do this!
if (acceptNode(next) != NodeFilter.FILTER_ACCEPT)
{
next = null;
}
if (null == next)
m_currentNode = current; // don't advance the current node.
}
if (null == next)
this.m_isDone = true;
return next;
}
/** True if the root node has been processed. */
boolean m_processedRoot = false;
}