mkwan 2003/04/01 11:14:06
Modified: java/src/org/apache/xml/dtm/ref DTMAxisIteratorBase.java
DTMDefaultBase.java DTMDefaultBaseIterators.java
DTMDefaultBaseTraversers.java DTMDocumentImpl.java
DTMManagerDefault.java DTMNamedNodeMap.java
DTMNodeList.java DTMNodeProxy.java
DTMStringPool.java ExpandedNameTable.java
IncrementalSAXSource_Xerces.java
Added: java/src/org/apache/xml/dtm/ref DTMAxisIterNodeList.java
DTMChildIterNodeList.java DTMNodeListBase.java
ExtendedType.java
Log:
Merging XSLTC_DTM and common serializer to the head
Changes in org.apache.xml.dtm.ref.
Add new files:
DTMAxisIterNodeList.java
DTMChildIterNodeList.java
DTMNodeListBase.java
ExtendedType.java
Revision Changes Path
1.8 +27 -2
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMAxisIteratorBase.java
Index: DTMAxisIteratorBase.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMAxisIteratorBase.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- DTMAxisIteratorBase.java 30 Jan 2003 18:46:16 -0000 1.7
+++ DTMAxisIteratorBase.java 1 Apr 2003 19:14:04 -0000 1.8
@@ -68,12 +68,12 @@
* Note that this is _not_ the node's handle within the DTM. Also, don't
* confuse it with the current (most recently returned) position.
*/
- private int _last = -1;
+ protected int _last = -1;
/** The position of the current node within the iteration, as defined by
XPath.
* Note that this is _not_ the node's handle within the DTM!
*/
- private int _position = 0;
+ protected int _position = 0;
/** The position of the marked node within the iteration;
* a saved itaration state that we may want to come back to.
@@ -287,5 +287,30 @@
{
return -1;
}
+
+ public void setRestartable(boolean isRestartable) {
+ _isRestartable = isRestartable;
+ }
+ /**
+ * Return the node at the given position.
+ *
+ * @param position The position
+ * @return The node at the given position.
+ */
+ public int getNodeByPosition(int position)
+ {
+ if (position > 0) {
+ final int pos = isReverse() ? getLast() - position + 1
+ : position;
+ int node;
+ while ((node = next()) != DTMAxisIterator.END) {
+ if (pos == getPosition()) {
+ return node;
+ }
+ }
+ }
+ return END;
+ }
+
}
1.34 +345 -92
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBase.java
Index: DTMDefaultBase.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBase.java,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -r1.33 -r1.34
--- DTMDefaultBase.java 30 Jan 2003 18:46:16 -0000 1.33
+++ DTMDefaultBase.java 1 Apr 2003 19:14:04 -0000 1.34
@@ -56,26 +56,22 @@
*/
package org.apache.xml.dtm.ref;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
+import org.apache.xml.dtm.*;
+import org.apache.xml.utils.SuballocatedIntVector;
+import org.apache.xml.utils.BoolStack;
+
import java.util.Vector;
import javax.xml.transform.Source;
-import org.apache.xml.dtm.DTM;
-import org.apache.xml.dtm.DTMAxisTraverser;
-import org.apache.xml.dtm.DTMException;
-import org.apache.xml.dtm.DTMManager;
-import org.apache.xml.dtm.DTMWSFilter;
-import org.apache.xml.res.XMLErrorResources;
-import org.apache.xml.res.XMLMessages;
-import org.apache.xml.utils.BoolStack;
-import org.apache.xml.utils.SuballocatedIntVector;
import org.apache.xml.utils.XMLString;
import org.apache.xml.utils.XMLStringFactory;
+
+import org.apache.xml.res.XMLMessages;
+import org.apache.xml.res.XMLErrorResources;
+
+import java.io.*; // for dumpDTM
+
/**
* The <code>DTMDefaultBase</code> class serves as a helper base for DTMs.
* It sets up structures for navigation and type, while leaving data
@@ -85,6 +81,11 @@
{
static boolean JJK_DEBUG=false;
+// %HZ%: Added following back in temporarily only - must remove!!!
+ /** The identity of the root node. */
+ public static final int ROOTNODE = 0;
+// %HZ%: Added preceding back in temporarily only - must remove!!!
+
/**
* The number of nodes, which is also used to determine the next
@@ -122,11 +123,17 @@
*/
protected int[][][] m_elemIndexes;
- /** The default initial block size of the node arrays */
- protected int m_initialblocksize = 512; // favor small docs.
-
- /** Size of blocks to allocate */
- protected int m_blocksize = 2 * 1024;
+ /** The default block size of the node arrays */
+ public static final int DEFAULT_BLOCKSIZE = 512; // favor small docs.
+
+ /** The number of blocks for the node arrays */
+ public static final int DEFAULT_NUMBLOCKS = 32;
+
+ /** The number of blocks used for small documents & RTFs */
+ public static final int DEFAULT_NUMBLOCKS_SMALL = 4;
+
+ /** The block size of the node arrays */
+ //protected final int m_blocksize;
/**
* The value to use when the information has not been built yet.
@@ -136,16 +143,19 @@
/**
* The DTM manager who "owns" this DTM.
*/
- protected DTMManager m_mgr;
+
+ public DTMManager m_mgr;
+
/**
* m_mgr cast to DTMManagerDefault, or null if it isn't an instance
* (Efficiency hook)
*/
protected DTMManagerDefault m_mgrDefault=null;
+
/** The document identity number(s). If we have overflowed the addressing
* range of the first that was assigned to us, we may add others. */
- protected SuballocatedIntVector m_dtmIdent=new SuballocatedIntVector(32);
+ protected SuballocatedIntVector m_dtmIdent;
/** The mask for the identity.
%REVIEW% Should this really be set to the _DEFAULT? What if
@@ -179,6 +189,27 @@
protected boolean m_indexing;
/**
+ * Construct a DTMDefaultBase object using the default block size.
+ *
+ * @param mgr The DTMManager who owns this DTM.
+ * @param domSource the DOM source that this DTM will wrap.
+ * @param source The object that is used to specify the construction
source.
+ * @param dtmIdentity The DTM identity ID for this DTM.
+ * @param whiteSpaceFilter The white space filter for this DTM, which may
+ * be null.
+ * @param xstringfactory The factory to use for creating XMLStrings.
+ * @param doIndexing true if the caller considers it worth it to use
+ * indexing schemes.
+ */
+ public DTMDefaultBase(DTMManager mgr, Source source, int dtmIdentity,
+ DTMWSFilter whiteSpaceFilter,
+ XMLStringFactory xstringfactory, boolean doIndexing)
+ {
+ this(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
+ doIndexing, DEFAULT_BLOCKSIZE, true);
+ }
+
+ /**
* Construct a DTMDefaultBase object from a DOM node.
*
* @param mgr The DTMManager who owns this DTM.
@@ -190,22 +221,40 @@
* @param xstringfactory The factory to use for creating XMLStrings.
* @param doIndexing true if the caller considers it worth it to use
* indexing schemes.
+ * @param blocksize The block size of the DTM.
+ * @param usePrevsib true if we want to build the previous sibling node
array.
*/
public DTMDefaultBase(DTMManager mgr, Source source, int dtmIdentity,
DTMWSFilter whiteSpaceFilter,
- XMLStringFactory xstringfactory, boolean doIndexing)
+ XMLStringFactory xstringfactory, boolean doIndexing,
+ int blocksize, boolean usePrevsib)
{
- if(false == doIndexing)
+ //m_blocksize = blocksize;
+
+ // Use smaller sizes for the internal node arrays if the block size
+ // is small.
+ int numblocks;
+ if (blocksize <= 64)
{
- m_initialblocksize = 8;
- m_blocksize = 16;
+ numblocks = DEFAULT_NUMBLOCKS_SMALL;
+ m_dtmIdent= new SuballocatedIntVector(4, 1);
}
-
- m_exptype = new SuballocatedIntVector(m_initialblocksize);
- m_firstch = new SuballocatedIntVector(m_initialblocksize);
- m_nextsib = new SuballocatedIntVector(m_initialblocksize);
- m_prevsib = new SuballocatedIntVector(m_initialblocksize);
- m_parent = new SuballocatedIntVector(m_initialblocksize);
+ else
+ {
+ numblocks = DEFAULT_NUMBLOCKS;
+ m_dtmIdent= new SuballocatedIntVector(32);
+ }
+
+ m_exptype = new SuballocatedIntVector(blocksize, numblocks);
+ m_firstch = new SuballocatedIntVector(blocksize, numblocks);
+ m_nextsib = new SuballocatedIntVector(blocksize, numblocks);
+ m_parent = new SuballocatedIntVector(blocksize, numblocks);
+
+ // Only create the m_prevsib array if the usePrevsib flag is true.
+ // Some DTM implementations (e.g. SAXImpl) do not need this array.
+ // We can save the time to build it in those cases.
+ if (usePrevsib)
+ m_prevsib = new SuballocatedIntVector(blocksize, numblocks);
m_mgr = mgr;
if(mgr instanceof DTMManagerDefault)
@@ -465,6 +514,8 @@
*/
protected int _exptype(int identity)
{
+ if (identity == DTM.NULL)
+ return NULL;
// Reorganized test and loop into single flow
// Tiny performance improvement, saves a few bytes of code, clearer.
// %OPT% Other internal getters could be treated simliarly
@@ -541,7 +592,6 @@
*/
protected int _nextsib(int identity)
{
-
// Boiler-plate code for each of the _xxx functions, except for the
array.
int info = (identity >= m_size) ? NOTPROCESSED :
m_nextsib.elementAt(identity);
@@ -718,14 +768,17 @@
else
ps.println("First child: " + firstChild);
- int prevSibling = _prevsib(index);
+ if (m_prevsib != null)
+ {
+ int prevSibling = _prevsib(index);
- if (DTM.NULL == prevSibling)
- ps.println("Prev sibling: DTM.NULL");
- else if (NOTPROCESSED == prevSibling)
- ps.println("Prev sibling: NOTPROCESSED");
- else
- ps.println("Prev sibling: " + prevSibling);
+ if (DTM.NULL == prevSibling)
+ ps.println("Prev sibling: DTM.NULL");
+ else if (NOTPROCESSED == prevSibling)
+ ps.println("Prev sibling: NOTPROCESSED");
+ else
+ ps.println("Prev sibling: " + prevSibling);
+ }
int nextSibling = _nextsib(index);
@@ -884,7 +937,7 @@
* @param nodeIdentity Internal offset to this node's records.
* @return NodeHandle (external representation of node)
* */
- final protected int makeNodeHandle(int nodeIdentity)
+ final public int makeNodeHandle(int nodeIdentity)
{
if(NULL==nodeIdentity) return NULL;
@@ -911,7 +964,7 @@
* @param NodeHandle (external representation of node)
* @return nodeIdentity Internal offset to this node's records.
* */
- final protected int makeNodeIdentity(int nodeHandle)
+ final public int makeNodeIdentity(int nodeHandle)
{
if(NULL==nodeHandle) return NULL;
@@ -959,6 +1012,41 @@
return makeNodeHandle(firstChild);
}
+
+ /**
+ * Given a node handle, get the handle of the node's first child.
+ * If not yet resolved, waits for more nodes to be added to the document
and
+ * tries again.
+ *
+ * @param nodeHandle int Handle of the node.
+ * @return int DTM node-number of first child, or DTM.NULL to indicate
none exists.
+ */
+ public int getTypedFirstChild(int nodeHandle, int nodeType)
+ {
+
+ int firstChild, eType;
+ if (nodeType < DTM.NTYPES) {
+ for (firstChild = _firstch(makeNodeIdentity(nodeHandle));
+ firstChild != DTM.NULL;
+ firstChild = _nextsib(firstChild)) {
+ eType = _exptype(firstChild);
+ if (eType == nodeType
+ || (eType >= DTM.NTYPES
+ && m_expandedNameTable.getType(eType) == nodeType)) {
+ return makeNodeHandle(firstChild);
+ }
+ }
+ } else {
+ for (firstChild = _firstch(makeNodeIdentity(nodeHandle));
+ firstChild != DTM.NULL;
+ firstChild = _nextsib(firstChild)) {
+ if (_exptype(firstChild) == nodeType) {
+ return makeNodeHandle(firstChild);
+ }
+ }
+ }
+ return DTM.NULL;
+ }
/**
* Given a node handle, advance to its last child.
@@ -1008,15 +1096,23 @@
*/
public int getFirstAttribute(int nodeHandle)
{
+ int nodeID = makeNodeIdentity(nodeHandle);
- int type = getNodeType(nodeHandle);
+ return makeNodeHandle(getFirstAttributeIdentity(nodeID));
+ }
+
+ /**
+ * Given a node identity, get the index of the node's first attribute.
+ *
+ * @param identity int identity of the node.
+ * @return Identity of first attribute, or DTM.NULL to indicate none
exists.
+ */
+ protected int getFirstAttributeIdentity(int identity) {
+ int type = _type(identity);
if (DTM.ELEMENT_NODE == type)
{
-
// Assume that attributes and namespaces immediately follow the
element.
- int identity = makeNodeIdentity(nodeHandle);
-
while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
{
@@ -1025,7 +1121,39 @@
if (type == DTM.ATTRIBUTE_NODE)
{
- return makeNodeHandle(identity);
+ return identity;
+ }
+ else if (DTM.NAMESPACE_NODE != type)
+ {
+ break;
+ }
+ }
+ }
+
+ return DTM.NULL;
+ }
+
+ /**
+ * Given a node handle and an expanded type ID, get the index of the node's
+ * attribute of that type, if any.
+ *
+ * @param nodeHandle int Handle of the node.
+ * @param attType int expanded type ID of the required attribute.
+ * @return Handle of attribute of the required type, or DTM.NULL to
indicate
+ * none exists.
+ */
+ protected int getTypedAttribute(int nodeHandle, int attType) {
+ int type = getNodeType(nodeHandle);
+ if (DTM.ELEMENT_NODE == type) {
+ int identity = makeNodeIdentity(nodeHandle);
+
+ while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
+ {
+ type = _type(identity);
+
+ if (type == DTM.ATTRIBUTE_NODE)
+ {
+ if (_exptype(identity) == attType) return makeNodeHandle(identity);
}
else if (DTM.NAMESPACE_NODE != type)
{
@@ -1047,8 +1175,32 @@
*/
public int getNextSibling(int nodeHandle)
{
+ if (nodeHandle == DTM.NULL)
+ return DTM.NULL;
return makeNodeHandle(_nextsib(makeNodeIdentity(nodeHandle)));
}
+
+ /**
+ * Given a node handle, advance to its next sibling.
+ * If not yet resolved, waits for more nodes to be added to the document
and
+ * tries again.
+ * @param nodeHandle int Handle of the node.
+ * @return int Node-number of next sibling,
+ * or DTM.NULL to indicate none exists.
+ */
+ public int getTypedNextSibling(int nodeHandle, int nodeType)
+ {
+ if (nodeHandle == DTM.NULL)
+ return DTM.NULL;
+ int node = makeNodeIdentity(nodeHandle);
+ int eType;
+ while ((node = _nextsib(node)) != DTM.NULL &&
+ ((eType = _exptype(node)) != nodeType &&
+ m_expandedNameTable.getType(eType)!= nodeType));
+ //_type(node) != nodeType));
+
+ return (node == DTM.NULL ? DTM.NULL : makeNodeHandle(node));
+ }
/**
* Given a node handle, find its preceeding sibling.
@@ -1061,7 +1213,27 @@
*/
public int getPreviousSibling(int nodeHandle)
{
- return makeNodeHandle(_prevsib(makeNodeIdentity(nodeHandle)));
+ if (nodeHandle == DTM.NULL)
+ return DTM.NULL;
+
+ if (m_prevsib != null)
+ return makeNodeHandle(_prevsib(makeNodeIdentity(nodeHandle)));
+ else
+ {
+ // If the previous sibling array is not built, we get at
+ // the previous sibling using the parent, firstch and
+ // nextsib arrays.
+ int nodeID = makeNodeIdentity(nodeHandle);
+ int parent = _parent(nodeID);
+ int node = _firstch(parent);
+ int result = DTM.NULL;
+ while (node != nodeID)
+ {
+ result = node;
+ node = _nextsib(node);
+ }
+ return makeNodeHandle(result);
+ }
}
/**
@@ -1073,28 +1245,35 @@
* @return int DTM node-number of the resolved attr,
* or DTM.NULL to indicate none exists.
*/
- public int getNextAttribute(int nodeHandle)
- {
-
- int type = getNodeType(nodeHandle);
+ public int getNextAttribute(int nodeHandle) {
+ int nodeID = makeNodeIdentity(nodeHandle);
- if (DTM.ATTRIBUTE_NODE == type)
- {
- // Assume that attributes and namespace nodes immediately follow the
element.
- int identity = makeNodeIdentity(nodeHandle);
+ if (_type(nodeID) == DTM.ATTRIBUTE_NODE) {
+ return makeNodeHandle(getNextAttributeIdentity(nodeID));
+ }
- while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
- {
- type = _type(identity);
+ return DTM.NULL;
+ }
- if (type == DTM.ATTRIBUTE_NODE)
- {
- return makeNodeHandle(identity);
- }
- else if (type != DTM.NAMESPACE_NODE)
- {
- break;
- }
+ /**
+ * Given a node identity for an attribute, advance to the next attribute.
+ *
+ * @param identity int identity of the attribute node. This
+ * <strong>must</strong> be an attribute node.
+ *
+ * @return int DTM node-identity of the resolved attr,
+ * or DTM.NULL to indicate none exists.
+ *
+ */
+ protected int getNextAttributeIdentity(int identity) {
+ // Assume that attributes and namespace nodes immediately follow the
element
+ while (DTM.NULL != (identity = getNextNodeIdentity(identity))) {
+ int type = _type(identity);
+
+ if (type == DTM.ATTRIBUTE_NODE) {
+ return identity;
+ } else if (type != DTM.NAMESPACE_NODE) {
+ break;
}
}
@@ -1146,27 +1325,29 @@
{
m_namespaceDeclSetElements.addElement(elementNodeIndex);
- SuballocatedIntVector inherited=
findNamespaceContext(_parent(elementNodeIndex));
+ SuballocatedIntVector inherited =
+
findNamespaceContext(_parent(elementNodeIndex));
- if(inherited!=null)
- {
+ if (inherited!=null) {
// %OPT% Count-down might be faster, but debuggability may
// be better this way, and if we ever decide we want to
// keep this ordered by expanded-type...
int isize=inherited.size();
-
- // Base the size of a new namespace list on the
- // size of the inherited list - but within reason!
- nsList=new
SuballocatedIntVector(Math.max(Math.min(isize+16,2048), 32));
-
+
+ // Base the size of a new namespace list on the
+ // size of the inherited list - but within reason!
+ nsList=new
SuballocatedIntVector(Math.max(Math.min(isize+16,2048),
+ 32));
+
for(int i=0;i<isize;++i)
{
nsList.addElement(inherited.elementAt(i));
}
- } else {
- nsList=new SuballocatedIntVector(32);
- }
- m_namespaceDeclSets.addElement(nsList);
+ } else {
+ nsList=new SuballocatedIntVector(32);
+ }
+
+ m_namespaceDeclSets.addElement(nsList);
}
// Handle overwriting inherited.
@@ -1213,16 +1394,41 @@
// Decrement wouldBeAt to find last possible ancestor
int candidate=m_namespaceDeclSetElements.elementAt(-- wouldBeAt);
int ancestor=_parent(elementNodeIndex);
+
+ // Special case: if the candidate is before the given node, and
+ // is in the earliest possible position in the document, it
+ // must have the namespace declarations we're interested in.
+ if (wouldBeAt == 0 && candidate < ancestor) {
+ int rootHandle = getDocumentRoot(makeNodeHandle(elementNodeIndex));
+ int rootID = makeNodeIdentity(rootHandle);
+ int uppermostNSCandidateID;
+
+ if (getNodeType(rootHandle) == DTM.DOCUMENT_NODE) {
+ int ch = _firstch(rootID);
+ uppermostNSCandidateID = (ch != DTM.NULL) ? ch : rootID;
+ } else {
+ uppermostNSCandidateID = rootID;
+ }
+
+ if (candidate == uppermostNSCandidateID) {
+ return
(SuballocatedIntVector)m_namespaceDeclSets.elementAt(wouldBeAt);
+ }
+ }
+
while(wouldBeAt>=0 && ancestor>0)
{
- candidate=m_namespaceDeclSetElements.elementAt(wouldBeAt);
-
- if(candidate==ancestor) // Found ancestor in list
+ if (candidate==ancestor) {
+ // Found ancestor in list
return
(SuballocatedIntVector)m_namespaceDeclSets.elementAt(wouldBeAt);
- else if(candidate<ancestor) // Too deep in tree
- ancestor=_parent(ancestor);
- else // Too late in list
- --wouldBeAt;
+ } else if (candidate<ancestor) {
+ // Too deep in tree
+ do {
+ ancestor=_parent(ancestor);
+ } while (candidate < ancestor);
+ } else {
+ // Too late in list
+ candidate=m_namespaceDeclSetElements.elementAt(--wouldBeAt);
+ }
}
}
@@ -1292,11 +1498,17 @@
{
if(inScope)
{
- SuballocatedIntVector
nsContext=findNamespaceContext(makeNodeIdentity(nodeHandle));
- if(nsContext==null || nsContext.size()<1)
+ int identity = makeNodeIdentity(nodeHandle);
+ if (_type(identity) == DTM.ELEMENT_NODE)
+ {
+ SuballocatedIntVector nsContext=findNamespaceContext(identity);
+ if(nsContext==null || nsContext.size()<1)
+ return NULL;
+
+ return nsContext.elementAt(0);
+ }
+ else
return NULL;
-
- return nsContext.elementAt(0);
}
else
{
@@ -1307,7 +1519,9 @@
// before all Attr nodes? Some costs at build time for 2nd
// pass...
int identity = makeNodeIdentity(nodeHandle);
- while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
+ if (_type(identity) == DTM.ELEMENT_NODE)
+ {
+ while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
{
int type = _type(identity);
if (type == DTM.NAMESPACE_NODE)
@@ -1315,7 +1529,10 @@
else if (DTM.ATTRIBUTE_NODE != type)
break;
}
- return NULL;
+ return NULL;
+ }
+ else
+ return NULL;
}
}
@@ -1658,7 +1875,9 @@
*/
public short getNodeType(int nodeHandle)
{
- return
m_expandedNameTable.getType(_exptype(makeNodeIdentity(nodeHandle)));
+ if (nodeHandle == DTM.NULL)
+ return DTM.NULL;
+ return
m_expandedNameTable.getType(_exptype(makeNodeIdentity(nodeHandle)));
}
/**
@@ -1674,6 +1893,40 @@
// Apparently, the axis walker stuff requires levels to count from 1.
int identity = makeNodeIdentity(nodeHandle);
return (short) (_level(identity) + 1);
+ }
+
+ /**
+ * <meta name="usage" content="internal"/>
+ * Get the identity of this node in the tree
+ *
+ * @param nodeHandle The node handle.
+ * @return the node identity
+ */
+ public int getNodeIdent(int nodeHandle)
+ {
+ /*if (nodeHandle != DTM.NULL)
+ return nodeHandle & m_mask;
+ else
+ return DTM.NULL;*/
+
+ return makeNodeIdentity(nodeHandle);
+ }
+
+ /**
+ * <meta name="usage" content="internal"/>
+ * Get the handle of this node in the tree
+ *
+ * @param nodeId The node identity.
+ * @return the node handle
+ */
+ public int getNodeHandle(int nodeId)
+ {
+ /*if (nodeId != DTM.NULL)
+ return nodeId | m_dtmIdent;
+ else
+ return DTM.NULL;*/
+
+ return makeNodeHandle(nodeId);
}
// ============== Document query functions ==============
1.19 +498 -206
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBaseIterators.java
Index: DTMDefaultBaseIterators.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBaseIterators.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- DTMDefaultBaseIterators.java 30 Jan 2003 18:46:16 -0000 1.18
+++ DTMDefaultBaseIterators.java 1 Apr 2003 19:14:04 -0000 1.19
@@ -56,18 +56,14 @@
*/
package org.apache.xml.dtm.ref;
+import org.apache.xml.dtm.*;
+
import javax.xml.transform.Source;
-import org.apache.xml.dtm.Axis;
-import org.apache.xml.dtm.DTM;
-import org.apache.xml.dtm.DTMAxisIterator;
-import org.apache.xml.dtm.DTMAxisTraverser;
-import org.apache.xml.dtm.DTMException;
-import org.apache.xml.dtm.DTMManager;
-import org.apache.xml.dtm.DTMWSFilter;
+import org.apache.xml.utils.XMLStringFactory;
+
import org.apache.xml.res.XMLErrorResources;
import org.apache.xml.res.XMLMessages;
-import org.apache.xml.utils.XMLStringFactory;
/**
@@ -100,6 +96,33 @@
}
/**
+ * Construct a DTMDefaultBaseTraversers object from a DOM node.
+ *
+ * @param mgr The DTMManager who owns this DTM.
+ * @param domSource the DOM source that this DTM will wrap.
+ * @param source The object that is used to specify the construction
source.
+ * @param dtmIdentity The DTM identity ID for this DTM.
+ * @param whiteSpaceFilter The white space filter for this DTM, which may
+ * be null.
+ * @param xstringfactory The factory to use for creating XMLStrings.
+ * @param doIndexing true if the caller considers it worth it to use
+ * indexing schemes.
+ * @param blocksize The block size of the DTM.
+ * @param usePrevsib true if we want to build the previous sibling node
array.
+ */
+ public DTMDefaultBaseIterators(DTMManager mgr, Source source,
+ int dtmIdentity,
+ DTMWSFilter whiteSpaceFilter,
+ XMLStringFactory xstringfactory,
+ boolean doIndexing,
+ int blocksize,
+ boolean usePrevsib)
+ {
+ super(mgr, source, dtmIdentity, whiteSpaceFilter,
+ xstringfactory, doIndexing, blocksize, usePrevsib);
+ }
+
+ /**
* Get an iterator that can navigate over an XPath Axis, predicated by
* the extended type ID.
* Returns an iterator that must be initialized
@@ -249,7 +272,7 @@
*
* Currently there isn't a lot here
*/
- private abstract class InternalAxisIteratorBase extends DTMAxisIteratorBase
+ public abstract class InternalAxisIteratorBase extends DTMAxisIteratorBase
{
// %REVIEW% We could opt to share _nodeType and setNodeType() as
@@ -286,12 +309,13 @@
{
_currentNode = _markedNode;
}
+
} // end of InternalAxisIteratorBase
/**
* Iterator that returns all immediate children of a given node
*/
- private final class ChildrenIterator extends InternalAxisIteratorBase
+ public final class ChildrenIterator extends InternalAxisIteratorBase
{
/**
@@ -306,13 +330,16 @@
*
* @return A DTMAxisIterator set to the start of the iteration.
*/
- public DTMAxisIterator setStartNode(final int node)
+ public DTMAxisIterator setStartNode(int node)
{
-
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isRestartable)
{
_startNode = node;
- _currentNode = NOTPROCESSED;
+ _currentNode = (node == DTM.NULL) ? DTM.NULL
+ : _firstch(makeNodeIdentity(node));
return resetPosition();
}
@@ -328,12 +355,13 @@
*/
public int next()
{
+ if (_currentNode != NULL) {
+ int node = _currentNode;
+ _currentNode = _nextsib(node);
+ return returnNode(makeNodeHandle(node));
+ }
- _currentNode = (NOTPROCESSED == _currentNode)
- ? getFirstChild(_startNode)
- : getNextSibling(_currentNode);
-
- return returnNode(_currentNode);
+ return END;
}
} // end of ChildrenIterator
@@ -342,7 +370,7 @@
* this delivers only a single node; if you want all the ancestors,
* see AncestorIterator.
*/
- private final class ParentIterator extends InternalAxisIteratorBase
+ public final class ParentIterator extends InternalAxisIteratorBase
{
/** The extended type ID that was requested. */
@@ -358,7 +386,9 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isRestartable)
{
_startNode = node;
@@ -396,13 +426,17 @@
*/
public int next()
{
-
int result = _currentNode;
- if ((_nodeType != -1) && (getExpandedTypeID(_currentNode) !=
_nodeType))
- result = END;
- else
- result = _currentNode;
+ if (_nodeType >= DTM.NTYPES) {
+ if (_nodeType != getExpandedTypeID(_currentNode)) {
+ result = END;
+ }
+ } else if (_nodeType != NULL) {
+ if (_nodeType != getNodeType(_currentNode)) {
+ result = END;
+ }
+ }
_currentNode = END;
@@ -416,7 +450,7 @@
* of a basic child iterator, but a specialised iterator is used
* for efficiency (both speed and size of translet).
*/
- private final class TypedChildrenIterator extends InternalAxisIteratorBase
+ public final class TypedChildrenIterator extends InternalAxisIteratorBase
{
/** The extended type ID that was requested. */
@@ -443,11 +477,15 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isRestartable)
{
_startNode = node;
- _currentNode = NOTPROCESSED;
+ _currentNode = (node == DTM.NULL)
+ ? DTM.NULL
+ : _firstch(makeNodeIdentity(_startNode));
return resetPosition();
}
@@ -462,21 +500,37 @@
*/
public int next()
{
+ int eType;
+ int node = _currentNode;
- for (int node = (NOTPROCESSED == _currentNode)
- ? getFirstChild(_startNode)
- : getNextSibling(_currentNode); node
- != END; node = getNextSibling(node))
- {
- if (getExpandedTypeID(node) == _nodeType)
- {
- _currentNode = node;
+ int nodeType = _nodeType;
- return returnNode(node);
+ if (nodeType >= DTM.NTYPES) {
+ while (node != DTM.NULL && _exptype(node) != nodeType) {
+ node = _nextsib(node);
+ }
+ } else {
+ while (node != DTM.NULL) {
+ eType = _exptype(node);
+ if (eType < DTM.NTYPES) {
+ if (eType == nodeType) {
+ break;
+ }
+ } else if (m_expandedNameTable.getType(eType) == nodeType) {
+ break;
+ }
+ node = _nextsib(node);
}
}
- return END;
+ if (node == DTM.NULL) {
+ _currentNode = DTM.NULL;
+ return DTM.NULL;
+ } else {
+ _currentNode = _nextsib(node);
+ return returnNode(makeNodeHandle(node));
+ }
+
}
} // end of TypedChildrenIterator
@@ -486,7 +540,7 @@
* filter on top of a basic child iterator, but a specialised
* iterator is used for efficiency (both speed and size of translet).
*/
- private final class NamespaceChildrenIterator
+ public final class NamespaceChildrenIterator
extends InternalAxisIteratorBase
{
@@ -514,11 +568,13 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isRestartable)
{
_startNode = node;
- _currentNode = NOTPROCESSED;
+ _currentNode = (node == DTM.NULL) ? DTM.NULL : NOTPROCESSED;
return resetPosition();
}
@@ -533,29 +589,29 @@
*/
public int next()
{
+ if (_currentNode != DTM.NULL) {
+ for (int node = (NOTPROCESSED == _currentNode)
+ ? _firstch(makeNodeIdentity(_startNode))
+ : _nextsib(_currentNode);
+ node != END;
+ node = _nextsib(node)) {
+ if (m_expandedNameTable.getNamespaceID(_exptype(node)) == _nsType)
{
+ _currentNode = node;
- for (int node = (NOTPROCESSED == _currentNode)
- ? getFirstChild(_startNode)
- : getNextSibling(_currentNode); node
- != END; node = getNextSibling(node))
- {
- if (getNamespaceType(node) == _nsType)
- {
- _currentNode = node;
-
- return returnNode(node);
+ return returnNode(node);
+ }
}
}
return END;
}
- } // end of TypedChildrenIterator
+ } // end of NamespaceChildrenIterator
/**
* Iterator that returns the namespace nodes as defined by the XPath data
model
* for a given node.
*/
- private class NamespaceIterator
+ public class NamespaceIterator
extends InternalAxisIteratorBase
{
@@ -578,7 +634,9 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isRestartable)
{
_startNode = node;
@@ -611,14 +669,14 @@
* Iterator that returns the namespace nodes as defined by the XPath data
model
* for a given node, filtered by extended type ID.
*/
- private class TypedNamespaceIterator extends NamespaceIterator
+ public class TypedNamespaceIterator extends NamespaceIterator
{
/** The extended type ID that was requested. */
private final int _nodeType;
/**
- * Constructor TypedChildrenIterator
+ * Constructor TypedNamespaceIterator
*
*
* @param nodeType The extended type ID being requested.
@@ -636,18 +694,21 @@
*/
public int next()
{
+ int node;
- for (int node = super.next(); node != END; node = super.next())
- {
- if (getExpandedTypeID(node) == _nodeType)
- {
+ for (node = _currentNode;
+ node != END;
+ node = getNextNamespaceNode(_startNode, node, true)) {
+ if (getExpandedTypeID(node) == _nodeType
+ || getNodeType(node) == _nodeType
+ || getNamespaceType(node) == _nodeType) {
_currentNode = node;
return returnNode(node);
}
}
- return END;
+ return (_currentNode =END);
}
} // end of TypedNamespaceIterator
@@ -655,7 +716,7 @@
* Iterator that returns the the root node as defined by the XPath data
model
* for a given node.
*/
- private class RootIterator
+ public class RootIterator
extends InternalAxisIteratorBase
{
@@ -710,7 +771,7 @@
* Iterator that returns the namespace nodes as defined by the XPath data
model
* for a given node, filtered by extended type ID.
*/
- private class TypedRootIterator extends RootIterator
+ public class TypedRootIterator extends RootIterator
{
/** The extended type ID that was requested. */
@@ -734,15 +795,29 @@
*/
public int next()
{
+ if(_startNode == _currentNode)
+ return NULL;
- for (int node = super.next(); node != END; node = super.next())
- {
- if (getExpandedTypeID(node) == _nodeType)
- {
- _currentNode = node;
+ int nodeType = _nodeType;
+ int node = _startNode;
+ int expType = getExpandedTypeID(node);
+
+ _currentNode = node;
+ if (nodeType >= DTM.NTYPES) {
+ if (nodeType == expType) {
return returnNode(node);
}
+ } else {
+ if (expType < DTM.NTYPES) {
+ if (expType == nodeType) {
+ return returnNode(node);
+ }
+ } else {
+ if (m_expandedNameTable.getType(expType) == nodeType) {
+ return returnNode(node);
+ }
+ }
}
return END;
@@ -752,7 +827,7 @@
/**
* Iterator that returns attributes within a given namespace for a node.
*/
- private final class NamespaceAttributeIterator
+ public final class NamespaceAttributeIterator
extends InternalAxisIteratorBase
{
@@ -783,7 +858,9 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isRestartable)
{
_startNode = node;
@@ -810,12 +887,12 @@
return returnNode(node);
}
- } // end of TypedChildrenIterator
+ } // end of NamespaceAttributeIterator
/**
* Iterator that returns all siblings of a given node.
*/
- private class FollowingSiblingIterator extends InternalAxisIteratorBase
+ public class FollowingSiblingIterator extends InternalAxisIteratorBase
{
/**
@@ -828,10 +905,13 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isRestartable)
{
- _currentNode = _startNode = node;
+ _startNode = node;
+ _currentNode = makeNodeIdentity(node);
return resetPosition();
}
@@ -846,14 +926,16 @@
*/
public int next()
{
- return returnNode(_currentNode = getNextSibling(_currentNode));
+ _currentNode = (_currentNode == DTM.NULL) ? DTM.NULL
+ : _nextsib(_currentNode);
+ return returnNode(makeNodeHandle(_currentNode));
}
} // end of FollowingSiblingIterator
/**
* Iterator that returns all following siblings of a given node.
*/
- private final class TypedFollowingSiblingIterator
+ public final class TypedFollowingSiblingIterator
extends FollowingSiblingIterator
{
@@ -878,20 +960,43 @@
*/
public int next()
{
+ if (_currentNode == DTM.NULL) {
+ return DTM.NULL;
+ }
- int node;
+ int node = _currentNode;
+ int eType;
+ int nodeType = _nodeType;
- while ((node = super.next()) != NULL
- && getExpandedTypeID(node) != _nodeType){}
+ if (nodeType >= DTM.NTYPES) {
+ do {
+ node = _nextsib(node);
+ } while (node != DTM.NULL && _exptype(node) != nodeType);
+ } else {
+ while ((node = _nextsib(node)) != DTM.NULL) {
+ eType = _exptype(node);
+ if (eType < DTM.NTYPES) {
+ if (eType == nodeType) {
+ break;
+ }
+ } else if (m_expandedNameTable.getType(eType) == nodeType) {
+ break;
+ }
+ }
+ }
+
+ _currentNode = node;
- return node;
+ return (_currentNode == DTM.NULL)
+ ? DTM.NULL
+ : returnNode(makeNodeHandle(_currentNode));
}
} // end of TypedFollowingSiblingIterator
/**
* Iterator that returns attribute nodes (of what nodes?)
*/
- private final class AttributeIterator extends InternalAxisIteratorBase
+ public final class AttributeIterator extends InternalAxisIteratorBase
{
// assumes caller will pass element nodes
@@ -906,11 +1011,13 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isRestartable)
{
_startNode = node;
- _currentNode = getFirstAttribute(node);
+ _currentNode = getFirstAttributeIdentity(makeNodeIdentity(node));
return resetPosition();
}
@@ -928,16 +1035,19 @@
final int node = _currentNode;
- _currentNode = getNextAttribute(node);
+ if (node != NULL) {
+ _currentNode = getNextAttributeIdentity(node);
+ return returnNode(makeNodeHandle(node));
+ }
- return returnNode(node);
+ return NULL;
}
} // end of AttributeIterator
/**
* Iterator that returns attribute nodes of a given type
*/
- private final class TypedAttributeIterator extends InternalAxisIteratorBase
+ public final class TypedAttributeIterator extends InternalAxisIteratorBase
{
/** The extended type ID that was requested. */
@@ -966,19 +1076,11 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-
if (_isRestartable)
{
_startNode = node;
- for (node = getFirstAttribute(node); node != END;
- node = getNextAttribute(node))
- {
- if (getExpandedTypeID(node) == _nodeType)
- break;
- }
-
- _currentNode = node;
+ _currentNode = getTypedAttribute(node, _nodeType);
return resetPosition();
}
@@ -1007,10 +1109,15 @@
/**
* Iterator that returns preceding siblings of a given node
*/
- private class PrecedingSiblingIterator extends InternalAxisIteratorBase
+ public class PrecedingSiblingIterator extends InternalAxisIteratorBase
{
/**
+ * The node identity of _startNode for this iterator
+ */
+ protected int _startNodeID;
+
+ /**
* True if this iterator has a reversed axis.
*
* @return true.
@@ -1030,31 +1137,35 @@
*/
public DTMAxisIterator setStartNode(int node)
{
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isRestartable)
{
_startNode = node;
+ node = _startNodeID = makeNodeIdentity(node);
if(node == NULL)
{
_currentNode = node;
return resetPosition();
}
-
- int type = m_expandedNameTable.getType(getExpandedTypeID(node));
+
+ int type = m_expandedNameTable.getType(_exptype(node));
if(ExpandedNameTable.ATTRIBUTE == type
|| ExpandedNameTable.NAMESPACE == type )
{
_currentNode = node;
}
else
- {
- // Be careful to handle the Document
node properly
- _currentNode = getParent(node);
- if(NULL!=_currentNode)
- _currentNode =
getFirstChild(_currentNode);
- else
- _currentNode = node;
- }
+ {
+ // Be careful to handle the Document node properly
+ _currentNode = _parent(node);
+ if(NULL!=_currentNode)
+ _currentNode = _firstch(_currentNode);
+ else
+ _currentNode = node;
+ }
return resetPosition();
}
@@ -1070,16 +1181,16 @@
public int next()
{
- if (_currentNode == _startNode)
+ if (_currentNode == _startNodeID || _currentNode == DTM.NULL)
{
return NULL;
}
else
{
final int node = _currentNode;
- _currentNode = getNextSibling(node);
+ _currentNode = _nextsib(node);
- return returnNode(node);
+ return returnNode(makeNodeHandle(node));
}
}
} // end of PrecedingSiblingIterator
@@ -1088,7 +1199,7 @@
* Iterator that returns preceding siblings of a given type for
* a given node
*/
- private final class TypedPrecedingSiblingIterator
+ public final class TypedPrecedingSiblingIterator
extends PrecedingSiblingIterator
{
@@ -1113,22 +1224,48 @@
*/
public int next()
{
+ int node = _currentNode;
+ int expType;
- int node;
+ int nodeType = _nodeType;
+ int startID = _startNodeID;
- while ((node = super.next()) != NULL
- && getExpandedTypeID(node) != _nodeType){}
+ if (nodeType >= DTM.NTYPES) {
+ while (node != NULL && node != startID && _exptype(node) !=
nodeType) {
+ node = _nextsib(node);
+ }
+ } else {
+ while (node != NULL && node != startID) {
+ expType = _exptype(node);
+ if (expType < DTM.NTYPES) {
+ if (expType == nodeType) {
+ break;
+ }
+ } else {
+ if (m_expandedNameTable.getType(expType) == nodeType) {
+ break;
+ }
+ }
+ node = _nextsib(node);
+ }
+ }
- return node;
+ if (node == DTM.NULL || node == _startNodeID) {
+ _currentNode = NULL;
+ return NULL;
+ } else {
+ _currentNode = _nextsib(node);
+ return returnNode(makeNodeHandle(node));
+ }
}
- } // end of PrecedingSiblingIterator
+ } // end of TypedPrecedingSiblingIterator
/**
* Iterator that returns preceding nodes of a given node.
* This includes the node set {root+1, start-1}, but excludes
* all ancestors, attributes, and namespace nodes.
*/
- private class PrecedingIterator extends InternalAxisIteratorBase
+ public class PrecedingIterator extends InternalAxisIteratorBase
{
/** The max ancestors, but it can grow... */
@@ -1138,10 +1275,12 @@
* The stack of start node + ancestors up to the root of the tree,
* which we must avoid.
*/
- private int[] _stack = new int[_maxAncestors];
+ protected int[] _stack = new int[_maxAncestors];
/** (not sure yet... -sb) */
- private int _sp, _oldsp;
+ protected int _sp, _oldsp;
+
+ protected int _markedsp, _markedNode, _markedDescendant;
/* _currentNode precedes candidates. This is the identity, not the
handle! */
@@ -1191,7 +1330,9 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isRestartable)
{
node = makeNodeIdentity(node);
@@ -1199,8 +1340,13 @@
// iterator is not a clone
int parent, index;
+ if (_type(node) == DTM.ATTRIBUTE_NODE)
+ node = _parent(node);
+
_startNode = node;
_stack[index = 0] = node;
+
+
parent=node;
while ((parent = _parent(parent)) != NULL)
@@ -1267,6 +1413,17 @@
return resetPosition();
}
+
+ public void setMark() {
+ _markedsp = _sp;
+ _markedNode = _currentNode;
+ _markedDescendant = _stack[0];
+ }
+
+ public void gotoMark() {
+ _sp = _markedsp;
+ _currentNode = _markedNode;
+ }
} // end of PrecedingIterator
/**
@@ -1274,7 +1431,7 @@
* given node. This includes the node set {root+1, start-1}, but
* excludes all ancestors.
*/
- private final class TypedPrecedingIterator extends PrecedingIterator
+ public final class TypedPrecedingIterator extends PrecedingIterator
{
/** The extended type ID that was requested. */
@@ -1298,20 +1455,64 @@
*/
public int next()
{
+ int node = _currentNode;
+ int nodeType = _nodeType;
- int node;
+ if (nodeType >= DTM.NTYPES) {
+ while (true) {
+ node = node + 1;
+
+ if (_sp < 0) {
+ node = NULL;
+ break;
+ } else if (node >= _stack[_sp]) {
+ if (--_sp < 0) {
+ node = NULL;
+ break;
+ }
+ } else if (_exptype(node) == nodeType) {
+ break;
+ }
+ }
+ } else {
+ int expType;
- while ((node = super.next()) != NULL
- && getExpandedTypeID(node) != _nodeType){}
+ while (true) {
+ node = node + 1;
- return node;
+ if (_sp < 0) {
+ node = NULL;
+ break;
+ } else if (node >= _stack[_sp]) {
+ if (--_sp < 0) {
+ node = NULL;
+ break;
+ }
+ } else {
+ expType = _exptype(node);
+ if (expType < DTM.NTYPES) {
+ if (expType == nodeType) {
+ break;
+ }
+ } else {
+ if (m_expandedNameTable.getType(expType) == nodeType) {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ _currentNode = node;
+
+ return (node == NULL) ? NULL : returnNode(makeNodeHandle(node));
}
} // end of TypedPrecedingIterator
/**
* Iterator that returns following nodes of for a given node.
*/
- private class FollowingIterator extends InternalAxisIteratorBase
+ public class FollowingIterator extends InternalAxisIteratorBase
{
DTMAxisTraverser m_traverser; // easier for now
@@ -1330,7 +1531,9 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isRestartable)
{
_startNode = node;
@@ -1368,7 +1571,7 @@
/**
* Iterator that returns following nodes of a given type for a given node.
*/
- private final class TypedFollowingIterator extends FollowingIterator
+ public final class TypedFollowingIterator extends FollowingIterator
{
/** The extended type ID that was requested. */
@@ -1395,10 +1598,16 @@
int node;
- while ((node = super.next()) != NULL
- && getExpandedTypeID(node) != _nodeType){}
+ do{
+ node = _currentNode;
- return returnNode(node);
+ _currentNode = m_traverser.next(_startNode, _currentNode);
+
+ }
+ while (node != DTM.NULL
+ && (getExpandedTypeID(node) != _nodeType && getNodeType(node)
!= _nodeType));
+
+ return (node == DTM.NULL ? DTM.NULL :returnNode(node));
}
} // end of TypedFollowingIterator
@@ -1406,12 +1615,14 @@
* Iterator that returns the ancestors of a given node in document
* order. (NOTE! This was changed from the XSLTC code!)
*/
- private class AncestorIterator extends InternalAxisIteratorBase
+ public class AncestorIterator extends InternalAxisIteratorBase
{
org.apache.xml.utils.NodeVector m_ancestors =
new org.apache.xml.utils.NodeVector();
int m_ancestorsPos;
+
+ int m_markedPos;
/** The real start node for this axes, since _startNode will be
adjusted. */
int m_realStartNode;
@@ -1438,21 +1649,6 @@
}
/**
- * Returns the last element in this interation.
- *
- * %TBD% %BUG% This is returning a nodeHandle rather than a _position
- * value. That conflicts with what everyone else is doing. And it's
- * talking about the start node, which conflicts with some of the
- * other reverse iterators. DEFINITE BUG; needs to be reconciled.
- *
- * @return the last element in this interation.
- */
- public int getLast()
- {
- return (_startNode);
- }
-
- /**
* Returns a deep copy of this iterator. The cloned iterator is not
reset.
*
* @return a deep copy of this iterator.
@@ -1486,20 +1682,26 @@
*/
public DTMAxisIterator setStartNode(int node)
{
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
m_realStartNode = node;
if (_isRestartable)
{
- if (_includeSelf)
- _startNode = node;
- else
- _startNode = getParent(node);
+ int nodeID = makeNodeIdentity(node);
- node = _startNode;
- while (node != END)
- {
+ if (!_includeSelf && node != DTM.NULL) {
+ nodeID = _parent(nodeID);
+ node = makeNodeHandle(nodeID);
+ }
+
+ _startNode = node;
+
+ while (nodeID != END) {
m_ancestors.addElement(node);
- node = getParent(node);
+ nodeID = _parent(nodeID);
+ node = makeNodeHandle(nodeID);
}
m_ancestorsPos = m_ancestors.size()-1;
@@ -1547,12 +1749,22 @@
return returnNode(next);
}
+
+ public void setMark() {
+ m_markedPos = m_ancestorsPos;
+ }
+
+ public void gotoMark() {
+ m_ancestorsPos = m_markedPos;
+ _currentNode = m_ancestorsPos>=0 ?
m_ancestors.elementAt(m_ancestorsPos)
+ : DTM.NULL;
+ }
} // end of AncestorIterator
/**
* Typed iterator that returns the ancestors of a given node.
*/
- private final class TypedAncestorIterator extends AncestorIterator
+ public final class TypedAncestorIterator extends AncestorIterator
{
/** The extended type ID that was requested. */
@@ -1570,51 +1782,69 @@
}
/**
- * Get the next node in the iteration.
+ * Set start to END should 'close' the iterator,
+ * i.e. subsequent call to next() should return END.
*
- * @return The next node handle in the iteration, or END.
+ * @param node Sets the root of the iteration.
+ *
+ * @return A DTMAxisIterator set to the start of the iteration.
*/
- public int next()
+ public DTMAxisIterator setStartNode(int node)
{
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
+ m_realStartNode = node;
- int node;
-
- while ((node = super.next()) != NULL)
+ if (_isRestartable)
{
- if (getExpandedTypeID(node) == _nodeType)
- return returnNode(node);
- }
+ int nodeID = makeNodeIdentity(node);
+ int nodeType = _nodeType;
- return (NULL);
- }
+ if (!_includeSelf && node != DTM.NULL) {
+ nodeID = _parent(nodeID);
+ }
- /**
- * Returns the last element in this interation.
- *
- * @return the last element in this interation.
- */
- public int getLast()
- {
+ _startNode = node;
- int last = NULL;
- int curr = _startNode;
+ if (nodeType >= DTM.NTYPES) {
+ while (nodeID != END) {
+ int eType = _exptype(nodeID);
+
+ if (eType == nodeType) {
+ m_ancestors.addElement(makeNodeHandle(nodeID));
+ }
+ nodeID = _parent(nodeID);
+ }
+ } else {
+ while (nodeID != END) {
+ int eType = _exptype(nodeID);
+
+ if ((eType >= DTM.NTYPES
+ && m_expandedNameTable.getType(eType) == nodeType)
+ || (eType < DTM.NTYPES && eType == nodeType)) {
+ m_ancestors.addElement(makeNodeHandle(nodeID));
+ }
+ nodeID = _parent(nodeID);
+ }
+ }
+ m_ancestorsPos = m_ancestors.size()-1;
- while (curr != NULL)
- {
- if (getExpandedTypeID(curr) == _nodeType)
- last = curr;
+ _currentNode = (m_ancestorsPos>=0)
+ ? m_ancestors.elementAt(m_ancestorsPos)
+ : DTM.NULL;
- curr = getParent(curr);
+ return resetPosition();
}
- return (last);
+ return this;
}
} // end of TypedAncestorIterator
/**
* Iterator that returns the descendants of a given node.
*/
- private class DescendantIterator extends InternalAxisIteratorBase
+ public class DescendantIterator extends InternalAxisIteratorBase
{
/**
@@ -1627,7 +1857,9 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isRestartable)
{
node = makeNodeIdentity(node);
@@ -1660,7 +1892,7 @@
*/
protected boolean isDescendant(int identity)
{
- return (_startNode == identity) || _parent(identity) >= _startNode;
+ return (_parent(identity) >= _startNode) || (_startNode == identity);
}
/**
@@ -1670,27 +1902,55 @@
*/
public int next()
{
+ if (_startNode == NULL) {
+ return NULL;
+ }
- while (true)
- {
- int node = ++_currentNode;
- int type = _type(node);
+ if (_includeSelf && (_currentNode + 1) == _startNode)
+ return returnNode(makeNodeHandle(++_currentNode)); // |
m_dtmIdent);
- if (NULL == type ||!isDescendant(node))
- return END;
+ int node = _currentNode;
+ int type;
- if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
- continue;
+ do {
+ node++;
+ type = _type(node);
- return returnNode(makeNodeHandle(node)); // make handle.
- }
+ if (NULL == type ||!isDescendant(node)) {
+ _currentNode = NULL;
+ return END;
+ }
+ } while(ATTRIBUTE_NODE == type || TEXT_NODE == type
+ || NAMESPACE_NODE == type);
+
+ _currentNode = node;
+ return returnNode(makeNodeHandle(node)); // make handle.
}
+
+ /**
+ * Reset.
+ *
+ */
+ public DTMAxisIterator reset()
+ {
+
+ final boolean temp = _isRestartable;
+
+ _isRestartable = true;
+
+ setStartNode(makeNodeHandle(_startNode));
+
+ _isRestartable = temp;
+
+ return this;
+ }
+
} // end of DescendantIterator
/**
* Typed iterator that returns the descendants of a given node.
*/
- private final class TypedDescendantIterator extends DescendantIterator
+ public final class TypedDescendantIterator extends DescendantIterator
{
/** The extended type ID that was requested. */
@@ -1714,13 +1974,29 @@
*/
public int next()
{
-
int node;
+ int type;
+
+ if (_startNode == NULL) {
+ return NULL;
+ }
+
+ node = _currentNode;
+
+ do
+ {
+ node++;
+ type = _type(node);
- while ((node = super.next()) != NULL
- && getExpandedTypeID(node) != _nodeType){}
+ if (NULL == type ||!isDescendant(node)) {
+ _currentNode = NULL;
+ return END;
+ }
+ }
+ while (type != _nodeType && _exptype(node) != _nodeType);
- return node;
+ _currentNode = node;
+ return returnNode(makeNodeHandle(node));
}
} // end of TypedDescendantIterator
@@ -1728,7 +2004,7 @@
* Iterator that returns the descendants of a given node.
* I'm not exactly clear about this one... -sb
*/
- private class NthDescendantIterator extends DescendantIterator
+ public class NthDescendantIterator extends DescendantIterator
{
/** The current nth position. */
@@ -1784,7 +2060,7 @@
/**
* Class SingletonIterator.
*/
- private class SingletonIterator extends InternalAxisIteratorBase
+ public class SingletonIterator extends InternalAxisIteratorBase
{
/** (not sure yet what this is. -sb) (sc & sb remove final to compile
in JDK 1.1.8) */
@@ -1833,7 +2109,9 @@
*/
public DTMAxisIterator setStartNode(int node)
{
-
+//%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
+ if (node == DTMDefaultBase.ROOTNODE)
+ node = getDocument();
if (_isConstant)
{
_currentNode = _startNode;
@@ -1896,12 +2174,12 @@
return returnNode(result);
}
- }
+ } // end of SingletonIterator
/**
* Iterator that returns a given node only if it is of a given type.
*/
- private final class TypedSingletonIterator extends SingletonIterator
+ public final class TypedSingletonIterator extends SingletonIterator
{
/** The extended type ID that was requested. */
@@ -1926,9 +2204,23 @@
public int next()
{
- final int result = super.next();
+ //final int result = super.next();
+ final int result = _currentNode;
+ int nodeType = _nodeType;
+
+ _currentNode = END;
+
+ if (nodeType >= DTM.NTYPES) {
+ if (getExpandedTypeID(result) == nodeType) {
+ return returnNode(result);
+ }
+ } else {
+ if (getNodeType(result) == nodeType) {
+ return returnNode(result);
+ }
+ }
- return getExpandedTypeID(result) == _nodeType ? result : NULL;
+ return NULL;
}
} // end of TypedSingletonIterator
}
1.17 +31 -7
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBaseTraversers.java
Index: DTMDefaultBaseTraversers.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBaseTraversers.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- DTMDefaultBaseTraversers.java 20 Mar 2003 20:57:58 -0000 1.16
+++ DTMDefaultBaseTraversers.java 1 Apr 2003 19:14:04 -0000 1.17
@@ -56,17 +56,14 @@
*/
package org.apache.xml.dtm.ref;
+import org.apache.xml.dtm.*;
+
import javax.xml.transform.Source;
-import org.apache.xml.dtm.Axis;
-import org.apache.xml.dtm.DTM;
-import org.apache.xml.dtm.DTMAxisTraverser;
-import org.apache.xml.dtm.DTMException;
-import org.apache.xml.dtm.DTMManager;
-import org.apache.xml.dtm.DTMWSFilter;
+import org.apache.xml.utils.XMLStringFactory;
+
import org.apache.xml.res.XMLErrorResources;
import org.apache.xml.res.XMLMessages;
-import org.apache.xml.utils.XMLStringFactory;
/**
@@ -101,6 +98,33 @@
{
super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
doIndexing);
+ }
+
+ /**
+ * Construct a DTMDefaultBaseTraversers object from a DOM node.
+ *
+ * @param mgr The DTMManager who owns this DTM.
+ * @param domSource the DOM source that this DTM will wrap.
+ * @param source The object that is used to specify the construction
source.
+ * @param dtmIdentity The DTM identity ID for this DTM.
+ * @param whiteSpaceFilter The white space filter for this DTM, which may
+ * be null.
+ * @param xstringfactory The factory to use for creating XMLStrings.
+ * @param doIndexing true if the caller considers it worth it to use
+ * indexing schemes.
+ * @param blocksize The block size of the DTM.
+ * @param usePrevsib true if we want to build the previous sibling node
array.
+ */
+ public DTMDefaultBaseTraversers(DTMManager mgr, Source source,
+ int dtmIdentity,
+ DTMWSFilter whiteSpaceFilter,
+ XMLStringFactory xstringfactory,
+ boolean doIndexing,
+ int blocksize,
+ boolean usePrevsib)
+ {
+ super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
+ doIndexing, blocksize, usePrevsib);
}
/**
1.10 +1 -1
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDocumentImpl.java
Index: DTMDocumentImpl.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDocumentImpl.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- DTMDocumentImpl.java 30 Jan 2003 18:46:17 -0000 1.9
+++ DTMDocumentImpl.java 1 Apr 2003 19:14:04 -0000 1.10
@@ -179,7 +179,7 @@
// retrieve them each time. Or this needs to be
// an interface _implemented_ by this class... which might be
simplest!
private ExpandedNameTable m_expandedNames=
- new ExpandedNameTable(m_localNames,m_nsNames);
+ new ExpandedNameTable();
private XMLStringFactory m_xsf;
1.46 +1 -1
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMManagerDefault.java
Index: DTMManagerDefault.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMManagerDefault.java,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -r1.45 -r1.46
--- DTMManagerDefault.java 3 Feb 2003 20:48:12 -0000 1.45
+++ DTMManagerDefault.java 1 Apr 2003 19:14:05 -0000 1.46
@@ -368,7 +368,7 @@
// If the reader is null, but they still requested an incremental
build,
// then we still want to set up the IncrementalSAXSource stuff.
- if (this.m_incremental && incremental /* || ((null == reader) &&
incremental) */)
+ if (m_incremental && incremental /* || ((null == reader) &&
incremental) */)
{
IncrementalSAXSource coParser=null;
1.6 +1 -1
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMNamedNodeMap.java
Index: DTMNamedNodeMap.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMNamedNodeMap.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- DTMNamedNodeMap.java 30 Jan 2003 18:46:17 -0000 1.5
+++ DTMNamedNodeMap.java 1 Apr 2003 19:14:05 -0000 1.6
@@ -95,7 +95,7 @@
* @param dtm The DTM Reference, must be non-null.
* @param element The DTM element handle.
*/
- DTMNamedNodeMap(DTM dtm, int element)
+ public DTMNamedNodeMap(DTM dtm, int element)
{
this.dtm = dtm;
this.element = element;
1.10 +49 -84
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMNodeList.java
Index: DTMNodeList.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMNodeList.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- DTMNodeList.java 30 Jan 2003 18:46:17 -0000 1.9
+++ DTMNodeList.java 1 Apr 2003 19:14:05 -0000 1.10
@@ -89,64 +89,47 @@
*
* <p>State: In progress!!</p>
* */
-public class DTMNodeList implements org.w3c.dom.NodeList
-{
- private DTMIterator dtm_iter;
- private boolean valid=true;
- private int m_firstChild;
- private DTM m_parentDTM;
-
- //================================================================
- // Methods unique to this class
-
- /** Public constructor: Wrap a DTMNodeList around an existing
- * and preconfigured DTMIterator
- *
- * WARNING: THIS HAS THE SIDE EFFECT OF ISSUING setShouldCacheNodes(true)
- * AGAINST THE DTMIterator.
- * */
- public DTMNodeList(DTMIterator dtmIterator)
- {
- int pos = dtmIterator.getCurrentPos();
- try
- {
- dtm_iter=(DTMIterator)dtmIterator.cloneWithReset();
- }
- catch(CloneNotSupportedException cnse) {}
- dtm_iter.setShouldCacheNodes(true);
- dtm_iter.runTo(-1);
- dtm_iter.setCurrentPos(pos);
+public class DTMNodeList extends DTMNodeListBase {
+ private DTMIterator m_iter;
+
+ //================================================================
+ // Methods unique to this class
+ private DTMNodeList() {
+ }
+
+ /**
+ * Public constructor: Wrap a DTMNodeList around an existing
+ * and preconfigured DTMIterator
+ *
+ * WARNING: THIS HAS THE SIDE EFFECT OF ISSUING setShouldCacheNodes(true)
+ * AGAINST THE DTMIterator.
+ *
+ */
+ public DTMNodeList(DTMIterator dtmIterator) {
+ if (dtmIterator != null) {
+ int pos = dtmIterator.getCurrentPos();
+ try {
+ m_iter=(DTMIterator)dtmIterator.cloneWithReset();
+ } catch(CloneNotSupportedException cnse) {
+ m_iter = dtmIterator;
+ }
+ m_iter.setShouldCacheNodes(true);
+ m_iter.runTo(-1);
+ m_iter.setCurrentPos(pos);
+ }
}
- /** Public constructor: Create a NodeList to support
- * DTMNodeProxy.getChildren().
- *
- * Unfortunately AxisIterators and DTMIterators don't share an API,
- * so I can't use the existing Axis.CHILD iterator. Rather than
- * create Yet Another Class, let's set up a special case of this
- * one.
- *
- * @param parentDTM The DTM containing this node
- * @param parentHandle DTM node-handle integer
- * */
- public DTMNodeList(DTM parentDTM,int parentHandle)
- {
- dtm_iter=null;
- m_parentDTM=parentDTM;
- m_firstChild=parentDTM.getFirstChild(parentHandle);
- }
-
- /** Access the wrapped DTMIterator. I'm not sure whether anyone will
- * need this or not, but let's write it and think about it.
- * */
- public DTMIterator getDTMIterator()
- {
- return dtm_iter;
- }
-
+ /**
+ * Access the wrapped DTMIterator. I'm not sure whether anyone will
+ * need this or not, but let's write it and think about it.
+ *
+ */
+ public DTMIterator getDTMIterator() {
+ return m_iter;
+ }
- //================================================================
- // org.w3c.dom.NodeList API follows
+ //================================================================
+ // org.w3c.dom.NodeList API follows
/**
* Returns the <code>index</code>th item in the collection. If
@@ -159,40 +142,22 @@
*/
public Node item(int index)
{
- if(dtm_iter!=null)
- {
- int handle=dtm_iter.item(index);
- if (handle == DTM.NULL) return null;
- return dtm_iter.getDTM(handle).getNode(handle);
- }
- else
- {
- int handle=m_firstChild;
- while(--index>=0 && handle!=DTM.NULL)
- handle=m_parentDTM.getNextSibling(handle);
- if (handle == DTM.NULL) return null;
- return m_parentDTM.getNode(handle);
- }
+ if (m_iter != null) {
+ int handle=m_iter.item(index);
+ if (handle == DTM.NULL) {
+ return null;
+ }
+ return m_iter.getDTM(handle).getNode(handle);
+ } else {
+ return null;
+ }
}
/**
* The number of nodes in the list. The range of valid child node
indices
* is 0 to <code>length-1</code> inclusive.
*/
- public int getLength()
- {
- if(dtm_iter!=null)
- {
- return dtm_iter.getLength();
- }
- else
- {
- int count=0;
- for(int handle=m_firstChild;
- handle!=DTM.NULL;
- handle=m_parentDTM.getNextSibling(handle))
- ++count;
- return count;
- }
+ public int getLength() {
+ return (m_iter != null) ? m_iter.getLength() : 0;
}
}
1.17 +8 -8
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMNodeProxy.java
Index: DTMNodeProxy.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMNodeProxy.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- DTMNodeProxy.java 30 Jan 2003 18:46:17 -0000 1.16
+++ DTMNodeProxy.java 1 Apr 2003 19:14:05 -0000 1.17
@@ -109,7 +109,7 @@
* @param dtm The DTM Reference, must be non-null.
* @param node The DTM node handle.
*/
- DTMNodeProxy(DTM dtm, int node)
+ public DTMNodeProxy(DTM dtm, int node)
{
this.dtm = dtm;
this.node = node;
@@ -392,7 +392,7 @@
// Annoyingly, AxisIterators do not currently implement DTMIterator, so
// we can't just wap DTMNodeList around an Axis.CHILD iterator.
// Instead, we've created a special-case operating mode for that object.
- return new DTMNodeList(dtm,node);
+ return new DTMChildIterNodeList(dtm,node);
// throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
}
@@ -616,17 +616,17 @@
public final Element getDocumentElement()
{
int dochandle=dtm.getDocument();
- int elementhandle=dtm.NULL;
+ int elementhandle=DTM.NULL;
for(int kidhandle=dtm.getFirstChild(dochandle);
- kidhandle!=dtm.NULL;
+ kidhandle!=DTM.NULL;
kidhandle=dtm.getNextSibling(kidhandle))
{
switch(dtm.getNodeType(kidhandle))
{
case Node.ELEMENT_NODE:
- if(elementhandle!=dtm.NULL)
+ if(elementhandle!=DTM.NULL)
{
- elementhandle=dtm.NULL; // More than
one; ill-formed.
+ elementhandle=DTM.NULL; // More than
one; ill-formed.
kidhandle=dtm.getLastChild(dochandle);
// End loop
}
else
@@ -640,12 +640,12 @@
break;
default:
- elementhandle=dtm.NULL; // ill-formed
+ elementhandle=DTM.NULL; // ill-formed
kidhandle=dtm.getLastChild(dochandle); // End
loop
break;
}
}
- if(elementhandle==dtm.NULL)
+ if(elementhandle==DTM.NULL)
throw new
DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
else
return (Element)(dtm.getNode(elementhandle));
1.7 +12 -4
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMStringPool.java
Index: DTMStringPool.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMStringPool.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- DTMStringPool.java 30 Jan 2003 18:46:17 -0000 1.6
+++ DTMStringPool.java 1 Apr 2003 19:14:05 -0000 1.7
@@ -57,8 +57,6 @@
package org.apache.xml.dtm.ref;
-// %REVIEW% Should this be based on SuballocatedIntVector instead?
-// (Unclear. Pools will rarely be huge. But if they ever are...)
import java.util.Vector;
import org.apache.xml.utils.IntVector;
@@ -100,16 +98,26 @@
IntVector m_hashChain;
public static final int NULL=-1;
- public DTMStringPool()
+ /**
+ * Create a DTMStringPool using the given chain size
+ *
+ * @param chainSize The size of the hash chain vector
+ */
+ public DTMStringPool(int chainSize)
{
m_intToString=new Vector();
- m_hashChain=new IntVector(512);
+ m_hashChain=new IntVector(chainSize);
removeAllElements();
// -sb Add this to force empty strings to be index 0.
stringToIndex("");
}
+ public DTMStringPool()
+ {
+ this(512);
+ }
+
public void removeAllElements()
{
m_intToString.removeAllElements();
1.10 +194 -158
xml-xalan/java/src/org/apache/xml/dtm/ref/ExpandedNameTable.java
Index: ExpandedNameTable.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/ExpandedNameTable.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- ExpandedNameTable.java 30 Jan 2003 18:46:17 -0000 1.9
+++ ExpandedNameTable.java 1 Apr 2003 19:14:05 -0000 1.10
@@ -56,38 +56,32 @@
*/
package org.apache.xml.dtm.ref;
-import java.util.Hashtable;
-import java.util.Vector;
-
import org.apache.xml.dtm.DTM;
/**
* This is a default implementation of a table that manages mappings from
* expanded names to expandedNameIDs.
*
- * %REVIEW% Note that this is not really a separate table, or a
- * separate pool. Instead, it's an access method build on top of the
- * existing pools, using three pieces of information: the index
- * numbers for a node's namespaceURI, localName, and node type, which
- * are combined to yield a composite index number.
- *
- * %TBD% startup sequence -- how this gets access to the appropriate
- * string pools in the DTMDocument/stylesheet.
- *
- * */
+ * %OPT% The performance of the getExpandedTypeID() method is very important
+ * to DTM building. To get the best performance out of this class, we
implement
+ * a simple hash algorithm directly into this class, instead of using the
+ * inefficient java.util.Hashtable. The code for the get and put operations
+ * are combined in getExpandedTypeID() method to share the same hash
calculation
+ * code. We only need to implement the rehash() interface which is used to
+ * expand the hash table.
+ */
public class ExpandedNameTable
{
- /** Probably a reference to static pool. */
- //private DTMStringPool m_locNamesPool;
-
- /** Probably a reference to static pool. */
- //private DTMStringPool m_namespaceNames;
-
- /** Vector of extended types for this document */
- private /*static*/ Vector m_extendedTypes;
+ /** Array of extended types for this document */
+ private ExtendedType[] m_extendedTypes;
+ /** The initial size of the m_extendedTypes array */
+ private static int m_initialSize = 128;
+
/** Next available extended type */
+ // %REVIEW% Since this is (should be) always equal
+ // to the length of m_extendedTypes, do we need this?
private int m_nextType;
// These are all the types prerotated, for caller convenience.
@@ -105,109 +99,181 @@
public static final int NOTATION = ((int)DTM.NOTATION_NODE) ;
public static final int NAMESPACE = ((int)DTM.NAMESPACE_NODE) ;
- Hashtable m_hashtable = new Hashtable();
-
/** Workspace for lookup. NOT THREAD SAFE!
* */
- ExtendedType hashET=new ExtendedType(-1,"","");
+ ExtendedType hashET = new ExtendedType(-1, "", "");
- private static Hashtable m_defaultHashtable;
- private static Vector m_defaultExtendedTypes;
+ /** The array to store the default extended types. */
+ private static ExtendedType[] m_defaultExtendedTypes;
/**
- * Init default vales
+ * The default load factor of the Hashtable.
+ * This is used to calcualte the threshold.
+ */
+ private static float m_loadFactor = 0.75f;
+
+ /**
+ * The initial capacity of the hash table. Use a bigger number
+ * to avoid the cost of expanding the table.
+ */
+ private static int m_initialCapacity = 203;
+
+ /**
+ * The capacity of the hash table, i.e. the size of the
+ * internal HashEntry array.
+ */
+ private int m_capacity;
+
+ /**
+ * The threshold of the hash table, which is equal to capacity *
loadFactor.
+ * If the number of entries in the hash table is bigger than the threshold,
+ * the hash table needs to be expanded.
+ */
+ private int m_threshold;
+
+ /**
+ * The internal array to store the hash entries.
+ * Each array member is a slot for a hash bucket.
+ */
+ private HashEntry[] m_table;
+
+ /**
+ * Init default values
*/
static {
- // use bigger values than default, to avoid reallocation in the future
- m_defaultExtendedTypes = new Vector(23);
- m_defaultHashtable = new Hashtable(23, 0.75f);
+ m_defaultExtendedTypes = new ExtendedType[DTM.NTYPES];
for (int i = 0; i < DTM.NTYPES; i++)
{
- ExtendedType newET = new ExtendedType(i, "", "");
- m_defaultExtendedTypes.addElement(newET);
- m_defaultHashtable.put(newET, new Integer(i));
+ m_defaultExtendedTypes[i] = new ExtendedType(i, "", "");
}
}
/**
- * Create an expanded name table that uses private string pool lookup.
+ * Create an expanded name table.
*/
public ExpandedNameTable()
{
- //m_locNamesPool = new DTMSafeStringPool();
- //m_namespaceNames = new DTMSafeStringPool();
+ m_capacity = m_initialCapacity;
+ m_threshold = (int)(m_capacity * m_loadFactor);
+ m_table = new HashEntry[m_capacity];
+
initExtendedTypes();
}
- /**
- * Constructor ExpandedNameTable
- *
- * @param locNamesPool Local element names lookup.
- * @param namespaceNames Namespace values lookup.
- */
- public ExpandedNameTable(DTMStringPool locNamesPool,
- DTMStringPool namespaceNames)
- {
- //m_locNamesPool = locNamesPool;
- //m_namespaceNames = namespaceNames;
- initExtendedTypes();
- }
/**
* Initialize the vector of extended types with the
* basic DOM node types.
*/
private void initExtendedTypes()
- {
- // Since objects in the Vector a m_extendedTypes and m_hashtable are
never changed
- // it should be safe to copy default tables
- m_extendedTypes = (Vector)m_defaultExtendedTypes.clone();
- m_hashtable = (Hashtable)m_defaultHashtable.clone();
- m_nextType = m_extendedTypes.size();
+ {
+ m_extendedTypes = new ExtendedType[m_initialSize];
+ for (int i = 0; i < DTM.NTYPES; i++) {
+ m_extendedTypes[i] = m_defaultExtendedTypes[i];
+ m_table[i] = new HashEntry(m_defaultExtendedTypes[i], i, i, null);
+ }
+
+ m_nextType = DTM.NTYPES;
}
/**
- * Given an expanded name, return an ID. If the expanded-name does not
- * exist in the internal tables, the entry will be created, and the ID will
- * be returned. Any additional nodes that are created that have this
- * expanded name will use this ID.
+ * Given an expanded name represented by namespace, local name and node
type,
+ * return an ID. If the expanded-name does not exist in the internal
tables,
+ * the entry will be created, and the ID will be returned. Any additional
+ * nodes that are created that have this expanded name will use this ID.
*
- * @param namespace
- * @param localName
+ * @param namespace The namespace
+ * @param localName The local name
+ * @param type The node type
*
* @return the expanded-name id of the node.
*/
public int getExpandedTypeID(String namespace, String localName, int type)
{
- /*int nsID = (null != namespace) ?
m_namespaceNames.stringToIndex(namespace) : 0;
- int lnID = m_locNamesPool.stringToIndex(localName);
-
- int expandedTypeID = (type << (BITS_PER_NAMESPACE+BITS_PER_LOCALNAME))
- | (nsID << BITS_PER_LOCALNAME) | lnID;
- return expandedTypeID;
-*/
if (null == namespace)
namespace = "";
if (null == localName)
localName = "";
- // Set our reusable ExpandedType so we can look
- // it up in the hashtable. Not threadsafe, but
- // avoids creating a new object until we know
- // this isn't one we've seen before.
- hashET.redefine(type,namespace,localName);
-
- Object eType;
- if ((eType = m_hashtable.get(hashET)) != null )
- return ((Integer)eType).intValue();
-
- ExtendedType newET=new ExtendedType(type, namespace, localName);
- m_extendedTypes.addElement(newET);
- m_hashtable.put(newET, new Integer(m_nextType));
+
+ // Calculate the hash code
+ int hash = type + namespace.hashCode() + localName.hashCode();
+
+ // Redefine the hashET object to represent the new expanded name.
+ hashET.redefine(type, namespace, localName, hash);
+
+ // Calculate the index into the HashEntry table.
+ int index = hash % m_capacity;
+ if (index < 0)
+ index = -index;
+
+ // Look up the expanded name in the hash table. Return the id if
+ // the expanded name is already in the hash table.
+ for (HashEntry e = m_table[index]; e != null; e = e.next)
+ {
+ if (e.hash == hash && e.key.equals(hashET))
+ return e.value;
+ }
+
+ // Expand the internal HashEntry array if necessary.
+ if (m_nextType > m_threshold)
+ rehash();
+
+ // Create a new ExtendedType object
+ ExtendedType newET = new ExtendedType(type, namespace, localName, hash);
+
+ // Expand the m_extendedTypes array if necessary.
+ if (m_extendedTypes.length == m_nextType) {
+ ExtendedType[] newArray = new ExtendedType[m_extendedTypes.length *
2];
+ System.arraycopy(m_extendedTypes, 0, newArray, 0,
+ m_extendedTypes.length);
+ m_extendedTypes = newArray;
+ }
+
+ m_extendedTypes[m_nextType] = newET;
+
+ // Create a new hash entry for the new ExtendedType and put it into
+ // the table.
+ HashEntry entry = new HashEntry(newET, m_nextType, hash, m_table[index]);
+ m_table[index] = entry;
+
return m_nextType++;
}
/**
+ * Increases the capacity of and internally reorganizes the hashtable,
+ * in order to accommodate and access its entries more efficiently.
+ * This method is called when the number of keys in the hashtable exceeds
+ * this hashtable's capacity and load factor.
+ */
+ private void rehash()
+ {
+ int oldCapacity = m_capacity;
+ HashEntry[] oldTable = m_table;
+
+ int newCapacity = 2 * oldCapacity + 1;
+ m_capacity = newCapacity;
+ m_threshold = (int)(newCapacity * m_loadFactor);
+
+ m_table = new HashEntry[newCapacity];
+ for (int i = oldCapacity-1; i >=0 ; i--)
+ {
+ for (HashEntry old = oldTable[i]; old != null; )
+ {
+ HashEntry e = old;
+ old = old.next;
+
+ int newIndex = e.hash % newCapacity;
+ if (newIndex < 0)
+ newIndex = -newIndex;
+
+ e.next = m_table[newIndex];
+ m_table[newIndex] = e;
+ }
+ }
+ }
+
+ /**
* Given a type, return an expanded name ID.Any additional nodes that are
* created that have this expanded name will use this ID.
*
@@ -229,9 +295,7 @@
*/
public String getLocalName(int ExpandedNameID)
{
- //return m_locNamesPool.indexToString(ExpandedNameID & MASK_LOCALNAME);
- ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt
(ExpandedNameID);
- return etype.localName;
+ return m_extendedTypes[ExpandedNameID].getLocalName();
}
/**
@@ -240,11 +304,10 @@
* @param ExpandedNameID an ID that represents an expanded-name.
* @return The id of this local name.
*/
- public /*static*/ final int getLocalNameID(int ExpandedNameID)
+ public final int getLocalNameID(int ExpandedNameID)
{
- //return (ExpandedNameID & MASK_LOCALNAME);
- ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt
(ExpandedNameID);
- if (etype.localName.equals(""))
+ // ExtendedType etype = m_extendedTypes[ExpandedNameID];
+ if (m_extendedTypes[ExpandedNameID].getLocalName().equals(""))
return 0;
else
return ExpandedNameID;
@@ -260,11 +323,8 @@
*/
public String getNamespace(int ExpandedNameID)
{
-
- //int id = (ExpandedNameID & MASK_NAMESPACE) >> BITS_PER_LOCALNAME;
- //return (0 == id) ? null : m_namespaceNames.indexToString(id);
- ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt
(ExpandedNameID);
- return (etype.namespace.equals("") ? null : etype.namespace);
+ String namespace = m_extendedTypes[ExpandedNameID].getNamespace();
+ return (namespace.equals("") ? null : namespace);
}
/**
@@ -273,11 +333,10 @@
* @param ExpandedNameID an ID that represents an expanded-name.
* @return The id of this namespace.
*/
- public /*static*/ final int getNamespaceID(int ExpandedNameID)
+ public final int getNamespaceID(int ExpandedNameID)
{
- //return (ExpandedNameID & MASK_NAMESPACE) >> BITS_PER_LOCALNAME;
- ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt
(ExpandedNameID);
- if (etype.namespace.equals(""))
+ //ExtendedType etype = m_extendedTypes[ExpandedNameID];
+ if (m_extendedTypes[ExpandedNameID].getNamespace().equals(""))
return 0;
else
return ExpandedNameID;
@@ -291,72 +350,49 @@
*/
public final short getType(int ExpandedNameID)
{
- //return (short)(ExpandedNameID >> ROTAMOUNT_TYPE);
- ExtendedType etype = (ExtendedType)m_extendedTypes.elementAt
(ExpandedNameID);
- return (short)etype.nodetype;
+ //ExtendedType etype = m_extendedTypes[ExpandedNameID];
+ return (short)m_extendedTypes[ExpandedNameID].getNodeType();
}
-
-
+
/**
- * Private class representing an extended type object
+ * Return the size of the ExpandedNameTable
+ *
+ * @return The size of the ExpandedNameTable
*/
- private static class ExtendedType
+ public int getSize()
{
- protected int nodetype;
- protected String namespace;
- protected String localName;
- protected int hash;
-
- protected ExtendedType (int nodetype, String namespace, String localName)
- {
- this.nodetype = nodetype;
- this.namespace = namespace;
- this.localName = localName;
- this.hash=nodetype+namespace.hashCode()+localName.hashCode();
- }
-
- /* This is intended to be used ONLY on the hashET
- * object. Using it elsewhere will mess up existing
- * hashtable entries!
- * */
- protected void redefine(int nodetype, String namespace, String localName)
- {
- this.nodetype = nodetype;
- this.namespace = namespace;
- this.localName = localName;
- this.hash=nodetype+namespace.hashCode()+localName.hashCode();
- }
-
- /* Override super method
- * */
- public int hashCode()
- {
- return hash;
- }
+ return m_nextType;
+ }
+
+ /**
+ * Return the array of extended types
+ *
+ * @return The array of extended types
+ */
+ public ExtendedType[] getExtendedTypes()
+ {
+ return m_extendedTypes;
+ }
- /* Override super method
- * */
- public boolean equals(Object other)
+ /**
+ * Inner class which represents a hash table entry.
+ * The field next points to the next entry which is hashed into
+ * the same bucket in the case of "hash collision".
+ */
+ private static final class HashEntry
+ {
+ ExtendedType key;
+ int value;
+ int hash;
+ HashEntry next;
+
+ protected HashEntry(ExtendedType key, int value, int hash, HashEntry
next)
{
- //Usually an optimization, but
- // won't arise in our usage:
- //if(other==this) return true;
- try
- {
- ExtendedType et=(ExtendedType)other;
- return et.nodetype==this.nodetype &&
- et.localName.equals(this.localName) &&
- et.namespace.equals(this.namespace);
- }
- catch(ClassCastException e)
- {
- return false;
- }
- catch(NullPointerException e)
- {
- return false;
- }
+ this.key = key;
+ this.value = value;
+ this.hash = hash;
+ this.next = next;
}
}
-
-}
+
+}
\ No newline at end of file
1.12 +3 -3
xml-xalan/java/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Xerces.java
Index: IncrementalSAXSource_Xerces.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Xerces.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- IncrementalSAXSource_Xerces.java 30 Jan 2003 18:46:17 -0000 1.11
+++ IncrementalSAXSource_Xerces.java 1 Apr 2003 19:14:05 -0000 1.12
@@ -134,14 +134,14 @@
Class me=this.getClass();
// If we can't get the magic constructor, no need to
look further.
- Class
xniConfigClass=me.forName("org.apache.xerces.xni.parser.XMLParserConfiguration");
+ Class
xniConfigClass=Class.forName("org.apache.xerces.xni.parser.XMLParserConfiguration");
Class[] args1={xniConfigClass};
Constructor ctor=SAXParser.class.getConstructor(args1);
// Build the parser configuration object.
StandardParserConfiguration
// happens to implement XMLPullParserConfiguration,
which is the API
// we're going to want to use.
- Class
xniStdConfigClass=me.forName("org.apache.xerces.parsers.StandardParserConfiguration");
+ Class
xniStdConfigClass=Class.forName("org.apache.xerces.parsers.StandardParserConfiguration");
fPullParserConfig=xniStdConfigClass.newInstance();
Object[] args2={fPullParserConfig};
fIncrementalParser = (SAXParser)ctor.newInstance(args2);
@@ -149,7 +149,7 @@
// Preload all the needed the configuration methods...
I want to know they're
// all here before we commit to trying to use them,
just in case the
// API changes again.
- Class
fXniInputSourceClass=me.forName("org.apache.xerces.xni.parser.XMLInputSource");
+ Class
fXniInputSourceClass=Class.forName("org.apache.xerces.xni.parser.XMLInputSource");
Class[] args3={fXniInputSourceClass};
fConfigSetInput=xniStdConfigClass.getMethod("setInputSource",args3);
1.2 +178 -0
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMAxisIterNodeList.java
1.2 +155 -0
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMChildIterNodeList.java
1.2 +117 -0
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMNodeListBase.java
1.2 +181 -0
xml-xalan/java/src/org/apache/xml/dtm/ref/ExtendedType.java
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]