dtmdefaultbase.java
来自「JAVA 所有包」· Java 代码 · 共 2,066 行 · 第 1/5 页
JAVA
2,066 行
/** 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(32); m_namespaceDeclSetElements.addElement(elementNodeIndex); m_namespaceDeclSets=new Vector(); nsList=new SuballocatedIntVector(32); 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); 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(); // 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); } // 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); 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) { if (candidate==ancestor) { // Found ancestor in list return (SuballocatedIntVector)m_namespaceDeclSets.elementAt(wouldBeAt); } else if (candidate<ancestor) { // Too deep in tree do { ancestor=_parent(ancestor); } while (candidate < ancestor); } else if(wouldBeAt > 0){ // Too late in list candidate=m_namespaceDeclSetElements.elementAt(--wouldBeAt); } else break; } } return null; // No namespaces known at this node } /** * Subroutine: Locate the specified node within * m_namespaceDeclSetElements, or the last element which * preceeds it in document order * * %REVIEW% Inlne this into findNamespaceContext? Create SortedSuballocatedIntVector type? * * @return If positive or zero, the index of the found item. * If negative, index of the point at which it would have appeared, * encoded as -1-index and hence reconvertable by subtracting * it from -1. (Encoding because I don't want to recompare the strings * but don't want to burn bytes on a datatype to hold a flagged value.) */ protected int findInSortedSuballocatedIntVector(SuballocatedIntVector vector, int lookfor) { // Binary search int i = 0; if(vector != null) { int first = 0; int last = vector.size() - 1; while (first <= last) { i = (first + last) / 2; int test = lookfor-vector.elementAt(i); if(test == 0) { return i; // Name found } else if (test < 0) { last = i - 1; // looked too late } else { first = i + 1; // looked ot early } } if (first > i) { i = first; // Clean up at loop end } } return -1 - i; // not-found has to be encoded. } /** * 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) { if(inScope) { 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; } else { // Assume that attributes and namespaces immediately // follow the element. // // %OPT% Would things be faster if all NS nodes were built // before all Attr nodes? Some costs at build time for 2nd // pass... int identity = makeNodeIdentity(nodeHandle); if (_type(identity) == DTM.ELEMENT_NODE) { while (DTM.NULL != (identity = getNextNodeIdentity(identity))) { int type = _type(identity); if (type == DTM.NAMESPACE_NODE) return makeNodeHandle(identity); else if (DTM.ATTRIBUTE_NODE != type) break; } return NULL; } else return NULL; } } /** * Given a namespace handle, advance to the next namespace. * * @param baseHandle handle to original node from where the first namespace * was relative to (needed to return nodes in document order). * @param nodeHandle A namespace handle for which we will find the next node. * @param inScope true if all namespaces that are in scope should be processed, * otherwise just process the nodes in the given element handle. * @return handle of next namespace, or DTM.NULL to indicate none exists. */ public int getNextNamespaceNode(int baseHandle, int nodeHandle, boolean inScope) { if(inScope) { //Since we've been given the base, try direct lookup //(could look from nodeHandle but this is at least one //comparison/get-parent faster) //SuballocatedIntVector nsContext=findNamespaceContext(nodeHandle & m_mask); SuballocatedIntVector nsContext=findNamespaceContext(makeNodeIdentity(baseHandle)); if(nsContext==null) return NULL; int i=1 + nsContext.indexOf(nodeHandle); if(i<=0 || i==nsContext.size()) return NULL; return nsContext.elementAt(i); } else { // Assume that attributes and namespace nodes immediately follow the element. int identity = makeNodeIdentity(nodeHandle); while (DTM.NULL != (identity = getNextNodeIdentity(identity))) { int type = _type(identity); if (type == DTM.NAMESPACE_NODE) { return makeNodeHandle(identity); } else if (type != DTM.ATTRIBUTE_NODE) { break; } } } return DTM.NULL; } /** * Given a node handle, find its parent node. * * @param nodeHandle the id of the node. * @return int Node-number of parent, * or DTM.NULL to indicate none exists. */ public int getParent(int nodeHandle) { int identity = makeNodeIdentity(nodeHandle); if (identity > 0) return makeNodeHandle(_parent(identity)); else return DTM.NULL; } /** * Find the Document node handle for the document currently under construction. * PLEASE NOTE that most people should use getOwnerDocument(nodeHandle) instead; * this version of the operation is primarily intended for use during negotiation * with the DTM Manager. * * @return int Node handle of document, which should always be valid. */ public int getDocument() { return m_dtmIdent.elementAt(0); // makeNodeHandle(0) } /** * Given a node handle, find the owning document node. This has the exact * same semantics as the DOM Document method of the same name, in that if * the nodeHandle is a document node, it will return NULL. * * <p>%REVIEW% Since this is DOM-specific, it may belong at the DOM * binding layer. Included here as a convenience function and to * aid porting of DOM code to DTM.</p> * * @param nodeHandle the id of the node. * @return int Node handle of owning document, or -1 if the node was a Docment */ public int getOwnerDocument(int nodeHandle) { if (DTM.DOCUMENT_NODE == getNodeType(nodeHandle)) return DTM.NULL; return getDocumentRoot(nodeHandle); } /** * Given a node handle, find the owning document node. Unlike the DOM, * this considers the owningDocument of a Document to be itself. * * @param nodeHandle the id of the node. * @return int Node handle of owning document, or the nodeHandle if it is * a Document. */ public int getDocumentRoot(int nodeHandle) { return getManager().getDTM(nodeHandle).getDocument(); } /** * Get the string-value of a node as a String object * (see http://www.w3.org/TR/xpath#data-model * for the definition of a node's string-value). * * @param nodeHandle The node ID. * * @return A string object that represents the string-value of the given node. */ public abstract XMLString getStringValue(int nodeHandle); /** * Get number of character array chunks in * the string-value of a node. * (see http://www.w3.org/TR/xpath#data-model * for the definition of a node's string-value). * Note that a single text node may have multiple text chunks. * * @param nodeHandle The node ID. * * @return number of character array chunks in * the string-value of a node. */ public int getStringValueChunkCount(int nodeHandle) { // %TBD% error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null));//("getStringValueChunkCount not yet supported!"); return 0; } /** * Get a character array chunk in the string-value of a node. * (see http://www.w3.org/TR/xpath#data-model * for the definition of a node's string-value). * Note that a single text node may have multiple text chunks. * * @param nodeHandle The node ID. * @param chunkIndex Which chunk to get. * @param startAndLen An array of 2 where the start position and length of * the chunk will be returned. *
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?