dtmdocumentimpl.java
来自「JAVA 所有包」· Java 代码 · 共 1,662 行 · 第 1/5 页
JAVA
1,662 行
/** * 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 getFirstChild(int nodeHandle) { // ###shs worry about tracing/debug later nodeHandle &= NODEHANDLE_MASK; // Read node into variable nodes.readSlot(nodeHandle, gotslot); // type is the last half of first slot short type = (short) (gotslot[0] & 0xFFFF); // Check to see if Element or Document node if ((type == ELEMENT_NODE) || (type == DOCUMENT_NODE) || (type == ENTITY_REFERENCE_NODE)) { // In case when Document root is given // if (nodeHandle == 0) nodeHandle = 1; // %TBD% Probably was a mistake. // If someone explicitly asks for first child // of Document, I would expect them to want // that and only that. int kid = nodeHandle + 1; nodes.readSlot(kid, gotslot); while (ATTRIBUTE_NODE == (gotslot[0] & 0xFFFF)) { // points to next sibling kid = gotslot[2]; // Return NULL if node has only attributes if (kid == NULL) return NULL; nodes.readSlot(kid, gotslot); } // If parent slot matches given parent, return kid if (gotslot[1] == nodeHandle) { int firstChild = kid | m_docHandle; return firstChild; } } // No child found return NULL; } /** * Given a node handle, advance to its last 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 Node-number of last child, * or DTM.NULL to indicate none exists. */ public int getLastChild(int nodeHandle) { // ###shs put trace/debug later nodeHandle &= NODEHANDLE_MASK; // do not need to test node type since getFirstChild does that int lastChild = NULL; for (int nextkid = getFirstChild(nodeHandle); nextkid != NULL; nextkid = getNextSibling(nextkid)) { lastChild = nextkid; } return lastChild | m_docHandle; } /** * Retrieves an attribute node by by qualified name and namespace URI. * * @param nodeHandle int Handle of the node upon which to look up this attribute. * @param namespaceURI The namespace URI of the attribute to * retrieve, or null. * @param name The local name of the attribute to * retrieve. * @return The attribute node handle with the specified name ( * <code>nodeName</code>) or <code>DTM.NULL</code> if there is no such * attribute. */ public int getAttributeNode(int nodeHandle, String namespaceURI, String name) { int nsIndex = m_nsNames.stringToIndex(namespaceURI), nameIndex = m_localNames.stringToIndex(name); nodeHandle &= NODEHANDLE_MASK; nodes.readSlot(nodeHandle, gotslot); short type = (short) (gotslot[0] & 0xFFFF); // If nodeHandle points to element next slot would be first attribute if (type == ELEMENT_NODE) nodeHandle++; // Iterate through Attribute Nodes while (type == ATTRIBUTE_NODE) { if ((nsIndex == (gotslot[0] << 16)) && (gotslot[3] == nameIndex)) return nodeHandle | m_docHandle; // Goto next sibling nodeHandle = gotslot[2]; nodes.readSlot(nodeHandle, gotslot); } return NULL; } /** * Given a node handle, get the index of the node's first attribute. * * @param nodeHandle int Handle of the Element node. * @return Handle of first attribute, or DTM.NULL to indicate none exists. */ public int getFirstAttribute(int nodeHandle) { nodeHandle &= NODEHANDLE_MASK; // %REVIEW% jjk: Just a quick observation: If you're going to // call readEntry repeatedly on the same node, it may be // more efficiently to do a readSlot to get the data locally, // reducing the addressing and call-and-return overhead. // Should we check if handle is element (do we want sanity checks?) if (ELEMENT_NODE != (nodes.readEntry(nodeHandle, 0) & 0xFFFF)) return NULL; // First Attribute (if any) should be at next position in table nodeHandle++; return(ATTRIBUTE_NODE == (nodes.readEntry(nodeHandle, 0) & 0xFFFF)) ? nodeHandle | m_docHandle : NULL; } /** * Given a node handle, get the index 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 handle to node, which should probably be an element * node, but need not be. * * @param inScope true if all namespaces in scope should be returned, * false if only the namespace declarations should be * returned. * @return handle of first namespace, or DTM.NULL to indicate none exists. */ public int getFirstNamespaceNode(int nodeHandle, boolean inScope) { return NULL; } /** * Given a node handle, advance to its next sibling. * * %TBD% This currently uses the DTM-internal definition of * sibling; eg, the last attr's next sib is the first * child. In the old DTM, the DOM proxy layer provided the * additional logic for the public view. If we're rewriting * for XPath emulation, that test must be done here. * * %TBD% CODE INTERACTION WITH INCREMENTAL PARSE - If not yet * resolved, should wait 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 getNextSibling(int nodeHandle) { nodeHandle &= NODEHANDLE_MASK; // Document root has no next sibling if (nodeHandle == 0) return NULL; short type = (short) (nodes.readEntry(nodeHandle, 0) & 0xFFFF); if ((type == ELEMENT_NODE) || (type == ATTRIBUTE_NODE) || (type == ENTITY_REFERENCE_NODE)) { int nextSib = nodes.readEntry(nodeHandle, 2); if (nextSib == NULL) return NULL; if (nextSib != 0) return (m_docHandle | nextSib); // ###shs should cycle/wait if nextSib is 0? Working on threading next } // Next Sibling is in the next position if it shares the same parent int thisParent = nodes.readEntry(nodeHandle, 1); if (nodes.readEntry(++nodeHandle, 1) == thisParent) return (m_docHandle | nodeHandle); return NULL; } /** * Given a node handle, find its preceeding sibling. * WARNING: DTM is asymmetric; this operation is resolved by search, and is * relatively expensive. * * @param nodeHandle the id of the node. * @return int Node-number of the previous sib, * or DTM.NULL to indicate none exists. */ public int getPreviousSibling(int nodeHandle) { nodeHandle &= NODEHANDLE_MASK; // Document root has no previous sibling if (nodeHandle == 0) return NULL; int parent = nodes.readEntry(nodeHandle, 1); int kid = NULL; for (int nextkid = getFirstChild(parent); nextkid != nodeHandle; nextkid = getNextSibling(nextkid)) { kid = nextkid; } return kid | m_docHandle; } /** * Given a node handle, advance to the next attribute. If an * element, we advance to its first attribute; if an attr, we advance to * the next attr on the same node. * * @param nodeHandle int Handle of the node. * @return int DTM node-number of the resolved attr, * or DTM.NULL to indicate none exists. */ public int getNextAttribute(int nodeHandle) { nodeHandle &= NODEHANDLE_MASK; nodes.readSlot(nodeHandle, gotslot); //%REVIEW% Why are we using short here? There's no storage //reduction for an automatic variable, especially one used //so briefly, and it typically costs more cycles to process //than an int would. short type = (short) (gotslot[0] & 0xFFFF); if (type == ELEMENT_NODE) { return getFirstAttribute(nodeHandle); } else if (type == ATTRIBUTE_NODE) { if (gotslot[2] != NULL) return (m_docHandle | gotslot[2]); } return NULL; } /** * Given a namespace handle, advance to the next namespace. * * %TBD% THIS METHOD DOES NOT MATCH THE CURRENT SIGNATURE IN * THE DTM INTERFACE. FIX IT, OR JUSTIFY CHANGING THE DTM * API. * * @param namespaceHandle handle to node which must be of type NAMESPACE_NODE. * @return handle of next namespace, or DTM.NULL to indicate none exists. */ public int getNextNamespaceNode(int baseHandle,int namespaceHandle, boolean inScope) { // ###shs need to work on namespace return NULL; } /** * Given a node handle, advance to its next descendant. * If not yet resolved, waits for more nodes to be added to the document and * tries again. * * @param subtreeRootHandle * @param nodeHandle int Handle of the node. * @return handle of next descendant, * or DTM.NULL to indicate none exists. */ public int getNextDescendant(int subtreeRootHandle, int nodeHandle) { subtreeRootHandle &= NODEHANDLE_MASK; nodeHandle &= NODEHANDLE_MASK; // Document root [Document Node? -- jjk] - no next-sib if (nodeHandle == 0) return NULL; while (!m_isError) { // Document done and node out of bounds if (done && (nodeHandle > nodes.slotsUsed())) break; if (nodeHandle > subtreeRootHandle) { nodes.readSlot(nodeHandle+1, gotslot); if (gotslot[2] != 0) { short type = (short) (gotslot[0] & 0xFFFF); if (type == ATTRIBUTE_NODE) { nodeHandle +=2; } else { int nextParentPos = gotslot[1]; if (nextParentPos >= subtreeRootHandle) return (m_docHandle | (nodeHandle+1)); else break; } } else if (!done) { // Add wait logic here } else break; } else { nodeHandle++; } } // Probably should throw error here like original instead of returning return NULL; } /** * Given a node handle, advance to the next node on the following axis. * * @param axisContextHandle the start of the axis that is being traversed. * @param nodeHandle * @return handle of next sibling, * or DTM.NULL to indicate none exists. */ public int getNextFollowing(int axisContextHandle, int nodeHandle) { //###shs still working on return NULL; } /** * Given a node handle, advance to the next node on the preceding axis. * * @param axisContextHandle the start of the axis that is being traversed. * @param nodeHandle the id of the node. * @return int Node-number of preceding sibling, * or DTM.NULL to indicate none exists. */ public int getNextPreceding(int axisContextHandle, int nodeHandle) { // ###shs copied from Xalan 1, what is this suppose to do? nodeHandle &= NODEHANDLE_MASK; while (nodeHandle > 1) { nodeHandle--; if (ATTRIBUTE_NODE == (nodes.readEntry(nodeHandle, 0) & 0xFFFF)) continue; // if nodeHandle is _not_ an ancestor of // axisContextHandle, specialFind will return it. // If it _is_ an ancestor, specialFind will return -1 // %REVIEW% unconditional return defeats the
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?