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 + -
显示快捷键?