dtmdefaultbase.java
来自「java jdk 1.4的源码」· Java 代码 · 共 2,022 行 · 第 1/5 页
JAVA
2,022 行
case DTM.ENTITY_NODE : typestring = "ENTITY"; break; case DTM.ENTITY_REFERENCE_NODE : typestring = "ENT_REF"; break; case DTM.NAMESPACE_NODE : typestring = "NAMESPACE"; break; case DTM.NOTATION_NODE : typestring = "NOTATION"; break; case DTM.NULL : typestring = "null"; break; case DTM.PROCESSING_INSTRUCTION_NODE : typestring = "PI"; break; case DTM.TEXT_NODE : typestring = "TEXT"; break; default : typestring = "Unknown!"; break; } StringBuffer sb=new StringBuffer(); sb.append("["+nodeHandle+": "+typestring+ "(0x"+Integer.toHexString(getExpandedTypeID(nodeHandle))+") "+ getNodeNameX(nodeHandle)+" {"+getNamespaceURI(nodeHandle)+"}"+ "=\""+ getNodeValue(nodeHandle)+"\"]"); return sb.toString(); } // ========= DTM Implementation Control Functions. ============== /** * Set an implementation dependent feature. * <p> * %REVIEW% Do we really expect to set features on DTMs? * * @param featureId A feature URL. * @param state true if this feature should be on, false otherwise. */ public void setFeature(String featureId, boolean state){} // ========= Document Navigation Functions ========= /** * Given a node handle, test if it has child nodes. * <p> %REVIEW% This is obviously useful at the DOM layer, where it * would permit testing this without having to create a proxy * node. It's less useful in the DTM API, where * (dtm.getFirstChild(nodeHandle)!=DTM.NULL) is just as fast and * almost as self-evident. But it's a convenience, and eases porting * of DOM code to DTM. </p> * * @param nodeHandle int Handle of the node. * @return int true if the given node has child nodes. */ public boolean hasChildNodes(int nodeHandle) { int identity = makeNodeIdentity(nodeHandle); int firstChild = _firstch(identity); return firstChild != DTM.NULL; } /** Given a node identity, return a node handle. If extended addressing * has been used (multiple DTM IDs), we need to map the high bits of the * identity into the proper DTM ID. * * This has been made FINAL to facilitate inlining, since we do not expect * any subclass of DTMDefaultBase to ever change the algorithm. (I don't * really like doing so, and would love to have an excuse not to...) * * %REVIEW% Is it worth trying to specialcase small documents? * %REVIEW% Should this be exposed at the package/public layers? * * @param nodeIdentity Internal offset to this node's records. * @return NodeHandle (external representation of node) * */ final protected int makeNodeHandle(int nodeIdentity) { if(NULL==nodeIdentity) return NULL; if(JJK_DEBUG && nodeIdentity>DTMManager.IDENT_NODE_DEFAULT) System.err.println("GONK! (only useful in limited situations)"); return m_dtmIdent.elementAt(nodeIdentity >>> DTMManager.IDENT_DTM_NODE_BITS) + (nodeIdentity & DTMManager.IDENT_NODE_DEFAULT) ; } /** Given a node handle, return a node identity. If extended addressing * has been used (multiple DTM IDs), we need to map the high bits of the * identity into the proper DTM ID and thence find the proper offset * to add to the low bits of the identity * * This has been made FINAL to facilitate inlining, since we do not expect * any subclass of DTMDefaultBase to ever change the algorithm. (I don't * really like doing so, and would love to have an excuse not to...) * * %OPT% Performance is critical for this operation. * * %REVIEW% Should this be exposed at the package/public layers? * * @param NodeHandle (external representation of node) * @return nodeIdentity Internal offset to this node's records. * */ final protected int makeNodeIdentity(int nodeHandle) { if(NULL==nodeHandle) return NULL; if(m_mgrDefault!=null) { // Optimization: use the DTMManagerDefault's fast DTMID-to-offsets // table. I'm not wild about this solution but this operation // needs need extreme speed. int whichDTMindex=nodeHandle>>>DTMManager.IDENT_DTM_NODE_BITS; // %REVIEW% Wish I didn't have to perform the pre-test, but // someone is apparently asking DTMs whether they contain nodes // which really don't belong to them. That's probably a bug // which should be fixed, but until it is: if(m_mgrDefault.m_dtms[whichDTMindex]!=this) return NULL; else return m_mgrDefault.m_dtm_offsets[whichDTMindex] | (nodeHandle & DTMManager.IDENT_NODE_DEFAULT); } int whichDTMid=m_dtmIdent.indexOf(nodeHandle & DTMManager.IDENT_DTM_DEFAULT); return (whichDTMid==NULL) ? NULL : (whichDTMid << DTMManager.IDENT_DTM_NODE_BITS) + (nodeHandle & DTMManager.IDENT_NODE_DEFAULT); } /** * 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) { int identity = makeNodeIdentity(nodeHandle); int firstChild = _firstch(identity); return makeNodeHandle(firstChild); } /** * 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) { int identity = makeNodeIdentity(nodeHandle); int child = _firstch(identity); int lastChild = DTM.NULL; while (child != DTM.NULL) { lastChild = child; child = _nextsib(child); } return makeNodeHandle(lastChild); } /** * 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 abstract int getAttributeNode(int nodeHandle, String namespaceURI, String name); /** * Given a node handle, get the index of the node's first attribute. * * @param nodeHandle int Handle of the node. * @return Handle of first attribute, or DTM.NULL to indicate none exists. */ public int getFirstAttribute(int nodeHandle) { int type = getNodeType(nodeHandle); if (DTM.ELEMENT_NODE == type) { // Assume that attributes and namespaces immediately follow the element. int identity = makeNodeIdentity(nodeHandle); while (DTM.NULL != (identity = getNextNodeIdentity(identity))) { // Assume this can not be null. type = _type(identity); if (type == DTM.ATTRIBUTE_NODE) { return makeNodeHandle(identity); } else if (DTM.NAMESPACE_NODE != type) { break; } } } return DTM.NULL; } /** * 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 getNextSibling(int nodeHandle) { return makeNodeHandle(_nextsib(makeNodeIdentity(nodeHandle))); } /** * 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) { return makeNodeHandle(_prevsib(makeNodeIdentity(nodeHandle))); } /** * Given a node handle, advance to the next attribute. * If an attr, we advance to * the next attr on the same node. If not an attribute, we return NULL. * * @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) { int type = getNodeType(nodeHandle); if (DTM.ATTRIBUTE_NODE == type) { // Assume that attributes and namespace nodes immediately follow the element. int identity = makeNodeIdentity(nodeHandle); while (DTM.NULL != (identity = getNextNodeIdentity(identity))) { type = _type(identity); if (type == DTM.ATTRIBUTE_NODE) { return makeNodeHandle(identity); } else if (type != DTM.NAMESPACE_NODE) { break; } } } return DTM.NULL; } /** Lazily created namespace lists. */ private Vector m_namespaceLists = null; // on demand /** Build table of namespace declaration * locations during DTM construction. Table is a Vector of * SuballocatedIntVectors containing the namespace node HANDLES declared at * that ID, plus an SuballocatedIntVector of the element node INDEXES at which * these declarations appeared. * * NOTE: Since this occurs during model build, nodes will be encountered * in doucment order and thus the table will be ordered by element, * permitting binary-search as a possible retrieval optimization. * * %REVIEW% Directly managed arrays rather than vectors? * %REVIEW% Handles or IDs? Given usage, I think handles. * */ protected void declareNamespaceInContext(int elementNodeIndex,int namespaceNodeIndex) { SuballocatedIntVector nsList=null; if(m_namespaceDeclSets==null) { // First m_namespaceDeclSetElements=new SuballocatedIntVector(); m_namespaceDeclSetElements.addElement(elementNodeIndex); m_namespaceDeclSets=new Vector(); nsList=new SuballocatedIntVector(); m_namespaceDeclSets.addElement(nsList); } else { // Most recent. May be -1 (none) if DTM was pruned. // %OPT% Is there a lastElement() method? Should there be? int last=m_namespaceDeclSetElements.size()-1; if(last>=0 && elementNodeIndex==m_namespaceDeclSetElements.elementAt(last)) { nsList=(SuballocatedIntVector)m_namespaceDeclSets.elementAt(last); } } if(nsList==null) { m_namespaceDeclSetElements.addElement(elementNodeIndex); nsList=new SuballocatedIntVector(); m_namespaceDeclSets.addElement(nsList); SuballocatedIntVector inherited= findNamespaceContext(_parent(elementNodeIndex)); 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(); for(int i=0;i<isize;++i) { nsList.addElement(inherited.elementAt(i)); } } } // Handle overwriting inherited. // %OPT% Keep sorted? (By expanded-name rather than by doc order...) // Downside: Would require insertElementAt if not found, // which has recopying costs. But these are generally short lists... int newEType=_exptype(namespaceNodeIndex); for(int i=nsList.size()-1;i>=0;--i) { if(newEType==getExpandedTypeID(nsList.elementAt(i))) { nsList.setElementAt(makeNodeHandle(namespaceNodeIndex),i); return; } } nsList.addElement(makeNodeHandle(namespaceNodeIndex)); } /** Retrieve list of namespace declaration locations * active at this node. List is an SuballocatedIntVector whose * entries are the namespace node HANDLES declared at that ID. * * %REVIEW% Directly managed arrays rather than vectors? * %REVIEW% Handles or IDs? Given usage, I think handles. * */ protected SuballocatedIntVector findNamespaceContext(int elementNodeIndex) { if (null!=m_namespaceDeclSetElements) { // %OPT% Is binary-search really saving us a lot versus linear? // (... It may be, in large docs with many NS decls.) int wouldBeAt=findInSortedSuballocatedIntVector(m_namespaceDeclSetElements, elementNodeIndex); if(wouldBeAt>=0) // Found it return (SuballocatedIntVector) m_namespaceDeclSets.elementAt(wouldBeAt); if(wouldBeAt == -1) // -1-wouldbeat == 0 return null; // Not after anything; definitely not found // Not found, but we know where it should have been. // Search back until we find an ancestor or run out. wouldBeAt=-1-wouldBeAt; // Decrement wouldBeAt to find last possible ancestor int candidate=m_namespaceDeclSetElements.elementAt(-- wouldBeAt);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?