sax2dtm.java

来自「JAVA 所有包」· Java 代码 · 共 2,129 行 · 第 1/5 页

JAVA
2,129
字号
   * Construct the node map from the node.   *   * @param type raw type ID, one of DTM.XXX_NODE.   * @param expandedTypeID The expended type ID.   * @param parentIndex The current parent index.   * @param previousSibling The previous sibling index.   * @param dataOrPrefix index into m_data table, or string handle.   * @param canHaveFirstChild true if the node can have a first child, false   *                          if it is atomic.   *   * @return The index identity of the node that was added.   */  protected int addNode(int type, int expandedTypeID,                        int parentIndex, int previousSibling,                        int dataOrPrefix, boolean canHaveFirstChild)  {    // Common to all nodes:    int nodeIndex = m_size++;    // Have we overflowed a DTM Identity's addressing range?    if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS))    {      addNewDTMID(nodeIndex);    }    m_firstch.addElement(canHaveFirstChild ? NOTPROCESSED : DTM.NULL);    m_nextsib.addElement(NOTPROCESSED);    m_parent.addElement(parentIndex);    m_exptype.addElement(expandedTypeID);    m_dataOrQName.addElement(dataOrPrefix);    if (m_prevsib != null) {      m_prevsib.addElement(previousSibling);    }    if (DTM.NULL != previousSibling) {      m_nextsib.setElementAt(nodeIndex,previousSibling);    }    if (m_locator != null && m_useSourceLocationProperty) {      setSourceLocation();    }    // Note that nextSibling is not processed until charactersFlush()    // is called, to handle successive characters() events.    // Special handling by type: Declare namespaces, attach first child    switch(type)    {    case DTM.NAMESPACE_NODE:      declareNamespaceInContext(parentIndex,nodeIndex);      break;    case DTM.ATTRIBUTE_NODE:      break;    default:      if (DTM.NULL == previousSibling && DTM.NULL != parentIndex) {        m_firstch.setElementAt(nodeIndex,parentIndex);      }      break;    }    return nodeIndex;  }  /**   * Get a new DTM ID beginning at the specified node index.   * @param  nodeIndex The node identity at which the new DTM ID will begin   * addressing.   */  protected void addNewDTMID(int nodeIndex) {    try    {      if(m_mgr==null)        throw new ClassCastException();                                                            // Handle as Extended Addressing      DTMManagerDefault mgrD=(DTMManagerDefault)m_mgr;      int id=mgrD.getFirstFreeDTMID();      mgrD.addDTM(this,id,nodeIndex);      m_dtmIdent.addElement(id<<DTMManager.IDENT_DTM_NODE_BITS);    }    catch(ClassCastException e)    {      // %REVIEW% Wrong error message, but I've been told we're trying      // not to add messages right not for I18N reasons.      // %REVIEW% Should this be a Fatal Error?      error(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_DTMIDS_AVAIL, null));//"No more DTM IDs are available";    }  }  /**    * Migrate a DTM built with an old DTMManager to a new DTMManager.    * After the migration, the new DTMManager will treat the DTM as    * one that is built by itself.    * This is used to support DTM sharing between multiple transformations.    * @param manager the DTMManager    */  public void migrateTo(DTMManager manager) {    super.migrateTo(manager);        // We have to reset the information in m_dtmIdent and    // register the DTM with the new manager.     int numDTMs = m_dtmIdent.size();    int dtmId = m_mgrDefault.getFirstFreeDTMID();    int nodeIndex = 0;    for (int i = 0; i < numDTMs; i++)    {           m_dtmIdent.setElementAt(dtmId << DTMManager.IDENT_DTM_NODE_BITS, i);      m_mgrDefault.addDTM(this, dtmId, nodeIndex);      dtmId++;      nodeIndex += (1 << DTMManager.IDENT_DTM_NODE_BITS);    }  }  /**   * Store the source location of the current node.  This method must be called   * as every node is added to the DTM or for no node.   */  protected void setSourceLocation() {    m_sourceSystemId.addElement(m_locator.getSystemId());    m_sourceLine.addElement(m_locator.getLineNumber());    m_sourceColumn.addElement(m_locator.getColumnNumber());    //%REVIEW% %BUG% Prevent this from arising in the first place    // by not allowing the enabling conditions to change after we start    // building the document.    if (m_sourceSystemId.size() != m_size) {        String msg = "CODING ERROR in Source Location: " + m_size + " != "                    + m_sourceSystemId.size();        System.err.println(msg);        throw new RuntimeException(msg);    }  }  /**   * Given a node handle, return its node value. This is mostly   * as defined by the DOM, but may ignore some conveniences.   * <p>   *   * @param nodeHandle The node id.   * @return String Value of this node, or null if not   * meaningful for this node type.   */  public String getNodeValue(int nodeHandle)  {    int identity = makeNodeIdentity(nodeHandle);    int type = _type(identity);    if (isTextType(type))    {      int dataIndex = _dataOrQName(identity);      int offset = m_data.elementAt(dataIndex);      int length = m_data.elementAt(dataIndex + 1);      // %OPT% We should cache this, I guess.      return m_chars.getString(offset, length);    }    else if (DTM.ELEMENT_NODE == type || DTM.DOCUMENT_FRAGMENT_NODE == type             || DTM.DOCUMENT_NODE == type)    {      return null;    }    else    {      int dataIndex = _dataOrQName(identity);      if (dataIndex < 0)      {        dataIndex = -dataIndex;        dataIndex = m_data.elementAt(dataIndex + 1);      }      return m_valuesOrPrefixes.indexToString(dataIndex);    }  }  /**   * Given a node handle, return its XPath-style localname.   * (As defined in Namespaces, this is the portion of the name after any   * colon character).   *   * @param nodeHandle the id of the node.   * @return String Local name of this node.   */  public String getLocalName(int nodeHandle)  {    return m_expandedNameTable.getLocalName(_exptype(makeNodeIdentity(nodeHandle)));  }  /**   * The getUnparsedEntityURI function returns the URI of the unparsed   * entity with the specified name in the same document as the context   * node (see [3.3 Unparsed Entities]). It returns the empty string if   * there is no such entity.   * <p>   * XML processors may choose to use the System Identifier (if one   * is provided) to resolve the entity, rather than the URI in the   * Public Identifier. The details are dependent on the processor, and   * we would have to support some form of plug-in resolver to handle   * this properly. Currently, we simply return the System Identifier if   * present, and hope that it a usable URI or that our caller can   * map it to one.   * TODO: Resolve Public Identifiers... or consider changing function name.   * <p>   * If we find a relative URI   * reference, XML expects it to be resolved in terms of the base URI   * of the document. The DOM doesn't do that for us, and it isn't   * entirely clear whether that should be done here; currently that's   * pushed up to a higher level of our application. (Note that DOM Level   * 1 didn't store the document's base URI.)   * TODO: Consider resolving Relative URIs.   * <p>   * (The DOM's statement that "An XML processor may choose to   * completely expand entities before the structure model is passed   * to the DOM" refers only to parsed entities, not unparsed, and hence   * doesn't affect this function.)   *   * @param name A string containing the Entity Name of the unparsed   * entity.   *   * @return String containing the URI of the Unparsed Entity, or an   * empty string if no such entity exists.   */  public String getUnparsedEntityURI(String name)  {    String url = "";    if (null == m_entities)      return url;    int n = m_entities.size();    for (int i = 0; i < n; i += ENTITY_FIELDS_PER)    {      String ename = (String) m_entities.elementAt(i + ENTITY_FIELD_NAME);      if (null != ename && ename.equals(name))      {        String nname = (String) m_entities.elementAt(i                         + ENTITY_FIELD_NOTATIONNAME);        if (null != nname)        {          // The draft says: "The XSLT processor may use the public          // identifier to generate a URI for the entity instead of the URI          // specified in the system identifier. If the XSLT processor does          // not use the public identifier to generate the URI, it must use          // the system identifier; if the system identifier is a relative          // URI, it must be resolved into an absolute URI using the URI of          // the resource containing the entity declaration as the base          // URI [RFC2396]."          // So I'm falling a bit short here.          url = (String) m_entities.elementAt(i + ENTITY_FIELD_SYSTEMID);          if (null == url)          {            url = (String) m_entities.elementAt(i + ENTITY_FIELD_PUBLICID);          }        }        break;      }    }    return url;  }  /**   * Given a namespace handle, return the prefix that the namespace decl is   * mapping.   * Given a node handle, return the prefix used to map to the namespace.   *   * <p> %REVIEW% Are you sure you want "" for no prefix?  </p>   * <p> %REVIEW-COMMENT% I think so... not totally sure. -sb  </p>   *   * @param nodeHandle the id of the node.   * @return String prefix of this node's name, or "" if no explicit   * namespace prefix was given.   */  public String getPrefix(int nodeHandle)  {    int identity = makeNodeIdentity(nodeHandle);    int type = _type(identity);    if (DTM.ELEMENT_NODE == type)    {      int prefixIndex = _dataOrQName(identity);      if (0 == prefixIndex)        return "";      else      {        String qname = m_valuesOrPrefixes.indexToString(prefixIndex);        return getPrefix(qname, null);      }    }    else if (DTM.ATTRIBUTE_NODE == type)    {      int prefixIndex = _dataOrQName(identity);      if (prefixIndex < 0)      {        prefixIndex = m_data.elementAt(-prefixIndex);        String qname = m_valuesOrPrefixes.indexToString(prefixIndex);        return getPrefix(qname, null);      }    }    return "";  }  /**   * 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)  {    for (int attrH = getFirstAttribute(nodeHandle); DTM.NULL != attrH;            attrH = getNextAttribute(attrH))    {      String attrNS = getNamespaceURI(attrH);      String attrName = getLocalName(attrH);      boolean nsMatch = namespaceURI == attrNS                        || (namespaceURI != null                            && namespaceURI.equals(attrNS));      if (nsMatch && name.equals(attrName))        return attrH;    }    return DTM.NULL;  }  /**   * Return the public identifier of the external subset,   * normalized as described in 4.2.2 External Entities [XML]. If there is   * no external subset or if it has no public identifier, this property   * has no value.   *   * @return the public identifier String object, or null if there is none.   */  public String getDocumentTypeDeclarationPublicIdentifier()  {    /** @todo: implement this com.sun.org.apache.xml.internal.dtm.DTMDefaultBase abstract method */    error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null));//"Not yet supported!");    return null;  }  /**   * Given a node handle, return its DOM-style namespace URI   * (As defined in Namespaces, this is the declared URI which this node's   * prefix -- or default in lieu thereof -- was mapped to.)   *   * <p>%REVIEW% Null or ""? -sb</p>   *   * @param nodeHandle the id of the node.   * @return String URI value of this node's namespace, or null if no   * namespace was resolved.   */  public String getNamespaceURI(int nodeHandle)  {    return m_expandedNameTable.getNamespace(_exptype(makeNodeIdentity(nodeHandle)));  }  /**   * 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 XMLString getStringValue(int nodeHandle)  {    int identity = makeNodeIdentity(nodeHandle);    int type;    if(identity==DTM.NULL) // Separate lines because I wanted to breakpoint it      type = DTM.NULL;    else      type= _type(identity);    if (isTextType(type))    {      int dataIndex = _dataOrQName(identity);      int offset = m_data.elementAt(dataIndex);      int length = m_data.elementAt(dataIndex + 1);      return m_xstrf.newstr(m_chars, offset, length);    }    else    {      int firstChild = _firstch(identity);      if (DTM.NULL != firstChild)      {        int offset = -1;        int length = 0;        int startNode = identity;        identity = firstChild;        do {          type = _type(identity);          if (isTextType(type))

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?