sboag 01/04/17 08:59:43
Modified: java/src/org/apache/xml/dtm/dom2dtm Tag: DTM_EXP
DOM2DTM.java
Log:
Periodic check-in. Class is almost functional, but has bugs which
I am working on. Some methods have not yet been implemented.
Revision Changes Path
No revision
No revision
1.1.2.3 +599 -113
xml-xalan/java/src/org/apache/xml/dtm/dom2dtm/Attic/DOM2DTM.java
Index: DOM2DTM.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/dom2dtm/Attic/DOM2DTM.java,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- DOM2DTM.java 2001/04/13 14:46:23 1.1.2.2
+++ DOM2DTM.java 2001/04/17 15:59:40 1.1.2.3
@@ -59,11 +59,17 @@
import org.apache.xml.dtm.*;
import org.apache.xml.utils.IntVector;
import org.apache.xml.utils.IntStack;
+import org.apache.xml.utils.StringBufferPool;
+import org.apache.xml.utils.FastStringBuffer;
+import org.apache.xml.utils.TreeWalker;
import org.w3c.dom.*;
import java.util.Vector;
+import javax.xml.transform.dom.DOMSource;
+import org.xml.sax.ContentHandler;
+
/**
* The <code>DOM2DTM</code> class serves up a DOM via a DTM API.
*/
@@ -86,36 +92,39 @@
// Offsets into each set of integers in the <code>m_info</code> table.
+ /** %TBD% Doc */
+ static final int OFFSET_EXPANDEDNAMEID = 0;
+
/** %TBD% Doc */
- static final int OFFSET_TYPE = 0;
+ static final int OFFSET_TYPE = 1;
/** %TBD% Doc */
- static final int OFFSET_LEVEL = 1;
+ static final int OFFSET_LEVEL = 2;
/** %TBD% Doc */
- static final int OFFSET_FIRSTCHILD = 2;
+ static final int OFFSET_FIRSTCHILD = 3;
/** %TBD% Doc */
- static final int OFFSET_NEXTSIBLING = 3;
+ static final int OFFSET_NEXTSIBLING = 4;
/** %TBD% Doc */
- static final int OFFSET_PREVSIBLING = 4;
+ static final int OFFSET_PREVSIBLING = 5;
/** %TBD% Doc */
- static final int OFFSET_PARENT = 5;
+ static final int OFFSET_PARENT = 6;
/**
* This represents the number of integers per node in the
* <code>m_info</code> member variable.
*/
- static final int NODEINFOBLOCKSIZE = 5;
+ static final int NODEINFOBLOCKSIZE = 7;
/**
* The value to use when the information has not been built yet.
*/
static final int NOTPROCESSED = DTM.NULL - 1;
- /** NEEDSDOC Field NODEIDENTITYBITS */
+ /** NEEDSDOC Field NODEIDENTITYBITS */
static final int NODEIDENTITYBITS = 0x000FFFFF;
/**
@@ -129,23 +138,28 @@
/** %TBD% Doc */
protected int m_mask;
+ /** %TBD% Doc */
+ protected String m_documentBaseURI;
+
/**
* Construct a DOM2DTM object from a DOM node.
*
* NEEDSDOC @param mgr
* NEEDSDOC @param node
+ * NEEDSDOC @param domSource
*/
- public DOM2DTM(DTMManager mgr, Node node)
+ public DOM2DTM(DTMManager mgr, DOMSource domSource, int dtmIdentity)
{
m_mgr = mgr;
- m_root = node;
+ m_root = domSource.getNode();
+ m_documentBaseURI = domSource.getSystemId();
m_pos = null;
m_nodesAreProcessed = false;
- m_dtmIdent = m_mgr.getDTMIdentity(this);
- m_mask = m_mgr.getNodeIdentityMask();
+ m_dtmIdent = dtmIdentity;
+ m_mask = mgr.getNodeIdentityMask();
- addNode(node, 0, DTM.NULL, DTM.NULL);
+ addNode(m_root, 0, DTM.NULL, DTM.NULL);
}
/**
@@ -170,20 +184,39 @@
m_info.addElements(NODEINFOBLOCKSIZE);
m_info.setElementAt(level, startInfo + OFFSET_LEVEL);
+
int type = node.getNodeType();
- if(Node.ATTRIBUTE_NODE == type)
+
+ if (Node.ATTRIBUTE_NODE == type)
{
String name = node.getNodeName();
- if(name.startsWith("xmlns:") || name.equals("xmlns"))
+
+ if (name.startsWith("xmlns:") || name.equals("xmlns"))
{
type = DTM.NAMESPACE_NODE;
}
}
+
m_info.setElementAt(type, startInfo + OFFSET_TYPE);
m_info.setElementAt(NOTPROCESSED, startInfo + OFFSET_FIRSTCHILD);
m_info.setElementAt(NOTPROCESSED, startInfo + OFFSET_NEXTSIBLING);
m_info.setElementAt(previousSibling, startInfo + OFFSET_PREVSIBLING);
m_info.setElementAt(parentIndex, startInfo + OFFSET_PARENT);
+
+ if(DTM.NULL != parentIndex && type != DTM.ATTRIBUTE_NODE && type !=
DTM.NAMESPACE_NODE)
+ {
+ int startParentInfo = parentIndex * NODEINFOBLOCKSIZE;
+ if(NOTPROCESSED == m_info.elementAt(startParentInfo +
OFFSET_FIRSTCHILD))
+ {
+ m_info.setElementAt(nodeIndex, startParentInfo + OFFSET_FIRSTCHILD);
+ }
+ }
+
+ String nsURI = node.getNamespaceURI();
+ String localName = node.getLocalName();
+ int expandedNameID
+ = m_mgr.getExpandedNameTable(this).getExpandedNameID(nsURI,
localName);
+ m_info.setElementAt(expandedNameID, startInfo + OFFSET_EXPANDEDNAMEID);
if (DTM.NULL != previousSibling)
{
@@ -221,14 +254,17 @@
*/
transient private int m_attrsPos;
- /** NEEDSDOC Field LEVELINFO_PARENT */
+ /** NEEDSDOC Field LEVELINFO_PARENT */
static final int LEVELINFO_PARENT = 1;
- /** NEEDSDOC Field LEVELINFO_PREVSIB */
+ /** NEEDSDOC Field LEVELINFO_PREVSIB */
static final int LEVELINFO_PREVSIB = 0;
- /** NEEDSDOC Field LEVELINFO_NPERLEVEL */
+ /** NEEDSDOC Field LEVELINFO_NPERLEVEL */
static final int LEVELINFO_NPERLEVEL = 2;
+
+ /** Samed element for attribute iteration */
+ private Node m_elementForAttrs;
/**
* This method iterates to the next node that will be added to the table.
@@ -254,6 +290,9 @@
Node nextNode;
int type = pos.getNodeType();
+ int currentIndexHandle = m_nodes.size()-1;
+ int posInfo = currentIndexHandle * NODEINFOBLOCKSIZE;
+
if (Node.ELEMENT_NODE == type)
{
m_attrs = pos.getAttributes();
@@ -262,42 +301,48 @@
if (null != m_attrs)
{
if (m_attrsPos < m_attrs.getLength())
+ {
+ m_elementForAttrs = pos;
nextNode = m_attrs.item(m_attrsPos);
+ }
else
- nextNode = null;
+ nextNode = pos.getFirstChild();
}
else
- nextNode = null;
+ nextNode = pos.getFirstChild();
}
else if (Node.ATTRIBUTE_NODE == type)
{
+ m_info.setElementAt(DTM.NULL, posInfo + OFFSET_FIRSTCHILD);
m_attrsPos++;
if (m_attrsPos < m_attrs.getLength())
nextNode = m_attrs.item(m_attrsPos);
else
{
- nextNode = null;
+ m_info.setElementAt(DTM.NULL, posInfo + OFFSET_NEXTSIBLING);
+ pos = m_elementForAttrs;
+ nextNode = pos.getFirstChild();
m_levelInfo.quickPop(LEVELINFO_NPERLEVEL);
}
}
else
- nextNode = null;
-
- if (null == nextNode)
- nextNode = pos.getFirstChild();
+ nextNode = pos.getFirstChild();
if (null != nextNode)
{
- int currentIndexHandle = m_nodes.size();
-
- m_levelInfo.push(currentIndexHandle);
- m_levelInfo.push(DTM.NULL);
+ m_levelInfo.push(currentIndexHandle); // parent
+ m_levelInfo.push(DTM.NULL); // previous sibling
}
while (null == nextNode)
{
+ if(m_info.elementAt(posInfo + OFFSET_FIRSTCHILD) == NOTPROCESSED)
+ {
+ m_info.setElementAt(DTM.NULL, posInfo + OFFSET_FIRSTCHILD);
+ }
+
if (top.equals(pos))
break;
@@ -305,6 +350,7 @@
if (null == nextNode)
{
+ m_info.setElementAt(DTM.NULL, posInfo + OFFSET_NEXTSIBLING);
pos = pos.getParentNode();
if ((null == pos) || (top.equals(pos)))
@@ -322,17 +368,17 @@
if (null != pos)
{
- int level = m_levelInfo.size() / 2;
+ int level = m_levelInfo.size() / LEVELINFO_NPERLEVEL;
- addNode(pos, level, m_levelInfo.peek(LEVELINFO_PARENT),
- m_levelInfo.peek(LEVELINFO_PREVSIB));
+ int newIndexHandle =
+ addNode(pos, level, m_levelInfo.peek(LEVELINFO_PARENT),
+ m_levelInfo.peek(LEVELINFO_PREVSIB));
m_pos = pos;
- int currentIndexHandle = m_nodes.size();
int sz = m_levelInfo.size();
- m_levelInfo.setElementAt(currentIndexHandle,
+ m_levelInfo.setElementAt(newIndexHandle,
sz - (1 + LEVELINFO_PREVSIB));
return pos;
@@ -395,6 +441,31 @@
}
/**
+ * Get the handle from a Node.
+ * <p>%OPT% This will be pretty slow.</p>
+ *
+ * @param node A node, which may be null.
+ *
+ * @return The node handle or <code>DTM.NULL</code>.
+ */
+ protected int getHandleFromNode(Node node)
+ {
+
+ if (null != node)
+ {
+ int len = m_nodes.size();
+
+ for (int i = 0; i < len; i++)
+ {
+ if (m_nodes == node)
+ return i | m_dtmIdent;
+ }
+ }
+
+ return DTM.NULL;
+ }
+
+ /**
* Get a node handle that is relative to the given node.
*
* @param identity The node identity.
@@ -476,7 +547,7 @@
int identity = nodeHandle & m_mask;
int firstChild = getNodeInfo(identity, OFFSET_FIRSTCHILD);
- return nodeHandle | m_dtmIdent;
+ return firstChild | m_dtmIdent;
}
/**
@@ -538,6 +609,7 @@
// Assume this can not be null.
type = node.getNodeType();
+
if (type == DTM.ATTRIBUTE_NODE)
{
String nodeuri = node.getNamespaceURI();
@@ -550,7 +622,7 @@
if (nodeuri.equals(namespaceURI) && name.equals(nodelocalname))
return identity | m_dtmIdent;
}
- else if(DTM.NAMESPACE_NODE != type)
+ else if (DTM.NAMESPACE_NODE != type)
{
break; // should be no more attribute nodes.
}
@@ -573,25 +645,28 @@
while (DTM.ELEMENT_NODE == type)
{
- // Assume that attributes and namespaces immediately follow the element.
+
+ // Assume that attributes and namespaces immediately follow the
element.
int identity = nodeHandle & m_mask;
- if(DTM.NULL != (identity = getNextNodeIdentity(identity)))
+ if (DTM.NULL != (identity = getNextNodeIdentity(identity)))
{
Node node = lookupNode(identity);
// Assume this can not be null.
type = node.getNodeType();
+
if (node.getNodeType() == DTM.ATTRIBUTE_NODE)
{
return identity | m_dtmIdent;
}
- else if(DTM.NAMESPACE_NODE != type)
+ else if (DTM.NAMESPACE_NODE != type)
{
break;
}
}
}
+
return DTM.NULL;
}
@@ -611,8 +686,33 @@
public int getFirstNamespaceNode(int nodeHandle, boolean inScope)
{
- // %TBD%
- return 0;
+ int type = getNodeType(nodeHandle);
+
+ while (DTM.ELEMENT_NODE == type)
+ {
+
+ // Assume that attributes and namespaces immediately follow the
element.
+ int identity = nodeHandle & m_mask;
+
+ if (DTM.NULL != (identity = getNextNodeIdentity(identity)))
+ {
+ Node node = lookupNode(identity);
+
+ // Assume this can not be null.
+ type = node.getNodeType();
+
+ if (node.getNodeType() == DTM.NAMESPACE_NODE)
+ {
+ return identity | m_dtmIdent;
+ }
+ else if (DTM.ATTRIBUTE_NODE != type)
+ {
+ break;
+ }
+ }
+ }
+
+ return DTM.NULL;
}
/**
@@ -626,8 +726,10 @@
public int getNextSibling(int nodeHandle)
{
- // %TBD%
- return 0;
+ int identity = nodeHandle & m_mask;
+ int nextSibling = getNodeInfo(identity, OFFSET_NEXTSIBLING);
+
+ return nextSibling | m_dtmIdent;
}
/**
@@ -642,8 +744,10 @@
public int getPreviousSibling(int nodeHandle)
{
- // %TBD%
- return 0;
+ int identity = nodeHandle & m_mask;
+ int firstChild = getNodeInfo(identity, OFFSET_PREVSIBLING);
+
+ return nodeHandle | m_dtmIdent;
}
/**
@@ -662,26 +766,28 @@
if (DTM.ATTRIBUTE_NODE == type)
{
- // Assume that attributes and namespace nodes immediately follow the
element.
+
+ // Assume that attributes and namespace nodes immediately follow the
element.
int identity = nodeHandle & m_mask;
- while(DTM.NULL != (identity = getNextNodeIdentity(identity)))
+ while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
{
Node node = lookupNode(identity);
// Assume this can not be null.
type = node.getNodeType();
+
if (type == DTM.ATTRIBUTE_NODE)
{
return identity | m_dtmIdent;
}
- else if(type != DTM.NAMESPACE_NODE)
+ else if (type != DTM.NAMESPACE_NODE)
{
break;
}
-
}
}
+
return DTM.NULL;
}
@@ -689,14 +795,41 @@
* Given a namespace handle, advance to the next namespace.
*
* @param namespaceHandle handle to node which must be of type
NAMESPACE_NODE.
+ *
+ * NEEDSDOC @param nodeHandle
* NEEDSDOC @param inScope
* @return handle of next namespace, or DTM.NULL to indicate none exists.
*/
- public int getNextNamespaceNode(int namespaceHandle, boolean inScope)
+ public int getNextNamespaceNode(int nodeHandle, boolean inScope)
{
- // %TBD%
- return 0;
+ int type = getNodeType(nodeHandle);
+
+ if (DTM.NAMESPACE_NODE == type)
+ {
+
+ // Assume that attributes and namespace nodes immediately follow the
element.
+ int identity = nodeHandle & m_mask;
+
+ while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
+ {
+ Node node = lookupNode(identity);
+
+ // Assume this can not be null.
+ type = node.getNodeType();
+
+ if (type == DTM.NAMESPACE_NODE)
+ {
+ return identity | m_dtmIdent;
+ }
+ else if (type != DTM.ATTRIBUTE_NODE)
+ {
+ break;
+ }
+ }
+ }
+
+ return DTM.NULL;
}
/**
@@ -758,8 +891,10 @@
public int getParent(int nodeHandle)
{
- // %TBD%
- return 0;
+ int identity = nodeHandle & m_mask;
+ int firstChild = getNodeInfo(identity, OFFSET_PARENT);
+
+ return nodeHandle | m_dtmIdent;
}
/**
@@ -770,9 +905,7 @@
*/
public int getDocument()
{
-
- // %TBD%
- return 0;
+ return 0 | m_dtmIdent;
}
/**
@@ -791,8 +924,14 @@
public int getOwnerDocument(int nodeHandle)
{
- // %TBD%
- return 0;
+ int type = getNodeType(nodeHandle);
+
+ if (DTM.DOCUMENT_NODE == type)
+ {
+ return DTM.NULL;
+ }
+
+ return getDocument();
}
/**
@@ -807,10 +946,80 @@
public String getStringValue(int nodeHandle)
{
- // %TBD%
- return null;
+ int type = getNodeType(nodeHandle);
+ Node node = getNode(nodeHandle);
+ if(DTM.ELEMENT_NODE == type || DTM.DOCUMENT_NODE == type)
+ {
+ FastStringBuffer buf = StringBufferPool.get();
+ String s;
+
+ try
+ {
+ getNodeData(node, buf);
+
+ s = (buf.length() > 0) ? buf.toString() : "";
+ }
+ finally
+ {
+ StringBufferPool.free(buf);
+ }
+
+ return s;
+
+ }
+ return node.getNodeValue();
+ }
+
+ /**
+ * Retrieve the text content of a DOM subtree, appending it into a
+ * user-supplied FastStringBuffer object. Note that attributes are
+ * not considered part of the content of an element.
+ * <p>
+ * There are open questions regarding whitespace stripping.
+ * Currently we make no special effort in that regard, since the standard
+ * DOM doesn't yet provide DTD-based information to distinguish
+ * whitespace-in-element-context from genuine #PCDATA. Note that we
+ * should probably also consider xml:space if/when we address this.
+ * DOM Level 3 may solve the problem for us.
+ *
+ * @param node Node whose subtree is to be walked, gathering the
+ * contents of all Text or CDATASection nodes.
+ * @param buf FastStringBuffer into which the contents of the text
+ * nodes are to be concatenated.
+ */
+ protected static void getNodeData(Node node, FastStringBuffer buf)
+ {
+
+ switch (node.getNodeType())
+ {
+ case Node.DOCUMENT_FRAGMENT_NODE :
+ case Node.DOCUMENT_NODE :
+ case Node.ELEMENT_NODE :
+ {
+ for (Node child = node.getFirstChild(); null != child;
+ child = child.getNextSibling())
+ {
+ getNodeData(child, buf);
+ }
+ }
+ break;
+ case Node.TEXT_NODE :
+ case Node.CDATA_SECTION_NODE :
+ buf.append(node.getNodeValue());
+ break;
+ case Node.ATTRIBUTE_NODE :
+ buf.append(node.getNodeValue());
+ break;
+ case Node.PROCESSING_INSTRUCTION_NODE :
+ // warning(XPATHErrorResources.WG_PARSING_AND_PREPARING);
+ break;
+ default :
+ // ignore
+ break;
+ }
}
+
/**
* Get number of character array chunks in
* the string-value of a node.
@@ -827,6 +1036,7 @@
{
// %TBD%
+ error("getStringValueChunkCount not yet supported!");
return 0;
}
@@ -848,6 +1058,7 @@
{
// %TBD%
+ error("getStringValueChunk not yet supported!");
return null;
}
@@ -861,8 +1072,9 @@
public int getExpandedNameID(int nodeHandle)
{
- // %TBD%
- return 0;
+ int identity = nodeHandle & m_mask;
+ int expandedNameID = getNodeInfo(identity, OFFSET_EXPANDEDNAMEID);
+ return expandedNameID;
}
/**
@@ -881,8 +1093,9 @@
public int getExpandedNameID(String namespace, String localName)
{
- // %TBD%
- return 0;
+ ExpandedNameTable ent = m_mgr.getExpandedNameTable(this);
+
+ return ent.getExpandedNameID(namespace, localName);
}
/**
@@ -893,9 +1106,9 @@
*/
public String getLocalNameFromExpandedNameID(int ExpandedNameID)
{
+ ExpandedNameTable ent = m_mgr.getExpandedNameTable(this);
- // %TBD%
- return null;
+ return ent.getLocalNameFromExpandedNameID(ExpandedNameID);
}
/**
@@ -907,9 +1120,9 @@
*/
public String getNamespaceFromExpandedNameID(int ExpandedNameID)
{
+ ExpandedNameTable ent = m_mgr.getExpandedNameTable(this);
- // %TBD%
- return null;
+ return ent.getNamespaceFromExpandedNameID(ExpandedNameID);
}
/**
@@ -919,12 +1132,15 @@
* @param nodeHandle the id of the node.
* @return String Name of this node, which may be an empty string.
* %REVIEW% Document when empty string is possible...
+ * %REVIEW-COMMENT% It should never be empty, should it?
*/
public String getNodeName(int nodeHandle)
{
- // %TBD%
- return null;
+ Node node = getNode(nodeHandle);
+
+ // Assume non-null.
+ return node.getNodeName();
}
/**
@@ -933,19 +1149,39 @@
* name.
*
* @param nodeHandle the id of the node.
- * @return String Name of this node.
+ * @return String Name of this node, which may be an empty string.
*/
public String getNodeNameX(int nodeHandle)
{
- // %TBD%
- return null;
+ String name;
+ short type = getNodeType(nodeHandle);
+
+ switch (type)
+ {
+ case DTM.ATTRIBUTE_NODE :
+ case DTM.ELEMENT_NODE :
+ case DTM.ENTITY_REFERENCE_NODE :
+ case DTM.NAMESPACE_NODE :
+ case DTM.PROCESSING_INSTRUCTION_NODE :
+ {
+ Node node = getNode(nodeHandle);
+
+ // assume not null.
+ name = node.getNodeName();
+ }
+ break;
+ default :
+ name = "";
+ }
+
+ return name;
}
/**
- * Given a node handle, return its DOM-style localname.
+ * Given a node handle, return its XPath-style localname.
* (As defined in Namespaces, this is the portion of the name after any
- * colon character)
+ * colon character).
*
* @param nodeHandle the id of the node.
* @return String Local name of this node.
@@ -953,8 +1189,36 @@
public String getLocalName(int nodeHandle)
{
- // %TBD%
- return null;
+ String name;
+ short type = getNodeType(nodeHandle);
+
+ switch (type)
+ {
+ case DTM.ATTRIBUTE_NODE :
+ case DTM.ELEMENT_NODE :
+ case DTM.ENTITY_REFERENCE_NODE :
+ case DTM.NAMESPACE_NODE :
+ case DTM.PROCESSING_INSTRUCTION_NODE :
+ {
+ Node node = getNode(nodeHandle);
+
+ // assume not null.
+ name = node.getLocalName();
+
+ if (null == name)
+ {
+ String qname = node.getNodeName();
+ int index = qname.indexOf(':');
+
+ name = (index < 0) ? qname : qname.substring(index + 1);
+ }
+ }
+ break;
+ default :
+ name = "";
+ }
+
+ return name;
}
/**
@@ -963,6 +1227,7 @@
* Given a node handle, return the prefix used to map to the namespace.
*
* <p> %REVIEW% Are you sure you want "" for no prefix? </p>
+ * <p> %REVIEW-COMMENT% I think so... not totally sure. -sb </p>
*
* @param nodeHandle the id of the node.
* @return String prefix of this node's name, or "" if no explicit
@@ -971,8 +1236,39 @@
public String getPrefix(int nodeHandle)
{
- // %TBD%
- return null;
+ String prefix;
+ short type = getNodeType(nodeHandle);
+
+ switch (type)
+ {
+ case DTM.NAMESPACE_NODE :
+ {
+ Node node = getNode(nodeHandle);
+
+ // assume not null.
+ String qname = node.getNodeName();
+ int index = qname.indexOf(':');
+
+ prefix = (index < 0) ? "" : qname.substring(index + 1);
+ }
+ break;
+ case DTM.ATTRIBUTE_NODE :
+ case DTM.ELEMENT_NODE :
+ {
+ Node node = getNode(nodeHandle);
+
+ // assume not null.
+ String qname = node.getNodeName();
+ int index = qname.indexOf(':');
+
+ prefix = (index < 0) ? "" : qname.substring(0, index);
+ }
+ break;
+ default :
+ prefix = "";
+ }
+
+ return prefix;
}
/**
@@ -980,6 +1276,8 @@
* (As defined in Namespaces, this is the declared URI which this node's
* prefix -- or default in lieu thereof -- was mapped to.)
*
+ * <p>%REVIEW% Null or ""? -sb</p>
+ *
* @param nodeHandle the id of the node.
* @return String URI value of this node's namespace, or null if no
* namespace was resolved.
@@ -987,8 +1285,30 @@
public String getNamespaceURI(int nodeHandle)
{
- // %TBD%
- return null;
+ String nsuri;
+ short type = getNodeType(nodeHandle);
+
+ switch (type)
+ {
+ case DTM.ATTRIBUTE_NODE :
+ case DTM.ELEMENT_NODE :
+ case DTM.ENTITY_REFERENCE_NODE :
+ case DTM.NAMESPACE_NODE :
+ case DTM.PROCESSING_INSTRUCTION_NODE :
+ {
+ Node node = getNode(nodeHandle);
+
+ // assume not null.
+ nsuri = node.getNamespaceURI();
+
+ // %TBD% Handle DOM1?
+ }
+ break;
+ default :
+ nsuri = null;
+ }
+
+ return nsuri;
}
/**
@@ -1003,8 +1323,9 @@
public String getNodeValue(int nodeHandle)
{
- // %TBD%
- return null;
+ Node node = getNode(nodeHandle);
+
+ return node.getNodeValue();
}
/**
@@ -1019,7 +1340,7 @@
{
int identity = nodeHandle & m_mask;
- short type = (short)getNodeInfo(identity, OFFSET_TYPE);
+ short type = (short) getNodeInfo(identity, OFFSET_TYPE);
return type;
}
@@ -1073,8 +1394,8 @@
public String getDocumentBaseURI(int nodeHandle)
{
- // %TBD%
- return null;
+ // %REVIEW% OK? -sb
+ return m_documentBaseURI;
}
/**
@@ -1087,8 +1408,8 @@
public String getDocumentSystemIdentifier(int nodeHandle)
{
- // %TBD%
- return null;
+ // %REVIEW% OK? -sb
+ return m_documentBaseURI;
}
/**
@@ -1101,8 +1422,8 @@
public String getDocumentEncoding(int nodeHandle)
{
- // %TBD%
- return null;
+ // %REVIEW% OK?? -sb
+ return "UTF-8";
}
/**
@@ -1117,8 +1438,6 @@
*/
public String getDocumentStandalone(int nodeHandle)
{
-
- // %TBD%
return null;
}
@@ -1132,12 +1451,10 @@
*
* NEEDSDOC @param documentHandle
*
- * @return the document version String object
+ * @return the document version String object.
*/
public String getDocumentVersion(int documentHandle)
{
-
- // %TBD%
return null;
}
@@ -1154,8 +1471,8 @@
public boolean getDocumentAllDeclarationsProcessed()
{
- // %TBD%
- return false;
+ // %REVIEW% OK?
+ return true;
}
/**
@@ -1169,7 +1486,23 @@
public String getDocumentTypeDeclarationSystemIdentifier()
{
- // %TBD%
+ Document doc;
+
+ if (m_root.getNodeType() == Node.DOCUMENT_NODE)
+ doc = (Document) m_root;
+ else
+ doc = m_root.getOwnerDocument();
+
+ if (null != doc)
+ {
+ DocumentType dtd = doc.getDoctype();
+
+ if (null != dtd)
+ {
+ return dtd.getSystemId();
+ }
+ }
+
return null;
}
@@ -1183,11 +1516,27 @@
*
* @return the public identifier String object, or null if there is none.
*/
- public int getDocumentTypeDeclarationPublicIdentifier()
+ public String getDocumentTypeDeclarationPublicIdentifier()
{
- // %TBD%
- return 0;
+ Document doc;
+
+ if (m_root.getNodeType() == Node.DOCUMENT_NODE)
+ doc = (Document) m_root;
+ else
+ doc = m_root.getOwnerDocument();
+
+ if (null != doc)
+ {
+ DocumentType dtd = doc.getDoctype();
+
+ if (null != dtd)
+ {
+ return dtd.getPublicId();
+ }
+ }
+
+ return null;
}
/**
@@ -1210,8 +1559,11 @@
public int getElementById(String elementId)
{
- // %TBD%
- return 0;
+ Document doc = (m_root.getNodeType() == Node.DOCUMENT_NODE)
+ ? (Document) m_root : m_root.getOwnerDocument();
+
+ return (null != doc)
+ ? getHandleFromNode(doc.getElementById(elementId)) : DTM.NULL;
}
/**
@@ -1251,8 +1603,52 @@
public String getUnparsedEntityURI(String name)
{
- // %TBD%
- return null;
+ String url = "";
+ Document doc = (m_root.getNodeType() == Node.DOCUMENT_NODE)
+ ? (Document) m_root : m_root.getOwnerDocument();
+
+ if (null != doc)
+ {
+ DocumentType doctype = doc.getDoctype();
+
+ if (null != doctype)
+ {
+ NamedNodeMap entities = doctype.getEntities();
+ if(null == entities)
+ return url;
+ Entity entity = (Entity) entities.getNamedItem(name);
+ if(null == entity)
+ return url;
+
+ String notationName = entity.getNotationName();
+
+ if (null != notationName) // then it's unparsed
+ {
+ // The draft says: "The XSLT processor may use the public
+ // identifier to generate a URI for the entity instead of the URI
+ // specified in the system identifier. If the XSLT processor does
+ // not use the public identifier to generate the URI, it must use
+ // the system identifier; if the system identifier is a relative
+ // URI, it must be resolved into an absolute URI using the URI of
+ // the resource containing the entity declaration as the base
+ // URI [RFC2396]."
+ // So I'm falling a bit short here.
+ url = entity.getSystemId();
+
+ if (null == url)
+ {
+ url = entity.getPublicId();
+ }
+ else
+ {
+ // This should be resolved to an absolute URL, but that's hard
+ // to do from here.
+ }
+ }
+ }
+ }
+
+ return url;
}
// ============== Boolean methods ================
@@ -1297,8 +1693,10 @@
public boolean isNodeAfter(int nodeHandle1, int nodeHandle2)
{
- // %TBD%
- return false;
+ int index1 = nodeHandle1 & m_mask;
+ int index2 = nodeHandle2 & m_mask;
+
+ return index1 <= index2;
}
/**
@@ -1341,8 +1739,7 @@
public boolean isDocumentAllDeclarationsProcessed(int documentHandle)
{
- // %TBD%
- return false;
+ return true;
}
/**
@@ -1358,8 +1755,13 @@
*/
public boolean isAttributeSpecified(int attributeHandle)
{
+ int type = getNodeType(attributeHandle);
- // %TBD%
+ if (DTM.ATTRIBUTE_NODE == type)
+ {
+ Attr attr = (Attr)getNode(attributeHandle);
+ return attr.getSpecified();
+ }
return false;
}
@@ -1380,8 +1782,64 @@
*/
public void dispatchCharactersEvents(
int nodeHandle, org.xml.sax.ContentHandler ch)
- throws org.xml.sax.SAXException{}
+ throws org.xml.sax.SAXException
+ {
+ int type = getNodeType(nodeHandle);
+ Node node = getNode(nodeHandle);
+ dispatchNodeData(node, ch);
+ }
+
+ /**
+ * Retrieve the text content of a DOM subtree, appending it into a
+ * user-supplied FastStringBuffer object. Note that attributes are
+ * not considered part of the content of an element.
+ * <p>
+ * There are open questions regarding whitespace stripping.
+ * Currently we make no special effort in that regard, since the standard
+ * DOM doesn't yet provide DTD-based information to distinguish
+ * whitespace-in-element-context from genuine #PCDATA. Note that we
+ * should probably also consider xml:space if/when we address this.
+ * DOM Level 3 may solve the problem for us.
+ *
+ * @param node Node whose subtree is to be walked, gathering the
+ * contents of all Text or CDATASection nodes.
+ * @param buf FastStringBuffer into which the contents of the text
+ * nodes are to be concatenated.
+ */
+ protected static void dispatchNodeData(Node node,
org.xml.sax.ContentHandler ch)
+ throws org.xml.sax.SAXException
+ {
+ switch (node.getNodeType())
+ {
+ case Node.DOCUMENT_FRAGMENT_NODE :
+ case Node.DOCUMENT_NODE :
+ case Node.ELEMENT_NODE :
+ {
+ for (Node child = node.getFirstChild(); null != child;
+ child = child.getNextSibling())
+ {
+ dispatchNodeData(child, ch);
+ }
+ }
+ break;
+ case Node.TEXT_NODE :
+ case Node.CDATA_SECTION_NODE :
+ case Node.ATTRIBUTE_NODE :
+ String str = node.getNodeValue();
+ ch.characters(str.toCharArray(), 0, str.length());
+ break;
+ case Node.PROCESSING_INSTRUCTION_NODE :
+ // warning(XPATHErrorResources.WG_PARSING_AND_PREPARING);
+ break;
+ default :
+ // ignore
+ break;
+ }
+ }
+
+ TreeWalker m_walker = new TreeWalker(null);
+
/**
* Directly create SAX parser events from a subtree.
*
@@ -1391,7 +1849,27 @@
* @throws org.xml.sax.SAXException
*/
public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch)
- throws org.xml.sax.SAXException{}
+ throws org.xml.sax.SAXException
+ {
+ TreeWalker treeWalker = m_walker;
+ ContentHandler prevCH = treeWalker.getContentHandler();
+
+ if(null != prevCH)
+ {
+ treeWalker = new TreeWalker(null);
+ }
+ treeWalker.setContentHandler(ch);
+
+ try
+ {
+ Node node = getNode(nodeHandle);
+ treeWalker.traverse(node);
+ }
+ finally
+ {
+ treeWalker.setContentHandler(null);
+ }
+ }
// ==== Construction methods (may not be supported by some
implementations!) =====
@@ -1419,4 +1897,12 @@
* @param str Non-null reverence to a string.
*/
public void appendTextChild(String str){}
+
+ /**
+ * Simple error for asserts and the like.
+ */
+ protected void error(String msg)
+ {
+ throw new DTMException(msg);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]