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