FileDocCategorySizeDatePackage
SAX2DTM.javaAPI DocJava SE 6 API78447Tue Jun 10 00:22:58 BST 2008com.sun.org.apache.xml.internal.dtm.ref.sax2dtm

SAX2DTM

public class SAX2DTM extends DTMDefaultBaseIterators implements ErrorHandler, DeclHandler, LexicalHandler, EntityResolver, DTDHandler, ContentHandler
This class implements a DTM that tends to be optimized more for speed than for compactness, that is constructed via SAX2 ContentHandler events.

Fields Summary
private static final boolean
DEBUG
Set true to monitor SAX events and similar diagnostic info.
private IncrementalSAXSource
m_incrementalSAXSource
If we're building the model incrementally on demand, we need to be able to tell the source when to send us more data. Note that if this has not been set, and you attempt to read ahead of the current build point, we'll probably throw a null-pointer exception. We could try to wait-and-retry instead, as a very poor fallback, but that has all the known problems with multithreading on multiprocessors and we Don't Want to Go There.
protected FastStringBuffer
m_chars
All the character content, including attribute values, are stored in this buffer. %REVIEW% Should this have an option of being shared across DTMs? Sequentially only; not threadsafe... Currently, I think not. %REVIEW% Initial size was pushed way down to reduce weight of RTFs. pending reduction in number of RTF DTMs. Now that we're sharing a DTM between RTFs, and tail-pruning... consider going back to the larger/faster. Made protected rather than private so SAX2RTFDTM can access it.
protected SuballocatedIntVector
m_data
This vector holds offset and length data.
protected transient IntStack
m_parents
The parent stack, needed only for construction. Made protected rather than private so SAX2RTFDTM can access it.
protected transient int
m_previous
The current previous node, needed only for construction time. Made protected rather than private so SAX2RTFDTM can access it.
protected transient Vector
m_prefixMappings
Namespace support, only relevent at construction time. Made protected rather than private so SAX2RTFDTM can access it.
protected transient IntStack
m_contextIndexes
Namespace support, only relevent at construction time. Made protected rather than private so SAX2RTFDTM can access it.
protected transient int
m_textType
Type of next characters() event within text block in prgress.
protected transient int
m_coalescedTextType
Type of coalesced text block. See logic in the characters() method.
protected transient Locator
m_locator
The SAX Document locator
private transient String
m_systemId
The SAX Document system-id
protected transient boolean
m_insideDTD
We are inside the DTD. This is used for ignoring comments.
protected DTMTreeWalker
m_walker
Tree Walker for dispatchToEvents.
protected DTMStringPool
m_valuesOrPrefixes
pool of string values that come as strings.
protected boolean
m_endDocumentOccured
End document has been reached. Made protected rather than private so SAX2RTFDTM can access it.
protected SuballocatedIntVector
m_dataOrQName
Data or qualified name values, one array element for each node.
protected Hashtable
m_idAttributes
This table holds the ID string to node associations, for XML IDs.
private static final String[]
m_fixednames
fixed dom-style names.
private Vector
m_entities
Vector of entities. Each record is composed of four Strings: publicId, systemID, notationName, and name.
private static final int
ENTITY_FIELD_PUBLICID
m_entities public ID offset.
private static final int
ENTITY_FIELD_SYSTEMID
m_entities system ID offset.
private static final int
ENTITY_FIELD_NOTATIONNAME
m_entities notation name offset.
private static final int
ENTITY_FIELD_NAME
m_entities name offset.
private static final int
ENTITY_FIELDS_PER
Number of entries per record for m_entities.
protected int
m_textPendingStart
The starting offset within m_chars for the text or CDATA_SECTION node currently being acumulated, or -1 if there is no text node in progress
protected boolean
m_useSourceLocationProperty
Describes whether information about document source location should be maintained or not. Made protected for access by SAX2RTFDTM.
protected StringVector
m_sourceSystemId
Made protected for access by SAX2RTFDTM.
protected IntVector
m_sourceLine
Made protected for access by SAX2RTFDTM.
protected IntVector
m_sourceColumn
Made protected for access by SAX2RTFDTM.
boolean
m_pastFirstElement
Constructors Summary
public SAX2DTM(DTMManager mgr, Source source, int dtmIdentity, DTMWSFilter whiteSpaceFilter, XMLStringFactory xstringfactory, boolean doIndexing)
Construct a SAX2DTM object using the default block size.

param
mgr The DTMManager who owns this DTM.
param
source the JAXP 1.1 Source object for this DTM.
param
dtmIdentity The DTM identity ID for this DTM.
param
whiteSpaceFilter The white space filter for this DTM, which may be null.
param
xstringfactory XMLString factory for creating character content.
param
doIndexing true if the caller considers it worth it to use indexing schemes.

  
                                                                                                                      
        
                  
                  
                  
  

    this(mgr, source, dtmIdentity, whiteSpaceFilter,
          xstringfactory, doIndexing, DEFAULT_BLOCKSIZE, true, false);
  
public SAX2DTM(DTMManager mgr, Source source, int dtmIdentity, DTMWSFilter whiteSpaceFilter, XMLStringFactory xstringfactory, boolean doIndexing, int blocksize, boolean usePrevsib, boolean newNameTable)
Construct a SAX2DTM object ready to be constructed from SAX2 ContentHandler events.

param
mgr The DTMManager who owns this DTM.
param
source the JAXP 1.1 Source object for this DTM.
param
dtmIdentity The DTM identity ID for this DTM.
param
whiteSpaceFilter The white space filter for this DTM, which may be null.
param
xstringfactory XMLString factory for creating character content.
param
doIndexing true if the caller considers it worth it to use indexing schemes.
param
blocksize The block size of the DTM.
param
usePrevsib true if we want to build the previous sibling node array.
param
newNameTable true if we want to use a new ExpandedNameTable for this DTM.


    super(mgr, source, dtmIdentity, whiteSpaceFilter,
          xstringfactory, doIndexing, blocksize, usePrevsib, newNameTable);

    // %OPT% Use smaller sizes for all internal storage units when
    // the blocksize is small. This reduces the cost of creating an RTF.
    if (blocksize <= 64) 
    {
      m_data = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS_SMALL);
      m_dataOrQName = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS_SMALL);
      m_valuesOrPrefixes = new DTMStringPool(16);
      m_chars = new FastStringBuffer(7, 10);
      m_contextIndexes = new IntStack(4);
      m_parents = new IntStack(4);
    }
    else
    {
      m_data = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS);
      m_dataOrQName = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS);
      m_valuesOrPrefixes = new DTMStringPool();
      m_chars = new FastStringBuffer(10, 13);
      m_contextIndexes = new IntStack();
      m_parents = new IntStack();
    }
         
    // %REVIEW%  Initial size pushed way down to reduce weight of RTFs
    // (I'm not entirely sure 0 would work, so I'm playing it safe for now.)
    //m_data = new SuballocatedIntVector(doIndexing ? (1024*2) : 512, 1024);
    //m_data = new SuballocatedIntVector(blocksize);

    m_data.addElement(0);   // Need placeholder in case index into here must be <0.

    //m_dataOrQName = new SuballocatedIntVector(blocksize);
    
    // m_useSourceLocationProperty=com.sun.org.apache.xalan.internal.processor.TransformerFactoryImpl.m_source_location;
    m_useSourceLocationProperty = mgr.getSource_location();
    m_sourceSystemId = (m_useSourceLocationProperty) ? new StringVector() : null;
 	m_sourceLine = (m_useSourceLocationProperty) ?  new IntVector() : null;
    m_sourceColumn = (m_useSourceLocationProperty) ?  new IntVector() : null; 
  
Methods Summary
protected int_dataOrQName(int identity)
Get the data or qualified name for the given node identity.

param
identity The node identity.
return
The data or qualified name, or DTM.NULL.


    if (identity < m_size)
      return m_dataOrQName.elementAt(identity);

    // Check to see if the information requested has been processed, and,
    // if not, advance the iterator until we the information has been
    // processed.
    while (true)
    {
      boolean isMore = nextNode();

      if (!isMore)
        return NULL;
      else if (identity < m_size)
        return m_dataOrQName.elementAt(identity);
    }
  
protected voidaddNewDTMID(int 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.

    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";
    }
  
protected intaddNode(int type, int expandedTypeID, int parentIndex, int previousSibling, int dataOrPrefix, boolean canHaveFirstChild)
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.

    // 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;
  
public voidattributeDecl(java.lang.String eName, java.lang.String aName, java.lang.String type, java.lang.String valueDefault, java.lang.String value)
Report an attribute type declaration.

Only the effective (first) declaration for an attribute will be reported. The type will be one of the strings "CDATA", "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES", or "NOTATION", or a parenthesized token group with the separator "|" and all whitespace removed.

param
eName The name of the associated element.
param
aName The name of the attribute.
param
type A string representing the attribute type.
param
valueDefault A string representing the attribute default ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if none of these applies.
param
value A string representing the attribute's default value, or null if there is none.
throws
SAXException The application may raise an exception.


    // no op
  
public voidcharacters(char[] ch, int start, int length)
Receive notification of character data inside an element.

By default, do nothing. Application writers may override this method to take specific actions for each chunk of character data (such as adding the data to a node or buffer, or printing it to a file).

param
ch The characters.
param
start The start position in the character array.
param
length The number of characters to use from the character array.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ContentHandler#characters

    if (m_textPendingStart == -1)  // First one in this block
    {
      m_textPendingStart = m_chars.size();
      m_coalescedTextType = m_textType;
    }
    // Type logic: If all adjacent text is CDATASections, the
    // concatentated text is treated as a single CDATASection (see
    // initialization above).  If any were ordinary Text, the whole
    // thing is treated as Text. This may be worth %REVIEW%ing.
    else if (m_textType == DTM.TEXT_NODE)
    {
      m_coalescedTextType = DTM.TEXT_NODE;
    }

    m_chars.append(ch, start, length);
  
protected voidcharactersFlush()
Check whether accumulated text should be stripped; if not, append the appropriate flavor of text/cdata node.


    if (m_textPendingStart >= 0)  // -1 indicates no-text-in-progress
    {
      int length = m_chars.size() - m_textPendingStart;
      boolean doStrip = false;

      if (getShouldStripWhitespace())
      {
        doStrip = m_chars.isWhitespace(m_textPendingStart, length);
      }

      if (doStrip) {
        m_chars.setLength(m_textPendingStart);  // Discard accumulated text
      } else {
        // Guard against characters/ignorableWhitespace events that
        // contained no characters.  They should not result in a node.
        if (length > 0) {
          int exName = m_expandedNameTable.getExpandedTypeID(DTM.TEXT_NODE);
          int dataIndex = m_data.size();

          m_previous = addNode(m_coalescedTextType, exName,
                               m_parents.peek(), m_previous, dataIndex, false);

          m_data.addElement(m_textPendingStart);
          m_data.addElement(length);
        }
      }

      // Reset for next text block
      m_textPendingStart = -1;
      m_textType = m_coalescedTextType = DTM.TEXT_NODE;
    }
  
public voidclearCoRoutine()
Ask the CoRoutine parser to doTerminate and clear the reference.

    clearCoRoutine(true);
  
public voidclearCoRoutine(boolean callDoTerminate)
Ask the CoRoutine parser to doTerminate and clear the reference. If the CoRoutine parser has already been cleared, this will have no effect.

param
callDoTerminate true of doTerminate should be called on the coRoutine parser.


    if (null != m_incrementalSAXSource)
    {
      if (callDoTerminate)
        m_incrementalSAXSource.deliverMoreNodes(false);

      m_incrementalSAXSource = null;
    }
  
public voidcomment(char[] ch, int start, int length)
Report an XML comment anywhere in the document.

This callback will be used for comments inside or outside the document element, including comments in the external DTD subset (if read).

param
ch An array holding the characters in the comment.
param
start The starting position in the array.
param
length The number of characters to use from the array.
throws
SAXException The application may raise an exception.


    if (m_insideDTD)      // ignore comments if we're inside the DTD
      return;

    charactersFlush();

    int exName = m_expandedNameTable.getExpandedTypeID(DTM.COMMENT_NODE);

    // For now, treat comments as strings...  I guess we should do a
    // seperate FSB buffer instead.
    int dataIndex = m_valuesOrPrefixes.stringToIndex(new String(ch, start,
                      length));


    m_previous = addNode(DTM.COMMENT_NODE, exName,
                         m_parents.peek(), m_previous, dataIndex, false);
  
protected booleandeclAlreadyDeclared(java.lang.String prefix)
Check if a declaration has already been made for a given prefix.

param
prefix non-null prefix string.
return
true if the declaration has already been declared in the current context.


    int startDecls = m_contextIndexes.peek();
    java.util.Vector prefixMappings = m_prefixMappings;
    int nDecls = prefixMappings.size();

    for (int i = startDecls; i < nDecls; i += 2)
    {
      String prefixDecl = (String) prefixMappings.elementAt(i);

      if (prefixDecl == null)
        continue;

      if (prefixDecl.equals(prefix))
        return true;
    }

    return false;
  
public voiddispatchCharactersEvents(int nodeHandle, org.xml.sax.ContentHandler ch, boolean normalize)
Directly call the characters method on the passed ContentHandler for the string-value of the given node (see http://www.w3.org/TR/xpath#data-model for the definition of a node's string-value). Multiple calls to the ContentHandler's characters methods may well occur for a single call to this method.

param
nodeHandle The node ID.
param
ch A non-null reference to a ContentHandler.
param
normalize true if the content should be normalized according to the rules for the XPath normalize-space function.
throws
SAXException


    int identity = makeNodeIdentity(nodeHandle);
    
    if (identity == DTM.NULL)
      return;
    
    int type = _type(identity);

    if (isTextType(type))
    {
      int dataIndex = m_dataOrQName.elementAt(identity);
      int offset = m_data.elementAt(dataIndex);
      int length = m_data.elementAt(dataIndex + 1);

      if(normalize)
        m_chars.sendNormalizedSAXcharacters(ch, offset, length);
      else
        m_chars.sendSAXcharacters(ch, 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))
          {
            int dataIndex = _dataOrQName(identity);

            if (-1 == offset)
            {
              offset = m_data.elementAt(dataIndex);
            }

            length += m_data.elementAt(dataIndex + 1);
          }

          identity = getNextNodeIdentity(identity);
        } while (DTM.NULL != identity && (_parent(identity) >= startNode));

        if (length > 0)
        {
          if(normalize)
            m_chars.sendNormalizedSAXcharacters(ch, offset, length);
          else
            m_chars.sendSAXcharacters(ch, offset, length);
        }
      }
      else if(type != DTM.ELEMENT_NODE)
      {
        int dataIndex = _dataOrQName(identity);

        if (dataIndex < 0)
        {
          dataIndex = -dataIndex;
          dataIndex = m_data.elementAt(dataIndex + 1);
        }

        String str = m_valuesOrPrefixes.indexToString(dataIndex);

          if(normalize)
            FastStringBuffer.sendNormalizedSAXcharacters(str.toCharArray(),
                                                         0, str.length(), ch);
          else
            ch.characters(str.toCharArray(), 0, str.length());
      }
    }
  
public voiddispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch)
Directly create SAX parser events from a subtree.

param
nodeHandle The node ID.
param
ch A non-null reference to a ContentHandler.
throws
org.xml.sax.SAXException


    DTMTreeWalker treeWalker = m_walker;
    ContentHandler prevCH = treeWalker.getcontentHandler();

    if (null != prevCH)
    {
      treeWalker = new DTMTreeWalker();
    }

    treeWalker.setcontentHandler(ch);
    treeWalker.setDTM(this);

    try
    {
      treeWalker.traverse(nodeHandle);
    }
    finally
    {
      treeWalker.setcontentHandler(null);
    }
  
public voidelementDecl(java.lang.String name, java.lang.String model)
Report an element type declaration.

The content model will consist of the string "EMPTY", the string "ANY", or a parenthesised group, optionally followed by an occurrence indicator. The model will be normalized so that all whitespace is removed,and will include the enclosing parentheses.

param
name The element type name.
param
model The content model as a normalized string.
throws
SAXException The application may raise an exception.


    // no op
  
public voidendCDATA()
Report the end of a CDATA section.

throws
SAXException The application may raise an exception.
see
#startCDATA

    m_textType = DTM.TEXT_NODE;
  
public voidendDTD()
Report the end of DTD declarations.

throws
SAXException The application may raise an exception.
see
#startDTD


    m_insideDTD = false;
  
public voidendDocument()
Receive notification of the end of the document.

throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ContentHandler#endDocument

    if (DEBUG)
      System.out.println("endDocument");

		charactersFlush();

    m_nextsib.setElementAt(NULL,0);

    if (m_firstch.elementAt(0) == NOTPROCESSED)
      m_firstch.setElementAt(NULL,0);

    if (DTM.NULL != m_previous)
      m_nextsib.setElementAt(DTM.NULL,m_previous);

    m_parents = null;
    m_prefixMappings = null;
    m_contextIndexes = null;

    m_endDocumentOccured = true;
    
    // Bugzilla 4858: throw away m_locator. we cache m_systemId
    m_locator = null;
  
public voidendElement(java.lang.String uri, java.lang.String localName, java.lang.String qName)
Receive notification of the end of an element.

By default, do nothing. Application writers may override this method in a subclass to take specific actions at the end of each element (such as finalising a tree node or writing output to a file).

param
uri The Namespace URI, or the empty string if the element has no Namespace URI or if Namespace processing is not being performed.
param
localName The local name (without prefix), or the empty string if Namespace processing is not being performed.
param
qName The qualified XML 1.0 name (with prefix), or the empty string if qualified names are not available.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ContentHandler#endElement

   if (DEBUG)
      System.out.println("endElement: uri: " + uri + ", localname: "
												 + localName + ", qname: "+qName);

    charactersFlush();

    // If no one noticed, startPrefixMapping is a drag.
    // Pop the context for the last child (the one pushed by startElement)
    m_contextIndexes.quickPop(1);

    // Do it again for this one (the one pushed by the last endElement).
    int topContextIndex = m_contextIndexes.peek();
    if (topContextIndex != m_prefixMappings.size()) {
      m_prefixMappings.setSize(topContextIndex);
    }

    int lastNode = m_previous;

    m_previous = m_parents.pop();

    // If lastNode is still DTM.NULL, this element had no children
    if (DTM.NULL == lastNode)
      m_firstch.setElementAt(DTM.NULL,m_previous);
    else
      m_nextsib.setElementAt(DTM.NULL,lastNode);

    popShouldStripWhitespace();
  
public voidendEntity(java.lang.String name)
Report the end of an entity.

param
name The name of the entity that is ending.
throws
SAXException The application may raise an exception.
see
#startEntity


    // no op
  
public voidendPrefixMapping(java.lang.String prefix)
Receive notification of the end of a Namespace mapping.

By default, do nothing. Application writers may override this method in a subclass to take specific actions at the end of each prefix mapping.

param
prefix The Namespace prefix being declared.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ContentHandler#endPrefixMapping

    if (DEBUG)
      System.out.println("endPrefixMapping: prefix: " + prefix);

    if(null == prefix)
      prefix = "";

    int index = m_contextIndexes.peek() - 1;

    do
    {
      index = m_prefixMappings.indexOf(prefix, ++index);
    } while ( (index >= 0) && ((index & 0x01) == 0x01) );


    if (index > -1)
    {
      m_prefixMappings.setElementAt("%@$#^@#", index);
      m_prefixMappings.setElementAt("%@$#^@#", index + 1);
    }

    // no op
  
public voiderror(org.xml.sax.SAXParseException e)
Receive notification of a recoverable parser error.

The default implementation does nothing. Application writers may override this method in a subclass to take specific actions for each error, such as inserting the message in a log file or printing it to the console.

param
e The warning information encoded as an exception.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ErrorHandler#warning
see
org.xml.sax.SAXParseException

    throw e;
  
public voidexternalEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
Report a parsed external entity declaration.

Only the effective (first) declaration for each entity will be reported.

param
name The name of the entity. If it is a parameter entity, the name will begin with '%'.
param
publicId The declared public identifier of the entity, or null if none was declared.
param
systemId The declared system identifier of the entity.
throws
SAXException The application may raise an exception.
see
#internalEntityDecl
see
org.xml.sax.DTDHandler#unparsedEntityDecl


    // no op
  
public voidfatalError(org.xml.sax.SAXParseException e)
Report a fatal XML parsing error.

The default implementation throws a SAXParseException. Application writers may override this method in a subclass if they need to take specific actions for each fatal error (such as collecting all of the errors into a single report): in any case, the application must stop all regular processing when this method is invoked, since the document is no longer reliable, and the parser may no longer report parsing events.

param
e The error information encoded as an exception.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ErrorHandler#fatalError
see
org.xml.sax.SAXParseException

    throw e;
  
public intgetAttributeNode(int nodeHandle, java.lang.String namespaceURI, java.lang.String name)
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 ( nodeName) or DTM.NULL if there is no such attribute.


    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;
  
public org.xml.sax.ContentHandlergetContentHandler()
getContentHandler returns "our SAX builder" -- the thing that someone else should send SAX events to in order to extend this DTM model. %REVIEW% Should this return null if constrution already done/begun?

return
null if this model doesn't respond to SAX events, "this" if the DTM object has a built-in SAX ContentHandler, the IncrementalSAXSource if we're bound to one and should receive the SAX stream via it for incremental build purposes... Note that IncrementalSAXSource_Filter is package private, hence it can be statically referenced using instanceof (CR 6537912).


    if (m_incrementalSAXSource.getClass()
        .getName().equals("com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter"))
      return (ContentHandler) m_incrementalSAXSource;
    else
      return this;
  
public org.xml.sax.DTDHandlergetDTDHandler()
Return this DTM's DTDHandler.

return
null if this model doesn't respond to SAX dtd events.

    return this;
  
public org.xml.sax.ext.DeclHandlergetDeclHandler()
Return this DTM's DeclHandler.

return
null if this model doesn't respond to SAX Decl events.

    return this;
  
public java.lang.StringgetDocumentTypeDeclarationPublicIdentifier()
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.


    /** @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;
  
public java.lang.StringgetDocumentTypeDeclarationSystemIdentifier()
A document type declaration information item has the following properties: 1. [system identifier] The system identifier of the external subset, if it exists. Otherwise this property has no value.

return
the system identifier String object, or null if there is none.


    /** @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;
  
public intgetElementById(java.lang.String elementId)
Returns the Element whose ID is given by elementId. If no such element exists, returns DTM.NULL. Behavior is not defined if more than one element has this ID. Attributes (including those with the name "ID") are not of type ID unless so defined by DTD/Schema information available to the DTM implementation. Implementations that do not know whether attributes are of type ID or not are expected to return DTM.NULL.

%REVIEW% Presumably IDs are still scoped to a single document, and this operation searches only within a single document, right? Wouldn't want collisions between DTMs in the same process.

param
elementId The unique id value for an element.
return
The handle of the matching element.


    Integer intObj;
    boolean isMore = true;

    do
    {
      intObj = (Integer) m_idAttributes.get(elementId);

      if (null != intObj)
        return makeNodeHandle(intObj.intValue());

      if (!isMore || m_endDocumentOccured)
        break;

      isMore = nextNode();
    }
    while (null == intObj);

    return DTM.NULL;
  
public org.xml.sax.EntityResolvergetEntityResolver()
Return this DTM's EntityResolver.

return
null if this model doesn't respond to SAX entity ref events.

    return this;
  
public org.xml.sax.ErrorHandlergetErrorHandler()
Return this DTM's ErrorHandler.

return
null if this model doesn't respond to SAX error events.

    return this;
  
public java.lang.StringgetFixedNames(int type)

    return m_fixednames[type];
  
public intgetIdForNamespace(java.lang.String uri)
Get a prefix either from the uri mapping, or just make one up!

param
uri The namespace URI, which may be null.
return
The prefix if there is one, or null.


     return m_valuesOrPrefixes.stringToIndex(uri);
    
  
public org.xml.sax.ext.LexicalHandlergetLexicalHandler()
Return this DTM's lexical handler. %REVIEW% Should this return null if constrution already done/begun?

return
null if this model doesn't respond to lexical SAX events, "this" if the DTM object has a built-in SAX ContentHandler, the IncrementalSAXSource if we're bound to one and should receive the SAX stream via it for incremental build purposes... Note that IncrementalSAXSource_Filter is package private, hence it can be statically referenced using instanceof (CR 6537912).


    if (m_incrementalSAXSource.getClass()
        .getName().equals("com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter"))
      return (LexicalHandler) m_incrementalSAXSource;
    else
      return this;
  
public java.lang.StringgetLocalName(int nodeHandle)
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.

    return m_expandedNameTable.getLocalName(_exptype(makeNodeIdentity(nodeHandle)));
  
public java.lang.StringgetNamespaceURI(int nodeHandle)
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.)

%REVIEW% Null or ""? -sb

param
nodeHandle the id of the node.
return
String URI value of this node's namespace, or null if no namespace was resolved.


    return m_expandedNameTable.getNamespace(_exptype(makeNodeIdentity(nodeHandle)));
  
public java.lang.StringgetNamespaceURI(java.lang.String prefix)
Get a prefix either from the qname or from the uri mapping, or just make one up!

return
The prefix if there is one, or null.


    String uri = "";
    int prefixIndex = m_contextIndexes.peek() - 1 ;

    if(null == prefix)
      prefix = "";

      do
      {
        prefixIndex = m_prefixMappings.indexOf(prefix, ++prefixIndex);
      } while ( (prefixIndex >= 0) && (prefixIndex & 0x01) == 0x01);

      if (prefixIndex > -1)
      {
        uri = (String) m_prefixMappings.elementAt(prefixIndex + 1);
      }


    return uri;
  
protected intgetNextNodeIdentity(int identity)
Get the next node identity value in the list, and call the iterator if it hasn't been added yet.

param
identity The node identity (index).
return
identity+1, or DTM.NULL.


    identity += 1;

    while (identity >= m_size)
    {
      if (null == m_incrementalSAXSource)
        return DTM.NULL;

      nextNode();
    }

    return identity;
  
public java.lang.StringgetNodeName(int nodeHandle)
Given a node handle, return its DOM-style node name. This will include names such as #text or #document.

param
nodeHandle the id of the node.
return
String Name of this node, which may be an empty string. %REVIEW% Document when empty string is possible... %REVIEW-COMMENT% It should never be empty, should it?


    int expandedTypeID = getExpandedTypeID(nodeHandle);
    // If just testing nonzero, no need to shift...
    int namespaceID = m_expandedNameTable.getNamespaceID(expandedTypeID);                     

    if (0 == namespaceID)
    {
      // Don't retrieve name until/unless needed
      // String name = m_expandedNameTable.getLocalName(expandedTypeID);
      int type = getNodeType(nodeHandle);

      if (type == DTM.NAMESPACE_NODE)
      {
        if (null == m_expandedNameTable.getLocalName(expandedTypeID))
          return "xmlns";
        else
          return "xmlns:" + m_expandedNameTable.getLocalName(expandedTypeID);
      }
      else if (0 == m_expandedNameTable.getLocalNameID(expandedTypeID))
      {
        return m_fixednames[type];
      }
      else
        return m_expandedNameTable.getLocalName(expandedTypeID);
    }
    else
    {
      int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle));

      if (qnameIndex < 0)
      {
        qnameIndex = -qnameIndex;
        qnameIndex = m_data.elementAt(qnameIndex);
      }

      return m_valuesOrPrefixes.indexToString(qnameIndex);
    }
  
public java.lang.StringgetNodeNameX(int nodeHandle)
Given a node handle, return the XPath node name. This should be the name as described by the XPath data model, NOT the DOM-style name.

param
nodeHandle the id of the node.
return
String Name of this node, which may be an empty string.


    int expandedTypeID = getExpandedTypeID(nodeHandle);    
    int namespaceID = m_expandedNameTable.getNamespaceID(expandedTypeID);                      

    if (0 == namespaceID)
    {
      String name = m_expandedNameTable.getLocalName(expandedTypeID);

      if (name == null)
        return "";
      else
        return name;
    }
    else
    {
      int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle));

      if (qnameIndex < 0)
      {
        qnameIndex = -qnameIndex;
        qnameIndex = m_data.elementAt(qnameIndex);
      }

      return m_valuesOrPrefixes.indexToString(qnameIndex);
    }
  
public java.lang.StringgetNodeValue(int nodeHandle)
Given a node handle, return its node value. This is mostly as defined by the DOM, but may ignore some conveniences.

param
nodeHandle The node id.
return
String Value of this node, or null if not meaningful for this node type.


    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);
    }
  
public intgetNumberOfNodes()
Get the number of nodes that have been added.

return
The number of that are currently in the tree.

    return m_size;
  
public java.lang.StringgetPrefix(int nodeHandle)
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.

%REVIEW% Are you sure you want "" for no prefix?

%REVIEW-COMMENT% I think so... not totally sure. -sb

param
nodeHandle the id of the node.
return
String prefix of this node's name, or "" if no explicit namespace prefix was given.


    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 "";
  
public java.lang.StringgetPrefix(java.lang.String qname, java.lang.String uri)
Get a prefix either from the qname or from the uri mapping, or just make one up!

param
qname The qualified name, which may be null.
param
uri The namespace URI, which may be null.
return
The prefix if there is one, or null.


    String prefix;
    int uriIndex = -1;

    if (null != uri && uri.length() > 0)
    {

      do
      {
        uriIndex = m_prefixMappings.indexOf(uri, ++uriIndex);
      } while ( (uriIndex & 0x01) == 0);

      if (uriIndex >= 0)
      {
        prefix = (String) m_prefixMappings.elementAt(uriIndex - 1);
      }
      else if (null != qname)
      {
        int indexOfNSSep = qname.indexOf(':");

        if (qname.equals("xmlns"))
          prefix = "";
        else if (qname.startsWith("xmlns:"))
          prefix = qname.substring(indexOfNSSep + 1);
        else
          prefix = (indexOfNSSep > 0)
                   ? qname.substring(0, indexOfNSSep) : null;
      }
      else
      {
        prefix = null;
      }
    }
    else if (null != qname)
    {
      int indexOfNSSep = qname.indexOf(':");

      if (indexOfNSSep > 0)
      {
        if (qname.startsWith("xmlns:"))
          prefix = qname.substring(indexOfNSSep + 1);
        else
          prefix = qname.substring(0, indexOfNSSep);	
      }
      else
      {
      	if (qname.equals("xmlns"))
      	  prefix = "";
      	else
      	  prefix = null;
      }
    }
    else
    {
      prefix = null;
    }

    return prefix;
  
public javax.xml.transform.SourceLocatorgetSourceLocatorFor(int node)
Retrieve the SourceLocator associated with a specific node. This is only meaningful if the XalanProperties.SOURCE_LOCATION flag was set True using setProperty; if it was never set, or was set false, we will return null. (We _could_ return a locator with the document's base URI and bogus line/column information. Trying that; see the else clause.)

    if (m_useSourceLocationProperty)
    {

      node = makeNodeIdentity(node);
      

      return new NodeLocator(null,
                             m_sourceSystemId.elementAt(node),
                             m_sourceLine.elementAt(node),
                             m_sourceColumn.elementAt(node));
    }
    else if(m_locator!=null)
    {
    	return new NodeLocator(null,m_locator.getSystemId(),-1,-1);
    }
    else if(m_systemId!=null)
    {
    	return new NodeLocator(null,m_systemId,-1,-1);
    }
    return null;
  
public com.sun.org.apache.xml.internal.utils.XMLStringgetStringValue(int 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.

    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))
          {
            int dataIndex = _dataOrQName(identity);

            if (-1 == offset)
            {
              offset = m_data.elementAt(dataIndex);
            }

            length += m_data.elementAt(dataIndex + 1);
          }

          identity = getNextNodeIdentity(identity);
        } while (DTM.NULL != identity && (_parent(identity) >= startNode));

        if (length > 0)
        {
          return m_xstrf.newstr(m_chars, offset, length);
        }
      }
      else if(type != DTM.ELEMENT_NODE)
      {
        int dataIndex = _dataOrQName(identity);

        if (dataIndex < 0)
        {
          dataIndex = -dataIndex;
          dataIndex = m_data.elementAt(dataIndex + 1);
        }
        return m_xstrf.newstr(m_valuesOrPrefixes.indexToString(dataIndex));
      }
    }

    return m_xstrf.emptystr();
  
public java.lang.StringgetUnparsedEntityURI(java.lang.String name)
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.

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.

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.

(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.


    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;
  
public voidignorableWhitespace(char[] ch, int start, int length)
Receive notification of ignorable whitespace in element content.

By default, do nothing. Application writers may override this method to take specific actions for each chunk of ignorable whitespace (such as adding data to a node or buffer, or printing it to a file).

param
ch The whitespace characters.
param
start The start position in the character array.
param
length The number of characters to use from the character array.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ContentHandler#ignorableWhitespace


    // %OPT% We can probably take advantage of the fact that we know this 
    // is whitespace.
    characters(ch, start, length);
  
public voidinternalEntityDecl(java.lang.String name, java.lang.String value)
Report an internal entity declaration.

Only the effective (first) declaration for each entity will be reported.

param
name The name of the entity. If it is a parameter entity, the name will begin with '%'.
param
value The replacement text of the entity.
throws
SAXException The application may raise an exception.
see
#externalEntityDecl
see
org.xml.sax.DTDHandler#unparsedEntityDecl


    // no op
  
public booleanisAttributeSpecified(int attributeHandle)
5. [specified] A flag indicating whether this attribute was actually specified in the start-tag of its element, or was defaulted from the DTD.

param
attributeHandle Must be a valid handle to an attribute node.
return
true if the attribute was specified; false if it was defaulted.


    // I'm not sure if I want to do anything with this...
    return true;  // ??
  
private final booleanisTextType(int type)
Bottleneck determination of text type.

param
type oneof DTM.XXX_NODE.
return
true if this is a text or cdata section.

    return (DTM.TEXT_NODE == type || DTM.CDATA_SECTION_NODE == type);
  
public booleanisWhitespace(int nodeHandle)
Determine if the string-value of a node is whitespace

param
nodeHandle The node Handle.
return
Return true if the given node is whitespace.

    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_chars.isWhitespace(offset, length);
    }
    return false;
  
public voidmigrateTo(com.sun.org.apache.xml.internal.dtm.DTMManager manager)
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

    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);
    }
  
public booleanneedsTwoThreads()

return
true iff we're building this model incrementally (eg we're partnered with a IncrementalSAXSource) and thus require that the transformation and the parse run simultaneously. Guidance to the DTMManager.

    return null != m_incrementalSAXSource;
  
protected booleannextNode()
This method should try and build one or more nodes in the table.

return
The true if a next node is found or false if there are no more nodes.


    if (null == m_incrementalSAXSource)
      return false;

    if (m_endDocumentOccured)
    {
      clearCoRoutine();

      return false;
    }

    Object gotMore = m_incrementalSAXSource.deliverMoreNodes(true);

    // gotMore may be a Boolean (TRUE if still parsing, FALSE if
    // EOF) or an exception if IncrementalSAXSource malfunctioned
    // (code error rather than user error).
    //
    // %REVIEW% Currently the ErrorHandlers sketched herein are
    // no-ops, so I'm going to initially leave this also as a
    // no-op.
    if (!(gotMore instanceof Boolean))
    {
      if(gotMore instanceof RuntimeException)
      {
        throw (RuntimeException)gotMore;
      }
      else if(gotMore instanceof Exception)
      {
        throw new WrappedRuntimeException((Exception)gotMore);
      }
      // for now...
      clearCoRoutine();

      return false;

      // %TBD%
    }

    if (gotMore != Boolean.TRUE)
    {

      // EOF reached without satisfying the request
      clearCoRoutine();  // Drop connection, stop trying

      // %TBD% deregister as its listener?
    }

    return true;
  
public voidnotationDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
Receive notification of a notation declaration.

By default, do nothing. Application writers may override this method in a subclass if they wish to keep track of the notations declared in a document.

param
name The notation name.
param
publicId The notation public identifier, or null if not available.
param
systemId The notation system identifier.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.DTDHandler#notationDecl
throws
SAXException


    // no op
  
public voidprocessingInstruction(java.lang.String target, java.lang.String data)
Receive notification of a processing instruction.

By default, do nothing. Application writers may override this method in a subclass to take specific actions for each processing instruction, such as setting status variables or invoking other methods.

param
target The processing instruction target.
param
data The processing instruction data, or null if none is supplied.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ContentHandler#processingInstruction

    if (DEBUG)
		 System.out.println("processingInstruction: target: " + target +", data: "+data);

    charactersFlush();

    int exName = m_expandedNameTable.getExpandedTypeID(null, target,
                                         DTM.PROCESSING_INSTRUCTION_NODE);
    int dataIndex = m_valuesOrPrefixes.stringToIndex(data);

    m_previous = addNode(DTM.PROCESSING_INSTRUCTION_NODE, exName,
                         m_parents.peek(), m_previous,
                         dataIndex, false);
  
public org.xml.sax.InputSourceresolveEntity(java.lang.String publicId, java.lang.String systemId)
Resolve an external entity.

Always return null, so that the parser will use the system identifier provided in the XML document. This method implements the SAX default behaviour: application writers can override it in a subclass to do special translations such as catalog lookups or URI redirection.

param
publicId The public identifer, or null if none is available.
param
systemId The system identifier provided in the XML document.
return
The new input source, or null to require the default behaviour.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.EntityResolver#resolveEntity
throws
SAXException

    return null;
  
public voidsetDocumentLocator(org.xml.sax.Locator locator)
Receive a Locator object for document events.

By default, do nothing. Application writers may override this method in a subclass if they wish to store the locator for use with other document events.

param
locator A locator for all SAX document events.
see
org.xml.sax.ContentHandler#setDocumentLocator
see
org.xml.sax.Locator

    m_locator = locator;
    m_systemId = locator.getSystemId();
  
public voidsetIDAttribute(java.lang.String id, int elem)
Set an ID string to node association in the ID table.

param
id The ID string.
param
elem The associated element handle.

    m_idAttributes.put(id, new Integer(elem));
  
public voidsetIncrementalSAXSource(com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource incrementalSAXSource)
Bind a IncrementalSAXSource to this DTM. If we discover we need nodes that have not yet been built, we will ask this object to send us more events, and it will manage interactions with its data sources. Note that we do not actually build the IncrementalSAXSource, since we don't know what source it's reading from, what thread that source will run in, or when it will run.

param
incrementalSAXSource The parser that we want to recieve events from on demand.


    // Establish coroutine link so we can request more data
    //
    // Note: It's possible that some versions of IncrementalSAXSource may
    // not actually use a CoroutineManager, and hence may not require
    // that we obtain an Application Coroutine ID. (This relies on the
    // coroutine transaction details having been encapsulated in the
    // IncrementalSAXSource.do...() methods.)
    m_incrementalSAXSource = incrementalSAXSource;

    // Establish SAX-stream link so we can receive the requested data
    incrementalSAXSource.setContentHandler(this);
    incrementalSAXSource.setLexicalHandler(this);
    incrementalSAXSource.setDTDHandler(this);

    // Are the following really needed? incrementalSAXSource doesn't yet
    // support them, and they're mostly no-ops here...
    //incrementalSAXSource.setErrorHandler(this);
    //incrementalSAXSource.setDeclHandler(this);
  
public voidsetProperty(java.lang.String property, java.lang.Object value)
Set a run time property for this DTM instance. %REVIEW% Now that we no longer use this method to support getSourceLocatorFor, can we remove it?

param
property a String value
param
value an Object value

  
protected voidsetSourceLocation()
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.

    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);
    }
  
public voidsetUseSourceLocation(boolean useSourceLocation)
Set whether information about document source location should be maintained or not.

    m_useSourceLocationProperty = useSourceLocation;
  
public voidskippedEntity(java.lang.String name)
Receive notification of a skipped entity.

By default, do nothing. Application writers may override this method in a subclass to take specific actions for each processing instruction, such as setting status variables or invoking other methods.

param
name The name of the skipped entity.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ContentHandler#processingInstruction


    // %REVIEW% What should be done here?
    // no op
  
public voidstartCDATA()
Report the start of a CDATA section.

The contents of the CDATA section will be reported through the regular {@link org.xml.sax.ContentHandler#characters characters} event.

throws
SAXException The application may raise an exception.
see
#endCDATA

    m_textType = DTM.CDATA_SECTION_NODE;
  
public voidstartDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
Report the start of DTD declarations, if any.

Any declarations are assumed to be in the internal subset unless otherwise indicated by a {@link #startEntity startEntity} event.

Note that the start/endDTD events will appear within the start/endDocument events from ContentHandler and before the first startElement event.

param
name The document type name.
param
publicId The declared public identifier for the external DTD subset, or null if none was declared.
param
systemId The declared system identifier for the external DTD subset, or null if none was declared.
throws
SAXException The application may raise an exception.
see
#endDTD
see
#startEntity


    m_insideDTD = true;
  
public voidstartDocument()
Receive notification of the beginning of the document.

throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ContentHandler#startDocument

    if (DEBUG)
      System.out.println("startDocument");

		
    int doc = addNode(DTM.DOCUMENT_NODE,
                      m_expandedNameTable.getExpandedTypeID(DTM.DOCUMENT_NODE),
                      DTM.NULL, DTM.NULL, 0, true);

    m_parents.push(doc);
    m_previous = DTM.NULL;

    m_contextIndexes.push(m_prefixMappings.size());  // for the next element.
  
public voidstartElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, org.xml.sax.Attributes attributes)
Receive notification of the start of an element.

By default, do nothing. Application writers may override this method in a subclass to take specific actions at the start of each element (such as allocating a new tree node or writing output to a file).

param
uri The Namespace URI, or the empty string if the element has no Namespace URI or if Namespace processing is not being performed.
param
localName The local name (without prefix), or the empty string if Namespace processing is not being performed.
param
qName The qualified name (with prefix), or the empty string if qualified names are not available.
param
attributes The specified or defaulted attributes.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ContentHandler#startElement


                                                                                                                                                                             
    
                 
             
  
   if (DEBUG)
	 {
      System.out.println("startElement: uri: " + uri + ", localname: "
												 + localName + ", qname: "+qName+", atts: " + attributes);

			boolean DEBUG_ATTRS=true;
			if(DEBUG_ATTRS & attributes!=null)
			{
				int n = attributes.getLength();
				if(n==0)
					System.out.println("\tempty attribute list");
				else for (int i = 0; i < n; i++)
					System.out.println("\t attr: uri: " + attributes.getURI(i) +
														 ", localname: " + attributes.getLocalName(i) +
														 ", qname: " + attributes.getQName(i) +
														 ", type: " + attributes.getType(i) +
														 ", value: " + attributes.getValue(i)
														 );
			}
	 }
		
    charactersFlush();

    int exName = m_expandedNameTable.getExpandedTypeID(uri, localName, DTM.ELEMENT_NODE);
    String prefix = getPrefix(qName, uri);
    int prefixIndex = (null != prefix)
                      ? m_valuesOrPrefixes.stringToIndex(qName) : 0;

    int elemNode = addNode(DTM.ELEMENT_NODE, exName,
                           m_parents.peek(), m_previous, prefixIndex, true);

    if(m_indexing)
      indexNode(exName, elemNode);
    

    m_parents.push(elemNode);

    int startDecls = m_contextIndexes.peek();
    int nDecls = m_prefixMappings.size();
    int prev = DTM.NULL;

    if(!m_pastFirstElement)
    {
      // SPECIAL CASE: Implied declaration at root element
      prefix="xml";
      String declURL = "http://www.w3.org/XML/1998/namespace";
      exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);
      int val = m_valuesOrPrefixes.stringToIndex(declURL);
      prev = addNode(DTM.NAMESPACE_NODE, exName, elemNode,
                     prev, val, false);
      m_pastFirstElement=true;
    }

    for (int i = startDecls; i < nDecls; i += 2)
    {
      prefix = (String) m_prefixMappings.elementAt(i);

      if (prefix == null)
        continue;

      String declURL = (String) m_prefixMappings.elementAt(i + 1);

      exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE);

      int val = m_valuesOrPrefixes.stringToIndex(declURL);

      prev = addNode(DTM.NAMESPACE_NODE, exName, elemNode,
                     prev, val, false);
    }

    int n = attributes.getLength();

    for (int i = 0; i < n; i++)
    {
      String attrUri = attributes.getURI(i);
      String attrQName = attributes.getQName(i);
      String valString = attributes.getValue(i);

      prefix = getPrefix(attrQName, attrUri);

      int nodeType;
      
       String attrLocalName = attributes.getLocalName(i);

      if ((null != attrQName)
              && (attrQName.equals("xmlns")
                  || attrQName.startsWith("xmlns:")))
      {
        if (declAlreadyDeclared(prefix))
          continue;  // go to the next attribute.

        nodeType = DTM.NAMESPACE_NODE;
      }
      else
      {
        nodeType = DTM.ATTRIBUTE_NODE;

        if (attributes.getType(i).equalsIgnoreCase("ID"))
          setIDAttribute(valString, elemNode);
      }

      // Bit of a hack... if somehow valString is null, stringToIndex will
      // return -1, which will make things very unhappy.
      if(null == valString)
        valString = "";

      int val = m_valuesOrPrefixes.stringToIndex(valString);
      //String attrLocalName = attributes.getLocalName(i);

      if (null != prefix)
      {

        prefixIndex = m_valuesOrPrefixes.stringToIndex(attrQName);

        int dataIndex = m_data.size();

        m_data.addElement(prefixIndex);
        m_data.addElement(val);

        val = -dataIndex;
      }

      exName = m_expandedNameTable.getExpandedTypeID(attrUri, attrLocalName, nodeType);
      prev = addNode(nodeType, exName, elemNode, prev, val,
                     false);
    }

    if (DTM.NULL != prev)
      m_nextsib.setElementAt(DTM.NULL,prev);

    if (null != m_wsfilter)
    {
      short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode), this);
      boolean shouldStrip = (DTMWSFilter.INHERIT == wsv)
                            ? getShouldStripWhitespace()
                            : (DTMWSFilter.STRIP == wsv);

      pushShouldStripWhitespace(shouldStrip);
    }

    m_previous = DTM.NULL;

    m_contextIndexes.push(m_prefixMappings.size());  // for the children.
  
public voidstartEntity(java.lang.String name)
Report the beginning of an entity in content.

NOTE: entity references in attribute values -- and the start and end of the document entity -- are never reported.

The start and end of the external DTD subset are reported using the pseudo-name "[dtd]". All other events must be properly nested within start/end entity events.

Note that skipped entities will be reported through the {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity} event, which is part of the ContentHandler interface.

param
name The name of the entity. If it is a parameter entity, the name will begin with '%'.
throws
SAXException The application may raise an exception.
see
#endEntity
see
org.xml.sax.ext.DeclHandler#internalEntityDecl
see
org.xml.sax.ext.DeclHandler#externalEntityDecl


    // no op
  
public voidstartPrefixMapping(java.lang.String prefix, java.lang.String uri)
Receive notification of the start of a Namespace mapping.

By default, do nothing. Application writers may override this method in a subclass to take specific actions at the start of each Namespace prefix scope (such as storing the prefix mapping).

param
prefix The Namespace prefix being declared.
param
uri The Namespace URI mapped to the prefix.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ContentHandler#startPrefixMapping


    if (DEBUG)
      System.out.println("startPrefixMapping: prefix: " + prefix + ", uri: "
                         + uri);

    if(null == prefix)
      prefix = "";
    m_prefixMappings.addElement(prefix);  // JDK 1.1.x compat -sc
    m_prefixMappings.addElement(uri);  // JDK 1.1.x compat -sc
  
public voidunparsedEntityDecl(java.lang.String name, java.lang.String publicId, java.lang.String systemId, java.lang.String notationName)
Receive notification of an unparsed entity declaration.

By default, do nothing. Application writers may override this method in a subclass to keep track of the unparsed entities declared in a document.

param
name The entity name.
param
publicId The entity public identifier, or null if not available.
param
systemId The entity system identifier.
param
notationName The name of the associated notation.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.DTDHandler#unparsedEntityDecl
throws
SAXException


    if (null == m_entities)
    {
      m_entities = new Vector();
    }

    try
    {
      systemId = SystemIDResolver.getAbsoluteURI(systemId,
                                                 getDocumentBaseURI());
    }
    catch (Exception e)
    {
      throw new org.xml.sax.SAXException(e);
    }

    //  private static final int ENTITY_FIELD_PUBLICID = 0;
    m_entities.addElement(publicId);

    //  private static final int ENTITY_FIELD_SYSTEMID = 1;
    m_entities.addElement(systemId);

    //  private static final int ENTITY_FIELD_NOTATIONNAME = 2;
    m_entities.addElement(notationName);

    //  private static final int ENTITY_FIELD_NAME = 3;
    m_entities.addElement(name);
  
public voidwarning(org.xml.sax.SAXParseException e)
Receive notification of a parser warning.

The default implementation does nothing. Application writers may override this method in a subclass to take specific actions for each warning, such as inserting the message in a log file or printing it to the console.

param
e The warning information encoded as an exception.
throws
SAXException Any SAX exception, possibly wrapping another exception.
see
org.xml.sax.ErrorHandler#warning
see
org.xml.sax.SAXParseException


    // %REVIEW% Is there anyway to get the JAXP error listener here?
    System.err.println(e.getMessage());