sboag 01/05/21 04:44:06
Modified: java/src/org/apache/xml/dtm Tag: DTM_EXP Axis.java DTM.java
DTMDefaultBase.java DTMDocumentImpl.java
Log:
Introduction of stateless AxisTraversers, for polymorphic axis traversal,
mainly for match patterns/match iterators.
Revision Changes Path
No revision
No revision
1.1.2.2 +46 -22 xml-xalan/java/src/org/apache/xml/dtm/Attic/Axis.java
Index: Axis.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/Axis.java,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- Axis.java 2001/05/20 17:33:26 1.1.2.1
+++ Axis.java 2001/05/21 11:43:59 1.1.2.2
@@ -69,20 +69,20 @@
* The ancestor axis contains the ancestors of the context node;
* the ancestors of the context node consist of the parent of context
* node and the parent's parent and so on; thus, the ancestor axis will
- * always include the root node, unless the context node is the root
node.
+ * always include the root node, unless the context node is the root node.
*/
public static final int ANCESTOR = 0;
/**
* the ancestor-or-self axis contains the context node and the ancestors of
* the context node; thus, the ancestor axis will always include the
- * root node.
+ * root node.
*/
public static final int ANCESTORORSELF = 1;
/**
* the attribute axis contains the attributes of the context node; the axis
- * will be empty unless the context node is an element.
+ * will be empty unless the context node is an element.
*/
public static final int ATTRIBUTE = 2;
@@ -92,64 +92,88 @@
/**
* The descendant axis contains the descendants of the context node;
* a descendant is a child or a child of a child and so on; thus the
- * descendant axis never contains attribute or namespace nodes.
+ * descendant axis never contains attribute or namespace nodes.
*/
public static final int DESCENDANT = 4;
/**
* The descendant-or-self axis contains the context node and the
- * descendants of the context node.
+ * descendants of the context node.
*/
public static final int DESCENDANTORSELF = 5;
/**
* the following axis contains all nodes in the same document as the
* context node that are after the context node in document order,
excluding
- * any descendants and excluding attribute nodes and namespace nodes.
+ * any descendants and excluding attribute nodes and namespace nodes.
*/
public static final int FOLLOWING = 6;
/**
* The following-sibling axis contains all the following siblings of the
* context node; if the context node is an attribute node or namespace
node,
- * the following-sibling axis is empty.
+ * the following-sibling axis is empty.
*/
public static final int FOLLOWINGSIBLING = 7;
/**
* The namespace axis contains the namespace nodes of the context node; the
- * axis will be empty unless the context node is an element.
+ * axis will be empty unless the context node is an element.
*/
- public static final int NAMESPACE = 8;
+ public static final int NAMESPACEDECLS = 8;
/**
+ * The namespace axis contains the namespace nodes of the context node; the
+ * axis will be empty unless the context node is an element.
+ */
+ public static final int NAMESPACE = 9;
+
+ /**
* The parent axis contains the parent of the context node,
- * if there is one.
+ * if there is one.
*/
- public static final int PARENT = 9;
+ public static final int PARENT = 10;
/**
* The preceding axis contains all nodes in the same document as the
context
* node that are before the context node in document order, excluding any
- * ancestors and excluding attribute nodes and namespace nodes
+ * ancestors and excluding attribute nodes and namespace nodes
*/
- public static final int PRECEDING = 10;
+ public static final int PRECEDING = 11;
/**
* The preceding-sibling axis contains all the preceding siblings of the
* context node; if the context node is an attribute node or namespace
node,
- * the preceding-sibling axis is empty.
+ * the preceding-sibling axis is empty.
*/
- public static final int PRECEDINGSIBLING = 11;
+ public static final int PRECEDINGSIBLING = 12;
/** The self axis contains just the context node itself. */
- public static final int SELF = 12;
+ public static final int SELF = 13;
+
+ /**
+ * A non-xpath axis, traversing the subtree including the subtree
+ * root, descendants, attributes, and namespace node decls.
+ */
+ public static final int SUBTREE = 14;
/** The names of the axes for diagnostic purposes. */
- public static final String[] names = { "ancestor", "ancestor-or-self",
- "attribute", "child", "descendant",
- "descendant-or-self", "following",
- "following-sibling", "namespace",
- "parent", "preceding",
- "preceding-sibling", "self" };
+ public static final String[] names =
+ {
+ "ancestor", // 0
+ "ancestor-or-self", // 1
+ "attribute", // 2
+ "child", // 3
+ "descendant", // 4
+ "descendant-or-self", // 5
+ "following", // 6
+ "following-sibling", // 7
+ "namespace-decls", // 8
+ "namespace", // 9
+ "parent", // 10
+ "preceding", // 11
+ "preceding-sibling", // 12
+ "self", // 13
+ "subtree" // 14
+ };
}
1.1.2.18 +12 -2 xml-xalan/java/src/org/apache/xml/dtm/Attic/DTM.java
Index: DTM.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/DTM.java,v
retrieving revision 1.1.2.17
retrieving revision 1.1.2.18
diff -u -r1.1.2.17 -r1.1.2.18
--- DTM.java 2001/05/20 17:33:26 1.1.2.17
+++ DTM.java 2001/05/21 11:44:00 1.1.2.18
@@ -189,8 +189,18 @@
// ========= Document Navigation Functions =========
/**
- * This is a shortcut to the iterators that implement the
- * supported XPath axes (only namespace::) is not supported.
+ * This returns a stateless "traverser", that can navigate over an
+ * XPath axis, though not in document order.
+ *
+ * @param axis One of Axes.ANCESTORORSELF, etc.
+ *
+ * @return A DTMAxisIterator, or null if the givin axis isn't supported.
+ */
+ public DTMAxisTraverser getAxisTraverser(final int axis);
+
+ /**
+ * This is a shortcut to the iterators that implement
+ * XPath axes.
* Returns a bare-bones iterator that must be initialized
* with a start node (using iterator.setStartNode()).
*
1.1.2.9 +853 -1
xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMDefaultBase.java
Index: DTMDefaultBase.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMDefaultBase.java,v
retrieving revision 1.1.2.8
retrieving revision 1.1.2.9
diff -u -r1.1.2.8 -r1.1.2.9
--- DTMDefaultBase.java 2001/05/20 17:33:26 1.1.2.8
+++ DTMDefaultBase.java 2001/05/21 11:44:01 1.1.2.9
@@ -214,7 +214,11 @@
* @return the number of nodes that have been mapped.
*/
protected abstract int getNumberOfNodes();
+
+ /** Stateless axis traversers, lazely built. */
+ protected DTMAxisTraverser[] m_traversers;
+
/**
* Ensure that the size of the information arrays can hold another entry
* at the given index.
@@ -1711,6 +1715,86 @@
if (null != m_shouldStripWhitespaceStack)
m_shouldStripWhitespaceStack.setTop(shouldStrip);
}
+
+ /**
+ * This returns a stateless "traverser", that can navigate over an
+ * XPath axis, though perhaps not in document order.
+ *
+ * @param axis One of Axes.ANCESTORORSELF, etc.
+ *
+ * @return A DTMAxisIterator, or null if the givin axis isn't supported.
+ */
+ public DTMAxisTraverser getAxisTraverser(final int axis)
+ {
+ DTMAxisTraverser traverser;
+ if(null == m_traversers)
+ {
+ m_traversers = new DTMAxisTraverser[Axis.names.length];
+ traverser = null;
+ }
+ else
+ {
+ traverser = m_traversers[axis];
+ if(traverser != null)
+ return traverser;
+ }
+
+ switch (axis)
+ {
+ case Axis.ANCESTOR:
+ traverser = new AncestorTraverser();
+ break;
+ case Axis.ANCESTORORSELF:
+ traverser = new AncestorOrSelfTraverser();
+ break;
+ case Axis.ATTRIBUTE:
+ traverser = new AttributeTraverser();
+ break;
+ case Axis.CHILD:
+ traverser = new ChildTraverser();
+ break;
+ case Axis.DESCENDANT:
+ traverser = new DescendantTraverser();
+ break;
+ case Axis.DESCENDANTORSELF:
+ traverser = new DescendantTraverser();
+ break;
+ case Axis.FOLLOWING:
+ traverser = new FollowingTraverser();
+ break;
+ case Axis.FOLLOWINGSIBLING:
+ traverser = new FollowingSiblingTraverser();
+ break;
+ case Axis.NAMESPACE:
+ traverser = new NamespaceTraverser();
+ break;
+ case Axis.NAMESPACEDECLS:
+ traverser = new NamespaceDeclsTraverser();
+ break;
+ case Axis.PARENT:
+ traverser = new ParentTraverser();
+ break;
+ case Axis.PRECEDING:
+ traverser = new PrecedingTraverser();
+ break;
+ case Axis.PRECEDINGSIBLING:
+ traverser = new PrecedingSiblingTraverser();
+ break;
+ case Axis.SELF:
+ traverser = new SelfTraverser();
+ break;
+ case Axis.SUBTREE:
+ traverser = new SubtreeTraverser();
+ break;
+ default:
+ throw new DTMException("Unknown axis traversal type");
+ }
+ if(null == traverser)
+ throw new DTMException("Axis traverser not supported:
"+Axis.names[axis]);
+
+ m_traversers[axis] = traverser;
+ return traverser;
+ }
/**
* Get an iterator that can navigate over an XPath Axis, predicated by
@@ -1785,7 +1869,7 @@
/**
* This is a shortcut to the iterators that implement the
- * supported XPath axes (only namespace::) is not supported.
+ * XPath axes.
* Returns a bare-bones iterator that must be initialized
* with a start node (using iterator.setStartNode()).
*
@@ -3490,4 +3574,772 @@
return getExpandedTypeID(result) == _nodeType ? result : NULL;
}
} // end of TypedSingletonIterator
+
+ /**
+ * Implements traversal of the Ancestor access, in reverse document order.
+ */
+ private class AncestorTraverser extends DTMAxisTraverser
+ {
+
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current)
+ {
+ return m_parent[current & m_mask] | m_dtmIdent;
+ }
+
+ /**
+ * Traverse to the next node after the current node that is matched
+ * by the extended type ID.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current, int extendedTypeID)
+ {
+
+ current = current & m_mask;
+
+ while (DTM.NULL != (current = m_parent[current]))
+ {
+ if (m_exptype[current] == extendedTypeID)
+ return current | m_dtmIdent;
+ }
+
+ return NULL;
+ }
+ }
+
+ /**
+ * Implements traversal of the Ancestor access, in reverse document order.
+ */
+ private class AncestorOrSelfTraverser extends AncestorTraverser
+ {
+
+ /**
+ * By the nature of the stateless traversal, the context node can not be
+ * returned or the iteration will go into an infinate loop. To see if
+ * the self node should be processed, use this function.
+ *
+ * @return true if the context node should be processed for this axis.
+ */
+ public boolean processSelf()
+ {
+ return true;
+ }
+
+ /**
+ * By the nature of the stateless traversal, the context node can not be
+ * returned or the iteration will go into an infinate loop. To see if
+ * the self node should be processed, use this function. If the context
+ * node does not match the extended type ID, this function will return
+ * false.
+ *
+ * @param context The context node if this traversal.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return true if the context node should be processed for this axis,
and
+ * the extendedTypeID matches that of the context.
+ */
+ public boolean processSelf(int context, int extendedTypeID)
+ {
+ return (m_exptype[context & m_mask] == extendedTypeID);
+ }
+ }
+
+ /**
+ * Implements traversal of the Ancestor access, in reverse document order.
+ */
+ private class AttributeTraverser extends DTMAxisTraverser
+ {
+
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current)
+ {
+ return (context == current)
+ ? getFirstAttribute(context) : getNextAttribute(current);
+ }
+
+ /**
+ * Traverse to the next node after the current node that is matched
+ * by the extended type ID.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current, int extendedTypeID)
+ {
+
+ current = (context == current)
+ ? getFirstAttribute(context) : getNextAttribute(current);
+
+ do
+ {
+ if (m_exptype[current] == extendedTypeID)
+ return current;
+ }
+ while (DTM.NULL != (current = getNextAttribute(current)));
+
+ return NULL;
+ }
+ }
+
+ /**
+ * Implements traversal of the Ancestor access, in reverse document order.
+ */
+ private class ChildTraverser extends DTMAxisTraverser
+ {
+
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current)
+ {
+ // %OPT%
+ return (context == current)
+ ? getFirstChild(context) : getNextSibling(current);
+ }
+
+ /**
+ * Traverse to the next node after the current node that is matched
+ * by the extended type ID.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current, int extendedTypeID)
+ {
+
+ current = (context == current)
+ ? getFirstChild(context) : getNextSibling(current);
+
+ do
+ {
+ if (m_exptype[current & m_mask] == extendedTypeID)
+ return current;
+ }
+ while (DTM.NULL != (current = getNextSibling(current)));
+
+ return NULL;
+ }
+ }
+
+ /**
+ * Implements traversal of the Ancestor access, in reverse document order.
+ */
+ private class DescendantTraverser extends DTMAxisTraverser
+ {
+
+ /**
+ * Tell if this node identity is a descendant. Assumes that
+ * the node info for the element has already been obtained.
+ * @param identity The index number of the node in question.
+ * @return true if the index is a descendant of _startNode.
+ */
+ protected boolean isDescendant(int subtreeRootIdentity, int identity)
+ {
+ return _parent(identity) >= subtreeRootIdentity;
+ }
+
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current)
+ {
+ int subtreeRootIdent = context & m_mask;
+
+ for (current = (current & m_mask)+1;;current++)
+ {
+ int type = _type(current); // may call nextNode()
+
+ if (!isDescendant(subtreeRootIdent, current))
+ return NULL;
+
+ if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
+ continue;
+
+ return (current | m_dtmIdent); // make handle.
+ }
+ }
+
+ /**
+ * Traverse to the next node after the current node that is matched
+ * by the extended type ID.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current, int extendedTypeID)
+ {
+
+ int subtreeRootIdent = context & m_mask;
+
+ for (current = (current & m_mask)+1;;current++)
+ {
+ int exptype = _exptype(current); // may call nextNode()
+
+ if (!isDescendant(subtreeRootIdent, current))
+ return NULL;
+
+ if (exptype != extendedTypeID)
+ continue;
+
+ return (current | m_dtmIdent); // make handle.
+ }
+ }
+ }
+
+ /**
+ * Implements traversal of the Ancestor access, in reverse document order.
+ */
+ private class DescendantOrSelfTraverser extends DescendantTraverser
+ {
+
+ /**
+ * By the nature of the stateless traversal, the context node can not be
+ * returned or the iteration will go into an infinate loop. To see if
+ * the self node should be processed, use this function.
+ *
+ * @return true if the context node should be processed for this axis.
+ */
+ public boolean processSelf()
+ {
+ return true;
+ }
+
+ /**
+ * By the nature of the stateless traversal, the context node can not be
+ * returned or the iteration will go into an infinate loop. To see if
+ * the self node should be processed, use this function. If the context
+ * node does not match the extended type ID, this function will return
+ * false.
+ *
+ * @param context The context node if this traversal.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return true if the context node should be processed for this axis,
and
+ * the extendedTypeID matches that of the context.
+ */
+ public boolean processSelf(int context, int extendedTypeID)
+ {
+ return (m_exptype[context & m_mask] == extendedTypeID);
+ }
+ }
+
+ /**
+ * Implements traversal of the entire subtree, including the root node.
+ */
+ private class SubtreeTraverser extends DescendantOrSelfTraverser
+ {
+
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current)
+ {
+ int subtreeRootIdent = context & m_mask;
+
+ for (current = (current & m_mask)+1;;current++)
+ {
+ _exptype(current); // make sure it's here.
+
+ if (!isDescendant(subtreeRootIdent, current))
+ return NULL;
+
+ return (current | m_dtmIdent); // make handle.
+ }
+ }
+
+ }
+
+
+ /**
+ * Implements traversal of the following access, in document order.
+ */
+ private class FollowingTraverser extends DescendantTraverser
+ {
+
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current)
+ {
+ int subtreeRootIdent = context & m_mask;
+
+ if(context == current)
+ current = getNextSibling(context) & m_mask;
+ else
+ current = (current & m_mask)+1;
+
+ for (;;current++)
+ {
+ int type = _type(current); // may call nextNode()
+
+ if(NULL == type)
+ return NULL;
+
+ if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
+ continue;
+
+ return (current | m_dtmIdent); // make handle.
+ }
+ }
+
+ /**
+ * Traverse to the next node after the current node that is matched
+ * by the extended type ID.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current, int extendedTypeID)
+ {
+
+ int subtreeRootIdent = context & m_mask;
+
+ if(context == current)
+ current = getNextSibling(context) & m_mask;
+ else
+ current = (current & m_mask)+1;
+
+ for (;;current++)
+ {
+ int exptype = _exptype(current); // may call nextNode()
+
+ if(NULL == exptype)
+ return NULL;
+
+ if (exptype != extendedTypeID)
+ continue;
+
+ return (current | m_dtmIdent); // make handle.
+ }
+ }
+ }
+
+ /**
+ * Implements traversal of the Ancestor access, in reverse document order.
+ */
+ private class FollowingSiblingTraverser extends DTMAxisTraverser
+ {
+
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current)
+ {
+ return getNextSibling(current);
+ }
+
+ /**
+ * Traverse to the next node after the current node that is matched
+ * by the extended type ID.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current, int extendedTypeID)
+ {
+
+ while (DTM.NULL != (current = getNextSibling(current)))
+ {
+ if (m_exptype[current & m_mask] == extendedTypeID)
+ return current;
+ }
+
+ return NULL;
+ }
+ }
+
+ /**
+ * Implements traversal of the Ancestor access, in reverse document order.
+ */
+ private class NamespaceDeclsTraverser extends DTMAxisTraverser
+ {
+
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current)
+ {
+ return (context == current)
+ ? getFirstNamespaceNode(context, false)
+ : getNextNamespaceNode(context, current, false);
+ }
+
+ /**
+ * Traverse to the next node after the current node that is matched
+ * by the extended type ID.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current, int extendedTypeID)
+ {
+
+ current = (context == current)
+ ? getFirstNamespaceNode(context, false)
+ : getNextNamespaceNode(context, current, false);
+
+ do
+ {
+ if (m_exptype[current] == extendedTypeID)
+ return current;
+ }
+ while (DTM.NULL != (current = getNextNamespaceNode(context, current,
false)));
+
+ return NULL;
+ }
+ }
+
+ /**
+ * Implements traversal of the Ancestor access, in reverse document order.
+ */
+ private class NamespaceTraverser extends DTMAxisTraverser
+ {
+
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current)
+ {
+ return (context == current)
+ ? getFirstNamespaceNode(context, true)
+ : getNextNamespaceNode(context, current, true);
+ }
+
+ /**
+ * Traverse to the next node after the current node that is matched
+ * by the extended type ID.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current, int extendedTypeID)
+ {
+
+ current = (context == current)
+ ? getFirstNamespaceNode(context, true)
+ : getNextNamespaceNode(context, current, true);
+
+ do
+ {
+ if (m_exptype[current] == extendedTypeID)
+ return current;
+ }
+ while (DTM.NULL != (current = getNextNamespaceNode(context, current,
true)));
+
+ return NULL;
+ }
+ }
+
+ /**
+ * Implements traversal of the Ancestor access, in reverse document order.
+ */
+ private class ParentTraverser extends DTMAxisTraverser
+ {
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current)
+ {
+ if(context == current)
+ return m_parent[current & m_mask] | m_dtmIdent;
+ else
+ return NULL;
+ }
+
+ /**
+ * Traverse to the next node after the current node that is matched
+ * by the extended type ID.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current, int extendedTypeID)
+ {
+ if(context != current)
+ return NULL;
+
+ current = current & m_mask;
+
+ while (NULL != (current = m_parent[current]))
+ {
+ if (m_exptype[current] == extendedTypeID)
+ return (current | m_dtmIdent);
+ }
+
+ return NULL;
+ }
+ }
+
+ /**
+ * Implements traversal of the Ancestor access, in reverse document order.
+ */
+ private class PrecedingTraverser extends DTMAxisTraverser
+ {
+ /**
+ * Tell if the current identity is an ancestor of the context identity.
+ * This is an expensive operation, made worse by the stateless traversal.
+ * But the preceding axis is used fairly infrequently.
+ *
+ * @param contextIdent The context node of the axis traversal.
+ * @param currentIdent The node in question.
+ * @return true if the currentIdent node is an ancestor of contextIdent.
+ */
+ protected boolean isAncestor(int contextIdent, int currentIdent)
+ {
+ for (contextIdent = m_parent[contextIdent];
+ DTM.NULL != contextIdent;
+ contextIdent = m_parent[contextIdent])
+ {
+ if(contextIdent == currentIdent)
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current)
+ {
+ int subtreeRootIdent = context & m_mask;
+
+ for (current = (current & m_mask)-1;current >= 0;current--)
+ {
+ int exptype = m_exptype[current];
+ int type = ExpandedNameTable.getType(exptype);
+
+ if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type ||
+ isAncestor(subtreeRootIdent, current))
+ continue;
+
+ return (current | m_dtmIdent); // make handle.
+ }
+ return NULL;
+ }
+
+ /**
+ * Traverse to the next node after the current node that is matched
+ * by the extended type ID.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current, int extendedTypeID)
+ {
+
+ int subtreeRootIdent = context & m_mask;
+
+ for (current = (current & m_mask)-1;current >= 0;current--)
+ {
+ int exptype = m_exptype[current];
+ int type = ExpandedNameTable.getType(exptype);
+
+ if (exptype != extendedTypeID ||
+ isAncestor(subtreeRootIdent, current))
+ continue;
+
+ return (current | m_dtmIdent); // make handle.
+ }
+ return NULL;
+ }
+ }
+
+ /**
+ * Implements traversal of the Ancestor access, in reverse document order.
+ */
+ private class PrecedingSiblingTraverser extends DTMAxisTraverser
+ {
+
+
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current)
+ {
+ return getPreviousSibling(current);
+ }
+
+ /**
+ * Traverse to the next node after the current node that is matched
+ * by the extended type ID.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current, int extendedTypeID)
+ {
+
+ while (DTM.NULL != (current = getPreviousSibling(current)))
+ {
+ if (m_exptype[current & m_mask] == extendedTypeID)
+ return current;
+ }
+
+ return NULL;
+ }
+ }
+
+ /**
+ * Implements traversal of the Self axis.
+ */
+ private class SelfTraverser extends DTMAxisTraverser
+ {
+
+ /**
+ * By the nature of the stateless traversal, the context node can not be
+ * returned or the iteration will go into an infinate loop. To see if
+ * the self node should be processed, use this function.
+ *
+ * @return true if the context node should be processed for this axis.
+ */
+ public boolean processSelf()
+ {
+ return true;
+ }
+
+ /**
+ * By the nature of the stateless traversal, the context node can not be
+ * returned or the iteration will go into an infinate loop. To see if
+ * the self node should be processed, use this function. If the context
+ * node does not match the extended type ID, this function will return
+ * false.
+ *
+ * @param context The context node if this traversal.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return true if the context node should be processed for this axis,
and
+ * the extendedTypeID matches that of the context.
+ */
+ public boolean processSelf(int context, int extendedTypeID)
+ {
+ return (m_exptype[context & m_mask] == extendedTypeID);
+ }
+
+ /**
+ * Traverse to the next node after the current node.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ *
+ * @return Always return NULL for this axis.
+ */
+ public int next(int context, int current)
+ {
+ return NULL;
+ }
+
+ /**
+ * Traverse to the next node after the current node that is matched
+ * by the extended type ID.
+ *
+ * @param context The context node if this iteration.
+ * @param current The current node of the iteration.
+ * @param extendedTypeID The extended type ID that must match.
+ *
+ * @return the next node in the iteration, or DTM.NULL.
+ */
+ public int next(int context, int current, int extendedTypeID)
+ {
+ return NULL;
+ }
+ }
}
1.1.2.21 +13 -0
xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMDocumentImpl.java
Index: DTMDocumentImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/Attic/DTMDocumentImpl.java,v
retrieving revision 1.1.2.20
retrieving revision 1.1.2.21
diff -u -r1.1.2.20 -r1.1.2.21
--- DTMDocumentImpl.java 2001/05/20 17:33:26 1.1.2.20
+++ DTMDocumentImpl.java 2001/05/21 11:44:02 1.1.2.21
@@ -2314,6 +2314,19 @@
}
/**
+ * This returns a stateless "traverser", that can navigate over an
+ * XPath axis, though not in document order.
+ *
+ * @param axis One of Axes.ANCESTORORSELF, etc.
+ *
+ * @return A DTMAxisIterator, or null if the givin axis isn't supported.
+ */
+ public DTMAxisTraverser getAxisTraverser(final int axis)
+ {
+ return null;
+ }
+
+ /**
* This is a shortcut to the iterators that implement the
* supported XPath axes (only namespace::) is not supported.
* Returns a bare-bones iterator that must be initialized
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]